r228138 - Let RecursiveASTVisitor walk both syntactic and semantic form of InitListExprs.

Daniel Jasper djasper at google.com
Wed Feb 4 05:11:43 PST 2015


Author: djasper
Date: Wed Feb  4 07:11:42 2015
New Revision: 228138

URL: http://llvm.org/viewvc/llvm-project?rev=228138&view=rev
Log:
Let RecursiveASTVisitor walk both syntactic and semantic form of InitListExprs.

Otherwise, this can lead to unexpected results when AST matching as
some nodes are only present in the semantic form.

For example, only looking at the syntactic form does not find the
DeclRefExpr to f() in:

  struct S { S(void (*a)()); };
  void f();
  S s[1] = {&f};

Modified:
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=228138&r1=228137&r2=228138&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Feb  4 07:11:42 2015
@@ -2039,6 +2039,13 @@ bool RecursiveASTVisitor<Derived>::Trave
   for (Stmt::child_range range = S->children(); range; ++range) {
     TRY_TO(TraverseStmt(*range));
   }
+  if (InitListExpr *Syn = S->getSemanticForm()) {
+    TRY_TO(WalkUpFromInitListExpr(Syn));
+    // All we need are the default actions.  FIXME: use a helper function.
+    for (Stmt::child_range range = Syn->children(); range; ++range) {
+      TRY_TO(TraverseStmt(*range));
+    }
+  }
   return true;
 }
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=228138&r1=228137&r2=228138&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Wed Feb  4 07:11:42 2015
@@ -3144,6 +3144,10 @@ TEST(InitListExpression, MatchesInitList
                       initListExpr(hasType(asString("int [2]")))));
   EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };",
                       initListExpr(hasType(recordDecl(hasName("B"))))));
+  EXPECT_TRUE(matches("struct S { S(void (*a)()); };"
+                      "void f();"
+                      "S s[1] = { &f };",
+                      declRefExpr(to(functionDecl(hasName("f"))))));
 }
 
 TEST(UsingDeclaration, MatchesUsingDeclarations) {





More information about the cfe-commits mailing list