Skip to content

Commit 4b462c5

Browse files
author
ct.clmsn
committed
inital import
Signed-off-by: ct.clmsn <[email protected]>
1 parent a8da483 commit 4b462c5

39 files changed

+7365
-0
lines changed

clang/include/clang/AST/RecursiveASTEnterExitVisitor.h

Lines changed: 4187 additions & 0 deletions
Large diffs are not rendered by default.

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,8 +1273,11 @@ DEF_TRAVERSE_TYPELOC(RValueReferenceType,
12731273
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
12741274
if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
12751275
TRY_TO(TraverseNestedNameSpecifierLoc(QL));
1276+
// if (auto *TSI = TL.getClassTInfo())
1277+
// TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
12761278
else
12771279
TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1280+
// TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
12781281
TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
12791282
})
12801283

clang/include/clang/AST/StmtOpenACC.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt {
8181
friend class ASTStmtWriter;
8282
friend class ASTStmtReader;
8383
template <typename Derived> friend class RecursiveASTVisitor;
84+
template <typename Derived> friend class RecursiveASTEnterExitVisitor;
8485
Stmt *AssociatedStmt = nullptr;
8586

8687
protected:

clang/unittests/Tooling/CMakeLists.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,40 @@ add_clang_unittest(ToolingTests
4949
RecursiveASTVisitorTestDeclVisitor.cpp
5050
RecursiveASTVisitorTestPostOrderVisitor.cpp
5151
RecursiveASTVisitorTestTypeLocVisitor.cpp
52+
RecursiveASTEnterExitVisitorTests/Attr.cpp
53+
RecursiveASTEnterExitVisitorTests/BitfieldInitializer.cpp
54+
RecursiveASTEnterExitVisitorTests/CallbacksLeaf.cpp
55+
RecursiveASTEnterExitVisitorTests/CallbacksUnaryOperator.cpp
56+
RecursiveASTEnterExitVisitorTests/CallbacksBinaryOperator.cpp
57+
RecursiveASTEnterExitVisitorTests/CallbacksCompoundAssignOperator.cpp
58+
RecursiveASTEnterExitVisitorTests/CallbacksCallExpr.cpp
59+
RecursiveASTEnterExitVisitorTests/Class.cpp
60+
RecursiveASTEnterExitVisitorTests/Concept.cpp
61+
RecursiveASTEnterExitVisitorTests/ConstructExpr.cpp
62+
RecursiveASTEnterExitVisitorTests/CXXBoolLiteralExpr.cpp
63+
RecursiveASTEnterExitVisitorTests/CXXMemberCall.cpp
64+
RecursiveASTEnterExitVisitorTests/CXXMethodDecl.cpp
65+
RecursiveASTEnterExitVisitorTests/CXXOperatorCallExprTraverser.cpp
66+
RecursiveASTEnterExitVisitorTests/DeclRefExpr.cpp
67+
RecursiveASTEnterExitVisitorTests/DeductionGuide.cpp
68+
RecursiveASTEnterExitVisitorTests/ImplicitCtor.cpp
69+
RecursiveASTEnterExitVisitorTests/ImplicitCtorInitializer.cpp
70+
RecursiveASTEnterExitVisitorTests/InitListExprPostOrder.cpp
71+
RecursiveASTEnterExitVisitorTests/InitListExprPostOrderNoQueue.cpp
72+
RecursiveASTEnterExitVisitorTests/InitListExprPreOrder.cpp
73+
RecursiveASTEnterExitVisitorTests/InitListExprPreOrderNoQueue.cpp
74+
RecursiveASTEnterExitVisitorTests/IntegerLiteral.cpp
75+
RecursiveASTEnterExitVisitorTests/LambdaDefaultCapture.cpp
76+
RecursiveASTEnterExitVisitorTests/LambdaExpr.cpp
77+
RecursiveASTEnterExitVisitorTests/LambdaTemplateParams.cpp
78+
RecursiveASTEnterExitVisitorTests/MemberPointerTypeLoc.cpp
79+
RecursiveASTEnterExitVisitorTests/NestedNameSpecifiers.cpp
80+
RecursiveASTEnterExitVisitorTests/ParenExpr.cpp
81+
RecursiveASTEnterExitVisitorTests/TemplateArgumentLocTraverser.cpp
82+
RecursiveASTEnterExitVisitorTests/TraversalScope.cpp
83+
RecursiveASTEnterExitVisitorTestDeclVisitor.cpp
84+
RecursiveASTEnterExitVisitorTestPostOrderVisitor.cpp
85+
RecursiveASTEnterExitVisitorTestTypeLocVisitor.cpp
5286
RefactoringActionRulesTest.cpp
5387
RefactoringCallbacksTest.cpp
5488
RefactoringTest.cpp
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//===- unittest/Tooling/EnterExitRecursiveASTVisitorTestDeclVisitor.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+
#include "clang/AST/RecursiveASTEnterExitVisitor.h"
11+
12+
using namespace clang;
13+
14+
namespace {
15+
16+
class VarDeclVisitor : public ExpectedLocationVisitor {
17+
public:
18+
bool VisitVarDecl(VarDecl *Variable) override {
19+
Match(Variable->getNameAsString(), Variable->getBeginLoc());
20+
return true;
21+
}
22+
};
23+
24+
TEST(EnterExitRecursiveASTVisitor, 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 : public ExpectedLocationVisitor {
34+
public:
35+
ParmVarDeclVisitorForImplicitCode() { ShouldVisitImplicitCode = true; }
36+
37+
bool VisitParmVarDecl(ParmVarDecl *ParamVar) override {
38+
Match(ParamVar->getNameAsString(), ParamVar->getBeginLoc());
39+
return true;
40+
}
41+
};
42+
43+
// Test RAV visits parameter variable declaration of the implicit
44+
// copy assignment operator and implicit copy constructor.
45+
TEST(EnterExitRecursiveASTVisitor, VisitsParmVarDeclForImplicitCode) {
46+
ParmVarDeclVisitorForImplicitCode Visitor;
47+
// Match parameter variable name of implicit copy assignment operator and
48+
// implicit copy constructor.
49+
// This parameter name does not have a valid IdentifierInfo, and shares
50+
// same SourceLocation with its class declaration, so we match an empty name
51+
// with the class' source location.
52+
Visitor.ExpectMatch("", 1, 7);
53+
Visitor.ExpectMatch("", 3, 7);
54+
EXPECT_TRUE(Visitor.runOver(
55+
"class X {};\n"
56+
"void foo(X a, X b) {a = b;}\n"
57+
"class Y {};\n"
58+
"void bar(Y a) {Y b = a;}"));
59+
}
60+
61+
class NamedDeclVisitor : public ExpectedLocationVisitor {
62+
public:
63+
bool VisitNamedDecl(NamedDecl *Decl) override {
64+
std::string NameWithTemplateArgs;
65+
llvm::raw_string_ostream OS(NameWithTemplateArgs);
66+
Decl->getNameForDiagnostic(OS,
67+
Decl->getASTContext().getPrintingPolicy(),
68+
true);
69+
Match(NameWithTemplateArgs, Decl->getLocation());
70+
return true;
71+
}
72+
};
73+
74+
TEST(EnterExitRecursiveASTVisitor, VisitsPartialTemplateSpecialization) {
75+
// From cfe-commits/Week-of-Mon-20100830/033998.html
76+
// Contrary to the approach suggested in that email, we visit all
77+
// specializations when we visit the primary template. Visiting them when we
78+
// visit the associated specialization is problematic for specializations of
79+
// template members of class templates.
80+
NamedDeclVisitor Visitor;
81+
Visitor.ExpectMatch("A<bool>", 1, 26);
82+
Visitor.ExpectMatch("A<char *>", 2, 26);
83+
EXPECT_TRUE(Visitor.runOver(
84+
"template <class T> class A {};\n"
85+
"template <class T> class A<T*> {};\n"
86+
"A<bool> ab;\n"
87+
"A<char*> acp;\n"));
88+
}
89+
90+
TEST(EnterExitRecursiveASTVisitor, VisitsUndefinedClassTemplateSpecialization) {
91+
NamedDeclVisitor Visitor;
92+
Visitor.ExpectMatch("A<int>", 1, 29);
93+
EXPECT_TRUE(Visitor.runOver(
94+
"template<typename T> struct A;\n"
95+
"A<int> *p;\n"));
96+
}
97+
98+
TEST(EnterExitRecursiveASTVisitor, VisitsNestedUndefinedClassTemplateSpecialization) {
99+
NamedDeclVisitor Visitor;
100+
Visitor.ExpectMatch("A<int>::B<char>", 2, 31);
101+
EXPECT_TRUE(Visitor.runOver(
102+
"template<typename T> struct A {\n"
103+
" template<typename U> struct B;\n"
104+
"};\n"
105+
"A<int>::B<char> *p;\n"));
106+
}
107+
108+
TEST(EnterExitRecursiveASTVisitor, VisitsUndefinedFunctionTemplateSpecialization) {
109+
NamedDeclVisitor Visitor;
110+
Visitor.ExpectMatch("A<int>", 1, 26);
111+
EXPECT_TRUE(Visitor.runOver(
112+
"template<typename T> int A();\n"
113+
"int k = A<int>();\n"));
114+
}
115+
116+
TEST(EnterExitRecursiveASTVisitor, VisitsNestedUndefinedFunctionTemplateSpecialization) {
117+
NamedDeclVisitor Visitor;
118+
Visitor.ExpectMatch("A<int>::B<char>", 2, 35);
119+
EXPECT_TRUE(Visitor.runOver(
120+
"template<typename T> struct A {\n"
121+
" template<typename U> static int B();\n"
122+
"};\n"
123+
"int k = A<int>::B<char>();\n"));
124+
}
125+
126+
TEST(EnterExitRecursiveASTVisitor, NoRecursionInSelfFriend) {
127+
// From cfe-commits/Week-of-Mon-20100830/033977.html
128+
NamedDeclVisitor Visitor;
129+
Visitor.ExpectMatch("vector_iterator<int>", 2, 7);
130+
EXPECT_TRUE(Visitor.runOver(
131+
"template<typename Container>\n"
132+
"class vector_iterator {\n"
133+
" template <typename C> friend class vector_iterator;\n"
134+
"};\n"
135+
"vector_iterator<int> it_int;\n"));
136+
}
137+
138+
} // end anonymous namespace
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===- unittests/Tooling/EnterExitRecursiveASTVisitorPostOrderASTVisitor.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+
// This file contains tests for the post-order traversing functionality
10+
// of EnterExitRecursiveASTVisitor.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "CRTPTestVisitor.h"
15+
#include "clang/AST/RecursiveASTEnterExitVisitor.h"
16+
17+
using namespace clang;
18+
19+
namespace {
20+
class RecordingVisitor : public CRTPTestVisitor<RecordingVisitor> {
21+
bool VisitPostOrder;
22+
23+
public:
24+
explicit RecordingVisitor(bool VisitPostOrder)
25+
: VisitPostOrder(VisitPostOrder) {}
26+
27+
// List of visited nodes during traversal.
28+
std::vector<std::string> VisitedNodes;
29+
30+
bool shouldTraversePostOrder() const { return VisitPostOrder; }
31+
32+
bool VisitUnaryOperator(UnaryOperator *Op) {
33+
VisitedNodes.push_back(std::string(Op->getOpcodeStr(Op->getOpcode())));
34+
return true;
35+
}
36+
37+
bool VisitBinaryOperator(BinaryOperator *Op) {
38+
VisitedNodes.push_back(std::string(Op->getOpcodeStr()));
39+
return true;
40+
}
41+
42+
bool VisitIntegerLiteral(IntegerLiteral *Lit) {
43+
VisitedNodes.push_back(toString(Lit->getValue(), 10, false));
44+
return true;
45+
}
46+
47+
bool VisitVarDecl(VarDecl *D) {
48+
VisitedNodes.push_back(D->getNameAsString());
49+
return true;
50+
}
51+
52+
bool VisitCXXMethodDecl(CXXMethodDecl *D) {
53+
VisitedNodes.push_back(D->getQualifiedNameAsString());
54+
return true;
55+
}
56+
57+
bool VisitReturnStmt(ReturnStmt *S) {
58+
VisitedNodes.push_back("return");
59+
return true;
60+
}
61+
62+
bool VisitCXXRecordDecl(CXXRecordDecl *D) {
63+
if (!D->isImplicit())
64+
VisitedNodes.push_back(D->getQualifiedNameAsString());
65+
return true;
66+
}
67+
68+
bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
69+
VisitedNodes.push_back(T->getDecl()->getQualifiedNameAsString());
70+
return true;
71+
}
72+
};
73+
} // namespace
74+
75+
TEST(EnterExitRecursiveASTVisitor, PostOrderTraversal) {
76+
// We traverse the translation unit and store all visited nodes.
77+
RecordingVisitor Visitor(true);
78+
Visitor.runOver("class A {\n"
79+
" class B {\n"
80+
" int foo() {\n"
81+
" while(4) { int i = 9; int j = -5; }\n"
82+
" return (1 + 3) + 2; }\n"
83+
" };\n"
84+
"};\n");
85+
86+
std::vector<std::string> expected = {"4", "9", "i", "5", "-",
87+
"j", "1", "3", "+", "2",
88+
"+", "return", "A::B::foo", "A::B", "A"};
89+
// Compare the list of actually visited nodes with the expected list of
90+
// visited nodes.
91+
ASSERT_EQ(expected.size(), Visitor.VisitedNodes.size());
92+
for (std::size_t I = 0; I < expected.size(); I++) {
93+
ASSERT_EQ(expected[I], Visitor.VisitedNodes[I]);
94+
}
95+
}
96+
97+
TEST(EnterExitRecursiveASTVisitor, NoPostOrderTraversal) {
98+
// We traverse the translation unit and store all visited nodes.
99+
RecordingVisitor Visitor(false);
100+
Visitor.runOver("class A {\n"
101+
" class B {\n"
102+
" int foo() { return 1 + 2; }\n"
103+
" };\n"
104+
"};\n");
105+
106+
std::vector<std::string> expected = {"A", "A::B", "A::B::foo", "return",
107+
"+", "1", "2"};
108+
// Compare the list of actually visited nodes with the expected list of
109+
// visited nodes.
110+
ASSERT_EQ(expected.size(), Visitor.VisitedNodes.size());
111+
for (std::size_t I = 0; I < expected.size(); I++) {
112+
ASSERT_EQ(expected[I], Visitor.VisitedNodes[I]);
113+
}
114+
}

0 commit comments

Comments
 (0)