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 e75e4b6
Show file tree
Hide file tree
Showing 4 changed files with 124 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
108 changes: 108 additions & 0 deletions unittests/AST/ASTImporterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2392,5 +2392,113 @@ 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());
}
}

const internal::VariadicDynCastAllOfMatcher<Decl, VarTemplateDecl>
varTemplateDecl;

TEST_F(Fixture, ShouldImportDefaultTemplateArgOfVariableTemplate) {
Decl *FromTU = getTuDecl(
"template<class T=double> constexpr T pi = T(3.1415926535897932385L);",
Lang_CXX14, "input0.cc");
auto FromD =
FirstDeclMatcher<VarTemplateDecl>().match(FromTU, varTemplateDecl());

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

{
auto ToD = cast<VarTemplateDecl>(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());
}
}

} // end namespace ast_matchers
} // end namespace clang
4 changes: 4 additions & 0 deletions unittests/AST/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum Language {
Lang_C89,
Lang_CXX,
Lang_CXX11,
Lang_CXX14,
Lang_OpenCL,
Lang_OBJCXX
};
Expand All @@ -42,6 +43,9 @@ void getLangArgs(Language Lang, StringVector &Args) {
case Lang_CXX11:
Args.push_back("-std=c++11");
break;
case Lang_CXX14:
Args.push_back("-std=c++14");
break;
case Lang_OpenCL:
case Lang_OBJCXX:
break;
Expand Down
4 changes: 4 additions & 0 deletions unittests/AST/MatchVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ testing::AssertionResult MatchVerifier<NodeType>::match(
Args.push_back("-std=c++11");
FileName = "input.cc";
break;
case Lang_CXX14:
Args.push_back("-std=c++14");
FileName = "input.cc";
break;
case Lang_OpenCL:
FileName = "input.cl";
break;
Expand Down

0 comments on commit e75e4b6

Please sign in to comment.