Skip to content

Commit d71380d

Browse files
committed
Describe the interaction of lexical ordering, pack expansion, and if
constexpr. Fixes #40
1 parent 72e84eb commit d71380d

File tree

1 file changed

+69
-19
lines changed

1 file changed

+69
-19
lines changed

abi.html

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4881,7 +4881,8 @@ <h5><a href="#mangling.named">5.1.5.5 Class, union, and enum types</a></h5>
48814881
</pre></font></code>
48824882

48834883
The number is omitted for the first unnamed type in the class; it is
4884-
n-2 for the nth unnamed type (in lexical order) otherwise.
4884+
n-2 for the nth unnamed type (in <a href="#lexical-ordering">lexical order</a>)
4885+
otherwise.
48854886
<p>
48864887
(The mangling of such unnamed types defined in namespace scope is
48874888
generally unspecified because they do not have to match across
@@ -5358,7 +5359,8 @@ <h4><a href="#mangling-scope">5.1.7 Scope Encoding</a></h4>
53585359
within a function if they are declared in different scopes. In this
53595360
case, a discriminator must be added to the
53605361
&lt;<a href="#mangle.local-name">local-name</a>&gt;. Entities with
5361-
the same "top-level" name are numbered in lexical order within
5362+
the same "top-level" name are numbered in
5363+
<a href="#lexical-ordering">lexical order</a> within
53625364
the function definition. A discriminator is added only for the second
53635365
and later occurrences of the same name, and so the
53645366
&lt;<a href="#mangle.number">number</a>&gt; in the discriminator
@@ -5379,8 +5381,8 @@ <h4><a href="#mangling-scope">5.1.7 Scope Encoding</a></h4>
53795381
</pre></font></code>
53805382

53815383
where the number is is omitted for the first unnamed type in the
5382-
function, and <i>n</i>-2 for the <i>n</i>th unnamed type (in lexical
5383-
order) otherwise.
5384+
function, and <i>n</i>-2 for the <i>n</i>th unnamed type
5385+
(in <a href="#lexical-ordering">lexical order</a>) otherwise.
53845386

53855387
<p>
53865388
For example:
@@ -5412,25 +5414,14 @@ <h4><a href="#mangling-scope">5.1.7 Scope Encoding</a></h4>
54125414
is used for string literals. The discriminator is used only if there
54135415
is more than one, for the second and subsequent ones. In this case
54145416
again &lt;<a href="#mangle.number">number</a>&gt; is <i>n</i>-2 for
5415-
the <i>n</i>th distinct string literal, in lexical order, appearing in
5417+
the <i>n</i>th distinct string literal, in
5418+
<a href="#lexical-ordering">lexical order</a>, appearing in
54165419
the function. Multiple references to the same string literal produce
54175420
one string object with one name in the sequence. <i>Note that this
54185421
assumes that the same string literal occurring twice in a given
54195422
function in fact represents a single entity, i.e. has a unique
54205423
address.</i>
54215424

5422-
<p>
5423-
In all cases, the numbering order is strictly lexical order based on
5424-
the original token sequence. All entities occurring in that sequence
5425-
are to be numbered, even if subsequent optimization makes some of them
5426-
unnecessary. The ordering of literals appearing in a
5427-
mem-initializer-list shall be the order that the literals appear in
5428-
the source, which may be different from the order in which the
5429-
initializers will be executed when the program runs. It is expected
5430-
that this will be the 'natural' order in most compilers. In any case,
5431-
conflicts would arise only if different compilation units including
5432-
the same code were compiled by different compilers.
5433-
54345425
<p>
54355426
For entities in constructors and destructors, the mangling of the
54365427
complete object constructor or destructor is used as the base function
@@ -5503,7 +5494,8 @@ <h4><a href="#closure-types">5.1.8 Closure Types (Lambdas)</a></h4>
55035494
</pre></font></code>
55045495
The number is omitted for the first closure type with a given
55055496
&lt;<a href="#mangle.lambda-sig">lambda-sig</a>&gt; in a given context; it is n-2 for the nth closure
5506-
type (in lexical order) with that same &lt;<a href="#mangle.lambda-sig">lambda-sig</a>&gt; and context.
5497+
type (in <a href="#lexical-ordering">lexical order</a>)
5498+
with that same &lt;<a href="#mangle.lambda-sig">lambda-sig</a>&gt; and context.
55075499
<p>
55085500

55095501
<p>
@@ -5587,9 +5579,67 @@ <h4><a href="#closure-types">5.1.8 Closure Types (Lambdas)</a></h4>
55875579
href="#mangle.lambda-sig">lambda-sig</a>&gt; can only ever refer to a
55885580
template parameter of a generic lambda.
55895581

5582+
<p>
5583+
<a name="lexical-ordering">
5584+
<h4><a href="#lexical-ordering">5.1.9 Lexical ordering</a></h4>
5585+
5586+
<p>
5587+
Lexical ordering is used for numbering local entities
5588+
(unnamed classes and enumerations,
5589+
closure types, and static local variables)
5590+
when there is no other way of distinguishing them.
5591+
Except as described below, all local entities are to be numbered,
5592+
even if subsequent optimization makes some of them unnecessary,
5593+
or no mangled name is actually required for some of them.
5594+
The ordering of entities appearing in a
5595+
mem-initializer-list shall be the order that the entities appear in
5596+
the source, which may be different from the order in which the
5597+
initializers will be executed when the program runs.
5598+
It is expected that this will be the 'natural' order in most compilers.
5599+
5600+
<p>
5601+
Within a non-template, the numbering
5602+
is in strictly lexical order based on the original token sequence.
5603+
Within a template instantiation, the numbering
5604+
is established after packs are expanded and discarded statements in
5605+
constexpr ifs are removed.
5606+
All entities from one expansion of a pack are considered to occur
5607+
lexically before any entities from the next expansion of the same pack,
5608+
but the ordering is otherwise based on the original token sequence.
5609+
This is expected to match the numbering that would be established for
5610+
the corresponding non-template generated by substitution into the template.
5611+
As a consequence of these rules, the entity instantiated for a particular
5612+
source construct can have a different mangling number in different
5613+
instantiations of the same template.
5614+
For example:
5615+
5616+
<code><pre>
5617+
void g(...);
5618+
template&lt;bool b, typename ...T> void f() {
5619+
if constexpr(b) { []{}; }
5620+
g(([]{}, []{ static T n; return &amp;n; }())...);
5621+
}
5622+
5623+
// The first lambda is discarded and does not receive a number.
5624+
// The variables passed to g are therefore mangled as
5625+
// _ZZZ1fILb0EJiiEEvvENKUlvE0_clEvE1n and
5626+
// _ZZZ1fILb0EJiiEEvvENKUlvE2_clEvE1n.
5627+
template void f&lt;false, int, int>();
5628+
5629+
// The variable passed to g is mangled as
5630+
// _ZZZ1fILb1EJiEEvvENKUlvE1_clEvE1n and
5631+
template void f&lt;true, int>();
5632+
5633+
// Both lambdas are numbered; returns _ZZZ1hvENKUlvE0_clEvE1n.
5634+
inline int *h() {
5635+
if constexpr(false) { []{}; }
5636+
return []{ static int n; return &amp;n; }();
5637+
}
5638+
</pre></code>
5639+
55905640
<p>
55915641
<a name="mangling-compression">
5592-
<h4><a href="#mangling-compression">5.1.9 Compression</a></h4>
5642+
<h4><a href="#mangling-compression">5.1.10 Compression</a></h4>
55935643

55945644
<p>
55955645
To minimize the length of external names,

0 commit comments

Comments
 (0)