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