Skip to content

Clang: Incomplete representation of type sugar for expanded argument packs in the AST. #56099

@mizvekov

Description

@mizvekov

When expanding template argument packs, clang does not synthesize TemplateTypeParmTypes for the SubstTemplateTypeParmTypes which correspond to the argument's position in the expanded form.

Consider example 1: https://godbolt.org/z/KvMTbh5T7

template <typename... As> struct Y;
template <typename ...Bs> using Z = Y<Bs...>;
template <typename ...Cs> struct foo {
  template <typename ...Ds> using bind = Z<Ds..., Cs...>;
};
using U = foo<int, short>::bind<char, float>;

AST:

TemplateSpecializationType 0x559e6e0cafa0 'Y<char, float, int, short>' sugar Y
          |-TemplateArgument type 'char':'char'
          | `-SubstTemplateTypeParmType 0x559e6e0cada0 'char' sugar
          |   |-TemplateTypeParmType 0x559e6e0acb60 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
          |   | `-TemplateTypeParm 0x559e6e0acb08 'Bs'
          |   `-BuiltinType 0x559e6e066e80 'char'
          |-TemplateArgument type 'float':'float'
          | `-SubstTemplateTypeParmType 0x559e6e0cade0 'float' sugar
          |   |-TemplateTypeParmType 0x559e6e0acb60 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
          |   | `-TemplateTypeParm 0x559e6e0acb08 'Bs'
          |   `-BuiltinType 0x559e6e066fe0 'float'
          |-TemplateArgument type 'int':'int'
          | `-SubstTemplateTypeParmType 0x559e6e0ca810 'int' sugar
          |   |-TemplateTypeParmType 0x559e6e0acb60 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
          |   | `-TemplateTypeParm 0x559e6e0acb08 'Bs'
          |   `-BuiltinType 0x559e6e066ee0 'int'
          |-TemplateArgument type 'short':'short'
          | `-SubstTemplateTypeParmType 0x559e6e0ca850 'short' sugar
          |   |-TemplateTypeParmType 0x559e6e0acb60 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack
          |   | `-TemplateTypeParm 0x559e6e0acb08 'Bs'
          |   `-BuiltinType 0x559e6e066ec0 'short'
          `-RecordType 0x559e6e0caf80 'Y<char, float, int, short>'
            `-ClassTemplateSpecialization 0x559e6e0cae98 'Y'

Example 2: https://godbolt.org/z/r7v8hYdKx

template<typename ...T> struct D {
  template<typename... U> using B = int(int (*...p)(T, U));
};
using foo = D<float, char>::B<int, short>;

AST:

FunctionProtoType 0x564b6179e8e0 'int (int (*)(float, int), int (*)(char, short))' cdecl
        |-BuiltinType 0x564b61738ee0 'int'
        |-PointerType 0x564b6179e620 'int (*)(float, int)'
        | `-ParenType 0x564b6179e5c0 'int (float, int)' sugar
        |   `-FunctionProtoType 0x564b6179e580 'int (float, int)' cdecl
        |     |-BuiltinType 0x564b61738ee0 'int'
        |     |-SubstTemplateTypeParmType 0x564b6179cef0 'float' sugar
        |     | |-TemplateTypeParmType 0x564b6177e6b0 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
        |     | | `-TemplateTypeParm 0x564b6177e630 'T'
        |     | `-BuiltinType 0x564b61738fe0 'float'
        |     `-SubstTemplateTypeParmType 0x564b6179e500 'int' sugar
        |       |-TemplateTypeParmType 0x564b6179c750 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
        |       | `-TemplateTypeParm 0x564b6179c6f8 'U'
        |       `-BuiltinType 0x564b61738ee0 'int'
        `-PointerType 0x564b6179e830 'int (*)(char, short)'
          `-ParenType 0x564b6179e7d0 'int (char, short)' sugar
            `-FunctionProtoType 0x564b6179e790 'int (char, short)' cdecl
              |-BuiltinType 0x564b61738ee0 'int'
              |-SubstTemplateTypeParmType 0x564b6179dd90 'char' sugar
              | |-TemplateTypeParmType 0x564b6177e6b0 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
              | | `-TemplateTypeParm 0x564b6177e630 'T'
              | `-BuiltinType 0x564b61738e80 'char'
              `-SubstTemplateTypeParmType 0x564b6179e710 'short' sugar
                |-TemplateTypeParmType 0x564b6179c750 'U' dependent contains_unexpanded_pack depth 0 index 0 pack
                | `-TemplateTypeParm 0x564b6179c6f8 'U'
                `-BuiltinType 0x564b61738ec0 'short'

The TemplateTypeParmType's used are the original ones from the packed template argument, and as such it's pretty hard to map these to the argument list as-written.

Metadata

Metadata

Assignees

Labels

clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions