summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2016-01-22 15:11:54 +0000
committerNico Weber <nicolasweber@gmx.de>2016-01-22 15:11:54 +0000
commitc4acee338097f7f2a6a70cdd38dc7eb1f97c040e (patch)
tree83dc24d9deaee4ab1af31446513c9b7dbed19ff9
parent0ff939f251ff18774050d3170697bf61dfbc4dba (diff)
downloadbcm5719-llvm-c4acee338097f7f2a6a70cdd38dc7eb1f97c040e.tar.gz
bcm5719-llvm-c4acee338097f7f2a6a70cdd38dc7eb1f97c040e.zip
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
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h4
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTest.cpp8
-rw-r--r--clang/unittests/Tooling/RecursiveASTVisitorTest.cpp19
3 files changed, 31 insertions, 0 deletions
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 725cf3bcea6..0b89a963e3e 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -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;
}
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index b6983052dd8..ab1997ab0f3 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -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; } };"
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 5d0e2bccd4d..991ae8bb7f3 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -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
OpenPOWER on IntegriCloud