Commit 2ef16140 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (do_inline_function_hair): Remove.

	* cp-tree.h (do_inline_function_hair): Remove.
	* class.c (layout_class_type): New function, split out from
	finish_struct_1.
	(fixup_pending_inline): Likewise.
	(fixup_inline_methods): New function.
	* method.c (fixup_pending_inline): Remove.
	(do_inline_function_hair): Likewise.

	* decl.c (BOOL_TYPE_SIZE): Bools always have size `1' under the
	new ABI.

From-SVN: r31115
parent fee7654e
1999-12-28 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (do_inline_function_hair): Remove.
* class.c (layout_class_type): New function, split out from
finish_struct_1.
(fixup_pending_inline): Likewise.
(fixup_inline_methods): New function.
* method.c (fixup_pending_inline): Remove.
(do_inline_function_hair): Likewise.
* decl.c (BOOL_TYPE_SIZE): Bools always have size `1' under the
new ABI.
* cp-tree.h (lang_type): Replace abstract_virtuals with pure_virtuals.
(CLASSTYPE_ABSTRACT_VIRTUALS): Rename to ...
(CLASSTYPE_PURE_VIRTUALS): ... this.
......@@ -17,6 +28,7 @@
(build_vtbl_initializer): Likewise.
(override_one_vtable): Likewise.
(check_methods): Likewise.
* decl.c (duplicate_decls): Likewise.
(redeclaration_error_message): Likewise.
(lang_mark_tree): Likewise.
......
......@@ -134,6 +134,9 @@ static void remove_zero_width_bit_fields PROTO((tree));
static void check_bases PROTO((tree, int *, int *, int *));
static void check_bases_and_members PROTO((tree, int *));
static void create_vtable_ptr PROTO((tree, int *, int *, int *, tree *, tree *));
static void layout_class_type PROTO((tree, int *, int *, int *, tree *, tree *));
static void fixup_pending_inline PROTO((struct pending_inline *));
static void fixup_inline_methods PROTO((tree));
/* Variables shared between class.c and call.c. */
......@@ -4112,99 +4115,93 @@ create_vtable_ptr (t, empty_p, has_virtual_p, max_has_virtual_p,
}
}
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
(or C++ class declaration).
For C++, we must handle the building of derived classes.
Also, C++ allows static class members. The way that this is
handled is to keep the field name where it is (as the DECL_NAME
of the field), and place the overloaded decl in the DECL_FIELD_BITPOS
of the field. layout_record and layout_union will know about this.
/* Fixup the inline function given by INFO now that the class is
complete. */
More C++ hair: inline functions have text in their
DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into
meaningful tree structure. After the struct has been laid out, set
things up so that this can happen.
static void
fixup_pending_inline (info)
struct pending_inline *info;
{
if (info)
{
tree args;
tree fn = info->fndecl;
And still more: virtual functions. In the case of single inheritance,
when a new virtual function is seen which redefines a virtual function
from the base class, the new virtual function is placed into
the virtual function table at exactly the same address that
it had in the base class. When this is extended to multiple
inheritance, the same thing happens, except that multiple virtual
function tables must be maintained. The first virtual function
table is treated in exactly the same way as in the case of single
inheritance. Additional virtual function tables have different
DELTAs, which tell how to adjust `this' to point to the right thing.
args = DECL_ARGUMENTS (fn);
while (args)
{
DECL_CONTEXT (args) = fn;
args = TREE_CHAIN (args);
}
}
}
ATTRIBUTES is the set of decl attributes to be applied, if any. */
/* Fixup the inline methods and friends in TYPE now that TYPE is
complete. */
void
finish_struct_1 (t)
tree t;
static void
fixup_inline_methods (type)
tree type;
{
tree x;
int has_virtual;
int max_has_virtual;
tree pending_virtuals = NULL_TREE;
tree pending_hard_virtuals = NULL_TREE;
int n_fields = 0;
tree vfield;
int n_baseclasses;
int empty = 1;
tree inline_friends;
tree method = TYPE_METHODS (type);
if (TYPE_SIZE (t))
if (method && TREE_CODE (method) == TREE_VEC)
{
if (IS_AGGR_TYPE (t))
cp_error ("redefinition of `%#T'", t);
if (TREE_VEC_ELT (method, 1))
method = TREE_VEC_ELT (method, 1);
else if (TREE_VEC_ELT (method, 0))
method = TREE_VEC_ELT (method, 0);
else
my_friendly_abort (172);
popclass ();
return;
method = TREE_VEC_ELT (method, 2);
}
GNU_xref_decl (current_function_decl, t);
/* If this type was previously laid out as a forward reference,
make sure we lay it out again. */
/* Do inline member functions. */
for (; method; method = TREE_CHAIN (method))
fixup_pending_inline (DECL_PENDING_INLINE_INFO (method));
TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0;
CLASSTYPE_VFIELD_PARENT (t) = -1;
has_virtual = 0;
max_has_virtual = 0;
CLASSTYPE_RTTI (t) = NULL_TREE;
n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
/* Do friends. */
for (method = CLASSTYPE_INLINE_FRIENDS (type);
method;
method = TREE_CHAIN (method))
fixup_pending_inline (DECL_PENDING_INLINE_INFO (TREE_VALUE (method)));
}
/* Do end-of-class semantic processing: checking the validity of the
bases and members and adding implicitly generated methods. */
check_bases_and_members (t, &empty);
/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
BINFO_OFFSETs for all of the base-classes. Position the vtable
pointer. */
static void
layout_class_type (t, empty_p, has_virtual_p, max_has_virtual_p,
pending_virtuals_p, pending_hard_virtuals_p)
tree t;
int *empty_p;
int *has_virtual_p;
int *max_has_virtual_p;
tree *pending_virtuals_p;
tree *pending_hard_virtuals_p;
{
/* Add pointers to all of our virtual base-classes. */
TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, &empty),
TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, empty_p),
TYPE_FIELDS (t));
/* Build FIELD_DECLs for all of the non-virtual base-types. */
TYPE_FIELDS (t) = chainon (build_base_fields (t, &empty),
TYPE_FIELDS (t) = chainon (build_base_fields (t, empty_p),
TYPE_FIELDS (t));
/* Create a pointer to our virtual function table. */
create_vtable_ptr (t, &empty, &has_virtual, &max_has_virtual,
&pending_virtuals, &pending_hard_virtuals);
create_vtable_ptr (t, empty_p, has_virtual_p, max_has_virtual_p,
pending_virtuals_p, pending_hard_virtuals_p);
/* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus,
we have to save this before we start modifying
TYPE_NONCOPIED_PARTS. */
inline_friends = CLASSTYPE_INLINE_FRIENDS (t);
CLASSTYPE_INLINE_FRIENDS (t) = NULL_TREE;
fixup_inline_methods (t);
/* We make all structures have at least one element, so that they
have non-zero size. The field that we add here is fake, in the
sense that, for example, we don't want people to be able to
initialize it later. So, we add it just long enough to let the
back-end lay out the type, and then remove it. */
if (empty)
if (*empty_p)
{
tree decl = build_lang_decl
(FIELD_DECL, NULL_TREE, char_type_node);
......@@ -4224,7 +4221,7 @@ finish_struct_1 (t)
/* If we added an extra field to make this class non-empty, remove
it now. */
if (empty)
if (*empty_p)
TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t));
/* Delete all zero-width bit-fields from the list of fields. Now
......@@ -4233,7 +4230,7 @@ finish_struct_1 (t)
/* Remember the size and alignment of the class before adding
the virtual bases. */
if (empty && flag_new_abi)
if (*empty_p && flag_new_abi)
CLASSTYPE_SIZE (t) = integer_zero_node;
else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t)
&& TYPE_HAS_COMPLEX_ASSIGN_REF (t))
......@@ -4245,16 +4242,88 @@ finish_struct_1 (t)
/* Set the TYPE_DECL for this type to contain the right
value for DECL_OFFSET, so that we can use it as part
of a COMPONENT_REF for multiple inheritance. */
layout_decl (TYPE_MAIN_DECL (t), 0);
/* Now fix up any virtual base class types that we left lying
around. We must get these done before we try to lay out the
virtual function table. */
if (n_baseclasses)
if (CLASSTYPE_N_BASECLASSES (t))
/* layout_basetypes will remove the base subobject fields. */
max_has_virtual = layout_basetypes (t, max_has_virtual);
*max_has_virtual_p = layout_basetypes (t, *max_has_virtual_p);
}
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
(or C++ class declaration).
For C++, we must handle the building of derived classes.
Also, C++ allows static class members. The way that this is
handled is to keep the field name where it is (as the DECL_NAME
of the field), and place the overloaded decl in the DECL_FIELD_BITPOS
of the field. layout_record and layout_union will know about this.
More C++ hair: inline functions have text in their
DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into
meaningful tree structure. After the struct has been laid out, set
things up so that this can happen.
And still more: virtual functions. In the case of single inheritance,
when a new virtual function is seen which redefines a virtual function
from the base class, the new virtual function is placed into
the virtual function table at exactly the same address that
it had in the base class. When this is extended to multiple
inheritance, the same thing happens, except that multiple virtual
function tables must be maintained. The first virtual function
table is treated in exactly the same way as in the case of single
inheritance. Additional virtual function tables have different
DELTAs, which tell how to adjust `this' to point to the right thing.
ATTRIBUTES is the set of decl attributes to be applied, if any. */
void
finish_struct_1 (t)
tree t;
{
tree x;
int has_virtual;
int max_has_virtual;
tree pending_virtuals = NULL_TREE;
tree pending_hard_virtuals = NULL_TREE;
int n_fields = 0;
tree vfield;
int n_baseclasses;
int empty = 1;
if (TYPE_SIZE (t))
{
if (IS_AGGR_TYPE (t))
cp_error ("redefinition of `%#T'", t);
else
my_friendly_abort (172);
popclass ();
return;
}
GNU_xref_decl (current_function_decl, t);
/* If this type was previously laid out as a forward reference,
make sure we lay it out again. */
TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0;
CLASSTYPE_VFIELD_PARENT (t) = -1;
has_virtual = 0;
max_has_virtual = 0;
CLASSTYPE_RTTI (t) = NULL_TREE;
n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
/* Do end-of-class semantic processing: checking the validity of the
bases and members and adding implicitly generated methods. */
check_bases_and_members (t, &empty);
/* Layout the class itself. */
layout_class_type (t, &empty, &has_virtual, &max_has_virtual,
&pending_virtuals, &pending_hard_virtuals);
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
{
......@@ -4492,9 +4561,6 @@ finish_struct_1 (t)
}
}
/* Write out inline function definitions. */
do_inline_function_hair (t, inline_friends);
if (CLASSTYPE_VSIZE (t) != 0)
{
/* In addition to this one, all the other vfields should be listed. */
......
......@@ -3757,7 +3757,6 @@ extern int cp_type_qual_from_rid PROTO((tree));
/* in method.c */
extern void init_method PROTO((void));
extern void do_inline_function_hair PROTO((tree, tree));
extern char *build_overload_name PROTO((tree, int, int));
extern tree build_static_name PROTO((tree, tree));
extern tree build_decl_overload PROTO((tree, tree, int));
......
......@@ -72,7 +72,10 @@ int ggc_p = 1;
#ifndef BOOL_TYPE_SIZE
#ifdef SLOW_BYTE_ACCESS
#define BOOL_TYPE_SIZE ((SLOW_BYTE_ACCESS) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
/* In the new ABI, `bool' has size and alignment `1', on all
platforms. */
#define BOOL_TYPE_SIZE \
((SLOW_BYTE_ACCESS && !flag_new_abi) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE))
#else
#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
#endif
......
......@@ -98,7 +98,6 @@ static int is_back_referenceable_type PROTO((tree));
static int check_btype PROTO((tree));
static void build_mangled_name_for_type PROTO((tree));
static void build_mangled_name_for_type_with_Gcode PROTO((tree, int));
static void fixup_pending_inline PROTO((struct pending_inline *));
# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
......@@ -143,57 +142,6 @@ init_method ()
value. */
static char digit_buffer[128];
/* Fixup the inline function given by INFO now that the class is
complete. */
static void
fixup_pending_inline (info)
struct pending_inline *info;
{
if (info)
{
tree args;
tree fn = info->fndecl;
args = DECL_ARGUMENTS (fn);
while (args)
{
DECL_CONTEXT (args) = fn;
args = TREE_CHAIN (args);
}
}
}
/* Move inline function definitions out of structure so that they
can be processed normally. CNAME is the name of the class
we are working from, METHOD_LIST is the list of method lists
of the structure. We delete friend methods here, after
saving away their inline function definitions (if any). */
void
do_inline_function_hair (type, friend_list)
tree type, friend_list;
{
tree method = TYPE_METHODS (type);
if (method && TREE_CODE (method) == TREE_VEC)
{
if (TREE_VEC_ELT (method, 1))
method = TREE_VEC_ELT (method, 1);
else if (TREE_VEC_ELT (method, 0))
method = TREE_VEC_ELT (method, 0);
else
method = TREE_VEC_ELT (method, 2);
}
/* Do inline member functions. */
for (; method; method = TREE_CHAIN (method))
fixup_pending_inline (DECL_PENDING_INLINE_INFO (method));
/* Do friends. */
for (; friend_list; friend_list = TREE_CHAIN (friend_list))
fixup_pending_inline (DECL_PENDING_INLINE_INFO (TREE_VALUE (friend_list)));
}
/* Here is where overload code starts. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment