This chapter focuses
on the symbol table data used to represent a program's symbols and the scopes
in which they occur.
This information is primarily used by symbolic debuggers.
11.1 New or Changed Symbol Information Features
Tru64 UNIX V5.1B includes the following new or changed features:
New basic types for boolean and wchar_t (see Table 11-4).
A new representation of C++ using directives for global symbols (see Section 11.3.1.5.4).
Tru64 UNIX V5.1 includes the following new or changed features:
A new basic type for 32-byte complex (see Table 11-4).
A new representation for empty classes or structures (see Section 11.3.3.6.1) to distinguish them from opaque classes and structures (see Section 11.3.3.6.2).
Version 3.14 of the symbol table includes the following new or changed features:
local symbols with external linkage (see Section 11.3.1.1)
Fortan 90 modules (see Section 11.3.1.6)
Version 3.13 of the symbol table includes the following new or changed features:
64-bit auxiliary support (see Section 11.3.2.3)
Parameters with static storage and unallocated parameters (see Section 11.2.4)
New representation for procedures with no text (see Section 11.3.1.2)
Modified variant record representation (see Section 11.3.3.11)
New function pointer representation (see Section 11.3.3.5)
Block symbol added for alternate entry prologue size (see Section 11.3.1.9)
New representation for C++ namespaces (see Section 11.3.1.5)
Unnamed union or structure representation (see Section 11.3.3.3)
11.2 Structures, Fields, and Values for Symbol Information
Unless otherwise specified, all structures described in this section
are declared in the header file
sym.h, and all constants
are defined in the header file
symconst.h.
11.2.1 Local Symbol Entry (
SYMR)
typedef struct {
coff_long value;
coff_int iss;
coff_uint st : 6;
coff_uint sc : 5;
coff_uint reserved : 1;
coff_uint index : 20;
} SYMR, *pSYMR;
SIZE - 16 bytes, ALIGNMENT - 8 bytes
See
Section 11.2.4,
Section 8.3, and
Section 11.3.3
for related information.
Local Symbol Table Entry Fields
valueA field that can contain an address, size, offset, or index. Its interpretation is determined by the symbol type and storage class combination, as explained in Section 11.2.4.
issByte offset from
the
issBase
field of a file descriptor table entry
to the name of the symbol.
If the symbol does not have a name, this field
is set to
issNil
(-1).
Generally, all user-defined symbols have names.
A symbol without a name
is one that has been created by the compilation system for its own use.
stSymbol type (see Table 11-1).
scStorage class (see Table 11-2).
reservedMust be zero.
indexAn index into
either the local symbol table or auxiliary symbol table, depending on the
symbol type and class.
The index is used as an offset from the
isymBase
field in the file descriptor entry for an entry in
the local symbol table or an offset from the
iauxBase
field for an entry in the auxiliary symbol table.
The index field may have a value of
indexNil, which is defined as (long)0xfffff.
This
value is used to indicate that the index is not a valid reference.
The next two tables contain all defined values for the
st
and
sc
constants, along with short
descriptions.
However, these fields must be considered as pairs that have
a limited number of possible pairings as explained in
Section 11.2.4.
Table 11-1: Symbol Type (
st) Constants
| Constant | Value | Description |
stNil |
0 | Dummy entry |
stGlobal |
1 | Global variable |
stStatic |
2 | Static variable |
stParam |
3 | Procedure argument |
stLocal |
4 | Local variable |
stLabel |
5 | Label |
stProc |
6 | Global procedure |
stBlock |
7 | Start of block |
stEnd |
8 | End of block, file, or procedure |
stMember |
9 | Member of class, structure, union, or enumeration |
stTypedef |
10 | User-defined type definition |
stFile |
11 | Source file name |
stStaticProc |
14 | Static procedure |
stConstant |
15 | Constant data |
stBase |
17 | Base class (for example, C++) |
stVirtBase |
18 | Virtual base class (for example, C++) |
stTag |
19 | Data structure tag value (for example, C++ class or struct) |
stInter |
20 | Interlude (for example, C++) |
stModule |
22 | (V5.1B - ) Fortran90 module definition |
stNamespace |
22 | (V5.0 - ) Namespace definition (for example, C++) |
stUsing |
23 | (V5.0 - ) Namespace use (for example, C++ "using") |
stAlias |
24 | (V5.0 - ) Defines an alias for another symbols. Currently, only used for namespace aliases. |
stExternal |
30 | (V5.1B - ) Local symbol with external linkage |
stUseModule |
31 | (V5.1B - ) Fortran90 module use |
stRename |
32 | (V5.1B - ) Name replacement |
stInterface |
33 | (V5.1B - ) Name replacement |
stMax |
64 | Maximum number of symbol types |
General Notes:
Symbol type codes with more than one interpretation are identified by
the
lang
field in the associated file descriptor.
This applies to the
stModule/
stNamespace
symbol types.
Table 11-2: Storage Class (
sc) Constants
| Constant | Value | Description |
scNil |
0 | Dummy entry |
scText |
1 | Symbol allocated in the
.text
section |
scData |
2 | Symbol allocated in the
.data
section |
scBss |
3 | Symbol allocated in the
.bss
section |
scRegister |
4 | Symbol allocated in a register |
scAbs |
5 | Symbol value is absolute |
scUndefined |
6 | Symbol referenced but not defined in the current module |
scUnallocated |
7 | Storage not allocated for this symbol |
scTlsUndefined |
9 | TLS symbol referenced but not defined in the current module |
scInfo |
11 | Symbol contains debugger information |
scSData |
13 | Symbol allocated in the
.sdata
section |
scSBss |
14 | Symbol allocated in the
.sbss
section |
scRData |
15 | Symbol allocated in the
.rdata
section |
scVar |
16 | Parameter passed by reference (for example, Fortran or Pascal) |
scCommon |
17 | Common symbol |
scSCommon |
18 | Small common symbol |
scVarRegister |
19 | Parameter passed by reference in a register |
scVariant |
20 | Variant record (for example, Pascal or Ada) |
scFileDesc |
20 | File descriptor (for example, COBOL) |
scSUndefined |
21 | Small undefined symbol |
scInit |
22 | Symbol allocated in the
.init
section |
scReportDesc |
23 | Report descriptor (for example, COBOL) |
scXData |
24 | Symbol allocated in the
.xdata
section |
scPData |
25 | Symbol allocated in the
.pdata
section |
scFini |
26 | Symbol allocated in the
.fini
section |
scRConst |
27 | Symbol allocated in the
.rconst
section |
scTlsCommon |
29 | TLS common symbol |
scTlsData |
30 | Symbol allocated in the
.tlsdata
section |
scTlsBss |
31 | Symbol allocated in the
.tlsbss
section |
scMax |
32 | Maximum number of storage classes |
Table 11-3: Use Module Constants
| Constant | Value | Description |
USE_MODULE_ONLY |
0 | Import only the explicitly listed symbols from a Fortran module |
USE_MODULE_ALL |
1 | Import all symbols from a Fortran module |
Version Note Fortran modules are supported in symbol table format V3.14 and greater.
11.2.2 Auxiliary Symbol Table Entry (
AUXU)
The auxiliary
symbol table entry is a 32-bit union.
It is either interpreted as a
TIR
or
RNDXR
structure or as an integer
value.
See
Section 11.3.2.3
for detailed instructions on reading
the auxiliary symbols.
typedef union {
TIR ti;
RNDXR rndx;
coff_int dnLow;
coff_int dnHigh;
coff_int isym;
coff_int iss;
coff_int width;
coff_int count;
coff_int slice; (V5.0A)
} AUXU, *pAUXU;
SIZE - 4 bytes, ALIGNMENT - 4 bytes
See
Section 11.3.2.3
for related information.
Auxiliary Symbol Table Entry Fields
tiType information record (TIR), as defined in
Section 11.2.2.1.
rndxRelative index
into local or auxiliary symbols (rndx), as defined
in
Section 11.2.2.2.
dnLowLower bound of range or array dimension. For large structures, two of these fields can be used together to form one 64-bit number.
dnHighUpper bound of range or array dimension. For large structures, two of these fields can be used together to form one 64-bit number.
isymFor procedures
(
stProc
or
stStaticProc
symbols), this field is an index into the local
symbols.
It is also used as an index into the relative file descriptors.
issUnused.
widthWidth of a bit field or array stride in bits. Fortran compilers set the array stride to the array element size in bits. Two of these fields can be used together to form one 64-bit number.
countCount of ranges
for variant arm.
This field name is only used within the type description
of a variant block (
stBlock,
scVariant).
sliceReserved.
General Notes:
The fields
dnLow,
dnHigh,
or
width
must all use either the 32-bit or 64-bit
representation when used together.
For example, an array dimension cannot
be specified with a 32-bit
dnLow
and a 64-bit
dnHigh.
11.2.2.1 Type Information Record (
TIR)
typedef struct {
coff_uint fBitfield : 1;
coff_uint continued : 1;
coff_uint bt : 6;
coff_uint tq4 : 4;
coff_uint tq5 : 4;
coff_uint tq0 : 4;
coff_uint tq1 : 4;
coff_uint tq2 : 4;
coff_uint tq3 : 4;
} TIR, *pTIR;
SIZE - 4 bytes, ALIGNMENT - 4 bytes
Type Information Record Entry Fields
fBitfieldFlag set if bit width is specified.
continuedFlag set
to indicate that the type description is continued in another
TIR
record.
This will happen if the type is represented with
more than six type qualifiers.
btBasic type (see Table 11-4 and Section 11.3.2.1).
tq0, tq1, tq2, tq3, tq4, tq5Type qualifiers
(see
Table 11-5
and
Section 11.3.2.2).
The lower-numbered
tq
fields must be used first, and all unneeded fields must be
set to
tqNil
(0).
Table 11-4: Basic Type (
bt) Constants
| Constant | Value | Description |
btNil |
0 | Undefined or void |
btAdr32 |
1 | Address (32 bits) |
btChar |
2 | Character |
btUChar |
3 | Unsigned character |
btShort |
4 | Short (16 bits) |
btUShort |
5 | Unsigned short (16 bits) |
btInt |
6 | Integer (32 bits) |
btUInt |
7 | Unsigned integer (32 bits) |
btLong32 |
8 | Long (32 bits) |
btULong32 |
9 | Unsigned long (32 bits) |
btFloat |
10 | Floating point |
btDouble |
11 | Double-precision floating point |
btStruct |
12 | Structure or record |
btUnion |
13 | Union |
btEnum |
14 | Enumeration |
btTypedef |
15 | Defined by means of a user-defined type definition |
btRange |
16 | Range of values (for example, Pascal subrange) |
btSet |
17 | Sets (for example, Pascal) |
btComplex |
18 | Single complex (for example, Fortran
COMPLEX*8) |
btDComplex |
19 | Double complex (for example, Fortran
COMPLEX*16) |
btIndirect |
20 | Indirect definition; following
rndx
points to an entry in the auxiliary symbol table that contains a
TIR
(type information record) |
btFixedBin |
21 | Fixed binary (for example, COBOL) |
btDecimal |
22 | Packed or unpacked decimal (for example, COBOL) |
btPicture |
25 | Picture (for example, COBOL) |
btVoid |
26 | Void |
btPtrMem |
27 | Currently unused |
btScaledBin |
27 | Scaled binary (for example, COBOL) |
btVptr |
28 | Virtual function table (for example, C++) |
btArrayDesc |
28 | Array descriptor (for example, Fortran, Pascal) |
btClass |
29 | Class (for example, C++) |
btLong64 |
30 | Address (64 bits) |
btLong |
30 | Long (64 bits) |
btULong64 |
31 | Unsigned long (64 bits) |
btULong |
31 | Unsigned long (64 bits) |
btLongLong |
32 | Long long (64 bits) |
btULongLong |
33 | Unsigned long long (64 bits) |
btAdr64 |
34 | Address (64 bits) |
btAdr |
34 | Address (64 bits) |
btInt64 |
35 | Integer (64 bits) |
btUInt64 |
36 | Unsigned integer (64 bits) |
btLDouble |
37 | Long double floating point (128 bits) |
btInt8 |
38 | Integer (8 bits) |
btUInt8 |
39 | Unsigned integer (8 bits) |
btRange_64 |
41 | (V5.0 - ) 64-bit range |
btProc |
42 | (V5.0 - ) Procedure or function |
btCobolIndex |
43 | (not supported) COBOL index variables |
btQComplex |
46 | (V5.1 - )
Quad complex
(for example Fortran
COMPLEX*32) |
btBool |
47 | (V5.1B - ) 1 byte boolean (false=0, true=1) |
btWchar_t |
48 | (V5.1B - ) 4 byte wchar_t |
btChecksum |
63 | Symbol table checksum value stored in auxiliary record |
btMax |
64 | Number of basic type codes |
Table Notes:
btInt
and
btLong32
are synonymous.
btUInt
and
btULong32
are synonymous.
btLong,
btLong64,
btLongLong, and
btInt64
are synonymous.
btULong64,
btULongLong, and
btUInt64
are synonymous.
Table 11-5: Type Qualifier (
tq) Constants
| Constant | Value | Description |
tqNil |
0 | No qualifier (placeholder) |
tqPtr |
1 | Pointer |
tqProc |
2 | (obsolete) Procedure or function |
tqArray |
3 | Array |
tqFar |
4 | 32-bit pointer; used with the -xtaso emulation |
tqVol |
5 | Volatile |
tqConst |
6 | Constant |
tqRef |
7 | Reference |
tqArray_64 |
8 | (V5.0 - ) Large array |
tqShar |
10 | (V5.0A - ) Reserved |
tqExpArray_64 |
11 | (V5.0A - ) Reserved |
tqMax |
16 | Number of type qualifier codes |
11.2.2.2 Relative Index Record (
RNDXR)
typedef struct {
coff_uint rfd : 12;
coff_uint index : 20;
} RNDXR, *pRNDXR;
SIZE - 4, ALIGNMENT - 4
Relative Index Record Fields
rfdIndex into relative file descriptor table if it exists; otherwise, index into file descriptor table.
This field may have a value of
ST_RFDESCAPE, defined as
0xfff
in the header file
cmplrs/stsupport.h.
This value is used to indicate that the next
auxiliary entry, interpreted as an
isym, contains
the actual rfd index.
indexSymbol index.
Used as an offset from either
FDR.isymbase
or
FDR.iauxbase,
depending on context.
Objects can contain two string tables: the local string table (corresponding to local symbols) and the external string table (corresponding to external symbols). The local string table is present only for objects created with full debugging information; it is removed if an object is locally stripped.
The storage format for the string tables is a list of null-terminated
character strings.
It is correctly considered as one long character array,
not an array of strings.
Fields in the symbolic header and file headers represent
string table sizes and offsets in bytes.
11.2.4 Symbol Type Combinations
Entries in the symbol table are primarily
identified by the combination of their symbol type (st)
and storage class (sc) values.
Not all combinations
are valid.
Figure 11-1
indicates which combinations are currently
in use.
Figure 11-1: st/sc Combination Matrix
A symbol's type and class taken together determines interpretation of other fields in the symbol table entry. The same combination can be used for different purposes in different contexts. As a result, to understand the symbol entry, it also may be necessary to access type information in the auxiliary table or the source language information in the file descriptor.
The contents of the
value
and
index
fields for each combination, with a brief explanation
of the symbol's use, are described in the following list of combinations.
For many combinations, greater detail can be found in
Section 11.3.2
and
Section 11.3.3.
stGlobal/
scAbs
The
value
field contains an absolute
value.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a global absolute value.
stGlobal/
scSData,
stGlobal/
scData,
stGlobal/
scSBss,
stGlobal/
scBss,
stGlobal/
scRData,
stGlobal/
scRConst
The
value
field is the symbol's
address.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a defined global variable.
stGlobal/
scTlsData,
stGlobal/
scTlsBss
The
value
field is the offset from
the base of the object's TLS region.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a defined global TLS variable.
stGlobal/
scSCommon,
stGlobal/
scCommon,
stGlobal/
scTlsCommon
The
value
field is the symbol's
size in bytes.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a common.
stGlobal/
scSUndefined,
stGlobal/
scUndefined,
stGlobal/
scTlsUndefined
The
value
field is zero in linked
objects.
In relocatable objects, the
value
field
is ignored.
(Some compilers store the size in bytes of the global variable
in the
value
field.)
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is an undefined global variable.
The
value
field is an absolute
value.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is an absolute value with static scope.
stStatic/
scSData,
stStatic/
scData,
stStatic/
scSBss,
stStatic/
scBss,
stStatic/
scRData,
stStatic/
scRConst
The
value
field is the symbol's
address.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a defined static variable.
stStatic/
scTlsData,
stStatic/
scTlsBss
The
value
field is an offset from
the base of the object's TLS region.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a defined static TLS variable.
The
value
field is zero.
The
index
field is an auxiliary
table index or
indexNil
if there
is no type information.
This symbol is a Fortran common block.
The
value
field is zero.
The
index
field is an auxiliary
table index.
This symbol is a C++ static data member.
The
value
field is an offset from
the virtual frame pointer.
The
index
field is an auxiliary
table index.
This symbol is a parameter stored on the stack.
stParam/
scRegister
The
value
field is the number of
the register containing the parameter.
The
index
field is an auxiliary
table index.
This symbol is a parameter stored in a register.
stParam/
scVar
The
value
field is an offset from
the virtual frame pointer to the parameter's address.
The
index
field is an auxiliary
table index.
This symbol is a parameter stored on the stack. One level of indirection is required to access the parameter's value.
stParam/
scVarRegister
The
value
field is the register
number containing the address of the parameter.
The
index
field is an auxiliary
table index.
This symbol is a parameter stored on the stack. One level of indirection is required to access the parameter's value.
stParam/
scInfo
The
value
field is zero.
The
index
field is an auxiliary
table index.
This symbol is a parameter of a C++ member function, function pointer definition, or procedure with no code.
stParam/
scSData,
stParam/
scData,
stParam/
scSBss,
stParam/
scBss,
stParam/
scRData,
stParam/
scRConst
The
value
field is the address
of the parameter.
The
index
field is an auxiliary
table index.
This symbol is a static parameter.
Version Note Static parameters are supported in symbol table format V3.13 and greater.
stParam/
scUnallocated
The
value
field is zero.
The
index
field is an auxiliary
table index.
This is an unallocated parameter.
The
value
field is an offset from
the virtual frame pointer.
The
index
field is an auxiliary
table index.
This is a local variable stored on the stack.
stLocal/
scRegister
The
value
field is the number of
the register containing the variable.
The
index
field is an auxiliary
table index.
This symbol is a local variable stored in a register.
stLocal/
scVar
The
value
field is an offset from
the virtual frame pointer to the symbol's address.
The
index
field is an auxiliary
table index.
This symbol is a local variable stored on the stack. One level of indirection is required to access its value.
stLocal/
scVarRegister
The
value
field is the register
number containing the address of this variable.
The
index
field is an auxiliary
table index.
This symbol is a local variable stored on the stack. One level of indirection is required to access its value.
stLocal/
scUnallocated
The
value
field is zero.
The
index
field is an auxiliary
table index.
This is an unallocated local variable.
Version Note The use of
scUnallocatedis supported in symbol table format V3.13 and greater.
stLocal/
scText,
stLocal/
scInit,
stLocal/
scFini,
stLocal/
scSData,
stLocal/
scData,
stLocal/
scSBss,
stLocal/
scBss,
stLocal/
scRData,
stLocal/
scRConst,
stLocal/
scTlsData,
stLocal/
scTlsBss
The
value
field is the address
of the section indicated by the storage class.
The
index
field is
indexNil.
These are special symbols inserted by the linker for shared
objects.
They are found in the external symbol table and their names are
the section names (for example,
.text
or
.init).
stLabel/
scAbs
The
value
field is the symbol's
value.
This may be either a numeric constant or absolute address.
The
index
field is
indexNil.
This symbol is a linker defined absolute symbol.
stLabel/
scText,
stLabel/
scInit,
stLabel/
scFini,
stLabel/
scSData,
stLabel/
scData,
stLabel/
scXData,
stLabel/
scPData,
stLabel/
scSBss,
stLabel/
scBss,
stLabel/
scRData,
stLabel/
scRConst,
stLabel/
scTlsData,
stLabel/
scTlsBss
The
value
field is the label's
value (an address).
The
index
field is
indexNil.
This symbol is an allocated label. It can be associated with any raw data section of the object file.
stLabel/
scUnallocated
The
value
field is zero.
The
index
field is
indexNil.
This symbol is an unallocated label.
The
value
field is zero.
The
index
field is
indexNil.
This symbol can be ignored. Compilers may produce this type/class combination for procedures that have been optimized away and that don't require debug information. The linker removes these symbols from the external symbol table in linked objects.
stProc/
scText
The
value
field is the procedure's
address.
This symbol can occur in the external or local symbol table:
In the local symbol table, the
index
field is an auxiliary table index.
In the external symbol table, it is the local symbol index
of the corresponding procedure symbol in the local symbol table, unless the
file is stripped of local symbol information.
If the file is locally stripped,
the
index
field is
indexNil.
This symbol is a defined procedure.
stProc/
scUndefined
The
value
field is zero.
The
index
field is
indexNil.
This symbol is an undefined procedure.
The
value
field contains a value
of:
-1
(a procedure with no code)
-2
(a function prototype or function pointer
definition)
A non-negative index into the virtual function table for this function, for a C++ virtual member function.
Version Note The use of
-1and-2in thevaluefield is supported in symbol table format V3.13 and greater.
The
index
field is an auxiliary
table index.
This symbol represents a procedure without code, a function
prototype, or a function pointer.
The
value
field
is used to distinguish among these possibilities.
The
value
field depends on context:
If this is the first
stBlock/
scText
symbol following
an
stProc/
scText
symbol, the
value
is the byte
offset from the procedure's address to the address of the first instruction
beyond the end of the procedure's prologue.
Otherwise, it is the byte offset from the procedure's address to the starting instruction address of the block.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
If this is the first
stBlock/
scText
following an
stProc/
scText
for an alternate entry point, the index field will be set to
indexNil
because the symbol will not have a matching
stEnd
symbol.
Version Note The use of
stBlock/scTextfor alternate entry points is supported in symbol table format V3.13 and greater.
This symbol indicates the start of a block scope.
The
value
field depends on context:
Size in bytes for a class, structure, or union.
Size of the underlying data type for an enumerated type.
Auxiliary table index for a variant record.
Zero for the block scope of a procedure with no code.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol indicates the start of a structure, union, or
enumeration definition (in C; the C++ representation differs).
It describes
a variant arm if it is inside an
stBlock/
scVariant
scope.
This symbol is also used to
define the block scope of a procedure with no code.
The
value
field is the size of
the common block in bytes.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol is a scoping symbol for a Fortran common block. It occurs in the context of the synthesized file used to define a common block.
The
value
field is the local symbol
index of the structure member whose value determines which variant range is
used.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol occurs in the context of Pascal and Ada variant records. It indicates the start of the symbols for one variant.
stBlock/
scFileDesc,
stBlock/
scReportDesc
The
value
field is zero.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol occurs in COBOL only. It indicates the start of the file or report descriptor scope.
The
value
field depends on the
type of scope it is ending.
It is:
The size in bytes of the procedure's text (for a procedure).
Byte offset from a procedure's address to the start of the epilogue (for the outermost text block in a procedure).
Byte offset from a procedure's address to the first instruction address beyond the end of the block (for a text block).
Zero (for a file).
The
index
field is the local symbol
index of the matching
stBlock,
stProc, or
stFile.
This symbol ends a file, procedure, or text block scope.
stEnd/
scInfo
The
value
field is zero.
The
index
field is the local symbol
index of the matching
stBlock
or
stNamespace.
If the matching symbol is an
stBlock, this symbol ends a structure, union, enumeration, C++
member function definition, procedure with no code, or the block scope contained
by a procedure with no code.
If the matching symbol is an
stNamespace, this symbol ends a namespace definition.
If the
matching symbol is an
stModule,
this symbol ends a module definition.
If the matching symbol is an
stUseModule, this symbol ends a module use definition.
If the matching symbol is an
stInterface,
this symbol ends a generic interface declaration.
stEnd/
scCommon
The
value
field is zero.
The
index
field is the local symbol
index of the matching
stBlock.
This symbol ends a Fortran common definition.
stEnd/
scVariant
The
value
field is the same as
that of the matching
stBlock.
The
index
field is the local symbol
index of the matching
stBlock.
This symbol ends a variant record block.
stEnd/
scFileDesc,
stEnd/
scReportDesc
The
value
field is zero.
The
index
field is the local symbol
index of the matching
stBlock.
This symbol ends a file or report descriptor block.
The
value
field depends on the
symbol's data type:
The ordinal value (for an element of an enumerated type).
Zero (for a namespace or union member).
Bit offset from the beginning of the structure (for a C structure or C++ class member).
The
index
field is an auxiliary
table index.
This symbol describes a data structure field or the member of a namespace. It is found inside a block defining a data structure (for example, class or struct) or a namespace definition block.
stMember/
scFileDesc,
stMember/
scReportDesc
The
value
field is zero or one,
depending on whether the symbol is local or external, respectively.
The
index
field is an auxiliary
table index.
This symbol occurs in COBOL only. It is found inside a file descriptor or report descriptor block.
The
value
field depends on the
purpose of this symbol:
Zero (for a user-defined type definition).
The auxiliary table index of the next auxiliary entry after
the start of the class definition (for a compiler-inserted symbol).
In effect,
the value is the contents of the
index
field plus
one.
The
index
field is an auxiliary
table index.
This symbol is a user-chosen name for a data type.
It also
appears as a compiler-inserted symbol following the
stTag/
scInfo
symbol
for a C++ opaque class or structure.
The
value
field is zero.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol denotes the scoping block for a source file.
The
value
field is the procedure's
address.
The
index
field is an auxiliary
table index.
This symbol is a defined static procedure.
stStaticProc/
scInit,
stStaticProc/
scFini
The
value
field is the procedure
address.
The
index
field is an auxiliary
table index.
These combinations are used for the special symbols
__istart
and
__fstart, which are inserted by the
linker.
The
value
field is the value of
the constant.
The
index
field is an auxiliary
table index.
This symbol represents a named value (for example, Fortran
PARAMETER).
stConstant/
scSData,
stConstant/
scData,
stConstant/
scSBss,
stConstant/
scBss,
stConstant/
scRData,
stConstant/
scRConst
The
value
field is the symbol's
address.
The
index
field is an auxiliary
table index.
This symbol represents allocated constant data.
The
value
field is the offset of
the base class relative to a derived class.
The
index
field is an auxiliary
table index.
This symbol is a C++ base class. It is found inside a block defining a data structure (for example, class or struct).
The
value
field is an index (starting
at 1) of the base class run-time description in the virtual base class table.
See
Section 11.3.3.6.3.
The
index
field is an auxiliary
table index.
This symbol is a C++ virtual base class. It is found inside a block defining a data structure (for example, class or struct).
The
value
field is zero.
The
index
field is an auxiliary
table index.
This symbol is a C++ class, structure, or union. See Section 11.3.3.6. Note that the representation for C structures and unions (Section 11.3.3.3) is different.
The
value
field is zero.
The
index
field is an auxiliary
table index.
This symbol is used in C++ to connect the definition of a member function with its prototype in the class definition context.
The
value
field is zero.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol indicates the start of the symbols in a namespace definition.
Version Note Namespace symbols are supported in symbol table format V3.13 and greater.
The
value
field is zero.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol defines a Fortran module.
Version Note Fortran modules are supported in symbol table format V3.14 and greater.
The
value
field is zero.
The
index
field is an auxiliary
table index.
This symbol specifies a C++ namespace (or portion thereof) that is being imported into another scope.
Version Note Namespace USING directives are supported in symbol table format V3.13 and greater.
The
value
field is zero.
The
index
field is an auxiliary
table index.
This symbol defines an alias for a C++ namespace.
Version Note Namespace aliases are supported in symbol table format V3.13 and greater.
The
value
field identifies source
language semantics for the declaration type: (0 = language default, 1 = "external",
2 = "extern", 3 = "static", 4 = "global", other = best guess or "external").
The
index
field is an auxiliary
table index.
This symbol identifies an external symbol (by name) that is visible in a local scope.
Version Note Local visibility for externals is supported in symbol table format V3.14 and greater.
The
value
field is either
USE_MODULE_ONLY
or
USE_MODULE_ALL
(see
Table 11-3).
The
index
field is either indexNil
or the local symbol index of the symbol following the matching
stEnd.
This symbol identifies a Fortran module (by name) from which symbols are imported and possibly renamed.
Version Note Fortran modules are supported in symbol table format V3.14 and greater.
The
value
field is a local string
table index identifying the name by which a symbol is referenced in the current
scope.
The
index
field is
issNil.
This symbol identifies a symbol that is renamed in the current scope. For example, Fortran module members that are renamed in a Fortran USE statement.
Version Note Fortran modules are supported in symbol table format V3.14 and greater.
The
value
field is 0.
The
index
field is the local symbol
index of the symbol following the matching
stEnd.
This symbol identifies a generic name for a set of procedure declarations, such as a Fortran interface declaration.
Version Note Generic names are supported in symbol table format V3.14 and greater.
Combinations may be valid in the local
symbol table, the external symbol table, or both.
Table 11-6
shows which combinations are valid in which table, based on the symbol type
value and also the storage class value where necessary.
Only combinations
previously specified as valid apply where the storage class value is shown
as a wildcard value with the character '*'.
Table 11-6: Valid Placement for
st/sc Combinations
st/sc
Combination |
External Symbol Table | Local Symbol Table |
stNil,
sc* |
X |
X |
stGlobal,
sc* |
X |
|
stStatic,
sc* |
X |
|
stParam,
sc* |
X |
|
stLocal,
scSCN
1 |
X |
|
stLocal, not
scSCN
1 |
X |
|
stLabel,
sc* |
X |
X |
stProc,
scInfo |
X |
|
stProc,
scText |
X |
X |
stProc,
scUndefined |
X |
|
stBlock,
sc* |
X |
|
stEnd,
sc* |
X |
|
stMember,
sc* |
X |
|
stTypedef,
sc* |
X |
|
stFile,
sc* |
X |
|
stStaticProc,
scText |
X |
|
stStaticProc,
scInit/
scFini |
X |
|
stConstant,
sc* |
X |
X |
stBase,
sc* |
X |
|
stVirtBase,
sc* |
X |
|
stTag,
* |
X |
|
stInter,
sc* |
X |
|
stNamespace,
sc* |
X |
|
stUsing,
sc* |
X |
|
stAlias,
* |
X |
|
stExternal,
* |
X |
|
stUseModule,
* |
X |
|
stRename,
* |
X |
|
stInterface,
* |
X |
Table Notes:
scSCN
is a section storage class:
scData,
scSData,
scBss,
scSBss,
scRConst,
scRData,
scInit,
scFini,
scText,
scXData,
scPData,
scTlsData,
scTlsBss
11.3 Symbol Information Usage
11.3.1 Scopes
From a user-program's point of view, an identifer's scope determines its visibility in different parts of the program. Programming languages provide facilities for declaring and defining names of procedures, variables and other program components inside various scoping levels. This section briefly discusses the concept of scope and then explains how it is represented in the symbol table. References are made to structures in the auxiliary symbol table; see Section 11.3.2.3 for details.
Generally speaking, the four main scoping levels in a program are block scope, procedure scope, file scope, and program scope. Most programming languages have constructs to implement at least these scoping levels. Figure 11-2 shows the hierarchy of these scopes.
Names with block scope can only be referenced inside the declaring block. Blocks are delimited by begin and end markers, the syntax of which varies among languages.
Names with procedure scope are only recognized inside their enclosing subroutines. For instance, the names of formal parameters and local variables declared inside a procedure are accessible only to that procedure's executable statements.
Names with file scope can be referenced by any instruction within the file where they are declared. A file can be composed of procedures and data external to any procedure. Both external data names and procedure names can have file scope or program scope. Note that in a compilation involving only a single file or in a compilation for a programming language with no separate-compilation facilities, file scope and program scope are equivalent.
Names with program scope are visible everywhere in the program, even when the executable program is built from many source and header files. The linker must resolve these names or pass them to the dynamic loader to resolve. See Chapter 13 for more information about symbol resolution.
In the symbol table, procedure scope, file scope, and program scope
correspond to local, static, and global symbols, respectively.
Block scope
names are also local symbols.
Local and static symbols appear in the local
symbol table, and global symbols are in the external symbol table.
11.3.1.1 Local Symbols with External Linkage
Version Note Local symbols with external linkage are supported in symbol table format V3.14 and greater.
Any scope below program scope can import symbols that are defined in program scope. For example, external declarations in C programs import program scope symbols to file, procedure, or block scope. Source language semantics normally limit the use of externally defined symbols to those that are declared within the local scope, but debuggers will assume that all external symbols are visible from any local scope when the symbol table excludes information on external declarations.
If a file descriptor's
fullExternals
flag
is set, debuggers can limit the visibility of externally defined symbols to
those with external declarations in that compilation unit.
External declarations are recorded as local symbol table entries
with symbol type
stExternal
and
storage class
scInfo.
If the name
being declared is unique to the containing scope (shared only with other instances
or copies of that scope), then the name must be mangled in some way.
The
symbol is known locally by the demangled name, but globally by the mangled
name.
The rule for demangling the name must be either built into an appropriate
language specific demangling module as is done for C++ or known to debuggers
on a language specific basis as is done for the Fortran trailing underscore
convention.
If there is no corresponding external symbol table entry for an external declaration, then the local name is considered unallocated. This is not necessarily an error.
External declarations may include type information.
The local symbol's
index
field is interpreted as an
AUX
index.
In addition, the symbol's
value
field provides
a hint as to how best to regenerate the source language declaration.
See
the
stExternal/
scInfo
entry in
Section 11.2.4
for details.
11.3.1.2 Procedure Scope
Although procedure
symbols can only be global or static (with symbol types
stProc
and
stStaticProc,
respectively), procedure entries appear in the local symbol table to identify
the containing scope of their local data.
The set of symbols appearing in
the local symbol table to describe a procedure scope and their associated
auxiliary entries is shown in
Figure 11-3.
Global procedures
also have entries in the external symbol table.
As illustrated, the indices
of these external entries point to the scoping entries in the local symbol
table.
Note
In this chapter, all diagrams of symbol table representations use arrows to show that one entry contains an index to another entry. For external and local symbol table entries, the index used is contained in the
indexfield. For auxiliary symbols, theisymorRNDXRfield is the index used. Any exceptions to this general rule are noted in the diagrams.
Figure 11-3: Procedure Representation
A special instance of a procedure definition occurs for a procedure with no text. This type of procedure occurs only in the local symbol table and is very similar to the representation of other procedures. It is generally used for procedures that have been optimized away that still need to be represented for debugging or profiling information.
Figure 11-4: Procedure with No Text
A procedure with no code can contain only nested procedures that also
have no code associated with them.
If a procedure with no code does not contain
any nested procedures, the
stBlock/
stEnd
symbol pair can be omitted from the representation.
The
stProc
symbol included
in this representation is distinguished from similar
stProc
symbols by its value field that is set to
addressNil
(-1).
Version Note Procedures with no code are supported in symbol table format V3.13 and greater.
As in the case of procedures, file name entries appear in the local symbol table to define the file's scope. This representation is shown in Figure 11-5. Note that file symbols appear in the local symbol table only.
Figure 11-5: File Representation
In general, the local symbol table
denotes scoping levels with
stBlock
and
stEnd
pairs, as shown in
Figure 11-6.
All symbols contained between these two entries belong to the scope
they describe.
Nested blocks are possible, and
stEnd
symbols match the most recent occurrences of
stBlock
(or other opening symbol entries such
as
stProc
or
stTag).
Figure 11-6: Block Representation
Block scopes occur in many languages.
In C, they take the form of lexical
blocks.
In C++, declarations can occur anywhere in the code.
In Pascal and
Ada, nested procedures are possible, with local variables at any or all levels.
11.3.1.5 Namespaces (C++)
Version Note Namespaces are supported in symbol table format V3.13 and greater.
A C++ namespace is a mechanism that allows the partitioning of the program global name space. This partitioning is intended to reduce name clashing and provide greater program manageability to C++ developers.
Figure 11-7: C++ Namespace Representation
A namespace definition may exist only at the global scope or within another namespace. The namespace representation in Figure 11-7 shows a single contribution to a namespace. This representation may be replicated many times in the symbol table for a single namespace. A namespace definition may be continued within the same file or over multiple source files.
A single namespace contribution that spans multiple source files is represented as if it were contained entirely within the source file in which it began.
Namespaces may be aliased, allowing a single namespace to be referred
to by multiple names.
Namespace components may also be referenced without
their namespace qualification if they are included within a scope by a using
directive or using declaration.
The representations of namespace aliases,
using directives, and using declarations are shown in
Figure 11-7.
Namespace definitions, namespace component declarations, namespace aliases,
using directives, and using declarations occur only in the local symbol table.
Namespace component definitions may occur in the local or external symbol
table.
11.3.1.5.1 Namespace Components
The components of a namespace are represented in two parts: declarations and definitions. Namespace components that do not require definition must be declared in the namespace definition. Namespace components that are referenced by a using declaration must be declared in the namespace definition. All other namespace component declarations may be omitted from the namespace definition.
Namespace component names are mangled only as needed. Function and data definitions have mangled name definitions in the local or external symbol table. These entries are mangled for type-safe linkage and as a method of matching components with the namespaces to which they belong. Names of component declarations within a namespace definition may or may not be mangled. They are not required to include the namespace name in their mangled form.
Empty namespace contributions can be omitted, but at least one instance
of a namespace definition must occur somewhere in the local symbol table.
This definition is required because name mangling rules do not distinguish
namespace component definitions from class member definitions.
11.3.1.5.2 Namespace Aliases
Namespace aliases can occur in namespace, file, procedure, or
block scope in the local symbol table.
The index value for the
stAlias
entry is an auxiliary table index.
The auxiliary entry is a
RNDXR
record containing
the local symbol table index of the
stNamespace
symbol in the first instance of a namespace definition within
a compilation unit.
For an alias of an alias, the
RNDXR
record can also contain the index of another
stAlias
symbol in the local symbol table.
Section 17.2.5
provides an example of a namespace alias.
The
stAlias
symbol type may
be used in future versions of the symbol table format as a general purpose
symbol alias representation.
The semantic interpretation of the
stAlias
symbol depends on the type of the symbol
it aliases.
11.3.1.5.3 Unnamed Namespace
An unnamed namespace can be declared at the global scope or within another namespace. An unnamed namespace is unique within a compilation unit. Multiple contributions to a unique unnamed namespace are not allowed. Unnamed namespace contributions are included in the non-mergeable portion of a C++ header file.
Unnamed namespace components are subject to the same rules as named namespaces for declarations and definitions.
The
stNamespace
symbol for
an unnamed namespace has a compiler generated name starting with
__N1.
This same name is used to identify the unnamed namespace
in the mangled names of components of that namespace.
(See the unnamed namespace
example in
Section 17.2.4.)
11.3.1.5.4 Usage of Namespaces
A C++ using directive or a using declaration is represented
by a symbol of type
stUsing.
It
may occur in any scope in the local symbol table.
The index value for the
stUsing
entry is an auxiliary table index.
If the
stUsing
entry represents
a using declaration for a single namespace component, the auxiliary entry
is a
RNDXR
record containing the local symbol table
index of a namespace component declaration.
If the
stUsing
entry represents a using directive, its
RNDXR
auxiliary contains the local symbol table index of the
stNamespace
symbol in the first definition of
that namespace in the compilation unit.
A using directive for a namespace alias is represented with a
RNDXR
auxiliary that directly references the aliased namespace.
This representation contains no record of the alias referenced by the using
directive.
A using directive for a global symbol is represented with a
RNDXR
auxiliary that references a local symbol table
stExternal/
scInfo
entry with a name matching the global symbol as it is recorded
in the external symbol table.
Version Note Using directives for global symbols are supported in Tru64 UNIX V5.1B and greater.
Names are not required for
stUsing
entries, but they can be set to match the namespace or namespace component
to which they refer.
Namespace components that are referenced by an
stUsing
symbol must be declared in the namespace definition.
Section 17.2.3
provides an example of namespace definitions
and uses.
11.3.1.6 Fortran Modules
Version Note Fortran modules are supported in symbol table format V3.14 and greater.
A Fortran 90 module provides a way of grouping symbol names and controlling naming conflicts. The definition of a Fortran 90 module is very similar to the definition of a C++ namespace, but the uses of these two constructs are very different. See Section 11.3.1.5 for a description of C++ namespaces.
The compilation of a Fortran 90 module unit will result in a complete
local symbol table for the module.
The module will be represented as shown
in
Figure 11-8
using the
stModule
and
stEnd
symbols
to delimit the start and end of the module.
Declarations within the module
are represented in the normal manner.
The
stModule
symbol type shares the same value as the
stNamespace
symbol type.
The
lang
field in the containing file descriptor determines which interpretation is
valid.
Figure 11-8: Fortran 90 Module Representation
External symbol table entries for declarations contained in modules use a simple form of name mangling. As illustrated in Section 17.3.4, the external name is constructed by converting names to lower case and assembling them as:
$module$symbol_
Modules can contain interface declarations and contained procedure definitions. Contained procedures are defined inside the module. They are represented the same as any other procedure in Fortran. Procedure definitions are described in Section 11.3.1.2. Interface declarations identify procedures that can be accessed as members of the module, but they are defined outside of the module context. The representation of an interface declaration is illustrated in Figure 11-9. Examples of contained procedures and interface declarations can be found in Section 17.3.5 and Section 17.3.6, respectively.
Figure 11-9: Fortran 90 Module with Interface Declaration
11.3.1.6.1 Modules with Use Statements
The Fortran 90
USE
statement imports symbols from
a module defined in a separate compilation unit.
Variations of the statement
allow importing all of a module's symbols or only those that are specified.
The
USE
statement also allows imported symbols to be renamed
in the local context.
Figure 11-10
shows the representation of a
USE
statement that imports all symbols from a module without renaming
any of them.
Note that the
stUseModule
symbol
index
field is
isymNil
and the
value
field is
USE_MODULE_ALL.
Figure 11-10: Fortran 90 Module USE (ALL) Representation
Module names must be unique across all compilation units, so debuggers
can resolve the
stUseModule
entry
by searching all compilation units for the definition of a module with the
same name.
A debugger cannot resolve all module uses by searching the external
symbol table.
It must access the definition of the exporting module to resolve
symbols that it imports from other modules.
The example in
Section 17.3.4
illustrates the Fortran 90
USE
statement used in a module
definition to import symbols from another module.
Figure 11-11
shows the representation of a
USE
statement that imports all symbols from a module renaming some
of them.
Note that the
stUseModule
symbol
index
field is the index of the local symbol
table entry following the corresponding
stEnd
symbol and the
value
field is
USE_MODULE_ALL.
Specific symbols are renamed
with
stRename
entries.
For these
entries the
iss
field is the local string table
index of the symbol name in the local context.
The
value
field is the local string table index for the symbol name as it is appears
in the module definition.
Figure 11-11: Fortran 90 Module USE with Renaming
Figure 11-12
shows the representation of a
USE
statement that imports selected symbols from a module.
Note that
the
stUseModule
symbol
index
field is the index of the local symbol table entry following
the corresponding
stEnd
symbol
and the
value
field is
USE_MODULE_ONLY.
Specific symbols are imported with
stRename
entries.
If a symbol is renamed its
stRename
iss
field
is the local string table index of the symbol's name in the local context.
Otherwise, both the
iss
and
value
fields contain the same local string table index for the symbol
name as it is appears in the module definition.
Figure 11-12: Fortran 90 Module USE (ONLY) Representation
11.3.1.6.2 Fortran Generic Interfaces
The Fortran 90
INTERFACE
statement can be used to
create a single generic interface name for a set of procedure names that are
distinguished by parameter types.
The representation of generic interfaces
is illustrated in
Figure 11-13
and an example is shown in
Section 17.3.7.
Figure 11-13: Fortran 90 Generic Interface Representation
11.3.1.7 Exception Handling Blocks (C++)
In C++, a special scoping mechanism is introduced to expand user-defined exception-handling capabilities. Exception handlers are defined to "catch" exceptions that are "thrown" by other functions. The symbol table must contain sufficient information to recognize the scope of a handler. The compiler generates special symbols to identify where exception handlers are valid.
Figure 11-14: C++ Exception Handler Representation
11.3.1.8 Fortran Common Blocks
Fortran common blocks constitute another scoping level.
Fortran uses common blocks as a way of specifying data that is global or shared
between program units.
A common block is global storage that can be named,
allocated, accessed, and used by various subroutines.
The block can be named
or unnamed; unnamed blocks are known as "blank commons".
Internal to the symbol
table, blank commons are named
_BLNK__.
Figure 11-15 shows the symbolic representation of Fortran common blocks.
Figure 11-15: Fortran Common Block Representation
Because a Fortran common is represented as a synthesized file, it also has an entry in the file descriptor table. Furthermore, a global symbol with the same name is also present in the external symbol table.
An example of a Fortran common block can be found in
Section 17.3.1.
11.3.1.9 Alternate Entry Points
Fortran
also has a facility for creating alternate entry points in procedures.
An
alternate entry point is represented using an
stProc/
scText
symbol.
In the procedure descriptor table, an alternate entry point is identified
by a
lnHigh
field with a value of -1.
Procedure
descriptors for alternate entry points follow the procedure descriptor for
the primary entry point.
In the local symbol table, an alternate entry point
has an entry inside the scope of the procedure's primary entry.
The representation of a procedure with an alternate entry point is shown in Figure 11-16
Version Note The
stBlocksymbol that follows the alternate entry'sstProcsymbol in Figure 11-16 is supported in symbol table format V3.13 and greater. In symbol table formats less than V3.13 alternate entries do not have a start block symbol, and their prologue size is unknown.
Figure 11-16: Alternate Entry Point Representation
An example of Fortran alternate entries can be found in
Section 17.3.2.
11.3.2 Data Types in the Symbol Table
A data element's type dictates its size and interpretation in a programming environment. One of the symbol table's most important tasks is to represent data types in a compact and complete manner.
Type information is stored in the local and auxiliary symbol tables.
This section provides guidelines for understanding the type information plus
specific examples for depicting a range of types.
11.3.2.1 Basic Types
All programming languages have a set of simple types that are built into the language and from which other data types can be derived. Examples of simple types are integer, character, and floating point. Languages also provide constructs for creating user-defined types based on the simple types. For example, a C++ class can be built using any simple type or previously defined user-defined type and the language facility for declaring classes.
Similarly, a basic type in the symbol table is a building block from
which each language constructs its type information.
Basic type (bt) values directly represent many of the simple types for supported
languages; for instance, the value
btChar
indicates a character.
Other
bt
values represent
language constructs for building aggregate types; a value of
btStruct
may be used, for example, to represent a C structure
or Pascal record.
The symbol table uses approximately forty basic type values.
The interpretation
of some of these values is language dependent.
See
Table 11-4
for a list of all values.
11.3.2.2 Type Qualifiers
Type qualifiers can be applied to basic types to create other data types. Examples are "pointer to", "array of", and "function returning". Generally the number and order of type qualifiers is unrestricted.
See
Table 11-5
for a list of type qualifiers and their
meanings.
11.3.2.3 Interpreting Type Descriptions in the Auxiliary Table
This section explains in detail the encoding of type descriptions in the symbol table. To fully describe the type of a symbol, the auxiliary symbol table must be created and referenced. Compilation with full symbolic information (-g option on system compilers) results in the creation of this table.
To correctly decode the type information, proceed sequentially, beginning with the symbol table entry. Several fields may be required from other symbol table structures:
symbol type (st)
storage class (sc)
index (SYMR.index)
value (SYMR.value)
source language (FDR.lang)
The first step is to determine whether the symbol contains an index
of an auxiliary table description.
Table 11-7: Symbols with Auxiliary Type Descriptions
| Symbol Type | Storage Class | Conditions | AUXU
Index Field |
stGlobal |
Any | None | index |
stStatic |
Any | None | index |
stParam |
Any | None | index |
stLocal |
Any | Local symbol table | index |
stProc |
Any | Local symbol table | index |
stBlock |
scInfo |
Inside an
scVariant
block |
value |
stMember |
scInfo |
None | index |
stTypedef |
scInfo |
None | index |
stStaticProc |
Any | Local symbol table | index |
stConstant |
Any | None | index |
stBase |
scInfo |
None | index |
stVirtBase |
scInfo |
None | index |
stTag |
scInfo |
None | index |
stInter |
scInfo |
None | index |
stNamespace |
scInfo |
None | index |
stUsing |
scInfo |
None | index |
stAlias |
scInfo |
None | index |
stExternal |
scInfo |
None | index |
If
the index does represent a record in the auxiliary symbol table, the interpretation
of the first auxiliary entry (AUXU) depends on the
type of the symbol:
If the symbol's type is
stProc
or
stStaticProc
and
the symbol is a local symbol, the indexed
AUXU
is
an
isym
(set to
indexNil
for alternate entry points) and the second
AUXU
is a
TIR.
External procedure symbols
do not have descriptions in the auxiliary table.
If the symbol's type is
stInter,
stAlias, or
stUsing, the indexed
AUXU
is an
RNDXR
and the type description does not contain
a
TIR.
If the symbol is an
stBlock
symbol inside an
scVariant
block,
the symbol entry's
value
field is an index into
the auxiliary table.
This special case is the only one where the
value
is used as an auxiliary symbol pointer.
In all other cases,
it is the
index
field that potentially indexes
the auxiliary table type description.
Otherwise, the indexed
AUXU
is a
TIR.
The next task is to examine the
contents of the
TIR.
The
TIR
contains constants representing the basic type of the symbol and up to six
type qualifiers, labeled
tq0-tq5.
If a type has
more than one qualifier, they are ordered from lowest to highest.
Lower qualifiers
are applied to the basic type before higher qualifiers.
All unused
tq
fields are set to
tqNil,
and no
tqNil
fields are present
before or between other type qualifiers.
In addition to the basic type and type qualifiers, the
TIR
contains two flags: an
fBitfield
flag to mark whether the size of the type is explicitly recorded, and a
continued
flag to indicate that the type description is continued
in another
TIR.
If
fBitfield
is set, the
TIR
is immediately followed by a
width
entry.
If more than six type qualifiers are required for
the current definition, the description is continued, and the
continued
flag is set.
If exactly six type qualifiers are needed,
all six fields are used and the
continued
flag
is cleared.
To illustrate, consider the type "array of pointers to integers".
The
basic type is "integer" and has two qualifiers, "array of" and "pointer to".
Each element of the array is a "pointer to integer".
Therefore, the qualifier
"pointer to" must be applied first to the basic type "integer".
In this example,
the qualifier "pointer to" is lower than the qualifier "array of".
The contents
of the
TIR
are as follows:
bt: btInt
tq0: tqPtr
tq1: tqArray
tq2: tqNil
tq3: tqNil
tq4: tqNil
tq5: tqNil
continued: 0
fBitfield: 0
The contents of the
TIR
dictate how to interpret
any subsequent records.
The records appear in a prescribed order:
If the
fBitfield
flag is set, a
width
record follows the
TIR.
If the basic type is
btPicture, the next four records contain integer values: the string table
index of the picture string, the length, precision and scale.
If the basic type is
btScaledBin, the next three records contain integer values: a basic type,
the precision and scale.
If the basic type field is
btStruct,
btUnion,
btEnum,
btClass,
btIndirect,
btSet,
btTypedef,
btRange,
btRange_64,
btDecimal,
btFixedBin, or
btProc,
the next record is an
RNDXR.
If the
rfd
field of the
RNDXR
contains the value
ST_RFDESCAPE,
the next record is an
isym.
If the basic type is
btRange, the next two records are
dnLow
and
dnHigh.
If the basic type is
btRange_64, the next two records are
dnLow
records
and the two after that are
dnHigh
records.
If the basic type is
btDecimal
or
btFixedBin, the
next two records contain integer values: the precision and scale.
For each array type qualifier in the
TIR,
the following symbols occur:
An
RNDXR, again possibly followed
by an
isym
Either one or two
dnLow
records
(depending on whether the array is
tqArray
or
tqArray_64)
Either one or two
dnHigh
records
(depending on whether the array is
tqArray
or
tqArray_64)
Either one or two
width
records
(depending on whether the array is
tqArray
or
tqArray_64)
If the
continued
flag is set, the
next record is another
TIR
For a type description containing more than one
TIR,
the fields of all
TIR
records are interpreted in
the same way.
When a
TIR
is reached with the flag
cleared and any records associated with that
TIR
have been decoded, the type description is complete.
As an example, consider an array of structures with the
fBitfield
flag set.
A total of seven auxiliary records can
be used to describe the type:
The
TIR
with a basic type of
btStruct
and with
tq0
set to
tqArray.
A
width
record.
The size of the
basic type.
A
RNDXR
record.
A pointer to the
structure definition in the local symbol table.
A
RNDXR
record.
A pointer to the
array index type description elsewhere in the auxiliary table.
A
dnlow
record.
The lower bound
of the array's range.
A
dnhigh
record.
The upper bound
of the array's range.
A
width
record.
The distance in
bits between each element in the array.
If the
continued
flag of the
TIR
is cleared, the
width
record corresponding
to the array qualifier is the final
AUXU
for this
type description.
For another view of this process, see Figure 11-17. Each box represents one auxiliary entry belonging to the symbol's type description. Using the flowchart, an ordered list of entries can be assembled.
Figure 11-17: Auxiliary Table Interpretation
Figure 11-18: Auxiliary Table "ti" Interpretation
Figure 11-19: Auxiliary Table "arrays" Interpretation
Figure 11-20: Auxiliary Table "bt vals" Interpretation
Figure 11-21: Auxiliary Table Range Interpretation
Figure 11-22: Auxiliary Table
RNDXR Interpretation
The final step is to decode the
RNDXR
records.
The basic types that are followed by
RNDXR
records
require reference to another local or auxiliary symbol to complete the type
description.
Interpret the
RNDXR
records as follows:
If the
basic type is
btStruct,
btUnion,
btEnum,
btClass,
btProc, or
btTypedef, the
index
field of the
RNDXR
points into the local symbol table.
The specified local
symbol is the start of the definition of the structure, union, enumeration,
class, or user-defined type.
For
btProc,
the referenced local symbol is the start of the set of symbols defining the
procedure's signature.
If the basic type is
btSet,
the
RNDXR
points into the auxiliary symbol table.
The specified record is the start of the description of the type of each element
in the set.
If the basic type is
btIndirect, the
RNDXR
points into the auxiliary
symbol table.
The specified auxiliary record is the start of the description
of the referenced type.
If the basic type is
btRange, the
RNDXR
points into the auxiliary
symbol table.
The specified auxiliary record is the start of the description
of the type being subranged.
If the basic type is
btFixedBin, the
rfd
field of the
RNDXR
contains a Boolean value.
If
rfd
is
true, the base is decimal; if
rfd
is
false, the base is binary.
The
index
field represents a type code.
If the basic type is
btDecimal, the
rfd
field of the
RNDXR
contains the value
1
for 4-bit digits
(packed decimal) or
2
for 8-bit digits (zoned decimal).
The
index
field represents a type code.
Additionally,
the index of every
RNDXR
used as a pointer must be
mapped through the relative file descriptor table (see
Section 6.3.2),
if the table exists.
The
rfd
field of the record
controls this mapping.
The following algorithm can be used to locate the symbol
referenced by the relative index record:
if (RNDXR.rfd == ST_RFDESCAPE)
RFD = (++AUXU).isym
else
RFD = RNDXR.rfd
if (HDRR.crfd) /* RFD table exists */
IFD = (current FDR's RFD table)[RFD]
else
IFD = RFD
if (SYMR needed)
SYMBASE = FDR[IFD].isymBase
SYMR = SYMBASE[RNDXR.index]
else if (AUXU needed)
AUXBASE = FDR[IFD].iauxBase
AUXU = AUXBASE[RNDXR.index]
11.3.3 Individual Type Representations
This section provides sketches of type representations in the local and auxiliary symbol tables. The connections between the two tables is depicted for each type. This form of representation is only possible when full symbolic information is present.
Note that external symbols as well as local symbols reference the auxiliary
table, although the examples in this chapter use local symbols only.
11.3.3.1 Pointer Type
A pointer is
a variable containing the address of another variable.
A pointer is represented
by a
tqPtr
type qualifier modifying
another type.
A pointer is represented by a single symbol with an entry in
the auxiliary table, as shown in
Figure 11-23.
Note that if the pointer referenced a user-defined type, such as a class
or structure, the
TIR
would be followed by an
RNDXR
(and possibly an
isym).
Figure 11-23: Pointer Representation
The combination of type
qualifiers
tqFar
and
tqPtr
are used to represent a short (32-bit)
pointer.
This pointer type is used with the XTASO emulation.
11.3.3.2 Array Type
An array is a list of elements that all have the same type. Arrays may be fixed size and allocated at compile time or dynamically sized and allocated at run time. This section describes the fixed-size array symbol table representation. For information on Fortran dynamic arrays, see Section 11.3.3.9. For conformant arrays in Pascal and Ada, see Section 11.3.3.10.
An array is represented by a
tqArray
or
tqArray_64
type qualifier applied
to another type.
This second type describes the type of all elements in the
array.
In the local or external symbol table, a single entry represents an
array.
Figure 11-24
shows the symbol table description for an
array.
Figure 11-24: Array Representation
Note that for an array of elements of a user-defined type, such as a
class or structure, another
RNDXR
(and possibly an
isym) would be inserted between the
TIR
and the
RNDXR
describing the subscript type.
If an array has multiple dimensions, the symbols describing the dimension
appear in the order of innermost to outermost.
For example, the following
declaration produces a
TIR
with the
tqArray
qualifier followed by the
RNDXR
and range description for 0-1 followed by the entries for the dimension 0-99:
float floattable[100][2]
Some arrays may have dimensions too large to represent in the 32-bit format shown in Figure 11-24. Such arrays are represented using a 64-bit format in which two auxiliary entries are used for the dimension bounds and size. Figure 11-25 illustrates the 64-bit representation.
Version Note The 64-bit representation of arrays is supported in symbol table format V3.13 and greater.
Figure 11-25: 64-Bit Array Representation
11.3.3.3 Structure, Union, and Enumerated Types
This section applies to data structures in languages other than C++. For the C++ structure, union, or enumerated type representation, see Section 11.3.3.6.
Structures, unions, and enumerated types have a common representation.
All three are identified using "tags" and contain zero or more fields.
In
the symbol table, the tag is the name associated with the starting
stBlock
symbol for the structure's set of local
symbols.
Note that it may be empty because the tag is optional.
Symbols for
fields follow.
The definition is completed by a block-end symbol matching
the block-start symbol.
Figure 11-26 contains a graphical depiction of this set of symbols.
Figure 11-26: Structure Representation
The structure members have auxiliary table indices pointing to their type descriptions.
Untagged structures and unions are represented with a NULL tag name. Unnamed structures can be embedded in other structures and are represented as a NULL-named member of the outer structure. See Section 17.1.1 for an example of an unnamed structure.
Version Note Unnamed member structures are supported in symbol table format V3.13 and greater. As of Tru64 UNIX V5.1 dbx will display structures with unnamed member structures, but neither dbx nor ladebug provide specific access to members of unnamed member structures.
A structure can contain a field that is a pointer to itself.
This field
is represented by an
stMember
symbol
with an auxiliary table entry that references the beginning of the structure's
block of local symbols, as shown in
Figure 11-27.
Figure 11-27: Recursive Structure Representation
When a field within a structure is itself a structure, the compiler may choose to generate the structure definitions either sequentially or embedded, as shown in Figure 11-28.
Figure 11-28: Nested Structure Representation
The following declaration might result in the nested structure representation:
struct line {
struct point {
float x, y;
} p1, p2;
};
Most languages allow programmers to choose alternate names, or aliases, for data types. The alias created by such a facility (such as C's typedef) is represented as a single local symbol entry that has a pointer to its type description in the auxiliary table. The auxiliary entry contains a pointer to the definition of the type name, as shown in Figure 11-29.
Figure 11-29: Typedef Representation
11.3.3.5 Function Pointer Type
Version Note The following function pointer representation is the preferred representation for symbol table format V3.13 and greater.
Languages such as C and C++, which allow pointers to functions, represent
the type of the function pointer using a special
stProc/
scInfo
block
describing the parameters and return value for the function as shown in
Figure 11-30.
Figure 11-30: Function Pointer Representation
The
stProc/
scInfo
entry has its value set to
-2, which
distinguishes it from similar entries used to represent procedures with no
text and C++ member functions.
The
stProc/
scInfo
and
stEnd/
scInfo
entries have
null names in the function pointer representation.
The parameters are optional
and may or may not be named.
Version Note For symbol table formats less than V3.13 the preceding representation for function pointers is not supported, and the following alternate representation is used exclusively.
An alternate representation of function pointers is shown in
Figure 11-31.
This representation describes the return type of the function pointer but
not its parameters, and it is valid for all symbol table format versions.
The combination of type qualifiers
tqPtr
and
tqProc
is interpreted as "pointer
to function returning".
The function return type may be the base type (bt) in the
TIR
or it may be constructed
from the base type augmented by additional type qualifiers.
Figure 11-31: Function Pointer Alternate Representation
A C++ class resembles an extended C structure. One major distinction is that class fields (referred to as "members") can be functions as well as variables. The set of symbols created for a class is organized as follows:
The name of the class
A block symbol for scoping
Data members
Symbols associated with member functions. Each member function is represented by the normal set of symbols present for a function.
Corresponding end symbols that denote the completion of the block and class.
Another characteristic of classes is that symbols are defined implicitly.
For example, all classes have an
operator=
operator-overloading
function included in the class definition and a
this
pointer
to its own type as a parameter to all member functions.
These symbols are
always included explicitly in the symbol table description.
Figure 11-32 is a graphical representation of the set of symbols for a class.
Figure 11-32: Class Representation
Class members, including member functions, have auxiliary references that point to their type descriptions. Note that member functions are represented as prototypes. The set of symbols defining the member function is elsewhere in the symbol table. To locate the definition of a member function, a name lookup can be performed using the mangled name of the member function with its class name qualifier. See Section 13.3.3 for information on name mangling.
C++ structures, unions, and enumerated types are represented the same way as classes. The different data structures are distinguished by basic type value.
The symbol table does not represent class member access attributes.
Examples of base and derived classes can be found in
Section 17.2.1.
11.3.3.6.1 Empty Class or Structure (C++)
The representation of an empty class in C++ is shown in
Figure 11-33.
Empty structures in C++ are represented in a similar
manner with the
TIR.bt
set to
btStruct.
Figure 11-33: Empty Class or Structure (C++)
Version Note This empty class or structure representation is supported in Tru64 UNIX V5.1. Prior to Tru64 UNIX V5.1, the default compilers did not distinguish empty classes and structures from opaque classes and structures. See Section 11.3.3.6.2 for more details.
11.3.3.6.2 Opaque Class or Structure (C++)
Opaque classes and structures are incomplete types.
They have
no member information, and they are distinguished from empty classes and structures
that have no members.
The representation of an opaque class in C++ is shown
in
Figure 11-34.
Opaque structures in C++ are represented in
a similar manner with
TIR.bt
set to
btStruct.
Figure 11-34: Opaque Class or Structure (C++)
Version Note Prior to Tru64 UNIX V5.1 the default compilers used the preceding representation for empty classes and structures as well as opaque classes and structures.
11.3.3.6.3 Base and Derived Classes (C++)
Hierarchical groups of classes can be designed in C++.
A base
class serves as a wider classification for its derived classes, and a derived
class has all of the members and methods of the base class, plus additional
members of its own.
In the symbol table, the set of symbols denoting a derived
class is nearly identical to that for a non-derived class.
The derived class
includes an additional
stBase
or
stVirtBase
symbol that identifies its corresponding
base class, and it does not need to duplicate the definitions for the base
class members.
This representation is shown in
Figure 11-35.
Figure 11-35: Base Class Representation
The representation of virtual base classes for C++ relies on
the definition of a special symbol that identifies the virtual base table.
The name for this symbol is derived from the name of the class to which it
belongs.
For example, the virtual base table symbol for class
C5
would be named
"_btbl_2C5".
This table contains
entries for base class run-time descriptions.
A class can include the special member
_bptr.
This
class member is a pointer to the virtual base table for that class.
The
value
field for a virtual base class
symbol (
stVirtBase/
scInfo) serves as an index (starting at 1) into the virtual base
class table.
11.3.3.7 Template Type (C++)
Templates
are a C++-specific language construct allowing the parameterization of types.
C++ class templates are represented in the symbol table for each instantiation,
but not for the template itself.
The set of class symbols is unchanged from
the set shown in
Figure 11-32.
11.3.3.8 Interlude Type (C++)
Interludes
are compiler generated functions in C++.
They are represented in the local
symbol table with special names starting with the "__INTER__" prefix.
Their
representation in the symbol table makes use of two
RNDXR
aux entries to identify the related member function and the actual interlude
function, both of which are local symbol table entries.
Figure 11-36: Interlude Representation
11.3.3.9 Array Descriptor Type (Fortran90)
A Fortran90 array descriptor is a structure that describes an array: its location, dimensions, bounds, sizes, and other attributes. Array descriptors are described in detail in the Fortran 90 User Manual for Tru64 UNIX. Fortran90 includes several types of arrays for which the dimensions or dimension bounds are determined at run time: allocatable arrays, assumed shape arrays, and array pointers.
Two symbol table representations have been used for array descriptors. The current representation describes the array descriptor itself. The retired representation described attributes of the array known at compile time.
For both representations, symbols of this type point to a data location at which the array descriptor is allocated. One of the array descriptor fields contains a pointer to the actual array. Other fields are used to describe the attributes of the array. Fields that describe the number of dimensions and upper and lower bounds are filled in at run time.
By default, array descriptors are described by a structure tag representation.
Most of the array descriptor fields are represented as structure members.
(Excluded fields are not needed by debuggers.) Special tag names are used
to identify array descriptor structure definitions:
$f90$f90_array_desc
(assumed-shape array),
$f90$f90_ptr_desc
(pointer
to array) and
$f90$f90_alloc_desc
(allocatable array).
Figure 11-37
shows the format of this representation.
Some compilers may emit other fields in addition to those shown in Figure 11-37. A consumer's ability to interpret additional fields depends on its knowledge of the producing compiler.
Figure 11-37: Array Descriptor Representation
An example of the default Fortran array descriptor representation can be found in Section 17.3.3.
Version Note The following representation of Fortan array descriptors is supported in symbol table formats less than V3.13. It is not supported in symbol table format V3.13 and greater.
This retired representation of Fortran array descriptors is substantially more compact in the local symbol table, but it provides no way to distinguish between the different array descriptor types.
The overloaded basic type value 28 indicates an array descriptor in
the
TIR, and dimension bounds are set to [1:1] indicating
their true size is unknown.
The alternate representation does not provide
any information describing the contents of the array descriptor itself, so
debuggers must assume a static representation for the descriptor and lookup
the fields at their expected offsets.
Figure 11-38 shows this representation of array descriptors.
Figure 11-38: Array Descriptor Representation (retired)
11.3.3.10 Conformant Array Type (Pascal)
Full details are not currently available for Pascal's conformant
array representation.
A Pascal conformant array is very similar to Fortran's
assumed shape arrays.
It is an array parameter with upper and lower dimension
bounds that are determined by the input argument.
A conformant array is represented
by an array descriptor.
The special names used and the format of the array
descriptor differ from those used for Fortran.
The DEC Pascal release notes
contain additional information on conformant arrays.
11.3.3.11 Variant Record Type (Pascal and Ada)
A variant record is an extension to the record data type, which is a Pascal or Ada data structure akin to a C structure and is represented in the same manner in the symbol table. The variant part of the record consists of sets of one or more fields associated with a range of values. Only one such set is part of the record, and it is selected based on the value of another record field. Any number of variant parts can be embedded in a single record.
Version Note The following variant record representation is for symbol table format V3.13 and greater.
The local symbol table entries for the variant part of a record are
contained within a block with the storage class (sc
value)
scVariant.
The
value
field of the
stBlock
entry contains the index of the local symbol entry for the member of the record
whose value determines which variant arm is used.
The variant block contains
multiple inner blocks, each representing a variant arm.
The
value
field of each of these block entries is an auxiliary table
index.
Each auxiliary table entry starts with a
count,
which indicates how many range entries follow.
The range entries describe
the values associated with the block.
Figure 11-39 is a graphical representation of a variant record.
Figure 11-39: Variant Record Representation
Version Note The following variant record representation is for symbol table formats less than V3.13. It is not supported in symbol table format V3.13 and greater.
The representation of variant records depicted in
Figure 11-40
does not include
TIR
auxiliaries.
Figure 11-40: Variant Record Representation (retired)
An example of a Pascal variant record can be found in
Section 17.4.3.
11.3.3.12 Subrange Type (Pascal and Ada)
A subrange data type
defines a subset of the values associated with a particular ordinal type (the
"base type" of the subrange).
Ordinal types in Pascal include integers, characters,
and enumerated types.
The symbol table representation of a subrange uses the
btRange
or
btRange_64
type followed by an auxiliary index identifying the base type
and entries providing the bounds of the subrange.
The 32-bit representation
is shown in
Figure 11-41
and the 64-bit representation is shown
in
Figure 11-42.
Figure 11-41: Subrange Representation
Figure 11-42: 64-bit Range Representation
Version Note The 64-bit range representation is supported in symbol table format V3.13 and greater.
An example of a Pascal subrange can be found in
Section 17.4.2.
11.3.3.13 Set Type (Pascal)
A set is a data type
that groups ordinal elements in an unordered list.
The arithmetic and logical
operators are overloaded in Pascal; this enables them to be used with set
variables to perform classic set operations such as union and intersection.
A special auxiliary type definition
btSet
exists to identify this type.
The symbol table representation is depicted
in
Figure 11-43.
Figure 11-43: Set Representation
The element type for a set is typically a range or an enumeration.
An example of a Pascal set can be found in
Section 17.4.1.
11.3.4 Special Debug Symbols
A variety of
special symbols are used throughout the symbol table to convey call frame
information, special type semantics, or other language specific information.
These names are reserved for use by compilers and other tools that produce Tru64 UNIX
object files.
Table 11-8: Special Debug Symbols
| Name | Purpose |
| Name | Purpose |
__StaticLink.* |
(SV3.13 - ) Uplevel link. See Section 8.3.4. |
_BLNK__ |
Fortran unnamed common block. See Section 11.3.1.8. |
MAIN__ |
Fortran alias for main program unit. See Section 13.3.4. |
ARGNAME.len |
Generated parameter for Fortran routines. It contains the length of ARGNAME, a parameter of character type. |
.lb_<ARRAY>.<dim> .ub_<ARRAY>.<dim>
|
Lower and upper bounds of particular dimensions of arrays - when the array has an explicit shape, yet some bounds come from non-constant specification expressions (array arguments in Pascal and Fortran routines). |
$f90$f90_array_desc $f90$f90_alloc_desc $f90$f90_ptr_desc
|
Variants of Fortran-90 described arrays (assumed shape, ALLOCATABLE, and POINTER, respectively). See Section 11.3.3.9. |
cray pointee |
Fortran-generated typedef describing the type of a variable pointed to by a CRAY pointer. |
pointer |
Fortran generated typedef describing the type of a scalar with the POINTER attribute. |
_DECCXX_generated_name_* |
DECC++ compiler-inserted name for unnamed classes and enumerations. |
this |
Hidden parameter in C++ member functions that is a pointer to the current instance of the class. See Section 11.3.3.6. |
__vptr |
Hidden C++ class member containing the virtual function table. See example in Section 17.2.2. |
__bptr |
Hidden C++ class member containing the virtual base class table. See example in Section 17.2.2. |
__vtbl_* |
Global symbols for C++ virtual function tables. See example in Section 17.2.2. |
__btbl_* |
Global symbols for C++ virtual base class tables. See example in Section 17.2.2. |
__control |
Hidden argument to C++ constructors controlling descent (in the face of virtual base classes). |
__t*__evdf |
Structure used to maintain a list of C++ global deconstructors. |
t*__iviw |
C++ static procedure used for global constructors. |
t*__evdw |
C++ static procedure used for global destructors. |
__t*_thunk |
C++ static procedure used to provide a defaulted argument value. |
__INTER__* |
C++ interlude. See example in Section 17.2.2. |
__N1* |
C++ unnamed namespaces. See example in Section 17.2.4. |
11.4 Language-Specific Symbol Information Features
Language-specific characteristics are pervasive in the symbol table, particularly in the local, external, and auxiliary symbol tables. See Section 6.2 and Section 11.3.2 for information on language-specific values.
The
lang
field of the file descriptor entry
encodes the source language of the file.
This field should be accessed prior
to decoding symbolic information, especially type descriptions.
This section
highlights, by language, language-specific features represented in the symbol
table.
Additional information on certain features is available elsewhere in
this chapter.
11.4.1 Fortran77 and Fortran90
In Fortran, it is possible to create multiple entry points in subroutines.
A subroutine has one main entry point and zero or more alternate entry points,
indicated by
ENTRY
statements.
See
Section 11.3.1.9
for their representation in the symbol table.
Fortran90 array descriptors include allocatable arrays, assumed-shape arrays, and pointers to arrays. Their representation in the symbol table is discussed in Section 11.3.3.9.
Modules provide another scoping level in Fortran90 programs.
Their
symbol table representation is described in
Section 11.3.1.6.
11.4.2 C++
C++ classes encapsulate functions and data inside a single structure.
Classes are represented in the symbol table using a
btClass
basic type and the
stBlock/
stEnd
scoping mechanism.
See
Section 11.3.3.6.
Templates provide for parameterized types. At present, no special symbol table values are related to templates. The template itself is not represented; rather, entries that correspond to each instantiation are generated. Template instantiations are distinguished by mangled names based on their type signatures.
C++ namespaces, like Fortran modules, offer an additional scope for program identifiers.
The C++ concepts of private, protected, and public data attributes are
not currently represented in the symbol table.
The C++ concept of "friend"
classes and functions are also not represented.
11.4.3 Pascal and Ada
Pascal conformant arrays are function parameters with array dimensions that are determined by the arguments passed to the function at run time. See Section 11.3.3.10.
Variant records are an extension of the record data structure. Variant records allow different sets of fields depending on the value of a particular record member. See Section 11.3.3.11.
Nested procedures are supported in these languages. They are represented using standard scoping mechanisms discussed in Section 11.3.1 and uplevel references described in Section 8.3.4.
Sets and subranges are user-defined subsets of ordinal types. Sets are unordered groups of elements, which can be manipulated with the classic set operations. Subranges are ordered and are used with the usual operators. See Section 11.3.3.12 and Section 11.3.3.13.
Ada subtypes of ordinal types are represented in the same manner as Pascal subranges.