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]]( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits