diff --git a/abi.html b/abi.html index 22f6a61..e0ebdf0 100644 --- a/abi.html +++ b/abi.html @@ -4533,13 +4533,13 @@
-For the purposes of mangling, the name of an anonymous union is -considered to be the name of the first named data member found by a +For the purposes of mangling, the name of an anonymous struct or union +is considered to be the name of the first named data member found by a pre-order, depth-first, declaration-order walk of the data members of -the anonymous union. If there is no such data member (i.e., if all of -the data members in the union are unnamed), then there is no way for a -program to refer to the anonymous union, and there is therefore no -need to mangle its name. +the anonymous type. If there is no such data member (i.e., if all of +the data members in the struct or union are unnamed), then there is +no way for a program to refer to the anonymous type, and there is +therefore no need to mangle its name.
@@ -5398,7 +5398,7 @@
_Z1fM1AKFvvRE
".
-A reference to a template parameter is mangled using the index @@ -5515,9 +5515,7 @@
Template argument lists appear after the unqualified template name, and are bracketed by I/E. This is used in names for specializations -in particular, but also in types and scope identification. Template -argument packs are bracketed by J/E to distinguish them from other -arguments. +in particular, but also in types and scope identification.
<template-args> ::= I <template-arg>+ E
@@ -5526,16 +5524,148 @@ 5.1.5.10 Template Arguments
::= X <expression> E # expression
::= <expr-primary> # simple expressions
::= J <template-arg>* E # argument pack
+ ::= <template-param-decl> <template-arg> # converted template argument
-Type arguments appear using their regular encoding.
-For example, the template class "A<char, float>" is encoded as "1AIcfE".
-A slightly more involved example is
-a dependent function parameter type "A<T2>::X"
-(T2 is the second template parameter)
-which is encoded as "N1AIT0_E1XE",
-where the "N...E" construct is used to describe a qualified name.
+Template arguments can be dependent when a template argument list
+is written in a context where dependent structures must be mangled.
+For example, if the parameter type of a function template is
+A<T2>::X
, where T2
is the second
+template parameter of the function template, this is mangled as
+N1AIT0_E1XE
.
+
+
+The mangling of template arguments in dependent contexts depends on
+whether the template argument can be matched with a template parameter
+and, if so, whether the argument can be checked against the parameter.
+In general, mangling assumes that all possible matching and checking
+has been performed. The conditions are not precisely laid out here,
+but matching is generally inhibited by an unresolved template name
+and in some situations with unexpanded pack expansions, while checking
+is generally inhibited by dependent arguments or parameters.
+In non-dependent contexts (in particular, in a top-level
+<encoding>
), template arguments should always be
+fully matched and checked against the template parameters of the
+specialized template.
+
+
+Under the ODR, function templates are distinguished by differences
+in their template head, such as a constraint on a template type
+parameter, the type of a non-type template parameter, or (recursively)
+the template head of a template template parameter. The template
+parameter list is not directly included in the
+<encoding>
of a function template specialization
+(except for the operator()
of a generic lambda),
+but it is indirectly reflected in the mangling of the template
+arguments as follows. A template parameter is said to be natural
+for a template argument that has been matched and checked against
+it if:
+
+The type of a non-type template parameter is said to contain deduced
+types if it is written with a placeholder type (auto
or
+decltype(auto)
) or a placeholder for a deduced class type
+(e.g. container
when that is a template with deducible
+template parameters).
+
+
+When mangling the template arguments of a function template that
+is not the operator()
of a lambda, if a template
+argument has been matched and checked against a template parameter
+that is not natural for the template argument, a
+<template-param-decl>
must be prefixed to the
+template argument. Earlier versions of this ABI did not call for this
+and so could fail to distinguish templates that must be distinguished
+under the ODR. This is not done for class templates in order to
+reduce ABI incompatibility, and in particular to allow class templates
+to adopt constraints without breaking ABI. It is not done for
+generic lambdas because the template parameter list is already
+encoded in the <lambda-sig>
.
+
+
+If a template parameter pack can be matched to a template argument
+pack, the pack is bracketed with J...E
+to distinguish it from other arguments. This is done even if some
+of the arguments in the pack cannot be checked against the parameter.
+If a <template-param-decl>
is required for the
+parameter, it is mangled immediately prior to the entire pack
+(the J
), not before the individual
+arguments in the pack.
+
+
+A template type argument or template template argument is mangled
+as a type in the usual way. For example, the class template
+specialization A<char, float>
is encoded as
+1AIcfE
.
+
+
+If a non-type template argument cannot be matched with a parameter, +or if it cannot be checked against that parameter, or if the +argument expression is instantiation-dependent, it is mangled +as an expression in the usual way for a +dependent mangling. Otherwise, +the argument is converted to the parameter type, constant-evaluated, +and then mangled as an expression representing that value. Precise typing is required when mangling +this constant if: +
operator()
of a generic lambda and a
+ <template-param-decl>
is not required.
+
+For example:
+
+
+
+
+
+template <class T, T value> class A;
+
+template <class U, template <class T, T N> class Temp> void f(Temp<U, 4+5>) {}
+
+f<unsigned, A> // _Z1fIj1AEvT0_IT_XplLi4ELi5EEE
+// The template parameter type is dependent, and so the template
+// argument is mangled as a dependent expression without any
+// constant-folding.
+
+template <template <class T, T N> class Temp> void g(Temp<unsigned, 4+5>) {}
+g<A> // _Z1gI1AEvT_IjLj9EE
+// The template parameter type is not dependent, and so the template
+// argument is converted to unsigned and constant-evaluated.
+
5.1.5.11 Template parameter declarations
+
+
+
+Template parameter declarations are usually not mangled. To distinguish +function templates with different template signatures, the ABI mostly +relies on the mangling of template arguments to include enough +information to determine which template is meant. However, there are +some cases where this is not sufficient, such as when the template +parameter contains deduced types, or when mangling generic lambdas. +In these cases, the template parameter must be mangled directly. + +
+ <template-param-decl> ::= Ty # template type parameter
+ ::= Tn <type> # template non-type parameter
+ ::= Tt <template-param-decl>* E # template template parameter
+ ::= Tp <non-pack template-param-decl> # template parameter pack
+
+It is sometimes necessary to mangle a constant value resulting from +constant evaluation. Currently this is limited to several places +in the mangling of a non-dependent non-type +template argument. In general, this is done by mangling a notional +expression with the value and type of the constant. For various reasons, +these mangled expressions do not always correspond to valid source +expressions. + +
+The mangling of constant values is sensitive to the converted type of
+the constant. For example, the expression 5
has type
+int
, but when it is used as the argument for a template
+parameter of type unsigned short
, it is converted to that
+type and mangled as Lt5E
. Some contexts require
+precise typing, meaning that constants must be mangled in a way
+that includes the exact converted type. In other contexts, some
+information not necessary to distinguish constants is omitted in
+order to reduce symbol sizes and preserve existing manglings.
+The places in this ABI that call for the mangling of a constant value
+all indicate whether precise typing is required for a particular
+constant.
+
+
+Values of integer, enumerated, floating-point, or complex type are
+mangled as literals of the approproiate
+type. Note that this can produce combinations which cannot normally be
+written in the source language, such as a literal of short
+type.
+
+
+Null pointers and member pointers are mangled as as a literal
+0
of their type. For example:
+
+
+
+
+struct A;
+template <void (A::*)()> void f();
+
+f<nullptr> // _Z1fILM1AFvvE0EEvv
+
+Non-null values of reference or pointer type are mangled using the
+constant object reference
+expression for the argument. Note that, if this is a simple
+declaration reference, it may end up being an
+<expr-primary>
+and must be mangled without X...E
when
+mangled as a template-arg
.
+
+
+Non-type template argument values of member pointer type +that are not null are mangled using the +member pointer +reference expression for the argument. + +
+Non-type template argument values of class type are mangled as
+a direct initialization (tl
) of the class type
+using the member
+initiializer sequence for the contents of the type.
+
+
+5.1.6.3 Constant object reference expressions
+
+
+
+Constant evaluation may result in a pointer or reference to a function +or to a subobject of an object of static storage duration, possibly +converted to a different type. Under the standard, references to +formally different subobjects are different template arguments even +if they coincide in their type and address. This entity is identified +in the mangling as if it were written with a specific expression, +called the reference expression. The exact expression depends on +whether precise typing is +required. + +
+Let ObjectType
be the unqualified type of the referenced
+function or subobject, and let ConstantType
be the pointee
+type of the constant type. These types can differ by more than just
+qualification if the constant has been converted to a type such as
+void*
.
+
+
+Initially, the reference expression is an expression referring
+to the function or top-level object, mangled with the L_Z
+production in
+<expr-primary>
.
+The notional type of this expression is the declared type of the
+function or object, including any qualifiers.
+
+
+Next, if the value refers to an object that is not a top-level object,
+the reference expression is wrapped in a special expression used only
+for this purpose, using the so
mangling
+below. The notional type of this expression is the encoded referent
+type.
+
ConstantType
differs from ObjectType
by
+ more than just qualification then the referent type for the mangling
+ is ObjectType
. Otherwise, the referent type for the
+ mangling is ConstantType
.
+
+ <expression> ::= so <referent type> <expression> [<offset number>] <union-selector>* E
+ <union-selector> ::= _ [<number>]
+
+
+
+Next, if the constant is a pointer, the reference expression is
+wrapped in a unary &
operator (that is, prefixed with
+ad
. The notional type of this expression
+is a pointer to the notional type of the previous reference expression.
+
+
+Finally, if precise typing is required and the notional type of the
+current reference expression doesn't match the type of the constant,
+the reference expression is wrapped in a C-style cast to the constant
+type (that is, prefixed with cv <type>
).
+
+
+5.1.6.4 Member pointer reference expressions
+
+
+
+Constant evaluation may result in a member pointer to a specific +member, possibly converted to a different type. As with other constant +manglings, this value is identified in the mangling as if it were written +with a certain expression, called the reference expression. The exact expression depends on whether precise +typing is required. + +
+The initial reference expression applies the prefix operator
+&
to the member declaration as if it were a regular
+function or variable. The notional type of this expression is a
+member pointer type using the declaring class and the declared type of
+the member. For example:
+
+
+
+
+struct A {
+ void foo();
+};
+template <void (A::*)()> void f();
+
+f<&A::foo> // _Z1fIXadL_ZN1A3fooEvEEEvv
+
+If the class type of the constant is not the declaring class of the
+member, the reference expression is wrapped in a special expression
+used only for this purpose, which encodes the this
-adjustment
+that must be applied to a pointer to the class type of the constant
+in order to produce a pointer to the declaring class of the member.
+The offset is omitted if zero. The notional type of this expression
+is a member pointer type using the class type of the constant and the
+declared type of the member.
+
+
+ <expression> ::= mc <class type> <expression> [<offset number>] E
+
+
+
+Finally, if precise typing is required and the notional type of the
+current reference expression is not the type of the constant, the
+reference expression is wrapped in a C-style cast to the constant
+type (that is, prefixed with cv <type>
).
+This can happen because static_cast
may add qualifiers
+to the member type.
+
+
+
+
+struct A {
+ char x;
+ void foo();
+};
+struct B {
+ char y;
+};
+
+struct C : A, B {};
+template <void (C::*)()> void f();
+
+f<&A::foo> // _Z1fIXmcM1CFvvEadL_ZN1A3fooEvE1EEEvv
+
+The mc
mangling uses an offset instead of
+a base path to avoid exposing private details of the class into the ABI,
+such as the names of any intermediate base classes.
+
+
+5.1.6.5 Member initializer sequences
+
+
+
+The constant evaluation of an expression of class type assigns +a constant value to each non-static data member of the class or, +if the class is a union, to at most one non-static data member, +called the active union member. Under the standard, this exact +structure uniquely determines a value, including whether a union +has an active union member member and (if so) which one. As +different values can produce different template specializations, +this structure must be faithfully represented in the mangling of +a value as a template argument. + +
+A value is converted to a flattened sequence of values by applying +the following expansions until no values of array or non-union class +type remain: +
+This sequence is then mangled as a sequence of
+<braced-expression>
s
+as follows:
+
L <type > E
.
+ +Precise typing is not required when mangling the constant member values. +Note that qualifiers on the type of a non-static data member are not +part of the type of the value stored in that member. + +
+For example:
+
+
+
+struct A {
+ int x, y;
+};
+struct B {
+ union { A a; };
+ constexpr B(int x, int y) { a.x = x; a.y = y; }
+};
+
+template <B v> struct C {};
+
+C<0,0> // 1CIXtl1BEEE
+C<1,0> // 1CIXtl1BtlNS0_Ut_Edi1atl1ALi1EEEEEE
+C<1,1> // 1CIXtl1BtlNS0_Ut_Edi1atl1ALi1ELi1EEEEEE
+
5.1.7 Scope Encoding