diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-12-16 22:18:22 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-12-16 22:18:22 +0000 |
commit | 607cf13135fdf7c664bb26f7cf2c5b3c18204f96 (patch) | |
tree | 418097af1b72d5c3400d623aa2be1b3611051d92 /gcc/cp | |
parent | a97901e608d0e3233e28a6d8e39d3124d661a650 (diff) | |
download | gcc-607cf13135fdf7c664bb26f7cf2c5b3c18204f96.zip gcc-607cf13135fdf7c664bb26f7cf2c5b3c18204f96.tar.gz gcc-607cf13135fdf7c664bb26f7cf2c5b3c18204f96.tar.bz2 |
class.c (check_field_decls): Don't return a value.
1999-12-16 Mark Mitchell <mark@codesourcery.com>
* class.c (check_field_decls): Don't return a value.
(avoid_overlap): Moved here from tree.c.
(build_base_fields): Likewise.
(check_bases): New function, split out from finish_base_struct.
(check_bases_and_members): New function, split out from finish_struct_1.
(struct base_info): Remove cant_have_default_ctor,
cant_have_const_ctor, cant_have_asn_ref.
(finish_base_struct): Split semantic analysis into check_bases.
(finish_struct_methods): Fix bogus assertion.
(check_field_decls): Call finish_struct_anon here.
(build_vbase_pointer_fields): Use CLASSTYPE_N_BASECLASSES.
(finish_struct_1): Use check_bases_and_members. Reorganize.
* cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation.
(build_base_fields): Don't declare.
* tree.c (avoid_overlap): Remove.
(build_base_fields): Likewise.
From-SVN: r30983
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/class.c | 463 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/method.c | 64 | ||||
-rw-r--r-- | gcc/cp/tree.c | 112 |
5 files changed, 365 insertions, 295 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 05f1618..2fe8bd3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,22 @@ 1999-12-16 Mark Mitchell <mark@codesourcery.com> + * class.c (check_field_decls): Don't return a value. + (avoid_overlap): Moved here from tree.c. + (build_base_fields): Likewise. + (check_bases): New function, split out from finish_base_struct. + (check_bases_and_members): New function, split out from finish_struct_1. + (struct base_info): Remove cant_have_default_ctor, + cant_have_const_ctor, cant_have_asn_ref. + (finish_base_struct): Split semantic analysis into check_bases. + (finish_struct_methods): Fix bogus assertion. + (check_field_decls): Call finish_struct_anon here. + (build_vbase_pointer_fields): Use CLASSTYPE_N_BASECLASSES. + (finish_struct_1): Use check_bases_and_members. Reorganize. + * cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation. + (build_base_fields): Don't declare. + * tree.c (avoid_overlap): Remove. + (build_base_fields): Likewise. + * optimize.c (struct inline_data): Remove scope_stmt. (remap_block): Don't use insert_block_after_note. Don't update scope_stmt. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 7bd62da..f0a4b92 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -123,12 +123,16 @@ static int count_fields PROTO((tree)); static int add_fields_to_vec PROTO((tree, tree, int)); static void check_bitfield_decl PROTO((tree)); static void check_field_decl PROTO((tree, tree, int *, int *, int *, int *)); -static tree* check_field_decls PROTO((tree, tree *, int *, int *, int *, - int *)); +static void check_field_decls PROTO((tree, tree *, int *, int *, int *, + int *)); +static int avoid_overlap PROTO((tree, tree, int *)); +static tree build_base_fields PROTO((tree, int *)); static tree build_vbase_pointer_fields PROTO((tree, int *)); static tree build_vtbl_or_vbase_field PROTO((tree, tree, tree, tree, int *)); static void check_methods PROTO((tree)); 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 *)); /* Variables shared between class.c and call.c. */ @@ -1486,52 +1490,43 @@ struct base_info tree vfield; tree vfields; tree rtti; - char cant_have_default_ctor; - char cant_have_const_ctor; - char no_const_asn_ref; }; -/* Record information about type T derived from its base classes. - Store most of that information in T itself, and place the - remaining information in the struct BASE_INFO. - - Propagate basetype offsets throughout the lattice. Note that the - lattice topped by T is really a pair: it's a DAG that gives the - structure of the derivation hierarchy, and it's a list of the - virtual baseclasses that appear anywhere in the DAG. When a vbase - type appears in the DAG, it's offset is 0, and it's children start - their offsets from that point. When a vbase type appears in the list, - its offset is the offset it has in the hierarchy, and its children's - offsets include that offset in theirs. +/* Run through the base clases of T, updating + CANT_HAVE_DEFAULT_CTOR_P, CANT_HAVE_CONST_CTOR_P, and + NO_CONST_ASN_REF_P. Also set flag bits in T based on properties of + the bases. */ - Returns the index of the first base class to have virtual functions, - or -1 if no such base class. */ - -static int -finish_base_struct (t, b) +static void +check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p, + no_const_asn_ref_p) tree t; - struct base_info *b; + int *cant_have_default_ctor_p; + int *cant_have_const_ctor_p; + int *no_const_asn_ref_p; { - tree binfos = TYPE_BINFO_BASETYPES (t); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - int first_vfn_base_index = -1; - bzero ((char *) b, sizeof (struct base_info)); + int n_baseclasses; + int i; + tree binfos; - for (i = 0; i < n_baseclasses; i++) + binfos = TYPE_BINFO_BASETYPES (t); + n_baseclasses = CLASSTYPE_N_BASECLASSES (t); + + /* An aggregate cannot have baseclasses. */ + CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses != 0); + + for (i = 0; i < n_baseclasses; ++i) { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); + tree base_binfo; + tree basetype; - /* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P - here because the case of virtual functions but non-virtual - dtor is handled in finish_struct_1. */ - if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype) - && TYPE_HAS_DESTRUCTOR (basetype)) - cp_warning ("base class `%#T' has a non-virtual destructor", basetype); + /* Figure out what base we're looking at. */ + base_binfo = TREE_VEC_ELT (binfos, i); + basetype = TREE_TYPE (base_binfo); - /* If the type of basetype is incomplete, then - we already complained about that fact - (and we should have fixed it up as well). */ + /* If the type of basetype is incomplete, then we already + complained about that fact (and we should have fixed it up as + well). */ if (TYPE_SIZE (basetype) == 0) { int j; @@ -1544,15 +1539,33 @@ finish_base_struct (t, b) n_baseclasses -= 1; for (j = i; j+1 < n_baseclasses; j++) TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1); + continue; } - if (! TYPE_HAS_CONST_INIT_REF (basetype)) - b->cant_have_const_ctor = 1; + /* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P + here because the case of virtual functions but non-virtual + dtor is handled in finish_struct_1. */ + if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype) + && TYPE_HAS_DESTRUCTOR (basetype)) + cp_warning ("base class `%#T' has a non-virtual destructor", + basetype); + /* If the base class doesn't have copy constructors or + assignment operators that take const references, then the + derived class cannot have such a member automatically + generated. */ + if (! TYPE_HAS_CONST_INIT_REF (basetype)) + *cant_have_const_ctor_p = 1; + if (TYPE_HAS_ASSIGN_REF (basetype) + && !TYPE_HAS_CONST_ASSIGN_REF (basetype)) + *no_const_asn_ref_p = 1; + /* Similarly, if the base class doesn't have a default + constructor, then the derived class won't have an + automatically generated default constructor. */ if (TYPE_HAS_CONSTRUCTOR (basetype) && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)) { - b->cant_have_default_ctor = 1; + *cant_have_default_ctor_p = 1; if (! TYPE_HAS_CONSTRUCTOR (t)) { cp_pedwarn ("base `%T' with only non-default constructor", @@ -1561,30 +1574,61 @@ finish_base_struct (t, b) } } - if (TYPE_HAS_ASSIGN_REF (basetype) - && !TYPE_HAS_CONST_ASSIGN_REF (basetype)) - b->no_const_asn_ref = 1; - + /* A lot of properties from the bases also apply to the derived + class. */ TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype); TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype); + TYPE_HAS_COMPLEX_ASSIGN_REF (t) + |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype); TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype); - TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype); TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype); TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype); + /* Derived classes can implicitly become COMified if their bases + are COM. */ if (CLASSTYPE_COM_INTERFACE (basetype)) - { - CLASSTYPE_COM_INTERFACE (t) = 1; - } - else if (CLASSTYPE_COM_INTERFACE (t) && i == 0) + CLASSTYPE_COM_INTERFACE (t) = 1; + else if (i == 0 && CLASSTYPE_COM_INTERFACE (t)) { cp_error ("COM interface type `%T' with non-COM leftmost base class `%T'", t, basetype); CLASSTYPE_COM_INTERFACE (t) = 0; } + } +} + +/* Record information about type T derived from its base classes. + Store most of that information in T itself, and place the + remaining information in the struct BASE_INFO. + + Propagate basetype offsets throughout the lattice. Note that the + lattice topped by T is really a pair: it's a DAG that gives the + structure of the derivation hierarchy, and it's a list of the + virtual baseclasses that appear anywhere in the DAG. When a vbase + type appears in the DAG, it's offset is 0, and it's children start + their offsets from that point. When a vbase type appears in the list, + its offset is the offset it has in the hierarchy, and its children's + offsets include that offset in theirs. + + Returns the index of the first base class to have virtual functions, + or -1 if no such base class. */ + +static int +finish_base_struct (t, b) + tree t; + struct base_info *b; +{ + tree binfos = TYPE_BINFO_BASETYPES (t); + int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); + int first_vfn_base_index = -1; + bzero ((char *) b, sizeof (struct base_info)); + + for (i = 0; i < n_baseclasses; i++) + { + tree base_binfo = TREE_VEC_ELT (binfos, i); + tree basetype = BINFO_TYPE (base_binfo); if (TYPE_VIRTUAL_P (basetype)) { @@ -2009,8 +2053,8 @@ finish_struct_methods (t) return; } - my_friendly_assert (method_vec != NULL_TREE, 19991215); method_vec = CLASSTYPE_METHOD_VEC (t); + my_friendly_assert (method_vec != NULL_TREE, 19991215); len = TREE_VEC_LENGTH (method_vec); /* First fill in entry 0 with the constructors, entry 1 with destructors, @@ -3387,7 +3431,7 @@ check_field_decl (field, t, cant_have_const_ctor, Returns a pointer to the end of the TYPE_FIELDs chain; additional fields can be added by adding to this chain. */ -static tree* +static void check_field_decls (t, access_decls, empty_p, cant_have_default_ctor_p, cant_have_const_ctor_p, no_const_asn_ref_p) @@ -3606,12 +3650,13 @@ check_field_decls (t, access_decls, empty_p, cp_warning (" but does not override `operator=(const %T&)'", t); } + + /* Check anonymous struct/anonymous union fields. */ + finish_struct_anon (t); + /* We've built up the list of access declarations in reverse order. Fix that now. */ *access_decls = nreverse (*access_decls); - - /* Return the last field. */ - return field; } /* Return a FIELD_DECL for a pointer-to-virtual-table or @@ -3662,7 +3707,7 @@ build_vbase_pointer_fields (rec, empty_p) base classes. */ tree vbase_decls = NULL_TREE; tree binfos = TYPE_BINFO_BASETYPES (rec); - int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; + int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec); tree decl; int i; @@ -3725,6 +3770,129 @@ build_vbase_pointer_fields (rec, empty_p) return vbase_decls; } +/* If the empty base field in DECL overlaps with a base of the same type in + NEWDECL, which is either another base field or the first data field of + the class, pad the base just before NEWDECL and return 1. Otherwise, + return 0. */ + +static int +avoid_overlap (decl, newdecl, empty_p) + tree decl, newdecl; + int *empty_p; +{ + tree field; + + if (newdecl == NULL_TREE + || ! types_overlap_p (TREE_TYPE (decl), TREE_TYPE (newdecl))) + return 0; + + for (field = decl; TREE_CHAIN (field) && TREE_CHAIN (field) != newdecl; + field = TREE_CHAIN (field)) + ; + + DECL_SIZE (field) = integer_one_node; + /* The containing class cannot be empty; this field takes up space. */ + *empty_p = 0; + + return 1; +} + +/* Returns a list of fields to stand in for the base class subobjects + of REC. These fields are later removed by layout_basetypes. */ + +static tree +build_base_fields (rec, empty_p) + tree rec; + int *empty_p; +{ + /* Chain to hold all the new FIELD_DECLs which stand in for base class + subobjects. */ + tree base_decls = NULL_TREE; + tree binfos = TYPE_BINFO_BASETYPES (rec); + int n_baseclasses = CLASSTYPE_N_BASECLASSES (rec); + tree decl, nextdecl; + int i, saw_empty = 0; + unsigned int base_align = 0; + + for (i = 0; i < n_baseclasses; ++i) + { + register tree base_binfo = TREE_VEC_ELT (binfos, i); + register tree basetype = BINFO_TYPE (base_binfo); + + if (TYPE_SIZE (basetype) == 0) + /* This error is now reported in xref_tag, thus giving better + location information. */ + continue; + + if (TREE_VIA_VIRTUAL (base_binfo)) + continue; + + decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype); + DECL_ARTIFICIAL (decl) = 1; + DECL_FIELD_CONTEXT (decl) = DECL_CLASS_CONTEXT (decl) = rec; + DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); + DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); + TREE_CHAIN (decl) = base_decls; + base_decls = decl; + + if (flag_new_abi && DECL_SIZE (decl) == integer_zero_node) + saw_empty = 1; + else + { + /* The containing class is non-empty because it has a + non-empty base class. */ + *empty_p = 0; + + if (! flag_new_abi) + { + /* Brain damage for backwards compatibility. For no + good reason, the old layout_basetypes made every base + at least as large as the alignment for the bases up + to that point, gratuitously wasting space. So we do + the same thing here. */ + base_align = MAX (base_align, DECL_ALIGN (decl)); + DECL_SIZE (decl) + = size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE (decl)), + (int) base_align)); + } + } + } + + /* Reverse the list of fields so we allocate the bases in the proper + order. */ + base_decls = nreverse (base_decls); + + /* In the presence of empty base classes, we run the risk of allocating + two objects of the same class on top of one another. Avoid that. */ + if (flag_new_abi && saw_empty) + for (decl = base_decls; decl; decl = TREE_CHAIN (decl)) + { + if (DECL_SIZE (decl) == integer_zero_node) + { + /* First step through the following bases until we find + an overlap or a non-empty base. */ + for (nextdecl = TREE_CHAIN (decl); nextdecl; + nextdecl = TREE_CHAIN (nextdecl)) + { + if (avoid_overlap (decl, nextdecl, empty_p) + || DECL_SIZE (nextdecl) != integer_zero_node) + goto nextbase; + } + + /* If we're still looking, also check against the first + field. */ + for (nextdecl = TYPE_FIELDS (rec); + nextdecl && TREE_CODE (nextdecl) != FIELD_DECL; + nextdecl = TREE_CHAIN (nextdecl)) + /* keep looking */; + avoid_overlap (decl, nextdecl, empty_p); + } + nextbase:; + } + + return base_decls; +} + /* Go through the TYPE_METHODS of T issuing any appropriate diagnostics, figuring out which methods override which other methods, and so forth. Returns non-zero if this class has any @@ -3800,6 +3968,80 @@ remove_zero_width_bit_fields (t) } } +/* Check the validity of the bases and members declared in T. Add any + implicitly-generated functions (like copy-constructors and + assignment operators). Compute various flag bits (like + CLASSTYPE_NON_POD_T) for T. This routine works purely at the C++ + level: i.e., independently of the ABI in use. */ + +static void +check_bases_and_members (t, empty_p) + tree t; + int *empty_p; +{ + /* Nonzero if we are not allowed to generate a default constructor + for this case. */ + int cant_have_default_ctor; + /* Nonzero if the implicitly generated copy constructor should take + a non-const reference argument. */ + int cant_have_const_ctor; + /* Nonzero if the the implicitly generated assignment operator + should take a non-const reference argument. */ + int no_const_asn_ref; + tree access_decls; + + /* By default, we use const reference arguments and generate default + constructors. */ + cant_have_default_ctor = 0; + cant_have_const_ctor = 0; + no_const_asn_ref = 0; + + /* Check all the base-classes. */ + check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor, + &no_const_asn_ref); + + /* Check all the data member declarations. */ + check_field_decls (t, &access_decls, empty_p, + &cant_have_default_ctor, + &cant_have_const_ctor, + &no_const_asn_ref); + + /* Check all the method declarations. */ + check_methods (t); + + /* Do some bookkeeping that will guide the generation of implicitly + declared member functions. */ + TYPE_HAS_COMPLEX_INIT_REF (t) + |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)); + TYPE_NEEDS_CONSTRUCTING (t) + |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)); + CLASSTYPE_NON_AGGREGATE (t) |= TYPE_HAS_CONSTRUCTOR (t); + CLASSTYPE_NON_POD_P (t) + |= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t) + || TYPE_HAS_ASSIGN_REF (t)); + TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t); + TYPE_HAS_COMPLEX_ASSIGN_REF (t) + |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t); + + /* Synthesize any needed methods. Note that methods will be synthesized + for anonymous unions; grok_x_components undoes that. */ + add_implicitly_declared_members (t, cant_have_default_ctor, + cant_have_const_ctor, + no_const_asn_ref); + + /* Build and sort the CLASSTYPE_METHOD_VEC. */ + finish_struct_methods (t); + + /* Process the access-declarations. We wait until now to do this + because handle_using_decls requires that the CLASSTYPE_METHOD_VEC + be set up correctly. */ + while (access_decls) + { + handle_using_decl (TREE_VALUE (access_decls), t); + access_decls = TREE_CHAIN (access_decls); + } +} + /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration (or C++ class declaration). @@ -3831,19 +4073,13 @@ void finish_struct_1 (t) tree t; { - tree fields; tree x; - tree *next_field; int has_virtual; int max_has_virtual; tree pending_virtuals = NULL_TREE; tree pending_hard_virtuals = NULL_TREE; tree vfield; tree vfields; - tree virtual_dtor; - int cant_have_default_ctor; - int cant_have_const_ctor; - int no_const_asn_ref; int n_fields = 0; /* The index of the first base class which has virtual @@ -3851,8 +4087,6 @@ finish_struct_1 (t) int first_vfn_base_index; int n_baseclasses; - tree access_decls; - int aggregate = 1; int empty = 1; tree inline_friends; @@ -3874,8 +4108,25 @@ finish_struct_1 (t) TYPE_SIZE (t) = NULL_TREE; CLASSTYPE_GOT_SEMICOLON (t) = 0; + first_vfn_base_index = -1; + has_virtual = 0; + max_has_virtual = 0; + vfield = NULL_TREE; + vfields = NULL_TREE; + 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); + + /* 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)); + if (n_baseclasses > 0) { struct base_info base_info; @@ -3890,74 +4141,8 @@ finish_struct_1 (t) vfields = base_info.vfields; CLASSTYPE_VFIELDS (t) = vfields; CLASSTYPE_RTTI (t) = base_info.rtti; - cant_have_default_ctor = base_info.cant_have_default_ctor; - cant_have_const_ctor = base_info.cant_have_const_ctor; - no_const_asn_ref = base_info.no_const_asn_ref; - aggregate = 0; - } - else - { - first_vfn_base_index = -1; - has_virtual = 0; - max_has_virtual = 0; - vfield = NULL_TREE; - vfields = NULL_TREE; - CLASSTYPE_RTTI (t) = NULL_TREE; - cant_have_default_ctor = 0; - cant_have_const_ctor = 0; - no_const_asn_ref = 0; - } - - /* Check all the data member declarations. */ - next_field = check_field_decls (t, &access_decls, &empty, - &cant_have_default_ctor, - &cant_have_const_ctor, - &no_const_asn_ref); - - /* Add pointers to all of our virtual base-classes. */ - if (n_baseclasses) - TYPE_FIELDS (t) = chainon (build_vbase_pointer_fields (t, &empty), - TYPE_FIELDS (t)); - - /* Build FIELD_DECLs for all of the non-virtual base-types. */ - fields = TYPE_FIELDS (t); - if (n_baseclasses) - { - TYPE_FIELDS (t) = chainon (build_base_fields (t), TYPE_FIELDS (t)); - - /* If any base is non-empty, then we are non-empty. */ - for (x = TYPE_FIELDS (t); empty && x != fields; x = TREE_CHAIN (x)) - if (DECL_SIZE (x) != integer_zero_node) - empty = 0; - - fields = TYPE_FIELDS (t); } - /* Check all the method declarations. */ - check_methods (t); - - /* Do some bookkeeping that will guide the generation of implicitly - declared member functions. */ - TYPE_HAS_COMPLEX_INIT_REF (t) - |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)); - TYPE_NEEDS_CONSTRUCTING (t) - |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)); - CLASSTYPE_NON_AGGREGATE (t) - = ! aggregate || TYPE_HAS_CONSTRUCTOR (t); - CLASSTYPE_NON_POD_P (t) - |= (CLASSTYPE_NON_AGGREGATE (t) || TYPE_HAS_DESTRUCTOR (t) - || TYPE_HAS_ASSIGN_REF (t)); - TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) - |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t); - - /* Synthesize any needed methods. Note that methods will be synthesized - for anonymous unions; grok_x_components undoes that. */ - virtual_dtor - = add_implicitly_declared_members (t, cant_have_default_ctor, - cant_have_const_ctor, - no_const_asn_ref); - /* Loop over the virtual functions, adding them to our various vtables. */ for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) @@ -3965,16 +4150,6 @@ finish_struct_1 (t) add_virtual_function (&pending_virtuals, &pending_hard_virtuals, &has_virtual, x, t); - /* Build and sort the CLASSTYPE_METHOD_VEC. */ - finish_struct_methods (t); - - /* Process the access-declarations. */ - while (access_decls) - { - handle_using_decl (TREE_VALUE (access_decls), t); - access_decls = TREE_CHAIN (access_decls); - } - if (vfield == NULL_TREE && has_virtual) { /* We build this decl with vtbl_ptr_type_node, which is a @@ -4002,7 +4177,7 @@ finish_struct_1 (t) t, &empty); TYPE_VFIELD (t) = vfield; - *next_field = vfield; + TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), vfield); vfields = chainon (vfields, build_tree_list (NULL_TREE, t)); } @@ -4046,8 +4221,6 @@ finish_struct_1 (t) CLASSTYPE_SIZE (t) = TYPE_SIZE (t); CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t); - finish_struct_anon (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. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ea58f86..0fefc7d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1388,7 +1388,8 @@ struct lang_type /* The number of virtual functions defined for this _CLASSTYPE node. */ #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize) -/* The virtual base classes that this type uses. */ +/* The direct and indirect virtual base classes that this type uses in + depth-first left-to-right order. */ #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases) /* The virtual function pointer fields that this type contains. */ #define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfields) @@ -4012,7 +4013,6 @@ extern tree build_cplus_method_type PROTO((tree, tree, tree)); extern tree build_cplus_staticfn_type PROTO((tree, tree, tree)); extern tree build_cplus_array_type PROTO((tree, tree)); extern int layout_basetypes PROTO((tree, int)); -extern tree build_base_fields PROTO((tree)); extern tree hash_tree_cons PROTO((tree, tree, tree)); extern tree hash_tree_chain PROTO((tree, tree)); extern tree hash_chainon PROTO((tree, tree)); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 7373f06..4873285 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -98,6 +98,7 @@ 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))) @@ -142,6 +143,27 @@ 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 @@ -164,43 +186,13 @@ do_inline_function_hair (type, friend_list) method = TREE_VEC_ELT (method, 2); } - while (method) - { - /* Do inline member functions. */ - struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); - if (info) - { - tree args; - - my_friendly_assert (info->fndecl == method, 238); - args = DECL_ARGUMENTS (method); - while (args) - { - DECL_CONTEXT (args) = method; - args = TREE_CHAIN (args); - } - } - method = TREE_CHAIN (method); - } - while (friend_list) - { - tree fndecl = TREE_VALUE (friend_list); - struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); - if (info) - { - tree args; - - my_friendly_assert (info->fndecl == fndecl, 239); - args = DECL_ARGUMENTS (fndecl); - while (args) - { - DECL_CONTEXT (args) = fndecl; - args = TREE_CHAIN (args); - } - } + /* Do inline member functions. */ + for (; method; method = TREE_CHAIN (method)) + fixup_pending_inline (DECL_PENDING_INLINE_INFO (method)); - friend_list = TREE_CHAIN (friend_list); - } + /* 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. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d50b459..cd837e6 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -38,7 +38,6 @@ static void list_hash_add PROTO((int, tree)); static int list_hash PROTO((tree, tree, tree)); static tree list_hash_lookup PROTO((int, tree, tree, tree)); static void propagate_binfo_offsets PROTO((tree, tree)); -static int avoid_overlap PROTO((tree, tree)); static cp_lvalue_kind lvalue_p_1 PROTO((tree, int)); static tree no_linkage_helper PROTO((tree *, int *, void *)); static tree build_srcloc PROTO((char *, int)); @@ -878,117 +877,6 @@ layout_basetypes (rec, max) return max; } -/* If the empty base field in DECL overlaps with a base of the same type in - NEWDECL, which is either another base field or the first data field of - the class, pad the base just before NEWDECL and return 1. Otherwise, - return 0. */ - -static int -avoid_overlap (decl, newdecl) - tree decl, newdecl; -{ - tree field; - - if (newdecl == NULL_TREE - || ! types_overlap_p (TREE_TYPE (decl), TREE_TYPE (newdecl))) - return 0; - - for (field = decl; TREE_CHAIN (field) && TREE_CHAIN (field) != newdecl; - field = TREE_CHAIN (field)) - ; - - DECL_SIZE (field) = integer_one_node; - - return 1; -} - -/* Returns a list of fields to stand in for the base class subobjects - of REC. These fields are later removed by layout_basetypes. */ - -tree -build_base_fields (rec) - tree rec; -{ - /* Chain to hold all the new FIELD_DECLs which stand in for base class - subobjects. */ - tree base_decls = NULL_TREE; - tree binfos = TYPE_BINFO_BASETYPES (rec); - int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree decl, nextdecl; - int i, saw_empty = 0; - unsigned int base_align = 0; - - for (i = 0; i < n_baseclasses; ++i) - { - register tree base_binfo = TREE_VEC_ELT (binfos, i); - register tree basetype = BINFO_TYPE (base_binfo); - - if (TYPE_SIZE (basetype) == 0) - /* This error is now reported in xref_tag, thus giving better - location information. */ - continue; - - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype); - DECL_ARTIFICIAL (decl) = 1; - DECL_FIELD_CONTEXT (decl) = DECL_CLASS_CONTEXT (decl) = rec; - DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); - DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); - TREE_CHAIN (decl) = base_decls; - base_decls = decl; - - if (! flag_new_abi) - { - /* Brain damage for backwards compatibility. For no good reason, - the old layout_basetypes made every base at least as large as - the alignment for the bases up to that point, gratuitously - wasting space. So we do the same thing here. */ - base_align = MAX (base_align, DECL_ALIGN (decl)); - DECL_SIZE (decl) - = size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE (decl)), - (int) base_align)); - } - else if (DECL_SIZE (decl) == integer_zero_node) - saw_empty = 1; - } - - /* Reverse the list of fields so we allocate the bases in the proper - order. */ - base_decls = nreverse (base_decls); - - /* In the presence of empty base classes, we run the risk of allocating - two objects of the same class on top of one another. Avoid that. */ - if (flag_new_abi && saw_empty) - for (decl = base_decls; decl; decl = TREE_CHAIN (decl)) - { - if (DECL_SIZE (decl) == integer_zero_node) - { - /* First step through the following bases until we find - an overlap or a non-empty base. */ - for (nextdecl = TREE_CHAIN (decl); nextdecl; - nextdecl = TREE_CHAIN (nextdecl)) - { - if (avoid_overlap (decl, nextdecl) - || DECL_SIZE (nextdecl) != integer_zero_node) - goto nextbase; - } - - /* If we're still looking, also check against the first - field. */ - for (nextdecl = TYPE_FIELDS (rec); - nextdecl && TREE_CODE (nextdecl) != FIELD_DECL; - nextdecl = TREE_CHAIN (nextdecl)) - /* keep looking */; - avoid_overlap (decl, nextdecl); - } - nextbase:; - } - - return base_decls; -} - /* Hashing of lists so that we don't make duplicates. The entry point is `list_hash_canon'. */ |