<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 4, 2016 at 7:49 PM, Nico Weber <span dir="ltr"><<a href="mailto:thakis@chromium.org" target="_blank">thakis@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Thu, Mar 3, 2016 at 10:31 PM, Peter Collingbourne via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Mon, Feb 29, 2016 at 1:53 PM,  <span dir="ltr"><<a></a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi all,<br>
<br>
I'd like to make a proposal to implement the new vtable ABI described in<br>
PR26723, which I'll call the relative ABI. That bug gives more details and<br>
justification for that ABI.<br>
<br>
The user interface for the new ABI would be that -fwhole-program-vtables<br>
would take an optional value indicating which aspects of the program have<br>
whole-program scope. For example, the existing implementation of whole-program<br>
vcall optimization allows external code to call into translation units<br>
compiled with -fwhole-program-vtables, but does not allow external code to<br>
derive from classes defined in such translation units, so you could request<br>
the current behaviour with "-fwhole-program-vtables=derive", which means<br>
that derived classes are not allowed from outside the program. To request<br>
the new ABI, you can specify "-fwhole-program-vtables=call,derive",<br>
which means that calls and derived classes are both not allowed from<br>
outside the program. "-fwhole-program-vtables" would be short for<br>
"-fwhole-program-vtables=call,derive,anythingelseweaddinfuture".<br></blockquote><div><br></div></span><div><div>Based on discussion with John McCall in PR26723, I’d like to change the user interface for -fwhole-program-vtables, and introduce an interface specifically to enable the relative ABI. That interface would be based on a whitelist rather than a blacklist, and together with -fwhole-program-vtables would enable devirtualization, virtual const prop, and virtual function stripping for those classes.</div><div><br></div><div>The new user interface is as follows:</div><div><br></div><div>We would introduce two new attributes, [[clang::unstable_abi]] and [[clang::stable_abi]], which would be attached to a class and would enable or disable the unstable ABI for that class. It is an ODR violation to use [[clang::unstable_abi]] in two translation units compiled with different versions of Clang (we may consider extending the object format to allow a linker to diagnose this). Specifically, mixing different head revisions or major releases is not allowed, but mixing different point releases is fine. The attribute __declspec(uuid()) (which is used for COM classes on Windows) would imply [[clang::stable_abi]].</div><div><br></div><div>A “dynamic-introducing” class is a class that declares new virtual member functions or virtual bases, and has no dynamic bases or virtual bases. A class that is dynamic but not dynamic-introducing would use the same ABI as its dynamic base classes. The compiler will diagnose if a class has two or more dynamic bases with different ABIs, or if the bases have a different ABI from the one explicitly specified by an attribute.</div><div><br></div><div>The ABI for a dynamic-introducing class is determined from the attribute, or if the class has no attribute, from the following flags:</div><div><br></div><div>-funstable-c++-abi or -funstable-c++-abi-classes would enable the unstable C++ ABI for all classes (the idea being that -funstable-c++-abi would also cover any unrelated ABI breaks we may want to make in future).</div><div>-funstable-c++-abi-classes=PATH would enable the unstable C++ ABI for dynamic-introducing classes specified in the file at PATH.</div><div>The -fwhole-program-vtables-blacklist flag would be removed, and I'm no longer proposing that -fwhole-program-vtables would take a value. The whole-program blacklist would be replaced by either inference based on visibility or a new [[clang::no_whole_program]] attribute.</div><div><br></div><div>It is effectively an ODR violation to define a class that uses the unstable ABI in a translation unit compiled with a different set of -funstable-c++-abi* flags. It is also a violation for a linkage unit other than the one compiled with -fwhole-program-vtables to define any of the classes that use the unstable ABI.</div><div><br></div><div>The format of the file is a series of lines ending in either * or **. Preceding that is a namespace specifier delimited by double-colons followed by “::”, or the empty string to denote the global namespace. Each entry in the list indicates that dynamic-introducing classes in that namespace, including nested classes, classes defined in enclosed anonymous namespaces, and classes defined within member functions of those classes, use the unstable ABI. If the line ends in “*” this applies to the given namespace only, while if the line ends in “**” it applies to the given namespace and any enclosed namespaces.</div><div><br></div><div>In Chromium for example, the contents of the file would look like this:</div><div><br></div><div>*</div><div>app::**</div><div>base::**</div><div>browser::**</div><div>[...]</div><div>wm::**</div><div>zip::**</div></div></div></div></div></blockquote><div><br></div></div></div><div>Wouldn't we want to say "use custom ABI for everything non-exported" instead of manually tagging everything?</div></div></div></div></blockquote><div><br></div><div>The problem with that is that system headers aren't necessarily tagged as non-exported. We have a way of identifying system headers, but it seems like a bad idea to implicitly generate different code for system headers without a good reason.</div><div><br></div><div>One other approach I considered was a "whitelist minus blacklist" approach, where the file would look like this:</div><div><br></div><div>**</div><div>-std::*</div><div><br></div><div>That would certainly be more maintainable for Chromium, but it would add a little complexity to the implementation, and would make it easier to make ABI mistakes. Before considering that, I'd like to float the initial proposal as an intent to implement on chromium-dev.</div><div><br></div><div>Thanks,</div><div>Peter</div></div>
</div></div>