Synopsis
=======

This proposal is a follow-up to Issue 250516.1: Support C++0x Variadic 
templates [1] to support variadic lambda captures and variadic structured 
binding declarations [2].

Motivation 
========

DWARFv6 is scheduled to support two new tags to encode parameter packs 
(motivated by the C++ feature of the same name) [1]: 
DW_TAG_template_parameter_pack and DW_TAG_formal_parameter_pack. These tags 
allow producers to represent template parameter packs and function argument 
packs respectively.

With C++20, parameter packs can be used in lambda variable capture lists:
```
template<typename... Args>
auto f(Args&& args) {
  return [...args = std::forward<Args>(args)] {
     // Use args
  };
}
```

Here, `args` is actually a collection of init-capture declarations. In DWARF 
one might want to represent these as 
`DW_TAG_member`s on the anonymous lambda structure. However, neither 
DW_TAG_formal_parameter_pack nor DW_TAG_template_parameter_pack would allow 
such a representation.

With C++26, parameter packs can be used in structured binding declarations:
```
struct C { int x = 1, y = 2, z = 3; };

template<int N>
void foo() {
  auto [d, ...e] = C();
}
```

Here, `e` is a collection of variable declarations. In DWARF one might want to 
represent these as `DW_TAG_variable`s local to the function `foo`. But, again, 
neither of the upcoming parameter pack tags would allow this.

More discussion on this is available in LLVM issue #152282 [3]

We propose a new tag `DW_TAG_variable_pack`, which functions similar to 
`DW_TAG_template_parameter_pack` and `DW_TAG_formal_parameter_pack`. The tag's 
purpose is to encode packs of variable declarations.

Document changes
================
Add the following new tags to Table 2.1, "Tag names", to Table 7.3, "Tag 
encodings", and to Table A.1, "Attributes by tag value":

* DW_TAG_variable_pack

  * Allowable attributes:

    * DECL

    * DW_AT_name

    * DW_AT_sibling



Add a new sub-chapter in Chapter 4 Data Objet and Object List Entries:

[NEW TEXT]
==========
Chapter 4.4 Variable Packs

A pack is a named entity that represents arbitrary many variable declarations. 
Indexing into the entity to retrieve individual members of the pack is language 
dependent. Such program entities may be represented in DWARF using 
`DW_TAG_variable_pack`. The `DW_AT_name` attribute can be used specify the name 
of the pack entity in the source.

For each variable declaration introduced by the pack in the source, the 
`DW_TAG_variable_pack` has a `DW_TAG_variable` or `DW_TAG_member` child. The 
order of the children is the same as the order in which the variable 
declarations are introduced in the source.

<non-normative>
DW_TAG_template_parameter_pack and DW_TAG_function_parameter_pack describe 
template and function parameter packs respectively. In C++, packs can also 
represent collections of variable declarations. For example, a lambda capture 
list may capture a pack of variables or a structured binding may decompose to a 
pack of variables (see examples in Appendix D.17).
</non-normative>
<<<<<<<<<<<<<<<

Add a new example to Appendix D: Examples:

[NEW TEXT]
==========
Appendix D.17 Variable Pack Examples

Consider following C++20 lambda:
```
1 template<typename... Args>
2 auto f(Args&& args) {
3   return [...captured = std::forward<Args>(args)] {
4     return captured...[0] + captured...[1]; // Pack indexing since C++26
5   };
6 }
7
8 int main() { auto x = f(1, 2); }
```

Here, `captured` is a collection of init-capture declarations. A DWARF producer 
may choose to represent the pack members as `DW_TAG_member`s on the anonymous 
lambda structure:

```
    DW_TAG_subprogram
        DW_AT_name("f")
        ! Anonymous lambda structure
        DW_TAG_class_type
          DW_TAG_variable_pack
            DW_AT_decl_line(3)
            DW_AT_name("captured")
            DW_TAG_member
              ! Optional name a producer may want to give the pack children
              DW_AT_name("captured:0")
              DW_AT_data_member_location(0x0)
            DW_TAG_member
              ! Optional name a producer may want to give the pack children
              DW_AT_name("captured:1")
              DW_AT_data_member_location(0x4)
```

Consider following C++26 structured binding pack declaration:
```
1 struct C { int x = 1, y = 2, z = 3; };
2
3 template<int N>
4 void foo() {
5   auto [d, ...e] = C();
6 }
```

Here, `e` is a collection of variable declarations. A DWARF producer may 
represent the pack members as `DW_TAG_variable`s:
```
    DW_TAG_subprogram
        DW_AT_name("foo")
        DW_TAG_variable_pack
            DW_AT_decl_line(5)
            DW_AT_name("e")
            DW_TAG_variable
              ! Optional name a producer may want to give the pack children
              DW_AT_name("e:0")
              DW_AT_location(...)
            DW_TAG_member
              ! Optional name a producer may want to give the pack children
              DW_AT_name("e:1")
              DW_AT_location(...)
```
<<<<<<<<<<<<<<<

Links
====

[1]: https://dwarfstd.org/issues/250516.1.html
[2]: https://en.cppreference.com/w/cpp/language/parameter_pack.html
[3]: https://github.com/llvm/llvm-project/issues/152282
-- 
Dwarf-discuss mailing list
[email protected]
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss

Reply via email to