[clang-tools-extra] d941863 - [clangd] Use HeuristicResolver to produce a better semantic token for name referring to UnresolvedUsingValueDecl

Nathan Ridge via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 25 13:45:28 PDT 2021


Author: Nathan Ridge
Date: 2021-04-25T16:45:04-04:00
New Revision: d941863de2becb3d8d2e00676fc7125974934c7f

URL: https://github.com/llvm/llvm-project/commit/d941863de2becb3d8d2e00676fc7125974934c7f
DIFF: https://github.com/llvm/llvm-project/commit/d941863de2becb3d8d2e00676fc7125974934c7f.diff

LOG: [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

Added: 
    

Modified: 
    clang-tools-extra/clangd/SemanticHighlighting.cpp
    clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index c4cb57e3f32b..ffd6fdc361d2 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<HighlightingKind> kindForType(const Type *TP);
-llvm::Optional<HighlightingKind> kindForDecl(const NamedDecl *D) {
+llvm::Optional<HighlightingKind> kindForType(const Type *TP,
+                                             const HeuristicResolver *Resolver);
+llvm::Optional<HighlightingKind>
+kindForDecl(const NamedDecl *D, const HeuristicResolver *Resolver) {
   if (auto *USD = dyn_cast<UsingShadowDecl>(D)) {
     if (auto *Target = USD->getTargetDecl())
       D = Target;
@@ -76,7 +78,8 @@ llvm::Optional<HighlightingKind> kindForDecl(const NamedDecl *D) {
   }
   if (auto *TD = dyn_cast<TypedefNameDecl>(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<HighlightingKind> kindForDecl(const NamedDecl *D) {
     return HighlightingKind::TemplateParameter;
   if (isa<ConceptDecl>(D))
     return HighlightingKind::Concept;
-  if (isa<UnresolvedUsingValueDecl>(D)) {
-    // FIXME: We may be able to do better using HeuristicResolver.
+  if (const auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(D)) {
+    auto Targets = Resolver->resolveUsingValueDecl(UUVD);
+    if (!Targets.empty()) {
+      return kindForDecl(Targets[0], Resolver);
+    }
     return HighlightingKind::Unknown;
   }
   return llvm::None;
 }
-llvm::Optional<HighlightingKind> kindForType(const Type *TP) {
+llvm::Optional<HighlightingKind>
+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<TemplateTypeParmType>(TP))
-    return kindForDecl(TD->getDecl());
+    return kindForDecl(TD->getDecl(), Resolver);
   if (isa<ObjCObjectPointerType>(TP))
     return HighlightingKind::Class;
   if (auto *TD = TP->getAsTagDecl())
-    return kindForDecl(TD);
+    return kindForDecl(TD, Resolver);
   return llvm::None;
 }
 
@@ -400,11 +407,14 @@ class HighlightingsBuilder {
     return WithInactiveLines;
   }
 
+  const HeuristicResolver *getResolver() const { return Resolver; }
+
 private:
   const syntax::TokenBuffer &TB;
   const SourceManager &SourceMgr;
   const LangOptions &LangOpts;
   std::vector<HighlightingToken> Tokens;
+  const HeuristicResolver *Resolver;
   // returned from addToken(InvalidLoc)
   HighlightingToken InvalidHighlightingToken;
 };
@@ -457,7 +467,7 @@ class CollectExtraHighlightings
   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 @@ class CollectExtraHighlightings
     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<HighlightingToken> 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 7e979ee4e75d..d36470b6b611 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 <typename $TemplateParameter_decl[[T]]>
         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",


        


More information about the cfe-commits mailing list