> On Aug 12, 2016, at 6:06 PM, Richard Smith <[email protected]> wrote: > On 12 August 2016 at 17:29, John McCall <[email protected] > <mailto:[email protected]>> wrote: > > On Aug 12, 2016, at 4:59 PM, Richard Smith <[email protected] > > <mailto:[email protected]>> 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.
Ah, so it's not like you can declare a bunch of separate extern variables and then define them using a single decomposition binding; it really is a sort of inherently different declaration that just happens to create multiple names. > 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) What. I mean, okay, it's not actually unreasonable for the language to start taking advantage of the nature of reference-binding to do things like this, but it is surprising to sneak it in this way. Have they lifted the restrictions on local reference-binding as well? Obviously they can't be lifted for parameter binding, but there's no reason you couldn't bind a local reference to a bit-field; it's just implementation complexity. > 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), This is essentially required to handle bit-fields, at least. The value being decomposed by a builtin binding has to be a pr-value, right? Or gets coerced to one? Or is the model really just as simple as "there's an object initialized by this expression, and these names are bound to sub-objects of it". > 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. If this is formally allowed, I don't see why extern int &&a, &&b; auto [a,b] = std::make_pair(1,2); wouldn't be. But of course this cannot be made to support bit-field references without breaking ABI. > 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. Ok. John.
_______________________________________________ cxx-abi-dev mailing list [email protected] http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev
