diff options
author | Cong Liu <congliu@google.com> | 2016-06-24 09:38:03 +0000 |
---|---|---|
committer | Cong Liu <congliu@google.com> | 2016-06-24 09:38:03 +0000 |
commit | 85b4750b8d7cfecda65218124138d8254ffa3c46 (patch) | |
tree | 0e1d5d42174b639f97ffa10ea13357698bf0fd2e | |
parent | 17a752beb9a8c15a8667569bae759590264bcc91 (diff) |
IgnoringImplicit matcher.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273659 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/LibASTMatchersReference.html | 25 | ||||
-rwxr-xr-x[-rw-r--r--] | docs/tools/dump_ast_matchers.py | 0 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 26 | ||||
-rw-r--r-- | lib/ASTMatchers/Dynamic/Registry.cpp | 1 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTraversalTest.cpp | 10 |
5 files changed, 59 insertions, 3 deletions
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 3606367d2f..30af7e326a 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -2347,7 +2347,7 @@ Given private: int c; }; fieldDecl(isPrivate()) - matches 'int c;' + matches 'int c;' </pre></td></tr> @@ -2361,7 +2361,7 @@ Given private: int c; }; fieldDecl(isProtected()) - matches 'int b;' + matches 'int b;' </pre></td></tr> @@ -2375,7 +2375,7 @@ Given private: int c; }; fieldDecl(isPublic()) - matches 'int a;' + matches 'int a;' </pre></td></tr> @@ -4455,6 +4455,25 @@ only match the declarations for b, c, and d. </pre></td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('ignoringImplicit0')"><a name="ignoringImplicit0Anchor">ignoringImplicit</a></td><td>ast_matchers::Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="ignoringImplicit0"><pre>Matches expressions that match InnerMatcher after any implicit AST +nodes are stripped off. + +Parentheses and explicit casts are not discarded. +Given + class C {}; + C a = C(); + C b; + C c = b; +The matchers + varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr()))) +would match the declarations for a, b, and c. +While + varDecl(hasInitializer(cxxConstructExpr())) +only match the declarations for b and c. +</pre></td></tr> + + <tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('ignoringParenCasts0')"><a name="ignoringParenCasts0Anchor">ignoringParenCasts</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="ignoringParenCasts0"><pre>Matches expressions that match InnerMatcher after parentheses and casts are stripped off. diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py index 45540405de..45540405de 100644..100755 --- a/docs/tools/dump_ast_matchers.py +++ b/docs/tools/dump_ast_matchers.py diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 712eef0d3c..41080e98e8 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -548,6 +548,32 @@ AST_POLYMORPHIC_MATCHER_P( Builder); } +/// \brief Matches expressions that match InnerMatcher after any implicit AST +/// nodes are stripped off. +/// +/// Parentheses and explicit casts are not discarded. +/// Given +/// \code +/// class C {}; +/// C a = C(); +/// C b; +/// C c = b; +/// \endcode +/// The matchers +/// \code +/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr()))) +/// \endcode +/// would match the declarations for a, b, and c. +/// While +/// \code +/// varDecl(hasInitializer(cxxConstructExpr())) +/// \endcode +/// only match the declarations for b and c. +AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher<Expr>, + InnerMatcher) { + return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder); +} + /// \brief Matches expressions that match InnerMatcher after any implicit casts /// are stripped off. /// diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp index 4961da8925..1fe08581db 100644 --- a/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/lib/ASTMatchers/Dynamic/Registry.cpp @@ -265,6 +265,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(hasUnarySelector); REGISTER_MATCHER(hasValueType); REGISTER_MATCHER(ifStmt); + REGISTER_MATCHER(ignoringImplicit); REGISTER_MATCHER(ignoringImpCasts); REGISTER_MATCHER(ignoringParenCasts); REGISTER_MATCHER(ignoringParenImpCasts); diff --git a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index cc5cf715a7..a3f616967d 100644 --- a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1088,6 +1088,16 @@ TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) { unless(anything()))))); } +TEST(IgnoringImplicit, MatchesImplicit) { + EXPECT_TRUE(matches("class C {}; C a = C();", + varDecl(has(ignoringImplicit(cxxConstructExpr()))))); +} + +TEST(IgnoringImplicit, DoesNotMatchIncorrectly) { + EXPECT_TRUE( + notMatches("class C {}; C a = C();", varDecl(has(cxxConstructExpr())))); +} + TEST(IgnoringImpCasts, MatchesImpCasts) { // This test checks that ignoringImpCasts matches when implicit casts are // present and its inner matcher alone does not match. |