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 @@ -57,6 +57,12 @@ return false; } +MATCHER_P(DeclKind, Kind, "") { + if (NamedDecl *ND = dyn_cast(arg)) + return ND->getDeclKindName() == Kind; + return false; +} + // Matches if the Decl has template args equal to ArgName. If the decl is a // NamedDecl and ArgName is an empty string it also matches. MATCHER_P(WithTemplateArgs, ArgName, "") { @@ -99,9 +105,23 @@ int header1(); int header2; )"; - TU.Code = "int main();"; + TU.Code = R"cpp( + int main(); + template bool X = true; + )cpp"; auto AST = TU.build(); - EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main"))); + EXPECT_THAT( + AST.getLocalTopLevelDecls(), + ElementsAreArray({AllOf(DeclNamed("main"), DeclKind("Function")), + AllOf(DeclNamed("X"), DeclKind("VarTemplate"))})); +} + +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) { 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; + Decl *OuterDecl = 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(); + OuterDecl = VT; + } break; } case ParsedTemplateInfo::ExplicitInstantiation: { @@ -2385,8 +2388,7 @@ } Actions.FinalizeDeclaration(ThisDecl); - - return ThisDecl; + return OuterDecl ? OuterDecl : ThisDecl; } /// ParseSpecifierQualifierList