diff options
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 8 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.cpp | 6 | ||||
-rw-r--r-- | unittests/Tooling/RecursiveASTVisitorTest.cpp | 25 | ||||
-rw-r--r-- | unittests/Tooling/TestVisitor.h | 6 |
4 files changed, 43 insertions, 2 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index ac7795f933..acba46dcd7 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1776,6 +1776,14 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { // including exception specifications. if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) { TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); + } else if (getDerived().shouldVisitImplicitCode()) { + // Visit parameter variable declarations of the implicit function + // if the traverser is visiting implicit code. Parameter variable + // declarations do not have valid TypeSourceInfo, so to visit them + // we need to traverse the declarations explicitly. + for (FunctionDecl::param_const_iterator I = D->param_begin(), + E = D->param_end(); I != E; ++I) + TRY_TO(TraverseDecl(*I)); } if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 4994192bda..556b0b896e 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1361,8 +1361,12 @@ TEST(Matcher, References) { ReferenceClassX)); EXPECT_TRUE( matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX)); + // The match here is on the implicit copy constructor code for + // class X, not on code 'X x = y'. EXPECT_TRUE( - notMatches("class X {}; void y(X y) { X x = y; }", ReferenceClassX)); + matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX)); + EXPECT_TRUE( + notMatches("class X {}; extern X x;", ReferenceClassX)); EXPECT_TRUE( notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX)); } diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp index b1d6f4a37c..b3a8915a59 100644 --- a/unittests/Tooling/RecursiveASTVisitorTest.cpp +++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -37,6 +37,17 @@ public: } }; +class ParmVarDeclVisitorForImplicitCode : + public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> { +public: + bool shouldVisitImplicitCode() const { return true; } + + bool VisitParmVarDecl(ParmVarDecl *ParamVar) { + Match(ParamVar->getNameAsString(), ParamVar->getLocStart()); + return true; + } +}; + class CXXMemberCallVisitor : public ExpectedLocationVisitor<CXXMemberCallVisitor> { public: @@ -144,6 +155,20 @@ public: } }; +// Test RAV visits parameter variable declaration of the implicit +// copy assignment operator. +TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) { + ParmVarDeclVisitorForImplicitCode Visitor; + // Match parameter variable name of implicit copy assignment operator. + // This parameter name does not have a valid IdentifierInfo, and shares + // same SourceLocation with its class declaration, so we match an empty name + // with the class' source location. + Visitor.ExpectMatch("", 1, 7); + EXPECT_TRUE(Visitor.runOver( + "class X {};\n" + "void foo(X a, X b) {a = b;}")); +} + TEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) { TypeLocVisitor Visitor; Visitor.ExpectMatch("class X", 1, 30); diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h index 5ee118ebdc..ec751c350e 100644 --- a/unittests/Tooling/TestVisitor.h +++ b/unittests/Tooling/TestVisitor.h @@ -31,7 +31,7 @@ namespace clang { /// This is a drop-in replacement for RecursiveASTVisitor itself, with the /// additional capability of running it over a snippet of code. /// -/// Visits template instantiations (but not implicit code) by default. +/// Visits template instantiations and implicit code by default. template <typename T> class TestVisitor : public RecursiveASTVisitor<T> { public: @@ -56,6 +56,10 @@ public: return true; } + bool shouldVisitImplicitCode() const { + return true; + } + protected: virtual ASTFrontendAction* CreateTestAction() { return new TestAction(this); |