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