Skip to content

Commit 357e79c

Browse files
kadircetsam-mccall
authored andcommitted
[clangd] Fix early selection for non-vardecl declarators
Summary: Selection tree was performing an early claim only for VarDecls, but there are other cases where we can have declarators, e.g. FieldDecls. This patch extends the early claim logic to all types of declarators. Fixes clangd/clangd#292 Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D75106 (cherry picked from commit e6b8181) Modified the cherry-picked test as diagnostics differ on the branch. Fixes clangd/clangd#421
1 parent 52f2d6d commit 357e79c

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

clang-tools-extra/clangd/Selection.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "Logger.h"
1111
#include "SourceCode.h"
1212
#include "clang/AST/ASTTypeTraits.h"
13+
#include "clang/AST/Decl.h"
1314
#include "clang/AST/DeclCXX.h"
1415
#include "clang/AST/Expr.h"
1516
#include "clang/AST/ExprCXX.h"
@@ -594,13 +595,23 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
594595
// Usually empty, but sometimes children cover tokens but shouldn't own them.
595596
SourceRange earlySourceRange(const DynTypedNode &N) {
596597
if (const Decl *D = N.get<Decl>()) {
598+
// We want constructor name to be claimed by TypeLoc not the constructor
599+
// itself. Similar for deduction guides, we rather want to select the
600+
// underlying TypeLoc.
601+
// FIXME: Unfortunately this doesn't work, even though RecursiveASTVisitor
602+
// traverses the underlying TypeLoc inside DeclarationName, it is null for
603+
// constructors.
604+
if (isa<CXXConstructorDecl>(D) || isa<CXXDeductionGuideDecl>(D))
605+
return SourceRange();
606+
// This will capture Field, Function, MSProperty, NonTypeTemplateParm and
607+
// VarDecls. We want the name in the declarator to be claimed by the decl
608+
// and not by any children. For example:
597609
// void [[foo]]();
598-
if (auto *FD = llvm::dyn_cast<FunctionDecl>(D))
599-
return FD->getNameInfo().getSourceRange();
600610
// int (*[[s]])();
601-
else if (auto *VD = llvm::dyn_cast<VarDecl>(D))
602-
return VD->getLocation();
603-
} else if (const auto* CCI = N.get<CXXCtorInitializer>()) {
611+
// struct X { int [[hash]] [32]; [[operator]] int();}
612+
if (const auto *DD = llvm::dyn_cast<DeclaratorDecl>(D))
613+
return DD->getLocation();
614+
} else if (const auto *CCI = N.get<CXXCtorInitializer>()) {
604615
// : [[b_]](42)
605616
return CCI->getMemberLocation();
606617
}

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ class Foo {})cpp";
339339
HI.Definition = "~X()";
340340
HI.Parameters.emplace();
341341
}},
342-
{"class X { operator [[in^t]](); };",
342+
{"class X { [[op^erator]] int(); };",
343343
[](HoverInfo &HI) {
344344
HI.NamespaceScope = "";
345345
HI.Name = "operator int";
@@ -348,6 +348,13 @@ class Foo {})cpp";
348348
HI.Definition = "operator int()";
349349
HI.Parameters.emplace();
350350
}},
351+
{"class X { operator [[^X]]*(); };",
352+
[](HoverInfo &HI) {
353+
HI.NamespaceScope = "";
354+
HI.Name = "X";
355+
HI.Kind = index::SymbolKind::Class;
356+
HI.Definition = "class X {}";
357+
}},
351358

352359
// auto on lambda
353360
{R"cpp(

clang-tools-extra/clangd/unittests/SelectionTests.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,12 @@ TEST(SelectionTest, CommonAncestor) {
329329
decltype([[^a]] + a) b;
330330
)cpp",
331331
"DeclRefExpr"},
332+
333+
{"struct foo { [[int has^h<:32:>]]; };", "FieldDecl"},
334+
{"struct foo { [[op^erator int()]]; };", "CXXConversionDecl"},
335+
{"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"},
336+
// FIXME: The following to should be class itself instead.
337+
{"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"},
332338
};
333339
for (const Case &C : Cases) {
334340
Annotations Test(C.Code);

0 commit comments

Comments
 (0)