diff --git a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp --- a/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp +++ b/clang-tools-extra/clangd/unittests/ParsedASTTests.cpp @@ -104,6 +104,14 @@ EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main"))); } +TEST(ParsedASTTest, VarTemplateDecl) { + TestTU TU; + TU.Code = "template bool X = true;"; + auto AST = TU.build(); + EXPECT_THAT(AST.getLocalTopLevelDecls(), + ElementsAre(AllOf(DeclNamed("X"), WithTemplateArgs("")))); +} + TEST(ParsedASTTest, DoesNotGetIncludedTopDecls) { TestTU TU; TU.HeaderCode = R"cpp( diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2195,6 +2195,7 @@ // Inform the current actions module that we just parsed this declarator. Decl *ThisDecl = nullptr; + VarTemplateDecl *VarTemplateD = nullptr; switch (TemplateInfo.Kind) { case ParsedTemplateInfo::NonTemplate: ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); @@ -2205,10 +2206,12 @@ ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), *TemplateInfo.TemplateParams, D); - if (VarTemplateDecl *VT = dyn_cast_or_null(ThisDecl)) + if (VarTemplateDecl *VT = dyn_cast_or_null(ThisDecl)) { // Re-direct this decl to refer to the templated decl so that we can // initialize it. ThisDecl = VT->getTemplatedDecl(); + VarTemplateD = VT; + } break; } case ParsedTemplateInfo::ExplicitInstantiation: { @@ -2385,8 +2388,7 @@ } Actions.FinalizeDeclaration(ThisDecl); - - return ThisDecl; + return VarTemplateD ? VarTemplateD : ThisDecl; } /// ParseSpecifierQualifierList