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

C++ ABI Summary



Sorry this is late.  Things have been distracting :-).

Here are the current versions of the issue pages.  Also, please look
again at the list of actions from the last meeting following.
I've included in the open issues document the priority initialization
writeup I promised (issue C-2), and the data layout document has been
adjusted as discussed for issue A-9 (empty base placement).  I have
not finished the Vtable layout work -- I apologize.


Date: Thu, 29 Jul 1999 20:55:46 -0700 (PDT)
From: dehnert (Jim Dehnert)
To: cxx-abi@xxxxxxxxxxxx
Subject: Action items from today's meeting
Reply-To: dehnert (Jim Dehnert)
Sender: owner-cxx-abi-sgi@cthulhu
Precedence: bulk

The following are the actions people agreed to (or were volunteered
for) at today's meeting.  AI-nn refers to an action item in the
summary, X-nn refers to the issue with that number.

Christophe
----------

AI-7, B-1:  We'd like to proceed with the virtual function call protocol,
      but need a write-up of what Christophe discussed last month.

Daveed
------

AI-13:  Describe RTTI representation.

Jim
---

A-9:  Reflect empty base class allocation decision in layout document.

B-6:  Rewrite Christophe's Vtable layout description as an exercise
      to identify any holes.

AI-15, C-2:  Do careful writeup of object file init priority representation.

Jason
-----

B-4/7:  Think carefully about the issues involved in putting Vtables
        (and therefore potentially objects that reference them) in
        shared memory.

Matt
----

C-7:  Write careful description of when parameter copy constructors
      may be elided.

Mike Ball
---------

B-3:  You apparently have a good characterization of when Vtable
      caching is safe/legal.  Can you please describe it for us?

Priti
-----

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

All
---

A-11:  Describe your representation for pointers to member functions.

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.



-- 
-	    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 29 July 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> 22 July </td> <td> 10:00-12:00 PDT </td>
<td align=left colspan=2> completed </td>
</tr>

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

<tr class=small>
<td> 5 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </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=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> ? </td>
<td> ? </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> ? </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> ? </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> ? </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=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> open </td>
<td> 990610 </td>
<td> </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> open </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>


</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> open </td>
<td> Sun </td>
<td> 990610 </td>
<td> </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> open </td>
<td> SGI </td>
<td> 990729 </td>
<td> </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> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> B-4 </td>
<td> Function descriptors in vtable </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </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> open </td>
<td> HP </td>
<td> 990624 </td>
<td> </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> open </td>
<td> All </td>
<td> 990625 </td>
<td> </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> </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-1 </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>Notes from 3 June 1999 </h4>

<ul>
<p>
<li> Introductions

<p>
<li> Objectives: see above

<p>
<li> Procedure

  <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>
<li> Issue Identification:  new issues reflected in status table.

</ul>

<p>
<h4>Notes from 10 June 1999 </h4>

<p>
Matt Austern presented an initial assessment of the object layout issues.
He categorized them as trivial
(requiring agreement, but without significant performance implications)
or significant.  The trivial issues are:

<ol>
<p>
<li> (A-1) Where is the Vptr stored in an object?
Given the absence of addressing modes with displacements on IA-64,
the consensus is at the beginning of the object.

<p>
<li> (A-9) What is the order of members in an object?
Discussion of the possibilities for reordering between access
specifications suggests that we might find significance here.

<p>
<li> (A-4) Empty base class optimization:
when can an empty base class be stored at the same offset as another member?

<p>
<li> (A-1) What is the order of the Vtable?

<p>
<li> (B-5) What is the external name of a global Vtable?

<p>
<li> (B-5) Where is a global Vtable emitted?

</ol>

<p>
The significant issues are:

<ol>
<p>
<li> (A-3) How are virtual functions handled given multiple inheritance?
That is, where is the "this" pointer adjusted?

<p>
<li> (A-2) How are virtual functions handled given virtual base types?

<p>
<li> (B-2) How are virtual functions with covariant return types handled?
That is, where is the result pointer adjusted?

<p>
<li> (A-6) How does RTTI interact with exceptions?

</ol>

<p>
<h4>Notes from 17 June 1999 </h4>

<p>
<b> Issues A-1, A-2, A-9</b> (Matt):
See the open issues list.

<p>
<b> Actions</b>:
Christophe will write a Vtable layout definition strawman,
including a description of covariant returns,
and more generally the virtual function protocol.
Daveed will write up the issue with dynamic casts and inaccessible bases.

<p>
Michael Lam will write summaries for the ctor/dtor issues for next week.

<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 4 August 1999</i>

</center>

</HEAD>

<BODY>

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

<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> <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> <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> <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>
<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> <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>
<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-12 </td>
<td> Merging secondary vtables </td>
<td> data </td>
<td> open </td>
<td> Sun </td>
<td> 990610 </td>
<td> </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>

</table>

<p>
<font color=blue>[990701 Michael Lam]</font>
Michael will check what the Sun ABI treatment is and report back.

<p>
<font color=blue>[990729 All]</font>
A separate issue raised in conjunction with A-6 is whether to include
Vfunc pointers in the primary Vtable for functions defined only in the
base classes and not overridden.
If the primary and secondary Vtables are concatenated,
this is no longer an issue,
since all can be referenced from the primary Vptr.

<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> <td> A-14 </td>
<td> Pointers to data members </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990729 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
How should pointers to data members be represented?
</td> </tr>

</table>

<p>
<font color=blue>[990729 SGI]</font>
We suggest an offset from the base address of the class,
represented as a <code>ptrdiff_t</code>.

<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> <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>
<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> 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> <td> B-3 </td>
<td> Allowed caching of vtable contents </td>
<td> call </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </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>

</table>

<p>
<font color=blue>[990604 HP Christophe]</font>
Mike (Ball) gave me what I believe is an excellent definition of  
when caching is allowed.  I'd like him to present it.

<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> B-4 </td>
<td> Function descriptors in vtable </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </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>

</table>

<p>
<font color=blue>[990624 All]</font>
Note that putting GP in the Vtable prevents putting it in shared memory.
See B-7.


<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> 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> <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>
<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> B-7 </td>
<td> Objects and Vtables in shared memory </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990624 </td>
<td> </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>

</table>

<p>
<font color=blue>[990624 All]</font>
Note that putting GP in the Vtable prevents putting it in shared memory.
This interacts with B-4.

<p>
<font color=blue>[990624 HP -- Cary]</font>
For a C++ object to be placed into shared memory,
its vtable pointer must be valid in all processes
that are sharing that object.

<ol>
<p>
<li>
If the vtable can be placed in text, that would be fine,
but the vtable contains function pointers (or descriptors)
that require runtime relocation, so it must be in data.

<p>
<li>
We can place the vtables in shared memory,
but only if the function pointers/descriptors are valid in all processes.
The entry point addresses, which refer to shared text, should be shareable,
but the gp values may not be identical for all processes.
(RTTI pointers are also an issue,
and could be solved by putting the RTTI information in shared memory as well.)

<p>
<li>
We can place the vtables in private memory,
provided they are at the same address in all processes.
</ol>

<p>
One way or another,
we need a way of ensuring that a pointer from shared 
memory to private memory is valid in all processes,
which means that we will need a means to ensure that certain shared
library data segments can get mapped at the same address in all
processes that load those certain libraries.

<p>
My wild idea a few years ago was to put the vtables in shared memory
(by allocating and building them at load time, as Taligent did),
and store a shared library index in place of the gp value
in each function descriptor.
Each process would have its own table of gp values,
indexed by this shared library index,
but the index space would be managed system-wide.
The C++ runtime library would have been responsible for allocating
a new index for each unique C++ shared library loaded on the system,
then storing the process-local copy of the gp pointer in the 
appropriate slot of the table.

<p>
<font color=blue>[990628 SGI -- Jim]</font>
Note a further problem with vtables in shared memory (Cary's point 2).
If a virtual function comes from another DSO,
it may be pre-empted differently in different programs.
Hence, the function pointer itself is a problem even if the GP isn't.

<p>
<font color=blue>[990701 All]</font>
An extensive discussion boiled down to a few points:
<ul>
<p>
<li> The primary issue is objects in shared memory --
    vtables aren't interesting in themselves, but rather because
    putting the object in shared memory implies having the vtable at
    the same address in all sharing processes.

<p>
<li> Many of us have a few customers asking for this.
    It is not clear just how extensive a facility they need,
    or how automatic it needs to be.
    We should attempt to gauge the need.

<p>
<li> Noone thinks we should penalize the non-shared case for
    the rare instances of shared demand.

<p>
<li> It is questionable whether we can define an ABI mechanism
    which will work on all of our systems,
    but we'd like not to preclude OS-specific extensions to do
    this if we can't.

<p>
<li> One possible approach would be an API allowing a user to
    place an object in shared memory,
    and then "install" it by setting its vtable pointers,
    possibly to copies also placed in the same shared memory.

<p>
<li> A more automatic approach would be something which allocated
    certain objects/vtables to shared memory,
    gave up at link time if not all pointers were internal to the
    object being linked,
    attempted to place the relevant segments at the same runtime
    addresses to allow sharing,
    and gave up on sharing if this was not possible.
    Such an approach would perhaps still require some care on the part
    of the user to prevent problematic runtime situations.
</ul>

<p>
These ideas are very fuzzy.
Participants should think about the need and possibilities and attempt
to identify more concrete approaches.


<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> 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> <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> <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>
<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> 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>
<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> 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> <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> <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> <td> C-7 </td>
<td> Passing value parameters by reference </td>
<td> call </td>
<td> open </td>
<td> All </td>
<td> 990624 </td>
<td> </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>

</table>

<p>
<font color=blue>[990701 All]</font>
Daveed and Matt will attempt to pin down the copy requirements with the
Core committee, i.e. when a non-trivial copy constructor may be elided.
The relevant Standard requirement is 12.8/15,
and there is an open defect report related to this question.
For cases where the ctor may not be elided,
we expect to perform the copy at the call site,
and pass a reference.

<p>
<font color=blue>[990729 All]</font>
Matt will produce a clear proposal for when the ABI will elide the
constructor (and therefore pass the class object like a normal C struct),
based on the Standard's exceptions.

<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> 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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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> <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>
<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> 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> <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> <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> <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> <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> <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> <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> <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> <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>
<HTML>

<HEAD>
<title>C++ ABI Closed 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 Closed Issues
</b></i></font>

<font size=-1>
<p>
<i>Revised 29 July 1999</i>

</center>

</HEAD>

<BODY>

<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> A.  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> <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>

</table>

<p>
<font color=blue>[990610 All]</font>
Given the absence of addressing modes with displacements on IA-64,
the consensus is to answer this question with "first."

<p>
<font color=blue>[990617 All]</font>
Given a Vptr and only non-polymorphic bases,
which (Vptr or base) goes at offset 0?
<ul>
<li> HP: Vptr at end, but IA-64 is different because no load displacement
<li> Sun: Vptr at 0 probably preferred
<li> g++: Vptr at end today
</ul>
<p>
Tentative decision:  Vptr always goes at beginning.

<p>
<font color=blue>[990624 All]</font>
Accepted tentative decision.
Rename, close this issue, and open separate issue (B-6) for Vtable layout.

<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-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>

</table>

<p>
<font color=blue>[990610 Matt]</font>
With regard to how data member accesses are handled,
the choices are to store either a pointer or an offset in the Vtable.
The concensus seems to be to prefer an offset.

<p>
<font color=blue>[990617 All]</font>
Any number of empty virtual base subobjects (rare) will be placed at
offset zero.
If there are no non-virtual polymorphic bases,
the first virtual base subobject with a Vpointer will be placed at
offset zero.
Finally, all other virtual base subobjects will be allocated at the
end of the class, left-to-right, depth-first.

<p>
<font color=blue>[990624 All]</font>
Define an empty object as one with no non-static, non-empty data members,
no virtual functions,
no virtual base classes,
and no non-empty non-virtual base classes.
Define a nearly empty object as one which contains only a Vptr.
The above resolution is accepted, restated as follows:

<p>
Any number of empty virtual base subobjects
(rare, because they cannot have virtual functions or bases themselves)
will be placed at offset zero, subject to the conflict rules in A-3
(i.e. this cannot result in two objects of the same type at the same
address).
If there are no non-virtual polymorphic base subobjects,
the first nearly empty virtual base subobject will be placed at offset zero.
Any virtual base subobjects not thus placed at offset zero will be
allocated at the end of the class,
in left-to-right, depth-first declaration order.

<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>

</table>

<p>
<font color=blue>[990617 All]</font>
At offset zero is the Vptr whenever there is one,
as well as the primary base class if any (see A-7).
Also at offset zero is any number of empty base classes,
as long as that does not place multiple subobjects of the same type at
the same offset.
If there are multiple empty base classes such that placing two of them
at offset zero would violate this constraint, the first is placed there.
(First means in declaration order.)

<p>
All other non-virtual base classes are laid out in declaration order at
the beginning of the class.
All other virtual base subobjects will be allocated at the
end of the class, left-to-right, depth-first.

<p>
The above ignores issues of padding for alignment,
and possible reordering of class members to fit in padding areas.
See issue A-9.

<p>
<font color=blue>[990624 All]</font>
There remains an issue concerning the selection of the primary base
class (see A-7), but we are otherwise in agreement.
We will attempt to close this on 1 July, modulo A-7.

<p>
<font color=blue>[990701 All]</font>
This issue is closed.
A full description of the class layout can be found in issue A-9.
(At this time, A-7 remains to be closed,
waiting for the Taligent rationale.)

<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?
(An empty base class is one with no non-static data members,
no virtual functions, no virtual base classes,
and no non-empty non-virtual base classes.)
</td> </tr>

</table>

<p>
<font color=blue>[990624 All]</font>
Closed as a duplicate of A-3.

<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>

</table>

<p>
<font color=blue>[990623 SGI]</font>
We propose that no parameter slot be allocated to such parameters,
i.e. that no register be used,
and that no space in the parameter memory sequence be used.
This implies that the callee must allocate storage at a unique address
if the address is taken (which we expect to be rare).

<p>
<font color=blue>[990624 All]</font>
In addition to the address-taken case,
care is required if the object has a non-trivial copy constructor.
HP observes that in (some?) such cases,
they perform the construction at the call site and pass the object by
reference.

<p>
<font color=blue>[990625 SGI -- Jim]</font>
I understand that the Standard explicitly allows elimination of
even non-trivial copy construction in some cases.
Is this one of them?  Where should I look?
Also, of course, varargs processing for elided empty parameters would
need to be careful.

<p>
I have opened a new issue (C-7) for passing copy-constructed
parameters by reference.
Since doing so would turn an empty value parameter
into a non-empty reference parameter,
this issue can ignore such cases.

<p>
<font color=blue>[990701 All]</font>
An empty parameter will not occupy a slot in the parameter sequence
unless:
<ol>
<li> its type is a class with a non-trivial copy constructor; or
<li> it corresponds to the variable part of a varargs parameter list.
</ol>

<p>
Daveed and Matt will pursue the question of when copy constructors may
be ignored for parameters with the Core committee,
and if they identify cases where the constructors may clearly be
omitted, those (empty) parameters will also be elided.

<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>
<font color=blue>[990617 All]</font>
It will be shared with the first polymorphic non-virtual base class,
or if none, with the first nearly empty polymorphic virtual base class.
(See A-2 for the definition of <i>nearly empty</i>.)

<p>
<font color=blue>[990624 All]</font>
HP noted that Taligent chooses a base class with virtual bases before
one without as the primary base class),
probably to avoid additional "this" pointer adjustments.
SGI observed that such a rule would prevent users from controlling the
choice by their ordering of the base classes in the declaration.
The bias of the group remains the above resolution,
but HP will attempt to find the Taligent rationale before this is decided.

<p>
<font color=blue>[990729 All]</font>
Close with the agree resolution.
If a convincing Taligent rationale is found, we can reconsider.

<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?
(An alternative for virtual bases:
allow the virtual base to move in the complete object.)
</td> </tr>

</table>

<p>
<font color=blue>[990623 SGI]</font>
We propose that the alignment of a class be the maximum alignment of
its virtual and non-virtual base classes,
non-static data members, and Vptr if any.

<p>
<font color=blue>[990624 All]</font>
Above proposal accepted.
(SGI observation:
the size of the class is rounded up to a multiple of this alignment,
per the underlying psABI rules.)

<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 name=A9>A-9</a> </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>
<b>Resolution</b>:
See separate writeup of <a href=abi-layout.html>Data Layout</a>.
</td> </tr>

</table>

<p>
<font color=blue>[990610 all]</font>
Some participants want to avoid attempts to reorder members differently
than the underlying C struct ABI rules.
Others think there may be benefit in reordering later access sections
to fill holes in earlier ones, or even in base classes.

<p>
<font color=blue>[990617 all]</font>
There are several potential reordering questions, more or less independent:
<ol>
<li> Do we reorder whole access regions relative to one another?
<li> Do we attempt to fill padding in earlier access regions with
	initial members from later regions?
<li> Do we fill the tail padding of non-POD base classes with members from
	the current class?
<li> Do we attempt to fill interior padding of non-POD base classes with later
	members?
</ol>

<p>
There is no apparent support for (1),
since no simple heuristic has been identified with obvious benefits.
There is interest in (2), based on a simple heuristic which might
sometimes help and will never hurt.
However, it is not clear that it will help much,
and Sun objects on grounds that they prefer to match C struct layout.
Unless someone is interested enough to implement and run experiments,
this will be hard to agree upon.
G++ has implemented (3) as an option,
based on specific user complaints.
It clearly helps HP's example of a base class containing a word and flag,
with a derived class adding more flags.
Idea (4) has more problems, including some non-intuitive (to users) layouts,
and possibly complicating the selection of bitwise copy in the compiler.

<p>
<font color=blue>[990624 all]</font>
We will not do (1), (2), or (4).  We will do (3).
Specifically, allocation will be in modified declaration order as follows:
<ol>
<li> Vptr if any, and the primary base class per A-7.
<li> Any empty base classes allocated at offset zero per A-3.
<li> Any remaining non-virtual base classes.
<li> Any non-static data members.
<li> Any remaining virtual base classes.
</ol>
Each subobject allocated is placed at the next available position that
satisfies its alignment constraints, as in the underlying psABI.
This is interpreted with the following special cases:
<ol>
<li> The "next available position" after a non-POD class subobject
	(base class or data member) with tail padding is at the
	beginning of the tail padding, not after it.
	(For POD objects, the tail padding is not "available.")
<li> Empty classes are considered to have alignment and size 1,
	consisting solely of one byte of tail padding.
<li> Placement on top of the tail padding of an empty class must avoid
	placing multiple subobjects of the same type at the same
	address.
</ol>
After allocation is complete,
the size is rounded up to a multiple of alignment (with tail padding).

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

<p>
<font color=blue>[990729 all]</font>
The layout writeup was accepted,
with the first choice for empty base placement.
That is, if placement at offset zero doesn't work,
it will be placed like a normal base/member.
The concensus was that this won't happen often,
and such bases will often overlap with the preceding tail padding or
following components anyway.
Jim will modify the writeup accordingly.

<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> 990710 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The C ABI specifies that 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>

</table>

<p>
<font color=blue>[990701 all]</font>
A separate issue (C-7) deals with cases where a non-trivial copy
constructor is required; we ignore those cases here.
Our conclusion is that, without a non-trivial copy constructor,
we need not be concerned about the class object moving in the process
of being passed, and there is no need to use a mechanism different from
the base ABI C struct mechanism.
At the same time, if we do use the underlying C struct mechanism,
the user has complete control of the passing technique,
by choosing whether to pass by value or reference/pointer.

<p>
Therefore, except in cases identified by issue C-7 for different treatment,
class parameters will be passed using the underlying C struct protocol.

<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>
<font color=blue>[990701 all]</font>
Define no special treatment for this case in the ABI.
A translator with control over both caller and callee may choose to optimize.


<p> <hr> <p>
<h3> B.  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> <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>
<font color=blue>[990610 Matt]</font>
One possibility is to have two Vtable entries,
which might point to different functions, different entrypoints,
or a real entrypoint and a thunk.
Another is to return two result pointers (base/derived),
and have the caller select the right one.

<p>
<font color=blue>[990715 All]</font>
Daveed presented his multiple-return-value scheme,
including an example that involved virtual base classes,
return values that are pointers to nonpolymorphic classes,
and other equally horrible things.

<p>
Consensus: we need to get the horrible cases correct,
but speed only matters in the simple case.
The simple case: class B has a virtual function f returning a B1*
and class D has a virtual function f returning a D1*,
where all four classes are polymorphic,
B is a primary base of D, and B1 is a primary base of D1.
(The really important case is where B1 is B and D1 is D,
but that simplification doesn't make any difference.)

<p>
Jason: Would the usual multiple-entry-point scheme work just as well?
That is, would it be just as fast as Daveed's scheme in the simple case,
and still preserve enough information for the more complicated cases?
It appears so, but we don't have a proof.
Jason will try to provide one.


<p>
<font color=blue>[990716 Cygnus -- Jason]</font>
Proof?
You always know what types a given override must be able to return,
and you know how to convert from the return type to those base types.
You know from the entry point which type is desired.
Seems pretty straightforward to me.



<p>
<font color=blue>[990716 Cygnus -- Jason]</font>
The alternative I was talking about yesterday goes something like this:

<p>
When we have a non-trivial covariant return situation,
we create a new entry in the vtable for the new return type.
The caller chooses which vtable entry to use based on the type they want.

<p>
This could be implemented several ways,
at the discretion of the vendor:

<ol>
<p>
<li>
Multiple entry points to one function,
with an internal flag indicating which type to return.
<p>
<li>
Thunks which intercept the function's return and modify the return value.
Note that unlike the case of calling virtual functions,
for covariant returns we always know which adjustments will be needed,
so we don't have to pay for a long branch.
We do, however, lose the 1-1 correspondence between calls and returns,
which apparently affects performance on the Pentium Pro.
<p>
<li>
Function duplication.
</ol>

<p>
The advantage of this approach to the complex case is that we don't have to
do a dynamic_cast when faced with multiple levels of virtual derivation.
It is also strictly simpler;
Daveed's model already requires something like
this in cases of multiple inheritance.

<p>
Of course, we can always mix and match;
we could choose to only do this in cases of virtual inheritance,
or use Daveed's proposal and do this only in
cases of repeated virtual inheritance.
In that case, the multiple returns
would just be an optimization for the single virtual inheritance case.

<p>
Since we don't seem to care about the performance of
anything but single nonvirtual inheritance,
it seems simpler not to bother with multiple returns.

<p>
The remaining question is how to handle the case of nontrivial
nonvirtual inheritance:
do we use multiple slots or have the caller do the adjustment?
My inclination is to have the caller adjust.

<p>
WRT patents,
the idea of having the function return the base-most class and having
the caller adjust is parallel to the patented Microsoft scheme whereby
they pass the base-most class as the 'this' argument to virtual functions,
but the word 'return' does not appear anywhere in the patent,
so it seems safe.


<p>
<font color=blue>[990722 All]</font>
The group was generally agreed that the simplicity of multiple entries
in the vtable outweighed any space/performance advantage of more
complex schemes (e.g. the method Daveed described on 15 July).
Discussion focussed on whether it is worthwhile to eliminate some of
the entries in cases where they are unnecessary because the caller
knows the required conversion,
namely when the return type has a unique non-virtual subobject of the
original return type.

<p>
Agreement was reached to avoid the complication of eliminating some of
the Vtable entries.
Thus, the Vtable will have one entry for each accessible return type of
a covariant virtual function.
These may be implemented in a variety of ways,
e.g. duplicated functions, separate entrypoints, or stubs,
and the ABI need not specify the choice.
The location of the Vtable entries is part of the separate Vtable
layout issue B-6.

<p> <hr> <p>
<h3> C.  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> <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> D.  Exception Handling Issues </h3>

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

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

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

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

<p>
<hr>

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

</BODY>
</HTML>
<HTML>

<HEAD>
<title>C++ ABI for IA-64: Data Layout</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 for IA-64: Data Layout
</b></i></font>

<font size=-1>
<p>
<i>Revised 30 July 1999</i>

</center>

</HEAD>

<BODY>

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

<p>
<font color=blue>[990730]</font>
Selected first variant for empty base allocation; removed others.


<p> <hr> <p>
<h3> General </h3>

In what follows, we define the memory layout for C++ data objects.
Specifically, for each type, we specify the following information about
an object O of that type:
<ul>
<li> the <i>size</i> of an object, <i>sizeof</i>(O);
<li> the <i>alignment</i> of an object, <i>align</i>(O); and
<li> the <i>offset</i> within O, <i>offset</i>(C),
     of each data component C, i.e. base or member.
</ul>

<p> For purposes internal to the specification,
we also specify the <i>data size</i> of an object, <i>dsize</i>(O),
which intuitively is sizeof(O) minus the size of tail padding.

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

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

<dl>

<p>
<dt> <i>alignment</i> of a type T (or object X)</dt>
<dd>
A value A such that any object X of type T has an address satisfying
the constraint that &X modulo A == 0.

<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>polymorphic class</i> </dt>
<dd>
A class requiring a virtual table pointer
(because it or its bases have one or more virtual member functions or
virtual base classes).

<p>
<dt> <i>primary base class</i> </dt>
<dd>
For a polymorphic class,
the unique base class (if any) with which it shares the Vptr at offset 0.

</dl>

<p> <hr> <p>
<h3> POD Data Types </h3>

The size and alignment of C POD types is as specified by the base (C) ABI.
Type bool has size and alignment 1.
All of these types have data size equal to their size.
(We ignore tail padding for PODs because the Standard does not allow us
to use it for anything else.)


<p> <hr> <p>
<h3> Non-POD Class Types </h3>

For non-POD class types C, assume that all component types
(i.e. base classes and non-static data member types)
have been laid out, defining size, data size, and alignment.
Layout (of type C) is done using the following procedure.

<ol type=I>
<p>
<li> <h5> Initialization </h5>
  <ol type=1>
  <p>
  <li> Initialize sizeof(C) to zero, align(C) to one, dsize(C) to zero.
  <p>
  <li> If C is a polymorphic type:
      <ol type=a>
      <p>
      <li> If C has a polymorphic base class,
	   attempt to choose a primary base class B.
	   It is the first non-virtual polymorphic base class, if any,
	   or else the first nearly empty virtual base class.
	   Allocate it at offset zero, and set
	   sizeof(C) to sizeof(B), align(C) to align(B), dsize(C) to dsize(B).
      <p>
      <li> Otherwise, allocate the Vtable pointer for C at offset zero,
	   and set sizeof(C), align(C), and dsize(C) to the appropriate
	   values for a pointer (all 8 bytes for IA-64 64-bit ABI).
      </ol>
  </ol>

<p>
<li> <h5> Non-Virtual-Base Allocation </h5>
<p>
For each data component D (i.e. base or non-static data member)
except virtual bases,
first the non-virtual base classes in declaration order
and then the non-static data members in declaration order,
allocate as follows:

  <ol type=1>

  <p>
  <li> If D is not an empty base class,
	start at offset dsize(C),
	incremented if necessary to alignment align(type(D)).
	Place D at this offset unless doing so would result in two
	components (direct or indirect) of the same type having the
	same offset.
	If such a component type conflict occurs,
	increment the candidate offset by align(type(D)),
	and try again,
	repeating until success occurs
	(which will occur no later than sizeof(C) incremented to the
	required alignment).

	<p>
	Update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)).
	Update align(C) to max (align(C), align(D)).
	If D is a base class (not empty in this case),
	update dsize(C) to offset(D)+dsize(D).
	If D is a data member,
	update dsize(C) to max (offset(D)+dsize(D), offset(D)+1).

  <p>
  <li> If D is an empty base class,
	its allocation is similar to the first case above,
	except that additional candidate offsets are considered before
	starting at dsize(C).
	First, attempt to place D at offset zero.
	If unsuccessful (due to a component type conflict),
	proceed with attempts at dsize(C) as for non-empty bases.

	<p>
	Once offset(D) has been chosen,
	update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)).
	Note that align(D) is 1, so no update of align(C) is needed.
	Similarly, since D is an empty base class,
	no update of dsize(C) is needed.

  </ol>

<p>
<li> <h5> Virtual Base Allocation </h5>
<p>
Finally allocate any virtual base classes
(except one selected as the primary base class in I-2a, if any)
as we did non-virtual base classes in step II-1,
in declaration order.
Update sizeof(C) to max (sizeof(C), offset(D)+sizeof(D)).
If non-empty, also update align(C) and dsize(C) as in II-1.

<p>
<li> <h5> Finalization </h5>
<p>
Round sizeof(C) up to a non-zero multiple of align(C).

</ol>


<p> <hr> <p>
<h3> Virtual Table Layout </h3>


<i>
&lt;To be defined.>

<p>
Issues:
<ul>
<li> A-2:  Contains offset of each virtual base class.
<li> A-6:  RTTI representation (TBD).
<li> A-12: Merging secondary vtables.
<li> B-2:  Will contain one entry per return type for covariant returns.
<li> B-4:  Function descriptors vs. function pointers in Vtable.
<li> B-7:  Possible to allocate in shared memory?
</ul>
</i>


<p> <hr> <p>
<h3> External Names (a.k.a. Mangling) </h3>

<i>
&lt;To be defined.>

<p>
<hr>

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

</BODY>
</HTML>