[clang] 0a57d14 - [ASTMatchers] Fix parent traversal with InitListExpr

Stephen Kelly via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 27 03:20:09 PST 2020


Author: Stephen Kelly
Date: 2020-01-27T11:19:59Z
New Revision: 0a57d14abf993331111fbfab15fb918a863aa391

URL: https://github.com/llvm/llvm-project/commit/0a57d14abf993331111fbfab15fb918a863aa391
DIFF: https://github.com/llvm/llvm-project/commit/0a57d14abf993331111fbfab15fb918a863aa391.diff

LOG: [ASTMatchers] Fix parent traversal with InitListExpr

Children of InitListExpr are traversed twice by RAV, so this code
populates a vector to represent the possibly-multiple parents (in
reality in this situation the parent is the same and is therefore
de-duplicated).

Added: 
    

Modified: 
    clang/lib/AST/ParentMapContext.cpp
    clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp
index 6a22e687ff57..e74e9909a606 100644
--- a/clang/lib/AST/ParentMapContext.cpp
+++ b/clang/lib/AST/ParentMapContext.cpp
@@ -133,8 +133,8 @@ class ParentMapContext::ParentMap {
     return getDynNodeFromMap(Node, OtherParents);
   }
 
-  ast_type_traits::DynTypedNode
-  AscendIgnoreUnlessSpelledInSource(const Expr *E, const Expr *Child) {
+  DynTypedNodeList AscendIgnoreUnlessSpelledInSource(const Expr *E,
+                                                     const Expr *Child) {
 
     auto ShouldSkip = [](const Expr *E, const Expr *Child) {
       if (isa<ImplicitCastExpr>(E))
@@ -179,8 +179,11 @@ class ParentMapContext::ParentMap {
       if (It == PointerParents.end())
         break;
       const auto *S = It->second.dyn_cast<const Stmt *>();
-      if (!S)
+      if (!S) {
+        if (auto *Vec = It->second.dyn_cast<ParentVector *>())
+          return llvm::makeArrayRef(*Vec);
         return getSingleDynTypedNodeFromParentMap(It->second);
+      }
       const auto *P = dyn_cast<Expr>(S);
       if (!P)
         return ast_type_traits::DynTypedNode::create(*S);

diff  --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 2143bb4965bb..b1f070bd8411 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1744,6 +1744,16 @@ void foo()
       Code,
       traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
                integerLiteral(equals(3), hasParent(varDecl(hasName("i")))))));
+
+  Code = R"cpp(
+const char *SomeString{"str"};
+)cpp";
+  EXPECT_TRUE(matches(Code, traverse(ast_type_traits::TK_AsIs,
+                                     stringLiteral(hasParent(implicitCastExpr(
+                                         hasParent(initListExpr())))))));
+  EXPECT_TRUE(
+      matches(Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+                             stringLiteral(hasParent(initListExpr())))));
 }
 
 template <typename MatcherT>


        


More information about the cfe-commits mailing list