summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2015-08-11 21:09:52 +0000
committerAaron Ballman <aaron@aaronballman.com>2015-08-11 21:09:52 +0000
commit6f6d0b6c5a37a42f17591e37a30c911ec1c52898 (patch)
treea457a591951a63edbd746ac32a1e420dc0b63f92
parentda06bce8b50d47ca841d694e10c12638157b2093 (diff)
downloadbcm5719-llvm-6f6d0b6c5a37a42f17591e37a30c911ec1c52898.tar.gz
bcm5719-llvm-6f6d0b6c5a37a42f17591e37a30c911ec1c52898.zip
Add a polymorphic AST matcher for testing whether a constructor or a conversion declaration is marked as explicit or not.
llvm-svn: 244666
-rw-r--r--clang/docs/LibASTMatchersReference.html26
-rw-r--r--clang/include/clang/ASTMatchers/ASTMatchers.h21
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Registry.cpp1
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTest.cpp14
4 files changed, 62 insertions, 0 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 799b47af6fd..954304efbcc 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -1483,6 +1483,19 @@ Example matches #1, but not #2 or #3 (matcher = constructorDecl(isDefaultConstru
</pre></td></tr>
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicit0')"><a name="isExplicit0Anchor">isExplicit</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicit0"><pre>Matches a constructor declaration if it is marked explicit.
+
+Given
+ struct S {
+ S(int); // #1
+ explicit S(double); // #2
+ };
+constructorDecl(isExplicit())
+ will match #2, but not #1.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('isMoveConstructor1')"><a name="isMoveConstructor1Anchor">isMoveConstructor</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isMoveConstructor1"><pre>Matches constructor declarations that are move constructors.
@@ -1495,6 +1508,19 @@ Example matches #3, but not #1 or #2 (matcher = constructorDecl(isMoveConstructo
</pre></td></tr>
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html">CXXConversionDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicit1')"><a name="isExplicit1Anchor">isExplicit</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicit1"><pre>Matches a conversion declaration if it is marked explicit.
+
+Given
+ struct S {
+ operator int(); // #1
+ explicit operator bool(); // #2
+ };
+conversionDecl(isExplicit())
+ will match #2, but not #1.
+</pre></td></tr>
+
+
<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>&gt;</td><td class="name" onclick="toggle('isBaseInitializer0')"><a name="isBaseInitializer0Anchor">isBaseInitializer</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isBaseInitializer0"><pre>Matches a constructor initializer if it is initializing a base, as opposed to a member.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 778e1f4dfe7..4aec6c1f445 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -4189,6 +4189,27 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) {
return Node.isDefaultConstructor();
}
+/// \brief Matches constructor and conversion declarations that are marked with
+/// the explicit keyword.
+///
+/// Given
+/// \code
+/// struct S {
+/// S(int); // #1
+/// explicit S(double); // #2
+/// operator int(); // #3
+/// explicit operator bool(); // #4
+/// };
+/// \endcode
+/// constructorDecl(isExplicit()) will match #2, but not #1.
+/// conversionDecl(isExplicit()) will match #4, but not #3.
+AST_POLYMORPHIC_MATCHER(isExplicit,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl,
+ CXXConversionDecl)) {
+ return Node.isExplicit();
+
+}
+
/// \brief If the given case statement does not use the GNU case range
/// extension, matches the constant given in the statement.
///
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 7e3df2dfd9a..be04ed47633 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -249,6 +249,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isDefinition);
REGISTER_MATCHER(isDeleted);
REGISTER_MATCHER(isExceptionVariable);
+ REGISTER_MATCHER(isExplicit);
REGISTER_MATCHER(isExplicitTemplateSpecialization);
REGISTER_MATCHER(isExpr);
REGISTER_MATCHER(isExternC);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index d51a5e28b5e..f0eede8a788 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -1420,6 +1420,13 @@ TEST(Callee, MatchesDeclarations) {
CallMethodX));
}
+TEST(ConversionDeclaration, IsExplicit) {
+ EXPECT_TRUE(matches("struct S { explicit operator int(); };",
+ conversionDecl(isExplicit())));
+ EXPECT_TRUE(notMatches("struct S { operator int(); };",
+ conversionDecl(isExplicit())));
+}
+
TEST(Callee, MatchesMemberExpressions) {
EXPECT_TRUE(matches("class Y { void x() { this->x(); } };",
callExpr(callee(memberExpr()))));
@@ -1992,6 +1999,13 @@ TEST(ConstructorDeclaration, IsImplicit) {
methodDecl(isImplicit(), hasName("operator="))));
}
+TEST(ConstructorDeclaration, IsExplicit) {
+ EXPECT_TRUE(matches("struct S { explicit S(int); };",
+ constructorDecl(isExplicit())));
+ EXPECT_TRUE(notMatches("struct S { S(int); };",
+ constructorDecl(isExplicit())));
+}
+
TEST(ConstructorDeclaration, Kinds) {
EXPECT_TRUE(matches("struct S { S(); };",
constructorDecl(isDefaultConstructor())));
OpenPOWER on IntegriCloud