Skip to content

Commit f651c40

Browse files
committed
[clangd] Capture the missing injected class names in findExplicitReferences.
Summary: Fixes clangd/clangd#237. Reviewers: kadircet, kbobyrev Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73088
1 parent 651fa66 commit f651c40

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,13 @@ llvm::SmallVector<ReferenceLoc, 2> refInTypeLoc(TypeLoc L) {
695695
DeclRelation::Alias)};
696696
}
697697

698+
void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
699+
Ref = ReferenceLoc{NestedNameSpecifierLoc(),
700+
TL.getNameLoc(),
701+
/*IsDecl=*/false,
702+
{TL.getDecl()}};
703+
}
704+
698705
void VisitDependentTemplateSpecializationTypeLoc(
699706
DependentTemplateSpecializationTypeLoc L) {
700707
Ref = ReferenceLoc{

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- FindSymbolsTests.cpp -------------------------*- C++ -*------------===//
1+
//===-- FindTargetTests.cpp --------------------------*- C++ -*------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -553,8 +553,8 @@ class FindExplicitReferencesTest : public ::testing::Test {
553553
std::string DumpedReferences;
554554
};
555555

556-
/// Parses \p Code, finds function '::foo' and annotates its body with results
557-
/// of findExplicitReferecnces.
556+
/// Parses \p Code, finds function or namespace '::foo' and annotates its body
557+
/// with results of findExplicitReferecnces.
558558
/// See actual tests for examples of annotation format.
559559
AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
560560
TestTU TU;
@@ -574,12 +574,21 @@ class FindExplicitReferencesTest : public ::testing::Test {
574574
auto *TestDecl = &findDecl(AST, "foo");
575575
if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
576576
TestDecl = T->getTemplatedDecl();
577-
auto &Func = llvm::cast<FunctionDecl>(*TestDecl);
578577

579578
std::vector<ReferenceLoc> Refs;
580-
findExplicitReferences(Func.getBody(), [&Refs](ReferenceLoc R) {
581-
Refs.push_back(std::move(R));
582-
});
579+
if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
580+
findExplicitReferences(Func->getBody(), [&Refs](ReferenceLoc R) {
581+
Refs.push_back(std::move(R));
582+
});
583+
else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
584+
findExplicitReferences(NS, [&Refs, &NS](ReferenceLoc R) {
585+
// Avoid adding the namespace foo decl to the results.
586+
if (R.Targets.size() == 1 && R.Targets.front() == NS)
587+
return;
588+
Refs.push_back(std::move(R));
589+
});
590+
else
591+
ADD_FAILURE() << "Failed to find ::foo decl for test";
583592

584593
auto &SM = AST.getSourceManager();
585594
llvm::sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
@@ -720,6 +729,25 @@ TEST_F(FindExplicitReferencesTest, All) {
720729
"1: targets = {vi}, decl\n"
721730
"2: targets = {valias}\n"
722731
"3: targets = {vb}, decl\n"},
732+
// Injected class name.
733+
{R"cpp(
734+
namespace foo {
735+
template <typename $0^T>
736+
class $1^$2^Bar {
737+
~$3^Bar();
738+
void $4^f($5^Bar);
739+
};
740+
}
741+
)cpp",
742+
"0: targets = {foo::Bar::T}, decl\n"
743+
// FIXME: avoid the 2 duplicated foo::Bar references below, the first
744+
// one comes from ClassTemplateDecl; the second comes from the
745+
// underlying CXXRecordDecl.
746+
"1: targets = {foo::Bar}, decl\n"
747+
"2: targets = {foo::Bar}, decl\n"
748+
"3: targets = {foo::Bar}\n"
749+
"4: targets = {foo::Bar::f}, decl\n"
750+
"5: targets = {foo::Bar}\n"},
723751
// MemberExpr should know their using declaration.
724752
{R"cpp(
725753
struct X { void func(int); };

clang-tools-extra/clangd/unittests/RenameTests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ TEST(RenameTest, WithinFileRename) {
127127
void [[Foo]]::foo(int x) {}
128128
)cpp",
129129

130+
// Rename template class, including constructor/destructor.
131+
R"cpp(
132+
template <typename T>
133+
class [[F^oo]] {
134+
[[F^oo]]();
135+
~[[F^oo]]();
136+
void f([[Foo]] x);
137+
};
138+
)cpp",
139+
130140
// Class in template argument.
131141
R"cpp(
132142
class [[F^oo]] {};

clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
525525
using $Typedef[[LVReference]] = $TemplateParameter[[T]] &;
526526
using $Typedef[[RVReference]] = $TemplateParameter[[T]]&&;
527527
using $Typedef[[Array]] = $TemplateParameter[[T]]*[3];
528-
using $Typedef[[MemberPointer]] = int (A::*)(int);
528+
using $Typedef[[MemberPointer]] = int ($Class[[A]]::*)(int);
529529
530530
// Use various previously defined typedefs in a function type.
531531
void $Method[[func]](

0 commit comments

Comments
 (0)