QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
ASTContext &Context = SemaRef.getASTContext();
TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
- TypeLocBuilder InnerTLB;
- QualType Transformed =
- TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
- TypeSourceInfo *TSI =
- TransformType(InnerTLB.getTypeSourceInfo(Context, Transformed));
-
- TypedefNameDecl *Decl = nullptr;
-
- if (isa<TypeAliasDecl>(OrigDecl))
- Decl = TypeAliasDecl::Create(
- Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
- OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
- else {
- assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
- Decl = TypedefDecl::Create(
- Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
- OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
+ TypedefNameDecl *Decl = OrigDecl;
+ // Transform the underlying type of the typedef and clone the Decl only if
+ // the typedef has a dependent context.
+ if (OrigDecl->getDeclContext()->isDependentContext()) {
+ TypeLocBuilder InnerTLB;
+ QualType Transformed =
+ TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc());
+ TypeSourceInfo *TSI =
+ TransformType(InnerTLB.getTypeSourceInfo(Context, Transformed));
+ if (isa<TypeAliasDecl>(OrigDecl))
+ Decl = TypeAliasDecl::Create(
+ Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
+ OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
+ else {
+ assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef");
+ Decl = TypedefDecl::Create(
+ Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(),
+ OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI);
+ }
+ MaterializedTypedefs.push_back(Decl);
}
- MaterializedTypedefs.push_back(Decl);
-
QualType TDTy = Context.getTypedefType(Decl);
TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy);
TypedefTL.setNameLoc(TL.getNameLoc());
EXPECT_TRUE(ToD->isExplicit());
}
+// FIXME Move these tests out of ASTImporterTest. For that we need to factor
+// out the ASTImporter specific pars from ASTImporterOptionSpecificTestBase
+// into a new test Fixture. Then we should lift up this Fixture to its own
+// implementation file and only then could we reuse the Fixture in other AST
+// unitttests.
+struct CTAD : ASTImporterOptionSpecificTestBase {};
+
+TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedef) {
+ Decl *TU = getTuDecl(
+ R"(
+ typedef int U;
+ template <typename T> struct A {
+ A(U, T);
+ };
+ A a{(int)0, (int)0};
+ )",
+ Lang_CXX17, "input.cc");
+ auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
+ TU, cxxDeductionGuideDecl());
+ auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
+ TU, typedefNameDecl(hasName("U")));
+ ParmVarDecl *Param = Guide->getParamDecl(0);
+ // The type of the first param (which is a typedef) should match the typedef
+ // in the global scope.
+ EXPECT_EQ(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
+}
+
+TEST_P(CTAD, DeductionGuideShouldReferToANonLocalTypedefInParamPtr) {
+ Decl *TU = getTuDecl(
+ R"(
+ typedef int U;
+ template <typename T> struct A {
+ A(U*, T);
+ };
+ A a{(int*)0, (int)0};
+ )",
+ Lang_CXX17, "input.cc");
+ auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
+ TU, cxxDeductionGuideDecl());
+ auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
+ TU, typedefNameDecl(hasName("U")));
+ ParmVarDecl *Param = Guide->getParamDecl(0);
+ EXPECT_EQ(Param->getType()
+ ->getAs<PointerType>()
+ ->getPointeeType()
+ ->getAs<TypedefType>()
+ ->getDecl(),
+ Typedef);
+}
+
+TEST_P(CTAD, DeductionGuideShouldCopyALocalTypedef) {
+ Decl *TU = getTuDecl(
+ R"(
+ template <typename T> struct A {
+ typedef T U;
+ A(U, T);
+ };
+ A a{(int)0, (int)0};
+ )",
+ Lang_CXX17, "input.cc");
+ auto *Guide = FirstDeclMatcher<CXXDeductionGuideDecl>().match(
+ TU, cxxDeductionGuideDecl());
+ auto *Typedef = FirstDeclMatcher<TypedefNameDecl>().match(
+ TU, typedefNameDecl(hasName("U")));
+ ParmVarDecl *Param = Guide->getParamDecl(0);
+ EXPECT_NE(Param->getType()->getAs<TypedefType>()->getDecl(), Typedef);
+}
+
+INSTANTIATE_TEST_CASE_P(ParameterizedTests, CTAD,
+ DefaultTestValuesForRunOptions, );
+
INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest,
DefaultTestValuesForRunOptions, );