Skip to content
This repository has been archived by the owner on Mar 30, 2021. It is now read-only.

Commit

Permalink
Import default template args
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabor Marton committed Mar 22, 2018
1 parent 6ef11d8 commit f2cc841
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 3 deletions.
11 changes: 8 additions & 3 deletions lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4172,9 +4172,7 @@ Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
// For template arguments, we adopt the translation unit as our declaration
// context. This context will be fixed when the actual template declaration
// is created.

// FIXME: Import default argument.
return TemplateTypeParmDecl::Create(Importer.getToContext(),
auto ToD = TemplateTypeParmDecl::Create(Importer.getToContext(),
Importer.getToContext().getTranslationUnitDecl(),
Importer.Import(D->getLocStart()),
Importer.Import(D->getLocation()),
Expand All @@ -4183,6 +4181,13 @@ Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Importer.Import(D->getIdentifier()),
D->wasDeclaredWithTypename(),
D->isParameterPack());
Importer.Imported(D, ToD);
if (D->hasDefaultArgument()) {
TypeSourceInfo *ToDefaultArgInfo =
Importer.Import(D->getDefaultArgumentInfo());
ToD->setDefaultArgument(ToDefaultArgInfo);
}
return ToD;
}

Decl *
Expand Down
82 changes: 82 additions & 0 deletions unittests/AST/ASTImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2392,5 +2392,87 @@ long b = strtol(&a);
EXPECT_EQ(DeclCounter<UsingShadowDecl>().match(ToTU, usingShadowDecl()), 1u);
}

TEST_F(Fixture, ShouldImportDefaultTemplateArg) {
Decl *FromTU =
getTuDecl("template <class T=int> struct X{};", Lang_CXX, "input0.cc");
auto FromD =
FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());

{
auto TPL = FromD->getTemplateParameters();
ASSERT_EQ((TPL->end() - TPL->begin()), 1);
TemplateTypeParmDecl *ParmD = cast<TemplateTypeParmDecl>(*(TPL->begin()));
ASSERT_TRUE(ParmD->hasDefaultArgument());
}

{
auto ToD = cast<ClassTemplateDecl>(Import(FromD, Lang_CXX));
auto TPL = ToD->getTemplateParameters();
ASSERT_EQ((TPL->end() - TPL->begin()), 1);
TemplateTypeParmDecl *ParmD = cast<TemplateTypeParmDecl>(*(TPL->begin()));
EXPECT_TRUE(ParmD->hasDefaultArgument());
}
}

TEST_F(Fixture, ShouldImportDefaultTemplateArgs) {
Decl *FromTU = getTuDecl("template <class T0=int, class T1=char> struct X{};",
Lang_CXX, "input0.cc");
auto FromD =
FirstDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());

{
auto TPL = FromD->getTemplateParameters();
ASSERT_EQ((TPL->end() - TPL->begin()), 2);
auto it = TPL->begin();
TemplateTypeParmDecl *ParmD0 = cast<TemplateTypeParmDecl>(*it++);
ASSERT_TRUE(ParmD0->hasDefaultArgument());
TemplateTypeParmDecl *ParmD1 = cast<TemplateTypeParmDecl>(*it);
ASSERT_TRUE(ParmD1->hasDefaultArgument());
}

{
auto ToD = cast<ClassTemplateDecl>(Import(FromD, Lang_CXX));
auto TPL = ToD->getTemplateParameters();
ASSERT_EQ((TPL->end() - TPL->begin()), 2);
auto it = TPL->begin();
TemplateTypeParmDecl *ParmD0 = cast<TemplateTypeParmDecl>(*it++);
EXPECT_TRUE(ParmD0->hasDefaultArgument());
TemplateTypeParmDecl *ParmD1 = cast<TemplateTypeParmDecl>(*it);
EXPECT_TRUE(ParmD1->hasDefaultArgument());
}
}

TEST_F(Fixture, ShouldImportDefaultTemplateArgFromFwdDecl) {
Decl *FromTU = getTuDecl(
R"(
template<typename T0, typename T1 = int> class A;
template<typename T0 = int, typename T1> class A;
)",
Lang_CXX, "input0.cc");
auto FromD =
LastDeclMatcher<ClassTemplateDecl>().match(FromTU, classTemplateDecl());

{
auto TPL = FromD->getTemplateParameters();
ASSERT_EQ((TPL->end() - TPL->begin()), 2);
auto it = TPL->begin();
TemplateTypeParmDecl *ParmD0 = cast<TemplateTypeParmDecl>(*it++);
ASSERT_TRUE(ParmD0->hasDefaultArgument());
TemplateTypeParmDecl *ParmD1 = cast<TemplateTypeParmDecl>(*it);
ASSERT_TRUE(ParmD1->hasDefaultArgument());
}

{
auto ToD = cast<ClassTemplateDecl>(Import(FromD, Lang_CXX));
auto TPL = ToD->getTemplateParameters();
ASSERT_EQ((TPL->end() - TPL->begin()), 2);
auto it = TPL->begin();
TemplateTypeParmDecl *ParmD0 = cast<TemplateTypeParmDecl>(*it++);
EXPECT_TRUE(ParmD0->hasDefaultArgument());
TemplateTypeParmDecl *ParmD1 = cast<TemplateTypeParmDecl>(*it);
EXPECT_TRUE(ParmD1->hasDefaultArgument());
}
}

} // end namespace ast_matchers
} // end namespace clang

0 comments on commit f2cc841

Please sign in to comment.