[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
Wed Jan 3 02:12:57 PST 2018
hokein updated this revision to Diff 128501.
hokein marked an inline comment as done.
hokein added a comment.
- Revise the way of checking definition.
- Add a test for function declaration.
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,16 @@
using namespace llvm;
namespace {
+bool IsDefinition(const Decl* D) {
+ if (const auto *TD = dyn_cast<TagDecl>(D))
+ return TD->isThisDeclarationADefinition();
+ else if (const auto *VD = dyn_cast<VarDecl>(D))
+ return VD->isThisDeclarationADefinition();
+ else if (const auto *FD = dyn_cast<FunctionDecl>(D))
+ return FD->isThisDeclarationADefinition();
+ return false;
+}
+
/// Finds declarations locations that a given source location refers to.
class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
std::vector<const Decl *> Decls;
@@ -50,8 +60,20 @@
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.
+ auto Def = std::find_if(D->redecls_begin(), D->redecls_end(),
+ [](const Decl *D) { return IsDefinition(D); });
+ if (Def != D->redecls_end()) {
+ 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.128501.patch
Type: text/x-patch
Size: 2285 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180103/dbb50ffe/attachment.bin>
More information about the cfe-commits
mailing list