]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / unittests / Tooling / RecursiveASTVisitorTestDeclVisitor.cpp
1 //===- unittest/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp ------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "TestVisitor.h"
11
12 using namespace clang;
13
14 namespace {
15
16 class VarDeclVisitor : public ExpectedLocationVisitor<VarDeclVisitor> {
17 public:
18  bool VisitVarDecl(VarDecl *Variable) {
19    Match(Variable->getNameAsString(), Variable->getBeginLoc());
20    return true;
21  }
22 };
23
24 TEST(RecursiveASTVisitor, VisitsCXXForRangeStmtLoopVariable) {
25   VarDeclVisitor Visitor;
26   Visitor.ExpectMatch("i", 2, 17);
27   EXPECT_TRUE(Visitor.runOver(
28     "int x[5];\n"
29     "void f() { for (int i : x) {} }",
30     VarDeclVisitor::Lang_CXX11));
31 }
32
33 class ParmVarDeclVisitorForImplicitCode :
34   public ExpectedLocationVisitor<ParmVarDeclVisitorForImplicitCode> {
35 public:
36   bool shouldVisitImplicitCode() const { return true; }
37
38   bool VisitParmVarDecl(ParmVarDecl *ParamVar) {
39     Match(ParamVar->getNameAsString(), ParamVar->getBeginLoc());
40     return true;
41   }
42 };
43
44 // Test RAV visits parameter variable declaration of the implicit
45 // copy assignment operator and implicit copy constructor.
46 TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {
47   ParmVarDeclVisitorForImplicitCode Visitor;
48   // Match parameter variable name of implicit copy assignment operator and
49   // implicit copy constructor.
50   // This parameter name does not have a valid IdentifierInfo, and shares
51   // same SourceLocation with its class declaration, so we match an empty name
52   // with the class' source location.
53   Visitor.ExpectMatch("", 1, 7);
54   Visitor.ExpectMatch("", 3, 7);
55   EXPECT_TRUE(Visitor.runOver(
56     "class X {};\n"
57     "void foo(X a, X b) {a = b;}\n"
58     "class Y {};\n"
59     "void bar(Y a) {Y b = a;}"));
60 }
61
62 class NamedDeclVisitor
63   : public ExpectedLocationVisitor<NamedDeclVisitor> {
64 public:
65   bool VisitNamedDecl(NamedDecl *Decl) {
66     std::string NameWithTemplateArgs;
67     llvm::raw_string_ostream OS(NameWithTemplateArgs);
68     Decl->getNameForDiagnostic(OS,
69                                Decl->getASTContext().getPrintingPolicy(),
70                                true);
71     Match(OS.str(), Decl->getLocation());
72     return true;
73   }
74 };
75
76 TEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) {
77   // From cfe-commits/Week-of-Mon-20100830/033998.html
78   // Contrary to the approach suggested in that email, we visit all
79   // specializations when we visit the primary template.  Visiting them when we
80   // visit the associated specialization is problematic for specializations of
81   // template members of class templates.
82   NamedDeclVisitor Visitor;
83   Visitor.ExpectMatch("A<bool>", 1, 26);
84   Visitor.ExpectMatch("A<char *>", 2, 26);
85   EXPECT_TRUE(Visitor.runOver(
86     "template <class T> class A {};\n"
87     "template <class T> class A<T*> {};\n"
88     "A<bool> ab;\n"
89     "A<char*> acp;\n"));
90 }
91
92 TEST(RecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) {
93   NamedDeclVisitor Visitor;
94   Visitor.ExpectMatch("A<int>", 1, 29);
95   EXPECT_TRUE(Visitor.runOver(
96     "template<typename T> struct A;\n"
97     "A<int> *p;\n"));
98 }
99
100 TEST(RecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) {
101   NamedDeclVisitor Visitor;
102   Visitor.ExpectMatch("A<int>::B<char>", 2, 31);
103   EXPECT_TRUE(Visitor.runOver(
104     "template<typename T> struct A {\n"
105     "  template<typename U> struct B;\n"
106     "};\n"
107     "A<int>::B<char> *p;\n"));
108 }
109
110 TEST(RecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) {
111   NamedDeclVisitor Visitor;
112   Visitor.ExpectMatch("A<int>", 1, 26);
113   EXPECT_TRUE(Visitor.runOver(
114     "template<typename T> int A();\n"
115     "int k = A<int>();\n"));
116 }
117
118 TEST(RecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) {
119   NamedDeclVisitor Visitor;
120   Visitor.ExpectMatch("A<int>::B<char>", 2, 35);
121   EXPECT_TRUE(Visitor.runOver(
122     "template<typename T> struct A {\n"
123     "  template<typename U> static int B();\n"
124     "};\n"
125     "int k = A<int>::B<char>();\n"));
126 }
127
128 TEST(RecursiveASTVisitor, NoRecursionInSelfFriend) {
129   // From cfe-commits/Week-of-Mon-20100830/033977.html
130   NamedDeclVisitor Visitor;
131   Visitor.ExpectMatch("vector_iterator<int>", 2, 7);
132   EXPECT_TRUE(Visitor.runOver(
133     "template<typename Container>\n"
134     "class vector_iterator {\n"
135     "    template <typename C> friend class vector_iterator;\n"
136     "};\n"
137     "vector_iterator<int> it_int;\n"));
138 }
139
140 } // end anonymous namespace