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 @@ -258,6 +258,25 @@ return true; } + bool VisitDependentTemplateSpecializationTypeLoc( + DependentTemplateSpecializationTypeLoc L) { + H.addToken(L.getTemplateNameLoc(), HighlightingKind::DependentType); + return true; + } + + // findExplicitReferences will walk nested-name-specifiers and + // find anything that can be resolved to a Decl. However, non-leaf + // components of nested-name-specifiers which are dependent names + // (kind "Identifier") cannot be resolved to a decl, so we visit + // them here. + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc Q) { + if (NestedNameSpecifier *NNS = Q.getNestedNameSpecifier()) { + if (NNS->getKind() == NestedNameSpecifier::Identifier) + H.addToken(Q.getLocalBeginLoc(), HighlightingKind::DependentType); + } + return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(Q); + } + private: HighlightingsBuilder &H; }; 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 @@ -630,7 +630,24 @@ R"cpp( template struct $Class[[TupleSize]] { - static const int $StaticField[[size]] = sizeof...($TemplateParameter[[Elements]]); + static const int $StaticField[[size]] = +sizeof...($TemplateParameter[[Elements]]); + }; + )cpp", + // More dependent types + R"cpp( + template + struct $Class[[Waldo]] { + using $Typedef[[Location1]] = typename $TemplateParameter[[T]] + ::$DependentType[[Resolver]]::$DependentType[[Location]]; + using $Typedef[[Location2]] = typename $TemplateParameter[[T]] + ::template $DependentType[[Resolver]]<$TemplateParameter[[T]]> + ::$DependentType[[Location]]; + using $Typedef[[Location3]] = typename $TemplateParameter[[T]] + ::$DependentType[[Resolver]] + ::template $DependentType[[Location]]<$TemplateParameter[[T]]>; + static const int $StaticField[[Value]] = $TemplateParameter[[T]] + ::$DependentType[[Resolver]]::$DependentName[[Value]]; }; )cpp"}; for (const auto &TestCase : TestCases) {