[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