From 2ef161408c2096be9b57848af32d5923046db7dc Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 29 Dec 1999 07:31:51 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 12 +++ gcc/cp/class.c | 218 ++++++++++++++++++++++++++++++----------------- gcc/cp/cp-tree.h | 1 - gcc/cp/decl.c | 5 +- gcc/cp/method.c | 52 ----------- 5 files changed, 158 insertions(+), 130 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 91c343aa58f..6e9e6fb950d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 1999-12-28 Mark Mitchell + * 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. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 628e5560c32..c381efb3ca2 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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,6 +4115,143 @@ create_vtable_ptr (t, empty_p, has_virtual_p, max_has_virtual_p, } } +/* 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); + } + } +} + +/* Fixup the inline methods and friends in TYPE now that TYPE is + complete. */ + +static void +fixup_inline_methods (type) + tree type; +{ + 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 (method = CLASSTYPE_INLINE_FRIENDS (type); + method; + method = TREE_CHAIN (method)) + fixup_pending_inline (DECL_PENDING_INLINE_INFO (TREE_VALUE (method))); +} + +/* 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_p), + TYPE_FIELDS (t)); + /* Build FIELD_DECLs for all of the non-virtual base-types. */ + 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_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. */ + 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_p) + { + tree decl = build_lang_decl + (FIELD_DECL, NULL_TREE, char_type_node); + TREE_CHAIN (decl) = TYPE_FIELDS (t); + TYPE_FIELDS (t) = decl; + TYPE_NONCOPIED_PARTS (t) + = tree_cons (NULL_TREE, decl, TYPE_NONCOPIED_PARTS (t)); + TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1; + } + + /* Let the back-end lay out the type. Note that at this point we + have only included non-virtual base-classes; we will lay out the + virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after + this call are not necessarily correct; they are just the size and + alignment when no virtual base clases are used. */ + layout_type (t); + + /* If we added an extra field to make this class non-empty, remove + it now. */ + if (*empty_p) + TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t)); + + /* Delete all zero-width bit-fields from the list of fields. Now + that the type is laid out they are no longer important. */ + remove_zero_width_bit_fields (t); + + /* Remember the size and alignment of the class before adding + the virtual bases. */ + 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)) + CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); + else + CLASSTYPE_SIZE (t) = TYPE_SIZE (t); + CLASSTYPE_ALIGN (t) = TYPE_ALIGN (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 (CLASSTYPE_N_BASECLASSES (t)) + /* layout_basetypes will remove the base subobject fields. */ + *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). @@ -4152,7 +4292,6 @@ finish_struct_1 (t) tree vfield; int n_baseclasses; int empty = 1; - tree inline_friends; if (TYPE_SIZE (t)) { @@ -4182,80 +4321,10 @@ finish_struct_1 (t) bases and members and adding implicitly generated methods. */ check_bases_and_members (t, &empty); - /* Add pointers to all of our virtual base-classes. */ - TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, &empty), - 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)); - - /* Create a pointer to our virtual function table. */ - create_vtable_ptr (t, &empty, &has_virtual, &max_has_virtual, + /* Layout the class itself. */ + layout_class_type (t, &empty, &has_virtual, &max_has_virtual, &pending_virtuals, &pending_hard_virtuals); - /* 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; - - /* 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) - { - tree decl = build_lang_decl - (FIELD_DECL, NULL_TREE, char_type_node); - TREE_CHAIN (decl) = TYPE_FIELDS (t); - TYPE_FIELDS (t) = decl; - TYPE_NONCOPIED_PARTS (t) - = tree_cons (NULL_TREE, decl, TYPE_NONCOPIED_PARTS (t)); - TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1; - } - - /* Let the back-end lay out the type. Note that at this point we - have only included non-virtual base-classes; we will lay out the - virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after - this call are not necessarily correct; they are just the size and - alignment when no virtual base clases are used. */ - layout_type (t); - - /* If we added an extra field to make this class non-empty, remove - it now. */ - if (empty) - TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t)); - - /* Delete all zero-width bit-fields from the list of fields. Now - that the type is laid out they are no longer important. */ - remove_zero_width_bit_fields (t); - - /* Remember the size and alignment of the class before adding - the virtual bases. */ - if (empty && 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)) - CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); - else - CLASSTYPE_SIZE (t) = TYPE_SIZE (t); - CLASSTYPE_ALIGN (t) = TYPE_ALIGN (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) - /* layout_basetypes will remove the base subobject fields. */ - max_has_virtual = layout_basetypes (t, max_has_virtual); - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree vbases; @@ -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. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f572916ffb3..0935f1ec11e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 51d2d9ec02e..e1b27ce82c8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 3e4cf2b36b2..12d96168001 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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. */