diff --git a/clang-tools-extra/clangd/ClangdUnit.cpp b/clang-tools-extra/clangd/ClangdUnit.cpp --- a/clang-tools-extra/clangd/ClangdUnit.cpp +++ b/clang-tools-extra/clangd/ClangdUnit.cpp @@ -19,8 +19,11 @@ #include "index/CanonicalIncludes.h" #include "index/Index.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TokenKinds.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" @@ -60,6 +63,12 @@ return Vec.capacity() * sizeof(T); } +template bool isImplicitTemplateInstantiation(const Decl *D) { + if (const auto *TD = dyn_cast(D)) + return TD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation; + return false; +} + class DeclTrackingASTConsumer : public ASTConsumer { public: DeclTrackingASTConsumer(std::vector &TopLevelDecls) @@ -70,6 +79,10 @@ auto &SM = D->getASTContext().getSourceManager(); if (!isInsideMainFile(D->getLocation(), SM)) continue; + if (isImplicitTemplateInstantiation(D) || + isImplicitTemplateInstantiation(D) || + isImplicitTemplateInstantiation(D)) + continue; // ObjCMethodDecl are not actually top-level decls. if (isa(D)) 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 @@ -214,7 +214,25 @@ template void $Function[[foo]]($TemplateParameter[[T]] ...); - )cpp"}; + )cpp", + R"cpp( + class $Class[[Foo]] { + public: + template + void $Method[[ff]]($TemplateParameter[[T1]]) {} + }; + template + void $Function[[ff]]($TemplateParameter[[T1]]) {} + enum $Enum[[E]] { $EnumConstant[[VALUE]] }; + void $Function[[s]]() { + $Function[[ff]]($EnumConstant[[VALUE]]); + $Function[[ff]]($Class[[Foo]]()); + $Class[[Foo]] $Variable[[s]]; + $Variable[[s]].$Method[[ff]]($EnumConstant[[VALUE]]); + $Variable[[s]].$Method[[ff]]($Class[[Foo]]()); + } + )cpp" + }; for (const auto &TestCase : TestCases) { checkHighlightings(TestCase); }