Index: unittests/Tooling/CMakeLists.txt =================================================================== --- unittests/Tooling/CMakeLists.txt +++ unittests/Tooling/CMakeLists.txt @@ -7,6 +7,10 @@ CompilationDatabaseTest.cpp ToolingTest.cpp RecursiveASTVisitorTest.cpp + RecursiveASTVisitorTestCallVisitor.cpp + RecursiveASTVisitorTestDeclVisitor.cpp + RecursiveASTVisitorTestExprVisitor.cpp + RecursiveASTVisitorTestTypeLocVisitor.cpp RefactoringTest.cpp RewriterTest.cpp RefactoringCallbacksTest.cpp Index: unittests/Tooling/RecursiveASTVisitorTest.cpp =================================================================== --- unittests/Tooling/RecursiveASTVisitorTest.cpp +++ unittests/Tooling/RecursiveASTVisitorTest.cpp @@ -14,85 +14,6 @@ namespace { -class TypeLocVisitor : public ExpectedLocationVisitor { -public: - bool VisitTypeLoc(TypeLoc TypeLocation) { - Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc()); - return true; - } -}; - -class DeclRefExprVisitor : public ExpectedLocationVisitor { -public: - bool VisitDeclRefExpr(DeclRefExpr *Reference) { - Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); - return true; - } -}; - -class VarDeclVisitor : public ExpectedLocationVisitor { -public: - bool VisitVarDecl(VarDecl *Variable) { - Match(Variable->getNameAsString(), Variable->getLocStart()); - return true; - } -}; - -class ParmVarDeclVisitorForImplicitCode : - public ExpectedLocationVisitor { -public: - bool shouldVisitImplicitCode() const { return true; } - - bool VisitParmVarDecl(ParmVarDecl *ParamVar) { - Match(ParamVar->getNameAsString(), ParamVar->getLocStart()); - return true; - } -}; - -class CXXMemberCallVisitor - : public ExpectedLocationVisitor { -public: - bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) { - Match(Call->getMethodDecl()->getQualifiedNameAsString(), - Call->getLocStart()); - return true; - } -}; - -class NamedDeclVisitor - : public ExpectedLocationVisitor { -public: - bool VisitNamedDecl(NamedDecl *Decl) { - std::string NameWithTemplateArgs; - llvm::raw_string_ostream OS(NameWithTemplateArgs); - Decl->getNameForDiagnostic(OS, - Decl->getASTContext().getPrintingPolicy(), - true); - Match(OS.str(), Decl->getLocation()); - return true; - } -}; - -class CXXOperatorCallExprTraverser - : public ExpectedLocationVisitor { -public: - // Use Traverse, not Visit, to check that data recursion optimization isn't - // bypassing the call of this function. - bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { - Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc()); - return ExpectedLocationVisitor:: - TraverseCXXOperatorCallExpr(CE); - } -}; - -class ParenExprVisitor : public ExpectedLocationVisitor { -public: - bool VisitParenExpr(ParenExpr *Parens) { - Match("", Parens->getExprLoc()); - return true; - } -}; - class LambdaExprVisitor : public ExpectedLocationVisitor { public: bool VisitLambdaExpr(LambdaExpr *Lambda) { @@ -117,429 +38,6 @@ std::stack PendingBodies; }; -// Matches the (optional) capture-default of a lambda-introducer. -class LambdaDefaultCaptureVisitor - : public ExpectedLocationVisitor { -public: - bool VisitLambdaExpr(LambdaExpr *Lambda) { - if (Lambda->getCaptureDefault() != LCD_None) { - Match("", Lambda->getCaptureDefaultLoc()); - } - return true; - } -}; - -class TemplateArgumentLocTraverser - : public ExpectedLocationVisitor { -public: - bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { - std::string ArgStr; - llvm::raw_string_ostream Stream(ArgStr); - const TemplateArgument &Arg = ArgLoc.getArgument(); - - Arg.print(Context->getPrintingPolicy(), Stream); - Match(Stream.str(), ArgLoc.getLocation()); - return ExpectedLocationVisitor:: - TraverseTemplateArgumentLoc(ArgLoc); - } -}; - -class CXXBoolLiteralExprVisitor - : public ExpectedLocationVisitor { -public: - bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) { - if (BE->getValue()) - Match("true", BE->getLocation()); - else - Match("false", BE->getLocation()); - return true; - } -}; - -// Test RAV visits parameter variable declaration of the implicit -// copy assignment operator and implicit copy constructor. -TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) { - ParmVarDeclVisitorForImplicitCode Visitor; - // Match parameter variable name of implicit copy assignment operator and - // implicit copy constructor. - // 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); - Visitor.ExpectMatch("", 3, 7); - EXPECT_TRUE(Visitor.runOver( - "class X {};\n" - "void foo(X a, X b) {a = b;}\n" - "class Y {};\n" - "void bar(Y a) {Y b = a;}")); -} - -TEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) { - TypeLocVisitor Visitor; - Visitor.ExpectMatch("class X", 1, 30); - EXPECT_TRUE(Visitor.runOver("class X {}; class Y : public X {};")); -} - -TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) { - TypeLocVisitor Visitor; - Visitor.ExpectMatch("class X", 3, 18); - EXPECT_TRUE(Visitor.runOver( - "class Y;\n" - "class X {};\n" - "class Y : public X {};")); -} - -TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) { - TypeLocVisitor Visitor; - Visitor.ExpectMatch("class X", 2, 18); - EXPECT_TRUE(Visitor.runOver( - "class X {};\n" - "class Y : public X { class Z; };")); -} - -TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) { - TypeLocVisitor Visitor; - Visitor.ExpectMatch("X", 2, 18); - EXPECT_TRUE(Visitor.runOver( - "template class X {};\n" - "class Y : public X {};")); -} - -TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 2, 3); - EXPECT_TRUE(Visitor.runOver( - "void x(); template class X {};\nX y;")); -} - -TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 2, 25); - Visitor.ExpectMatch("x", 2, 30); - EXPECT_TRUE(Visitor.runOver( - "int x[5];\n" - "void f() { for (int i : x) { x[0] = 1; } }", - DeclRefExprVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) { - VarDeclVisitor Visitor; - Visitor.ExpectMatch("i", 2, 17); - EXPECT_TRUE(Visitor.runOver( - "int x[5];\n" - "void f() { for (int i : x) {} }", - VarDeclVisitor::Lang_CXX11)); -} - -TEST(RecursiveASTVisitor, VisitsCallExpr) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 1, 22); - EXPECT_TRUE(Visitor.runOver( - "void x(); void y() { x(); }")); -} - -TEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) { - CXXMemberCallVisitor Visitor; - Visitor.ExpectMatch("Y::x", 3, 3); - EXPECT_TRUE(Visitor.runOver( - "struct Y { void x(); };\n" - "template void y(T t) {\n" - " t.x();\n" - "}\n" - "void foo() { y(Y()); }")); -} - -TEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) { - CXXMemberCallVisitor Visitor; - Visitor.ExpectMatch("Y::x", 4, 5); - EXPECT_TRUE(Visitor.runOver( - "struct Y { void x(); };\n" - "template struct Z {\n" - " template static void f() {\n" - " T().x();\n" - " }\n" - "};\n" - "void foo() { Z::f(); }")); -} - -TEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) { - CXXMemberCallVisitor Visitor; - Visitor.ExpectMatch("A::x", 5, 7); - EXPECT_TRUE(Visitor.runOver( - "template struct X {\n" - " template struct Y {\n" - " void f() {\n" - " T2 y;\n" - " y.x();\n" - " }\n" - " };\n" - "};\n" - "struct A { void x(); };\n" - "int main() {\n" - " (new X::Y())->f();\n" - "}")); -} - -/* FIXME: According to Richard Smith this is a bug in the AST. -TEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { - DeclRefExprVisitor Visitor; - Visitor.ExpectMatch("x", 3, 43); - EXPECT_TRUE(Visitor.runOver( - "template void x();\n" - "template class X {};\n" - "template class Y : public X< x > {};\n" - "Y y;")); -} -*/ - -TEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) { - CXXMemberCallVisitor Visitor; - Visitor.ExpectMatch("A::x", 6, 20); - EXPECT_TRUE(Visitor.runOver( - "template struct X {\n" - " template struct Y { void g(); };\n" - "};\n" - "template template \n" - "struct X::Y {\n" - " void f() { T2 y; y.x(); }\n" - "};\n" - "struct A { void x(); };\n" - "int main() {\n" - " (new X::Y())->f();\n" - "}\n")); -} - -TEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) { - CXXMemberCallVisitor Visitor; - Visitor.ExpectMatch("A::f", 4, 5); - EXPECT_TRUE(Visitor.runOver( - "struct A {\n" - " void f() const {}\n" - " template void g(const T& t) const {\n" - " t.f();\n" - " }\n" - "};\n" - "template void A::g(const A& a) const;\n")); -} - -TEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) { - // From cfe-commits/Week-of-Mon-20100830/033998.html - // Contrary to the approach suggested in that email, we visit all - // specializations when we visit the primary template. Visiting them when we - // visit the associated specialization is problematic for specializations of - // template members of class templates. - NamedDeclVisitor Visitor; - Visitor.ExpectMatch("A", 1, 26); - Visitor.ExpectMatch("A", 2, 26); - EXPECT_TRUE(Visitor.runOver( - "template class A {};\n" - "template class A {};\n" - "A ab;\n" - "A acp;\n")); -} - -TEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) { - NamedDeclVisitor Visitor; - Visitor.ExpectMatch("A", 1, 29); - EXPECT_TRUE(Visitor.runOver( - "template struct A;\n" - "A *p;\n")); -} - -TEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) { - NamedDeclVisitor Visitor; - Visitor.ExpectMatch("A::B", 2, 31); - EXPECT_TRUE(Visitor.runOver( - "template struct A {\n" - " template struct B;\n" - "};\n" - "A::B *p;\n")); -} - -TEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) { - NamedDeclVisitor Visitor; - Visitor.ExpectMatch("A", 1, 26); - EXPECT_TRUE(Visitor.runOver( - "template int A();\n" - "int k = A();\n")); -} - -TEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) { - NamedDeclVisitor Visitor; - Visitor.ExpectMatch("A::B", 2, 35); - EXPECT_TRUE(Visitor.runOver( - "template struct A {\n" - " template static int B();\n" - "};\n" - "int k = A::B();\n")); -} - -TEST(RecursiveASTVisitor, NoRecursionInSelfFriend) { - // From cfe-commits/Week-of-Mon-20100830/033977.html - NamedDeclVisitor Visitor; - Visitor.ExpectMatch("vector_iterator", 2, 7); - EXPECT_TRUE(Visitor.runOver( - "template\n" - "class vector_iterator {\n" - " template friend class vector_iterator;\n" - "};\n" - "vector_iterator it_int;\n")); -} - -TEST(RecursiveASTVisitor, TraversesOverloadedOperator) { - CXXOperatorCallExprTraverser Visitor; - Visitor.ExpectMatch("()", 4, 9); - EXPECT_TRUE(Visitor.runOver( - "struct A {\n" - " int operator()();\n" - "} a;\n" - "int k = a();\n")); -} - -TEST(RecursiveASTVisitor, VisitsParensDuringDataRecursion) { - ParenExprVisitor Visitor; - Visitor.ExpectMatch("", 1, 9); - EXPECT_TRUE(Visitor.runOver("int k = (4) + 9;\n")); -} - -TEST(RecursiveASTVisitor, VisitsClassTemplateNonTypeParmDefaultArgument) { - CXXBoolLiteralExprVisitor Visitor; - Visitor.ExpectMatch("true", 2, 19); - EXPECT_TRUE(Visitor.runOver( - "template class X;\n" - "template class Y;\n" - "template class Y {};\n")); -} - -TEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) { - TypeLocVisitor Visitor; - Visitor.ExpectMatch("class X", 2, 23); - EXPECT_TRUE(Visitor.runOver( - "class X;\n" - "template class Y;\n" - "template class Y {};\n")); -} - -TEST(RecursiveASTVisitor, VisitsClassTemplateTemplateParmDefaultArgument) { - TemplateArgumentLocTraverser Visitor; - Visitor.ExpectMatch("X", 2, 40); - EXPECT_TRUE(Visitor.runOver( - "template class X;\n" - "template