[cfe-dev] [llvm-dev] RFC: A new ABI for virtual calls, and a change to the virtual call representation in the IR

Peter Collingbourne via cfe-dev cfe-dev at lists.llvm.org
Fri Mar 4 20:16:55 PST 2016

On Fri, Mar 4, 2016 at 7:49 PM, Nico Weber <thakis at chromium.org> wrote:

> On Thu, Mar 3, 2016 at 10:31 PM, Peter Collingbourne via cfe-dev <
> cfe-dev at lists.llvm.org> wrote:
>> On Mon, Feb 29, 2016 at 1:53 PM, <> wrote:
>>> Hi all,
>>> I'd like to make a proposal to implement the new vtable ABI described in
>>> PR26723, which I'll call the relative ABI. That bug gives more details
>>> and
>>> justification for that ABI.
>>> The user interface for the new ABI would be that -fwhole-program-vtables
>>> would take an optional value indicating which aspects of the program have
>>> whole-program scope. For example, the existing implementation of
>>> whole-program
>>> vcall optimization allows external code to call into translation units
>>> compiled with -fwhole-program-vtables, but does not allow external code
>>> to
>>> derive from classes defined in such translation units, so you could
>>> request
>>> the current behaviour with "-fwhole-program-vtables=derive", which means
>>> that derived classes are not allowed from outside the program. To request
>>> the new ABI, you can specify "-fwhole-program-vtables=call,derive",
>>> which means that calls and derived classes are both not allowed from
>>> outside the program. "-fwhole-program-vtables" would be short for
>>> "-fwhole-program-vtables=call,derive,anythingelseweaddinfuture".
>> 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.
>> The new user interface is as follows:
>> 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]].
>> 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.
>> The ABI for a dynamic-introducing class is determined from the attribute,
>> or if the class has no attribute, from the following flags:
>> -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).
>> -funstable-c++-abi-classes=PATH would enable the unstable C++ ABI for
>> dynamic-introducing classes specified in the file at PATH.
>> 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.
>> 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.
>> 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.
>> In Chromium for example, the contents of the file would look like this:
>> *
>> app::**
>> base::**
>> browser::**
>> [...]
>> wm::**
>> zip::**
> Wouldn't we want to say "use custom ABI for everything non-exported"
> instead of manually tagging everything?

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.

One other approach I considered was a "whitelist minus blacklist" approach,
where the file would look like this:


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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160304/b78b6a45/attachment.html>

More information about the cfe-dev mailing list