[PATCH] D41661: [clangd] Don't navigate to forward class declaration when go to definition.

Haojian Wu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 12 06:22:37 PST 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL322370: [clangd] Don't navigate to forward class declaration when go to definition. (authored by hokein, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D41661

Files:
  clang-tools-extra/trunk/clangd/XRefs.cpp
  clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp


Index: clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
===================================================================
--- clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
+++ clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
@@ -203,6 +203,18 @@
         #define MACRO 2
         #undef macro
       )cpp",
+
+      R"cpp(// Forward class declaration
+        class Foo;
+        [[class Foo {}]];
+        F^oo* foo();
+      )cpp",
+
+      R"cpp(// Function declaration
+        void foo();
+        void g() { f^oo(); }
+        [[void foo() {}]]
+      )cpp",
   };
   for (const char *Test : Tests) {
     Annotations T(Test);
Index: clang-tools-extra/trunk/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp
+++ clang-tools-extra/trunk/clangd/XRefs.cpp
@@ -14,6 +14,20 @@
 using namespace llvm;
 namespace {
 
+// Get the definition from a given declaration `D`.
+// Return nullptr if no definition is found, or the declaration type of `D` is
+// not supported.
+const Decl* GetDefinition(const Decl* D) {
+  assert(D);
+  if (const auto *TD = dyn_cast<TagDecl>(D))
+    return TD->getDefinition();
+  else if (const auto *VD = dyn_cast<VarDecl>(D))
+    return VD->getDefinition();
+  else if (const auto *FD = dyn_cast<FunctionDecl>(D))
+    return FD->getDefinition();
+  return nullptr;
+}
+
 /// Finds declarations locations that a given source location refers to.
 class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
   std::vector<const Decl *> Decls;
@@ -50,8 +64,18 @@
                       ArrayRef<index::SymbolRelation> Relations, FileID FID,
                       unsigned Offset,
                       index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
-    if (isSearchedLocation(FID, Offset))
-      Decls.push_back(D);
+    if (isSearchedLocation(FID, Offset)) {
+      // Find and add definition declarations (for GoToDefinition).
+      // We don't use parameter `D`, as Parameter `D` is the canonical
+      // declaration, which is the first declaration of a redeclarable
+      // declaration, and it could be a forward declaration.
+      if (const auto* Def = GetDefinition(D)) {
+        Decls.push_back(Def);
+      } else {
+        // Couldn't find a definition, fall back to use `D`.
+        Decls.push_back(D);
+      }
+    }
     return true;
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41661.129615.patch
Type: text/x-patch
Size: 2422 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180112/63d10b98/attachment.bin>


More information about the cfe-commits mailing list