C++ ABI Summary
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

C++ ABI Summary



Here are the updated documents.  (I sent the layout document a couple
of hours ago, and the closed issues list hasn't changed since the
mailing last Friday.)

I've added a concrete proposal for C-3.  The biggest issues for
discussion are probably B-6, C-2, and C-3.  Once again, here's the
list of most important actions we're waiting for:

Daveed
------

AI-13, A-6, B-8:  Describe RTTI representation, dynamic cast.

Priti
-----

AI-12:  Describe the Intel C++ exception handling model.
AI-5:   Set up N-way NDA if necessary to discuss it.

All
---

B-6:  Describe your RTTI representation.

F-x:  In anticipation of mangling discussions, please help by (a)
      identifying what needs to be mangled, and (b) describing any
      mangling/compression scheme(s) you think we should consider.
      (I have started a list in F-1.)

-- 
-	    Jim Dehnert		dehnert@xxxxxxx
				(650)933-4272
<HTML>

<HEAD>
<title>C++ ABI Summary</title>

<link rel=stylesheet href=small-table.css type="text/css">

<hr>

<font size=6><i><b>
<p>
C++ ABI Summary
</b></i></font>

<p>
<i>Revised 10 August 1999</i>

</center>

</HEAD>

<BODY>

<p>
<h4>Links</h4>

<ul>
<li> Full <a href=cxx-open.html>open</a> issues list.
<li> Full <a href=cxx-closed.html>closed</a> issues list.
<li> Draft <a href=abi-layout.html>data layout</a> specification.
</ul>

<p>
<hr>

<p>
<h4>Meetings</h4>

<p>
<table align=center border=on cellpadding=3>

<tr class=small>
<th colspan=2> When </th>
<th> Where </th>
<th> Phone </th>
</tr>

<tr class=small>
<td> 5 August </td> <td> 10:00-12:00 PDT </td>
<td align=left colspan=2> completed </td>
</tr>

<tr class=small>
<td> 12 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 19 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 26 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 2 September </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 9 September </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 16 September </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 23 September </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 30 September </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 7 October </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 14 October </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 21 October </td>
<td> 10:00-12:00 PDT </td>
<td> SGI ??? </td>
<td> 650-933-7952 </td>
</tr>

<tr class=small>
<td> 28 October </td>
<td> 10:00-12:00 PDT </td>
<td> SGI ??? </td>
<td> 650-933-7952 </td>
</tr>

</table>

<p>
Note:  When calling the SGI telephone bridges,
the first caller continues to ring until the second party joins.
To get rid of it, you can call from a second phone,
and I believe you can hang it up right away.

<p>
<hr>

<p>
<h4>Participants</h4>

<p>
<table border=on cellpadding=3>

<tr class=small>
<th> Company </th>
<th> Name </th>
<th> Telephone </th>
<th> Fax </th>
<th> Email </th>
</tr>

<tr class=tiny>
<th rowspan=1> </th>
<td colspan=3> overall reflector </td>
<td> <a href=mailto:cxx-abi@xxxxxxxxxxxxxxxxxxxx>cxx-abi@xxxxxxxxxxxx</a> </td>
</tr>

<tr class=tiny>
<th rowspan=6> SGI </th>
<td> Jim Dehnert </td>
<td> (650) 933-4272 </td>
<td> (650) 932-4272 </td>
<td> <a href=mailto:dehnert@xxxxxxx> dehnert@xxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Matt Austern </td>
<td> (650) 933-4196 </td>
<td> (650) 932-4196 </td>
<td> <a href=mailto:austern@xxxxxxxxxxxx> austern@xxxxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Hans Boehm </td>
<td> (650) 933-7144 </td>
<td> (650) 932-7144 </td>
<td> <a href=mailto:boehm@xxxxxxxxxxxx> boehm@xxxxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Shin-Ming Liu </td>
<td> (650) 933-4287 </td>
<td> (650) 932-4287 </td>
<td> <a href=mailto:shin@xxxxxxxxxxxx> shin@xxxxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> John Wilkinson </td>
<td> (650) 933-4298 </td>
<td> (650) 932-4298 </td>
<td> <a href=mailto:jfw@xxxxxxxxxxxx> jfw@xxxxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:cxx-abi-sgi@xxxxxxxxxxxx>
cxx-abi-sgi@xxxxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> CodeSourcery </th>
<td> Mark Mitchell </td>
<td> (650) 365-3064 </td>
<td> (650) 375-7694 </td>
<td> <a href=mailto:mark@xxxxxxxxxxxxxxxx> mark@xxxxxxxxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Cygnus </th>
<td> Jason Merrill </td>
<td> (408) 542-9665 </td>
<td> (408) 542-9765 </td>
<td> <a href=mailto:jason@xxxxxxxxxx> jason@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Ian Carmichael </td>
<td> (416) 482-3946 </td>
<td> (416) 482-6299 </td>
<td> <a href=mailto:iancarm@xxxxxxxxxx> iancarm@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Ulrich Drepper </td>
<td> (408) 765-4699 </td>
<td> ? </td>
<td> <a href=mailto:drepper@xxxxxxxxxx> drepper@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:c++abi@xxxxxxxxxx> c++abi@xxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> EDG </th>
<td> Daveed Vandevoorde </td>
<td> (650) 592-5768 </td>
<td> (650) 592-5781 </td>
<td> <a href=mailto:daveed@xxxxxxx> daveed@xxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> EPC </th>
<td> Colin McPhail </td>
<td> +44 (131) 225-6262 </td>
<td> +44 (131) 225-6644 </td>
<td> <a href=mailto:colin@xxxxxxxxx> colin@xxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Hewlett- Packard </th>
<td> Cary Coutant </td>
<td> (408) 447-5759 </td>
<td> (408) 447-4244 </td>
<td> <a href=mailto:cary@xxxxxxxxxx> cary@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Christophe de Dinechin </td>
<td> (408) 447-5491 </td>
<td> (408) 447-4244 </td>
<td> <a href=mailto:ddd@xxxxxxxxxx> ddd@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Sassan Hazeghi </td>
<td> (408) 447-5007 </td>
<td> (408) 447-4244 </td>
<td> <a href=mailto:sassan@xxxxxxxxxx> sassan@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:cxx-abi-hp@xxxxxxxxxxxxxxxxxx>
cxx-abi-hp@xxxxxxxxxxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> Humboldt- Universit&auml;t zu Berlin </th>
<td> Martin von L&ouml;wis </td>
<td> +49 30 2093 3118 </td>
<td> +49 30 2093 3112 </td>
<td> <a href=mailto:loewis@xxxxxxxxxxxxxxxxxxxxxxx> 
loewis@xxxxxxxxxxxxxxxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=3> IBM </th>
<td> Mark Mendell </td>
<td> (416) 448-3485 </td>
<td> (416) 448-4414 </td>
<td> <a href=mailto:mendell@xxxxxxxxxx> mendell@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Allan H. Kielstra </td>
<td> (416) 448-3558 </td>
<td> (416) 448-4414 </td>
<td> <a href=mailto:kielstra@xxxxxxxxxx> kielstra@xxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:CxxABI-ADTC-CAN@xxxxxxxxxx>
CxxABI-ADTC-CAN@xxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Intel </th>
<td> Sunil Saxena </td>
<td> (408) 765-5272 </td>
<td> (408) 653-8511 </td>
<td> <a href=mailto:Sunil.Saxena@xxxxxxxxx> Sunil.Saxena@xxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Suresh Rao </td>
<td> (408) 765-5416 </td>
<td> (408) 765-5165 </td>
<td> <a href=mailto:Suresh.K.Rao@xxxxxxxxx>
Suresh.K.Rao@xxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Priti Shrivastav </td>
<td> (408) 765-4699 </td>
<td> (408) 765-5165 </td>
<td> <a href=mailto:Priti.Shrivastav@xxxxxxxxx>
Priti.Shrivastav@xxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:cxx-abi@xxxxxxxxxxxxxxxxxxxx>
cxx-abi@xxxxxxxxxxxxxxxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> SCO </th>
<td> Jonathan Schilling </td>
<td> (908) 790-2364 </td>
<td> (908) 790-2426 </td>
<td> <a href=mailto:jls@xxxxxxx> jls@xxxxxxx </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Sun </th>
<td> George Vasick </td>
<td> (650) 786-5123 </td>
<td> (650) 786-9551 </td>
<td> <a href=mailto:george.vasick@xxxxxxxxxxx>
george.vasick@xxxxxxxxxxx <a></td>
</tr>
<tr class=tiny>
<td> Michael Lam </td>
<td> (650) 786-3492 </td>
<td> (650) 786-9551 </td>
<td> <a href=mailto:michael.lam@xxxxxxxxxxx> michael.lam@xxxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Michael Ball </td>
<td> (650) 786-9109 </td>
<td> (650) 786-9551 </td>
<td> <a href=mailto:michael.ball@xxxxxxxxxxx> michael.ball@xxxxxxxxxxx </a></td>
</tr>
<tr class=tiny>
<td> Reza Monajjemi </td>
<td> (650) 786-6175 </td>
<td> ? </td>
<td> <a href=mailto:reza.monajjemi@xxxxxxxxxxx>
     reza.monajjemi@xxxxxxxxxxx </a></td>
</tr>

</table>

<p>
<hr>

<p>
<h4> Objectives </h4>

<ul>
<p>
<li>
Interoperable C++ compilation on IA-64:
we want users to be able to build relocatable objects with
different compilers and link them together,
and if possible even to ship common DSOs.
This objective implies agreement on:
    <ul>    
    <li> Data representation
    <li> Object file representation
    <li> Library API
    </ul>

<p>
<li>
ISO Standard C++:
highest priority is functionality and performance of standard-compliant code.
It should not be sacrificed for the benefit of language extensions or
legacy implementations (though considering them as tie-breakers is fine).

<p>
<li>
Some areas will be easier to agree on than others.
Our priorities should be based on achieving as much
interoperability as possible if we can't attain perfection.
That is, it is better to end up with a few restrictions being required
for interoperable code, than to have no interoperability at all.
This suggests priorities as follows:
    <ol>
    <li> Items requiring base ABI changes that might affect other
	languages, and will therefore become impossible soon.
	Examples include exception handling / stack unwind,
	or ELF changes (not extensions).
    <li> Core features where differences will prevent virtually any
	C++ object code from porting.
	Examples include data layout and calling conventions.
    <li> Limited usage features,
	where users can achieve portability by avoiding the feature.
	An example might be multi-threading.
    <li> Peripheral features,
	where the requirements on users to achieve
	portability are clear and easy to implement.
	An example is non-explicit inlining,
	where compilers would presumably allow it to just be suppressed.
    <li> Tool interfaces, which affect how users build code,
	rather than what they build.
	An example is the compilation command line.
    </ol>

<p>
<li>
Mechanisms/methods which allow coexistence of incompatible
implementations may be suitable in some cases.
For instance, packaging vendor-specific compiler support runtimes
in DSOs occupying distinct namespaces might allow multiple such DSOs to
be loaded for mixed objects and avoid requiring that all vendors have
the same support runtimes.

</ul>

<p>
<hr>

<p>
<h4> Action Item Status </h4>

<p>
<table border=on cellpadding=3>

<tr class=small>
<th> # </th>
<th> Action </th>
<th> Who </th>
<th> Status </th>
<th> Opened </th>
<th> Closed </th>
</tr>

<tr class=small> <td> 1 </td>
<td> Distribute Sun C++ ABI </td>
<td> Mike Ball </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 2 </td>
<td> Distribute Sun C++ ABI Rationale </td>
<td> Mike Ball </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 3 </td>
<td> Distribute Taligent C++ ABI </td>
<td> Cary Coutant </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 4 </td>
<td> Expedite IA-64 RT Arch doc release </td>
<td> Cary Coutant </td>
<td> closed </td>
<td> 990603 </td>
<td> 990720 </td>
</tr>

<tr class=small> <td> 5 </td>
<td> Set up n-way NDA for eligible members </td>
<td> Priti Shrivastav </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 6 </td>
<td> Organize/summarize object layout issues and alternatives </td>
<td> Matt Austern </td>
<td> closed </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> 7 </td>
<td> Write-up of Vfunc call protocol
</td>
<td> Christophe de Dinechin </td>
<td> closed </td>
<td> 990610 </td>
<td> 990805 </td>
</tr>

<tr class=small> <td> 8 </td>
<td> Write-up of object layout strawman </td>
<td> Matt Austern </td>
<td> closed </td>
<td> 990610 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> 9 </td>
<td> Check with c++-core about empty base placement </td>
<td> Jason Merrill </td>
<td> closed </td>
<td> 990610 </td>
<td> 990618 </td>
</tr>

<tr class=small> <td> 10 </td>
<td> Describe dynamic cast / inaccessible base issue </td>
<td> Daveed Vandevoorde </td>
<td> closed </td>
<td> 990617 </td>
<td> 990701 </td>
</tr>

<tr class=small> <td> 11 </td>
<td> Summarize ctor/dtor issues </td>
<td> Michael Lam </td>
<td> closed </td>
<td> 990617 </td>
<td> 990729 </td>
</tr>

<tr class=small> <td> 12 </td>
<td> Describe Intel exception model </td>
<td> Priti Shrivastav </td>
<td> open </td>
<td> 990624 </td>
<td> </td>
</tr>

<tr class=small> <td> 13 </td>
<td> Propose RTTI representation </td>
<td> Daveed Vandevoorde </td>
<td> open </td>
<td> 990701 </td>
<td> </td>
</tr>

<tr class=small> <td> 14 </td>
<td> Open EDG exception stack? </td>
<td> Daveed Vandevoorde </td>
<td> open </td>
<td> 990715 </td>
<td> </td>
</tr>

<tr class=small> <td> 15 </td>
<td> Priority scheme descriptor for C-2 </td>
<td> Jim Dehnert </td>
<td> closed </td>
<td> 990715 </td>
<td> 990804 </td>
</tr>

<tr class=small> <td> 16 </td>
<td> Covariant return scheme </td>
<td> Jason Merill </td>
<td> closed </td>
<td> 990715 </td>
<td> 990729 </td>
</tr>

<tr class=small> <td> 17 </td>
<td> Validate Christophe's B-6 Vtable layout </td>
<td> Jim Dehnert </td>
<td> open </td>
<td> 990729 </td>
<td> </td>
</tr>

<tr class=small> <td> 18 </td>
<td> Check Sun dynamic cast algorithm </td>
<td> Michael Lam </td>
<td> open </td>
<td> 990805 </td>
<td>  </td>
</tr>

<tr class=small> <td> 19 </td>
<td> Write up C-3 destructor proposal </td>
<td> Jim Dehnert </td>
<td> open </td>
<td> 990805 </td>
<td> </td>
</tr>


</table>

<p>
<hr>

<p>
<h4> Issue Status </h4>

In the following table,
the <b><i>class</i></b> column attempts to classify the issue on the
basis of what it likely affects.
The identifiers used are:

<table>
<tr class=small> <td> call </td>
<td> Function call interface, i.e. call linkage </td>
</tr>

<tr class=small> <td> data </td>
<td> Data layout </td>
</tr>

<tr class=small> <td> lib </td>
<td> Runtime library support </td>
</tr>

<tr class=small> <td> lif </td>
<td> Library interface, i.e. API </td>
</tr>

<tr class=small> <td> g </td>
<td> Potential gABI impact </td>
</tr>

<tr class=small> <td> ps </td>
<td> Potential psABI impact </td>
</tr>

<tr class=small> <td> source </td>
<td> Source code conventions (i.e. API, not ABI) </td>
</tr>

<tr class=small> <td> tools </td>
<td> May affect how program construction tools interact </td>
</tr>
</table>

<p>
<hr width=50%>

<p>
<table border=on cellpadding=3>

<tr class=small>
<th> # </th>
<th> Issue </th>
<th> Class </th>
<th> Status </th>
<th> Source </th>
<th> Opened </th>
<th> Closed </th>
</tr>

<tr class=small> </tr>
<tr class=small> <th> A </th>
<th colspan=6> <a href=issues-C++-layout.html> Object Layout </a> </th>
</tr>

<tr class=small> <td> A-1 </td>
<td> Vptr location </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-2 </td>
<td> Virtual base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-3 </td>
<td> Multiple inheritance </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990701 </td>
</tr>

<tr class=small> <td> A-4 </td>
<td> Empty base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-5 </td>
<td> Empty parameters </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990701 </td>
</tr>

<tr class=small> <td> A-6 </td>
<td> RTTI (<code>type_info</code>) .o representation </td>
<td> data call ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> A-7 </td>
<td> Vptr sharing with primary base class </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990729 </td>
</tr>

<tr class=small> <td> A-8 </td>
<td> (Virtual) base class alignment </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-9 </td>
<td> Sorting fields as allowed by [class.mem]/12 </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-10 </td>
<td> Class parameters in registers </td>
<td> call </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990701 </td>
</tr>

<tr class=small> <td> A-11 </td>
<td> Pointers to member functions </td>
<td> data </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> A-12 </td>
<td> Merging secondary vtables </td>
<td> data </td>
<td> closed </td>
<td> Sun </td>
<td> 990610 </td>
<td> 990805 </td>
</tr>

<tr class=small> <td> A-13 </td>
<td> Parameter struct field promotion </td>
<td> call </td>
<td> closed </td>
<td> SGI </td>
<td> 990603 </td>
<td> 990701 </td>
</tr>

<tr class=small> <td> A-14 </td>
<td> Pointers to data members </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990729 </td>
<td> 990805 </td>
</tr>

<tr class=small> </tr>
<tr class=small> <th> B </th>
<th colspan=6> <a href=issues-C++-layout.html#vfunc>
Virtual Function Handling </a> </th>
</tr>

<tr class=small> <td> B-1 </td>
<td> Adjustment of "this" pointer (e.g. thunks) </td>
<td> data call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> B-2 </td>
<td> Covariant return types </td>
<td> call </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990722 </td>
</tr>

<tr class=small> <td> B-3 </td>
<td> Allowed caching of vtable contents </td>
<td> call </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990805 </td>
</tr>

<tr class=small> <td> B-4 </td>
<td> Function descriptors in vtable </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990805 </td>
</tr>

<tr class=small> <td> B-5 </td>
<td> Where are vtables emitted? </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> B-6 </td>
<td> Virtual function table layout </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> B-7 </td>
<td> Objects and Vtables in shared memory </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990624 </td>
<td> 990805 </td>
</tr>

<tr class=small> <td> B-8 </td>
<td> dynamic_cast </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990628 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> C </th>
<th colspan=6> Object Construction/Destruction </th>
</tr>

<tr class=small> <td> C-1 </td>
<td> Interaction with .init/.fini </td>
<td> lif ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> C-2 </td>
<td> Order of ctors/dtors w.r.t. link </td>
<td> lif ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-3 </td>
<td> Order of ctors/dtors w.r.t. DSOs </td>
<td> ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-4 </td>
<td> Calling vfuncs in ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-5 </td>
<td> Calling virtual destructors </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-6 </td>
<td> Extra parameters to ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-7 </td>
<td> Passing value parameters by reference </td>
<td> call </td>
<td> closed </td>
<td> All </td>
<td> 990625 </td>
<td> 990805 </td>
</tr>

<tr class=small> <td> C-8 </td>
<td> Returning classes with non-trival copy constructors </td>
<td> call </td>
<td> closed </td>
<td> All </td>
<td> 990625 </td>
<td> 990722 </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> D </th>
<th colspan=6> Exception Handling </th>
</tr>

<tr class=small> <td> D-1 </td>
<td> Language-specific data area format </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-2 </td>
<td> Unwind personality routines </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-3 </td>
<td> Unwind process clarification </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-4 </td>
<td> Unwind routines nested? </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-5 </td>
<td> Interaction with other languages (e.g. Java) </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> D-6 </td>
<td> Allow resumption in other languages? </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> D-7 </td>
<td> Interaction with signals or asynch events </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> D-8 </td>
<td> Interaction with threads packages </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990603 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> E </th>
<th colspan=6> Template Instantiation Model </th>
</tr>

<tr class=small> <td> E-1 </td>
<td> When does instantiation occur? </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> E-2 </td>
<td> Separate compilation model </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> E-3 </td>
<td> Template repository </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> F </th>
<th colspan=6> Name Mangling </th>
</tr>

<tr class=small> <td> F-1 </td>
<td> Mangling convention </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> F-2 </td>
<td> Mangled name size </td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> F-3 </td>
<td> Distinguish template instantiation and specialization
</td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> G </th>
<th colspan=6> Miscellaneous </th>
</tr>

<tr class=small> <td> G-1 </td>
<td> Basic command line options </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> G-2 </td>
<td> Detection of 1-def rule violations </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> G-3 </td>
<td> Inlined routine linkage </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> G-4 </td>
<td> Dynamic init of local static objects and multithreading </td>
<td> call </td>
<td> open </td>
<td> SCO </td>
<td> 990607 </td>
<td> </td>
</tr>

<tr class=small> <td> G-5 </td>
<td> Varargs routine interface </td>
<td> call </td>
<td> open </td>
<td> HU-B </td>
<td> 990810 </td>
<td> </td>
</tr>

<tr class=small> </tr>
<tr class=small> <th> H </th>
<th colspan=6> Runtime Library Interface </th>
</tr>

<tr class=small> <td> H-1 </td>
<td> Runtime library DSO name </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>

<tr class=small> <td> H-2 </td>
<td> Runtime library API </td>
<td> lif </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>


</table>

<p>
<hr>

<p>
<h4> Procedure Notes from 3 June 1999 </h4>

<ul>
<li> Meetings:  10-12 Thursdays at SGI for the near term.
<li> Intel NDA:  Generally unnecessary.  Priti will set up n-way
     for eligible members for cases where needed.  Cary expects RT
     architecture/software conventions document to be released in the
     next month or two, removing most of the issues.
<li> Communication:  Use of reflector encouraged for discussion.
     NDA communication will be handled with password-protected PDF
     once Intel sets up n-way.
<li> Available documents:  Parties with existing, relevant documents
     (includes Sun, HP) will send them to group.
<li> Intellectual property:  Participants don't expect problems with
     release of any of their IP.  Microsoft has extensive patents in
     the area, but they are excessively broad (covering obvious ideas
     and prior art), so expectation is that they are not a problem.
     Nonetheless, we should be aware of them.
</ul>

<p>
<hr>

<p>
Please send corrections to <a href=mailto:dehnert@xxxxxxx>Jim Dehnert</a>.


</BODY>
</HTML>
<HTML>

<HEAD>
<title>C++ ABI Open Issues</title>

<link rel=stylesheet href=small-table.css type="text/css">
<link rel=stylesheet href=code.css type="text/css">

<hr>

<font size=6><i><b>
<p>
C++ ABI Open Issues
</b></i></font>

<font size=-1>
<p>
<i>Revised 10 August 1999</i>

</center>

</HEAD>

<BODY>

<p> <hr> <p>
<h3> Revisions </h3>

<p>
<font color=blue>[990810]</font>
New issue <a href=#G5>G-5</a>.
Additions to <a href=#B6>B-6</a>, <a href=#C2>C-2</a>, <a href=#C3>C-3</a>.

<p>
<font color=blue>[990805]</font>
Closed A-12, A-14, B-3, B-4, B-7, C-7.
Additions to <a href=#A6>A-6</a>, <a href=#A11>A-11</a>,
<a href=#B1>B-1</a>, <a href=#B6>B-6</a>, <a href=#F1>F-1</a>.

<p>
<font color=blue>[990729]</font>
Closed A-7.
Additions to A-11, A-12, C-2.
Summary added for A-12.
New issue A-14.

<p>
<font color=blue>[990727]</font>
Closed B-2, C-8.
Additions to A-9 (closed), C-2.
Summaries added for C-4, C-6, D-1 to D-4.

<p>
<font color=blue>[990720]</font>
Additions to B-2, B-5, C-2, D-1.

<p>
<font color=blue>[990701]</font>
Closed A-3, A-5, A-10, A-13.
Additions to A-6, B-6, B-7, B-8, C-2, C-7.

<p>
<font color=blue>[990625]</font>
Closed A-1, A-2, A-4, A-8, A-9.
Additions to A-3, A-5, A-7, B-4, B-5, B-7, G-3, G-4.
New issues B-6, B-7, B-8, C-7, C-8.

<p>
<font color=blue>[990616]</font>
Added HP summaries.
Added sketchy notes from 990610 discussions (A and B issues).
A-10 was intended by HP as something different than I described,
so it was renamed, and a new issue A-13 opened as an SGI issue.
HP did not submit A-12, so relabeled as Sun's (is that right?).
Added library interface issues, H-1 and H-2.


<p> <hr> <p>
<h3> Definitions </h3>

<p>
The issues below make use of the following definitions:

<dl>

<p>
<dt> <i>empty class</i> </dt>
<dd>
A class with no non-static data members,
no virtual functions, no virtual base classes,
and no non-empty non-virtual base classes.)

<p>
<dt> <i>nearly empty class</i> </dt>
<dd>
A class, the objects of which contain only a Vptr.

<p>
<dt> <i>vague linkage</i> </dt>
<dd>
The treatment of entities --
e.g. inline functions, templates, vtables --
with external linkage that can be
defined in multiple translation units,
while the ODR requires that the program
behave as if there were only a single definition.

</dl>


<p> <hr> <p>
<h3> Issue Status </h3>

In the following sections,
the <b><i>class</i></b> of an issue attempts to classify it on the
basis of what it likely affects.
The identifiers used are:

<table>
<tr> <td> call </td>
<td> Function call interface, i.e. call linkage </td>
</tr>

<tr> <td> data </td>
<td> Data layout </td>
</tr>

<tr> <td> lib </td>
<td> Runtime library support </td>
</tr>

<tr> <td> lif </td>
<td> Library interface, i.e. API </td>
</tr>

<tr> <td> g </td>
<td> Potential gABI impact </td>
</tr>

<tr> <td> ps </td>
<td> Potential psABI impact </td>
</tr>

<tr> <td> source </td>
<td> Source code conventions (i.e. API, not ABI) </td>
</tr>

<tr> <td> tools </td>
<td> May affect how program construction tools interact </td>
</tr>
</table>

<p> <hr> <p>
<h3> Object Layout Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=A1></a> <td> A-1 </td>
<td> Vptr location </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where is the Vptr stored in an object (first or last are the usual answers).
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
First.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=A2></a> <td> A-2 </td>
<td> Virtual base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where are the virtual base subobjects placed in the class layout?
How are data member accesses to them handled?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Virtual base subobjects are normally placed at the end (see issue A-9).
The Vtable will contain an offset to the beginning of the base object
for use by member accesses to them (see issue B-6).
</td> </tr>

</table>

<p>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-3 </td>
<td> Multiple inheritance </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990701 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Define the class layout in the presence of multiple base classes.
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
See the class layout description in closed issue A-9.
Briefly, empty bases will normally go at offset zero,
non-virtual base classes at the beginning,
and virtual base classes at the end.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-4 </td>
<td> Empty base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where are empty base classes allocated?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
At offset zero if possible.  See A-9.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-5 </td>
<td> Empty parameters </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990701 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
When passing a parameter with an empty class type by value,
what is the convention?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Except for cases of non-trivial copy constructors (see C-7),
and parameters in the variable part of varargs lists,
no parameter slot will be allocated to empty parameters.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=A6></a> <td> A-6 </td>
<td> RTTI .o representation </td>
<td> data call ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Define the data structure to be used for RTTI, that is:
<ul>
<li> for user <code>type_info</code> calls;
<li> for dynamic_cast implementation; and
<li> for exception-handling.
</ul>
</td> </tr>

</table>

<p>
<font color=blue>[990701 All]</font>
Daveed will put together a proposal by the 15th (action #13);
the group will discuss it on the 22nd.

<p>
<font color=blue>[990805 All]</font>
Daveed should have his proposal together for discussion.
Michael Lam will look into the Sun dynamic cast algorithm.

<p>
It was noted that appropriate name selection along with the normal
DSO global name resolution should be sufficient to produce a unique
address for each class' RTTI struct,
which address would then be a suitable identifier for comparisons.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-7 </td>
<td> Vptr sharing with primary base class </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990729 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
It is in general possible to share the virtual pointer with a
polymorphic base class (the <i>primary</i> base class).
Which base class do we use for this?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Share with the first non-virtual polymorphic base class,
or if none with the first nearly empty virtual base class.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-8 </td>
<td> (Virtual) base class alignment </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
A (virtual) base class may have a larger alignment constraint than a
derived class.
Do we agree to extend the alignment constraint to the derived class?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
The derived class will have at least the alignment of any base class.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-9 </td>
<td> Sorting fields as allowed by [class.mem]/12 </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The standard constrains ordering of class members in memory only if
they are not separated by an access clause.
Do we use an access clause as an opportunity to fill the gaps left by padding?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
See <a href=cxx-closed.html#A9>closed issue list</a>.
</td> </tr>

</table>

<p>
<font color=blue>[990722 all]</font>
The precise placement of empty bases when they don't fit at offset zero
remained imprecise in the original description.
Accordingly, a precise layout algorithm is described in
a separate writeup of <a href=abi-layout.html>Data Layout</a>.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-10 </td>
<td> Class parameters in registers </td>
<td> call </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990701 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The C ABI specifies that small structs are passed in registers.
Does this apply to small non-POD C++ objects passed by value?
What about the copy constructor and <code>this</code> pointer in that case?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Non-POD C++ objects are passed like C structs,
except for cases with non-trivial copy constructors identified in C-7.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=A11></a> <td> A-11 </td>
<td> Pointers to member functions </td>
<td> data </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
How should pointers to member functions be represented?
</td> </tr>

</table>

<p>
<font color=blue>[990729 All]</font>
Jason described the g++ implementation, which is a three-member struct:
<ol>
<li> The adjustment to <i>this</i>.
<li> The Vtable index plus one of the function, or -1.
     (Zero is a NULL pointer.)
<li> If (2) is an index, the offset from the full object to the member
     function's Vtable.  If -1, a pointer to the function (non-virtual).
</ol>

<p>
A concern about covariant returns was raised.
It was observed that, given our decision to use distinct Vtable entries
for distinct return types, no further concern is required here.
Others will describe their representations.
IBM has an alternative, but it is believed to be patented by Microsoft.

<p>
<font color=blue>[990805 All]</font>
It is agreed that a two-element struct will be used for a pointer to a
member function, with elements as follows:

<dl>
<p>
<dt> <code>ptr</code>:
<dd> For a non-virtual function, this field is a simple function pointer.
     (Under current base IA-64 psABI conventions,
     this is a pointer to a GP/function address pair.)
     For a virtual function,
     it is 1 plus twice the Vtable offset of the function.
     The value zero is a NULL pointer.

<p>
<dt> <code>adj</code>:
<dd> The required adjustment to <i>this</i>.
</dl>

<p>
Although we agreed to close this, SGI suggests a minor modification.
Since the Vtable offset of a virtual function will always be even,
we suggest that it not be doubled before adding 1.
This is because shifts are more restricted on many processors than
other integer ALU operations (shifters are large structures),
so an XOR or NAND will often be cheaper than a right shift.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=A12></a> <td> A-12 </td>
<td> Merging secondary vtables </td>
<td> data </td>
<td> closed </td>
<td> Sun </td>
<td> 990610 </td>
<td> 990805 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Sun merges the secondary Vtables for a class (i.e. those for
non-primary base classes) with the primary Vtable by appending them.
This allows their reference via the primary Vtable entry symbol,
minimizing the number of external symbols required in linking,
in the GOT, etc.
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Concatenate the Vtables associated with a class in the same order
that the corresponding base subobjects are allocated in the object.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-13 </td>
<td> Parameter struct field promotion </td>
<td> call </td>
<td> closed </td>
<td> SGI </td>
<td> 990603 </td>
<td> 990701 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
It is possible to pass small classes either as memory images,
as is specified by the base ABI for C structs,
or as a sequence of parameters, one for each member.
Which should be done, and if the latter,
what are the rules for identifying "small" classes?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
No special treatment will be specified by the ABI.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr class=small> <a name=A14></a> <td> A-14 </td>
<td> Pointers to data members </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990729 </td>
<td> 990805 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
How should pointers to data members be represented?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Represented as one plus the offset from the base address.
</td> </tr>

</table>


<p> <hr> <p>
<h3> Virtual Function Handling Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B1></a> <td> B-1 </td>
<td> Adjustment of "this" pointer (e.g. thunks) </td>
<td> data call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
There are several methods for adjusting the <i>this</i> pointer
for a member function call,
including thunks or offsets located in the vtable.
We need to agree on the mechanism used,
and on the location of offsets, if any are needed.
To maximize performance on IA64,
a slightly unusual approach such as using secondary entry points
to perform the adjustment may actually prove interesting. 
</td> </tr>

</table>

<p>
<font color=blue>[990623 HP -- Christophe]</font>

<p>
<h4>Open Issues Relevant To This Discussion</h4>

<ol>
<p>
<li>
Keeping all of a class in a single load module.
The vtable contains the target address and one copy of the target GP.
This implies that it is not in text, and that it is generated by dld.

<p>
<li>
Detailed layout of the virtual table.

<p>
<li>
How can we share class offsets?

</ol>


<p>
<h4> 1. Scope and "State of the Art"</h4>

<p>
The following proposal applies only to calls to virtual functions  
when a this pointer adjustment is required from a base class to a  
derived class.
Essentially, this means multiple inheritance, and the  
existence of two or more virtual table pointers (vptr)
in the complete object.
The multiple vptrs are required so that the layout  
of all bases is unchanged in the complete object.
There will be one additional vptr for each base class which already
required a vptr,  
but cannot be placed in the whole object so that it shares its vptr  
with the whole object.
Note: when the vptr is shared,
the base class  is said to be the "primary base class",
and there is only one such class.

<p>
For the primary base class, no pointer adjustment is needed.
For all  other bases, a pointer to the whole object is not a pointer
to the base class,
so whenever a pointer to the base class is needed,  
adjustment will occur.

<p>
In particular, when calling a virtual function,
one does not know in advance in which class the function was actually defined.
Depending on the actual class of the object pointed to,
pointer adjustment may be needed or not,
and the pointer adjustment value may vary from class to class.
The existing solution is to have the vtable point not to the function itself,
but to a "thunk" which does pointer adjustment when needed,
and then jumps to the actual function.  
Another possibility is to have an offset in the vtable,
which is used by the called function.
However, more often than not, this implies adding zero.

<p>
Virtual bases make things slightly more complicated.
In that case, the data layout is such that there is only
one instance of the virtual base in the whole object.
Therefore, the offset from a this  
pointer to a same virtual base may change along the inheritance tree.  
This is solved by placing an offset in the virtual table,
which is used to adjust the this pointer to the virtual base.


<p>
<h4> 2. Proposal and Rationale </h4>

<p>
My proposal is to replace thunks with offsets,
with two additional tricks:
<ul>
<li>
Give a virtual function two entry points,
so as to bypass the adjustment when it's known to be zero.
<li>
Moving the adjustment at call-site,
where it can be scheduled more easily,
using a "reasonable" value,
so that the adjustment is bypassed even more often.
</ul>

<p>
The thunks are believed to cost more on IA64 than they would on  
other platforms.
The reason is that they are small islands of code spread throughout the code,
where you cannot guarantee any cache locality.
Since they immediately follow an indirect branch,
chances are we will always encounter both a branch misprediction and a  
I-cache miss in a row.

<p>
On the other hand,
a virtual function call starts by reading the virtual function address.
Reading the offset immediately thereafter should almost never cause a
D-cache miss (cache locality should be good).
More often than not, no adjustment is needed,
or the adjustment will be done at call site correctly.
In the worst case scenario, we perform two adjustments,
one static at call site, and one dynamic in the callee,
but this case should be really infrequent.


<p>
<h4> 3. New Calling Convention </h4>

<p>
The new calling convention requires that the 'this' pointer on entry  
points to the class for which the virtual function is just defined.  
That is, for A::f(),
the pointer is an A* when the main entry of the function is reached.
If the actual pointer is not an A*,
then an adjusting entry point is used,
which immediately precedes the function.

<p>
In the following, we will assume the following examples:
<p>
<code><pre>
    struct A { virtual void f(); };
    struct B { virtual void g(); };
    struct C: A, B { }
    struct D : C { virtual void f(); virtual void g(); }
    struct E: Other, C { virtual void f(); virtual void g(); }
    struct F: D, E { virtual void f(); }

    void call_Cf(C *c) { c->f(); }
    void call_Cg(C *c) { c->g(); }
    void call_Df(D* d) { d->f(); }
    void call_Dg(D* d) { d->g(); }
    void call_Ef(E* e) { e->f(); }
    void call_Eg(E* e) { e->g(); }
    void call_Ff(F *ff) { ff->f(); }
    void call_Fg(F *ff) { ff->g(); }	// Invalid: ambiguous
</pre></code>

<dl>
<p>
<dt> a) Call site:
<dd>
The caller performs adjustment to match the class of the last  
overrider of the given function.

<ul>
<p>
<li> call_Cf will assume that the pointer needs to be cast to an A*,  
since C::f is actually A::f. Since A is the primary base class, no  
adjustment is done at call site.

<p>
<li> call_Cg is similar, but assumes that the actual type is a B*, and  
performs the adjustment, since B is not the primary base class.

<p>
<li> call_Df and call_Dg will assume that the pointer needs to be cast  
to a D*, which is where D::f is defined. No adjustment is performed  
at call site.
</ul>
</dd>


<p>
<dt> b) Callee
<dd>
<ul>
<p>
<li> A::f and B::g are defined in classes where there is a single vptr.  
They don't define a secondary entry point. Because of call-site  
conventions, they expect to always be called with the correct type.

<p>
<li> D::f is defined in a class where there is more than one vptr, so  
it needs a secondary entry point and an entry 'convert_to_D' in the  
vtable. That's because it can be potentially called with either an A*  
or a B*. There are two vtables, one for A in D, one for B in D. The  
D::f entry in A in D points to the non-adjusting entry point, since A  
shares its vptr.

<p>
<li> D::g requires a secondary entry point, that will read the same  
offset 'convert_to_D' from the vtable.

<p>
<li> E also will require a 'convert_to_E' entry in the vtable, but this  
time, the vtable for A in C will have to point to an adjusting entry  
point, since A no longer shares the vptr with E (assuming Other has  
a vptr). This vtable is also the vtable of C in E.
</ul>
</dd>


<p>
<dt> c) Offsets in the vtable
<dd>
Offsets have to be placed in the vtable at a position which does not  
conflict with any offset in the inheritance tree.

<p>
convert_to_D and convert_to_E are likely to be at the same offset in  
the vtable. This is not a problem, even if D and E are used in the  
same class, such as F, because this is the same offset in different  
vtables.

<ul>
<p>
<li> call_Fg is invalid, because it is ambiguous.

<p>
<li> A notation such as ((E*) ff)->g() can be used to disambiguate, but  
in that case, we don't use the same vtable (either the E in F or D  
in F vtable). The E in F vtable uses that offset as 'convert_to_E',  
whereas the D in F vtable uses that offset as 'convert_to_D'.

<p>
<li> Similarly, call_Cf called with an F object will actually be called  
with the E in F or D in F, which disambiguates which C is actually  
used. The actual C* passed will have been adjusted by the caller  
unambiguously, or the call will be invalid.

<p>
<li> For functions overriden in F, an entry 'convert_to_F' is created  
anyway. This entry will not overlap with either convert_to_E or  
convert_to_D.
</ul>

<p>
The fact that an offset is reserved does not mean that it is  
actually used. A vtable need to contain the offset only if it refers  
to a function that will use it. An offset of 0 is not needed, since  
the function pointer will point to the non-adjusting entry point in  
that case.
</dd>

</dl>


<p>
<h4> 4. Cases where adjustment is performed </h4>

<ul>
<p>
<li> For call_Cf: No adjustment is done at call site. No adjustment is  
done at callee site if the dynamic type is C,  or D, or D in F (that  
is, F casted to an E).

<p>
<li> For call_Cg: Adjustment to B* is done at call-site. No further  
adjustment is needed if the dynamic type is C, D, or D in F. On the  
other hand, a second adjustment may happen for an E or E in F,  
because C is not their primary base.
</ul>

<p>
In other words, adjustment is made only when necessary, and at a  
place where it is better scheduled than with thunks. The only bad  
case is double adjustment for call_Cg called with an E*. This case  
can probably be considered rare enough, compared to calls such as  
call_Cg called with a C*, where we now actually do the adjustment at  
the call-site.


<p>
<h4> 5. Comparing the code trails </h4>

<p>
Currently, the sequence for a virtual function call in a shared  
library will look as follows. I'm assuming +DD64, there would be some  
additional addp4 in +DD32. The trail below is the dynamic execution  
sequence. In bold and between #if/#endif, the affected code.

<p>
<code><pre>
        // Compute the address of the vptr in the object,
	// from the this pointer
        // Optional, since vptroffset is often 0.
	// This also adjusts to the class of the final overrider
        addi            Rthis=vptroffset_of_final_overrider,Rthis
        ;;
        // Load the vptr in a register
        ld8             Rvptr=[Rthis]
        ;;
        // Add the offset to get to the function descriptor pointer
	// in the vtable.  Never zero, this instruction is always generated
        addi            Rfndescr=fndescroffset,Rvptr
        ;;
        // (Assuming inlined stub) Load the function address and new GP
        ld8             Rfnaddr=[Rfndescr],8
        ;;
        // Load the new GP
        ld8             GP=[Rfndescr]
        mov             BRn=Rfnaddr
        ;;
        // Perform the actual branch to the target

        // For prediction to occur correctly on McKinley,
        // at least 5 cycles between the mov to BR above and the use
        // of the BR.  Up to 16 bundles...
        // This is very unlikely to be possible in most actual code, so...
        // ... Branch misprediction almost always, followed by
        // ... I-Cache miss almost always if jumping to a thunk
        br.call B0=BRn

#if OLD_ADJUST
thunk_A::f_from_a_B:
        // If the 'adjustment_from_B_to_A is the 'adjustment_to_A' above,
        // then in the new case, the vtable directly points to A::f
        addi            Rthis,adjustment_from_B_to_A

        // In most cases, we can probably generate a PC-relative branch here
        // It is unclear whether we would correctly predict that branch
        // (since it is assumed that we arrive here immediately following
        // a misprediction at call site)
        br              A::f
#endif // OLD_ADJUST

// This occurs less often than OLD_ADJUST
// (it does not happen when call-site adjustment is correct)
#if NEW_ADJUST
adjusting_entry_A::f
        // Can't be executed in less than 3 cycles?
        addi            Rvptr=class_adjustment_offset,Rvptr
        ;;
        // This loads data which is close to the fn descriptor,
        // so it's likely to be in the D-cache
        ld8             Rvptr=[Rvptr]
        ;;
        add             Rthis=Rthis,Rvptr
#endif

A::f:
        alloc   ...
</pre></code>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B2></a> <td> B-2 </td>
<td> Covariant return types </td>
<td> call </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990722 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
There are several methods for adjusting the 'this' pointer of the
returned value for member functions with covariant return types.
We need to decide how this is done.
Return thunks might be especially costly on IA64,
so a solution based on returning multiple pointers may prove more interesting.
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
Provide a separate Vtable entry for each return type.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B3></a> <td> B-3 </td>
<td> Allowed caching of vtable contents </td>
<td> call </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990805 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The contents of the vtable can sometimes be modified,
but the concensus is that it is nonetheless always allowed to "cache" elements,
i.e. to retain them in registers and reuse them,
whenever it is really useful.
However, this may sometimes break "beyond the standard" code,
such as code loading a shared library that replaces a virtual function.
Can we all agree when caching is allowed? 
</td> </tr>
<tr> <td colspan=7>
<b> Resolution </b>:
Caching is allowed within a member function.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B4></a> <td> B-4 </td>
<td> Function descriptors in vtable </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990805 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
For a runtime architecture where the caller is expected to load the GP
of the callee (if it is in, or may be in, a different DSO), e.g. HP/UX,
what should vtable entries contain?
One possibility is to put a function address/GP pair in the vtable.
Another is to include only the address of a thunk which loads the GP
before doing the actual call.
</td> </tr>
<tr> <td colspan=7>
<b> Resolution </b>:
The Vtable will contain a function address/GP pair.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B5></a> <td> B-5 </td>
<td> Where are vtables emitted? </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
In C++, there are various things with external linkage that can be
defined in multiple translation units,
while the ODR requires that the program
behave as if there were only a single definition.
>From the user's standpoint, this applies to inlines and templates.
>From the implementation's perspective,
it also applies to things like vtables and RTTI info.
(We call this <i>vague linkage</i>.)
</td> </tr>

</table>

<p>
<font color=blue>[990624 Cygnus -- Jason]</font>
There are several ways of dealing with vague linkage items:
<ol>
<li> Emit them everywhere and only use one.
<li> Use some heuristic to decide where to emit them.
<li> Use a database to decide where to emit them.
<li> Generate them at link time.
</ol>

<p>
#3 and #4 are feasible for templates,
but I consider them too heavyweight to be used for other things.

<p>
The typical heuristic for #2 is "with the first non-inline,
non-abstract virtual function in the class".
This works pretty well,
but fails for classes that have no such virtual function,
and for non-member inlines.
Worse, the heuristic may produce different results in different
translation units,
as a method could be defined inline after being declared non-inline
in the class body.
So we have to handle multiple copies in some cases anyway.

<p>
The way to handle this in standard ELF is weak symbols.
If all definitions are marked weak,
the linker will choose one
and the others will just sit there taking up space.

<p>
Christophe mentioned the other day that the HP compiler used the
typical heuristic above,
and handled the case of different results by encoding the
key function in the vtable name.
But this seems unnecessary when we can just choose one of multiple defns.

<p>
A better solution than weak symbols alone would be to set things up so
that the linker will discard the extra copies.
Various existing implementations of this are:

<ol>
<p>
<li>
The Microsoft PE/COFF defn includes support for COMDAT sections,
which key off of the first symbol defined.
One copy is chosen, others are discarded.
You can specify conditions to the linker
(must have same contents, must have same size).

<p>
<li>
The IBM XCOFF platform includes a garbage-collecting linker;
sections that are not referenced in a sweep from main are discarded.
In xlC, template instantiations are emitted in separate sections,
with encoded names;
at link time, one copy is renamed to the real mangled name,
and the others are discarded by garbage collection.
</ol>

<p>
The GNU ELF toolchain does a variant of #1 here;
any sections with names beginning with ".gnu.linkonce."
are treated as COMDAT sections.
It seems more sensible to me to key off of the section name
than the first symbol name as in PE.

<p>
The GNU linker recently added support for garbage collection,
and I've been thinking about changing our handling of vague
linkage to make use of it, but haven't.

<p>
I propose that the ia64 base ABI be extended to
provide for either COMDAT sections or garbage collection,
and that we use that support for vague linkage.

<p>
I further propose that we not use heuristics to
cut down the number of copies ahead of time;
they usually work fine, but can cause problems in some situations,
such as when not all of the class's members are in the same symbol space.
Does the ia64 ABI provide for controlling which symbols
are exported from a shared library?

<p>
A side issue: What do we want to do with
dynamically-initialized variables?
The same thing, or use COMMON?
I propose COMMON.

<p>
See also G-3, for vague linkage of inlined routines and their static variables.

<p>
<font color=blue>[990624 SGI summarizing others]</font>
HP uses COMDAT for many cases, keying from the symbol names.
HP also uses some heuristics.
HP observes that IA-64 objects will already be large.
>From the base ABI discussions,
any use of WEAK or COMMON symbols will need to take care not to depend
on vendor-specific treatment.

<p>
Defining a COMDAT mechanism doesn't preclude using heuristics to avoid
some copies up front.
A COMDAT mechanism should also specify how to get rid of associated
sections like debugging info, unless the identical mechanism works.

<p>
<font color=blue>[990629 HP -- Christophe]</font>
First, the "usual" heuristic
(which is usual because it dates back to Cfront)
is to emit vtables in the translation unit that contains  
the definition of the first non inline, non pure virtual function.  
That is, for:
<pre><code>
        struct X {
                void a();
                virtual void f() { return; }
                virtual void g() = 0;
                virtual void h();
                virtual void i();
        };
</code></pre>
the vtable is emitted only in the TU that contains the definition of h().

<p>
This breaks and becomes non-portable if:
<ul>
<li>There is no such thing. In that case,
    you generally emit duplicate versions of vtables
<li>There is a "change of mind",
    such as having the above class followed by:
    <code><p>
    <dd>inline void X::h() { f(); }
    </code>
</ul>

<p>
Now, the COMDAT issue is as follows:
a COMDAT section is, in some cases, slightly more difficult to handle
(at least, that's the impression Jason gave me).
For statics with runtime initialization,  
what you can do is reserve COMMON space ('easier'),
then initialize that space at runtime.
As I said, the problem is if two compilers disagree on whether this
is a runtime or a compile time initialization, such as in :
<pre><code>
	int f() { return 1; }
	int x = f();	// Static (COMDAT) or Dynamic (COMMON) initialization?
</code></pre>

<p>
So I personally recommend that we put everything in COMDAT.

<p>
<font color=blue>[990715 All]</font>
Consensus so far: use a heuristic for vtable and typeinfo emission,
based on the definition of the key function.
(The first virtual function that is not
declared inline in the class definition.)
The vtable must be emitted where the key function is defined,
it may also be emitted in other translation units as well.
If there is no key function then the vtable must be emitted in any
translation unit that refers to the vtable in any way.

<p>
Implication: the linker must be prepared to discard duplicate vtables.
We want to use COMDAT sections for this
(and for other entities with vague linkage.)

<p>
Open issue: the elf format allows only 16 bits for section identifiers,
and typically two of those bits are already taken up for other things.
So we've only got 16k sections available,
which is unacceptable if we're creating lots of small sections.

<p>
Jason - COMDATs disappear into text and data at link time,
so the issue is really only serious if we've got more than 16k vtables
(or template instantiations, etc.)
in a single translation unit.

<p>
Daveed - HP has gotten around this problem by hacking their ELF files
to steal another 8 bits from somewhere else.

<p>
Jack - a new kind of section table could be a viable solution.
However, it would break everything if we did it for ia32.
Is a solution that only works on ia64 acceptable?
Note also that the elf section table has its own string table,
which we wouldn't be able to share with the new kind of section table.
Index and link fields often point into section table,
we would have to figure out how to deal with this.
(Jack is not opposed to the idea of an alternate section table,
he is just pointing out some of the issues we will have to resolve.)



<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B6></a> <td> B-6 </td>
<td> Virtual function table layout </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What is the layout of the Vtable?
</td> </tr>

</table>

<p>
<font color=blue>[990624]</font>
Issue split from A-1.

<p>
<font color=blue>[990630 HP - Christophe]</font>

<p>
Here is a short description of the virtual tables layout. This is
mostly taken out of the existing Taligent runtime.


<p>
<h4>Virtual tables</h4>

<p>
Virtual tables (vtables) are used to dispatch virtual functions, to  
access virtual base class subobjects, and to access information for  
runtime type identification (RTTI). Each class that has virtual
member functions or virtual bases has an associated set of vtables.  
The vtable pointers within all the objects (instances) of a class
point to the same set of vtables.


<p>
<h4>Vtable layout</h4>

<p>
Each vtable consists of the following parts, in the order listed.
All offsets in a vtable are of type ptrdiff_t.

<p>
"Virtual base offsets" are used to access the virtual bases of an
object and to non virtual bases when pointer adjustment is required  
for some overriden virtual function. Each entry is a displacement to  
a virtual base subobject from the location within the object of the  
vtable pointer that addresses this vtable. These entries are only
necessary if the class directly or indirectly inherits from virtual  
base classes, or if it overrides a virtual function defined in a base  
class and if  adjustment from the based to the derived class is
needed. The values can be positive or negative.

<p>
"Offset to top" holds the displacement to the top of the object from  
the location within the object of the vtable pointer that addresses  
this vtable. A negative value indicates the vtable pointer is part of  
an embedded base class subobject; otherwise it is zero. The offset
provides a way to find the top of the object from any base subobject  
with a vtable
pointer. This is necessary for dynamic_cast<void*> in particular.
The virtual pointer points to the "offset to top" field.

<p>
"Typeinfo pointer" points to the typeinfo object used for RTTI. All  
entries in each of the vtables for a given class point to the same
typeinfo object.

<p>
"Duplicate base information pointer" points to a table used to
perform runtime disambiguation of duplicate base classes for dynamic  
casts. The entries in each of the vtables for a given class do not
all point to the same table of duplicate base information.

<p>
Function pointers are used for virtual function dispatch. Each
pointer holds either the address of a virtual function of the class,  
or the address of a secondary entry point that performs certain
adjustments before transferring control to a virtual function. [To be  
discussed] In the case of shared library builds, [Solution 1] a
function pointer entry contains the address of a function descriptor,  
which contains the target GP value and the actual function address
[Solution 2] a function pointer entry contains two words: the value  
of the target GP value and the actual function address [Solution 3] a  
function pointer points to an import table generated by the dynamic  
loader, which will transfer control to the target function.

<p>
The function pointers are grouped so that the entries for all
virtual functions introduced by a base class are kept together, in
declaration order. Function pointers from a derived class immediately  
follow those for the base class. The order of function pointers
therefore depends on the static type of subobject whose vtable
pointer points to that virtual table.

<p>
A vtable pointer in an object addresses the "offset to top" field
of a vtable. This location is known as the address point of the
vtable. Note that the virtual base offsets are at negative
displacements from the address point.

<p>
The typeinfo and duplicate base information are covered in separate  
discussions.



<p>
<h4>Types of vtables</h4>

<p>
The following categories describe the rules for how vtables of a
class are constructed from the vtables of its bases.

<p>
<b>Category 1</b>

<p>
This category is for a class that inherits no base classes. If the
class declares no virtual functions, then it has no vtable, and its  
objects have no vtable pointers.

If the class declares virtual functions, then it has a single vtable  
containing RTTI fields followed by function pointer entries. There  
is one function pointer entry for each virtual function declared in  
the class. The vtable pointer in an object of the class addresses
this vtable.

<p>
<b>Category 2</b>

<p>
This category is for a class that inherits only non-virtual base
classes, and the non- virtual base classes have no base classes, and  
there is no adjustment in any of the overriden virtual functions.

<p>
If none of the base classes have vtables, a vtable is constructed
for the class according to the same rules as in Category 1. Otherwise  
the class has a vtable for each base class that has a vtable. The
class's vtables are constructed from copies of the base class
vtables. The entries are the same, except:
<ul>
<li>The RTTI fields contain information for the class, rather than
for the base class.
<p>
<li>The function pointer entries for virtual functions inherited from  
the base class and
overridden by this class are replaced with the addresses of the
overridden functions
(or the corresponding adjustor secondary entry points),
<p>
<li>At negative offsets, offsets to the base classes are generated if  
used by adjustor secondary entry points.
</ul>

<p>
Informally, each of these vtables has a name in the form
Base-in-Derived vtable, where Base is a base class and Derived is the  
derived class. Each vtable pointer in an object addresses one of
these vtables for the class. The vtable pointer of an A subobject
within a B object would address the A-in-B vtable.

<p>
The vtable copied from the primary base class is also called the
primary vtable; it is addressed by the vtable pointer at the top of  
the object. The other vtables of the class are called secondary
vtables; they are addressed by vtable pointers inside the object.


<p>
Aside from the function pointer entries that correspond to those of  
the primary base class, the primary vtable holds the following
additional entries at its tail:
- Entries for virtual functions introduced by this class
- Entries for overridden virtual functions not already in the
vtable. (These are also called replicated entries because they are
already in the secondary vtables of the class.) [I wonder if this is  
actually needed, this seems to be a consequence of RRBC]

<p>
The primary vtable, therefore, has the base class functions
appearing before the derived
class functions. The primary vtable can be viewed as two vtables
accessed from a shared
vtable pointer.


<p>
Note Another benefit of replicating virtual function entries is
that it reduces the number of this pointer adjustments during virtual  
calls. Without replication, there would be more cases where the this  
pointer would have to be adjusted to access a secondary vtable prior  
to the call. These additional cases would be exactly those where the  
function is overridden in the derived class, implying an additional  
thunk adjustment back to the original pointer. Thus replication saves  
two adjustments for each virtual call to an overridden function
introduced by a non-primary base class.


<p>
<b>Category 3</b>

<p>
This category is for a class that inherits only virtual base
classes, and the virtual base classes have no base classes.

<p>
The class has a vtable for each virtual base class that has a
vtable. These are all secondary vtables and are constructed from
copies of the base class vtables according to the same rules as in
Category 2. The vtable pointers of the virtual base subobjects within  
the object address these vtables.

<p>
The class also has a vtable that is not copied from the virtual base  
class vtables. This vtable is the primary vtable of the class and
addressed by the vtable pointer at the top of the object, which is
not shared. It holds the following function pointer entries:
<ul>
<li>
Entries for virtual functions introduced by this class
<li>
Entries for overridden virtual functions. (These are also called
replicated entries, because they are already in the secondary vtables  
of the class)
</ul>

<p>
The primary vtable also has virtual base offset entries to allow
finding the virtual base subobjects. There is one virtual base
offset entry for each virtual base class. For a class that inherits  
only virtual bases, the entries are in the reverse order in which the  
virtual bases appear in the class declaration, that is, the entry
for the leftmost virtual base is
closest to the address point of the vtable.


<p>
<b>Category 4</b>

<p>
This category is for a class that directly or indirectly inherits
base classes that are either virtual or non-virtual.

<p>
The rules for constructing vtables of the class are a combination of  
the rules from Categories 2 and 3, and for the most part can be
determined inductively. However the rules for placing virtual base
offset entries in the vtables requires elaboration.

<p>
The primary vtable has virtual base offset entries for all virtual
bases directly or indirectly inherited by the class. Each secondary  
vtable has entries only for virtual bases visible to the
corresponding base class. The entries in the primary vtable are
ordered so that entries for virtual bases visible to the primary base  
class appear below entries for virtual bases only visible to this
class.

<p>
For virtual bases only visible to this class, the entries are in the  
reverse order in which the virtual bases are encountered in a
depth-first, left-to-right traversal of the inheritance graph formed  
by the class definitions. Note
that this does not follow the order that virtual bases are placed in  
the object.



<p>
<h4>Vtables for partially constructed objects</h4>

<p>
In some situations, a special vtable, called a construction vtable
is used during the execution of base class constructors and
destructors. These vtables are for specific cases of virtual
inheritance.

<p>
During the construction of a class object, the object assumes the
type of each of its base classes, as each base class subobject is
constructed. RTTI queries in the base class constructor will return  
the type of the base class, and virtual calls will resolve to member  
functions of the base class rather than the complete class. Normally,  
this behavior is accomplished by setting, in the base class
constructor, the object's vtable pointers to the addresses of the
vtables for the base class.

<p>
However, if the base class has direct or indirect virtual bases, the  
vtable pointers have to be set to the addresses of construction
vtables. This is because the normal base class vtables may not hold  
the correct virtual base index values to access the virtual bases of  
the object under construction, and adjustment addressed by these
vtables may hold
the wrong this parameter adjustment if the adjustment is to cast
from a virtual base to another part of the object. The problem is
that a complete object of a base class and a complete object of a
derived class do not have virtual bases at the same offsets.

<p>
A construction vtable holds the virtual function addresses and the
RTTI information associated with the base class and the virtual base  
indexes and the addresses of adjustor entry points with this
parameter adjustments associated with objects of the complete class.

<p>
To ensure that the vtable pointers are set to the appropriate
vtables during base class construction, a table of vtable pointers,  
called the VTT, which holds the addresses of construction and
non-construction vtables is generated for the complete class. The
constructor for the complete class passes to each base class
constructor a pointer to the appropriate place in the VTT where the  
base class constructor can find its set of vtables. Construction
vtables are used in a similar way during the execution of base class  
destructors.


<p>
<font color=blue>[990701 All]</font>
The above arrived to late for everyone to read it carefully.
It was agreed that we would consider it outside the meetings,
discuss any issues noted by email,
and attempt to close on 22 July.
(Christophe is on vacation until that week,
and Daveed leaves on vacation the next week.)


<p>
<font color=blue>[990805 All]</font>
We need a specific proposed representation for COMDAT.
IBM's version is restricted to one symbol per section.
Jim will look for Microsoft's PECOFF definition.
Anyone else with a usable definition should send it.

<p>
<font color=blue>[990811 SGI -- Jim]</font>
I've put a reworked version of Christophe's writeup in the
<a href=abi-layout.html#vtable>data layout document</a>,
along with a number of questions it raises.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B7></a> <td> B-7 </td>
<td> Objects and Vtables in shared memory </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990624 </td>
<td> 990805 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Is it possible to allocate objects in shared memory?
For polymorphic objects, this implies that the Vtable must also be
in shared memory.
</td> </tr>
<tr> <td colspan=7>
<b> Resolution </b>:
No special representation is useful in support of shared memory.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=B8></a> <td> B-8 </td>
<td> dynamic_cast </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990628 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What information to we put in the vtable to enable (a) dynamic_cast
from pointer-to-base to pointer-to-derived (including detection of
ambiguous base classes) and (b) dynamic_cast to void*?
</td> </tr>

</table>

<p>
<font color=blue>[990701 All]</font>
This should be part of the proposal Daveed will put together
by the 15th (action #13); the group will discuss it on the 22nd.


<p> <hr> <p>
<h3> Object Construction/Destruction Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C1></a> <td> C-1 </td>
<td> Interaction with .init/.fini </td>
<td> lif ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Static objects with dynamic constructors must be constructed at
intialization time.
This is done via the executable object initialization functions that
are identified (in ELF) by the DT_INIT and DT_INITARRAY dynamic tags.
How should the compiler identify the constructors to be called in this way?
One traditional mechanism is to put calls in a .init section.
Another, used by HP, is to put function addresses in a .initarray section.
<p>
The dual question arises for static object destructors.
Again, the extant mechanisms include putting calls in a .fini section,
or putting function addresses in a .finiarray section.
<p>
Finally, which mechanism (DT_INIT or DT_INITARRAY, or the FINI versions)
should be used in linked objects?
The gABI, and the IA-64 psABI, will support both,
with DT_INIT being executed before the DT_INITARRAY elements.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C2></a> <td> C-2 </td>
<td> Order of ctors/dtors w.r.t. link </td>
<td> lif ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Given that the compiler has identified constructor/destructor calls for
static objects in each relocatable object, in what order should the
static linker combine them in the linked executable object?
(The initialization order determines the finalization order,
as its opposite.)
</td> </tr>

</table>

<p>
<font color=blue>[990610 All]</font>
Meeting concensus is that the desirable order is right to left on the
link command line, i.e. last listed relocatable object is initialized
first.

<p>
<font color=blue>[990701 SGI]</font>
We propose that global constructors be handled as follows:
<ul>
<p>
<li>
The compiler shall emit global constructor calls as one or more entries
in an SHF_INIT_ARRAY section.
<p>
<li>
The linker shall combine them according to the rules of the base gABI,
namely as a concatenated array of entries, in link argument order,
pointed to by a DT_INIT_ARRAY tag.
(The linker may intersperse entries from command line flags or modules
from other languages, but that is beyond the C++ ABI scope.)
</ul>

<p>
This does not address the global destructor problem.
That solution needs to deal not only with the global objects seen by
the compiler, but also interspersed local static objects.
This treatment seems to be tied up in the question of how early
unloading of DSOs is handled, and the data structure used for that
purpose (issue C-3).

<p>
<font color=blue>[990715 All]</font>
Cygnus scheme:
priorities are 16-bit unsigned integers, lower numbers are higher priority.
In each translation unit,
there's a single initialization function for each priority.
Anything that's prioritized has a higher priority than anything that
isn't explicitly assigned a priority.

<p>
IBM scheme:
priorities are 32-bit signed integers, higher numbers are higher priority.
Something that isn't explicitly assigned a priority effectively
gets a priority of 0.

<p>
Consensus:
nobody is sure that negative priorities are very important,
but also nobody can think of a reason not to allow them.
We accept the idea that priorities are 32-bit signed integers.
On a source level Cygnus will keep lower numbers as higher priority,
but that's a source issue, not an ABI issue.

<p>
Status: No real technical issues,
we have consensus on everything that matters.
We need to write up the finicky details.

<p>
<font color=blue>[990722 all]</font>
It was decided to follow the IBM approach, including:
<ul>
<li> The source pragma will use a 32-bit signed priority.
	The default will map to 0,
	and larger numbers are lower priority.

<li> Priorities MIN_INT .. MIN_INT+1000 are reserved to the implementation.

<li> The object representation will use a 32-bit unsigned priority,
	obtained from the source priority by subtracting INT_MIN.

<li> Initialization priorities are only relevant within a DSO.
	Between DSOs, the normal ELF ordering based on object order applies.

</ul>

<p>
To be resolved are the precise source pragma definition (possibly IBM's),
and the ELF file representation.

<p>
<font color=blue>[990729 all]</font>
SGI suggested an object representation involving (in relocatables)
a new section type, containing pairs &lt;priority, entry address>.
The linker would merge all such sections,
include any initialization entries specified by other means,
and leave one or more DT_INITARRAY entries for normal runtime
initialization, either building a routine to call the entries,
or referencing a standard runtime routine.

<p>
IBM noted that they combine their equivalent data structures in the
linker, but don't sort them, leaving that to a runtime routine.
This can be done without explicit linker support,
but involves runtime overhead.

<p>
Cygnus suggested that if we are going to require linker sorting,
we should make the facility more general.

<p>
Jim will write up a more precise proposal.

<p>
<font color=blue>[990804 SGI -- Jim]</font>
<h4> Proposal </h4>

<p>
My objectives are:
<ul>
<li> Simple representation in relocatable objects.
<li> No new representation in executable objects.
<li> Simple static linker processing (general if possible).
<li> Minimal unnecessary runtime cost.
<li> Minimal library interface.
<li> Integration with other initialization (at source priority zero).
</ul>

<p>
<h5> Object File Representation </h5>

<p>
Define a new section type, e.g. <code><b>SHT_CXX_PRIORITY_INIT</b></code>.
Its elements are structs:
<code><pre>
	typedef struct {
	  ElfXX_Word	pi_pri;
	  ElfXX_Addr	pi_addr;
	} ElfXX_Cxx_Priority_Init;
</pre></code>
The semantics are that <code>pi_addr</code> is a function pointer,
with an <code>unsigned int</code> priority parameter,
which performs some initialization at priority <code>pi_pri</code>.
Each of these functions will be called with the GP of the
executable object containing the table.
The section header field <code>sh_entsize</code> is 8 for ELF-32,
or 16 for ELF-64.

<p>
<h5> Runtime Library Support </h5>

<p>
Each implementation shall provide a runtime library function with
prototype:
<code><center>
void __cxx_priority_init ( ElfXX_Cxx_Priority_Init *pi, int cnt );
</center></code>
It will be called with the address of a <code>cnt</code>-element
(sub-)vector of the priority initialization entries,
and will call each of them in order.
It will be called with the GP of the initialization entries.

<p>
<h5> Linker Processing </h5>

<p>
The linker must take the collection of SHT_CXX_PRIORITY_INIT section
entries from the relocatable object files being linked,
and other initialization tasks specified in other ways
(and treated as source priority 0 or object priority -MIN_INT),
and produce an executable object file which executes the initialization
tasks in priority order using only <code>DT_INIT</code>,
<code>DT_INIT_ARRAY</code>, and <code>__cxx_priority_init</code>.
Priority order is first according to the priority of the task,
and then according to the order of relocatable objects and options
in the link command.
The order of tasks specified by other methods,
relative to SHT_CXX_PRIORITY_INIT tasks of priority zero,
is implementation defined.
There are several possible implementations.  Two extremes are:

<ul>
<p>
<li>
The linker sorts the SHT_CXX_PRIORITY_INIT sections together.
If it inserts entries for initialization tasks specified in other ways,
it may make a single DT_INIT_ARRAY entry pointing to __cxx_priority_init.
If not, it must break it into subranges,
interspersing DT_INIT_ARRAY entries for the other tasks with entries
for the SHT_CXX_PRIORITY_INIT entries.
(This implementation will minimize runtime overhead.)

<p>
<li>
The linker simply appends the SHT_CXX_PRIORITY_INIT sections.
It inserts DT_INIT_ARRAY entries before and after the entries for other
initialization tasks which sort this vector and then execute the
negative-priority calls on the first call,
and the positive-priority ones on the second call.
(I believe this is much like today's IBM implementation.)
However, to be conforming, the routine which performs these tasks
must be linked with the resulting executable object,
or shippable with it as an associated DSO.

</ul>

<p>
Note that if one is linking ELF-32 objects into a 64-bit program,
the entries must be expanded as part of this process.

<p>
<h5> Sorting Sections </h5>

<p>
Jason suggested that if we base this feature on sorting sections,
we should provide a general mechanism.
Following is a proposal for that purpose.

<p>
Define a new section header flag, <code>SHF_SORT</code>.
If present, the linker is required to sort the elements of the
concatenated sections of the same type,
where the elements are determined by <code>sh_entsize</code>.
The sort is controlled by fields in <code>sh_info</code>:

<dl>
<p>
<dt> <code>#define SH_INFO_KEYSIZE(info) (info & 0xff)</code>
<br><dd>	The size of the sort key (bytes).
<p>
<dt> <code>#define SH_INFO_KEYSTART(info) ((info>>8) & 0xff)</code>
<br><dd>	The start byte of the sort key within element, from 0.
<p>
<dt> <code>#define SH_INFO_SORTKIND(info) ((info>>16) & 0xf)</code>
<br><dd>	The kind of sort data:
		0 for unsigned integer, 1 for signed integer.

</dl>

<p>
The sort must be stable.
The sort key must be naturally aligned.

<p>
Other conceivable options would be to allow sorting strings
(like SHF_MERGE, this would be indicated by setting SHF_STRING
and putting the character size in <code>sh_entsize</code>),
or floating point data.
Also, note that if we don't anticipate using such a general mechanism,
it becomes possible to avoid padding words in the ELF-64 format by
separating the priority and address vectors.

<p>
<font color=blue>[990810 HU-B -- Martin]</font>
Global destructor ordering must not only interleave with static locals,
but also with atexit.
This gives two problems:
atexit is only guaranteed to support 32 functions;
and dynamic unloading of DSOs break when functions are atexit registered.

<p>
<font color=blue>[990810 SGI -- Matt]</font>
Yes, the interleaving is required by the C++ standard.
It's a nuisance, and I don't think there's any good reason for it,
but the requirement is quite explicit.

<p>
The relevant part of the C++ standard is section 3.6.3, paragraph 3:

<p>
<dl><dd>
<cite>
"If a function is registered with atexit (see <cstdlib>, 18.3) then
following the call to exit, any objects with static storage duration
initialized prior to the registration of that function shall not be
destroyed until the registered function is called from the termination
process and has completed. For an object with static storage duration
constructed after a function is registered with atexit, then following
the call to exit, the registered function is not called until the
execution of the object's destructor has completed. If atexit is called
during the construction of an object, the complete object to which it
belongs shall be destroyed before the registered function is called."
</cite>
</dd></dl>

<p>
What this implies to me is that atexit, and the part of the runtime
library that handles destructors for static objects, must know about
each other.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C3></a> <td> C-3 </td>
<td> Order of ctors/dtors w.r.t. DSOs </td>
<td> ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Given the constructor/destructor calls for each executable object
comprising a program, what is the order of execution between objects?
For constructors, there is not much question:
unless we choose some explicit means of control,
file-scope objects will be initialized by the DT_INIT/DT_INITARRAY
functions in the order determined by the base ABI order rules,
and local objects will be initialized in the order their containing
scopes are entered.
<p>
For destructors, the Standard requires opposite-order destruction,
which implies a runtime structure to keep track of the order.
Furthermore, the potential for dynamic unloading of a DSO
(e.g. by dlclose)
requires a mechanism for early destruction of a subset.
</td> </tr>

</table>

<p>
<font color=blue>[990804 SGI -- Jim]</font>
<h4> Proposal </h4>

<p>
My objectives are:
<ul>
<li> Simple library interface.
<li> Efficient handling during construction.
<li> Standard-conforming treatment during normal program exit.
<li> Reasonable treatment during early DSO unload (e.g. dlclose).
<li> Minimal dynamic and static linker impact.
</ul>

<p>
<h5> Runtime Data Structure </h5>

<p>
The runtime library shall maintain a list of termination functions
with the following information about each:

<ul>
<li> A function pointer (a pointer to a function descriptor on IA-64).
<li> A void* operand to be passed to the function.
<li> A void* handle for the <i>home DSO</i> of the entry (below).
</ul>

<p>
The representation of this structure is implementation defined.
All references are via the API described below.

<p>
<h5> Runtime API </h5>

<ol type=A>
<p>
<li> Object construction:
<p>
When a global or local static object is constructed,
which will require destruction on exit,
a termination function is <i>registered</i> as follows:
<center><code>
int __cxx_atexit ( void (*f)(void *), void *p, dso_handle d );
</code></center>
This registration, e.g. <code>__cxx_atexit(f,p,d)</code>,
is intended to cause the call <code>f(p)</code> when DSO d is unloaded,
before all such termination calls registered before this one.
It returns zero if registration is successful, nonzero on failure.
<font color=red>Should we use exceptions instead?</font>

<p>
The registration function is called separate from the constructor.

<p>
<li> User atexit calls:
<p>
When the user registers exit functions with <code>atexit</code>,
they should be registered with NULL parameter and DSO handle, i.e.
<center><code>
__cxx_atexit ( f, NULL, NULL );
</code></center>
<font color=red>
Should we also allow user registration with a parameter?
With a home DSO?
</font>

<p>
<li> Termination:
<p>
When linking any DSO containing a call to <code>__cxx_atexit</code>,
the linker should define a hidden symbol <code>__dso_handle</code>,
with a value which is an address in one of the object's segments.
(It doesn't matter what address,
as long as they are different in different DSOs.)
It should also include a call to the following function in the FINI
list (to be executed first):
<center><code>
void __cxx_finalize ( dso_handle d );
</code></center>
The parameter passed should be <code>__dso_handle</code>.

<p>
Note that the above can be accomplished either by explicitly providing
the symbol and call in the linker, or by implicitly including a
relocatable object in the link with the necessary definitions,
using a .fini_array section for the FINI call.
Also, note that these can be omitted for an object with no calls to
<code>__cxx_atexit</code>, but they can be safely included in all objects.

<p>
Finally, a main program should be linked with a FINI call to
<code>__cxx_finalize</code> with NULL parameter.

<p>
When <code>__cxx_finalize(d)</code> is called,
it should walk the termination function list,
calling each in turn if <code>d</code> matches
<code>__dso_handle</code> for the termination function entry.
If <code>d == NULL</code>, it should call all of them.
Multiple calls to <code>__cxx_finalize</code> should not result in
calling termination function entries multiple times;
the implementation may either remove entries or mark them finished.

<p>
<font color=red>
Issue: By passing a NULL-terminated vector of DSO handles to
<code>__cxx_finalize</code> instead of one,
we could deal with unloading multiple DSOs at once.
However, <code>dlclose</code> closes one at a time,
so I'm not sure the extra complexity is worthwhile.
</font>

</ol>

<p>
Since <code>__cxx_atexit</code> and <code>__cxx_finalize</code>
must both manipulate the same termination function list,
they must be defined in the implementation's C++ runtime library,
rather than in the individual linked objects.




<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C4></a> <td> C-4 </td>
<td> Calling vfuncs in ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
When calling a virtual function from the constructor/destructor of a
base subobject,
the version specific to the base type is required,
unlike the typical case when calling such a vfunc for the full object
from some other context.
Since the pointer for that vfunc in the full object's vtable
(or even the subobject's sub-vtable) is the full object version,
some other means is required for accessing the correct vfunc.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C5></a> <td> C-5 </td>
<td> Calling destructors </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What is the calling convention for destructors?
Do virtual destructors require special treatment?
Is delete() integrated with the destructor call or separate?
How is delete() handled when invoked on a base subobject?
</td> </tr>

</table>

<p>
<font color=blue>[990729 all]</font>
Some implementations combine destructors with deletion,
checking a flag in the destructor to determine whether to delete.
This produces somewhat less code,
especially if there are many delete() calls.
However, it adds overhead to any destructor which does not require
deletion, e.g. base and member objects, automatic objects.
There is some concern that a runtime test is sometimes required,
but noone has yet identified why.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C6></a> <td> C-6 </td>
<td> Extra parameters to ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
When calling constructors and destructors for classes with virtual bases,
information about the virtual base subobjects in the full class
must be transmitted somehow to the ctor/dtor.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C7></a> <td> C-7 </td>
<td> Passing value parameters by reference </td>
<td> call </td>
<td> closed </td>
<td> All </td>
<td> 990624 </td>
<td> 990805 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
It may be desirable in some cases where a type has a non-trivial
copy constructor to pass value parameters of that type by performing
the copy at the call site and passing a reference.
</td> </tr>
<tr> <td colspan=7>
<b> Resolution </b>:
Whenever a class type has a non-trivial copy constructor,
pass value parameters of that type by performing
the copy at the call site and passing a reference.
</td> </tr>

</table>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=C8></a> <td> C-8 </td>
<td> Returning classes with non-trival copy constructors </td>
<td> call </td>
<td> closed </td>
<td> All </td>
<td> 990625 </td>
<td> 990722 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
How do we return classes with non-trivial copy constructors?
</td> </tr>
<tr> <td colspan=7>
<b>Resolution</b>:
The caller allocates space,
and passes a pointer as an implicit first parameter
(prior to the implicit <i>this</i> parameter).
</td> </tr>

</table>

<p> <hr> <p>
<h3> Exception Handling Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D1></a> <td> D-1 </td>
<td> Language-specific data area format </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The IA-64 runtime conventions describe language-independent descriptors
for restoring registers when unwinding the stack.
The do not specify how C++ performs language-specific unwinding for
exception handling, i.e. locating a handler and destroying automatic
objects.
Note that this can be handled by agreeing on common descriptors,
or by agreeing on per-frame personality routines with common APIs.
</td> </tr>

</table>

<p>
<font color=blue>[990715 Cygnus -- Jason]</font>
The languge-specific part of the EH stack in g++ contains these
elements:

<p>
<code><pre>
void *value; // pointer to the thrown object, or the thrown value
             // itself if a pointer
void *type;  // pointer to the type_info node for the thrown object
void (*cleanup)(void *, int) // pointer to the dtor for the object
bool caught; // has this exception been caught since its last throw?
long handlers; // how many catch handlers are active for this exception
</code></pre>

<p>
Both 'caught' and 'handlers' are needed to handle rethrowing and
catching within a catch block.

<p>
Language interaction is handled by recording the language of both the
exception region and the thrown exception.  Each thrown exception also
includes a pointer to a language-specific matching function which is
called to compare the types of the exception and handler.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D2></a> <td> D-2 </td>
<td> Unwind personality routines </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The IA-64 runtime conventions provide for a personality routine
pointer for language-specific actions when unwinding the stack.
They do not specify its interface.
There are typically two required actions for C++:
locating a handler (non-destructively)
and destroying automatic objects while unwinding.
This issue involves specification of the API (see also D-3).
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D3></a> <td> D-3 </td>
<td> Unwind process clarification </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The IA-64 runtime conventions provide for a personality routine
pointer for language-specific actions when unwinding the stack.
However, they are quite muddy about the precise sequence of calls.
This issue involves specification of unwind process (see also D-2).
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D4></a> <td> D-4 </td>
<td> Unwind routines nested? </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The IA-64 runtime conventions call for the unwind personality routine
to behave like a routine nested in the routine raising an exception.
Is that the preferred definition?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D5></a> <td> D-5 </td>
<td> Interaction with other languages (e.g. Java) </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The IA64 exceptions handling framework is largely language independent.
What is the behaviour of a C++ runtime receiving, for instance,
an exception thrown from Java?
Does it call terminate()?
Does it allow the exception to pass through C++ code with destructors
if there is no catch clause?
Does it allow the exception to be caught in a catch(...) provided this
catch(...) ends with a rethrow?
Does it allow even more?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D6></a> <td> D-6 </td>
<td> Allow resumption in other languages? </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The exception handling framework requires the interaction of the
runtime of all the languages "on the stack" during exception processing.
Some of these languages may have very different exception handling semantics.
What are the constraints we impose on the C++ exception handling runtime
to preserve the relative language neutrality of the EH framework?
Example: do we allow a handler to cleanup and resume at the point
where the exception was thrown?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D7></a> <td> D-7 </td>
<td> Interaction with signals or asynch events </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The Standard says that the behavior of anything other than
"pure C code" (POF) is implementation defined,
and warns (in a note) against using EH in a signal handler.
We should define what is supported,
possibly explicitly stating that signal handler code must be a POF.
We could allow any feature but exception handling to be used.
We could allow some EH routines to be called
(for instance, <code>uncaught_exception()</code>).
Or we could allow even an exception to be thrown,
if it does not exit the handler.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=D8></a> <td> D-8 </td>
<td> Interaction with threads packages </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What happens when an exception is not caught in the thread where raised?
What does uncaught_exception() return if another thread is currently
processing an exception?
</td> </tr>

</table>

<p> <hr> <p>
<h3> Template Instantiation Model Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>


<tr> </tr>
<tr> <th> E </th>
<th colspan=6> Template Instantiation Model </th>
</tr>

<tr> <a name=E1></a> <td> E-1 </td>
<td> When does instantiation occur? </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
There are two principal models for instantiation.
The <i>early instantiation</i> (or Borland) model performs all
instantiation at compile time,
potentially resulting in extra copies which are removed at link time.
The <i>pre-link instantiation</i> model identifies the required
instantiations prior to linking and instantiates them via a special
compile step.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=E2></a> <td> E-2 </td>
<td> Separate compilation model </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[SGI]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=E3></a> <td> E-3 </td>
<td> Template repository </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Independent of the template instantiation model,
we need to make sure that whatever template persistent storage is used
by one vendor does not interact negatively with other vendors' mechanisms.
Issues:
  (1) Avoiding conflict on the name of any repository.
  (2) If .o files are used,
	describe how this information is to be preserved, ignored, etc.
  (3) Evaluate if tools such as make, ld, ar, or others, can
	break because .o files get written at unexpected times.
</td> </tr>

</table>

<p> <hr> <p>
<h3> Name Mangling Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=F1></a> <td> F-1 </td>
<td> Mangling convention </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What rules shall be used for mangling names,
i.e. for encoding the information other than the source-level object
name necessary to resolve overloading?
</td> </tr>

</table>

<p>
<font color=blue>[990806 SGI -- Jim]</font>
Naming to be resolved under this issue includes:
<ul>
<li> Global and member operator names
<li> Global and member function names
<li> Vtable names (primary and initialization)
<li> RTTI struct names
<li> Template instance names
<li> Namespace effects
</ul>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=F2></a> <td> F-2 </td>
<td> Mangled name size </td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Typical name mangling schemes to date typically begin to produce very
long names.  SGI routinely encounters multi-kilobyte names,
and increasing usage of namespaces and templates will make them worse.
This has a negative impact on object file size, and on linker speed.
<p>
SGI has considered solutions to this problem including modified string
tables and/or symbol tables to eliminate redundancy.
Cygnus, HP, and Sun have also considered or implemented approaches
which at least mitigate it.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=F3></a> <td> F-3 </td>
<td> Distinguish template instantiation and specialization
</td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
In order to allow detection of conflicting template instantiation
and specialization (in different translation units),
should we name them differently?
If we do so in an easily recognizable way,
the linker could check for conflicts and report the ODR violation.
</td> </tr>

</table>

<p> <hr> <p>
<h3> Miscellaneous Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=G1></a> <td> G-1 </td>
<td> Basic command line options </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Can we agree on basic command line options (compiler and linker)
for fundamental functionality,
possibly allowing portable makefiles?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=G2></a> <td> G-2 </td>
<td> Detection of ODR violations </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Sun]
(See also F-3.)
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=G3></a> <td> G-3 </td>
<td> Inlined routine linkage </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Inline routines with external linkage require a method of handling
vague linkage (see B-5 for definition) for the out-of-line instance,
as well as for any static data they contain.
The latter includes string constants per [7.1.2]/4.
</td> </tr>

</table>

<p>
<font color=blue>[990624 Cygnus -- Jason]</font>
How should we handle local static variables in inlines?
G++ currently avoids this issue by suppressing
inlining of functions with local statics.
If we don't want to do that,
we'll need to specify a mangling for the statics,
and handle multiple copies like we do above.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=G4></a> <td> G-4 </td>
<td> Dynamic init of local static objects and multithreading </td>
<td> call </td>
<td> open </td>
<td> SCO </td>
<td> 990607 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The Standard requires that local static objects with dynamic
constructors be initialized exactly once, the first time the containing
scope is entered.
Multi-threading renders the simple check of a flag before
initialization inadequate to prevent multiple initialization.
Should the ABI require locking for this purpose,
and if so, what are the necessary interfaces?
In addition to the locking of the initialization,
special exception handling treatment is required to deal with an
exception during construction.
</td> </tr>

</table>

<p>
<font color=blue>[990607 SCO -- Jonathan]</font>
The standard is mute on multiple threads of control in general, so 
there is no requirement in the language to support what I'm talking
about. But as a practical matter compilers have to do it (Watcom gave
a paper on their approach during the standardization process, if I
remember).  This example using UI/SVR4 threads will usually show
whether a compiler does it or not: 

<pre><code>
thr5.C:
// static local initialization and threads

#include <stdlib.h>
#define EXIT(a) exit(a)
#define THR_EXIT() thr_exit(0)

#include <thread.h>

int init_count = 0;
int start_count = 0;

int init()
{
  
        ::thr_yield();
        return ++init_count;
}

void* start(void* s)
{
  
        start_count++;
        static int i = init();
        if (i != 1) EXIT(5);
        THR_EXIT();
        return 0;
}
                
int main()
{
  
        thread_t t1, t2;
        if (::thr_create(0, 0, start, 0, 0L, &t1) != 0) EXIT(1);
        if (::thr_create(0, 0, start, 0, 0L, &t2) != 0) EXIT(2);
        if (::thr_join(t1, 0, 0) != 0) EXIT(3);
        if (::thr_join(t2, 0, 0) != 0) EXIT(4);
        if (start_count != 2)
                EXIT(6);
        if (init_count != 1)
                EXIT(7);
        THR_EXIT();
}
</code></pre>

<p>
When compiled with CC -Kthread thr5.C on UnixWare 7, for instance,
it passes by returning 0.  When compiled with CC -mt thr5.C on
Solaris/x86 C++ 4.2 (sorry don't have the latest version!), it
fails by returning 5.


<p>
<font color=blue>[990607 Sun -- Mike Ball]</font>
As far as I can tell, the language says that the automatic blocking 
issue isn't a valid approach.  It says what has to happen, and
it isn't that.

<p>
If you look at the entire statement you find that it reads:
<quote>
"Otherwise such an object is initialized the first time control passes
through its declaration; such an object is considered initialized upon
the completion of its initialization.
If the initialization exits by throwing an exception,
the initialization is not complete,
so it will be tried again the next time control enters the declaration.
If control re-enters the declaration (recursively)
while the object is being initialized,
the behavior is undefined."
</quote>

<p>
The word "recursively" is normative,
so eliminates that sentence from consideration.

<p>
One can, of course, make any extension to the language,
but in this case I think the extension invalidates some otherwise valid code.

<p>
The sentence I'm referring to is that the object is considered
initialized upon the completion of its initialization.
This is explicit, and the reason for it is covered in the following sentence,
which discusses an initialization that terminates with an exception.
A person catching such an exception has the right to try again
without danger that the static variable will be initialized in the meantime.

<p>
I don't see anything at all to justify semantics that say,
"after initialization is started, Any other threads of control are
blocked until that thread completes the initialization,
unless, of course, it executes by an exception,
in which case the other thread can do the initialization before the
exception handler gets a chance to try again, except...."
 Take an attempt to define the semantics as far as you like.

<p>
The problem is that there is no way for the compiler writer to know
what the programmer really wanted to do.
I can (and will at some other date, if necessary)
come up with scenarios justifying a variety of mutual exclusion policies,
including none.

<p>
The solution is to let the programmer write the mutual exclusion, the
same as we do for every other potential race condition.
It's a real mess, and, I claim, an unwise one to put in as an extension.

<p>
<font color=blue>[990608 HP -- Christophe]</font>
The semantics currently implemented in the HP aC++ compiler is as follows:
<ul>
<li> No two thread can enter a static initialization at the same time
<li> Threads are blocked until immediately after the static  
    initialization either succeeds or fails with an exception.
</ul>

<p>
There are details of our implementation that I disagree with, but in  
general, the semantics seem clear and sane, not as convoluted as you  
seemed to imply. In particular, it correctly covers the case where  
the static initialization fails with an exception. Any thread at that  
point can attempt the initialization.

<p>
<font color=blue>[990608 SCO -- Jonathan]</font>
Here's what the SCO UnixWare 7 C++ compiler does for IA-32,
from a (slightly sanitized) design document.
 It meets Jim's goal of having no overhead for non-threaded programs
and minimal overhead for threaded programs unless
actual contention occurs (infrequent),
and meets Mike's goal of handling exceptions in the initialization correctly
(although it doesn't guarantee that the thread getting the exception is
the one that gets next crack at initializing the static).
 It's also worth noting that dynamic initialization of local variables
(static or otherwise) is very common in C++,
since that's what most object constructions involve,
so I don't think this case is as rare as Jim does.


<p>
[...] This is in local static variables with dynamic initialization,
where the compiler generates out a static one-time flag to guard the
initialization.
Two threads could read the flag as zero before either of them set it,
resulting in multiple initializations.

<p>
[...] Accordingly, when compilation is done with -Kthread on,
a code sequence will be generated to lock this initialization.  
[...] the basic idea is to have one guard saying whether the
initialization is done (so that multiple initializations do not occur)
and have another guard saying whether initialization is in progress
(so that a second thread doesn't access what it thinks is
an initialized value before the first thread has finished the
initialization).  [...]

<p>
When compiled with -Kthread, the generated code for a dynamic
initialization of a local static variable will look like the
following. guard is a local static boolean, initialized to zero,
generated by the [middle pass of the compiler]. 
Two bits of it are used: the low-order 'done bit'
and the next-low-order 'busy bit'.

<pre><code>
.again:
        movl    $guard,%eax
        testl   $1,(%eax)       // test the done bit
        jnz     .done           // if set, variable is initialized,
done
        lock; btsl  $1,(%eax)   // test and set the busy bit
        jc      .busy
        < init code >           // not busy, do the initialization
        movl    $guard,%eax
        movl    $3,(%eax)       // set the done bit
        jmp     .done
.busy:
        pushl   %eax            // call RTS routine to wait, passing address
        call1   __static_init_wait      // of guard to monitor
        testl   %eax,%eax       // 1 means exception occurred in init code,
        popl    %ecx
        jnz     .again                  // start the whole thing over
.done                                   // 0 means wait finished
</code></pre>

<p>
The above code will work for position-independent code as well.

The complication due to exceptions is:
what happens if the initialization code throws an exception?
The [compiler] EH tables will have set up a special region and flag in
their region table to detect this situation,
along with a pointer to the guard variable.
Because the initialization never completed,
when the RTS sees that it is cleaning up from such a region,
it will reset the guard variable back to both zeroes.
This will free up a busy-waiting thread, if any,
or will reset everything for the next thread that calls the function.

<p>
The idea of the __static_init_wait() RTS routine is to monitor the
value of guard bits passed in, by looping on this decision table:
<pre><code>
    done    busy
    0       0       return 1 in %eax        (EH wipe-out)
    1       1       return 0 in %eax        (no longer busy)
    0       1       continue to wait        (still busy)
    1       0       internal error, shouldn't happen
</code></pre>

<p>
As for how the wait is done [... not relevant for ABI,
although currently we're using thr_yield(),
which may or may not be right for this context].

<p>
<font color=blue>[990608 SGI -- Hans]</font>
I'd like to make some claims about function scope static constructor
calls in multithreaded environments.
I personally can't recall ever having used such a construct,
which somewhat substantiates my claims,
but also implies some lack of certainty.
I'd be interested in hearing any arguments to the contrary.

<p>
I believe that these arguments imply that this problem is not important
enough to warrant added ABI complexity or overhead for sequential code.

<p>
Consider the following skeletal example:

<p><code>
f(int x) { static foo a(...); ... }
</code>

<ol>
<p>
<li>
If the constructor argument doesn't depend on the function parameter,
and the code behaves reasonably, it should be possible to rewrite this as

<p><code>
static foo a(...);
<br>
f(int x) { ... }
</code>

<p>
<li>
If I read the standard correctly (and that's a big disclaimer),
the compiler is entitled to perform the above transformation under
conditions that are usually true,
but hard for the compiler to deduce.
Thus code that relies on the initialization occurring during the
execution of f is usually broken.

<p>
<li>
Thus the foo constructor cannot rely on its caller holding any locks.
It must explicitly acquire any locks it needs.

<p>
<li>
It is far preferable to write the transformed form with a file scope
static variable to start with.
The initial form risks deadlock,
since f may be called with locks held which the constructor
can't assume are held.
If it needs one of those locks it will need to reacquire it.
With default mutex semantics that results in deadlock with itself.
(If locks may be reentered,
it may fail in a more subtle manner since the foo constructor may
acquire a monitor lock whose monitor invariant doesn't hold.)

<p>
<li>
File scope static constructor calls aren't a problem and require no locking,
since they are executed in a single thread before main is called or
before dlopen returns.
(Forking a thread in a static constructor should probably be disallowed.
Threads may not have been fully initialized, among other issues.)

<p>
<li>
Static function scope constructor calls which depend on function
arguments are likely to involve a race condition anyway,
if multiple instances of the function can be invoked concurrently.
Any of the calls might determine the constructor parameters.
Thus these aren't very interesting either.
And if they are really needed, they can be replaced with a file scope
static constructor call plus an assignment.

</ol>


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr class=small> <a name=G5></a> <td> G-5 </td>
<td> Varargs routine interface </td>
<td> call </td>
<td> open </td>
<td> HU-B </td>
<td> 990810 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The underlying C ABI defines conventions for calling varargs routines.
Does C++ need, or would it benefit from, any modifications or special cases?
How should we pass references or class objects?
Is any runtime library support required?
</td> </tr>

</table>

<p>
<font color=blue>[990810 HU-B Martin]</font>
I'd like to see an indirection in vararg lists,
so they can be passed through thunks.
This is necessary at least for the covariant returns,
but might have other applications as well.




<p> <hr> <p>
<h3> Library Interface Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=H1></a> <td> H-1 </td>
<td> Runtime library DSO name </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Determine the name of the common C++ runtime library DSO,
e.g. <code>libC.so</code>.
If there are to be vendor-specific support libraries which must coexist
in programs from mixed sources, identify naming convention for them.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <a name=H2></a> <td> H-2 </td>
<td> Runtime library API </td>
<td> lif </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Define the required entrypoints in the common C++ runtime library DSO,
and their prototypes.
</td> </tr>

</table>

<p>
<hr>

<p>
Please send corrections to <a href=mailto:dehnert@xxxxxxx>Jim Dehnert</a>.


</BODY>
</HTML>