[Dwarf-discuss] Proposal: Support for C++ variadic variable captures
Michael Buch
m_buch@apple.com
Thu Sep 25 14:03:34 GMT 2025
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.dwarfstd.org/pipermail/dwarf-discuss/attachments/20250925/50135228/attachment-0001.htm>
More information about the Dwarf-discuss
mailing list