Let RecursiveASTVisitor visit array index VarDecls

An implicit copy ctor creates loop VarDecls that hang off CXXCtorInitializer.
RecursiveASTVisitor used to not visit them, so that they didn't show up in the
parent map used by ASTMatchers, causing asserts() when the implicit
DeclRefExpr() in a CXXCtorInitializer referred to one of these VarDecls.

Fixes PR26227.
http://reviews.llvm.org/D16413

llvm-svn: 258503
This commit is contained in:
Nico Weber 2016-01-22 15:11:54 +00:00
parent 0ff939f251
commit c4acee3380
3 changed files with 31 additions and 0 deletions

View File

@ -809,6 +809,10 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
TRY_TO(TraverseStmt(Init->getInit()));
if (Init->getNumArrayIndices() && getDerived().shouldVisitImplicitCode())
for (VarDecl *VD : Init->getArrayIndexes())
TRY_TO(TraverseDecl(VD));
return true;
}

View File

@ -4217,6 +4217,14 @@ TEST(HasAncestor, MatchesAllAncestors) {
hasAncestor(cxxRecordDecl(unless(isTemplateInstantiation())))))));
}
TEST(HasAncestor, ImplicitArrayCopyCtorDeclRefExpr) {
EXPECT_TRUE(matches("struct MyClass {\n"
" int c[1];\n"
" static MyClass Create() { return MyClass(); }\n"
"};",
declRefExpr(to(decl(hasAncestor(decl()))))));
}
TEST(HasParent, MatchesAllParents) {
EXPECT_TRUE(matches(
"template <typename T> struct C { static void f() { 42; } };"

View File

@ -133,4 +133,23 @@ TEST(RecursiveASTVisitor, AttributesAreVisited) {
"};\n"));
}
// Check to ensure that VarDecls are visited.
class VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
public:
bool VisitVarDecl(VarDecl *VD) {
Match(VD->getNameAsString(), VD->getLocStart());
return true;
}
};
TEST(RecursiveASTVisitor, ArrayInitializersAreVisited) {
VarDeclVisitor Visitor;
Visitor.ExpectMatch("__i0", 1, 8);
EXPECT_TRUE(
Visitor.runOver("struct MyClass {\n"
" int c[1];\n"
" static MyClass Create() { return MyClass(); }\n"
"};\n"));
}
} // end anonymous namespace