[cxx-abi-dev] mangling for c++17 decomposition declarations

Richard Smith richardsmith at google.com
Sat Aug 13 01:06:03 UTC 2016


On 12 August 2016 at 17:29, John McCall <rjmccall at apple.com> wrote:

> > On Aug 12, 2016, at 4:59 PM, Richard Smith <richardsmith at google.com>
> wrote:
> >
> > C++17 decomposition declarations are (surprisingly) permitted at global
> scope. They can't be forward-declared nor made inline (yet...), and it
> seems likely that the wording probably didn't *mean* to allow them to be
> declared as templates, so we don't appear to need a cross-vendor mangling
> for them. However, establishing a convention would be useful for demanglers.
> >
> > For now, I'm mangling global decomposition declarations as:
> >
> >   <unqualified-name> ::= DC <source-name>* E
> >
> > ... where the <source-name>s are the names of the bindings. (I'm
> mangling the bindings in the obvious way, as if they were reference
> declarations, but they get a mangled name even at global scope.)
> >
> > We could get away with mangling only the name of the first binding, but
> the extra information seems useful to people looking at the mangled name.
> >
> > Thoughts? Is it worth specifying this in the ABI?
>
> For those of us who aren't following the standards process that closely,
> would you mind explaining the more basic ABI impact of the feature?  Are
> the individual bindings separate objects that should be mangled as it they
> were actually declared separately, and so this compound mangling only
> serves to uniquely identify the initializer in case it contains entities
> that need / ought to be mangled?


Yes, but the bindings are always of reference type when they exist at all.
In a decomposition declaration like:

  auto [a, b, c] = expr;

there are (potentially, see below) four distinct entities: a variable

  auto e = expr;

and three bindings (a, b, and c). The mangling above would be used for the
'e' variable. There is no way to reference that implicit variable except
through the bindings.

There are two different cases for the behavior of the bindings: either they
are built-in bindings representing some subobject of e (including bitfield
members) with no corresponding entity, or (for types like std::tuple) they
act as variables of reference type initialized by some user-specified
expression which can have arbitrary side-effects (the corresponding
extension mechanism involves specializing standard-library templates and
providing a function template to be found by ADL, and has no ABI impact).

For the built-in case, it seems most straightforward to not generate
globals at all (and emit references to a, b, and c directly as references
to the corresponding subobject of e), but for the user-defined extension
case, code is run to initialize the bindings and they generally need to act
like global variables. A pedantic reading of the standard suggests that you
could do this:

  auto [a] = std::tuple<int>(0); // tu1.cc

  extern int &&a; // tu2.cc

... which would certainly restrict the ABI choices, but I don't think that
was an intended consequence of the rules.

There is (currently) no way to declare the same decomposition declaration
across multiple translation units (there's a syntactic limitation
preventing them from being static locals, inline globals, or static data
members), so in that sense there is no formal ABI impact.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20160812/c98b94d5/attachment.html>


More information about the cxx-abi-dev mailing list