diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h --- a/clang-tools-extra/clangd/AST.h +++ b/clang-tools-extra/clangd/AST.h @@ -81,7 +81,7 @@ /// Example: shortenNamespace("ns1::MyClass", "ns1") /// --> "MyClass" std::string shortenNamespace(const llvm::StringRef OriginalName, - const llvm::StringRef CurrentNamespace); + const llvm::StringRef CurrentNamespace); } // namespace clangd 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/ClangdUnitTests.cpp b/clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp --- a/clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdUnitTests.cpp @@ -103,6 +103,20 @@ EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main"))); } +TEST(ClangdUnitTest, DoesNotGetImplicitTemplateTopDecls) { + TestTU TU; + TU.Code = R"cpp( + template + void f(T) {} + void s() { + f(10UL); + } + )cpp"; + auto AST = TU.build(); + EXPECT_THAT(AST.getLocalTopLevelDecls(), + ElementsAre(DeclNamed("f"), DeclNamed("s"))); +} + TEST(ClangdUnitTest, TokensAfterPreamble) { TestTU TU; TU.AdditionalFiles["foo.h"] = R"(