1009 lines
50 KiB
HTML
1009 lines
50 KiB
HTML
<HTML>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<!-- Created on March, 13 2002 by texi2html 1.64 -->
|
|
<!--
|
|
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
|
|
Karl Berry <karl@freefriends.org>
|
|
Olaf Bachmann <obachman@mathematik.uni-kl.de>
|
|
and many others.
|
|
Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
|
|
Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
|
|
|
|
-->
|
|
<HEAD>
|
|
<TITLE>STABS: Cplusplus</TITLE>
|
|
|
|
<META NAME="description" CONTENT="STABS: Cplusplus">
|
|
<META NAME="keywords" CONTENT="STABS: Cplusplus">
|
|
<META NAME="resource-type" CONTENT="document">
|
|
<META NAME="distribution" CONTENT="global">
|
|
<META NAME="Generator" CONTENT="texi2html 1.64">
|
|
|
|
</HEAD>
|
|
|
|
<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
|
|
|
|
<A NAME="SEC52"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_6.html#SEC51"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC53"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H1> 7. GNU C++ Stabs </H1>
|
|
<!--docid::SEC52::-->
|
|
<P>
|
|
|
|
<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC53">7.1 C++ Class Names</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">C++ class names are both tags and typedefs.</TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC54">7.2 Defining a Symbol Within Another Type</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">C++ symbol names can be within other types.</TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC55">7.3 Basic Types For C++</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC56">7.4 Simple Class Definition</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC57">7.5 Class Instance</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC58">7.6 Method Definition</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Method definition</TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC59">7.7 The <SAMP>`#'</SAMP> Type Descriptor</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">The <SAMP>`#'</SAMP> type descriptor</TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC60">7.8 The <SAMP>`@'</SAMP> Type Descriptor</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">The <SAMP>`@'</SAMP> type descriptor</TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC61">7.9 Protections</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC62">7.10 Method Modifiers (<CODE>const</CODE>, <CODE>volatile</CODE>, <CODE>const volatile</CODE>)</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC63">7.11 Virtual Methods</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC64">7.12 Inheritance</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC65">7.13 Virtual Base Classes</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="stabs_7.html#SEC66">7.14 Static Members</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR>
|
|
</TABLE></BLOCKQUOTE>
|
|
<P>
|
|
|
|
<A NAME="Class Names"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC53"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.1 C++ Class Names </H2>
|
|
<!--docid::SEC53::-->
|
|
<P>
|
|
|
|
In C++, a class name which is declared with <CODE>class</CODE>, <CODE>struct</CODE>,
|
|
or <CODE>union</CODE>, is not only a tag, as in C, but also a type name. Thus
|
|
there should be stabs with both <SAMP>`t'</SAMP> and <SAMP>`T'</SAMP> symbol descriptors
|
|
(see section <A HREF="stabs_5.html#SEC43">5.9 Giving a Type a Name</A>).
|
|
</P><P>
|
|
|
|
To save space, there is a special abbreviation for this case. If the
|
|
<SAMP>`T'</SAMP> symbol descriptor is followed by <SAMP>`t'</SAMP>, then the stab
|
|
defines both a type name and a tag.
|
|
</P><P>
|
|
|
|
For example, the C++ code
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>struct foo {int x;};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
can be represented as either
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "foo:T19=s4x:1,0,32;;",128,0,0,0 # 128 is N_LSYM
|
|
.stabs "foo:t19",128,0,0,0
|
|
</pre></td></tr></table></P><P>
|
|
|
|
or
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "foo:Tt19=s4x:1,0,32;;",128,0,0,0
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Nested Symbols"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC54"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC53"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC55"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC55"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.2 Defining a Symbol Within Another Type </H2>
|
|
<!--docid::SEC54::-->
|
|
<P>
|
|
|
|
In C++, a symbol (such as a type name) can be defined within another type.
|
|
</P><P>
|
|
|
|
In stabs, this is sometimes represented by making the name of a symbol
|
|
which contains <SAMP>`::'</SAMP>. Such a pair of colons does not end the name
|
|
of the symbol, the way a single colon would (see section <A HREF="stabs_1.html#SEC4">1.3 The String Field</A>). I'm
|
|
not sure how consistently used or well thought out this mechanism is.
|
|
So that a pair of colons in this position always has this meaning,
|
|
<SAMP>`:'</SAMP> cannot be used as a symbol descriptor.
|
|
</P><P>
|
|
|
|
For example, if the string for a stab is <SAMP>`foo::bar::baz:t5=*6'</SAMP>,
|
|
then <CODE>foo::bar::baz</CODE> is the name of the symbol, <SAMP>`t'</SAMP> is the
|
|
symbol descriptor, and <SAMP>`5=*6'</SAMP> is the type information.
|
|
</P><P>
|
|
|
|
<A NAME="Basic Cplusplus Types"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC55"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC56"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC56"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.3 Basic Types For C++ </H2>
|
|
<!--docid::SEC55::-->
|
|
<P>
|
|
|
|
<< the examples that follow are based on a01.C >>
|
|
</P><P>
|
|
|
|
C++ adds two more builtin types to the set defined for C. These are
|
|
the unknown type and the vtable record type. The unknown type, type
|
|
16, is defined in terms of itself like the void type.
|
|
</P><P>
|
|
|
|
The vtable record type, type 17, is defined as a structure type and
|
|
then as a structure tag. The structure has four fields: delta, index,
|
|
pfn, and delta2. pfn is the function pointer.
|
|
</P><P>
|
|
|
|
<< In boilerplate $vtbl_ptr_type, what are the fields delta,
|
|
index, and delta2 used for? >>
|
|
</P><P>
|
|
|
|
This basic type is present in all C++ programs even if there are no
|
|
virtual methods defined.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "struct_name:sym_desc(type)type_def(17)=type_desc(struct)struct_bytes(8)
|
|
elem_name(delta):type_ref(short int),bit_offset(0),field_bits(16);
|
|
elem_name(index):type_ref(short int),bit_offset(16),field_bits(16);
|
|
elem_name(pfn):type_def(18)=type_desc(ptr to)type_ref(void),
|
|
bit_offset(32),field_bits(32);
|
|
elem_name(delta2):type_def(short int);bit_offset(32),field_bits(16);;"
|
|
N_LSYM, NIL, NIL
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>.stabs "$vtbl_ptr_type:t17=s8
|
|
delta:6,0,16;index:6,16,16;pfn:18=*15,32,32;delta2:6,32,16;;"
|
|
,128,0,0,0
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "name:sym_dec(struct tag)type_ref($vtbl_ptr_type)",N_LSYM,NIL,NIL,NIL
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "$vtbl_ptr_type:T17",128,0,0,0
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Simple Classes"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC56"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC55"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC57"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC57"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.4 Simple Class Definition </H2>
|
|
<!--docid::SEC56::-->
|
|
<P>
|
|
|
|
The stabs describing C++ language features are an extension of the
|
|
stabs describing C. Stabs representing C++ class types elaborate
|
|
extensively on the stab format used to describe structure types in C.
|
|
Stabs representing class type variables look just like stabs
|
|
representing C language variables.
|
|
</P><P>
|
|
|
|
Consider the following very simple class definition.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>class baseA {
|
|
public:
|
|
int Adat;
|
|
int Ameth(int in, char other);
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
The class <CODE>baseA</CODE> is represented by two stabs. The first stab describes
|
|
the class as a structure type. The second stab describes a structure
|
|
tag of the class type. Both stabs are of stab type <CODE>N_LSYM</CODE>. Since the
|
|
stab is not located between an <CODE>N_FUN</CODE> and an <CODE>N_LBRAC</CODE> stab this indicates
|
|
that the class is defined at file scope. If it were, then the <CODE>N_LSYM</CODE>
|
|
would signify a local variable.
|
|
</P><P>
|
|
|
|
A stab describing a C++ class type is similar in format to a stab
|
|
describing a C struct, with each class member shown as a field in the
|
|
structure. The part of the struct format describing fields is
|
|
expanded to include extra information relevant to C++ class members.
|
|
In addition, if the class has multiple base classes or virtual
|
|
functions the struct format outside of the field parts is also
|
|
augmented.
|
|
</P><P>
|
|
|
|
In this simple example the field part of the C++ class stab
|
|
representing member data looks just like the field part of a C struct
|
|
stab. The section on protections describes how its format is
|
|
sometimes extended for member data.
|
|
</P><P>
|
|
|
|
The field part of a C++ class stab representing a member function
|
|
differs substantially from the field part of a C struct stab. It
|
|
still begins with <SAMP>`name:'</SAMP> but then goes on to define a new type number
|
|
for the member function, describe its return type, its argument types,
|
|
its protection level, any qualifiers applied to the method definition,
|
|
and whether the method is virtual or not. If the method is virtual
|
|
then the method description goes on to give the vtable index of the
|
|
method, and the type number of the first base class defining the
|
|
method.
|
|
</P><P>
|
|
|
|
When the field name is a method name it is followed by two colons rather
|
|
than one. This is followed by a new type definition for the method.
|
|
This is a number followed by an equal sign and the type of the method.
|
|
Normally this will be a type declared using the <SAMP>`#'</SAMP> type
|
|
descriptor; see <A HREF="stabs_7.html#SEC59">7.7 The <SAMP>`#'</SAMP> Type Descriptor</A>; static member functions
|
|
are declared using the <SAMP>`f'</SAMP> type descriptor instead; see
|
|
<A HREF="stabs_5.html#SEC45">5.11 Function Types</A>.
|
|
</P><P>
|
|
|
|
The format of an overloaded operator method name differs from that of
|
|
other methods. It is <SAMP>`op$::<VAR>operator-name</VAR>.'</SAMP> where
|
|
<VAR>operator-name</VAR> is the operator name such as <SAMP>`+'</SAMP> or <SAMP>`+='</SAMP>.
|
|
The name ends with a period, and any characters except the period can
|
|
occur in the <VAR>operator-name</VAR> string.
|
|
</P><P>
|
|
|
|
The next part of the method description represents the arguments to the
|
|
method, preceded by a colon and ending with a semi-colon. The types of
|
|
the arguments are expressed in the same way argument types are expressed
|
|
in C++ name mangling. In this example an <CODE>int</CODE> and a <CODE>char</CODE>
|
|
map to <SAMP>`ic'</SAMP>.
|
|
</P><P>
|
|
|
|
This is followed by a number, a letter, and an asterisk or period,
|
|
followed by another semicolon. The number indicates the protections
|
|
that apply to the member function. Here the 2 means public. The
|
|
letter encodes any qualifier applied to the method definition. In
|
|
this case, <SAMP>`A'</SAMP> means that it is a normal function definition. The dot
|
|
shows that the method is not virtual. The sections that follow
|
|
elaborate further on these fields and describe the additional
|
|
information present for virtual methods.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "class_name:sym_desc(type)type_def(20)=type_desc(struct)struct_bytes(4)
|
|
field_name(Adat):type(int),bit_offset(0),field_bits(32);
|
|
|
|
method_name(Ameth)::type_def(21)=type_desc(method)return_type(int);
|
|
:arg_types(int char);
|
|
protection(public)qualifier(normal)virtual(no);;"
|
|
N_LSYM,NIL,NIL,NIL
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>.stabs "baseA:t20=s4Adat:1,0,32;Ameth::21=##1;:ic;2A.;;",128,0,0,0
|
|
|
|
.stabs "class_name:sym_desc(struct tag)",N_LSYM,NIL,NIL,NIL
|
|
|
|
.stabs "baseA:T20",128,0,0,0
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Class Instance"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC57"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC56"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC58"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC58"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.5 Class Instance </H2>
|
|
<!--docid::SEC57::-->
|
|
<P>
|
|
|
|
As shown above, describing even a simple C++ class definition is
|
|
accomplished by massively extending the stab format used in C to
|
|
describe structure types. However, once the class is defined, C stabs
|
|
with no modifications can be used to describe class instances. The
|
|
following source:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>main () {
|
|
baseA AbaseA;
|
|
}
|
|
</pre></td></tr></table></P><P>
|
|
|
|
yields the following stab describing the class instance. It looks no
|
|
different from a standard C stab describing a local variable.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "name:type_ref(baseA)", N_LSYM, NIL, NIL, frame_ptr_offset
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "AbaseA:20",128,0,0,-20
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Methods"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC58"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC57"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC59"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC59"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.6 Method Definition </H2>
|
|
<!--docid::SEC58::-->
|
|
<P>
|
|
|
|
The class definition shown above declares Ameth. The C++ source below
|
|
defines Ameth:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>int
|
|
baseA::Ameth(int in, char other)
|
|
{
|
|
return in;
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
This method definition yields three stabs following the code of the
|
|
method. One stab describes the method itself and following two describe
|
|
its parameters. Although there is only one formal argument all methods
|
|
have an implicit argument which is the <CODE>this</CODE> pointer. The <CODE>this</CODE>
|
|
pointer is a pointer to the object on which the method was called. Note
|
|
that the method name is mangled to encode the class name and argument
|
|
types. Name mangling is described in the ARM (<CITE>The Annotated
|
|
C++ Reference Manual</CITE>, by Ellis and Stroustrup, ISBN
|
|
0-201-51459-1); <TT>`gpcompare.texi'</TT> in Cygnus GCC distributions
|
|
describes the differences between GNU mangling and ARM
|
|
mangling.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "name:symbol_descriptor(global function)return_type(int)",
|
|
N_FUN, NIL, NIL, code_addr_of_method_start
|
|
|
|
.stabs "Ameth__5baseAic:F1",36,0,0,_Ameth__5baseAic
|
|
</pre></td></tr></table></P><P>
|
|
|
|
Here is the stab for the <CODE>this</CODE> pointer implicit argument. The
|
|
name of the <CODE>this</CODE> pointer is always <CODE>this</CODE>. Type 19, the
|
|
<CODE>this</CODE> pointer is defined as a pointer to type 20, <CODE>baseA</CODE>,
|
|
but a stab defining <CODE>baseA</CODE> has not yet been emitted. Since the
|
|
compiler knows it will be emitted shortly, here it just outputs a cross
|
|
reference to the undefined symbol, by prefixing the symbol name with
|
|
<SAMP>`xs'</SAMP>.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "name:sym_desc(register param)type_def(19)=
|
|
type_desc(ptr to)type_ref(baseA)=
|
|
type_desc(cross-reference to)baseA:",N_RSYM,NIL,NIL,register_number
|
|
|
|
.stabs "this:P19=*20=xsbaseA:",64,0,0,8
|
|
</pre></td></tr></table></P><P>
|
|
|
|
The stab for the explicit integer argument looks just like a parameter
|
|
to a C function. The last field of the stab is the offset from the
|
|
argument pointer, which in most systems is the same as the frame
|
|
pointer.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "name:sym_desc(value parameter)type_ref(int)",
|
|
N_PSYM,NIL,NIL,offset_from_arg_ptr
|
|
|
|
.stabs "in:p1",160,0,0,72
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<< The examples that follow are based on A1.C >>
|
|
</P><P>
|
|
|
|
<A NAME="Method Type Descriptor"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC59"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC58"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC60"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC60"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.7 The <SAMP>`#'</SAMP> Type Descriptor </H2>
|
|
<!--docid::SEC59::-->
|
|
<P>
|
|
|
|
This is used to describe a class method. This is a function which takes
|
|
an extra argument as its first argument, for the <CODE>this</CODE> pointer.
|
|
</P><P>
|
|
|
|
If the <SAMP>`#'</SAMP> is immediately followed by another <SAMP>`#'</SAMP>, the second
|
|
one will be followed by the return type and a semicolon. The class and
|
|
argument types are not specified, and must be determined by demangling
|
|
the name of the method if it is available.
|
|
</P><P>
|
|
|
|
Otherwise, the single <SAMP>`#'</SAMP> is followed by the class type, a comma,
|
|
the return type, a comma, and zero or more parameter types separated by
|
|
commas. The list of arguments is terminated by a semicolon. In the
|
|
debugging output generated by gcc, a final argument type of <CODE>void</CODE>
|
|
indicates a method which does not take a variable number of arguments.
|
|
If the final argument type of <CODE>void</CODE> does not appear, the method
|
|
was declared with an ellipsis.
|
|
</P><P>
|
|
|
|
Note that although such a type will normally be used to describe fields
|
|
in structures, unions, or classes, for at least some versions of the
|
|
compiler it can also be used in other contexts.
|
|
</P><P>
|
|
|
|
<A NAME="Member Type Descriptor"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC60"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC59"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC61"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC61"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.8 The <SAMP>`@'</SAMP> Type Descriptor </H2>
|
|
<!--docid::SEC60::-->
|
|
<P>
|
|
|
|
The <SAMP>`@'</SAMP> type descriptor is for a member (class and variable) type.
|
|
It is followed by type information for the offset basetype, a comma, and
|
|
type information for the type of the field being pointed to. (FIXME:
|
|
this is acknowledged to be gibberish. Can anyone say what really goes
|
|
here?).
|
|
</P><P>
|
|
|
|
Note that there is a conflict between this and type attributes
|
|
(see section <A HREF="stabs_1.html#SEC4">1.3 The String Field</A>); both use type descriptor <SAMP>`@'</SAMP>.
|
|
Fortunately, the <SAMP>`@'</SAMP> type descriptor used in this C++ sense always
|
|
will be followed by a digit, <SAMP>`('</SAMP>, or <SAMP>`-'</SAMP>, and type attributes
|
|
never start with those things.
|
|
</P><P>
|
|
|
|
<A NAME="Protections"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC61"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC60"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC62"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[ << ]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.9 Protections </H2>
|
|
<!--docid::SEC61::-->
|
|
<P>
|
|
|
|
In the simple class definition shown above all member data and
|
|
functions were publicly accessible. The example that follows
|
|
contrasts public, protected and privately accessible fields and shows
|
|
how these protections are encoded in C++ stabs.
|
|
</P><P>
|
|
|
|
If the character following the <SAMP>`<VAR>field-name</VAR>:'</SAMP> part of the
|
|
string is <SAMP>`/'</SAMP>, then the next character is the visibility. <SAMP>`0'</SAMP>
|
|
means private, <SAMP>`1'</SAMP> means protected, and <SAMP>`2'</SAMP> means public.
|
|
Debuggers should ignore visibility characters they do not recognize, and
|
|
assume a reasonable default (such as public) (GDB 4.11 does not, but
|
|
this should be fixed in the next GDB release). If no visibility is
|
|
specified the field is public. The visibility <SAMP>`9'</SAMP> means that the
|
|
field has been optimized out and is public (there is no way to specify
|
|
an optimized out field with a private or protected visibility).
|
|
Visibility <SAMP>`9'</SAMP> is not supported by GDB 4.11; this should be fixed
|
|
in the next GDB release.
|
|
</P><P>
|
|
|
|
The following C++ source:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>class vis {
|
|
private:
|
|
int priv;
|
|
protected:
|
|
char prot;
|
|
public:
|
|
float pub;
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
generates the following stab:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre># 128 is N_LSYM
|
|
.stabs "vis:T19=s12priv:/01,0,32;prot:/12,32,8;pub:12,64,32;;",128,0,0,0
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<SAMP>`vis:T19=s12'</SAMP> indicates that type number 19 is a 12 byte structure
|
|
named <CODE>vis</CODE> The <CODE>priv</CODE> field has public visibility
|
|
(<SAMP>`/0'</SAMP>), type int (<SAMP>`1'</SAMP>), and offset and size <SAMP>`,0,32;'</SAMP>.
|
|
The <CODE>prot</CODE> field has protected visibility (<SAMP>`/1'</SAMP>), type char
|
|
(<SAMP>`2'</SAMP>) and offset and size <SAMP>`,32,8;'</SAMP>. The <CODE>pub</CODE> field has
|
|
type float (<SAMP>`12'</SAMP>), and offset and size <SAMP>`,64,32;'</SAMP>.
|
|
</P><P>
|
|
|
|
Protections for member functions are signified by one digit embedded in
|
|
the field part of the stab describing the method. The digit is 0 if
|
|
private, 1 if protected and 2 if public. Consider the C++ class
|
|
definition below:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>class all_methods {
|
|
private:
|
|
int priv_meth(int in){return in;};
|
|
protected:
|
|
char protMeth(char in){return in;};
|
|
public:
|
|
float pubMeth(float in){return in;};
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
It generates the following stab. The digit in question is to the left
|
|
of an <SAMP>`A'</SAMP> in each case. Notice also that in this case two symbol
|
|
descriptors apply to the class name struct tag and struct type.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "class_name:sym_desc(struct tag&type)type_def(21)=
|
|
sym_desc(struct)struct_bytes(1)
|
|
meth_name::type_def(22)=sym_desc(method)returning(int);
|
|
:args(int);protection(private)modifier(normal)virtual(no);
|
|
meth_name::type_def(23)=sym_desc(method)returning(char);
|
|
:args(char);protection(protected)modifier(normal)virtual(no);
|
|
meth_name::type_def(24)=sym_desc(method)returning(float);
|
|
:args(float);protection(public)modifier(normal)virtual(no);;",
|
|
N_LSYM,NIL,NIL,NIL
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>.stabs "all_methods:Tt21=s1priv_meth::22=##1;:i;0A.;protMeth::23=##2;:c;1A.;
|
|
pubMeth::24=##12;:f;2A.;;",128,0,0,0
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Method Modifiers"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC62"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC61"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC63"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.10 Method Modifiers (<CODE>const</CODE>, <CODE>volatile</CODE>, <CODE>const volatile</CODE>) </H2>
|
|
<!--docid::SEC62::-->
|
|
<P>
|
|
|
|
<< based on a6.C >>
|
|
</P><P>
|
|
|
|
In the class example described above all the methods have the normal
|
|
modifier. This method modifier information is located just after the
|
|
protection information for the method. This field has four possible
|
|
character values. Normal methods use <SAMP>`A'</SAMP>, const methods use
|
|
<SAMP>`B'</SAMP>, volatile methods use <SAMP>`C'</SAMP>, and const volatile methods use
|
|
<SAMP>`D'</SAMP>. Consider the class definition below:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>class A {
|
|
public:
|
|
int ConstMeth (int arg) const { return arg; };
|
|
char VolatileMeth (char arg) volatile { return arg; };
|
|
float ConstVolMeth (float arg) const volatile {return arg; };
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
This class is described by the following stab:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "class(A):sym_desc(struct)type_def(20)=type_desc(struct)struct_bytes(1)
|
|
meth_name(ConstMeth)::type_def(21)sym_desc(method)
|
|
returning(int);:arg(int);protection(public)modifier(const)virtual(no);
|
|
meth_name(VolatileMeth)::type_def(22)=sym_desc(method)
|
|
returning(char);:arg(char);protection(public)modifier(volatile)virt(no)
|
|
meth_name(ConstVolMeth)::type_def(23)=sym_desc(method)
|
|
returning(float);:arg(float);protection(public)modifier(const volatile)
|
|
virtual(no);;", <small>...</small>
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "A:T20=s1ConstMeth::21=##1;:i;2B.;VolatileMeth::22=##2;:c;2C.;
|
|
ConstVolMeth::23=##12;:f;2D.;;",128,0,0,0
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Virtual Methods"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC63"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC62"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC64"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.11 Virtual Methods </H2>
|
|
<!--docid::SEC63::-->
|
|
<P>
|
|
|
|
<< The following examples are based on a4.C >>
|
|
</P><P>
|
|
|
|
The presence of virtual methods in a class definition adds additional
|
|
data to the class description. The extra data is appended to the
|
|
description of the virtual method and to the end of the class
|
|
description. Consider the class definition below:
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>class A {
|
|
public:
|
|
int Adat;
|
|
virtual int A_virt (int arg) { return arg; };
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
This results in the stab below describing class A. It defines a new
|
|
type (20) which is an 8 byte structure. The first field of the class
|
|
struct is <SAMP>`Adat'</SAMP>, an integer, starting at structure offset 0 and
|
|
occupying 32 bits.
|
|
</P><P>
|
|
|
|
The second field in the class struct is not explicitly defined by the
|
|
C++ class definition but is implied by the fact that the class
|
|
contains a virtual method. This field is the vtable pointer. The
|
|
name of the vtable pointer field starts with <SAMP>`$vf'</SAMP> and continues with a
|
|
type reference to the class it is part of. In this example the type
|
|
reference for class A is 20 so the name of its vtable pointer field is
|
|
<SAMP>`$vf20'</SAMP>, followed by the usual colon.
|
|
</P><P>
|
|
|
|
Next there is a type definition for the vtable pointer type (21).
|
|
This is in turn defined as a pointer to another new type (22).
|
|
</P><P>
|
|
|
|
Type 22 is the vtable itself, which is defined as an array, indexed by
|
|
a range of integers between 0 and 1, and whose elements are of type
|
|
17. Type 17 was the vtable record type defined by the boilerplate C++
|
|
type definitions, as shown earlier.
|
|
</P><P>
|
|
|
|
The bit offset of the vtable pointer field is 32. The number of bits
|
|
in the field are not specified when the field is a vtable pointer.
|
|
</P><P>
|
|
|
|
Next is the method definition for the virtual member function <CODE>A_virt</CODE>.
|
|
Its description starts out using the same format as the non-virtual
|
|
member functions described above, except instead of a dot after the
|
|
<SAMP>`A'</SAMP> there is an asterisk, indicating that the function is virtual.
|
|
Since is is virtual some addition information is appended to the end
|
|
of the method description.
|
|
</P><P>
|
|
|
|
The first number represents the vtable index of the method. This is a
|
|
32 bit unsigned number with the high bit set, followed by a
|
|
semi-colon.
|
|
</P><P>
|
|
|
|
The second number is a type reference to the first base class in the
|
|
inheritance hierarchy defining the virtual member function. In this
|
|
case the class stab describes a base class so the virtual function is
|
|
not overriding any other definition of the method. Therefore the
|
|
reference is to the type number of the class that the stab is
|
|
describing (20).
|
|
</P><P>
|
|
|
|
This is followed by three semi-colons. One marks the end of the
|
|
current sub-section, one marks the end of the method field, and the
|
|
third marks the end of the struct definition.
|
|
</P><P>
|
|
|
|
For classes containing virtual functions the very last section of the
|
|
string part of the stab holds a type reference to the first base
|
|
class. This is preceded by <SAMP>`~%'</SAMP> and followed by a final semi-colon.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "class_name(A):type_def(20)=sym_desc(struct)struct_bytes(8)
|
|
field_name(Adat):type_ref(int),bit_offset(0),field_bits(32);
|
|
field_name(A virt func ptr):type_def(21)=type_desc(ptr to)type_def(22)=
|
|
sym_desc(array)index_type_ref(range of int from 0 to 1);
|
|
elem_type_ref(vtbl elem type),
|
|
bit_offset(32);
|
|
meth_name(A_virt)::typedef(23)=sym_desc(method)returning(int);
|
|
:arg_type(int),protection(public)normal(yes)virtual(yes)
|
|
vtable_index(1);class_first_defining(A);;;~%first_base(A);",
|
|
N_LSYM,NIL,NIL,NIL
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "A:t20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;
|
|
A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Inheritance"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC64"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC63"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC65"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.12 Inheritance </H2>
|
|
<!--docid::SEC64::-->
|
|
<P>
|
|
|
|
Stabs describing C++ derived classes include additional sections that
|
|
describe the inheritance hierarchy of the class. A derived class stab
|
|
also encodes the number of base classes. For each base class it tells
|
|
if the base class is virtual or not, and if the inheritance is private
|
|
or public. It also gives the offset into the object of the portion of
|
|
the object corresponding to each base class.
|
|
</P><P>
|
|
|
|
This additional information is embedded in the class stab following the
|
|
number of bytes in the struct. First the number of base classes
|
|
appears bracketed by an exclamation point and a comma.
|
|
</P><P>
|
|
|
|
Then for each base type there repeats a series: a virtual character, a
|
|
visibility character, a number, a comma, another number, and a
|
|
semi-colon.
|
|
</P><P>
|
|
|
|
The virtual character is <SAMP>`1'</SAMP> if the base class is virtual and
|
|
<SAMP>`0'</SAMP> if not. The visibility character is <SAMP>`2'</SAMP> if the derivation
|
|
is public, <SAMP>`1'</SAMP> if it is protected, and <SAMP>`0'</SAMP> if it is private.
|
|
Debuggers should ignore virtual or visibility characters they do not
|
|
recognize, and assume a reasonable default (such as public and
|
|
non-virtual) (GDB 4.11 does not, but this should be fixed in the next
|
|
GDB release).
|
|
</P><P>
|
|
|
|
The number following the virtual and visibility characters is the offset
|
|
from the start of the object to the part of the object pertaining to the
|
|
base class.
|
|
</P><P>
|
|
|
|
After the comma, the second number is a type_descriptor for the base
|
|
type. Finally a semi-colon ends the series, which repeats for each
|
|
base class.
|
|
</P><P>
|
|
|
|
The source below defines three base classes <CODE>A</CODE>, <CODE>B</CODE>, and
|
|
<CODE>C</CODE> and the derived class <CODE>D</CODE>.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>class A {
|
|
public:
|
|
int Adat;
|
|
virtual int A_virt (int arg) { return arg; };
|
|
};
|
|
|
|
class B {
|
|
public:
|
|
int B_dat;
|
|
virtual int B_virt (int arg) {return arg; };
|
|
};
|
|
|
|
class C {
|
|
public:
|
|
int Cdat;
|
|
virtual int C_virt (int arg) {return arg; };
|
|
};
|
|
|
|
class D : A, virtual B, public C {
|
|
public:
|
|
int Ddat;
|
|
virtual int A_virt (int arg ) { return arg+1; };
|
|
virtual int B_virt (int arg) { return arg+2; };
|
|
virtual int C_virt (int arg) { return arg+3; };
|
|
virtual int D_virt (int arg) { return arg; };
|
|
};
|
|
</pre></td></tr></table></P><P>
|
|
|
|
Class stabs similar to the ones described earlier are generated for
|
|
each base class.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>.stabs "A:T20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;
|
|
A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
|
|
|
|
.stabs "B:Tt25=s8Bdat:1,0,32;$vf25:21,32;B_virt::26=##1;
|
|
:i;2A*-2147483647;25;;;~%25;",128,0,0,0
|
|
|
|
.stabs "C:Tt28=s8Cdat:1,0,32;$vf28:21,32;C_virt::29=##1;
|
|
:i;2A*-2147483647;28;;;~%28;",128,0,0,0
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
In the stab describing derived class <CODE>D</CODE> below, the information about
|
|
the derivation of this class is encoded as follows.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">.stabs "derived_class_name:symbol_descriptors(struct tag&type)=
|
|
type_descriptor(struct)struct_bytes(32)!num_bases(3),
|
|
base_virtual(no)inheritance_public(no)base_offset(0),
|
|
base_class_type_ref(A);
|
|
base_virtual(yes)inheritance_public(no)base_offset(NIL),
|
|
base_class_type_ref(B);
|
|
base_virtual(no)inheritance_public(yes)base_offset(64),
|
|
base_class_type_ref(C); <small>...</small>
|
|
</pre></td></tr></table></P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:
|
|
1,160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt:
|
|
:32:i;2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;
|
|
28;;D_virt::32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
<A NAME="Virtual Base Classes"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC65"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC64"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC66"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.13 Virtual Base Classes </H2>
|
|
<!--docid::SEC65::-->
|
|
<P>
|
|
|
|
A derived class object consists of a concatenation in memory of the data
|
|
areas defined by each base class, starting with the leftmost and ending
|
|
with the rightmost in the list of base classes. The exception to this
|
|
rule is for virtual inheritance. In the example above, class <CODE>D</CODE>
|
|
inherits virtually from base class <CODE>B</CODE>. This means that an
|
|
instance of a <CODE>D</CODE> object will not contain its own <CODE>B</CODE> part but
|
|
merely a pointer to a <CODE>B</CODE> part, known as a virtual base pointer.
|
|
</P><P>
|
|
|
|
In a derived class stab, the base offset part of the derivation
|
|
information, described above, shows how the base class parts are
|
|
ordered. The base offset for a virtual base class is always given as 0.
|
|
Notice that the base offset for <CODE>B</CODE> is given as 0 even though
|
|
<CODE>B</CODE> is not the first base class. The first base class <CODE>A</CODE>
|
|
starts at offset 0.
|
|
</P><P>
|
|
|
|
The field information part of the stab for class <CODE>D</CODE> describes the field
|
|
which is the pointer to the virtual base class <CODE>B</CODE>. The vbase pointer
|
|
name is <SAMP>`$vb'</SAMP> followed by a type reference to the virtual base class.
|
|
Since the type id for <CODE>B</CODE> in this example is 25, the vbase pointer name
|
|
is <SAMP>`$vb25'</SAMP>.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:1,
|
|
160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt::32:i;
|
|
2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;28;;D_virt:
|
|
:32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
|
|
</FONT></pre></td></tr></table></P><P>
|
|
|
|
Following the name and a semicolon is a type reference describing the
|
|
type of the virtual base class pointer, in this case 24. Type 24 was
|
|
defined earlier as the type of the <CODE>B</CODE> class <CODE>this</CODE> pointer. The
|
|
<CODE>this</CODE> pointer for a class is a pointer to the class type.
|
|
</P><P>
|
|
|
|
<TABLE><tr><td> </td><td class=example><pre>.stabs "this:P24=*25=xsB:",64,0,0,8
|
|
</pre></td></tr></table></P><P>
|
|
|
|
Finally the field offset part of the vbase pointer field description
|
|
shows that the vbase pointer is the first field in the <CODE>D</CODE> object,
|
|
before any data fields defined by the class. The layout of a <CODE>D</CODE>
|
|
class object is a follows, <CODE>Adat</CODE> at 0, the vtable pointer for
|
|
<CODE>A</CODE> at 32, <CODE>Cdat</CODE> at 64, the vtable pointer for C at 96, the
|
|
virtual base pointer for <CODE>B</CODE> at 128, and <CODE>Ddat</CODE> at 160.
|
|
</P><P>
|
|
|
|
<A NAME="Static Members"></A>
|
|
<HR SIZE="6">
|
|
<A NAME="SEC66"></A>
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC65"> < </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> > </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC52"> Up </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<H2> 7.14 Static Members </H2>
|
|
<!--docid::SEC66::-->
|
|
<P>
|
|
|
|
The data area for a class is a concatenation of the space used by the
|
|
data members of the class. If the class has virtual methods, a vtable
|
|
pointer follows the class data. The field offset part of each field
|
|
description in the class stab shows this ordering.
|
|
</P><P>
|
|
|
|
<< How is this reflected in stabs? See Cygnus bug #677 for some info. >>
|
|
</P><P>
|
|
|
|
<A NAME="Stab Types"></A>
|
|
<HR SIZE="6">
|
|
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
|
|
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_7.html#SEC54"> << </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_8.html#SEC67"> >> </A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs.html#SEC_Top">Top</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_toc.html#SEC_Contents">Contents</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_14.html#SEC90">Index</A>]</TD>
|
|
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="stabs_abt.html#SEC_About"> ? </A>]</TD>
|
|
</TR></TABLE>
|
|
<BR>
|
|
<FONT SIZE="-1">
|
|
This document was generated
|
|
by <I>GDB Administrator</I> on <I>March, 13 2002</I>
|
|
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
|
|
"><I>texi2html</I></A>
|
|
|
|
</BODY>
|
|
</HTML>
|