RecursiveASTVisitorTest.cpp revision 82b4550fb25ad578b6c8143b87a003fae7106cae
1e002631101d3bafbc90ed8589ffc615f04dc245bDavid Blaikie//===- unittest/Tooling/RecursiveASTVisitorTest.cpp -----------------------===// 2fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// 3fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// The LLVM Compiler Infrastructure 4fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// 5fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// This file is distributed under the University of Illinois Open Source 6fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// License. See LICENSE.TXT for details. 7fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek// 8fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek//===----------------------------------------------------------------------===// 9fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 10bc9e5582467e70ec38b9fc5d3605152e86e2a5f8Richard Smith#include "TestVisitor.h" 11fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 12fad7f85553da052559077f28c6937a8dd704b28dManuel Klimeknamespace clang { 13fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 14fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> { 15fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic: 16fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek bool VisitTypeLoc(TypeLoc TypeLocation) { 17fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc()); 18fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek return true; 19fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek } 20fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}; 21fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 22fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> { 23fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic: 24fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek bool VisitDeclRefExpr(DeclRefExpr *Reference) { 25fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); 26fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek return true; 27fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek } 28fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}; 29fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 3052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasperclass VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> { 3152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasperpublic: 3252ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper bool VisitVarDecl(VarDecl *Variable) { 3352ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper Match(Variable->getNameAsString(), Variable->getLocStart()); 3452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper return true; 3552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper } 3652ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper}; 3752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper 38fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass CXXMemberCallVisitor 39fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek : public ExpectedLocationVisitor<CXXMemberCallVisitor> { 40fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic: 41fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) { 42fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Match(Call->getMethodDecl()->getQualifiedNameAsString(), 43fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Call->getLocStart()); 44fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek return true; 45fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek } 46fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}; 47fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 48a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smithclass NamedDeclVisitor 49a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith : public ExpectedLocationVisitor<NamedDeclVisitor> { 50a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smithpublic: 51a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith bool VisitNamedDecl(NamedDecl *Decl) { 52a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith std::string NameWithTemplateArgs; 53a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Decl->getNameForDiagnostic(NameWithTemplateArgs, 54a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Decl->getASTContext().getPrintingPolicy(), 55a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith true); 56a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Match(NameWithTemplateArgs, Decl->getLocation()); 57a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith return true; 58a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith } 59a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}; 60a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 61c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithclass CXXOperatorCallExprTraverser 62c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> { 63c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithpublic: 64c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith // Use Traverse, not Visit, to check that data recursion optimization isn't 65c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith // bypassing the call of this function. 66c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { 67c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc()); 68c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>:: 69c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith TraverseCXXOperatorCallExpr(CE); 70c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith } 71c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith}; 72c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 73c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithclass ParenExprVisitor : public ExpectedLocationVisitor<ParenExprVisitor> { 74c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithpublic: 75c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith bool VisitParenExpr(ParenExpr *Parens) { 76c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Match("", Parens->getExprLoc()); 77c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith return true; 78c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith } 79c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith}; 80c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 816fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithclass TemplateArgumentLocTraverser 826fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith : public ExpectedLocationVisitor<TemplateArgumentLocTraverser> { 836fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithpublic: 846fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { 856fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith std::string ArgStr; 866fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith llvm::raw_string_ostream Stream(ArgStr); 876fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith const TemplateArgument &Arg = ArgLoc.getArgument(); 886fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 896fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Arg.print(Context->getPrintingPolicy(), Stream); 906fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Match(Stream.str(), ArgLoc.getLocation()); 916fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith return ExpectedLocationVisitor<TemplateArgumentLocTraverser>:: 926fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith TraverseTemplateArgumentLoc(ArgLoc); 936fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith } 946fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}; 956fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 966fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithclass CXXBoolLiteralExprVisitor 976fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith : public ExpectedLocationVisitor<CXXBoolLiteralExprVisitor> { 986fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithpublic: 996fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) { 1006fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith if (BE->getValue()) 1016fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Match("true", BE->getLocation()); 1026fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith else 1036fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Match("false", BE->getLocation()); 1046fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith return true; 1056fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith } 1066fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}; 1076fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 108fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) { 109fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek TypeLocVisitor Visitor; 110fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("class X", 1, 30); 111fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver("class X {}; class Y : public X {};")); 112fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 113fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 1149f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) { 1159f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek TypeLocVisitor Visitor; 1169f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek Visitor.ExpectMatch("class X", 3, 18); 1179f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek EXPECT_TRUE(Visitor.runOver( 1189f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y;\n" 1199f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class X {};\n" 1209f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y : public X {};")); 1219f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek} 1229f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek 1239f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) { 1249f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek TypeLocVisitor Visitor; 1259f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek Visitor.ExpectMatch("class X", 2, 18); 1269f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek EXPECT_TRUE(Visitor.runOver( 1279f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class X {};\n" 1289f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y : public X { class Z; };")); 1299f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek} 1309f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek 1319f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) { 1329f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek TypeLocVisitor Visitor; 1339f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek Visitor.ExpectMatch("X<class Y>", 2, 18); 1349f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek EXPECT_TRUE(Visitor.runOver( 1359f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "template<typename T> class X {};\n" 1369f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y : public X<Y> {};")); 1379f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek} 1389f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek 139fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { 140fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek DeclRefExprVisitor Visitor; 141fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("x", 2, 3); 142fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 143fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void x(); template <void (*T)()> class X {};\nX<x> y;")); 144fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 145fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 14652ec0c0357ce970ca52a27c1086626450f0967e7Daniel JasperTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) { 14752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper DeclRefExprVisitor Visitor; 14852ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper Visitor.ExpectMatch("x", 2, 25); 1491071ba9c324d831b437870a1fe63bf2ecdc4e9e4Daniel Jasper Visitor.ExpectMatch("x", 2, 30); 15052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper EXPECT_TRUE(Visitor.runOver( 15152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper "int x[5];\n" 1521071ba9c324d831b437870a1fe63bf2ecdc4e9e4Daniel Jasper "void f() { for (int i : x) { x[0] = 1; } }")); 15352ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper} 15452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper 15552ec0c0357ce970ca52a27c1086626450f0967e7Daniel JasperTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) { 15652ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper VarDeclVisitor Visitor; 15752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper Visitor.ExpectMatch("i", 2, 17); 15852ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper EXPECT_TRUE(Visitor.runOver( 15952ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper "int x[5];\n" 16052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper "void f() { for (int i : x) {} }")); 16152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper} 16252ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper 163fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsCallExpr) { 164fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek DeclRefExprVisitor Visitor; 165fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("x", 1, 22); 166fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 167fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void x(); void y() { x(); }")); 168fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 169fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 170fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) { 171fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek CXXMemberCallVisitor Visitor; 172fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("Y::x", 3, 3); 173fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 174fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "struct Y { void x(); };\n" 175fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template<typename T> void y(T t) {\n" 176fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " t.x();\n" 177fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "}\n" 178fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void foo() { y<Y>(Y()); }")); 179fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 180fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 1815482dc3a88fce51307b5e1e19bdf72dea1562040Richard SmithTEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) { 182fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek CXXMemberCallVisitor Visitor; 183fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("Y::x", 4, 5); 184fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 185fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "struct Y { void x(); };\n" 186fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template<typename T> struct Z {\n" 187fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " template<typename U> static void f() {\n" 188fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " T().x();\n" 189fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " }\n" 190fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "};\n" 191fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void foo() { Z<Y>::f<int>(); }")); 192fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 1935482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith 1945482dc3a88fce51307b5e1e19bdf72dea1562040Richard SmithTEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) { 1955482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith CXXMemberCallVisitor Visitor; 1965482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith Visitor.ExpectMatch("A::x", 5, 7); 1975482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith EXPECT_TRUE(Visitor.runOver( 1985482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "template <typename T1> struct X {\n" 1995482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " template <typename T2> struct Y {\n" 2005482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " void f() {\n" 2015482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " T2 y;\n" 2025482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " y.x();\n" 2035482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " }\n" 2045482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " };\n" 2055482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "};\n" 2065482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "struct A { void x(); };\n" 2075482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "int main() {\n" 2085482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " (new X<A>::Y<A>())->f();\n" 2095482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "}")); 2105482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith} 211fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 212fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek/* FIXME: According to Richard Smith this is a bug in the AST. 213fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { 214fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek DeclRefExprVisitor Visitor; 215fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("x", 3, 43); 216fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 217fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template <typename T> void x();\n" 218fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template <void (*T)()> class X {};\n" 219fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template <typename T> class Y : public X< x<T> > {};\n" 220fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "Y<int> y;")); 221fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 222fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek*/ 223fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 224a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) { 225a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith CXXMemberCallVisitor Visitor; 226a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A::x", 6, 20); 227a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 228a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <typename T1> struct X {\n" 229a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template <typename T2, bool B> struct Y { void g(); };\n" 230a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 231a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <typename T1> template <typename T2>\n" 232a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "struct X<T1>::Y<T2, true> {\n" 233a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " void f() { T2 y; y.x(); }\n" 234a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 235a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "struct A { void x(); };\n" 236a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "int main() {\n" 237a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " (new X<A>::Y<A, true>())->f();\n" 238a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "}\n")); 239a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 240a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 24106cd51a83577019ea26661b7d570ae9aef06f674Richard SmithTEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) { 24206cd51a83577019ea26661b7d570ae9aef06f674Richard Smith CXXMemberCallVisitor Visitor; 24306cd51a83577019ea26661b7d570ae9aef06f674Richard Smith Visitor.ExpectMatch("A::f", 4, 5); 24406cd51a83577019ea26661b7d570ae9aef06f674Richard Smith EXPECT_TRUE(Visitor.runOver( 24506cd51a83577019ea26661b7d570ae9aef06f674Richard Smith "struct A {\n" 24606cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " void f() const {}\n" 24706cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " template<class T> void g(const T& t) const {\n" 24806cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " t.f();\n" 24906cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " }\n" 25006cd51a83577019ea26661b7d570ae9aef06f674Richard Smith "};\n" 25106cd51a83577019ea26661b7d570ae9aef06f674Richard Smith "template void A::g(const A& a) const;\n")); 25206cd51a83577019ea26661b7d570ae9aef06f674Richard Smith} 25306cd51a83577019ea26661b7d570ae9aef06f674Richard Smith 254a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) { 255a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // From cfe-commits/Week-of-Mon-20100830/033998.html 256e966beaa6ef3eb7ced09203f748e6042f81b2a6cDaniel Jasper // Contrary to the approach suggested in that email, we visit all 257a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // specializations when we visit the primary template. Visiting them when we 258a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // visit the associated specialization is problematic for specializations of 259a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // template members of class templates. 260a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 261a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<bool>", 1, 26); 262a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<char *>", 2, 26); 263a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 264a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <class T> class A {};\n" 265a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <class T> class A<T*> {};\n" 266a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<bool> ab;\n" 267a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<char*> acp;\n")); 268a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 269a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 270a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) { 271a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 272a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>", 1, 29); 273a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 274a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> struct A;\n" 275a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<int> *p;\n")); 276a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 277a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 278a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) { 279a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 280a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>::B<char>", 2, 31); 281a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 282a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> struct A {\n" 283a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template<typename U> struct B;\n" 284a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 285a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<int>::B<char> *p;\n")); 286a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 287a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 288a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) { 289a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 290a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>", 1, 26); 291a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 292a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> int A();\n" 293a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "int k = A<int>();\n")); 294a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 295a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 296a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) { 297a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 298a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>::B<char>", 2, 35); 299a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 300a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> struct A {\n" 301a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template<typename U> static int B();\n" 302a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 303a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "int k = A<int>::B<char>();\n")); 304a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 305a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 306a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, NoRecursionInSelfFriend) { 307a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // From cfe-commits/Week-of-Mon-20100830/033977.html 308a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 309a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("vector_iterator<int>", 2, 7); 310a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 311a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename Container>\n" 312a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "class vector_iterator {\n" 313a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template <typename C> friend class vector_iterator;\n" 314a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 315a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "vector_iterator<int> it_int;\n")); 316a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 317a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 318c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard SmithTEST(RecursiveASTVisitor, TraversesOverloadedOperator) { 319c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith CXXOperatorCallExprTraverser Visitor; 320c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Visitor.ExpectMatch("()", 4, 9); 321c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith EXPECT_TRUE(Visitor.runOver( 322c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith "struct A {\n" 323c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith " int operator()();\n" 324c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith "} a;\n" 325c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith "int k = a();\n")); 326c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith} 327c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 328c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard SmithTEST(RecursiveASTVisitor, VisitsParensDuringDataRecursion) { 329c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith ParenExprVisitor Visitor; 330c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Visitor.ExpectMatch("", 1, 9); 331c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith EXPECT_TRUE(Visitor.runOver("int k = (4) + 9;\n")); 332c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith} 333c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 3346fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateNonTypeParmDefaultArgument) { 3356fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith CXXBoolLiteralExprVisitor Visitor; 3366fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Visitor.ExpectMatch("true", 2, 19); 3376fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith EXPECT_TRUE(Visitor.runOver( 3386fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<bool B> class X;\n" 3396fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<bool B = true> class Y;\n" 3406fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<bool B> class Y {};\n")); 3416fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith} 3426fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 3436fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) { 3446fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith TypeLocVisitor Visitor; 3456fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Visitor.ExpectMatch("class X", 2, 23); 3466fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith EXPECT_TRUE(Visitor.runOver( 3476fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "class X;\n" 3486fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<typename T = X> class Y;\n" 3496fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<typename T> class Y {};\n")); 3506fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith} 3516fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 3526fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateTemplateParmDefaultArgument) { 3536fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith TemplateArgumentLocTraverser Visitor; 3546fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Visitor.ExpectMatch("X", 2, 40); 3556fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith EXPECT_TRUE(Visitor.runOver( 3566fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<typename T> class X;\n" 3576fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<template <typename> class T = X> class Y;\n" 3586fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<template <typename> class T> class Y {};\n")); 3596fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith} 3606fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 361c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith// A visitor that visits implicit declarations and matches constructors. 362c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smithclass ImplicitCtorVisitor 363c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith : public ExpectedLocationVisitor<ImplicitCtorVisitor> { 364c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smithpublic: 36552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper bool shouldVisitImplicitCode() const { return true; } 366c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith 367c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) { 368c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith if (Ctor->isImplicit()) { // Was not written in source code 369c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith if (const CXXRecordDecl* Class = Ctor->getParent()) { 370c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith Match(Class->getName(), Ctor->getLocation()); 371c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith } 372c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith } 373c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith return true; 374c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith } 375c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith}; 376c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith 377c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard SmithTEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) { 378c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith ImplicitCtorVisitor Visitor; 379c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith Visitor.ExpectMatch("Simple", 2, 8); 380c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith // Note: Clang lazily instantiates implicit declarations, so we need 381c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith // to use them in order to force them to appear in the AST. 382c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith EXPECT_TRUE(Visitor.runOver( 383c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith "struct WithCtor { WithCtor(); }; \n" 384c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith "struct Simple { Simple(); WithCtor w; }; \n" 385c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith "int main() { Simple s; Simple t(s); }\n")); 386c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith} 387c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith 3880652c35a303a6186142eea566c88714c59bdc664Richard SmithTEST(RecursiveASTVisitor, VisitsExtension) { 3890652c35a303a6186142eea566c88714c59bdc664Richard Smith DeclRefExprVisitor Visitor; 3900652c35a303a6186142eea566c88714c59bdc664Richard Smith Visitor.ExpectMatch("s", 1, 24); 3910652c35a303a6186142eea566c88714c59bdc664Richard Smith EXPECT_TRUE(Visitor.runOver( 3920652c35a303a6186142eea566c88714c59bdc664Richard Smith "int s = __extension__ (s);\n")); 3930652c35a303a6186142eea566c88714c59bdc664Richard Smith} 3940652c35a303a6186142eea566c88714c59bdc664Richard Smith 39582b4550fb25ad578b6c8143b87a003fae7106caeRichard SmithTEST(RecursiveASTVisitor, VisitsCompoundLiteralType) { 39682b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith TypeLocVisitor Visitor; 39782b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith Visitor.ExpectMatch("struct S", 1, 26); 39882b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith EXPECT_TRUE(Visitor.runOver( 39982b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith "int f() { return (struct S { int a; }){.a = 0}.a; }", 40082b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith TypeLocVisitor::Lang_C)); 40182b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith} 40282b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith 403fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} // end namespace clang 404