138 lines · cpp
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-exception6//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(Variable->getNameAsString(), 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(ParamVar->getNameAsString(), ParamVar->getBeginLoc());38 return true;39 }40};41 42// Test RAV visits parameter variable declaration of the implicit43// copy assignment operator and implicit copy constructor.44TEST(RecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {45 ParmVarDeclVisitorForImplicitCode Visitor;46 // Match parameter variable name of implicit copy assignment operator and47 // implicit copy constructor.48 // This parameter name does not have a valid IdentifierInfo, and shares49 // same SourceLocation with its class declaration, so we match an empty name50 // 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 Decl->getASTContext().getPrintingPolicy(),67 true);68 Match(NameWithTemplateArgs, Decl->getLocation());69 return true;70 }71};72 73TEST(RecursiveASTVisitor, VisitsPartialTemplateSpecialization) {74 // From cfe-commits/Week-of-Mon-20100830/033998.html75 // Contrary to the approach suggested in that email, we visit all76 // specializations when we visit the primary template. Visiting them when we77 // visit the associated specialization is problematic for specializations of78 // 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.html127 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 namespace138