From f16eeb943facb90735c606d63e18d9f31f5e77f8 Mon Sep 17 00:00:00 2001 From: Balazs Keri <1.int32@gmail.com> Date: Tue, 7 May 2019 10:55:11 +0000 Subject: [PATCH] [ASTImporter] Import TemplateParameterLists in function templates. Summary: Correct missing import of TemplateParameterList in function decl. Reviewers: martong, a.sidorin, shafik Reviewed By: martong Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D60461 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360132 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTImporter.cpp | 21 +++++++++++++++++++++ unittests/AST/ASTImporterTest.cpp | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 1ac4870cab..da0d68900a 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -419,6 +419,8 @@ namespace clang { Expected ImportFunctionTemplateWithTemplateArgsFromSpecialization( FunctionDecl *FromFD); + Error ImportTemplateParameterLists(const DeclaratorDecl *FromD, + DeclaratorDecl *ToD); Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD); @@ -2780,6 +2782,22 @@ ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) { return ToEnumerator; } +Error ASTNodeImporter::ImportTemplateParameterLists(const DeclaratorDecl *FromD, + DeclaratorDecl *ToD) { + unsigned int Num = FromD->getNumTemplateParameterLists(); + if (Num == 0) + return Error::success(); + SmallVector ToTPLists(Num); + for (unsigned int I = 0; I < Num; ++I) + if (Expected ToTPListOrErr = + import(FromD->getTemplateParameterList(I))) + ToTPLists[I] = *ToTPListOrErr; + else + return ToTPListOrErr.takeError(); + ToD->setTemplateParameterListsInfo(Importer.ToContext, ToTPLists); + return Error::success(); +} + Error ASTNodeImporter::ImportTemplateInformation( FunctionDecl *FromFD, FunctionDecl *ToFD) { switch (FromFD->getTemplatedKind()) { @@ -2826,6 +2844,9 @@ Error ASTNodeImporter::ImportTemplateInformation( if (!POIOrErr) return POIOrErr.takeError(); + if (Error Err = ImportTemplateParameterLists(FromFD, ToFD)) + return Err; + TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind(); ToFD->setFunctionTemplateSpecialization( std::get<0>(*FunctionAndArgsOrErr), ToTAList, /* InsertPos= */ nullptr, diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp index 7cac2b5703..952e6f92db 100644 --- a/unittests/AST/ASTImporterTest.cpp +++ b/unittests/AST/ASTImporterTest.cpp @@ -5083,6 +5083,24 @@ TEST_P(ASTImporterOptionSpecificTestBase, EXPECT_FALSE(ImportedD->getUnderlyingType()->isIncompleteType()); } +TEST_P(ASTImporterOptionSpecificTestBase, ImportTemplateParameterLists) { + auto Code = + R"( + template + int f() { return 0; } + template <> int f() { return 4; } + )"; + + Decl *FromTU = getTuDecl(Code, Lang_CXX); + auto *FromD = FirstDeclMatcher().match(FromTU, + functionDecl(hasName("f"), isExplicitTemplateSpecialization())); + ASSERT_EQ(FromD->getNumTemplateParameterLists(), 1); + + auto *ToD = Import(FromD, Lang_CXX); + // The template parameter list should exist. + EXPECT_EQ(ToD->getNumTemplateParameterLists(), 1); +} + struct ASTImporterLookupTableTest : ASTImporterOptionSpecificTestBase {}; TEST_P(ASTImporterLookupTableTest, OneDecl) { -- 2.40.0