Meeting agenda for 17 Feb 2000
Daveed Vandevoorde
daveed at edg.com
Thu Feb 17 17:24:24 UTC 2000
Attached is an updated mangling spec. It starts with a "left to do" list.
I won't be able to attend today's meeting though.
Daveed
-------------- next part --------------
Name mangling
=============
[ To do:
. Revise examples.
. Mangling of special entities: VT, VTT, typeinfo, "TID", helper variables
to ensure one-time initialization and thread protection, ...
. ILP-32 conventions?
. Complete glossary of Sx abbreviations.
. Escape mechanism for extended operator like __alignof?
. Proof of nonambiguity
. 80-bit vs. 128-bit long doubles?
]
Entities with C linkage and file scope variables are not mangled.
General structure
-----------------
_Z<name><type>opt
<name> is one of:
<unqualified-name>
<length><function name>
<length><function name>I<template-args>E
<operator-name>
<operator-name>I<template-args>E
<special-name>
(see below: ctors, vtables, ...)
<qualified-name>
N<qual-1>...<qual-J><unqualified-name>E
<local-name>
(see below: scope encoding)
<type> is used to disambiguate overloaded functions, but also to
distinguish the various virtual tables associated with a given complete
class type. For nontemplate functions, <type> lists the parameter types
only. For template functions, <type> lists the return type followed by
the parameter types. <type> is omitted for variables and static data
members.
Operator encodings
------------------
Operators appear as function names, but also in nontype template argument
expressions.
new nw
new[] na
delete dl
delete[] da
- (unary) ng
& (unary) ad
* (unary) de
~ co
+ pl
- mi
* ml
/ dv
% rm
& an
| or
^ eo
= aS
+= pL
-= mI
*= mL
/= dV
%= rM
&= aN
|= oR
^= eO
<< ls
>> rs
<<= lS
>>= rS
== eq
!= ne
< lt
> gt
<= le
>= ge
! nt
&& aa
|| oo
++ pp
-- mm
, cm
->* pm
-> pt
() cl
[] ix
? qu
(cast) cv
sizeof sz
Unlike Cfront, unary and binary operators using the same symbol have
different encodings. All operators are encoded using exactly two letters,
the first of which is lowercase.
Other special functions and entities
------------------------------------
TV virtual table
TI typeinfo structure
C1 complete object constructor
C2 base object constructor
D0 deleting destructor
D1 complete object destructor
D2 base object destructor
Type encodings
--------------
Types are encoded as follows:
builtin types: (one letter)
void v
wchar_t w
bool b
char c
signed char a
unsigned char h
short s
unsigned short t
int i
unsigned int j
long l
unsigned long m
long long x
unsigned long long y
float f
double d
long double e
ellipsis z
classes & enums:
<decimal length of unqualified name><unqualified-name>
Class names can optionally be followed by the encoding of a template
argument list (see below).
template params (including nontype and template template parameters):
T<param num>_
other dependent names: (see below)
N<qual 1>...<qual N><unqual name>E
template argument list: (see below)
I<arg1>...<argN>E
function types:
F<return type><param type 1>...<param type N>E
array types:
A<dimension>_<element type encoding>
pointers, references:
P<encoding pointed-to type>
R<encoding pointed-to type>
pointer-to-member:
M<class type encoding><member type encoding>
cv-qualifiers:
K const
V volatile
r restrict
Scope encoding
--------------
A nonlocal scope is encoded as the qualifier of a qualified name: it can be
the top-level name qualification or it can appear inside <type> to denote
dependent types or bind specific names as arguments. Qualified names are
encoded as:
N<qual 1>...<qual N><unqual name>E
where each <qual K> is the encoding of a namespace name or a class name (with
the latter possibly including a template argument list).
Occasionally entities in local scopes must be mangled too (e..g., because
inlining or separate template compilation causes mutliple translation units
to need access to that entity). Local entities that might be mangled are
numbered in lexical order starting with "1". The numbered entities are:
. local static variables
. local classes
. string literals
The local name encoding is then:
Z<function-encoding-without-prefix>E<num>_<entity-name>
where <entity-name> is either the entity's unqualified name or "0" (zero) if
it is a string literal.
Example:
namespace N {
inline char* f(int i) {
static char *p = "IA-64 C++ ABI"; // p = 1, "..." = 2
{ struct X { // X = 3
void g() {}
}; }
return p[i];
}
}
"_ZZN1N1fEiE1_1p": encoding of N::f:p (first local mangled entity)
"_ZZN1N1fEiE2_0": encoding of N::f:"IA-64 C++ ABI"
"_ZNZN1N1fEiE3_1X1gE": encoding of N::f:X::g()
(third local mangled entity used as a class-qualifier)
Template argument encoding
--------------------------
Template-ids are encoded by following the unqualified name with
I<arguments>E
This is used for the <specialization> segment in particular, but also in the
<type> and <scope> segments.
Type arguments appear using their regular encoding. For example, the
template class "A<char, float>" is encoded as "1AIcfE". A slightly more
involved example might be a dependent function parameter type "A<T2>::X"
(T2 is the second template parameter) which is encoded as "N1AIT2_E1XE",
where the "N...E" construct is used to describe a qualified name.
Nontype arguments can be:
a) a literal, e.g. "A<42L>": these are encoded as "L<type><num>E";
negative integer <num> are preceded with "n"; false is "Lb0E";
true is "Lb1E". For example, "A<-42L>" becomes "1AILln42EE".
If floating-point arguments are accepted as an extension, they
should be encoded using a fixed-length lowercase hexadecimal
string corresponding to the internal (IEEE) representation.
For example: "Lfbff000000" is -1.0f.
b) a reference to an entity with external linkage: encoded with
"L<mangled name>E". For example:
void foo(char); // mangled as _Z3fooc
template<void (&)(char)> struct CB;
// CB<foo> is encoded with "2CBIL_Z3foocEE"
c) an expression, e.g., "B<(J+1)/2>" is encoded with a prefix traversal
of the operators involved, delimited by "X...E". The operators are
encoded using their two letter mangled names. For example, "B<(J+1)/2>"
becomes "1BI Xdv pl T1_ Li1E Li2E E E" (the blanks were inserted to
visualize the decomposition).
Compression
-----------
The subsequence
S<num>_
is used to repeat the num-th most recently encoded type, namespace or template
(in right-to-left order, starting at "1"), but only if "S<num>_" is strictly
shorter that the previous encoding. A qualifier is less recent than what it
qualifies and a template name is is less recent than the template-id it might
be a part of. For example:
"_ZN1N1TIiiE2mfES4_IddE": Ret? N::T<int, int>::mf(N::T<double, double>)
since at the point where S4_ appears:
"S1_" == int
"S2_" == int
"S3_" == N::T<int, int>
"S4_" == N::T (template is less recent than template-id)
"S5_" == N (qualifier is less recent than qualified entity)
In addition, the following catalog of abbreviations of the form "Sx" should
be used:
St = ::std::
Sb = ::std::basic_string
Ss = ::std::basic_string<char, ::std::char_traits<char>,
::std::allocator<char> >
The abbreviation St is always treated as a qualifier and therefore does not
need a N...E construct. For example:
"_ZSt5state": ::std::state
"_ZStN3_In4wardE": ::std::_In::ward
Examples
--------
1) "f": The C function or variable "f" or a file scope variable "f".
2) "_Z1f": Ret? f();
3) "_Z1fi": Ret? f(int);
4) "_Z3foo3bar": Ret? foo(bar);
5) "_Zrm1X1X": Ret? operator%(X, X);
6) "_ZplR1XR1X": Ret? operator+(X&, X&);
7) "_ZlsRK1XS1_": Ret? operator(X const&, X const&);
(Note: strlen("S1_")<strlen("RK1X"))
8) "_Z1fIiE": void f<int>();
9) "_Z1fIiEvi": void f<int>(/*nondependent*/int);
(Note: the return type is always explicitly encoded for template
functions taking parameters.)
10) "_Z5firstI3DuoEvS2_": void first<Duo>(/*nondependent*/Duo);
(Note: "S1_" would refer to the "void" return type.)
11) "_Z5firstI3DuoEvT1_": void first<Duo>(/*T1=*/Duo);
12) "_ZN1N1fE": Ret? N::f();
13) "_ZN6System5Sound4beepE: Ret? System::Sound::beep();
14) "_ZN5Arena5levelE": Type? Arena::level;
15) "_ZN5StackIiiE5levelE": Type? Stack<int, int>::level
16) "_Z1fI1XEvPVN1AIT1_E1TE": void f<X>(A</*T1=*/X>::T volatile*);
| |
| `------> end dependent name encoding
`----------------> start of dependent name A<T1>::T
17) "_ZngIL42iEEvN1AIXplT1_L2iEE1TE": void operator-</*int J=*/42>(A<J+2>::T);
18) "_Z4makeI7FactoryiET1_IT2_E":
/*T1=*/Factory</*T2=*/int> make<Factory, int>();
// T1 == template template parameter
More information about the cxx-abi-dev
mailing list