qchateau updated this revision to Diff 310872.
qchateau added a comment.
Fix unittests and behavior
I've fixed the failing unittests, added some more
to test the new behavior, and fixed some bugs in
the new code.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92977/new/
https://reviews.llvm.org/D92977
Files:
clang-tools-extra/clangd/Hover.cpp
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/HoverTests.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -624,6 +624,140 @@
struct Fo^o<T*> {};
)cpp",
+ R"cpp(// auto builtin type (not supported)
+ au^to x = 42;
+ )cpp",
+
+ R"cpp(// auto on lambda
+ auto x = [[[]]]{};
+ au^to y = x;
+ )cpp",
+
+ R"cpp(// auto on struct
+ namespace ns1 {
+ struct [[S1]] {};
+ } // namespace ns1
+
+ au^to x = ns1::S1{};
+ )cpp",
+
+ R"cpp(// decltype on struct
+ namespace ns1 {
+ struct [[S1]] {};
+ } // namespace ns1
+
+ ns1::S1 i;
+ decl^type(i) j;
+ )cpp",
+
+ R"cpp(// decltype(auto) on struct
+ namespace ns1 {
+ struct [[S1]] {};
+ } // namespace ns1
+
+ ns1::S1 i;
+ ns1::S1& j = i;
+ decl^type(auto) k = j;
+ )cpp",
+
+ R"cpp(// auto on template class
+ template<typename T> class [[Foo]] {};
+
+ au^to x = Foo<int>();
+ )cpp",
+
+ R"cpp(// auto on template class with forward declared class
+ template<typename T> class [[Foo]] {};
+ class X;
+
+ au^to x = Foo<X>();
+ )cpp",
+
+ R"cpp(// auto on specialized template class
+ template<typename T> class Foo {};
+ template<> class [[Foo]]<int> {};
+
+ au^to x = Foo<int>();
+ )cpp",
+
+ R"cpp(// auto on initializer list.
+ namespace std
+ {
+ template<class _E>
+ class [[initializer_list]] {};
+ }
+
+ au^to i = {1,2};
+ )cpp",
+
+ R"cpp(// auto function return with trailing type
+ struct [[Bar]] {};
+ au^to test() -> decltype(Bar()) {
+ return Bar();
+ }
+ )cpp",
+
+ R"cpp(// decltype in trailing return type
+ struct [[Bar]] {};
+ auto test() -> decl^type(Bar()) {
+ return Bar();
+ }
+ )cpp",
+
+ R"cpp(// auto in function return
+ struct [[Bar]] {};
+ au^to test() {
+ return Bar();
+ }
+ )cpp",
+
+ R"cpp(// auto& in function return
+ struct [[Bar]] {};
+ au^to& test() {
+ static Bar x;
+ return x;
+ }
+ )cpp",
+
+ R"cpp(// auto* in function return
+ struct [[Bar]] {};
+ au^to* test() {
+ Bar* x;
+ return x;
+ }
+ )cpp",
+
+ R"cpp(// const auto& in function return
+ struct [[Bar]] {};
+ const au^to& test() {
+ static Bar x;
+ return x;
+ }
+ )cpp",
+
+ R"cpp(// decltype(auto) in function return
+ struct [[Bar]] {};
+ decl^type(auto) test() {
+ return Bar();
+ }
+ )cpp",
+
+ R"cpp(// decltype of function with trailing return type.
+ struct [[Bar]] {};
+ auto test() -> decltype(Bar()) {
+ return Bar();
+ }
+ void foo() {
+ decl^type(test()) i = test();
+ }
+ )cpp",
+
+ R"cpp(// auto on alias
+ struct [[cls]] {};
+ typedef cls cls_type;
+ au^to y = cls_type();
+ )cpp",
+
R"cpp(// Override specifier jumps to overridden method
class Y { virtual void $decl[[a]]() = 0; };
class X : Y { void a() ^override {} };
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -388,6 +388,9 @@
[](HoverInfo &HI) {
HI.Name = "(lambda)";
HI.Kind = index::SymbolKind::Class;
+ HI.NamespaceScope = "";
+ HI.LocalScope = "foo::";
+ HI.Definition = "class {}";
}},
// auto on template instantiation
{R"cpp(
@@ -399,6 +402,8 @@
[](HoverInfo &HI) {
HI.Name = "Foo<int>";
HI.Kind = index::SymbolKind::Class;
+ HI.NamespaceScope = "";
+ HI.Definition = "template <> class Foo<int> {}";
}},
// auto on specialized template
{R"cpp(
@@ -411,6 +416,8 @@
[](HoverInfo &HI) {
HI.Name = "Foo<int>";
HI.Kind = index::SymbolKind::Class;
+ HI.NamespaceScope = "";
+ HI.Definition = "template <> class Foo<int> {}";
}},
// macro
@@ -584,6 +591,8 @@
[](HoverInfo &HI) {
HI.Name = "Foo<X>";
HI.Kind = index::SymbolKind::Class;
+ HI.NamespaceScope = "";
+ HI.Definition = "template <> class Foo<X> {}";
}},
{// Falls back to primary template, when the type is not instantiated.
R"cpp(
@@ -1593,6 +1602,8 @@
[](HoverInfo &HI) {
HI.Name = "initializer_list<int>";
HI.Kind = index::SymbolKind::Class;
+ HI.NamespaceScope = "std::";
+ HI.Definition = "template <> class initializer_list<int> {}";
}},
{
R"cpp(// User defined conversion to auto
@@ -1651,6 +1662,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "auto function return with trailing type";
}},
{
@@ -1663,6 +1676,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "trailing return type";
}},
{
@@ -1675,6 +1690,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "auto in function return";
}},
{
@@ -1688,6 +1705,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "auto& in function return";
}},
{
@@ -1701,6 +1720,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "auto* in function return";
}},
{
@@ -1714,6 +1735,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "const auto& in function return";
}},
{
@@ -1726,6 +1749,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation = "decltype(auto) in function return";
}},
{
@@ -1791,6 +1816,8 @@
[](HoverInfo &HI) {
HI.Name = "Bar";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct Bar {}";
HI.Documentation =
"decltype of function with trailing return type.";
}},
@@ -1837,10 +1864,12 @@
[](HoverInfo &HI) {
HI.Name = "cls";
HI.Kind = index::SymbolKind::Struct;
+ HI.NamespaceScope = "";
+ HI.Definition = "struct cls {}";
HI.Documentation = "auto on alias";
}},
{
- R"cpp(// auto on alias
+ R"cpp(// auto on template
template <class>
struct templ {};
^[[auto]] z = templ<int>();
@@ -1848,7 +1877,9 @@
[](HoverInfo &HI) {
HI.Name = "templ<int>";
HI.Kind = index::SymbolKind::Struct;
- HI.Documentation = "auto on alias";
+ HI.NamespaceScope = "";
+ HI.Definition = "template <> struct templ<int> {}";
+ HI.Documentation = "auto on template";
}},
{
R"cpp(// should not crash.
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -667,15 +667,45 @@
return {};
}
- const syntax::Token *TouchedIdentifier =
- syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
- if (TouchedIdentifier)
- if (auto Macro =
- locateMacroReferent(*TouchedIdentifier, AST, *MainFilePath))
- // Don't look at the AST or index if we have a macro result.
- // (We'd just return declarations referenced from the macro's
- // expansion.)
- return {*std::move(Macro)};
+ const syntax::Token *TouchedIdentifier = nullptr;
+ auto TokensTouchingCursor =
+ syntax::spelledTokensTouching(*CurLoc, AST.getTokens());
+ for (const syntax::Token &Tok : TokensTouchingCursor) {
+ if (Tok.kind() == tok::identifier) {
+ if (auto Macro = locateMacroReferent(Tok, AST, *MainFilePath))
+ // Don't look at the AST or index if we have a macro result.
+ // (We'd just return declarations referenced from the macro's
+ // expansion.)
+ return {*std::move(Macro)};
+
+ TouchedIdentifier = &Tok;
+ break;
+ }
+
+ if (Tok.kind() == tok::kw_auto || Tok.kind() == tok::kw_decltype) {
+ if (auto Deduced = getDeducedType(AST.getASTContext(), Tok.location())) {
+ Deduced = Deduced->getNonReferenceType();
+ const NamedDecl *D = Deduced->getTypePtr()->getAsTagDecl();
+ if (!D)
+ continue;
+
+ D = getPreferredDecl(D);
+ auto Loc = makeLocation(AST.getASTContext(), nameLocation(*D, SM),
+ *MainFilePath);
+ if (!Loc)
+ continue;
+
+ LocatedSymbol LocSym;
+ LocSym.Name = printName(AST.getASTContext(), *D);
+ LocSym.PreferredDeclaration = *Loc;
+ if (const NamedDecl *Def = getDefinition(D))
+ LocSym.Definition = makeLocation(
+ AST.getASTContext(), nameLocation(*Def, SM), *MainFilePath);
+
+ return {std::move(LocSym)};
+ }
+ }
+ }
ASTNodeKind NodeKind;
auto ASTResults = locateASTReferent(*CurLoc, TouchedIdentifier, AST,
Index: clang-tools-extra/clangd/Hover.cpp
===================================================================
--- clang-tools-extra/clangd/Hover.cpp
+++ clang-tools-extra/clangd/Hover.cpp
@@ -556,12 +556,7 @@
HoverInfo HI;
if (const auto *D = T->getAsTagDecl()) {
- HI.Name = printName(ASTCtx, *D);
- HI.Kind = index::getSymbolInfo(D).Kind;
-
- const auto *CommentD = getDeclForComment(D);
- HI.Documentation = getDeclComment(ASTCtx, *CommentD);
- enhanceFromIndex(HI, *CommentD, Index);
+ return getHoverContents(D, Index);
} else {
// Builtin types
auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits