Skip to content

Commit e2a97bb

Browse files
authored
Merge branch 'master' into functions
2 parents 70a56da + d74f3d0 commit e2a97bb

File tree

2 files changed

+114
-55
lines changed

2 files changed

+114
-55
lines changed

abi-mangling.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@
5656
<tr><td>oper</td> <td>d</td> <td> V </td> <td> Operator /= </td> </tr>
5757
<tr><td>syn </td> <td>d</td> <td> x </td> <td> Designated array initializer </td> </tr>
5858
<tr><td>syn </td> <td>d</td> <td> X </td> <td> Designated array range initializer </td> </tr>
59-
<tr><td>type</td> <td>D</td> <td> p </td> <td> pack expansion of (C++0x) </td> </tr>
60-
<tr><td>type</td> <td>D</td> <td> t </td> <td> decltype of an id-expression or class member access (C++0x) </td> </tr>
59+
<tr><td>type</td> <td>D</td> <td> p </td> <td> pack expansion of (C++11) </td> </tr>
60+
<tr><td>type</td> <td>D</td> <td> t </td> <td> decltype of an id-expression or class member access (C++11) </td> </tr>
6161
<tr><td>obj </td> <td>D</td> <td> C </td> <td> structured binding declaration (C++1z) </td> </tr>
62-
<tr><td>type</td> <td>D</td> <td> T </td> <td> decltype of an expression (C++0x) </td> </tr>
62+
<tr><td>type</td> <td>D</td> <td> T </td> <td> decltype of an expression (C++11) </td> </tr>
6363
<tr><td>obj </td> <td>D</td> <td> 0 </td> <td> Deleting destructor</td> </tr>
6464
<tr><td>obj </td> <td>D</td> <td> 1 </td> <td> Complete object (in-charge) destructor</td> </tr>
6565
<tr><td>obj </td> <td>D</td> <td> 2 </td> <td> Base object (not-in-charge) destructor</td> </tr>
@@ -107,7 +107,7 @@
107107
<tr><td>oper</td> <td>o</td> <td> o </td> <td> Operator || </td> </tr>
108108
<tr><td>oper</td> <td>o</td> <td> r </td> <td> Operator | </td> </tr>
109109
<tr><td>oper</td> <td>o</td> <td> R </td> <td> Operator |= </td> </tr>
110-
<tr><td>type</td> <td>O</td> <td></td> <td> rvalue reference type (C++0x) </td> </tr>
110+
<tr><td>type</td> <td>O</td> <td></td> <td> rvalue reference type (C++11) </td> </tr>
111111
<tr><td>oper</td> <td>p</td> <td> l </td> <td> Operator + </td> </tr>
112112
<tr><td>oper</td> <td>p</td> <td> L </td> <td> Operator += </td> </tr>
113113
<tr><td>oper</td> <td>p</td> <td> m </td> <td> Operator ->* </td> </tr>

abi.html

Lines changed: 110 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -707,11 +707,13 @@ <h4><a href="#data-member-pointers"> 2.3.1 Data Member Pointers </a></h4>
707707

708708
<p>
709709
A null data member pointer is represented as an offset of <code>-1</code>.
710-
Unfortunately, it is possible to generate an data member pointer with an
710+
Unfortunately, it is possible to generate a data member pointer with an
711711
offset of <code>-1</code> using explicit derived-to-base conversions.
712712
If this is done, implementations following this ABI may misbehave.
713713
<span class="future-abi">Recommendation for new platforms: consider using
714-
<code>PTRDIFF_MIN</code> as the null data member pointer instead.</span>
714+
a different representation for data member pointers, such as left-shifting
715+
the offset by one and using a non-zero low bit to indicate a non-null
716+
value.</span>
715717

716718
<p>
717719
Note that by <code>[dcl.init]</code>, "zero initialization" of a data
@@ -732,8 +734,17 @@ <h4><a href="#data-member-pointers"> 2.3.1 Data Member Pointers </a></h4>
732734
<h4><a href="#member-function-pointers"> 2.3.2 Member Function Pointers </a></h4>
733735

734736
<p>
735-
The basic ABI properties of member function pointer types are those of
736-
the following class:
737+
Several different representions of member function pointers are in use.
738+
The standard representation relies on several assumptions about the
739+
platform, such as that the low bit of a function pointer to a non-virtual
740+
member function is always zero. For platforms where this is not reasonable
741+
to guarantee, an alternate representation must be used. One such
742+
representation, used on the 32-bit ARM architecture, is also described here.
743+
744+
<p>
745+
In all representations, the basic ABI properties of member function
746+
pointer types are those of the following class, where <code>fnptr_t</code>
747+
is the appropriate function-pointer type for a member function of this type:
737748

738749
<pre>
739750
struct {
@@ -742,61 +753,107 @@ <h4><a href="#member-function-pointers"> 2.3.2 Member Function Pointers </a></h4
742753
};
743754
</pre>
744755

745-
where <code>fnptr_t</code> is the appropriate function-pointer type
746-
for the member type.
747-
748756
<p>
749-
A member function pointer for a non-virtual function is represented
750-
with <code>ptr</code> set to a function pointer to the function,
751-
using the base ABI's representation of function pointers.
757+
A member function pointer for a non-virtual member function is represented
758+
with <code>ptr</code> set to a pointer to the function, using the base
759+
ABI's representation of function pointers.
752760

753761
<p>
754-
A member function pointer for a virtual function is represented
755-
with <code>ptr</code> set to 1 plus the virtual table offset of
756-
the function (in bytes), converted to a function pointer as if by <code>reinterpret_cast&lt;fnptr_t&gt;(uintfnptr_t(1 + offset))</code>,
762+
In the standard representation, a member function pointer for a virtual
763+
function is represented with <code>ptr</code> set to 1 plus the function's
764+
v-table entry offset (in bytes), converted to a function pointer as if by
765+
<code>reinterpret_cast&lt;fnptr_t&gt;(uintfnptr_t(1 + offset))</code>,
757766
where <code>uintfnptr_t</code> is an unsigned integer of the same
758767
size as <code>fnptr_t</code>.
759768

760769
<p>
761-
In both cases, <code>adj</code> stores the offset (in bytes) which
762-
must be added to a pointer to the base type before the call can be
763-
made. For a virtual member function pointer, the v-table is loaded
764-
from the adjusted address.
770+
In both of these cases, <code>adj</code> stores the offset (in bytes)
771+
which must be added to the <code>this</code> pointer before the call.
765772

766773
<p>
767-
The representation of virtual member function pointers requires the
768-
representation of a function pointer to a non-static member function
769-
to never have its lowest bit set. On most platforms, this is either
770-
always true, or it can be made true at little cost. (For example,
771-
on most platforms a function pointer is just the address of the
772-
first instruction in the function. Many architectures align all
773-
instructions to at least 2 bytes; even on architectures where that's
774-
not true, or where functions aren't byte-addressed, the compiler can
775-
just increase the alignment of non-static member functions until the
776-
low bit of the address is always reliably zero.) However, some platforms
777-
use the low bit of a function pointer for special purposes, such as to
778-
distinguish THUMB functions on ARM. Such platforms must use a slightly
779-
different representation: the virtual/non-virtual bit is instead stored
780-
as the lowest bit of <code>adj</code>, and the adjustment value is
781-
stored left-shifted by 1.
774+
In the standard representation, a null member function pointer is
775+
represented with <code>ptr</code> set to a null pointer. The value
776+
of <code>adj</code> is unspecified for null member function pointers.
782777

783778
<p>
784-
A null member function pointer is represented by a null value for
785-
<code>ptr</code>. (This assumes that the low bit of a null pointer
786-
is not 1; platforms with non-zero bit representations for null function
787-
pointers may need an adjusted rule.) The value of <code>adj</code>
788-
is not specified unless the alternative virtual-bit representation
789-
is being used, in which case the lowest bit of <code>adj</code> must
790-
also be zero but the remaining bits are still unspecified.
779+
The standard representation relies on some assumptions which are
780+
true for most platforms:
781+
782+
<ul compact>
783+
<li>The low bit of a function pointer to a non-static member function
784+
is never set. On most platforms, this is either always true or
785+
can be made true at little cost. For example, on platforms where
786+
a function pointer is just the address of the first instruction in the
787+
function, the implementation can ensure that this addresss is always
788+
sufficiently aligned to make the low bit zero for non-static member
789+
functions; often this is required by the underlying architecture.</li>
790+
791+
<li>A null function pointer can be distinguished from a virtual
792+
offset value. On most platforms, this is always true because the
793+
null function pointer is the zero value.</li>
794+
795+
<li>The offset to a v-table entry is never odd. On most platforms,
796+
the size of a v-table entry is even because the architecture is
797+
byte-addressed and pointers are even-sized.</li>
798+
799+
<li>A virtual call can be performed knowing only the addresss of a
800+
v-table entry and the type of the virtual function. On most
801+
platforms, a v-table entry is equivalent to a function pointer,
802+
and the type of that function pointer can be determined from the
803+
member pointer type.</li>
804+
</ul>
805+
806+
<p>
807+
However, there are exceptions. For example, on the 32-bit ARM
808+
architecture, the low bit of a function pointer determines whether
809+
the function begins in THUMB mode. Such platforms must use an
810+
alternate representation.
811+
812+
<p>
813+
In the 32-bit ARM representation, the <code>this</code>-adjustment
814+
stored in <code>adj</code> is left-shifted by one, and the low bit
815+
of <code>adj</code> indicates whether <code>ptr</code> is a function
816+
pointer (including null) or the offset of a v-table entry. A virtual
817+
member function pointer sets <code>ptr</code> to the v-table entry
818+
offset as if by
819+
<code>reinterpret_cast&lt;fnptr_t&gt;(uintfnptr_t(offset))</code>.
820+
A null member function pointer sets <code>ptr</code> to a null
821+
function pointer and must ensure that the low bit of <code>adj</code>
822+
is clear; the upper bits of <code>adj</code> remain unspecified.
823+
824+
<p>A member function pointer is null if <code>ptr</code> is equal
825+
to a null function pointer and (only when using the 32-bit ARM
826+
representation) the low bit of <code>adj</code> is clear.
827+
828+
<p>Two member function pointers are equal if they are both null or
829+
if their corresponding values of <code>ptr</code> and <code>adj</code>
830+
are equal. Note that the C++ standard does not require member pointers
831+
to the same virtual member function to compare equal; implementations
832+
using this ABI will do so, but only if the member pointers are built
833+
using the same v-table offset, which they may not be in the presence
834+
of multiple inheritance or overrides with covariant return types.
791835

792836
<p>
793837
Base-to-derived and derived-to-base conversions of a member function
794838
pointer can be performed by adding or subtracting (respectively) the
795-
static offset of the base within the derived class to the value of
796-
<code>adj</code>. In the alternative virtual-bit representation,
797-
the addend must be shifted by one. Because the adjustment does not
798-
factor into whether a member function pointer is null, this can be
799-
done unconditionally when performing a conversion.
839+
static offset of the base within the derived class to the stored
840+
<code>this</code>-adjustment value. In the standard representation,
841+
this simply means adding it to <code>adj</code>; in the 32-bit ARM
842+
representation, the addend must be left-shifted by one. Because the
843+
adjustment does not factor into whether a member function pointer is
844+
null, this addition can be done unconditionally when performing a
845+
conversion.
846+
847+
<p>
848+
A call is performed as follows:
849+
850+
<ol>
851+
<li>Add the stored adjustment to the <code>this</code> address.</li>
852+
<li>If the member pointer stores a v-table entry offset, load the
853+
v-table from the adjusted <code>this</code> address and call
854+
the v-table entry at the stored offset.</li>
855+
<li>Otherwise, call the stored function pointer.</li>
856+
</ol>
800857

801858
<p> <hr> <p>
802859
<a name="class-types">
@@ -4962,12 +5019,13 @@ <h5><a href="#mangling-builtin">5.1.5.2 Builtin types</a></h5>
49625019
::= Da # auto
49635020
::= Dc # decltype(auto)
49645021
::= Dn # std::nullptr_t (i.e., decltype(nullptr))
4965-
::= u &lt;<a href="#mangle.source-name">source-name</a>&gt; # vendor extended type
5022+
::= u &lt;<a href="#mangle.source-name">source-name</a>&gt; [&lt;<a href="#mangle.template-args">template-args</a>&gt;] # vendor extended type
49665023
</pre></font></code>
49675024

49685025
<p>
49695026
Vendors who define builtin extended types shall encode them
4970-
as a 'u' prefix followed by the name in &lt;length,ID> form.
5027+
as a 'u' prefix followed by the name in &lt;length,I&gt; form,
5028+
followed by any arguments to the extended type.
49715029

49725030
<a name="mangle.function-type">
49735031
<h5><a href="#mangle.function-type">5.1.5.3 Function types</a></h5>
@@ -5064,10 +5122,10 @@ <h5><a href="#mangle.function-type">5.1.5.3 Function types</a></h5>
50645122
</p>
50655123

50665124
<p>
5067-
When a function parameter is a C++0x function parameter pack, its type
5125+
When a function parameter is a C++11 function parameter pack, its type
50685126
is mangled with <code>Dp &lt;<a href="#mangle.type">type</a>&gt;</code>, i.e., its type is a pack
50695127
expansion:
5070-
<pre><font color="blue"><code> &lt;<a name="mangle.type">type</a>&gt; ::= Dp &lt;<a href="#mangle.type">type</a>&gt; # pack expansion (C++0x)
5128+
<pre><font color="blue"><code> &lt;<a name="mangle.type">type</a>&gt; ::= Dp &lt;<a href="#mangle.type">type</a>&gt; # pack expansion (C++11)
50715129
</code></font></pre>
50725130
</p>
50735131

@@ -5080,8 +5138,8 @@ <h5><a href="#mangle.decltype">5.1.5.4 C++11 <code>decltype</code></a></h5>
50805138
the <code>decltype</code> type was parsed. (See farther <a href=#expressions>below</a> for
50815139
the encoding of expressions.)
50825140

5083-
<pre><font color="blue"><code> &lt;decltype&gt; ::= Dt &lt;<a href="#mangle.expression">expression</a>&gt; E # decltype of an id-expression or class member access (C++0x)
5084-
::= DT &lt;<a href="#mangle.expression">expression</a>&gt; E # decltype of an expression (C++0x)
5141+
<pre><font color="blue"><code> &lt;decltype&gt; ::= Dt &lt;<a href="#mangle.expression">expression</a>&gt; E # decltype of an id-expression or class member access (C++11)
5142+
::= DT &lt;<a href="#mangle.expression">expression</a>&gt; E # decltype of an expression (C++11)
50855143
</code></font></pre>
50865144
If the operand expression of <code>decltype</code> is not
50875145
<a href=#instantiation-dependent>instantiation-dependent</a>
@@ -5250,6 +5308,7 @@ <h5><a href="#mangle.function-param">5.1.5.9 Function parameter references</a></
52505308
::= fL &lt;L-1 non-negative <a href="#mangle.number">number</a>&gt; p &lt;<i>top-level</i> <a href="#mangle.CV-qualifiers">CV-qualifiers</a>&gt; _ # L > 0, first parameter
52515309
::= fL &lt;L-1 non-negative <a href="#mangle.number">number</a>&gt; p &lt;<i>top-level</i> <a href="#mangle.CV-qualifiers">CV-qualifiers</a>&gt;
52525310
&lt;<i>parameter-2 non-negative</i> <a href="#mangle.number">number</a>&gt; _ # L > 0, second and later parameters
5311+
::= fpT # this
52535312
</font></code></pre>
52545313
Note that top-level cv-qualifiers specified on a parameter type do not
52555314
affect the function type directly (i.e., <code>int(*)(T)</code> and
@@ -5544,7 +5603,7 @@ <h5><a href="#mangling.declaration-reference">5.1.6.2 References to declared ent
55445603
an <code>&lt;<a href="#mangle.unresolved-qualifier-level">unresolved-qualifier-level</a>&gt;</code> may encode a known
55455604
class type.
55465605
That production is also used for references to nonstatic members with no
5547-
associated expression designating the enclosing object (a C++0x feature).
5606+
associated expression designating the enclosing object (a C++11 feature).
55485607
For example:
55495608
<code><pre> struct Q { int x; } q;
55505609
template&lt;class T> auto f(T p)->decltype(p.x + q.x);

0 commit comments

Comments
 (0)