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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/unittests/Tooling/RecursiveASTVisitorTestDeclVisitor.cpp