8
8
9
9
#include " clang/Tooling/Refactoring/Lookup.h"
10
10
#include " TestVisitor.h"
11
+ #include " clang/AST/TypeLoc.h"
12
+ #include " clang/Basic/SourceLocation.h"
11
13
using namespace clang ;
12
14
13
15
namespace {
14
16
struct GetDeclsVisitor : TestVisitor<GetDeclsVisitor> {
15
17
std::function<void (CallExpr *)> OnCall;
16
18
std::function<void (RecordTypeLoc)> OnRecordTypeLoc;
19
+ std::function<void (UsingTypeLoc)> OnUsingTypeLoc;
17
20
SmallVector<Decl *, 4 > DeclStack;
18
21
19
22
bool VisitCallExpr (CallExpr *Expr) {
@@ -28,6 +31,12 @@ struct GetDeclsVisitor : TestVisitor<GetDeclsVisitor> {
28
31
return true ;
29
32
}
30
33
34
+ bool VisitUsingTypeLoc (UsingTypeLoc Loc) {
35
+ if (OnUsingTypeLoc)
36
+ OnUsingTypeLoc (Loc);
37
+ return true ;
38
+ }
39
+
31
40
bool TraverseDecl (Decl *D) {
32
41
DeclStack.push_back (D);
33
42
bool Ret = TestVisitor::TraverseDecl (D);
@@ -181,32 +190,33 @@ TEST(LookupTest, replaceNestedFunctionName) {
181
190
TEST (LookupTest, replaceNestedClassName) {
182
191
GetDeclsVisitor Visitor;
183
192
184
- auto replaceRecordTypeLoc = [&](RecordTypeLoc TLoc,
185
- StringRef ReplacementString) {
186
- const auto *FD = cast<CXXRecordDecl>(TLoc.getDecl ());
193
+ auto replaceTypeLoc = [&](const NamedDecl *ND, SourceLocation Loc,
194
+ StringRef ReplacementString) {
187
195
return tooling::replaceNestedName (
188
- nullptr , TLoc. getBeginLoc () , Visitor.DeclStack .back ()->getDeclContext (),
189
- FD, ReplacementString);
196
+ nullptr , Loc , Visitor.DeclStack .back ()->getDeclContext (), ND ,
197
+ ReplacementString);
190
198
};
191
199
192
200
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
193
201
// Filter Types by name since there are other `RecordTypeLoc` in the test
194
202
// file.
195
203
if (Type.getDecl ()->getQualifiedNameAsString () == " a::b::Foo" ) {
196
- EXPECT_EQ (" x::Bar" , replaceRecordTypeLoc (Type, " ::a::x::Bar" ));
204
+ EXPECT_EQ (" x::Bar" , replaceTypeLoc (Type.getDecl (), Type.getBeginLoc (),
205
+ " ::a::x::Bar" ));
197
206
}
198
207
};
199
208
Visitor.runOver (" namespace a { namespace b {\n "
200
209
" class Foo;\n "
201
210
" namespace c { Foo f();; }\n "
202
211
" } }\n " );
203
212
204
- Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
213
+ Visitor.OnUsingTypeLoc = [&](UsingTypeLoc Type) {
205
214
// Filter Types by name since there are other `RecordTypeLoc` in the test
206
215
// file.
207
216
// `a::b::Foo` in using shadow decl is not `TypeLoc`.
208
- if (Type.getDecl ()->getQualifiedNameAsString () == " a::b::Foo" ) {
209
- EXPECT_EQ (" Bar" , replaceRecordTypeLoc (Type, " ::a::x::Bar" ));
217
+ auto *TD = Type.getFoundDecl ()->getTargetDecl ();
218
+ if (TD->getQualifiedNameAsString () == " a::b::Foo" ) {
219
+ EXPECT_EQ (" Bar" , replaceTypeLoc (TD, Type.getBeginLoc (), " ::a::x::Bar" ));
210
220
}
211
221
};
212
222
Visitor.runOver (" namespace a { namespace b { class Foo {}; } }\n "
@@ -218,7 +228,8 @@ TEST(LookupTest, replaceNestedClassName) {
218
228
// it's not visible at [0].
219
229
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
220
230
if (Type.getDecl ()->getQualifiedNameAsString () == " x::y::Old" ) {
221
- EXPECT_EQ (" Foo" , replaceRecordTypeLoc (Type, " ::x::Foo" ));
231
+ EXPECT_EQ (" Foo" ,
232
+ replaceTypeLoc (Type.getDecl (), Type.getBeginLoc (), " ::x::Foo" ));
222
233
}
223
234
};
224
235
Visitor.runOver (R"(
0 commit comments