hokein updated this revision to Diff 128516. hokein added a comment. Use getDefinition to simply the code.
Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D41661 Files: clangd/XRefs.cpp unittests/clangd/XRefsTests.cpp Index: unittests/clangd/XRefsTests.cpp =================================================================== --- unittests/clangd/XRefsTests.cpp +++ 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: clangd/XRefs.cpp =================================================================== --- clangd/XRefs.cpp +++ 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; }
Index: unittests/clangd/XRefsTests.cpp =================================================================== --- unittests/clangd/XRefsTests.cpp +++ 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: clangd/XRefs.cpp =================================================================== --- clangd/XRefs.cpp +++ 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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits