diff options
author | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
commit | c8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch) | |
tree | 29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/cp/class.c | |
parent | c9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff) | |
download | FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz |
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/cp/class.c')
-rw-r--r-- | contrib/gcc/cp/class.c | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index aa83b8d..82360b0 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "ggc.h" #include "lex.h" +#include "target.h" #include "obstack.h" #define obstack_chunk_alloc xmalloc @@ -289,12 +290,9 @@ build_base_path (code, expr, binfo, nonnull) } fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); - if (fixed_type_p < 0) - /* Virtual base layout is not fixed, even in ctors and dtors. */ - fixed_type_p = 0; - if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) + if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); - + if (!want_pointer) expr = build_unary_op (ADDR_EXPR, expr, 0); else if (!nonnull) @@ -302,7 +300,7 @@ build_base_path (code, expr, binfo, nonnull) offset = BINFO_OFFSET (binfo); - if (v_binfo && !fixed_type_p) + if (v_binfo && fixed_type_p <= 0) { /* Going via virtual base V_BINFO. We need the static offset from V_BINFO to BINFO, and the dynamic offset from D_BINFO to @@ -323,7 +321,17 @@ build_base_path (code, expr, binfo, nonnull) size_diffop (offset, BINFO_OFFSET (v_binfo))); if (!integer_zerop (offset)) - offset = build (code, ptrdiff_type_node, v_offset, offset); + v_offset = build (code, ptrdiff_type_node, v_offset, offset); + + if (fixed_type_p < 0) + /* Negative fixed_type_p means this is a constructor or destructor; + virtual base layout is fixed in in-charge [cd]tors, but not in + base [cd]tors. */ + offset = build (COND_EXPR, ptrdiff_type_node, + build (EQ_EXPR, boolean_type_node, + current_in_charge_parm, integer_zero_node), + v_offset, + BINFO_OFFSET (binfo)); else offset = v_offset; } @@ -350,7 +358,7 @@ build_base_path (code, expr, binfo, nonnull) expr = build (COND_EXPR, target_type, null_test, build1 (NOP_EXPR, target_type, integer_zero_node), expr); - + return expr; } @@ -1842,17 +1850,11 @@ finish_struct_bits (t) } } - /* If this type has a copy constructor, force its mode to be BLKmode, and - force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to - be passed by invisible reference and prevent it from being returned in - a register. - - Also do this if the class has BLKmode but can still be returned in - registers, since function_cannot_inline_p won't let us inline - functions returning such a type. This affects the HP-PA. */ - if (! TYPE_HAS_TRIVIAL_INIT_REF (t) - || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t) - && CLASSTYPE_NON_AGGREGATE (t))) + /* If this type has a copy constructor or a destructor, force its mode to + be BLKmode, and force its TREE_ADDRESSABLE bit to be nonzero. This + will cause it to be passed by invisible reference and prevent it from + being returned in a register. */ + if (! TYPE_HAS_TRIVIAL_INIT_REF (t) || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)) { tree variants; DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode; @@ -3106,7 +3108,8 @@ check_bitfield_decl (field) DECL_SIZE (field) = convert (bitsizetype, w); DECL_BIT_FIELD (field) = 1; - if (integer_zerop (w)) + if (integer_zerop (w) + && ! (* targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (field))) { #ifdef EMPTY_FIELD_BOUNDARY DECL_ALIGN (field) = MAX (DECL_ALIGN (field), @@ -3284,8 +3287,6 @@ check_field_decls (t, access_decls, empty_p, tree x = *field; tree type = TREE_TYPE (x); - GNU_xref_member (current_class_name, x); - next = &TREE_CHAIN (x); if (TREE_CODE (x) == FIELD_DECL) @@ -3925,8 +3926,6 @@ check_methods (t) for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { - GNU_xref_member (current_class_name, x); - /* If this was an evil function, don't keep it in class. */ if (DECL_ASSEMBLER_NAME_SET_P (x) && IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x))) @@ -4607,8 +4606,7 @@ layout_virtual_bases (t, offsets) tree t; splay_tree offsets; { - tree vbases; - unsigned HOST_WIDE_INT dsize; + tree vbases, dsize; unsigned HOST_WIDE_INT eoc; if (CLASSTYPE_N_BASECLASSES (t) == 0) @@ -4621,7 +4619,7 @@ layout_virtual_bases (t, offsets) #endif /* DSIZE is the size of the class without the virtual bases. */ - dsize = tree_low_cst (TYPE_SIZE (t), 1); + dsize = TYPE_SIZE (t); /* Make every class have alignment of at least one. */ TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT); @@ -4643,7 +4641,7 @@ layout_virtual_bases (t, offsets) { /* This virtual base is not a primary base of any class in the hierarchy, so we have to add space for it. */ - tree basetype; + tree basetype, usize; unsigned int desired_align; basetype = BINFO_TYPE (vbase); @@ -4653,19 +4651,21 @@ layout_virtual_bases (t, offsets) /* Add padding so that we can put the virtual base class at an appropriately aligned offset. */ - dsize = CEIL (dsize, desired_align) * desired_align; + dsize = round_up (dsize, desired_align); + + usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node); /* We try to squish empty virtual bases in just like ordinary empty bases. */ if (is_empty_class (basetype)) layout_empty_base (vbase, - size_int (CEIL (dsize, BITS_PER_UNIT)), + convert (sizetype, usize), offsets, t); else { tree offset; - offset = ssize_int (CEIL (dsize, BITS_PER_UNIT)); + offset = convert (ssizetype, usize); offset = size_diffop (offset, convert (ssizetype, BINFO_OFFSET (vbase))); @@ -4675,8 +4675,9 @@ layout_virtual_bases (t, offsets) /* Every virtual baseclass takes a least a UNIT, so that we can take it's address and get something different for each base. */ - dsize += MAX (BITS_PER_UNIT, - tree_low_cst (CLASSTYPE_SIZE (basetype), 0)); + dsize = size_binop (PLUS_EXPR, dsize, + size_binop (MAX_EXPR, bitsize_unit_node, + CLASSTYPE_SIZE (basetype))); } /* Keep track of the offsets assigned to this virtual base. */ @@ -4698,13 +4699,12 @@ layout_virtual_bases (t, offsets) class, we didn't update DSIZE above; we were hoping to overlay multiple such bases at the same location. */ eoc = end_of_class (t, /*include_virtuals_p=*/1); - if (eoc * BITS_PER_UNIT > dsize) - dsize = eoc * BITS_PER_UNIT; + dsize = size_binop (MAX_EXPR, dsize, bitsize_int (eoc * BITS_PER_UNIT)); /* Now, make sure that the total size of the type is a multiple of its alignment. */ - dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t); - TYPE_SIZE (t) = bitsize_int (dsize); + dsize = round_up (dsize, TYPE_ALIGN (t)); + TYPE_SIZE (t) = dsize; TYPE_SIZE_UNIT (t) = convert (sizetype, size_binop (CEIL_DIV_EXPR, TYPE_SIZE (t), bitsize_unit_node)); @@ -4863,6 +4863,18 @@ layout_class_type (t, empty_p, vfuns_p, if (TREE_CODE (field) != FIELD_DECL) { place_field (rli, field); + /* If the static data member has incomplete type, keep track + of it so that it can be completed later. (The handling + of pending statics in finish_record_layout is + insufficient; consider: + + struct S1; + struct S2 { static S1 s1; }; + + At this point, finish_record_layout will be called, but + S1 is still incomplete.) */ + if (TREE_CODE (field) == VAR_DECL) + maybe_register_incomplete_var (field); continue; } @@ -5049,8 +5061,6 @@ finish_struct_1 (t) 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; @@ -5158,7 +5168,7 @@ finish_struct_1 (t) working on. */ for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x)) if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) - && TREE_TYPE (x) == t) + && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t)) DECL_MODE (x) = TYPE_MODE (t); /* Done with FIELDS...now decide whether to sort these for @@ -5207,7 +5217,7 @@ finish_struct_1 (t) && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1)) == NULL_TREE) warning ("`%#T' has virtual functions but non-virtual destructor", t); - hack_incomplete_structures (t); + complete_vars (t); if (warn_overloaded_virtual) warn_hidden (t); @@ -6047,14 +6057,14 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'", tree instantiate_type (lhstype, rhs, flags) tree lhstype, rhs; - enum instantiate_type_flags flags; + tsubst_flags_t flags; { - int complain = (flags & itf_complain); - int strict = (flags & itf_no_attributes) + int complain = (flags & tf_error); + int strict = (flags & tf_no_attributes) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT; - int allow_ptrmem = flags & itf_ptrmem_ok; + int allow_ptrmem = flags & tf_ptrmem_ok; - flags &= ~itf_ptrmem_ok; + flags &= ~tf_ptrmem_ok; if (TREE_CODE (lhstype) == UNKNOWN_TYPE) { @@ -6261,7 +6271,7 @@ instantiate_type (lhstype, rhs, flags) case ADDR_EXPR: { if (PTRMEM_OK_P (rhs)) - flags |= itf_ptrmem_ok; + flags |= tf_ptrmem_ok; return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags); } @@ -6299,7 +6309,8 @@ get_vfield_name (type) type = BINFO_TYPE (binfo); buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT) + TYPE_NAME_LENGTH (type) + 2); - sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type)); + sprintf (buf, VFIELD_NAME_FORMAT, + IDENTIFIER_POINTER (constructor_name (type))); return get_identifier (buf); } |