Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -2347,7 +2347,7 @@ private: int c; }; fieldDecl(isPrivate()) - matches 'int c;' + matches 'int c;' @@ -2361,7 +2361,7 @@ private: int c; }; fieldDecl(isProtected()) - matches 'int b;' + matches 'int b;' @@ -2375,7 +2375,7 @@ private: int c; }; fieldDecl(isPublic()) - matches 'int a;' + matches 'int a;' @@ -4455,6 +4455,25 @@ +Matcher<Expr>ignoringImplicitast_matchers::Matcher<Expr> InnerMatcher +
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.
+
+ + Matcher<Expr>ignoringParenCastsMatcher<Expr> InnerMatcher
Matches expressions that match InnerMatcher after parentheses and
 casts are stripped off.
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -548,6 +548,32 @@
                              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,
+              InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
+}
+
 /// \brief Matches expressions that match InnerMatcher after any implicit casts
 /// are stripped off.
 ///
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -265,6 +265,7 @@
   REGISTER_MATCHER(hasUnarySelector);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringImplicit);
   REGISTER_MATCHER(ignoringImpCasts);
   REGISTER_MATCHER(ignoringParenCasts);
   REGISTER_MATCHER(ignoringParenImpCasts);
Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1088,6 +1088,16 @@
                            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.