1176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//===- unittest/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp ------------===// 2176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// 3176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// The LLVM Compiler Infrastructure 4176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// 5176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// This file is distributed under the University of Illinois Open Source 6176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// License. See LICENSE.TXT for details. 7176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// 8176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines//===----------------------------------------------------------------------===// 9176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 10176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include "TestVisitor.h" 11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#include <stack> 12176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 13176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesusing namespace clang; 14176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 15176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesnamespace { 16176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 17176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> { 18176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic: 19176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool VisitVarDecl(VarDecl *Variable) { 20176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Match(Variable->getNameAsString(), Variable->getLocStart()); 21176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 22176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 23176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}; 24176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 25176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) { 26176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VarDeclVisitor Visitor; 27176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("i", 2, 17); 28176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 29176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "int x[5];\n" 30176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "void f() { for (int i : x) {} }", 31176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines VarDeclVisitor::Lang_CXX11)); 32176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 33176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 34176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass ParmVarDeclVisitorForImplicitCode : 35176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> { 36176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic: 37176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool shouldVisitImplicitCode() const { return true; } 38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 39176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool VisitParmVarDecl(ParmVarDecl *ParamVar) { 40176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Match(ParamVar->getNameAsString(), ParamVar->getLocStart()); 41176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 42176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 43176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}; 44176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 45176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Test RAV visits parameter variable declaration of the implicit 46176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// copy assignment operator and implicit copy constructor. 47176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) { 48176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines ParmVarDeclVisitorForImplicitCode Visitor; 49176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Match parameter variable name of implicit copy assignment operator and 50176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // implicit copy constructor. 51176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // This parameter name does not have a valid IdentifierInfo, and shares 52176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // same SourceLocation with its class declaration, so we match an empty name 53176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // with the class' source location. 54176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("", 1, 7); 55176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("", 3, 7); 56176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 57176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "class X {};\n" 58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "void foo(X a, X b) {a = b;}\n" 59176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "class Y {};\n" 60176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "void bar(Y a) {Y b = a;}")); 61176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 62176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 63176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinesclass NamedDeclVisitor 64176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines : public ExpectedLocationVisitor<NamedDeclVisitor> { 65176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinespublic: 66176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines bool VisitNamedDecl(NamedDecl *Decl) { 67176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines std::string NameWithTemplateArgs; 68176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines llvm::raw_string_ostream OS(NameWithTemplateArgs); 69176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Decl->getNameForDiagnostic(OS, 70176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Decl->getASTContext().getPrintingPolicy(), 71176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines true); 72176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Match(OS.str(), Decl->getLocation()); 73176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines return true; 74176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines } 75176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}; 76176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 77176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) { 78176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // From cfe-commits/Week-of-Mon-20100830/033998.html 79176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // Contrary to the approach suggested in that email, we visit all 80176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // specializations when we visit the primary template. Visiting them when we 81176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // visit the associated specialization is problematic for specializations of 82176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // template members of class templates. 83176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NamedDeclVisitor Visitor; 84176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("A<bool>", 1, 26); 85176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("A<char *>", 2, 26); 86176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 87176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template <class T> class A {};\n" 88176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template <class T> class A<T*> {};\n" 89176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "A<bool> ab;\n" 90176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "A<char*> acp;\n")); 91176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 92176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 93176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) { 94176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NamedDeclVisitor Visitor; 95176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("A<int>", 1, 29); 96176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 97176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template<typename T> struct A;\n" 98176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "A<int> *p;\n")); 99176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 100176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 101176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) { 102176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NamedDeclVisitor Visitor; 103176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("A<int>::B<char>", 2, 31); 104176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 105176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template<typename T> struct A {\n" 106176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines " template<typename U> struct B;\n" 107176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "};\n" 108176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "A<int>::B<char> *p;\n")); 109176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 110176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 111176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) { 112176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NamedDeclVisitor Visitor; 113176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("A<int>", 1, 26); 114176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 115176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template<typename T> int A();\n" 116176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "int k = A<int>();\n")); 117176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 118176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 119176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) { 120176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NamedDeclVisitor Visitor; 121176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("A<int>::B<char>", 2, 35); 122176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 123176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template<typename T> struct A {\n" 124176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines " template<typename U> static int B();\n" 125176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "};\n" 126176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "int k = A<int>::B<char>();\n")); 127176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 128176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 129176edba5311f6eff0cad2631449885ddf4fbc9eaStephen HinesTEST(RecursiveASTVisitor, NoRecursionInSelfFriend) { 130176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines // From cfe-commits/Week-of-Mon-20100830/033977.html 131176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines NamedDeclVisitor Visitor; 132176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines Visitor.ExpectMatch("vector_iterator<int>", 2, 7); 133176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines EXPECT_TRUE(Visitor.runOver( 134176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "template<typename Container>\n" 135176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "class vector_iterator {\n" 136176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines " template <typename C> friend class vector_iterator;\n" 137176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "};\n" 138176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines "vector_iterator<int> it_int;\n")); 139176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} 140176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines 141176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines} // end anonymous namespace 142