Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4905,7 +4905,7 @@ bool Sema::CheckTemplateTypeArgument(
[[fallthrough]];
}
default: {
// We allow instantiateing a template with template argument packs when
// We allow instantiating a template with template argument packs when
// building deduction guides.
if (Arg.getKind() == TemplateArgument::Pack &&
CodeSynthesisContexts.back().Kind ==
Expand Down
20 changes: 13 additions & 7 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,7 @@ namespace {
TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
pack, QualType(), SourceLocation{});
TemplateArgumentLoc Output;
if (SemaRef.SubstTemplateArgument(Input, TemplateArgs, Output))
if (TransformTemplateArgument(Input, Output, Uneval))
return true; // fails
TArgs.push_back(Output.getArgument());
}
Expand Down Expand Up @@ -2041,9 +2041,11 @@ TemplateName TemplateInstantiator::TransformTemplateName(
// We're rewriting the template parameter as a reference to another
// template parameter.
if (Arg.getKind() == TemplateArgument::Pack) {
assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
assert(Arg.pack_size() == 1 &&
"unexpected pack arguments in template rewrite");
Arg = Arg.pack_begin()->getPackExpansionPattern();
Arg = *Arg.pack_begin();
if (Arg.isPackExpansion())
Arg = Arg.getPackExpansionPattern();
}
assert(Arg.getKind() == TemplateArgument::Template &&
"unexpected nontype template argument kind in template rewrite");
Expand Down Expand Up @@ -2126,9 +2128,11 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
// We're rewriting the template parameter as a reference to another
// template parameter.
if (Arg.getKind() == TemplateArgument::Pack) {
assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
assert(Arg.pack_size() == 1 &&
"unexpected pack arguments in template rewrite");
Arg = Arg.pack_begin()->getPackExpansionPattern();
Arg = *Arg.pack_begin();
if (Arg.isPackExpansion())
Arg = Arg.getPackExpansionPattern();
}
assert(Arg.getKind() == TemplateArgument::Expression &&
"unexpected nontype template argument kind in template rewrite");
Expand Down Expand Up @@ -2592,9 +2596,11 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
// We're rewriting the template parameter as a reference to another
// template parameter.
if (Arg.getKind() == TemplateArgument::Pack) {
assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
assert(Arg.pack_size() == 1 &&
"unexpected pack arguments in template rewrite");
Arg = Arg.pack_begin()->getPackExpansionPattern();
Arg = *Arg.pack_begin();
if (Arg.isPackExpansion())
Arg = Arg.getPackExpansionPattern();
}
assert(Arg.getKind() == TemplateArgument::Type &&
"unexpected nontype template argument kind in template rewrite");
Expand Down
46 changes: 46 additions & 0 deletions clang/test/AST/ast-dump-ctad-alias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,49 @@ ATemplatedClass2 test2(list);
// CHECK-NEXT: |-TypeTraitExpr {{.*}} 'bool' __is_deducible

} // namespace GH90209

namespace GH124715 {

template <class T, class... Args>
concept invocable = true;

template <class T, class... Args> struct Struct {
template <class U>
requires invocable<U, Args...>
Struct(U, Args...) {}
};

template <class...> struct Packs {};

template <class Lambda, class... Args>
Struct(Lambda lambda, Args... args) -> Struct<Lambda, Args...>;

template <class T, class... Ts> using Alias = Struct<T, Packs<Ts...>>;

void foo() {
Alias([](int) {}, Packs<int>());
}

// CHECK: |-FunctionTemplateDecl {{.*}} implicit <deduction guide for Alias>
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} class depth 0 index 0 T
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} class depth 0 index 1 ... Ts
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} class depth 0 index 2 U
// CHECK-NEXT: | |-BinaryOperator {{.*}} 'bool' '&&'
// CHECK-NEXT: | | |-ConceptSpecializationExpr {{.*}} 'bool' Concept {{.*}} 'invocable'
// CHECK-NEXT: | | | |-ImplicitConceptSpecializationDecl {{.*}}
// CHECK-NEXT: | | | | |-TemplateArgument type 'type-parameter-0-2'
// CHECK-NEXT: | | | | | `-TemplateTypeParmType {{.*}} 'type-parameter-0-2' dependent depth 0 index 2
// CHECK-NEXT: | | | | `-TemplateArgument pack '<Packs<type-parameter-0-1...>>'
// CHECK-NEXT: | | | | `-TemplateArgument type 'Packs<type-parameter-0-1...>'
// CHECK-NEXT: | | | | `-TemplateSpecializationType {{.*}} 'Packs<type-parameter-0-1...>' dependent
// CHECK-NEXT: | | | | |-name: 'GH124715::Packs'
// CHECK-NEXT: | | | | | `-ClassTemplateDecl {{.*}} Packs
// CHECK-NEXT: | | | | `-TemplateArgument pack '<type-parameter-0-1...>'
// CHECK-NEXT: | | | | `-TemplateArgument type 'type-parameter-0-1...'
// CHECK-NEXT: | | | | `-PackExpansionType {{.*}} 'type-parameter-0-1...' dependent
// CHECK-NEXT: | | | | `-TemplateTypeParmType {{.*}} 'type-parameter-0-1' dependent contains_unexpanded_pack depth 0 index 1 pack
// CHECK-NEXT: | | | |-TemplateArgument {{.*}} type 'U':'type-parameter-0-2'
// CHECK-NEXT: | | | | `-TemplateTypeParmType {{.*}} 'U' dependent depth 0 index 2
// CHECK-NEXT: | | | | `-TemplateTypeParm {{.*}} 'U'

} // namespace GH124715