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