-
Notifications
You must be signed in to change notification settings - Fork 100
Description
Standard paper: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf
C++20 adds the ability for near-arbitrary class types to be used as the type of non-type template arguments. We need a mangling for these.
We are guaranteed that such classes are not unions and do not contain unions, so perhaps the simplest approach would be to emit pseudo-aggregate-initialization syntax for the flattened sequence of subobjects:
struct A {
int x;
int : 0;
int y;
};
struct B : A { int arr[2]; };
template<auto> struct Q {};
void f(Q<B{1, 2, 3, 4}>); // mangled as _Z1f1QIXtl1BLi1ELi2ELi3ELi4EEEE
These are going to get very long, very fast, so we might want an alternative representation for large objects. One intended use case is for things like:
template<size_t N> struct str {
constexpr str(const char *p) : data{} { for (int n = 0; *p; ++p) data[n] = *p; }
char data[N];
};
template<size_t N> str(const char (&)[N]) -> str<N>;
template<str S> struct R {};
void f(R<"some very long string here">);
... and encoding this with a long sequence of Lic123E
manglings seems highly undesirable. This ties into another open question: how should string literal expressions be mangled? (Currently we say that we only mangle the length, which is insufficient.) Reusing whatever mangling we use for string literals as the mangling for char
arrays within a non-type template argument might be wise. Alternatively / additionally, we could emit only a (suitably secure) hash of the literal value if it's very long.
Another form of mangling is also required here: all non-type template arguments with the same value throughout the entire program are lvalues denoting the same object, so we need a mangling for the global constant holding that object. Proposal:
<special-name> ::= TA <template-arg> # template parameter object for argument <template-arg>
Eg:
template<auto V> const auto *p = &V;
// mangled as _Z1pIXtl1BLi1ELi2ELi3ELi4EEEE
// initialized as pointer to _ZTAXtl1BLi1ELi2ELi3ELi4EEE
template const B *p<B{1, 2, 3, 4}>;