Go forward to Implementation Specifics.
Go backward to Limitations of g++.
Go up to Top.
Routines
========
This section describes some of the routines used in the C++
front-end.
`build_vtable' and `prepare_fresh_vtable' is used only within the
`cp-class.c' file, and only in `finish_struct' and
`modify_vtable_entries'.
`build_vtable', `prepare_fresh_vtable', and `finish_struct' are the
only routines that set `DECL_VPARENT'.
`finish_struct' can steal the virtual function table from parents,
this prohibits related_vslot from working. When finish_struct steals,
we know that
get_binfo (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (t)), t, 0)
will get the related binfo.
`layout_basetypes' does something with the VIRTUALS.
Supposedly (according to Tiemann) most of the breadth first searching
done, like in `get_base_distance' and in `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
`MAIN_VARIANT == type' as the condition to get left-most, because the
things that have `BINFO_OFFSET's of zero are shared and will have
themselves as their own `MAIN_VARIANT's. The non-shared right ones,
are copies of the left-most one, hence if it is its own `MAIN_VARIANT',
we know it IS a left-most one, if it is not, it is a non-left-most one.
`get_base_distance''s path and distance matters in its use in:
* `prepare_fresh_vtable' (the code is probably wrong)
* `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.
* `get_first_matching_virtual' probably should check for
`get_base_distance' returning -2.
* `resolve_offset_ref' should be called in a more deterministic
manner. Right now, it is called in some random contexts, like for
arguments at `build_method_call' time, `default_conversion' time,
`convert_arguments' time, `build_unary_op' time, `build_c_cast'
time, `build_modify_expr' time, `convert_for_assignment' time, and
`convert_for_initialization' time.
But, there are still more contexts it needs to be called in, one
was the ever simple:
if (obj.*pmi != 7)
...
Seems that the problems were due to the fact that `TREE_TYPE' of
the `OFFSET_REF' was not a `OFFSET_TYPE', but rather the type of
the referent (like `INTEGER_TYPE'). This problem was fixed by
changing `default_conversion' to check `TREE_CODE (x)', instead of
only checking `TREE_CODE (TREE_TYPE (x))' to see if it was
`OFFSET_TYPE'.