forked from OSchip/llvm-project
[clangd] Don't navigate to forward class declaration when go to definition.
Summary: For some cases, GoToDefinition will navigate to the forward class declaration, we should always navigate to the class definition. Reviewers: sammccall Reviewed By: sammccall Subscribers: klimek, ilya-biryukov, cfe-commits Differential Revision: https://reviews.llvm.org/D41661 llvm-svn: 322370
This commit is contained in:
parent
70bfe66111
commit
f4374f087f
|
@ -14,6 +14,20 @@ namespace clangd {
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
namespace {
|
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.
|
/// Finds declarations locations that a given source location refers to.
|
||||||
class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
|
class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
|
||||||
std::vector<const Decl *> Decls;
|
std::vector<const Decl *> Decls;
|
||||||
|
@ -50,8 +64,18 @@ public:
|
||||||
ArrayRef<index::SymbolRelation> Relations, FileID FID,
|
ArrayRef<index::SymbolRelation> Relations, FileID FID,
|
||||||
unsigned Offset,
|
unsigned Offset,
|
||||||
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
|
index::IndexDataConsumer::ASTNodeInfo ASTNode) override {
|
||||||
if (isSearchedLocation(FID, Offset))
|
if (isSearchedLocation(FID, Offset)) {
|
||||||
Decls.push_back(D);
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,18 @@ TEST(GoToDefinition, All) {
|
||||||
#define MACRO 2
|
#define MACRO 2
|
||||||
#undef macro
|
#undef macro
|
||||||
)cpp",
|
)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) {
|
for (const char *Test : Tests) {
|
||||||
Annotations T(Test);
|
Annotations T(Test);
|
||||||
|
|
Loading…
Reference in New Issue