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
This commit is contained in:
Daniel Jasper 2015-02-04 13:11:42 +00:00
parent 42fa73cef0
commit 1d8ecbdffc
2 changed files with 11 additions and 0 deletions

View File

@ -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;
}

View File

@ -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) {