aboutsummaryrefslogtreecommitdiff
path: root/contrib/gcc/cp/gxxint.texi
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/gxxint.texi')
-rw-r--r--contrib/gcc/cp/gxxint.texi1585
1 files changed, 1585 insertions, 0 deletions
diff --git a/contrib/gcc/cp/gxxint.texi b/contrib/gcc/cp/gxxint.texi
new file mode 100644
index 000000000000..015a33c002cc
--- /dev/null
+++ b/contrib/gcc/cp/gxxint.texi
@@ -0,0 +1,1585 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename g++int.info
+@settitle G++ internals
+@setchapternewpage odd
+@c %**end of header
+
+@node Top, Limitations of g++, (dir), (dir)
+@chapter Internal Architecture of the Compiler
+
+This is meant to describe the C++ front-end for gcc in detail.
+Questions and comments to mrs@@cygnus.com.
+
+@menu
+* Limitations of g++::
+* Routines::
+* Implementation Specifics::
+* Glossary::
+* Macros::
+* Typical Behavior::
+* Coding Conventions::
+* Templates::
+* Access Control::
+* Error Reporting::
+* Parser::
+* Copying Objects::
+* Exception Handling::
+* Free Store::
+* Concept Index::
+@end menu
+
+@node Limitations of g++, Routines, Top, Top
+@section Limitations of g++
+
+@itemize @bullet
+@item
+Limitations on input source code: 240 nesting levels with the parser
+stacksize (YYSTACKSIZE) set to 500 (the default), and requires around
+16.4k swap space per nesting level. The parser needs about 2.09 *
+number of nesting levels worth of stackspace.
+
+@cindex pushdecl_class_level
+@item
+I suspect there are other uses of pushdecl_class_level that do not call
+set_identifier_type_value in tandem with the call to
+pushdecl_class_level. It would seem to be an omission.
+
+@cindex access checking
+@item
+Access checking is unimplemented for nested types.
+
+@cindex @code{volatile}
+@item
+@code{volatile} is not implemented in general.
+
+@cindex pointers to members
+@item
+Pointers to members are only minimally supported, and there are places
+where the grammar doesn't even properly accept them yet.
+
+@cindex multiple inheritance
+@item
+@code{this} will be wrong in virtual members functions defined in a
+virtual base class, when they are overridden in a derived class, when
+called via a non-left most object.
+
+An example would be:
+
+@example
+extern "C" int printf(const char*, ...);
+struct A @{ virtual void f() @{ @} @};
+struct B : virtual A @{ int b; B() : b(0) @{@} void f() @{ b++; @} @};
+struct C : B @{@};
+struct D : B @{@};
+struct E : C, D @{@};
+int main()
+@{
+ E e;
+ C& c = e; D& d = e;
+ c.f(); d.f();
+ printf ("C::b = %d, D::b = %d\n", e.C::b, e.D::b);
+ return 0;
+@}
+@end example
+
+This will print out 2, 0, instead of 1,1.
+
+@end itemize
+
+@node Routines, Implementation Specifics, Limitations of g++, Top
+@section Routines
+
+This section describes some of the routines used in the C++ front-end.
+
+@code{build_vtable} and @code{prepare_fresh_vtable} is used only within
+the @file{cp-class.c} file, and only in @code{finish_struct} and
+@code{modify_vtable_entries}.
+
+@code{build_vtable}, @code{prepare_fresh_vtable}, and
+@code{finish_struct} are the only routines that set @code{DECL_VPARENT}.
+
+@code{finish_struct} can steal the virtual function table from parents,
+this prohibits related_vslot from working. When finish_struct steals,
+we know that
+
+@example
+get_binfo (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (t)), t, 0)
+@end example
+
+@noindent
+will get the related binfo.
+
+@code{layout_basetypes} does something with the VIRTUALS.
+
+Supposedly (according to Tiemann) most of the breadth first searching
+done, like in @code{get_base_distance} and in @code{get_binfo} was not
+because of any design decision. I have since found out the at least one
+part of the compiler needs the notion of depth first binfo searching, I
+am going to try and convert the whole thing, it should just work. The
+term left-most refers to the depth first left-most node. It uses
+@code{MAIN_VARIANT == type} as the condition to get left-most, because
+the things that have @code{BINFO_OFFSET}s of zero are shared and will
+have themselves as their own @code{MAIN_VARIANT}s. The non-shared right
+ones, are copies of the left-most one, hence if it is its own
+@code{MAIN_VARIANT}, we know it IS a left-most one, if it is not, it is
+a non-left-most one.
+
+@code{get_base_distance}'s path and distance matters in its use in:
+
+@itemize @bullet
+@item
+@code{prepare_fresh_vtable} (the code is probably wrong)
+@item
+@code{init_vfields} Depends upon distance probably in a safe way,
+build_offset_ref might use partial paths to do further lookups,
+hack_identifier is probably not properly checking access.
+
+@item
+@code{get_first_matching_virtual} probably should check for
+@code{get_base_distance} returning -2.
+
+@item
+@code{resolve_offset_ref} should be called in a more deterministic
+manner. Right now, it is called in some random contexts, like for
+arguments at @code{build_method_call} time, @code{default_conversion}
+time, @code{convert_arguments} time, @code{build_unary_op} time,
+@code{build_c_cast} time, @code{build_modify_expr} time,
+@code{convert_for_assignment} time, and
+@code{convert_for_initialization} time.
+
+But, there are still more contexts it needs to be called in, one was the
+ever simple:
+
+@example
+if (obj.*pmi != 7)
+ @dots{}
+@end example
+
+Seems that the problems were due to the fact that @code{TREE_TYPE} of
+the @code{OFFSET_REF} was not a @code{OFFSET_TYPE}, but rather the type
+of the referent (like @code{INTEGER_TYPE}). This problem was fixed by
+changing @code{default_conversion} to check @code{TREE_CODE (x)},
+instead of only checking @code{TREE_CODE (TREE_TYPE (x))} to see if it
+was @code{OFFSET_TYPE}.
+
+@end itemize
+
+@node Implementation Specifics, Glossary, Routines, Top
+@section Implementation Specifics
+
+@itemize @bullet
+@item Explicit Initialization
+
+The global list @code{current_member_init_list} contains the list of
+mem-initializers specified in a constructor declaration. For example:
+
+@example
+foo::foo() : a(1), b(2) @{@}
+@end example
+
+@noindent
+will initialize @samp{a} with 1 and @samp{b} with 2.
+@code{expand_member_init} places each initialization (a with 1) on the
+global list. Then, when the fndecl is being processed,
+@code{emit_base_init} runs down the list, initializing them. It used to
+be the case that g++ first ran down @code{current_member_init_list},
+then ran down the list of members initializing the ones that weren't
+explicitly initialized. Things were rewritten to perform the
+initializations in order of declaration in the class. So, for the above
+example, @samp{a} and @samp{b} will be initialized in the order that
+they were declared:
+
+@example
+class foo @{ public: int b; int a; foo (); @};
+@end example
+
+@noindent
+Thus, @samp{b} will be initialized with 2 first, then @samp{a} will be
+initialized with 1, regardless of how they're listed in the mem-initializer.
+
+@item Argument Matching
+
+In early 1993, the argument matching scheme in @sc{gnu} C++ changed
+significantly. The original code was completely replaced with a new
+method that will, hopefully, be easier to understand and make fixing
+specific cases much easier.
+
+The @samp{-fansi-overloading} option is used to enable the new code; at
+some point in the future, it will become the default behavior of the
+compiler.
+
+The file @file{cp-call.c} contains all of the new work, in the functions
+@code{rank_for_overload}, @code{compute_harshness},
+@code{compute_conversion_costs}, and @code{ideal_candidate}.
+
+Instead of using obscure numerical values, the quality of an argument
+match is now represented by clear, individual codes. The new data
+structure @code{struct harshness} (it used to be an @code{unsigned}
+number) contains:
+
+@enumerate a
+@item the @samp{code} field, to signify what was involved in matching two
+arguments;
+@item the @samp{distance} field, used in situations where inheritance
+decides which function should be called (one is ``closer'' than
+another);
+@item and the @samp{int_penalty} field, used by some codes as a tie-breaker.
+@end enumerate
+
+The @samp{code} field is a number with a given bit set for each type of
+code, OR'd together. The new codes are:
+
+@itemize @bullet
+@item @code{EVIL_CODE}
+The argument was not a permissible match.
+
+@item @code{CONST_CODE}
+Currently, this is only used by @code{compute_conversion_costs}, to
+distinguish when a non-@code{const} member function is called from a
+@code{const} member function.
+
+@item @code{ELLIPSIS_CODE}
+A match against an ellipsis @samp{...} is considered worse than all others.
+
+@item @code{USER_CODE}
+Used for a match involving a user-defined conversion.
+
+@item @code{STD_CODE}
+A match involving a standard conversion.
+
+@item @code{PROMO_CODE}
+A match involving an integral promotion. For these, the
+@code{int_penalty} field is used to handle the ARM's rule (XXX cite)
+that a smaller @code{unsigned} type should promote to a @code{int}, not
+to an @code{unsigned int}.
+
+@item @code{QUAL_CODE}
+Used to mark use of qualifiers like @code{const} and @code{volatile}.
+
+@item @code{TRIVIAL_CODE}
+Used for trivial conversions. The @samp{int_penalty} field is used by
+@code{convert_harshness} to communicate further penalty information back
+to @code{build_overload_call_real} when deciding which function should
+be call.
+@end itemize
+
+The functions @code{convert_to_aggr} and @code{build_method_call} use
+@code{compute_conversion_costs} to rate each argument's suitability for
+a given candidate function (that's how we get the list of candidates for
+@code{ideal_candidate}).
+
+@end itemize
+
+@node Glossary, Macros, Implementation Specifics, Top
+@section Glossary
+
+@table @r
+@item binfo
+The main data structure in the compiler used to represent the
+inheritance relationships between classes. The data in the binfo can be
+accessed by the BINFO_ accessor macros.
+
+@item vtable
+@itemx virtual function table
+
+The virtual function table holds information used in virtual function
+dispatching. In the compiler, they are usually referred to as vtables,
+or vtbls. The first index is not used in the normal way, I believe it
+is probably used for the virtual destructor.
+
+@item vfield
+
+vfields can be thought of as the base information needed to build
+vtables. For every vtable that exists for a class, there is a vfield.
+See also vtable and virtual function table pointer. When a type is used
+as a base class to another type, the virtual function table for the
+derived class can be based upon the vtable for the base class, just
+extended to include the additional virtual methods declared in the
+derived class. The virtual function table from a virtual base class is
+never reused in a derived class. @code{is_normal} depends upon this.
+
+@item virtual function table pointer
+
+These are @code{FIELD_DECL}s that are pointer types that point to
+vtables. See also vtable and vfield.
+@end table
+
+@node Macros, Typical Behavior, Glossary, Top
+@section Macros
+
+This section describes some of the macros used on trees. The list
+should be alphabetical. Eventually all macros should be documented
+here. There are some postscript drawings that can be used to better
+understand from of the more complex data structures, contact Mike Stump
+(@code{mrs@@cygnus.com}) for information about them.
+
+@table @code
+@item BINFO_BASETYPES
+A vector of additional binfos for the types inherited by this basetype.
+The binfos are fully unshared (except for virtual bases, in which
+case the binfo structure is shared).
+
+ If this basetype describes type D as inherited in C,
+ and if the basetypes of D are E anf F,
+ then this vector contains binfos for inheritance of E and F by C.
+
+Has values of:
+
+ TREE_VECs
+
+
+@item BINFO_INHERITANCE_CHAIN
+Temporarily used to represent specific inheritances. It usually points
+to the binfo associated with the lesser derived type, but it can be
+reversed by reverse_path. For example:
+
+@example
+ Z ZbY least derived
+ |
+ Y YbX
+ |
+ X Xb most derived
+
+TYPE_BINFO (X) == Xb
+BINFO_INHERITANCE_CHAIN (Xb) == YbX
+BINFO_INHERITANCE_CHAIN (Yb) == ZbY
+BINFO_INHERITANCE_CHAIN (Zb) == 0
+@end example
+
+Not sure is the above is really true, get_base_distance has is point
+towards the most derived type, opposite from above.
+
+Set by build_vbase_path, recursive_bounded_basetype_p,
+get_base_distance, lookup_field, lookup_fnfields, and reverse_path.
+
+What things can this be used on:
+
+ TREE_VECs that are binfos
+
+
+@item BINFO_OFFSET
+The offset where this basetype appears in its containing type.
+BINFO_OFFSET slot holds the offset (in bytes) from the base of the
+complete object to the base of the part of the object that is allocated
+on behalf of this `type'. This is always 0 except when there is
+multiple inheritance.
+
+Used on TREE_VEC_ELTs of the binfos BINFO_BASETYPES (...) for example.
+
+
+@item BINFO_VIRTUALS
+A unique list of functions for the virtual function table. See also
+TYPE_BINFO_VIRTUALS.
+
+What things can this be used on:
+
+ TREE_VECs that are binfos
+
+
+@item BINFO_VTABLE
+Used to find the VAR_DECL that is the virtual function table associated
+with this binfo. See also TYPE_BINFO_VTABLE. To get the virtual
+function table pointer, see CLASSTYPE_VFIELD.
+
+What things can this be used on:
+
+ TREE_VECs that are binfos
+
+Has values of:
+
+ VAR_DECLs that are virtual function tables
+
+
+@item BLOCK_SUPERCONTEXT
+In the outermost scope of each function, it points to the FUNCTION_DECL
+node. It aids in better DWARF support of inline functions.
+
+
+@item CLASSTYPE_TAGS
+CLASSTYPE_TAGS is a linked (via TREE_CHAIN) list of member classes of a
+class. TREE_PURPOSE is the name, TREE_VALUE is the type (pushclass scans
+these and calls pushtag on them.)
+
+finish_struct scans these to produce TYPE_DECLs to add to the
+TYPE_FIELDS of the type.
+
+It is expected that name found in the TREE_PURPOSE slot is unique,
+resolve_scope_to_name is one such place that depends upon this
+uniqueness.
+
+
+@item CLASSTYPE_METHOD_VEC
+The following is true after finish_struct has been called (on the
+class?) but not before. Before finish_struct is called, things are
+different to some extent. Contains a TREE_VEC of methods of the class.
+The TREE_VEC_LENGTH is the number of differently named methods plus one
+for the 0th entry. The 0th entry is always allocated, and reserved for
+ctors and dtors. If there are none, TREE_VEC_ELT(N,0) == NULL_TREE.
+Each entry of the TREE_VEC is a FUNCTION_DECL. For each FUNCTION_DECL,
+there is a DECL_CHAIN slot. If the FUNCTION_DECL is the last one with a
+given name, the DECL_CHAIN slot is NULL_TREE. Otherwise it is the next
+method that has the same name (but a different signature). It would
+seem that it is not true that because the DECL_CHAIN slot is used in
+this way, we cannot call pushdecl to put the method in the global scope
+(cause that would overwrite the TREE_CHAIN slot), because they use
+different _CHAINs. finish_struct_methods setups up one version of the
+TREE_CHAIN slots on the FUNCTION_DECLs.
+
+friends are kept in TREE_LISTs, so that there's no need to use their
+TREE_CHAIN slot for anything.
+
+Has values of:
+
+ TREE_VECs
+
+
+@item CLASSTYPE_VFIELD
+Seems to be in the process of being renamed TYPE_VFIELD. Use on types
+to get the main virtual function table pointer. To get the virtual
+function table use BINFO_VTABLE (TYPE_BINFO ()).
+
+Has values of:
+
+ FIELD_DECLs that are virtual function table pointers
+
+What things can this be used on:
+
+ RECORD_TYPEs
+
+
+@item DECL_CLASS_CONTEXT
+Identifies the context that the _DECL was found in. For virtual function
+tables, it points to the type associated with the virtual function
+table. See also DECL_CONTEXT, DECL_FIELD_CONTEXT and DECL_FCONTEXT.
+
+The difference between this and DECL_CONTEXT, is that for virtuals
+functions like:
+
+@example
+struct A
+@{
+ virtual int f ();
+@};
+
+struct B : A
+@{
+ int f ();
+@};
+
+DECL_CONTEXT (A::f) == A
+DECL_CLASS_CONTEXT (A::f) == A
+
+DECL_CONTEXT (B::f) == A
+DECL_CLASS_CONTEXT (B::f) == B
+@end example
+
+Has values of:
+
+ RECORD_TYPEs, or UNION_TYPEs
+
+What things can this be used on:
+
+ TYPE_DECLs, _DECLs
+
+
+@item DECL_CONTEXT
+Identifies the context that the _DECL was found in. Can be used on
+virtual function tables to find the type associated with the virtual
+function table, but since they are FIELD_DECLs, DECL_FIELD_CONTEXT is a
+better access method. Internally the same as DECL_FIELD_CONTEXT, so
+don't us both. See also DECL_FIELD_CONTEXT, DECL_FCONTEXT and
+DECL_CLASS_CONTEXT.
+
+Has values of:
+
+ RECORD_TYPEs
+
+
+What things can this be used on:
+
+@display
+VAR_DECLs that are virtual function tables
+_DECLs
+@end display
+
+
+@item DECL_FIELD_CONTEXT
+Identifies the context that the FIELD_DECL was found in. Internally the
+same as DECL_CONTEXT, so don't us both. See also DECL_CONTEXT,
+DECL_FCONTEXT and DECL_CLASS_CONTEXT.
+
+Has values of:
+
+ RECORD_TYPEs
+
+What things can this be used on:
+
+@display
+FIELD_DECLs that are virtual function pointers
+FIELD_DECLs
+@end display
+
+
+@item DECL_NESTED_TYPENAME
+Holds the fully qualified type name. Example, Base::Derived.
+
+Has values of:
+
+ IDENTIFIER_NODEs
+
+What things can this be used on:
+
+ TYPE_DECLs
+
+
+@item DECL_NAME
+
+Has values of:
+
+@display
+0 for things that don't have names
+IDENTIFIER_NODEs for TYPE_DECLs
+@end display
+
+@item DECL_IGNORED_P
+A bit that can be set to inform the debug information output routines in
+the back-end that a certain _DECL node should be totally ignored.
+
+Used in cases where it is known that the debugging information will be
+output in another file, or where a sub-type is known not to be needed
+because the enclosing type is not needed.
+
+A compiler constructed virtual destructor in derived classes that do not
+define an explicit destructor that was defined explicit in a base class
+has this bit set as well. Also used on __FUNCTION__ and
+__PRETTY_FUNCTION__ to mark they are ``compiler generated.'' c-decl and
+c-lex.c both want DECL_IGNORED_P set for ``internally generated vars,''
+and ``user-invisible variable.''
+
+Functions built by the C++ front-end such as default destructors,
+virtual destructors and default constructors want to be marked that
+they are compiler generated, but unsure why.
+
+Currently, it is used in an absolute way in the C++ front-end, as an
+optimization, to tell the debug information output routines to not
+generate debugging information that will be output by another separately
+compiled file.
+
+
+@item DECL_VIRTUAL_P
+A flag used on FIELD_DECLs and VAR_DECLs. (Documentation in tree.h is
+wrong.) Used in VAR_DECLs to indicate that the variable is a vtable.
+It is also used in FIELD_DECLs for vtable pointers.
+
+What things can this be used on:
+
+ FIELD_DECLs and VAR_DECLs
+
+
+@item DECL_VPARENT
+Used to point to the parent type of the vtable if there is one, else it
+is just the type associated with the vtable. Because of the sharing of
+virtual function tables that goes on, this slot is not very useful, and
+is in fact, not used in the compiler at all. It can be removed.
+
+What things can this be used on:
+
+ VAR_DECLs that are virtual function tables
+
+Has values of:
+
+ RECORD_TYPEs maybe UNION_TYPEs
+
+
+@item DECL_FCONTEXT
+Used to find the first baseclass in which this FIELD_DECL is defined.
+See also DECL_CONTEXT, DECL_FIELD_CONTEXT and DECL_CLASS_CONTEXT.
+
+How it is used:
+
+ Used when writing out debugging information about vfield and
+ vbase decls.
+
+What things can this be used on:
+
+ FIELD_DECLs that are virtual function pointers
+ FIELD_DECLs
+
+
+@item DECL_REFERENCE_SLOT
+Used to hold the initialize for the reference.
+
+What things can this be used on:
+
+ PARM_DECLs and VAR_DECLs that have a reference type
+
+
+@item DECL_VINDEX
+Used for FUNCTION_DECLs in two different ways. Before the structure
+containing the FUNCTION_DECL is laid out, DECL_VINDEX may point to a
+FUNCTION_DECL in a base class which is the FUNCTION_DECL which this
+FUNCTION_DECL will replace as a virtual function. When the class is
+laid out, this pointer is changed to an INTEGER_CST node which is
+suitable to find an index into the virtual function table. See
+get_vtable_entry as to how one can find the right index into the virtual
+function table. The first index 0, of a virtual function table it not
+used in the normal way, so the first real index is 1.
+
+DECL_VINDEX may be a TREE_LIST, that would seem to be a list of
+overridden FUNCTION_DECLs. add_virtual_function has code to deal with
+this when it uses the variable base_fndecl_list, but it would seem that
+somehow, it is possible for the TREE_LIST to pursist until method_call,
+and it should not.
+
+
+What things can this be used on:
+
+ FUNCTION_DECLs
+
+
+@item DECL_SOURCE_FILE
+Identifies what source file a particular declaration was found in.
+
+Has values of:
+
+ "<built-in>" on TYPE_DECLs to mean the typedef is built in
+
+
+@item DECL_SOURCE_LINE
+Identifies what source line number in the source file the declaration
+was found at.
+
+Has values of:
+
+@display
+0 for an undefined label
+
+0 for TYPE_DECLs that are internally generated
+
+0 for FUNCTION_DECLs for functions generated by the compiler
+ (not yet, but should be)
+
+0 for ``magic'' arguments to functions, that the user has no
+ control over
+@end display
+
+
+@item TREE_USED
+
+Has values of:
+
+ 0 for unused labels
+
+
+@item TREE_ADDRESSABLE
+A flag that is set for any type that has a constructor.
+
+
+@item TREE_COMPLEXITY
+They seem a kludge way to track recursion, poping, and pushing. They only
+appear in cp-decl.c and cp-decl2.c, so the are a good candidate for
+proper fixing, and removal.
+
+
+@item TREE_PRIVATE
+Set for FIELD_DECLs by finish_struct. But not uniformly set.
+
+The following routines do something with PRIVATE access:
+build_method_call, alter_access, finish_struct_methods,
+finish_struct, convert_to_aggr, CWriteLanguageDecl, CWriteLanguageType,
+CWriteUseObject, compute_access, lookup_field, dfs_pushdecl,
+GNU_xref_member, dbxout_type_fields, dbxout_type_method_1
+
+
+@item TREE_PROTECTED
+The following routines do something with PROTECTED access:
+build_method_call, alter_access, finish_struct, convert_to_aggr,
+CWriteLanguageDecl, CWriteLanguageType, CWriteUseObject,
+compute_access, lookup_field, GNU_xref_member, dbxout_type_fields,
+dbxout_type_method_1
+
+
+@item TYPE_BINFO
+Used to get the binfo for the type.
+
+Has values of:
+
+ TREE_VECs that are binfos
+
+What things can this be used on:
+
+ RECORD_TYPEs
+
+
+@item TYPE_BINFO_BASETYPES
+See also BINFO_BASETYPES.
+
+@item TYPE_BINFO_VIRTUALS
+A unique list of functions for the virtual function table. See also
+BINFO_VIRTUALS.
+
+What things can this be used on:
+
+ RECORD_TYPEs
+
+
+@item TYPE_BINFO_VTABLE
+Points to the virtual function table associated with the given type.
+See also BINFO_VTABLE.
+
+What things can this be used on:
+
+ RECORD_TYPEs
+
+Has values of:
+
+ VAR_DECLs that are virtual function tables
+
+
+@item TYPE_NAME
+Names the type.
+
+Has values of:
+
+@display
+0 for things that don't have names.
+should be IDENTIFIER_NODE for RECORD_TYPEs UNION_TYPEs and
+ ENUM_TYPEs.
+TYPE_DECL for RECORD_TYPEs, UNION_TYPEs and ENUM_TYPEs, but
+ shouldn't be.
+TYPE_DECL for typedefs, unsure why.
+@end display
+
+What things can one use this on:
+
+@display
+TYPE_DECLs
+RECORD_TYPEs
+UNION_TYPEs
+ENUM_TYPEs
+@end display
+
+History:
+
+ It currently points to the TYPE_DECL for RECORD_TYPEs,
+ UNION_TYPEs and ENUM_TYPEs, but it should be history soon.
+
+
+@item TYPE_METHODS
+Synonym for @code{CLASSTYPE_METHOD_VEC}. Chained together with
+@code{TREE_CHAIN}. @file{dbxout.c} uses this to get at the methods of a
+class.
+
+
+@item TYPE_DECL
+Used to represent typedefs, and used to represent bindings layers.
+
+Components:
+
+ DECL_NAME is the name of the typedef. For example, foo would
+ be found in the DECL_NAME slot when @code{typedef int foo;} is
+ seen.
+
+ DECL_SOURCE_LINE identifies what source line number in the
+ source file the declaration was found at. A value of 0
+ indicates that this TYPE_DECL is just an internal binding layer
+ marker, and does not correspond to a user supplied typedef.
+
+ DECL_SOURCE_FILE
+
+@item TYPE_FIELDS
+A linked list (via @code{TREE_CHAIN}) of member types of a class. The
+list can contain @code{TYPE_DECL}s, but there can also be other things
+in the list apparently. See also @code{CLASSTYPE_TAGS}.
+
+
+@item TYPE_VIRTUAL_P
+A flag used on a @code{FIELD_DECL} or a @code{VAR_DECL}, indicates it is
+a virtual function table or a pointer to one. When used on a
+@code{FUNCTION_DECL}, indicates that it is a virtual function. When
+used on an @code{IDENTIFIER_NODE}, indicates that a function with this
+same name exists and has been declared virtual.
+
+When used on types, it indicates that the type has virtual functions, or
+is derived from one that does.
+
+Not sure if the above about virtual function tables is still true. See
+also info on @code{DECL_VIRTUAL_P}.
+
+What things can this be used on:
+
+ FIELD_DECLs, VAR_DECLs, FUNCTION_DECLs, IDENTIFIER_NODEs
+
+
+@item VF_BASETYPE_VALUE
+Get the associated type from the binfo that caused the given vfield to
+exist. This is the least derived class (the most parent class) that
+needed a virtual function table. It is probably the case that all uses
+of this field are misguided, but they need to be examined on a
+case-by-case basis. See history for more information on why the
+previous statement was made.
+
+Set at @code{finish_base_struct} time.
+
+What things can this be used on:
+
+ TREE_LISTs that are vfields
+
+History:
+
+ This field was used to determine if a virtual function table's
+ slot should be filled in with a certain virtual function, by
+ checking to see if the type returned by VF_BASETYPE_VALUE was a
+ parent of the context in which the old virtual function existed.
+ This incorrectly assumes that a given type _could_ not appear as
+ a parent twice in a given inheritance lattice. For single
+ inheritance, this would in fact work, because a type could not
+ possibly appear more than once in an inheritance lattice, but
+ with multiple inheritance, a type can appear more than once.
+
+
+@item VF_BINFO_VALUE
+Identifies the binfo that caused this vfield to exist. If this vfield
+is from the first direct base class that has a virtual function table,
+then VF_BINFO_VALUE is NULL_TREE, otherwise it will be the binfo of the
+direct base where the vfield came from. Can use @code{TREE_VIA_VIRTUAL}
+on result to find out if it is a virtual base class. Related to the
+binfo found by
+
+@example
+get_binfo (VF_BASETYPE_VALUE (vfield), t, 0)
+@end example
+
+@noindent
+where @samp{t} is the type that has the given vfield.
+
+@example
+get_binfo (VF_BASETYPE_VALUE (vfield), t, 0)
+@end example
+
+@noindent
+will return the binfo for the the given vfield.
+
+May or may not be set at @code{modify_vtable_entries} time. Set at
+@code{finish_base_struct} time.
+
+What things can this be used on:
+
+ TREE_LISTs that are vfields
+
+
+@item VF_DERIVED_VALUE
+Identifies the type of the most derived class of the vfield, excluding
+the the class this vfield is for.
+
+Set at @code{finish_base_struct} time.
+
+What things can this be used on:
+
+ TREE_LISTs that are vfields
+
+
+@item VF_NORMAL_VALUE
+Identifies the type of the most derived class of the vfield, including
+the class this vfield is for.
+
+Set at @code{finish_base_struct} time.
+
+What things can this be used on:
+
+ TREE_LISTs that are vfields
+
+
+@item WRITABLE_VTABLES
+This is a option that can be defined when building the compiler, that
+will cause the compiler to output vtables into the data segment so that
+the vtables maybe written. This is undefined by default, because
+normally the vtables should be unwritable. People that implement object
+I/O facilities may, or people that want to change the dynamic type of
+objects may want to have the vtables writable. Another way of achieving
+this would be to make a copy of the vtable into writable memory, but the
+drawback there is that that method only changes the type for one object.
+
+@end table
+
+@node Typical Behavior, Coding Conventions, Macros, Top
+@section Typical Behavior
+
+@cindex parse errors
+
+Whenever seemingly normal code fails with errors like
+@code{syntax error at `\@{'}, it's highly likely that grokdeclarator is
+returning a NULL_TREE for whatever reason.
+
+@node Coding Conventions, Templates, Typical Behavior, Top
+@section Coding Conventions
+
+It should never be that case that trees are modified in-place by the
+back-end, @emph{unless} it is guaranteed that the semantics are the same
+no matter how shared the tree structure is. @file{fold-const.c} still
+has some cases where this is not true, but rms hypothesizes that this
+will never be a problem.
+
+@node Templates, Access Control, Coding Conventions, Top
+@section Templates
+
+A template is represented by a @code{TEMPLATE_DECL}. The specific
+fields used are:
+
+@table @code
+@item DECL_TEMPLATE_RESULT
+The generic decl on which instantiations are based. This looks just
+like any other decl.
+
+@item DECL_TEMPLATE_PARMS
+The parameters to this template.
+@end table
+
+The generic decl is parsed as much like any other decl as possible,
+given the parameterization. The template decl is not built up until the
+generic decl has been completed. For template classes, a template decl
+is generated for each member function and static data member, as well.
+
+Template members of template classes are represented by a TEMPLATE_DECL
+for the class' parameters around another TEMPLATE_DECL for the member's
+parameters.
+
+All declarations that are instantiations or specializations of templates
+refer to their template and parameters through DECL_TEMPLATE_INFO.
+
+How should I handle parsing member functions with the proper param
+decls? Set them up again or try to use the same ones? Currently we do
+the former. We can probably do this without any extra machinery in
+store_pending_inline, by deducing the parameters from the decl in
+do_pending_inlines. PRE_PARSED_TEMPLATE_DECL?
+
+If a base is a parm, we can't check anything about it. If a base is not
+a parm, we need to check it for name binding. Do finish_base_struct if
+no bases are parameterized (only if none, including indirect, are
+parms). Nah, don't bother trying to do any of this until instantiation
+-- we only need to do name binding in advance.
+
+Always set up method vec and fields, inc. synthesized methods. Really?
+We can't know the types of the copy folks, or whether we need a
+destructor, or can have a default ctor, until we know our bases and
+fields. Otherwise, we can assume and fix ourselves later. Hopefully.
+
+@node Access Control, Error Reporting, Templates, Top
+@section Access Control
+The function compute_access returns one of three values:
+
+@table @code
+@item access_public
+means that the field can be accessed by the current lexical scope.
+
+@item access_protected
+means that the field cannot be accessed by the current lexical scope
+because it is protected.
+
+@item access_private
+means that the field cannot be accessed by the current lexical scope
+because it is private.
+@end table
+
+DECL_ACCESS is used for access declarations; alter_access creates a list
+of types and accesses for a given decl.
+
+Formerly, DECL_@{PUBLIC,PROTECTED,PRIVATE@} corresponded to the return
+codes of compute_access and were used as a cache for compute_access.
+Now they are not used at all.
+
+TREE_PROTECTED and TREE_PRIVATE are used to record the access levels
+granted by the containing class. BEWARE: TREE_PUBLIC means something
+completely unrelated to access control!
+
+@node Error Reporting, Parser, Access Control, Top
+@section Error Reporting
+
+The C++ front-end uses a call-back mechanism to allow functions to print
+out reasonable strings for types and functions without putting extra
+logic in the functions where errors are found. The interface is through
+the @code{cp_error} function (or @code{cp_warning}, etc.). The
+syntax is exactly like that of @code{error}, except that a few more
+conversions are supported:
+
+@itemize @bullet
+@item
+%C indicates a value of `enum tree_code'.
+@item
+%D indicates a *_DECL node.
+@item
+%E indicates a *_EXPR node.
+@item
+%L indicates a value of `enum languages'.
+@item
+%P indicates the name of a parameter (i.e. "this", "1", "2", ...)
+@item
+%T indicates a *_TYPE node.
+@item
+%O indicates the name of an operator (MODIFY_EXPR -> "operator =").
+
+@end itemize
+
+There is some overlap between these; for instance, any of the node
+options can be used for printing an identifier (though only @code{%D}
+tries to decipher function names).
+
+For a more verbose message (@code{class foo} as opposed to just @code{foo},
+including the return type for functions), use @code{%#c}.
+To have the line number on the error message indicate the line of the
+DECL, use @code{cp_error_at} and its ilk; to indicate which argument you want,
+use @code{%+D}, or it will default to the first.
+
+@node Parser, Copying Objects, Error Reporting, Top
+@section Parser
+
+Some comments on the parser:
+
+The @code{after_type_declarator} / @code{notype_declarator} hack is
+necessary in order to allow redeclarations of @code{TYPENAME}s, for
+instance
+
+@example
+typedef int foo;
+class A @{
+ char *foo;
+@};
+@end example
+
+In the above, the first @code{foo} is parsed as a @code{notype_declarator},
+and the second as a @code{after_type_declarator}.
+
+Ambiguities:
+
+There are currently four reduce/reduce ambiguities in the parser. They are:
+
+1) Between @code{template_parm} and
+@code{named_class_head_sans_basetype}, for the tokens @code{aggr
+identifier}. This situation occurs in code looking like
+
+@example
+template <class T> class A @{ @};
+@end example
+
+It is ambiguous whether @code{class T} should be parsed as the
+declaration of a template type parameter named @code{T} or an unnamed
+constant parameter of type @code{class T}. Section 14.6, paragraph 3 of
+the January '94 working paper states that the first interpretation is
+the correct one. This ambiguity results in two reduce/reduce conflicts.
+
+2) Between @code{primary} and @code{type_id} for code like @samp{int()}
+in places where both can be accepted, such as the argument to
+@code{sizeof}. Section 8.1 of the pre-San Diego working paper specifies
+that these ambiguous constructs will be interpreted as @code{typename}s.
+This ambiguity results in six reduce/reduce conflicts between
+@samp{absdcl} and @samp{functional_cast}.
+
+3) Between @code{functional_cast} and
+@code{complex_direct_notype_declarator}, for various token strings.
+This situation occurs in code looking like
+
+@example
+int (*a);
+@end example
+
+This code is ambiguous; it could be a declaration of the variable
+@samp{a} as a pointer to @samp{int}, or it could be a functional cast of
+@samp{*a} to @samp{int}. Section 6.8 specifies that the former
+interpretation is correct. This ambiguity results in 7 reduce/reduce
+conflicts. Another aspect of this ambiguity is code like 'int (x[2]);',
+which is resolved at the '[' and accounts for 6 reduce/reduce conflicts
+between @samp{direct_notype_declarator} and
+@samp{primary}/@samp{overqualified_id}. Finally, there are 4 r/r
+conflicts between @samp{expr_or_declarator} and @samp{primary} over code
+like 'int (a);', which could probably be resolved but would also
+probably be more trouble than it's worth. In all, this situation
+accounts for 17 conflicts. Ack!
+
+The second case above is responsible for the failure to parse 'LinppFile
+ppfile (String (argv[1]), &outs, argc, argv);' (from Rogue Wave
+Math.h++) as an object declaration, and must be fixed so that it does
+not resolve until later.
+
+4) Indirectly between @code{after_type_declarator} and @code{parm}, for
+type names. This occurs in (as one example) code like
+
+@example
+typedef int foo, bar;
+class A @{
+ foo (bar);
+@};
+@end example
+
+What is @code{bar} inside the class definition? We currently interpret
+it as a @code{parm}, as does Cfront, but IBM xlC interprets it as an
+@code{after_type_declarator}. I believe that xlC is correct, in light
+of 7.1p2, which says "The longest sequence of @i{decl-specifiers} that
+could possibly be a type name is taken as the @i{decl-specifier-seq} of
+a @i{declaration}." However, it seems clear that this rule must be
+violated in the case of constructors. This ambiguity accounts for 8
+conflicts.
+
+Unlike the others, this ambiguity is not recognized by the Working Paper.
+
+@node Copying Objects, Exception Handling, Parser, Top
+@section Copying Objects
+
+The generated copy assignment operator in g++ does not currently do the
+right thing for multiple inheritance involving virtual bases; it just
+calls the copy assignment operators for its direct bases. What it
+should probably do is:
+
+1) Split up the copy assignment operator for all classes that have
+vbases into "copy my vbases" and "copy everything else" parts. Or do
+the trickiness that the constructors do to ensure that vbases don't get
+initialized by intermediate bases.
+
+2) Wander through the class lattice, find all vbases for which no
+intermediate base has a user-defined copy assignment operator, and call
+their "copy everything else" routines. If not all of my vbases satisfy
+this criterion, warn, because this may be surprising behavior.
+
+3) Call the "copy everything else" routine for my direct bases.
+
+If we only have one direct base, we can just foist everything off onto
+them.
+
+This issue is currently under discussion in the core reflector
+(2/28/94).
+
+@node Exception Handling, Free Store, Copying Objects, Top
+@section Exception Handling
+
+Note, exception handling in g++ is still under development.
+
+This section describes the mapping of C++ exceptions in the C++
+front-end, into the back-end exception handling framework.
+
+The basic mechanism of exception handling in the back-end is
+unwind-protect a la elisp. This is a general, robust, and language
+independent representation for exceptions.
+
+The C++ front-end exceptions are mapping into the unwind-protect
+semantics by the C++ front-end. The mapping is describe below.
+
+When -frtti is used, rtti is used to do exception object type checking,
+when it isn't used, the encoded name for the type of the object being
+thrown is used instead. All code that originates exceptions, even code
+that throws exceptions as a side effect, like dynamic casting, and all
+code that catches exceptions must be compiled with either -frtti, or
+-fno-rtti. It is not possible to mix rtti base exception handling
+objects with code that doesn't use rtti. The exceptions to this, are
+code that doesn't catch or throw exceptions, catch (...), and code that
+just rethrows an exception.
+
+Currently we use the normal mangling used in building functions names
+(int's are "i", const char * is PCc) to build the non-rtti base type
+descriptors for exception handling. These descriptors are just plain
+NULL terminated strings, and internally they are passed around as char
+*.
+
+In C++, all cleanups should be protected by exception regions. The
+region starts just after the reason why the cleanup is created has
+ended. For example, with an automatic variable, that has a constructor,
+it would be right after the constructor is run. The region ends just
+before the finalization is expanded. Since the backend may expand the
+cleanup multiple times along different paths, once for normal end of the
+region, once for non-local gotos, once for returns, etc, the backend
+must take special care to protect the finalization expansion, if the
+expansion is for any other reason than normal region end, and it is
+`inline' (it is inside the exception region). The backend can either
+choose to move them out of line, or it can created an exception region
+over the finalization to protect it, and in the handler associated with
+it, it would not run the finalization as it otherwise would have, but
+rather just rethrow to the outer handler, careful to skip the normal
+handler for the original region.
+
+In Ada, they will use the more runtime intensive approach of having
+fewer regions, but at the cost of additional work at run time, to keep a
+list of things that need cleanups. When a variable has finished
+construction, they add the cleanup to the list, when the come to the end
+of the lifetime of the variable, the run the list down. If the take a
+hit before the section finishes normally, they examine the list for
+actions to perform. I hope they add this logic into the back-end, as it
+would be nice to get that alternative approach in C++.
+
+On an rs6000, xlC stores exception objects on that stack, under the try
+block. When is unwinds down into a handler, the frame pointer is
+adjusted back to the normal value for the frame in which the handler
+resides, and the stack pointer is left unchanged from the time at which
+the object was thrown. This is so that there is always someplace for
+the exception object, and nothing can overwrite it, once we start
+throwing. The only bad part, is that the stack remains large.
+
+The below points out some things that work in g++'s exception handling.
+
+All completely constructed temps and local variables are cleaned up in
+all unwinded scopes. Completely constructed parts of partially
+constructed objects are cleaned up. This includes partially built
+arrays. Exception specifications are now handled.
+
+The below points out some flaws in g++'s exception handling, as it now
+stands.
+
+Only exact type matching or reference matching of throw types works when
+-fno-rtti is used. Only works on a SPARC (like Suns), i386, arm and
+rs6000 machines. Partial support is in for all other machines, but a
+stack unwinder called __unwind_function has to be written, and added to
+libgcc2 for them. See below for details on __unwind_function. Don't
+expect exception handling to work right if you optimize, in fact the
+compiler will probably core dump. RTL_EXPRs for EH cond variables for
+&& and || exprs should probably be wrapped in UNSAVE_EXPRs, and
+RTL_EXPRs tweaked so that they can be unsaved, and the UNSAVE_EXPR code
+should be in the backend, or alternatively, UNSAVE_EXPR should be ripped
+out and exactly one finalization allowed to be expanded by the backend.
+I talked with kenner about this, and we have to allow multiple
+expansions.
+
+We only do pointer conversions on exception matching a la 15.3 p2 case
+3: `A handler with type T, const T, T&, or const T& is a match for a
+throw-expression with an object of type E if [3]T is a pointer type and
+E is a pointer type that can be converted to T by a standard pointer
+conversion (_conv.ptr_) not involving conversions to pointers to private
+or protected base classes.' when -frtti is given.
+
+We don't call delete on new expressions that die because the ctor threw
+an exception. See except/18 for a test case.
+
+15.2 para 13: The exception being handled should be rethrown if control
+reaches the end of a handler of the function-try-block of a constructor
+or destructor, right now, it is not.
+
+15.2 para 12: If a return statement appears in a handler of
+function-try-block of a constructor, the program is ill-formed, but this
+isn't diagnosed.
+
+15.2 para 11: If the handlers of a function-try-block contain a jump
+into the body of a constructor or destructor, the program is ill-formed,
+but this isn't diagnosed.
+
+15.2 para 9: Check that the fully constructed base classes and members
+of an object are destroyed before entering the handler of a
+function-try-block of a constructor or destructor for that object.
+
+build_exception_variant should sort the incoming list, so that it
+implements set compares, not exact list equality. Type smashing should
+smash exception specifications using set union.
+
+Thrown objects are usually allocated on the heap, in the usual way, but
+they are never deleted. They should be deleted by the catch clauses.
+If one runs out of heap space, throwing an object will probably never
+work. This could be relaxed some by passing an __in_chrg parameter to
+track who has control over the exception object. Thrown objects are not
+allocated on the heap when they are pointer to object types.
+
+When the backend returns a value, it can create new exception regions
+that need protecting. The new region should rethrow the object in
+context of the last associated cleanup that ran to completion.
+
+The structure of the code that is generated for C++ exception handling
+code is shown below:
+
+@example
+Ln: throw value;
+ copy value onto heap
+ jump throw (Ln, id, address of copy of value on heap)
+
+ try {
++Lstart: the start of the main EH region
+|... ...
++Lend: the end of the main EH region
+ } catch (T o) {
+ ...1
+ }
+Lresume:
+ nop used to make sure there is something before
+ the next region ends, if there is one
+... ...
+
+ jump Ldone
+[
+Lmainhandler: handler for the region Lstart-Lend
+ cleanup
+] zero or more, depending upon automatic vars with dtors
++Lpartial:
+| jump Lover
++Lhere:
+ rethrow (Lhere, same id, same obj);
+Lterm: handler for the region Lpartial-Lhere
+ call terminate
+Lover:
+[
+ [
+ call throw_type_match
+ if (eq) {
+ ] these lines disappear when there is no catch condition
++Lsregion2:
+| ...1
+| jump Lresume
+|Lhandler: handler for the region Lsregion2-Leregion2
+| rethrow (Lresume, same id, same obj);
++Leregion2
+ }
+] there are zero or more of these sections, depending upon how many
+ catch clauses there are
+----------------------------- expand_end_all_catch --------------------------
+ here we have fallen off the end of all catch
+ clauses, so we rethrow to outer
+ rethrow (Lresume, same id, same obj);
+----------------------------- expand_end_all_catch --------------------------
+[
+L1: maybe throw routine
+] depending upon if we have expanded it or not
+Ldone:
+ ret
+
+start_all_catch emits labels: Lresume,
+
+#end example
+
+The __unwind_function takes a pointer to the throw handler, and is
+expected to pop the stack frame that was built to call it, as well as
+the frame underneath and then jump to the throw handler. It must
+restore all registers to their proper values as well as all other
+machine state as determined by the context in which we are unwinding
+into. The way I normally start is to compile:
+
+ void *g;
+ foo(void* a) { g = a; }
+
+with -S, and change the thing that alters the PC (return, or ret
+usually) to not alter the PC, making sure to leave all other semantics
+(like adjusting the stack pointer, or frame pointers) in. After that,
+replicate the prologue once more at the end, again, changing the PC
+altering instructions, and finally, at the very end, jump to `g'.
+
+It takes about a week to write this routine, if someone wants to
+volunteer to write this routine for any architecture, exception support
+for that architecture will be added to g++. Please send in those code
+donations. One other thing that needs to be done, is to double check
+that __builtin_return_address (0) works.
+
+@subsection Specific Targets
+
+For the alpha, the __unwind_function will be something resembling:
+
+@example
+void
+__unwind_function(void *ptr)
+@{
+ /* First frame */
+ asm ("ldq $15, 8($30)"); /* get the saved frame ptr; 15 is fp, 30 is sp */
+ asm ("bis $15, $15, $30"); /* reload sp with the fp we found */
+
+ /* Second frame */
+ asm ("ldq $15, 8($30)"); /* fp */
+ asm ("bis $15, $15, $30"); /* reload sp with the fp we found */
+
+ /* Return */
+ asm ("ret $31, ($16), 1"); /* return to PTR, stored in a0 */
+@}
+@end example
+
+@noindent
+However, there are a few problems preventing it from working. First of
+all, the gcc-internal function @code{__builtin_return_address} needs to
+work given an argument of 0 for the alpha. As it stands as of August
+30th, 1995, the code for @code{BUILT_IN_RETURN_ADDRESS} in @file{expr.c}
+will definitely not work on the alpha. Instead, we need to define
+the macros @code{DYNAMIC_CHAIN_ADDRESS} (maybe),
+@code{RETURN_ADDR_IN_PREVIOUS_FRAME}, and definitely need a new
+definition for @code{RETURN_ADDR_RTX}.
+
+In addition (and more importantly), we need a way to reliably find the
+frame pointer on the alpha. The use of the value 8 above to restore the
+frame pointer (register 15) is incorrect. On many systems, the frame
+pointer is consistently offset to a specific point on the stack. On the
+alpha, however, the frame pointer is pushed last. First the return
+address is stored, then any other registers are saved (e.g., @code{s0}),
+and finally the frame pointer is put in place. So @code{fp} could have
+an offset of 8, but if the calling function saved any registers at all,
+they add to the offset.
+
+The only places the frame size is noted are with the @samp{.frame}
+directive, for use by the debugger and the OSF exception handling model
+(useless to us), and in the initial computation of the new value for
+@code{sp}, the stack pointer. For example, the function may start with:
+
+@example
+lda $30,-32($30)
+.frame $15,32,$26,0
+@end example
+
+@noindent
+The 32 above is exactly the value we need. With this, we can be sure
+that the frame pointer is stored 8 bytes less---in this case, at 24(sp)).
+The drawback is that there is no way that I (Brendan) have found to let
+us discover the size of a previous frame @emph{inside} the definition
+of @code{__unwind_function}.
+
+So to accomplish exception handling support on the alpha, we need two
+things: first, a way to figure out where the frame pointer was stored,
+and second, a functional @code{__builtin_return_address} implementation
+for except.c to be able to use it.
+
+@subsection Backend Exception Support
+
+The backend must be extended to fully support exceptions. Right now
+there are a few hooks into the alpha exception handling backend that
+resides in the C++ frontend from that backend that allows exception
+handling to work in g++. An exception region is a segment of generated
+code that has a handler associated with it. The exception regions are
+denoted in the generated code as address ranges denoted by a starting PC
+value and an ending PC value of the region. Some of the limitations
+with this scheme are:
+
+@itemize @bullet
+@item
+The backend replicates insns for such things as loop unrolling and
+function inlining. Right now, there are no hooks into the frontend's
+exception handling backend to handle the replication of insns. When
+replication happens, a new exception region descriptor needs to be
+generated for the new region.
+
+@item
+The backend expects to be able to rearrange code, for things like jump
+optimization. Any rearranging of the code needs have exception region
+descriptors updated appropriately.
+
+@item
+The backend can eliminate dead code. Any associated exception region
+descriptor that refers to fully contained code that has been eliminated
+should also be removed, although not doing this is harmless in terms of
+semantics.
+
+#end itemize
+
+The above is not meant to be exhaustive, but does include all things I
+have thought of so far. I am sure other limitations exist.
+
+Below are some notes on the migration of the exception handling code
+backend from the C++ frontend to the backend.
+
+NOTEs are to be used to denote the start of an exception region, and the
+end of the region. I presume that the interface used to generate these
+notes in the backend would be two functions, start_exception_region and
+end_exception_region (or something like that). The frontends are
+required to call them in pairs. When marking the end of a region, an
+argument can be passed to indicate the handler for the marked region.
+This can be passed in many ways, currently a tree is used. Another
+possibility would be insns for the handler, or a label that denotes a
+handler. I have a feeling insns might be the the best way to pass it.
+Semantics are, if an exception is thrown inside the region, control is
+transfered unconditionally to the handler. If control passes through
+the handler, then the backend is to rethrow the exception, in the
+context of the end of the original region. The handler is protected by
+the conventional mechanisms; it is the frontend's responsibility to
+protect the handler, if special semantics are required.
+
+This is a very low level view, and it would be nice is the backend
+supported a somewhat higher level view in addition to this view. This
+higher level could include source line number, name of the source file,
+name of the language that threw the exception and possibly the name of
+the exception. Kenner may want to rope you into doing more than just
+the basics required by C++. You will have to resolve this. He may want
+you to do support for non-local gotos, first scan for exception handler,
+if none is found, allow the debugger to be entered, without any cleanups
+being done. To do this, the backend would have to know the difference
+between a cleanup-rethrower, and a real handler, if would also have to
+have a way to know if a handler `matches' a thrown exception, and this
+is frontend specific.
+
+The UNSAVE_EXPR tree code has to be migrated to the backend. Exprs such
+as TARGET_EXPRs, WITH_CLEANUP_EXPRs, CALL_EXPRs and RTL_EXPRs have to be
+changed to support unsaving. This is meant to be a complete list.
+SAVE_EXPRs can be unsaved already. expand_decl_cleanup should be
+changed to unsave it's argument, if needed. See
+cp/tree.c:cp_expand_decl_cleanup, unsave_expr_now, unsave_expr, and
+cp/expr.c:cplus_expand_expr(case UNSAVE_EXPR:) for the UNSAVE_EXPR code.
+Now, as to why... because kenner already tripped over the exact same
+problem in Ada, we talked about it, he didn't like any of the solution,
+but yet, didn't like no solution either. He was willing to live with
+the drawbacks of this solution. The drawback is unsave_expr_now. It
+should have a callback into the frontend, to allow the unsaveing of
+frontend special codes. The callback goes in, inplace of the call to
+my_friendly_abort.
+
+The stack unwinder is one of the hardest parts to do. It is highly
+machine dependent. The form that kenner seems to like was a couple of
+macros, that would do the machine dependent grunt work. One preexisting
+function that might be of some use is __builtin_return_address (). One
+macro he seemed to want was __builtin_return_address, and the other
+would do the hard work of fixing up the registers, adjusting the stack
+pointer, frame pointer, arg pointer and so on.
+
+The eh archive (~mrs/eh) might be good reading for understanding the Ada
+perspective, and some of kenners mindset, and a detailed explanation
+(Message-Id: <9308301130.AA10543@vlsi1.ultra.nyu.edu>) of the concepts
+involved.
+
+Here is a guide to existing backend type code. It is all in
+cp/except.c. Check out do_unwind, and expand_builtin_throw for current
+code on how to figure out what handler matches an exception,
+emit_exception_table for code on emitting the PC range table that is
+built during compilation, expand_exception_blocks for code that emits
+all the handlers at the end of a functions, end_protect to mark the end
+of an exception region, start_protect to mark the start of an exception
+region, lang_interim_eh is the master hook used by the backend into the
+EH backend that now exists in the frontend, and expand_internal_throw to
+raise an exception.
+
+
+@node Free Store, Concept Index, Exception Handling, Top
+@section Free Store
+
+operator new [] adds a magic cookie to the beginning of arrays for which
+the number of elements will be needed by operator delete []. These are
+arrays of objects with destructors and arrays of objects that define
+operator delete [] with the optional size_t argument. This cookie can
+be examined from a program as follows:
+
+@example
+typedef unsigned long size_t;
+extern "C" int printf (const char *, ...);
+
+size_t nelts (void *p)
+@{
+ struct cookie @{
+ size_t nelts __attribute__ ((aligned (sizeof (double))));
+ @};
+
+ cookie *cp = (cookie *)p;
+ --cp;
+
+ return cp->nelts;
+@}
+
+struct A @{
+ ~A() @{ @}
+@};
+
+main()
+@{
+ A *ap = new A[3];
+ printf ("%ld\n", nelts (ap));
+@}
+@end example
+
+@section Linkage
+The linkage code in g++ is horribly twisted in order to meet two design goals:
+
+1) Avoid unnecessary emission of inlines and vtables.
+
+2) Support pedantic assemblers like the one in AIX.
+
+To meet the first goal, we defer emission of inlines and vtables until
+the end of the translation unit, where we can decide whether or not they
+are needed, and how to emit them if they are.
+
+@node Concept Index, , Free Store, Top
+@section Concept Index
+
+@printindex cp
+
+@bye