diff --git a/abi.html b/abi.html index f1147bd..ba6903d 100644 --- a/abi.html +++ b/abi.html @@ -5408,13 +5408,6 @@
T_
,
T0_
, T1_
, and so on.
-
- <template-param> ::= T_ # first template parameter
- ::= T <parameter-2 non-negative number> _
- <template-template-param> ::= <template-param>
- ::= <substitution>
-
-
For example:
@@ -5425,6 +5418,35 @@ 5.1.5.8 Template parameters
++In some contexts, it is necessary to mangle references to template parameters +that are not introduced by the innermost enclosing template parameter list. +Let L be the number of template parameter scopes enclosing the +template parameter scope in which the parameter is declared, +excluding any template parameter scopes whose template arguments +have already been substituted into the type or expression being mangled. +Typically L will be zero, but can be nonzero when a generic lambda +occurs within the signature of a function template, when mangling +a template template parameter declaration, or when mangling a constraint. +For example: + +
+ template<typename> struct A {
+ // Type of a is TL0_0_, type of b is T_, type of c is TL0__, type of u is TL1__.
+ template<typename T> void f(decltype([]<typename U, template<U u> typename>(auto a, T b, U c){})) {}
+ };
+
+
+
+
+ <template-param> ::= T_ # L == 0, first parameter
+ ::= T <parameter-2 non-negative number> _ # L == 0, second and later parameters
+ ::= TL <L-1 non-negative number> __ # L > 0, first parameter
+ ::= TL <L-1 non-negative number> _ <parameter-2 non-negative number> _ # L > 0, second and later parameters
+ <template-template-param> ::= <template-param>
+ ::= <substitution>
+
+
Note that a template parameter reference is a substitution candidate. @@ -5691,6 +5713,7 @@
::x
).
+When a lambda expression appears in the type of a function template at namespace scope, +that function template cannot be redeclared in other translation units, +so this ABI does not constrain its mangling except that it cannot collide +with symbols in other translation units. +When a lambda expression appears in an instantiation-dependent expression +in other contexts (for example, in the signature of a function template at class scope), +it is mangled as a <closure-type-name>, +excluding any name prefix, but including its number within its context. +The context is implied by the remaining portion of the encoding.
+tl
is used for direct-list-initializations, where the type name is directly followed by a braced-init-list; e.g., MyArray{1,2,3}
should be mangled tl7MyArrayLi1ELi2ELi3EE
. If the braced-init-list is parenthesized, this is not a direct-list-initialization, and it should be mangled with cv
and a nested il
; for example, MyArray({1,2,3})
should be mangled cv7MyArrayilLi1ELi2ELi3EE
.
If an implementation supports the full C99 designated initializer syntax (as an extension), a designator list comprising multiple designators results in @@ -5993,7 +6026,8 @@
+<lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters +
The number is omitted for the first closure type with a given <lambda-sig> in a given context; it is n-2 for the nth closure @@ -6081,16 +6116,75 @@<lambda-sig> ::= <explicit template-param-decl>* # Excluding template parameters introduced for
auto
parameters + <parameter type>+ # Parameter types or "v" if the lambda has no parameters5.1.8 Closure Types (Lambdas)
// Corresponding operator(): _ZNK1SIiE1xMUlvE_clEv
+If the context is within a class definition,
+and not within one of the above more specific cases,
+the closure class and its members are encoded as follows:
+
+As above, the <local-name> ::= Z <class name> E <entity name>
+
<entity name>
will contain a
+<closure-type-name>
,
+which is numbered within the class, counting only those closure types for which
+this mangling rule applies.
+For example:
+
+
+ struct S {
+ // Template argument is LZ1SEUlvE_E; f<true> is _ZN1S1fILb1EEEv1XILUlvE_EE
+ template<bool B> void f(X<[]{ return B; }()>) { ... }
+ int n = []{ return 0; }(); // not counted towards numbering in struct S
+ // Template argument is LZ1SEUlvE0_E; f<true> is _ZN1S1fILb1EEEv1XILUlvE0_EE
+ template<bool B> void f(X<[]{ return !B; }()>) { ... }
+ };
+
+When a lambda appears in the declaration portion of a function template,
+it is numbered within the enclosing context when determining
+the mangling of the function template and its instantiations.
+Similarly, when a lambda appears in the declaration portion
+of a non-template variable or function,
+it is numbered within the enclosing context.
+However, when a function or variable template is instantiated,
+all lambdas produced by that instantiation,
+including those in the declaration portion,
+are numbered within the resulting instantiated function or variable
+as part of the same numbering sequence as lambdas appearing
+in the function definition or variable initializer.
+For example:
+
+
+ struct S {
+ // S::f<int, int> is _ZN1S1fIJiiEEEv1XIJXspLUlvE_EEEE
+ // The lambda call operators for the two lambdas are
+ // _ZZN1S1fIJiiEEEv1XIJXspLUlvE_EEEEENKUlvE_clEi and
+ // _ZZN1S1fIJiiEEEv1XIJXspLUlvE_EEEEENKUlvE0_clEi,
+ // and numbering of lambdas with a <lambda-sig> of v
+ // within the body starts at UlvE1_.
+ template<typename ...T> void f(X<[]{ static T n; return &n; }...>) { ... }
+ };
+
In a generic lambda, uses of auto
in the parameter list
are mangled as the corresponding artificial template type parameter.
-This is never ambiguous with a lambda parameter whose type is an
-enclosing template type parameter, because lambdas are never mangled
-in a dependent context (they are forbidden from appearing in function
-signatures). A <template-param> in a <lambda-sig> can only ever refer to a
-template parameter of a generic lambda.
+If a generic lambda appears in a dependent context (for example, in
+the signature of a function template), references to its template
+parameters (including those introduced by uses of auto
)
+are encoded as <template-param>
s
+with a non-zero level.
+
+ + +A non-member function template whose signature contains a lambda-expression can +never redeclare a function template declared in a different translation unit. +Implementations must ensure that such symbols are not linked together across +translation units, perhaps by giving affected symbols internal linkage. + +