martong updated this revision to Diff 308920.
martong added a comment.
- Move dependent context check into TransformTypedefType
- Add new test case for param with pointer type
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92101/new/
https://reviews.llvm.org/D92101
Files:
clang/lib/Sema/SemaTemplate.cpp
clang/unittests/AST/ASTImporterTest.cpp
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -5884,6 +5884,77 @@
EXPECT_EQ(Record, CompletedTags.front());
}
+// 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, );
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2077,23 +2077,28 @@
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;
+
+ // Create a new Decl only if the typedef has a dependent context.
+ if (OrigDecl->getDeclContext()->isDependentContext()) {
+ 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);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits