From d941863de2becb3d8d2e00676fc7125974934c7f Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Mon, 22 Mar 2021 02:43:41 -0400 Subject: [PATCH] [clangd] Use HeuristicResolver to produce a better semantic token for name referring to UnresolvedUsingValueDecl Fixes https://github.com/clangd/clangd/issues/686 Differential Revision: https://reviews.llvm.org/D99056 --- clang-tools-extra/clangd/SemanticHighlighting.cpp | 33 ++++++++++++++-------- .../clangd/unittests/SemanticHighlightingTests.cpp | 4 +-- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index c4cb57e..ffd6fdc 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -64,8 +64,10 @@ bool canHighlightName(DeclarationName Name) { llvm_unreachable("invalid name kind"); } -llvm::Optional kindForType(const Type *TP); -llvm::Optional kindForDecl(const NamedDecl *D) { +llvm::Optional kindForType(const Type *TP, + const HeuristicResolver *Resolver); +llvm::Optional +kindForDecl(const NamedDecl *D, const HeuristicResolver *Resolver) { if (auto *USD = dyn_cast(D)) { if (auto *Target = USD->getTargetDecl()) D = Target; @@ -76,7 +78,8 @@ llvm::Optional kindForDecl(const NamedDecl *D) { } if (auto *TD = dyn_cast(D)) { // We try to highlight typedefs as their underlying type. - if (auto K = kindForType(TD->getUnderlyingType().getTypePtrOrNull())) + if (auto K = + kindForType(TD->getUnderlyingType().getTypePtrOrNull(), Resolver)) return K; // And fallback to a generic kind if this fails. return HighlightingKind::Typedef; @@ -133,23 +136,27 @@ llvm::Optional kindForDecl(const NamedDecl *D) { return HighlightingKind::TemplateParameter; if (isa(D)) return HighlightingKind::Concept; - if (isa(D)) { - // FIXME: We may be able to do better using HeuristicResolver. + if (const auto *UUVD = dyn_cast(D)) { + auto Targets = Resolver->resolveUsingValueDecl(UUVD); + if (!Targets.empty()) { + return kindForDecl(Targets[0], Resolver); + } return HighlightingKind::Unknown; } return llvm::None; } -llvm::Optional kindForType(const Type *TP) { +llvm::Optional +kindForType(const Type *TP, const HeuristicResolver *Resolver) { if (!TP) return llvm::None; if (TP->isBuiltinType()) // Builtins are special, they do not have decls. return HighlightingKind::Primitive; if (auto *TD = dyn_cast(TP)) - return kindForDecl(TD->getDecl()); + return kindForDecl(TD->getDecl(), Resolver); if (isa(TP)) return HighlightingKind::Class; if (auto *TD = TP->getAsTagDecl()) - return kindForDecl(TD); + return kindForDecl(TD, Resolver); return llvm::None; } @@ -400,11 +407,14 @@ public: return WithInactiveLines; } + const HeuristicResolver *getResolver() const { return Resolver; } + private: const syntax::TokenBuffer &TB; const SourceManager &SourceMgr; const LangOptions &LangOpts; std::vector Tokens; + const HeuristicResolver *Resolver; // returned from addToken(InvalidLoc) HighlightingToken InvalidHighlightingToken; }; @@ -457,7 +467,7 @@ public: CollectExtraHighlightings(HighlightingsBuilder &H) : H(H) {} bool VisitDecltypeTypeLoc(DecltypeTypeLoc L) { - if (auto K = kindForType(L.getTypePtr())) { + if (auto K = kindForType(L.getTypePtr(), H.getResolver())) { auto &Tok = H.addToken(L.getBeginLoc(), *K) .addModifier(HighlightingModifier::Deduced); if (auto Mod = scopeModifier(L.getTypePtr())) @@ -470,7 +480,8 @@ public: auto *AT = D->getType()->getContainedAutoType(); if (!AT) return true; - if (auto K = kindForType(AT->getDeducedType().getTypePtrOrNull())) { + if (auto K = kindForType(AT->getDeducedType().getTypePtrOrNull(), + H.getResolver())) { auto &Tok = H.addToken(D->getTypeSpecStartLoc(), *K) .addModifier(HighlightingModifier::Deduced); if (auto Mod = scopeModifier(AT->getDeducedType().getTypePtrOrNull())) @@ -611,7 +622,7 @@ std::vector getSemanticHighlightings(ParsedAST &AST) { for (const NamedDecl *Decl : R.Targets) { if (!canHighlightName(Decl->getDeclName())) continue; - auto Kind = kindForDecl(Decl); + auto Kind = kindForDecl(Decl, AST.getHeuristicResolver()); if (!Kind) continue; auto &Tok = Builder.addToken(R.NameLoc, *Kind); diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp index 7e979ee..d36470b 100644 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -695,10 +695,10 @@ sizeof...($TemplateParameter[[Elements]]); }; template struct $Class_decl[[Derived]] : $Class[[Base]]<$TemplateParameter[[T]]> { - using $Class[[Base]]<$TemplateParameter[[T]]>::$Unknown_dependentName[[member]]; + using $Class[[Base]]<$TemplateParameter[[T]]>::$Field_dependentName[[member]]; void $Method_decl[[method]]() { - (void)$Unknown_dependentName[[member]]; + (void)$Field_dependentName[[member]]; } }; )cpp", -- 2.7.4