<div dir="ltr"><div dir="ltr"><div>Thanks Richard.</div><div><br></div>Ok; ignore Question 2 - you are absolutely right (what I was thinking).<div>Printing different labels for the same type defeats the point of this request.</div><div><br></div><div>OTOH, Question 1 is a request for Clang to print different output for different types.<br></div><div>The linked bug report is an example of where it is important to distinguish types.</div><div><br></div><div>Here's a summary of suggested output vs current output for Clang, GCC, MSVC.</div><div><a href="https://godbolt.org/z/QEae7F">https://godbolt.org/z/QEae7F</a><br></div><div><br></div><div><span style="font-family:monospace,monospace">Plain, unscoped enum</span>  <br></div><font face="monospace, monospace">   enum e { a, b, c=b };<br>   auto_name<a, e(1), c, e(3)><br><br></font><span style="font-family:monospace,monospace">  Suggested:</span><font face="monospace, monospace"> a, b, b, (e)3<br>      Clang: a, b, b, 3<br>        GCC: (e)0, (e)1, (e)1, (e)3<br>       MSCV: 0, 1, 1, 3<br><br></font><span style="font-family:monospace,monospace">Scoped / opaque enum:</span> <font face="monospace, monospace"><br>   enum class E { a, b, c=b };<br>   auto_name<E::a, E{1}, E::c, E{3}></font><div><font face="monospace, monospace"><br></font><div><span style="font-family:monospace,monospace">  Suggested:</span><font face="monospace, monospace"> </font>

<span style="font-family:monospace,monospace">E::a, E::b, E::b, (E)3</span>  <font face="monospace, monospace"><br>      Clang: </font>

<span style="font-family:monospace,monospace">E::a, E::b, E::b</span><span style="font-family:monospace,monospace">, 3</span>  <font face="monospace, monospace"><br>        GCC: </font>

<span style="font-family:monospace,monospace">(E)0, (E)1, (E)1, (E)3</span>  <font face="monospace, monospace"><br>       MSCV: 0, 1, 1, 3</font></div><div><div><div><div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><br></div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">None of these are ideal -</div><div>- Clang loses type info for non-enumerated values.<br>- GCC does not distinguish enumerated / non-enumerated.<br>- MSVC lo<span style="color:rgb(0,0,0);background-color:rgb(255,255,254)">ses type all info, does not distinguish.</span></div></div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><br></div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">Interestingly, it turns out that GCC's behaviour is a bug!</div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">(The *intent* of gcc code is to print the suggested output.</div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"> I intend to submit a bug report and a patch.)</div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><br></div></div></div><div>You are concerned that this suggested change would</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">make the template argument string more verbose without (necessarily) providing any more information.</blockquote><div> </div><div>Yet the information is necessary in order to distinguish different types.</div><div>This change is needed for correctness. Verbosity is a secondary concern.</div><div>Clang's current behaviour here could be treated as a bug</div><div>(it has been described as "seriously suboptimal" by a gcc dev).</div><div> </div><div>For Clang, the increased verbosity is only for non-enumerated values.</div><div>Enum-templates would be expected to mostly use enumerated values.</div><div>Also, verbosity becomes more similar for enumerated / non-enumerated</div><div>the number of characters in the identifier label vs the number of digits.</div><div><br></div><div>I'm now preferring C-style cast notation over C++ function-style</div><div>as it simplifies output and parsing code.</div><div><br></div><div>Please reflect on this and consider - is this suggested change acceptable?</div></div></div><div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 4, 2018 at 4:30 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, 4 Sep 2018 at 09:09, will wray via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><a style="font-size:10pt">A request to change Clang's __PRETTY_FUNCTION__ output to fix an issue.</a></div><div><a style="font-size:10pt"><br></a></div><a style="font-size:10pt"></a><div><a style="font-size:10pt"></a><a style="font-size:10pt"></a><a style="font-size:small"></a><div style="font-size:small"><a>The code used in pretty function is also used to generate debug info in </a><a><div style="display:inline">DWARF etc</div></a><a><div style="display:inline">.</div></a></div><div style="font-size:small"><a><div style="display:inline">(I believe). See, for instance the comment on this bug report:</div></a></div><div style="font-size:small"><a><div style="display:inline">https://sourceware.org/bugzilla/show_bug.cgi?id=21492#c1</div></a></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><span style="color:rgb(0,0,0);white-space:pre-wrap">Clang shows these arguments with the same DW_AT_name, X<1>, but they're distinct types</span></blockquote></div><div style="font-size:small"><span style="color:rgb(0,0,0);font-size:medium;white-space:pre-wrap"><br></span></div><div style="font-size:small"><span style="font-size:13.3333px"><a href="https://godbolt.org/z/0Ik0Hl" target="_blank">https://godbolt.org/z/0Ik0Hl</a></span><span style="color:rgb(0,0,0);font-size:medium;white-space:pre-wrap"><br></span></div>Pretty function output, for auto... args<div>(variadic just so that outputs display together):<div><span style="font-size:13.3333px"><br></span><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><a style="font-size:10pt"><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><div><div><span style="color:rgb(0,0,255)">template</span> <<span style="color:rgb(0,0,255)">auto</span>... V></div><div><span style="color:rgb(0,0,255)">constexpr</span> <span style="color:rgb(0,0,255)">char</span> <span style="color:rgb(0,0,255)">const</span>* auto_name()</div><div>{</div><div>       <span style="color:rgb(0,0,255)">return</span> __PRETTY_FUNCTION__;</div><div>}</div><br><div><span style="color:rgb(0,0,255)">enum</span> e { a, b, c=b };</div><div><span style="color:rgb(0,0,255)">enum</span> <span style="color:rgb(0,0,255)">class</span> E { a, b, c=b };</div><br><div><span style="color:rgb(0,0,255)">char</span> <span style="color:rgb(0,0,255)">const</span>* nameU() { <span style="color:rgb(0,0,255)">return</span> auto_name<a, b, c, e(<span style="color:rgb(9,136,90)">3</span>)>(); }</div><div><span style="color:rgb(0,0,255)">char</span> <span style="color:rgb(0,0,255)">const</span>* nameS() { <span style="color:rgb(0,0,255)">return</span> auto_name<E::a, E::b, E::c, E{<span style="color:rgb(9,136,90)">3</span>}>(); }</div></div></div></div></a></div></blockquote></div><div><a></a><div><a></a><div style="font-size:small"><a></a><a style="font-size:10pt"><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><br></div></div></a></div><div style="font-size:small"><a style="font-size:10pt">Gives output with these strings embedded;</a></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><a></a><div><a></a><div style="font-size:small"><a></a><a style="font-size:10pt">nameU: </a><a style="font-size:10pt"><div style="color:rgb(0,0,0);background-color:rgb(255,255,254);display:inline"><div style="display:inline"><span style="color:rgb(163,21,21)"><a, b, b, 3></span></div></div></a></div></div></div></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><a></a><div><a>nameS: </a><a><div style="display:inline"><div style="color:rgb(0,0,0);background-color:rgb(255,255,254);display:inline"><div style="display:inline"><span style="color:rgb(163,21,21)"><E::a, E::b, E::b, 3></span></div></div></div></a></div></div></blockquote></blockquote></blockquote></blockquote></blockquote></blockquote><div><a><div><div style="font-size:small"><br></div><div style="font-size:small">The first two enumerated values, a & b, are returned with no loss of type info as a, b.</div></div><div style="font-size:small">The next enumerated value, c, is a duplicate label for b's value, and is reported as b.</div><div style="font-size:small">The final value is not enumerated - there is no enum label with value 3 -</div></a><div style="font-size:small"><a>it is reported with </a><a>an unnecessary loss of type info </a><a><div style="display:inline!important">as plain digits 3.</div></a></div><div style="font-size:small"><br></div><div style="font-size:small">The non-enumerated value should be reported with a cast or constructor:</div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div><a><div style="font-size:small">unscoped e: 3 -> (e)3 or e(3)</div></a></div></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><a><div style="display:inline!important">  scoped   E: 3 -> (E)3 or E(3) or E{3}</div></a></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div style="font-size:small"><a> (init-list E{3} only for scoped enum and only since c++17)</a><a><div style="display:inline">    </div></a></div></blockquote></blockquote></blockquote><div><a></a><div style="font-size:small"><a></a><a><div style="display:inline">Question 1:</div></a><br></div><div style="font-size:small">Will it be acceptable to change the output for non-enumerated values as so?</div></div></div></div></blockquote><div><br></div><div>In the case where the template parameter involves a deduced type (`auto` or `decltype(auto)` or eventually a deduced template specialization type), it would make a lot of sense to include the actual type in the printed template argument if it differs from the type of the formatted argument string. But I think we should leave out the type in all other cases, as it would make the template argument string more verbose without (necessarily) providing any more information.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div style="font-size:small"><a><div style="display:inline">This will retain type info and allow round-trip without loss.</div></a></div><div style="font-size:small">Either C-style cast (e)3  or  function-cast / type-constructor e(3) - seem ok</div><div style="font-size:small">(gcc uses C-style casts and Clang uses this same style in source labels).</div><div style="font-size:small"><br></div><div style="font-size:small">For the duplicate-valued labels case there is no loss of type info,</div><div style="font-size:small">but there is a loss of information about the label used for the auto arg.</div><div style="font-size:small">Presumably, the code works from the supplied underlying-type value</div><div style="font-size:small">and picks the first label with the given value. I'd guess that Clang knows</div><div style="font-size:small">the label used in a direct instantiation and could return it in that case.</div><div style="font-size:small">(c.f. named member-pointer args have to retain the id for reporting).</div></div></div></div></blockquote><div><br></div><div>In the case of duplicated enumerators, there simply is no distinction between 'b' and 'c' -- they are both merely names for the value 1 of type 'e'. auto_name<b>() and auto_name<c>() are the same function and therefore must return the same string.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div style="font-size:small"><a><div style="display:inline">Question 2:</div></a><br></div><div style="font-size:small"><a><div style="display:inline">Is it possible / acceptable to retain the label in the duplicate enum value case?</div></a></div></div></div></div></blockquote><div><br></div><div>No, per the above, we cannot and must not do that.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div style="font-size:small"><a><div style="display:inline">Can anyone point me to the relevant code?</div></a></div></div></div></div></blockquote><div><br></div><div>This is printIntegral, at the top of lib/AST/TemplateBase.cpp. The "else" case at the bottom would need to print out additional text representing the cast when needed.</div></div></div>
</blockquote></div>