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 C++ pack indexing #175

Open
cor3ntin opened this issue Jan 10, 2024 · 4 comments
Open

Mangling for C++ pack indexing #175

cor3ntin opened this issue Jan 10, 2024 · 4 comments

Comments

@cor3ntin
Copy link

Hey folks

Pack indexing (https://wg21.link/p2662r3) was approved for C++26.
We will need to mangle these things.

A pack indexing is constituted of a pattern (which is either a type or an expression) and an indexing expression.
I am unfortunately not familiar enough with the ABI to offer suggestions

@rjmccall
Copy link
Collaborator

rjmccall commented Jan 11, 2024

Looks like it's a new type-level operator and a new expression-level operator. Apparently it will eventually be accepted as a template-name as well, but that's not currently included? Anyway, this should be straightforward; we just need to add new forms to <expression> and <type>.

Typical uses of this are probably going to exacerbate our existing problems with partial substitution, though. Consider when a pack indexing operator is used in the signature of a templated member of a class template and we can't expand the pack in the instantiated dependent signature of the template:

template <class... T> struct tuple {
  template <unsigned I> T...[I] get();
};

We'll need to solve that problem.

@cor3ntin
Copy link
Author

Ping on that, it would be nice to settle on a grammar! Thanks

@jicama
Copy link
Contributor

jicama commented Oct 25, 2024

template <class... T> struct tuple {
  template <unsigned I> T...[I] get();
};

I would expect mangling of T...[I] to just refer to the two template parameters, following the mangling for template parameters at different depths from PR #85 .

@zygoloid
Copy link
Contributor

I agree that using a reference to a template parameter by depth and index makes sense here. The scheme in #85 counts levels inwards from the first non-substituted level, and so L in this case would be -1, for which we don't yet have a mangling. Maybe something like TM<1 - L>_<index - 1>_, so I in the previous example would be TM0__?

One additional thought on this:

The "count from the first non-substituted level" rule means that we get different template parameter numbering in constraints versus the rest of the signature (due to the different number of substituted levels), which is annoying for demanglers to deal with. It'd be nice to change that to also use this new negative-levels numbering relative to the total number of substituted levels for the <encoding>, so that in

template<typename T, typename U> concept C = true;
template<typename ...T> struct A {
    template<typename ...U, int I> void f(T...[I], U...[I]) requires C<T...[I], U...[I]>;
};

... we'd use TM0__ and T_ to refer to T and U in both the constraint and the parameter types, rather than instead using T_ and TL0__ for T and U in the constraint as we currently do. Obviously that's an ABI break, and maybe it's already too late, but I think it would be a substantial improvement to the ease of demangling.

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

4 participants