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