Author: malcolm.parsons Date: Sat Dec 24 07:35:14 2016 New Revision: 290492
URL: http://llvm.org/viewvc/llvm-project?rev=290492&view=rev Log: [ASTMatchers] Add hasInClassInitializer traversal matcher for FieldDecl. Summary: I needed to know whether a FieldDecl had an in-class initializer for D26453. I used a narrowing matcher there, but a traversal matcher might be generally useful. Reviewers: sbenza, bkramer, klimek, aaron.ballman Subscribers: aaron.ballman, Prazek, cfe-commits Differential Revision: https://reviews.llvm.org/D28034 Modified: cfe/trunk/docs/LibASTMatchersReference.html cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Modified: cfe/trunk/docs/LibASTMatchersReference.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=290492&r1=290491&r2=290492&view=diff ============================================================================== --- cfe/trunk/docs/LibASTMatchersReference.html (original) +++ cfe/trunk/docs/LibASTMatchersReference.html Sat Dec 24 07:35:14 2016 @@ -4751,6 +4751,22 @@ would only match the declaration for a. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>></td><td class="name" onclick="toggle('hasInClassInitializer0')"><a name="hasInClassInitializer0Anchor">hasInClassInitializer</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasInClassInitializer0"><pre>Matches non-static data members that have an in-class initializer. + +Given + class C { + int a = 2; + int b = 3; + int c; + }; +fieldDecl(hasInClassInitializer(integerLiteral(equals(2)))) + matches 'int a;' but not 'int b;'. +fieldDecl(hasInClassInitializer(anything())) + matches 'int a;' and 'int b;' but not 'int c;'. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasBody1')"><a name="hasBody1Anchor">hasBody</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasBody1"><pre>Matches a 'for', 'while', 'do while' statement or a function definition that has a given body. Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=290492&r1=290491&r2=290492&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sat Dec 24 07:35:14 2016 @@ -551,6 +551,27 @@ AST_MATCHER_P(FieldDecl, hasBitWidth, un Node.getBitWidthValue(Finder->getASTContext()) == Width; } +/// \brief Matches non-static data members that have an in-class initializer. +/// +/// Given +/// \code +/// class C { +/// int a = 2; +/// int b = 3; +/// int c; +/// }; +/// \endcode +/// fieldDecl(hasInClassInitializer(integerLiteral(equals(2)))) +/// matches 'int a;' but not 'int b;'. +/// fieldDecl(hasInClassInitializer(anything())) +/// matches 'int a;' and 'int b;' but not 'int c;'. +AST_MATCHER_P(FieldDecl, hasInClassInitializer, internal::Matcher<Expr>, + InnerMatcher) { + const Expr *Initializer = Node.getInClassInitializer(); + return (Initializer != nullptr && + InnerMatcher.matches(*Initializer, Finder, Builder)); +} + /// \brief Matches a declaration that has been implicitly added /// by the compiler (eg. implicit default/copy constructors). AST_MATCHER(Decl, isImplicit) { Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=290492&r1=290491&r2=290492&view=diff ============================================================================== --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original) +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Sat Dec 24 07:35:14 2016 @@ -232,6 +232,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasFalseExpression); REGISTER_MATCHER(hasGlobalStorage); REGISTER_MATCHER(hasImplicitDestinationType); + REGISTER_MATCHER(hasInClassInitializer); REGISTER_MATCHER(hasIncrement); REGISTER_MATCHER(hasIndex); REGISTER_MATCHER(hasInitializer); Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=290492&r1=290491&r2=290492&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp Sat Dec 24 07:35:14 2016 @@ -1404,6 +1404,16 @@ TEST(Member, BitFields) { fieldDecl(isBitField(), hasBitWidth(2), hasName("a")))); } +TEST(Member, InClassInitializer) { + EXPECT_TRUE( + matches("class C { int a = 2; int b; };", + fieldDecl(hasInClassInitializer(integerLiteral(equals(2))), + hasName("a")))); + EXPECT_TRUE( + notMatches("class C { int a = 2; int b; };", + fieldDecl(hasInClassInitializer(anything()), hasName("b")))); +} + TEST(Member, UnderstandsAccess) { EXPECT_TRUE(matches( "struct A { int i; };", fieldDecl(isPublic(), hasName("i")))); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits