diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -47,8 +47,10 @@ return II && !II->getName().empty(); } -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; @@ -59,7 +61,8 @@ } 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; @@ -106,21 +109,25 @@ 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 (auto *TD = TP->getAsTagDecl()) - return kindForDecl(TD); + return kindForDecl(TD, Resolver); return llvm::None; } @@ -371,11 +378,14 @@ 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; HighlightingToken Dummy; // returned from addToken(InvalidLoc) }; @@ -427,7 +437,7 @@ 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())) @@ -440,7 +450,8 @@ 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())) @@ -551,7 +562,7 @@ 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 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -652,10 +652,10 @@ }; template struct $Class_decl[[Derived]] : $Class[[Base]]<$TemplateParameter[[T]]> { - using $Class[[Base]]<$TemplateParameter[[T]]>::$Unknown_decl_dependentName[[member]]; + using $Class[[Base]]<$TemplateParameter[[T]]>::$Field_decl_dependentName[[member]]; void $Method_decl[[method]]() { - (void)$Unknown_dependentName[[member]]; + (void)$Field_dependentName[[member]]; } }; )cpp",