mizvekov created this revision. Herald added a subscriber: kristof.beyls. Herald added a project: All. mizvekov updated this revision to Diff 438089. mizvekov added a comment. mizvekov published this revision for review. mizvekov added reviewers: rsmith, v.g.vassilev. Herald added a project: clang. Herald added a subscriber: cfe-commits.
. When expanding template argument packs, clang does not synthesize TemplateTypeParmTypes for the SubstTemplateTypeParmTypes which correspond to the argument's position in the expanded form. Fixes PR56099. Signed-off-by: Matheus Izvekov <mizve...@gmail.com> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D128113 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/AST/ast-dump-template-decls.cpp Index: clang/test/AST/ast-dump-template-decls.cpp =================================================================== --- clang/test/AST/ast-dump-template-decls.cpp +++ clang/test/AST/ast-dump-template-decls.cpp @@ -137,13 +137,13 @@ using t1 = foo<int, short>::bind<char, float>; // CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y<char, float, int, short>' sugar Y // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-0' dependent depth 0 index 0 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-1' dependent depth 0 index 1 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-2' dependent depth 0 index 2 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-3' dependent depth 0 index 3 template <typename... T> struct D { template <typename... U> using B = int(int (*...p)(T, U)); @@ -153,12 +153,12 @@ // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-0' dependent depth 0 index 0 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-1-0' dependent depth 1 index 0 // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-1' dependent depth 0 index 1 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-1-1' dependent depth 1 index 1 } // namespace PR56099 Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1839,9 +1839,18 @@ QualType Replacement = Arg.getAsType(); - // TODO: only do this uniquing once, at the start of instantiation. - QualType Result - = getSema().Context.getSubstTemplateTypeParmType(T, Replacement); + QualType Result; + if (T->isParameterPack()) { + QualType NewT = getSema().Context.getTemplateTypeParmType( + T->getDepth(), + T->getIndex() + getSema().ArgumentPackSubstitutionIndex, false); + Result = getSema().Context.getSubstTemplateTypeParmType( + cast<TemplateTypeParmType>(NewT), Replacement); + } else { + // TODO: only do this uniquing once, at the start of instantiation. + Result = getSema().Context.getSubstTemplateTypeParmType(T, Replacement); + } + SubstTemplateTypeParmTypeLoc NewTL = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); @@ -1879,11 +1888,14 @@ TemplateArgument Arg = TL.getTypePtr()->getArgumentPack(); Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); - QualType Result = Arg.getAsType(); - Result = getSema().Context.getSubstTemplateTypeParmType( - TL.getTypePtr()->getReplacedParameter(), - Result); + const TemplateTypeParmType *T = TL.getTypePtr()->getReplacedParameter(); + QualType NewT = getSema().Context.getTemplateTypeParmType( + T->getDepth(), T->getIndex() + getSema().ArgumentPackSubstitutionIndex, + false); + QualType Result = getSema().Context.getSubstTemplateTypeParmType( + cast<TemplateTypeParmType>(NewT), Arg.getAsType()); + SubstTemplateTypeParmTypeLoc NewTL = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc());
Index: clang/test/AST/ast-dump-template-decls.cpp =================================================================== --- clang/test/AST/ast-dump-template-decls.cpp +++ clang/test/AST/ast-dump-template-decls.cpp @@ -137,13 +137,13 @@ using t1 = foo<int, short>::bind<char, float>; // CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y<char, float, int, short>' sugar Y // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-0' dependent depth 0 index 0 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-1' dependent depth 0 index 1 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-2' dependent depth 0 index 2 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-3' dependent depth 0 index 3 template <typename... T> struct D { template <typename... U> using B = int(int (*...p)(T, U)); @@ -153,12 +153,12 @@ // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-0' dependent depth 0 index 0 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-1-0' dependent depth 1 index 0 // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-0-1' dependent depth 0 index 1 // CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack +// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'type-parameter-1-1' dependent depth 1 index 1 } // namespace PR56099 Index: clang/lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- clang/lib/Sema/SemaTemplateInstantiate.cpp +++ clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1839,9 +1839,18 @@ QualType Replacement = Arg.getAsType(); - // TODO: only do this uniquing once, at the start of instantiation. - QualType Result - = getSema().Context.getSubstTemplateTypeParmType(T, Replacement); + QualType Result; + if (T->isParameterPack()) { + QualType NewT = getSema().Context.getTemplateTypeParmType( + T->getDepth(), + T->getIndex() + getSema().ArgumentPackSubstitutionIndex, false); + Result = getSema().Context.getSubstTemplateTypeParmType( + cast<TemplateTypeParmType>(NewT), Replacement); + } else { + // TODO: only do this uniquing once, at the start of instantiation. + Result = getSema().Context.getSubstTemplateTypeParmType(T, Replacement); + } + SubstTemplateTypeParmTypeLoc NewTL = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); @@ -1879,11 +1888,14 @@ TemplateArgument Arg = TL.getTypePtr()->getArgumentPack(); Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); - QualType Result = Arg.getAsType(); - Result = getSema().Context.getSubstTemplateTypeParmType( - TL.getTypePtr()->getReplacedParameter(), - Result); + const TemplateTypeParmType *T = TL.getTypePtr()->getReplacedParameter(); + QualType NewT = getSema().Context.getTemplateTypeParmType( + T->getDepth(), T->getIndex() + getSema().ArgumentPackSubstitutionIndex, + false); + QualType Result = getSema().Context.getSubstTemplateTypeParmType( + cast<TemplateTypeParmType>(NewT), Arg.getAsType()); + SubstTemplateTypeParmTypeLoc NewTL = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits