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 1249007d7561212c0ae168702c1af1404c01ef43ffJames Dennett#include <stack> 1349007d7561212c0ae168702c1af1404c01ef43ffJames Dennett 14fad7f85553da052559077f28c6937a8dd704b28dManuel Klimeknamespace clang { 15fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 16fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> { 17fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic: 18fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek bool VisitTypeLoc(TypeLoc TypeLocation) { 19fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Match(TypeLocation.getType().getAsString(), TypeLocation.getBeginLoc()); 20fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek return true; 21fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek } 22fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}; 23fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 24fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass DeclRefExprVisitor : public ExpectedLocationVisitor<DeclRefExprVisitor> { 25fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic: 26fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek bool VisitDeclRefExpr(DeclRefExpr *Reference) { 27fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Match(Reference->getNameInfo().getAsString(), Reference->getLocation()); 28fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek return true; 29fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek } 30fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}; 31fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 3252ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasperclass VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> { 3352ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasperpublic: 3452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper bool VisitVarDecl(VarDecl *Variable) { 3552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper Match(Variable->getNameAsString(), Variable->getLocStart()); 3652ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper return true; 3752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper } 3852ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper}; 3952ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper 40fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekclass CXXMemberCallVisitor 41fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek : public ExpectedLocationVisitor<CXXMemberCallVisitor> { 42fad7f85553da052559077f28c6937a8dd704b28dManuel Klimekpublic: 43fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek bool VisitCXXMemberCallExpr(CXXMemberCallExpr *Call) { 44fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Match(Call->getMethodDecl()->getQualifiedNameAsString(), 45fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Call->getLocStart()); 46fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek return true; 47fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek } 48fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek}; 49fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 50a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smithclass NamedDeclVisitor 51a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith : public ExpectedLocationVisitor<NamedDeclVisitor> { 52a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smithpublic: 53a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith bool VisitNamedDecl(NamedDecl *Decl) { 54a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith std::string NameWithTemplateArgs; 555eada844fa70b6e2bc941dd7306f7a4fb1e8529dBenjamin Kramer llvm::raw_string_ostream OS(NameWithTemplateArgs); 565eada844fa70b6e2bc941dd7306f7a4fb1e8529dBenjamin Kramer Decl->getNameForDiagnostic(OS, 57a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Decl->getASTContext().getPrintingPolicy(), 58a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith true); 595eada844fa70b6e2bc941dd7306f7a4fb1e8529dBenjamin Kramer Match(OS.str(), Decl->getLocation()); 60a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith return true; 61a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith } 62a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith}; 63a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 64c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithclass CXXOperatorCallExprTraverser 65c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith : public ExpectedLocationVisitor<CXXOperatorCallExprTraverser> { 66c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithpublic: 67c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith // Use Traverse, not Visit, to check that data recursion optimization isn't 68c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith // bypassing the call of this function. 69c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *CE) { 70c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Match(getOperatorSpelling(CE->getOperator()), CE->getExprLoc()); 71c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith return ExpectedLocationVisitor<CXXOperatorCallExprTraverser>:: 72c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith TraverseCXXOperatorCallExpr(CE); 73c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith } 74c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith}; 75c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 76c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithclass ParenExprVisitor : public ExpectedLocationVisitor<ParenExprVisitor> { 77c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smithpublic: 78c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith bool VisitParenExpr(ParenExpr *Parens) { 79c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Match("", Parens->getExprLoc()); 80c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith return true; 81c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith } 82c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith}; 83c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 8489faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennettclass LambdaExprVisitor : public ExpectedLocationVisitor<LambdaExprVisitor> { 8589faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennettpublic: 8689faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett bool VisitLambdaExpr(LambdaExpr *Lambda) { 8749007d7561212c0ae168702c1af1404c01ef43ffJames Dennett PendingBodies.push(Lambda); 8889faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett Match("", Lambda->getIntroducerRange().getBegin()); 8989faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett return true; 9089faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett } 9149007d7561212c0ae168702c1af1404c01ef43ffJames Dennett /// For each call to VisitLambdaExpr, we expect a subsequent call (with 9249007d7561212c0ae168702c1af1404c01ef43ffJames Dennett /// proper nesting) to TraverseLambdaBody. 9349007d7561212c0ae168702c1af1404c01ef43ffJames Dennett bool TraverseLambdaBody(LambdaExpr *Lambda) { 9449007d7561212c0ae168702c1af1404c01ef43ffJames Dennett EXPECT_FALSE(PendingBodies.empty()); 9549007d7561212c0ae168702c1af1404c01ef43ffJames Dennett EXPECT_EQ(PendingBodies.top(), Lambda); 9649007d7561212c0ae168702c1af1404c01ef43ffJames Dennett PendingBodies.pop(); 9749007d7561212c0ae168702c1af1404c01ef43ffJames Dennett return TraverseStmt(Lambda->getBody()); 9849007d7561212c0ae168702c1af1404c01ef43ffJames Dennett } 9949007d7561212c0ae168702c1af1404c01ef43ffJames Dennett /// Determine whether TraverseLambdaBody has been called for every call to 10049007d7561212c0ae168702c1af1404c01ef43ffJames Dennett /// VisitLambdaExpr. 10149007d7561212c0ae168702c1af1404c01ef43ffJames Dennett bool allBodiesHaveBeenTraversed() const { 10249007d7561212c0ae168702c1af1404c01ef43ffJames Dennett return PendingBodies.empty(); 10349007d7561212c0ae168702c1af1404c01ef43ffJames Dennett } 10449007d7561212c0ae168702c1af1404c01ef43ffJames Dennettprivate: 10549007d7561212c0ae168702c1af1404c01ef43ffJames Dennett std::stack<LambdaExpr *> PendingBodies; 10689faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett}; 10789faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett 1086fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithclass TemplateArgumentLocTraverser 1096fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith : public ExpectedLocationVisitor<TemplateArgumentLocTraverser> { 1106fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithpublic: 1116fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { 1126fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith std::string ArgStr; 1136fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith llvm::raw_string_ostream Stream(ArgStr); 1146fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith const TemplateArgument &Arg = ArgLoc.getArgument(); 1156fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 1166fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Arg.print(Context->getPrintingPolicy(), Stream); 1176fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Match(Stream.str(), ArgLoc.getLocation()); 1186fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith return ExpectedLocationVisitor<TemplateArgumentLocTraverser>:: 1196fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith TraverseTemplateArgumentLoc(ArgLoc); 1206fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith } 1216fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}; 1226fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 1236fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithclass CXXBoolLiteralExprVisitor 1246fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith : public ExpectedLocationVisitor<CXXBoolLiteralExprVisitor> { 1256fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smithpublic: 1266fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith bool VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *BE) { 1276fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith if (BE->getValue()) 1286fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Match("true", BE->getLocation()); 1296fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith else 1306fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Match("false", BE->getLocation()); 1316fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith return true; 1326fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith } 1336fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith}; 1346fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 135fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) { 136fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek TypeLocVisitor Visitor; 137fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("class X", 1, 30); 138fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver("class X {}; class Y : public X {};")); 139fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 140fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 1419f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) { 1429f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek TypeLocVisitor Visitor; 1439f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek Visitor.ExpectMatch("class X", 3, 18); 1449f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek EXPECT_TRUE(Visitor.runOver( 1459f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y;\n" 1469f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class X {};\n" 1479f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y : public X {};")); 1489f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek} 1499f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek 1509f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) { 1519f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek TypeLocVisitor Visitor; 1529f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek Visitor.ExpectMatch("class X", 2, 18); 1539f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek EXPECT_TRUE(Visitor.runOver( 1549f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class X {};\n" 1559f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y : public X { class Z; };")); 1569f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek} 1579f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek 1589f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel KlimekTEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) { 1599f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek TypeLocVisitor Visitor; 1609f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek Visitor.ExpectMatch("X<class Y>", 2, 18); 1619f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek EXPECT_TRUE(Visitor.runOver( 1629f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "template<typename T> class X {};\n" 1639f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek "class Y : public X<Y> {};")); 1649f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek} 1659f99d06e0d22380b9d1f0609a083dbfbd8b37c10Manuel Klimek 166fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassTemplateArguments) { 167fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek DeclRefExprVisitor Visitor; 168fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("x", 2, 3); 169fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 170fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void x(); template <void (*T)()> class X {};\nX<x> y;")); 171fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 172fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 17352ec0c0357ce970ca52a27c1086626450f0967e7Daniel JasperTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtRange) { 17452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper DeclRefExprVisitor Visitor; 17552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper Visitor.ExpectMatch("x", 2, 25); 1761071ba9c324d831b437870a1fe63bf2ecdc4e9e4Daniel Jasper Visitor.ExpectMatch("x", 2, 30); 17752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper EXPECT_TRUE(Visitor.runOver( 17852ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper "int x[5];\n" 17989faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett "void f() { for (int i : x) { x[0] = 1; } }", 18089faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett DeclRefExprVisitor::Lang_CXX11)); 18152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper} 18252ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper 18352ec0c0357ce970ca52a27c1086626450f0967e7Daniel JasperTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) { 18452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper VarDeclVisitor Visitor; 18552ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper Visitor.ExpectMatch("i", 2, 17); 18652ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper EXPECT_TRUE(Visitor.runOver( 18752ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper "int x[5];\n" 18889faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett "void f() { for (int i : x) {} }", 18989faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett VarDeclVisitor::Lang_CXX11)); 19052ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper} 19152ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper 192fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsCallExpr) { 193fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek DeclRefExprVisitor Visitor; 194fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("x", 1, 22); 195fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 196fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void x(); void y() { x(); }")); 197fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 198fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 199fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsCallInTemplateInstantiation) { 200fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek CXXMemberCallVisitor Visitor; 201fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("Y::x", 3, 3); 202fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 203fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "struct Y { void x(); };\n" 204fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template<typename T> void y(T t) {\n" 205fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " t.x();\n" 206fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "}\n" 207fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void foo() { y<Y>(Y()); }")); 208fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 209fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 2105482dc3a88fce51307b5e1e19bdf72dea1562040Richard SmithTEST(RecursiveASTVisitor, VisitsCallInNestedFunctionTemplateInstantiation) { 211fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek CXXMemberCallVisitor Visitor; 212fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("Y::x", 4, 5); 213fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 214fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "struct Y { void x(); };\n" 215fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template<typename T> struct Z {\n" 216fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " template<typename U> static void f() {\n" 217fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " T().x();\n" 218fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek " }\n" 219fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "};\n" 220fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "void foo() { Z<Y>::f<int>(); }")); 221fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 2225482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith 2235482dc3a88fce51307b5e1e19bdf72dea1562040Richard SmithTEST(RecursiveASTVisitor, VisitsCallInNestedClassTemplateInstantiation) { 2245482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith CXXMemberCallVisitor Visitor; 2255482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith Visitor.ExpectMatch("A::x", 5, 7); 2265482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith EXPECT_TRUE(Visitor.runOver( 2275482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "template <typename T1> struct X {\n" 2285482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " template <typename T2> struct Y {\n" 2295482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " void f() {\n" 2305482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " T2 y;\n" 2315482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " y.x();\n" 2325482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " }\n" 2335482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " };\n" 2345482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "};\n" 2355482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "struct A { void x(); };\n" 2365482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "int main() {\n" 2375482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith " (new X<A>::Y<A>())->f();\n" 2385482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith "}")); 2395482dc3a88fce51307b5e1e19bdf72dea1562040Richard Smith} 240fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 241fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek/* FIXME: According to Richard Smith this is a bug in the AST. 242fad7f85553da052559077f28c6937a8dd704b28dManuel KlimekTEST(RecursiveASTVisitor, VisitsBaseClassTemplateArgumentsInInstantiation) { 243fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek DeclRefExprVisitor Visitor; 244fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek Visitor.ExpectMatch("x", 3, 43); 245fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek EXPECT_TRUE(Visitor.runOver( 246fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template <typename T> void x();\n" 247fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template <void (*T)()> class X {};\n" 248fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "template <typename T> class Y : public X< x<T> > {};\n" 249fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek "Y<int> y;")); 250fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} 251fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek*/ 252fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek 253a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsCallInPartialTemplateSpecialization) { 254a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith CXXMemberCallVisitor Visitor; 255a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A::x", 6, 20); 256a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 257a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <typename T1> struct X {\n" 258a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template <typename T2, bool B> struct Y { void g(); };\n" 259a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 260a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <typename T1> template <typename T2>\n" 261a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "struct X<T1>::Y<T2, true> {\n" 262a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " void f() { T2 y; y.x(); }\n" 263a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 264a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "struct A { void x(); };\n" 265a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "int main() {\n" 266a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " (new X<A>::Y<A, true>())->f();\n" 267a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "}\n")); 268a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 269a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 27006cd51a83577019ea26661b7d570ae9aef06f674Richard SmithTEST(RecursiveASTVisitor, VisitsExplicitTemplateSpecialization) { 27106cd51a83577019ea26661b7d570ae9aef06f674Richard Smith CXXMemberCallVisitor Visitor; 27206cd51a83577019ea26661b7d570ae9aef06f674Richard Smith Visitor.ExpectMatch("A::f", 4, 5); 27306cd51a83577019ea26661b7d570ae9aef06f674Richard Smith EXPECT_TRUE(Visitor.runOver( 27406cd51a83577019ea26661b7d570ae9aef06f674Richard Smith "struct A {\n" 27506cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " void f() const {}\n" 27606cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " template<class T> void g(const T& t) const {\n" 27706cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " t.f();\n" 27806cd51a83577019ea26661b7d570ae9aef06f674Richard Smith " }\n" 27906cd51a83577019ea26661b7d570ae9aef06f674Richard Smith "};\n" 28006cd51a83577019ea26661b7d570ae9aef06f674Richard Smith "template void A::g(const A& a) const;\n")); 28106cd51a83577019ea26661b7d570ae9aef06f674Richard Smith} 28206cd51a83577019ea26661b7d570ae9aef06f674Richard Smith 283a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) { 284a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // From cfe-commits/Week-of-Mon-20100830/033998.html 285e966beaa6ef3eb7ced09203f748e6042f81b2a6cDaniel Jasper // Contrary to the approach suggested in that email, we visit all 286a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // specializations when we visit the primary template. Visiting them when we 287a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // visit the associated specialization is problematic for specializations of 288a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // template members of class templates. 289a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 290a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<bool>", 1, 26); 291a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<char *>", 2, 26); 292a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 293a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <class T> class A {};\n" 294a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template <class T> class A<T*> {};\n" 295a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<bool> ab;\n" 296a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<char*> acp;\n")); 297a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 298a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 299a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) { 300a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 301a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>", 1, 29); 302a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 303a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> struct A;\n" 304a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<int> *p;\n")); 305a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 306a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 307a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) { 308a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 309a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>::B<char>", 2, 31); 310a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 311a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> struct A {\n" 312a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template<typename U> struct B;\n" 313a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 314a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "A<int>::B<char> *p;\n")); 315a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 316a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 317a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) { 318a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 319a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>", 1, 26); 320a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 321a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> int A();\n" 322a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "int k = A<int>();\n")); 323a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 324a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 325a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) { 326a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 327a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("A<int>::B<char>", 2, 35); 328a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 329a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename T> struct A {\n" 330a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template<typename U> static int B();\n" 331a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 332a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "int k = A<int>::B<char>();\n")); 333a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 334a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 335a313b2fbba86c901e58dc58df036e731f24fdaeeRichard SmithTEST(RecursiveASTVisitor, NoRecursionInSelfFriend) { 336a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith // From cfe-commits/Week-of-Mon-20100830/033977.html 337a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith NamedDeclVisitor Visitor; 338a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith Visitor.ExpectMatch("vector_iterator<int>", 2, 7); 339a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith EXPECT_TRUE(Visitor.runOver( 340a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "template<typename Container>\n" 341a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "class vector_iterator {\n" 342a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith " template <typename C> friend class vector_iterator;\n" 343a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "};\n" 344a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith "vector_iterator<int> it_int;\n")); 345a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith} 346a313b2fbba86c901e58dc58df036e731f24fdaeeRichard Smith 347c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard SmithTEST(RecursiveASTVisitor, TraversesOverloadedOperator) { 348c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith CXXOperatorCallExprTraverser Visitor; 349c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Visitor.ExpectMatch("()", 4, 9); 350c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith EXPECT_TRUE(Visitor.runOver( 351c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith "struct A {\n" 352c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith " int operator()();\n" 353c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith "} a;\n" 354c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith "int k = a();\n")); 355c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith} 356c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 357c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard SmithTEST(RecursiveASTVisitor, VisitsParensDuringDataRecursion) { 358c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith ParenExprVisitor Visitor; 359c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith Visitor.ExpectMatch("", 1, 9); 360c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith EXPECT_TRUE(Visitor.runOver("int k = (4) + 9;\n")); 361c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith} 362c8c222830a1d8df8ed05bedfcac868fe6838fba8Richard Smith 3636fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateNonTypeParmDefaultArgument) { 3646fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith CXXBoolLiteralExprVisitor Visitor; 3656fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Visitor.ExpectMatch("true", 2, 19); 3666fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith EXPECT_TRUE(Visitor.runOver( 3676fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<bool B> class X;\n" 3686fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<bool B = true> class Y;\n" 3696fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<bool B> class Y {};\n")); 3706fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith} 3716fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 3726fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) { 3736fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith TypeLocVisitor Visitor; 3746fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Visitor.ExpectMatch("class X", 2, 23); 3756fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith EXPECT_TRUE(Visitor.runOver( 3766fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "class X;\n" 3776fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<typename T = X> class Y;\n" 3786fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<typename T> class Y {};\n")); 3796fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith} 3806fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 3816fada8e820f2fd1b4cd38e48c8986110e87c5915Richard SmithTEST(RecursiveASTVisitor, VisitsClassTemplateTemplateParmDefaultArgument) { 3826fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith TemplateArgumentLocTraverser Visitor; 3836fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith Visitor.ExpectMatch("X", 2, 40); 3846fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith EXPECT_TRUE(Visitor.runOver( 3856fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<typename T> class X;\n" 3866fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<template <typename> class T = X> class Y;\n" 3876fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith "template<template <typename> class T> class Y {};\n")); 3886fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith} 3896fada8e820f2fd1b4cd38e48c8986110e87c5915Richard Smith 390c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith// A visitor that visits implicit declarations and matches constructors. 391c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smithclass ImplicitCtorVisitor 392c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith : public ExpectedLocationVisitor<ImplicitCtorVisitor> { 393c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smithpublic: 39452ec0c0357ce970ca52a27c1086626450f0967e7Daniel Jasper bool shouldVisitImplicitCode() const { return true; } 395c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith 396c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith bool VisitCXXConstructorDecl(CXXConstructorDecl* Ctor) { 397c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith if (Ctor->isImplicit()) { // Was not written in source code 398c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith if (const CXXRecordDecl* Class = Ctor->getParent()) { 399c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith Match(Class->getName(), Ctor->getLocation()); 400c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith } 401c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith } 402c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith return true; 403c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith } 404c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith}; 405c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith 406c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard SmithTEST(RecursiveASTVisitor, VisitsImplicitCopyConstructors) { 407c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith ImplicitCtorVisitor Visitor; 408c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith Visitor.ExpectMatch("Simple", 2, 8); 409c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith // Note: Clang lazily instantiates implicit declarations, so we need 410c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith // to use them in order to force them to appear in the AST. 411c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith EXPECT_TRUE(Visitor.runOver( 412c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith "struct WithCtor { WithCtor(); }; \n" 413c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith "struct Simple { Simple(); WithCtor w; }; \n" 414c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith "int main() { Simple s; Simple t(s); }\n")); 415c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith} 416c28a335184207a47f34eb9d1707dc8d7c6c7b8b6Richard Smith 4178268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett/// \brief A visitor that optionally includes implicit code and matches 4188268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett/// CXXConstructExpr. 4198268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett/// 4208268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett/// The name recorded for the match is the name of the class whose constructor 4218268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett/// is invoked by the CXXConstructExpr, not the name of the class whose 4228268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett/// constructor the CXXConstructExpr is contained in. 4238268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennettclass ConstructExprVisitor 4248268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett : public ExpectedLocationVisitor<ConstructExprVisitor> { 4258268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennettpublic: 4268268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett ConstructExprVisitor() : ShouldVisitImplicitCode(false) {} 4278268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4288268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett bool shouldVisitImplicitCode() const { return ShouldVisitImplicitCode; } 4298268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4308268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett void setShouldVisitImplicitCode(bool NewValue) { 4318268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett ShouldVisitImplicitCode = NewValue; 4328268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett } 4338268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4348268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett bool VisitCXXConstructExpr(CXXConstructExpr* Expr) { 4358268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett if (const CXXConstructorDecl* Ctor = Expr->getConstructor()) { 4368268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett if (const CXXRecordDecl* Class = Ctor->getParent()) { 4378268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett Match(Class->getName(), Expr->getLocation()); 4388268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett } 4398268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett } 4408268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett return true; 4418268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett } 4428268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4438268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett private: 4448268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett bool ShouldVisitImplicitCode; 4458268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett}; 4468268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4478268fe7c4bdfa341975a687a8a5e236c2c5b88a4James DennettTEST(RecursiveASTVisitor, CanVisitImplicitMemberInitializations) { 4488268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett ConstructExprVisitor Visitor; 4498268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett Visitor.setShouldVisitImplicitCode(true); 4508268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett Visitor.ExpectMatch("WithCtor", 2, 8); 4518268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // Simple has a constructor that implicitly initializes 'w'. Test 4528268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // that a visitor that visits implicit code visits that initialization. 4538268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // Note: Clang lazily instantiates implicit declarations, so we need 4548268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // to use them in order to force them to appear in the AST. 4558268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett EXPECT_TRUE(Visitor.runOver( 4568268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett "struct WithCtor { WithCtor(); }; \n" 4578268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett "struct Simple { WithCtor w; }; \n" 4588268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett "int main() { Simple s; }\n")); 4598268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett} 4608268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4618268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett// The same as CanVisitImplicitMemberInitializations, but checking that the 4628268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett// visits are omitted when the visitor does not include implicit code. 4638268fe7c4bdfa341975a687a8a5e236c2c5b88a4James DennettTEST(RecursiveASTVisitor, CanSkipImplicitMemberInitializations) { 4648268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett ConstructExprVisitor Visitor; 4658268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett Visitor.setShouldVisitImplicitCode(false); 4668268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett Visitor.DisallowMatch("WithCtor", 2, 8); 4678268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // Simple has a constructor that implicitly initializes 'w'. Test 4688268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // that a visitor that skips implicit code skips that initialization. 4698268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // Note: Clang lazily instantiates implicit declarations, so we need 4708268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett // to use them in order to force them to appear in the AST. 4718268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett EXPECT_TRUE(Visitor.runOver( 4728268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett "struct WithCtor { WithCtor(); }; \n" 4738268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett "struct Simple { WithCtor w; }; \n" 4748268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett "int main() { Simple s; }\n")); 4758268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett} 4768268fe7c4bdfa341975a687a8a5e236c2c5b88a4James Dennett 4770652c35a303a6186142eea566c88714c59bdc664Richard SmithTEST(RecursiveASTVisitor, VisitsExtension) { 4780652c35a303a6186142eea566c88714c59bdc664Richard Smith DeclRefExprVisitor Visitor; 4790652c35a303a6186142eea566c88714c59bdc664Richard Smith Visitor.ExpectMatch("s", 1, 24); 4800652c35a303a6186142eea566c88714c59bdc664Richard Smith EXPECT_TRUE(Visitor.runOver( 4810652c35a303a6186142eea566c88714c59bdc664Richard Smith "int s = __extension__ (s);\n")); 4820652c35a303a6186142eea566c88714c59bdc664Richard Smith} 4830652c35a303a6186142eea566c88714c59bdc664Richard Smith 48482b4550fb25ad578b6c8143b87a003fae7106caeRichard SmithTEST(RecursiveASTVisitor, VisitsCompoundLiteralType) { 48582b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith TypeLocVisitor Visitor; 48682b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith Visitor.ExpectMatch("struct S", 1, 26); 48782b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith EXPECT_TRUE(Visitor.runOver( 48882b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith "int f() { return (struct S { int a; }){.a = 0}.a; }", 48982b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith TypeLocVisitor::Lang_C)); 49082b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith} 49182b4550fb25ad578b6c8143b87a003fae7106caeRichard Smith 49289faf86c6e23ed62519dfe369f8ea408df1cb02eJames DennettTEST(RecursiveASTVisitor, VisitsLambdaExpr) { 49389faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett LambdaExprVisitor Visitor; 49489faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett Visitor.ExpectMatch("", 1, 12); 49589faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", 49689faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett LambdaExprVisitor::Lang_CXX11)); 49789faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett} 49889faf86c6e23ed62519dfe369f8ea408df1cb02eJames Dennett 49949007d7561212c0ae168702c1af1404c01ef43ffJames DennettTEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) { 50049007d7561212c0ae168702c1af1404c01ef43ffJames Dennett LambdaExprVisitor Visitor; 50149007d7561212c0ae168702c1af1404c01ef43ffJames Dennett EXPECT_TRUE(Visitor.runOver("void f() { []{ return; }(); }", 50249007d7561212c0ae168702c1af1404c01ef43ffJames Dennett LambdaExprVisitor::Lang_CXX11)); 50349007d7561212c0ae168702c1af1404c01ef43ffJames Dennett EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed()); 50449007d7561212c0ae168702c1af1404c01ef43ffJames Dennett} 50549007d7561212c0ae168702c1af1404c01ef43ffJames Dennett 506fad7f85553da052559077f28c6937a8dd704b28dManuel Klimek} // end namespace clang 507