[clang-tools-extra] f651c40 - [clangd] Capture the missing injected class names in findExplicitReferences.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 21 06:12:22 PST 2020
Author: Haojian Wu
Date: 2020-01-21T15:09:23+01:00
New Revision: f651c402a221a20f3bc6ea43f70b29326a357010
URL: https://github.com/llvm/llvm-project/commit/f651c402a221a20f3bc6ea43f70b29326a357010
DIFF: https://github.com/llvm/llvm-project/commit/f651c402a221a20f3bc6ea43f70b29326a357010.diff
LOG: [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
Added:
Modified:
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/clangd/unittests/RenameTests.cpp
clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 0e3c30e16dd5..cbe83cc2cce4 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -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{
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index a420348fcda8..4c9fe120a8d6 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -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 @@ class FindExplicitReferencesTest : public ::testing::Test {
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 @@ class FindExplicitReferencesTest : public ::testing::Test {
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); };
diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp
index d0fc4d1033b5..65a3d27f9b19 100644
--- a/clang-tools-extra/clangd/unittests/RenameTests.cpp
+++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp
@@ -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]] {};
diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
index b353c0bdb4ec..6dcad34857cd 100644
--- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp
@@ -525,7 +525,7 @@ TEST(SemanticHighlighting, GetsCorrectTokens) {
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]](
More information about the cfe-commits
mailing list