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 @@ -224,6 +224,28 @@ addToken(Loc, HighlightingKind::TemplateParameter); return; } + if (const auto *NTP = dyn_cast(D)) { + if (const auto *T = NTP->getTypeSourceInfo()) + if (const auto *TP = T->getTypeLoc().getTypePtr()) { + if (TP->isFunctionPointerType()) { + addToken(Loc, HighlightingKind::Function); + return; + } + if (TP->isMemberFunctionPointerType()) { + addToken(Loc, HighlightingKind::Method); + return; + } + if (TP->isPointerType() || TP->isLValueReferenceType()) { + addToken(Loc, HighlightingKind::Variable); + return; + } + } + // If it's not a function ptr, member ptr, ptr or reference that means it + // is probably a builtin value. Those should just be highlighted as normal + // TemplateParameters. + addToken(Loc, HighlightingKind::TemplateParameter); + return; + } } void addToken(SourceLocation Loc, HighlightingKind 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 @@ -323,6 +323,59 @@ $Primitive[[auto]] $Variable[[Form]] = 10.2 + 2 * 4; $Primitive[[decltype]]($Variable[[Form]]) $Variable[[F]] = 10; auto $Variable[[Fun]] = []()->$Primitive[[void]]{}; + )cpp", + R"cpp( + class $Class[[G]] {}; + template<$Class[[G]] *$Variable[[U]]> + class $Class[[GP]] {}; + template<$Class[[G]] &$Variable[[U]]> + class $Class[[GR]] {}; + template<$Primitive[[int]] *$Variable[[U]]> + class $Class[[IP]] { + $Primitive[[void]] $Method[[f]]() { + *$Variable[[U]] += 5; + } + }; + template<$Primitive[[unsigned]] $TemplateParameter[[U]] = 2> + class $Class[[Foo]] { + $Primitive[[void]] $Method[[f]]() { + for($Primitive[[int]] $Variable[[I]] = 0; + $Variable[[I]] < $TemplateParameter[[U]];) {} + } + }; + + $Class[[G]] $Variable[[L]]; + $Primitive[[void]] $Function[[f]]() { + $Class[[Foo]]<123> $Variable[[F]]; + $Class[[GP]]<&$Variable[[L]]> $Variable[[LL]]; + $Class[[GR]]<$Variable[[L]]> $Variable[[LLL]]; + } + )cpp", + R"cpp( + template + struct $Class[[G]] { + $Primitive[[void]] $Method[[foo]]( + $TemplateParameter[[T]] *$Variable[[O]]) { + ($Variable[[O]]->*$Method[[method]])(10); + } + }; + struct $Class[[F]] { + $Primitive[[void]] $Method[[f]]($Primitive[[int]]); + }; + template<$Primitive[[void]] (*$Function[[Func]])()> + struct $Class[[A]] { + $Primitive[[void]] $Method[[f]]() { + (*$Function[[Func]])(); + } + }; + + $Primitive[[void]] $Function[[foo]]() { + $Class[[F]] $Variable[[FF]]; + $Class[[G]]<$Class[[F]], &$Class[[F]]::$Method[[f]]> $Variable[[GG]]; + $Variable[[GG]].$Method[[foo]](&$Variable[[FF]]); + $Class[[A]]<$Function[[foo]]> $Variable[[AA]]; + } )cpp"}; for (const auto &TestCase : TestCases) { checkHighlightings(TestCase);