njames93 updated this revision to Diff 325776.
njames93 marked an inline comment as done.
njames93 added a comment.

Address comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97246/new/

https://reviews.llvm.org/D97246

Files:
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/include/clang/ASTMatchers/ASTMatchersInternal.h
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===================================================================
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -3276,6 +3276,18 @@
                      hasExplicitSpecifier(callExpr(has(declRefExpr()))))),
         true, {"-std=c++20"}));
   }
+  Code = R"cpp(
+    struct Foo{
+      int A = 4, B;
+      Foo() : B(5) {}
+    };
+  )cpp";
+  {
+    auto M =
+        cxxConstructorDecl(hasAnyConstructorInitializer(cxxCtorInitializer()));
+    EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M)));
+    EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M)));
+  }
 }
 
 template <typename MatcherT>
Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -792,6 +792,12 @@
   return End;
 }
 
+inline bool isSpelledInSource(const Decl *Node) { return !Node->isImplicit(); }
+
+inline bool isSpelledInSource(const CXXCtorInitializer *Node) {
+  return Node->isWritten();
+}
+
 /// Finds the first node in a pointer range that matches the given
 /// matcher.
 template <typename MatcherT, typename IteratorT>
@@ -808,6 +814,26 @@
   return End;
 }
 
+/// Finds the first node in a pointer range that matches the given
+/// matcher. Ignores any nodes that aren't spelled in source if Finder is
+/// ignoring implicit nodes.
+template <typename MatcherT, typename IteratorT>
+IteratorT matchesFirstInPointerRangeIgnoreUnspelled(
+    const MatcherT &Matcher, IteratorT Start, IteratorT End,
+    ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) {
+  bool IgnoreIsSpelledInSource = Finder->isTraversalIgnoringImplicitNodes();
+  for (IteratorT I = Start; I != End; ++I) {
+    if (IgnoreIsSpelledInSource && !isSpelledInSource(*I))
+      continue;
+    BoundNodesTreeBuilder Result(*Builder);
+    if (Matcher.matches(**I, Finder, &Result)) {
+      *Builder = std::move(Result);
+      return I;
+    }
+  }
+  return End;
+}
+
 template <typename T, std::enable_if_t<!std::is_base_of<FunctionDecl, T>::value>
                           * = nullptr>
 inline bool isDefaultedHelper(const T *) {
Index: clang/include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- clang/include/clang/ASTMatchers/ASTMatchers.h
+++ clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -3293,13 +3293,10 @@
 AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
               InnerMatcher) {
   BoundNodesTreeBuilder Result(*Builder);
-  auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
-                                            Node.method_end(), Finder, &Result);
+  auto MatchIt = matchesFirstInPointerRangeIgnoreUnspelled(
+      InnerMatcher, Node.method_begin(), Node.method_end(), Finder, &Result);
   if (MatchIt == Node.method_end())
     return false;
-
-  if (Finder->isTraversalIgnoringImplicitNodes() && (*MatchIt)->isImplicit())
-    return false;
   *Builder = std::move(Result);
   return true;
 }
@@ -4358,11 +4355,9 @@
 ///   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
 AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
               internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
-  auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
-                                            Node.init_end(), Finder, Builder);
-  if (MatchIt == Node.init_end())
-    return false;
-  return (*MatchIt)->isWritten() || !Finder->isTraversalIgnoringImplicitNodes();
+  const auto *MatchIt = matchesFirstInPointerRangeIgnoreUnspelled(
+      InnerMatcher, Node.init_begin(), Node.init_end(), Finder, Builder);
+  return MatchIt != Node.init_end();
 }
 
 /// Matches the field declaration of a constructor initializer.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to