Update patch based on comments from Richard. Hi klimek, rsmith,
http://llvm-reviews.chandlerc.com/D958 CHANGE SINCE LAST DIFF http://llvm-reviews.chandlerc.com/D958?vs=4045&id=4182#toc Files: unittests/Tooling/RecursiveASTVisitorTest.cpp unittests/Tooling/TestVisitor.h unittests/ASTMatchers/ASTMatchersTest.cpp include/clang/AST/RecursiveASTVisitor.h Index: unittests/Tooling/RecursiveASTVisitorTest.cpp =================================================================== --- unittests/Tooling/RecursiveASTVisitorTest.cpp +++ unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -37,6 +37,17 @@ } }; +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 @@ } }; +// Test RAV visits parameter variable declaration of 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 class source location here. + 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); Index: unittests/Tooling/TestVisitor.h =================================================================== --- unittests/Tooling/TestVisitor.h +++ unittests/Tooling/TestVisitor.h @@ -31,7 +31,7 @@ /// 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 @@ return true; } + bool shouldVisitImplicitCode() const { + return true; + } + protected: virtual ASTFrontendAction* CreateTestAction() { return new TestAction(this); Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1361,9 +1361,13 @@ 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)); } Index: include/clang/AST/RecursiveASTVisitor.h =================================================================== --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -1776,6 +1776,14 @@ // 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)) {
Index: unittests/Tooling/RecursiveASTVisitorTest.cpp =================================================================== --- unittests/Tooling/RecursiveASTVisitorTest.cpp +++ unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -37,6 +37,17 @@ } }; +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 @@ } }; +// Test RAV visits parameter variable declaration of 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 class source location here. + 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); Index: unittests/Tooling/TestVisitor.h =================================================================== --- unittests/Tooling/TestVisitor.h +++ unittests/Tooling/TestVisitor.h @@ -31,7 +31,7 @@ /// 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 @@ return true; } + bool shouldVisitImplicitCode() const { + return true; + } + protected: virtual ASTFrontendAction* CreateTestAction() { return new TestAction(this); Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -1361,9 +1361,13 @@ 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)); } Index: include/clang/AST/RecursiveASTVisitor.h =================================================================== --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -1776,6 +1776,14 @@ // 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)) {
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits