forked from OSchip/llvm-project
[clangd] Capture the missing injected class names in findExplicitReferences.
Summary: Fixes https://github.com/clangd/clangd/issues/237. Reviewers: kadircet, kbobyrev Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73088
This commit is contained in:
parent
651fa669a2
commit
f651c402a2
|
@ -695,6 +695,13 @@ llvm::SmallVector<ReferenceLoc, 2> refInTypeLoc(TypeLoc L) {
|
|||
DeclRelation::Alias)};
|
||||
}
|
||||
|
||||
void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
|
||||
Ref = ReferenceLoc{NestedNameSpecifierLoc(),
|
||||
TL.getNameLoc(),
|
||||
/*IsDecl=*/false,
|
||||
{TL.getDecl()}};
|
||||
}
|
||||
|
||||
void VisitDependentTemplateSpecializationTypeLoc(
|
||||
DependentTemplateSpecializationTypeLoc L) {
|
||||
Ref = ReferenceLoc{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- FindSymbolsTests.cpp -------------------------*- C++ -*------------===//
|
||||
//===-- FindTargetTests.cpp --------------------------*- C++ -*------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
|
@ -553,8 +553,8 @@ protected:
|
|||
std::string DumpedReferences;
|
||||
};
|
||||
|
||||
/// Parses \p Code, finds function '::foo' and annotates its body with results
|
||||
/// of findExplicitReferecnces.
|
||||
/// Parses \p Code, finds function or namespace '::foo' and annotates its body
|
||||
/// with results of findExplicitReferecnces.
|
||||
/// See actual tests for examples of annotation format.
|
||||
AllRefs annotateReferencesInFoo(llvm::StringRef Code) {
|
||||
TestTU TU;
|
||||
|
@ -574,12 +574,21 @@ protected:
|
|||
auto *TestDecl = &findDecl(AST, "foo");
|
||||
if (auto *T = llvm::dyn_cast<FunctionTemplateDecl>(TestDecl))
|
||||
TestDecl = T->getTemplatedDecl();
|
||||
auto &Func = llvm::cast<FunctionDecl>(*TestDecl);
|
||||
|
||||
std::vector<ReferenceLoc> Refs;
|
||||
findExplicitReferences(Func.getBody(), [&Refs](ReferenceLoc R) {
|
||||
Refs.push_back(std::move(R));
|
||||
});
|
||||
if (const auto *Func = llvm::dyn_cast<FunctionDecl>(TestDecl))
|
||||
findExplicitReferences(Func->getBody(), [&Refs](ReferenceLoc R) {
|
||||
Refs.push_back(std::move(R));
|
||||
});
|
||||
else if (const auto *NS = llvm::dyn_cast<NamespaceDecl>(TestDecl))
|
||||
findExplicitReferences(NS, [&Refs, &NS](ReferenceLoc R) {
|
||||
// Avoid adding the namespace foo decl to the results.
|
||||
if (R.Targets.size() == 1 && R.Targets.front() == NS)
|
||||
return;
|
||||
Refs.push_back(std::move(R));
|
||||
});
|
||||
else
|
||||
ADD_FAILURE() << "Failed to find ::foo decl for test";
|
||||
|
||||
auto &SM = AST.getSourceManager();
|
||||
llvm::sort(Refs, [&](const ReferenceLoc &L, const ReferenceLoc &R) {
|
||||
|
@ -720,6 +729,25 @@ TEST_F(FindExplicitReferencesTest, All) {
|
|||
"1: targets = {vi}, decl\n"
|
||||
"2: targets = {valias}\n"
|
||||
"3: targets = {vb}, decl\n"},
|
||||
// Injected class name.
|
||||
{R"cpp(
|
||||
namespace foo {
|
||||
template <typename $0^T>
|
||||
class $1^$2^Bar {
|
||||
~$3^Bar();
|
||||
void $4^f($5^Bar);
|
||||
};
|
||||
}
|
||||
)cpp",
|
||||
"0: targets = {foo::Bar::T}, decl\n"
|
||||
// FIXME: avoid the 2 duplicated foo::Bar references below, the first
|
||||
// one comes from ClassTemplateDecl; the second comes from the
|
||||
// underlying CXXRecordDecl.
|
||||
"1: targets = {foo::Bar}, decl\n"
|
||||
"2: targets = {foo::Bar}, decl\n"
|
||||
"3: targets = {foo::Bar}\n"
|
||||
"4: targets = {foo::Bar::f}, decl\n"
|
||||
"5: targets = {foo::Bar}\n"},
|
||||
// MemberExpr should know their using declaration.
|
||||
{R"cpp(
|
||||
struct X { void func(int); };
|
||||
|
|
|
@ -127,6 +127,16 @@ TEST(RenameTest, WithinFileRename) {
|
|||
void [[Foo]]::foo(int x) {}
|
||||
)cpp",
|
||||
|
||||
// Rename template class, including constructor/destructor.
|
||||
R"cpp(
|
||||
template <typename T>
|
||||
class [[F^oo]] {
|
||||
[[F^oo]]();
|
||||
~[[F^oo]]();
|
||||
void f([[Foo]] x);
|
||||
};
|
||||
)cpp",
|
||||
|
||||
// Class in template argument.
|
||||
R"cpp(
|
||||
class [[F^oo]] {};
|
||||
|
|
|
@ -525,7 +525,7 @@ $InactiveCode[[]] #endif
|
|||
using $Typedef[[LVReference]] = $TemplateParameter[[T]] &;
|
||||
using $Typedef[[RVReference]] = $TemplateParameter[[T]]&&;
|
||||
using $Typedef[[Array]] = $TemplateParameter[[T]]*[3];
|
||||
using $Typedef[[MemberPointer]] = int (A::*)(int);
|
||||
using $Typedef[[MemberPointer]] = int ($Class[[A]]::*)(int);
|
||||
|
||||
// Use various previously defined typedefs in a function type.
|
||||
void $Method[[func]](
|
||||
|
|
Loading…
Reference in New Issue