diff --git a/abi.html b/abi.html index f1147bd..ba6903d 100644 --- a/abi.html +++ b/abi.html @@ -5408,13 +5408,6 @@
5.1.5.8 Template parameters
The sequence of parameters is therefore 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 @@

5.1.6 Expressions

::= L <nullptr type> E # nullptr literal (i.e., "LDnE") ::= L <pointer type> 0 E # null pointer template argument ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000) + ::= L <lambda closure-type-name> E # lambda expression ::= L _Z <encoding> E # external name <braced-expression> ::= <expression> @@ -5710,6 +5733,16 @@

5.1.6 Expressions

(e.g., ::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 @@

5.1.8 Closure Types (Lambdas)

  • default arguments appearing in class definitions
  • default member initializers
  • the bodies of inline or templated functions
  • -
  • the initializers of inline or templated variables
  • +
  • the initializers of inline or templated variables and static data members
  • +
  • the remaining contexts in class definitions
  • In all these contexts, the encoding of the closure types builds on an @@ -6004,7 +6038,8 @@

    5.1.8 Closure Types (Lambdas)

    <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ with -
      <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
    +
      <lambda-sig> ::= <explicit template-param-decl>*	# Excluding template parameters introduced for auto parameters
    +                   <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 @@

    5.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: +

      <local-name> ::= Z <class name> E <entity name>
    +
    +As above, the <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. +

    + +

    +<b>NOTE</b>: + +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. + +