diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2015-08-11 21:09:52 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2015-08-11 21:09:52 +0000 |
commit | 6f6d0b6c5a37a42f17591e37a30c911ec1c52898 (patch) | |
tree | a457a591951a63edbd746ac32a1e420dc0b63f92 | |
parent | da06bce8b50d47ca841d694e10c12638157b2093 (diff) | |
download | bcm5719-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.html | 26 | ||||
-rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 21 | ||||
-rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 14 |
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<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConversionDecl.html">CXXConversionDecl</a>></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<<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>></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()))); |