Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mangling for designated initialization #25

Closed
zygoloid opened this issue Jul 26, 2017 · 12 comments
Closed

mangling for designated initialization #25

zygoloid opened this issue Jul 26, 2017 · 12 comments

Comments

@zygoloid
Copy link
Contributor

Now that we've voted designated initialization into the C++ draft, we need a mangling. These are distinct:

template<typename T> void f(decltype(T{.a = 1, .b = 2}));
template<typename T> void f(decltype(T{.c = 1, .d = 2}));

Something like il di 1a Li1E di 1b Li1E E would be enough for what we've voted into C++ (and di 1a di 1b could be used for a multi-level .a.b designator, which implementations will likely support as an extension).

@rjmccall
Copy link
Collaborator

We should probably assume that implementations will support the full C99 feature as an extension, which means we need a designator for [3].

@thiagomacieira
Copy link

How are those distinct? I'm probably missing something, but to me those two look like two instantiations of function f, which are only possible if the template parameter T has either a member "a" then "b", or "c" then "d", which all can be initialised from integers. If you passed a type T that has a, b, c, d or c, d, a, b, then it would be an ambiguous overload.

Going to read the paper now to see if I can answer my own question.

@rjmccall
Copy link
Collaborator

They are distinct due to [temp.over.link]p4-6: corresponding parameter types contain expressions that name template parameters, and those expressions are neither equivalent nor functionally equivalent.

I believe you may be correct that it is not possible to unambiguously use them both in a single translation unit for an arbitrary set of template arguments. Unfortunately, that does not matter for the ODR; if it did, I think there would be a lot of stuff we wouldn't have to mangle.

@thiagomacieira
Copy link

Thanks for the reference. I was going to say that we don't need the values that were used to initialise since they aren't used in the actual call, but then I realised that you could have:

  template<typename T> void f(decltype(T{.a = 1, .b = nullptr}));

If the conversion from nullptr to b's type fails, then this is not a suitable overload. That means we do need the values used.

Anyway, as you said, we may expect compilers to support C99 extensions, like nested initialisation. So if we had:

  template<typename T> void f(decltype(T{.a.b = 1, .b = 2}));

Would that mangle instead as il di 1a1b Li1E di 1b Li1E E?

I assume an array declaration [1] = 2 would then be il di 1_ Li2E E, as array subscripts are always size_t and thus need no type specifier.

Finally, extracted from the kernel:

	[0 ... __NR_syscall_max] = &sys_ni_syscall,

becomes il di 0_547_ Xad12sys_ni_syscallE E (current value of __NR_syscall_max is 548 on x86-64). Or maybe il di 0_547_ L12sys_ni_syscallE E if we use the expansion since this is not a dependent name.

@zygoloid
Copy link
Contributor Author

Would that mangle instead as il di 1a1b Li1E di 1b Li1E E?

My suggestion was that it would mangle as il di 1a di 1b Li1E di 1b Li1E E. Under your proposal we would need a terminator for the list of designators, which seems like the wrong tradeoff given that a single-level designator is likely to be vastly more common.

I assume an array declaration [1] = 2 would then be il di 1_ Li2E E

That would mean { ._ = 2 }. Also, we need an expression here not just an index, since {[sizeof(T)] = 1} is valid. di <expr> doesn't quite work, because {[a] = 1} and {.a = 1} would mangle the same, but we could pick a different prefix, such as dx <expr> (designator index).

[0 ... __NR_syscall_max] =

Sure, if we want to support GNU extensions as well as C99 extensions, maybe dX <expr> <expr> would work as a mangling for this.

@thiagomacieira
Copy link

My suggestion was that it would mangle as il di 1a di 1b Li1E di 1b Li1E E. Under your proposal we would need a terminator for the list of designators, which seems like the wrong tradeoff given that a single-level designator is likely to be vastly more common.

I imagined that it would terminate at the first L or X, but sure, repeating di is a good idea too.

For the array, I'd recommend ix <expression> (for "index", same as the mangling for operator[]). That would make

    [obj[1]] = 2

mangle as ix Xix3objLi1EE Li2E (or ix XixL_Z3objELi1EE Li2E, depending on what that obj is).

In fact, for the dot, maybe dt <unresolved-name> instead of di ?

           ::= dt <expression> <unresolved-name>                    # expr.name

Sure, if we want to support GNU extensions as well as C99 extensions, maybe dX <expr> <expr> would work as a mangling for this.

Just being careful if some vendor wants to do this. But I'd recommend iX <expr> <expr> instead

@zygoloid
Copy link
Contributor Author

I imagined that it would terminate at the first L or X, but sure, repeating di is a good idea too.

This is an arbitrary expression context, not something like a <template-arg> with a very restrictive grammar. So we can't use that rule, and can't use dt or ix either.

@thiagomacieira
Copy link

Ah, right, I see il is already there:

           ::= il <expression> E                                    # {expr-list}, braced-init-list in any other context

I hadn't noticed it before, I thought it was new and then allowed for a new grammar expansion.

(shouldn't there be a + after <expression>?)

@rjmccall
Copy link
Collaborator

rjmccall commented Jul 26, 2017

Fixed (to be an <expression>*).

@itanium-cxx-abi itanium-cxx-abi deleted a comment from zygoloid Jul 26, 2017
@thiagomacieira
Copy link

While you're at it...

If the braced-init-list is parenthesized, this is not a direct-list-initialization, and it should be mangled with cv and a nested il; for example, MyArray({1,2,3}) should be mangled cv7MyArrayliLi1ELi2ELi3EE.

The il is transposed as li.

@rjmccall
Copy link
Collaborator

Also fixed, thanks!

@rjmccall
Copy link
Collaborator

PR has been merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants