diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/expr.c | 11 | ||||
-rw-r--r-- | gcc/function.c | 3 | ||||
-rw-r--r-- | gcc/tree.c | 16 | ||||
-rw-r--r-- | gcc/tree.h | 4 |
5 files changed, 41 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0abf7f5..9ce13da 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2000-03-13 Jason Merrill <jason@casey.cygnus.com> + + * function.c (put_var_into_stack): Use type_for_mode to calculate + part_type. Use MEM_SET_IN_STRUCT_P. + * expr.c (store_field): Handle CONCAT. + (store_constructor): Use fields_length. + * tree.c (fields_length): New fn. + * tree.h: Declare it. + 2000-03-13 Zack Weinberg <zack@wolery.cumb.org> * Makefile.in (LIBCPP_OBJS): Add cpplex.o. @@ -4151,7 +4151,7 @@ store_constructor (exp, target, align, cleared, size) clear the whole structure first. */ else if (size > 0 && ((list_length (CONSTRUCTOR_ELTS (exp)) - != list_length (TYPE_FIELDS (type))) + != fields_length (type)) || mostly_zeros_p (exp))) { if (! cleared) @@ -4758,6 +4758,15 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, return blk_object; } + if (GET_CODE (target) == CONCAT) + { + /* We're storing into a struct containing a single __complex. */ + + if (bitpos != 0) + abort (); + return store_expr (exp, target, 0); + } + /* If the structure is in a register or if the component is a bit field, we cannot use addressing to access it. Use bit-field techniques or SUBREG to store in it. */ diff --git a/gcc/function.c b/gcc/function.c index 1ffb821..318d16b 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1383,7 +1383,7 @@ put_var_into_stack (decl) /* A CONCAT contains two pseudos; put them both in the stack. We do it so they end up consecutive. */ enum machine_mode part_mode = GET_MODE (XEXP (reg, 0)); - tree part_type = TREE_TYPE (TREE_TYPE (decl)); + tree part_type = type_for_mode (part_mode, 0); #ifdef FRAME_GROWS_DOWNWARD /* Since part 0 should have a lower address, do it second. */ put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode, @@ -1409,6 +1409,7 @@ put_var_into_stack (decl) PUT_CODE (reg, MEM); MEM_VOLATILE_P (reg) = MEM_VOLATILE_P (XEXP (reg, 0)); MEM_ALIAS_SET (reg) = get_alias_set (decl); + MEM_SET_IN_STRUCT_P (reg, AGGREGATE_TYPE_P (TREE_TYPE (decl))); /* The two parts are in memory order already. Use the lower parts address as ours. */ @@ -2004,6 +2004,22 @@ list_length (t) return len; } +/* Returns the number of FIELD_DECLs in TYPE. */ + +int +fields_length (type) + tree type; +{ + tree t = TYPE_FIELDS (type); + int count = 0; + + for (; t; t = TREE_CHAIN (t)) + if (TREE_CODE (t) == FIELD_DECL) + ++count; + + return count; +} + /* Concatenate two chains of nodes (chained through TREE_CHAIN) by modifying the last node in chain 1 to point to chain 2. This is the Lisp primitive `nconc'. */ @@ -1930,6 +1930,10 @@ extern tree nreverse PARAMS ((tree)); extern int list_length PARAMS ((tree)); +/* Returns the number of FIELD_DECLs in a type. */ + +extern int fields_length PARAMS ((tree)); + /* integer_zerop (tree x) is nonzero if X is an integer constant of value 0 */ extern int integer_zerop PARAMS ((tree)); |