diff options
| author | Daniel Jasper <djasper@google.com> | 2015-02-04 13:11:42 +0000 |
|---|---|---|
| committer | Daniel Jasper <djasper@google.com> | 2015-02-04 13:11:42 +0000 |
| commit | 1d8ecbdffce64bef87723535b3c4a439340e9d8e (patch) | |
| tree | c4e2e6f269c930806c67b5feaf18d4d14549489f /clang | |
| parent | 42fa73cef0a974bb98fcd341a94cc3286a593a58 (diff) | |
| download | bcm5719-llvm-1d8ecbdffce64bef87723535b3c4a439340e9d8e.tar.gz bcm5719-llvm-1d8ecbdffce64bef87723535b3c4a439340e9d8e.zip | |
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};
llvm-svn: 228138
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 7 | ||||
| -rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 4 |
2 files changed, 11 insertions, 0 deletions
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index a1d36180d73..3db0eb79e68 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2039,6 +2039,13 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { 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; } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index 9cc011d3a6a..7325e065039 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -3144,6 +3144,10 @@ TEST(InitListExpression, MatchesInitListExpression) { 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) { |

