Mangling literals

Mike Herrick mjh at edg.com
Thu May 20 14:13:32 UTC 2010


The ABI specification currently specifies how to mangle integer-literal (including boolean-literal and character-literal) as well as floating-literal but doesn't specify manglings for string-literal (outside of a function), pointer-literal, or user-defined-literal.

The need to mangle such literals comes from cases like:

 void *f(void *);
 template <class T> auto f1(T p1) -> decltype(p1("xyz"));
 template <class T> auto f2(T p1) -> decltype(p1(nullptr));
 int main() {
   f1(f);
   f2(f);
 }

pointer-literal (which includes only nullptr) could be mangled using the integer case of <expr-primary> to produce a mangled encoding of "L Dn 0 E" (uses "Dn" as the <builtin-type> for std::nullptr_t from Daveed's latest proposal -- https://www.codesourcery.com/archives/cxx-abi-dev/msg02250.html).  Alternatively, a new <expr-primary> production could be added specifically for nullptr which would eliminate the superfluous "0 E" in this case, but we feel that having the zero makes this look more like a value as opposed to a type.  So we're proposing to use the existing integer mangling for this case.

string-literals are currently given mangled names when they appear in inline or template functions (so that the address of the string will be the same across all instances).  Because string-literals aren't allowed as nontype template arguments, there's no mangled encoding specified for them.

The first thought is to extend the unique numbering scheme currently used to identify string literals, but we're wondering if even that is necessary.  We're not sure that you can write a test case that can distinguish two functions in overload resolution if they differ only in the contents of two string literals.  For example, we need a mangling that differentiates between these:

 template <class T> auto f(T p1) -> decltype(p1 == "xyz") { return true; }
 template <class T> auto f(T p1) -> decltype(p1 == 0.0)  { return false; }
 int main() {
   return !f("xyz");
 }

but do we need to differentiate between these ambiguous cases:

 template <class T> auto f(T p1) -> decltype(p1 == "xyz") { return true; }
 template <class T> auto f(T p1) -> decltype(p1 == "abc") { return false; }
 template <class T> auto f(T p1) -> decltype(p1 == "x")   { return false; }
 int main() {
   return !f("xyz");
 }

If not, then perhaps simply encoding the fact that a string literal was seen (and perhaps the character type) is sufficient.  For example, adding this to <expr-primary>:

             ::= L <character type> E 	            # string literal

which could be demangled as "...", L"...", u8"...", etc.

user-defined-literals are left for another day (unless someone would like to make a proposal).

Thoughts?

Mike Herrick
Edison Design Group


More information about the cxx-abi-dev mailing list