<html aria-label="message body"><head><meta http-equiv="content-type" content="text/html; charset=us-ascii"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi all,</div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><br></div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">I have been working on some LLDB/debug-info issues surrounding parameter packs recently and stumbled upon following DWARFv6 proposal: <font color="#000000"><a href="https://dwarfstd.org/issues/250516.1.html" rel="nofollow" style="box-sizing: border-box; text-underline-offset: 0.2rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 14px;">https://dwarfstd.org/issues/250516.1.html</a><span style="caret-color: rgb(5, 12, 20); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; font-size: 14px;"> </span></font></div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><br></div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">I'm in favour of standardising parameter pack support in DWARF, but wanted to recommend a few changes to the above proposal to make sure we accommodate various use-cases not yet covered by it.</div><div dir="auto" style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div><br></div><div>At the time of the proposal there were two kinds of packs</div><div>1. template parameter packs</div><div>2. function parameter packs</div><div><br></div><div>Since then two more kinds of packs have been added to the language:</div><div>3. lambda capture packs (C++20)</div><div>4. structured binding packs (C++26)</div><div><br></div><div>The proposal currently describes (1)<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"> as DW_TAG_template_parameter_pack and (2) as </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);">DW_TAG_formal_parameter_pack</span></div><div><br></div><div>However, it seems to me that neither of these are suitable to describe (3) and (4).</div><div><br></div><div># Lambda Capture Packs</div><div><br></div><div>Here is an example of such pack:</div><div>```</div><div><span style="white-space: pre-wrap; font-family: Monaco, Menlo, Consolas, "Courier New", monospace; font-variant-ligatures: none; orphans: 2; widows: 2; background-color: rgba(232, 232, 232, 0.04); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><font color="#000000">template <typename ... Args>
auto f(Args&& ... args){
return [... args = std::forward<Args>(args)] {
// use args
};
}</font></span></div><div>```</div><div><br></div><div>Here, `args` is actually a collection of init-capture declarations. In DWARF one might want to represent these as </div><div>`DW_TAG_member`s on the anonymous lambda structure. However, neither <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);">DW_TAG_formal_parameter_pack nor </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);">DW_TAG_template_parameter_pack would allow such a representation.</span></div><div><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><br></span></div><div><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"># Structured Binding Packs</span></div><div><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);"><br></span></div><div><div style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);">Here is an example of such pack:</div></div><div>```</div><div><pre class="notranslate" style="box-sizing: border-box; font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); font-size: 11.9px; margin-top: 0px; margin-bottom: var(--base-size-16); tab-size: var(--tab-size-preference); overflow-wrap: normal; padding: var(--base-size-16); overflow: auto; line-height: 1.45; color: rgb(5, 12, 20); border-radius: 6px; caret-color: rgb(5, 12, 20);"><code class="notranslate" style="box-sizing: border-box; font-family: var(--fontStack-monospace, ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace); font-size: 11.9px; tab-size: var(--tab-size-preference); padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; border-radius: 6px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; overflow-wrap: normal;">struct C { int x = 1, y = 2, z = 3; };
void foo() {
auto [d, ...e] = C();
}</code></pre></div><div>```</div><div><br></div><div>Here, `e` is a collection of variable declarations. <span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);">In DWARF one might want to represent these as `DW_TAG_variable`s local to the function `foo`. But, again, neither of the proposed new tags currently allows this.</span></div><div><br></div><div>More discussion on that here: <a href="https://github.com/llvm/llvm-project/issues/152282">https://github.com/llvm/llvm-project/issues/152282</a></div><div><br></div><div># Proposed changes to the proposal</div><div><br></div><div><p dir="auto" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); caret-color: rgb(5, 12, 20); color: rgb(5, 12, 20);">A more general representation for packs would be having the notion of a "type pack" and a "variable pack". The "type pack" is a collection of types, which is what<font face="monospace"><span style="white-space-collapse: break-spaces;"> DW_TAG_template_paramaeter_pack </span></font>encodes. A "variable pack" is a collection of variable declarations, which could be function parameters (<font face="monospace"><span style="white-space-collapse: break-spaces;">DW_TAG_formal_parameter</span></font>) or variables introduced with structured bindings (<font face="monospace"><span style="white-space-collapse: break-spaces;">DW_TAG_variable</span></font>) or even variables introduced via lambda capture packs <font face="monospace"><span style="white-space-collapse: break-spaces;">(DW_TAG_member</span></font> on the fake lambda structure).</p><p dir="auto" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); caret-color: rgb(5, 12, 20); color: rgb(5, 12, 20);"><br></p><p dir="auto" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); caret-color: rgb(5, 12, 20); color: rgb(5, 12, 20);">That way we could represent the DWARF for<code class="notranslate" style="box-sizing: border-box; tab-size: var(--tab-size-preference); padding: 0.2em 0.4em; margin: 0px; white-space: break-spaces; border-radius: 6px;">auto [a, ...e]</code> like so:</p><p dir="auto" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); caret-color: rgb(5, 12, 20); color: rgb(5, 12, 20);">```</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" style="box-sizing: border-box; caret-color: rgb(5, 12, 20); color: rgb(5, 12, 20); position: relative !important; overflow: auto !important; margin-bottom: 0px !important;"><pre class="notranslate" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); tab-size: var(--tab-size-preference); overflow-wrap: normal; padding: var(--base-size-16); overflow: auto; line-height: 1.45; border-radius: 6px;"><code class="notranslate" style="box-sizing: border-box; tab-size: var(--tab-size-preference); padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; border-radius: 6px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; overflow-wrap: normal;"><font face="Helvetica">DW_TAG_variable
DW_AT_name ("a")
DW_TAG_variable_pack
DW_AT_name ("e")
DW_TAG_variable
DW_AT_type
DW_AT_name ("fake_var_1") << may or may not be needed. Debugger could synthesize this
DW_TAG_variable
DW_AT_type
DW_AT_name ("fake_var_2") << may or may not be needed. Debugger could synthesize this</font></code></pre><pre class="notranslate" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); tab-size: var(--tab-size-preference); overflow-wrap: normal; padding: var(--base-size-16); overflow: auto; line-height: 1.45; border-radius: 6px;"><code class="notranslate" style="box-sizing: border-box; tab-size: var(--tab-size-preference); padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; border-radius: 6px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; overflow-wrap: normal;"><font face="Helvetica">```</font></code></pre><pre class="notranslate" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); tab-size: var(--tab-size-preference); overflow-wrap: normal; padding: var(--base-size-16); overflow: auto; line-height: 1.45; border-radius: 6px;"><code class="notranslate" style="box-sizing: border-box; tab-size: var(--tab-size-preference); padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; border-radius: 6px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; overflow-wrap: normal;"><font face="Helvetica"><br></font></code></pre><pre class="notranslate" style="box-sizing: border-box; margin-top: 0px; margin-bottom: var(--base-size-16); tab-size: var(--tab-size-preference); overflow-wrap: normal; padding: var(--base-size-16); overflow: auto; line-height: 1.45; border-radius: 6px;"><code class="notranslate" style="box-sizing: border-box; tab-size: var(--tab-size-preference); padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; border-radius: 6px; word-break: normal; border: 0px; display: inline; overflow: visible; line-height: inherit; overflow-wrap: normal;"><font face="Helvetica">Let me know if you have any questions/concerns with these suggestions. Happy to discuss!</font></code></pre></div></div></div></div></body></html>