From 5e9bec999ea3f54fc6abfabc9d43bacfdd550892 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Sun, 27 Jun 1993 21:14:04 -0400 Subject: [PATCH] Add prototypes for layout_record and layout_union. (smallest_mode_for_size): New function. (variable_size): Allow variable sizes if global_bindings_p returns a negative value. (mode_for_size): Fix incorrect comment. (layout_decl): If DECL has a size already, don't copy from type. (layout_type, case INTEGER_TYPE, ENUMERAL_TYPE): Use smallest integer mode that fits, whether or not it fits exactly. From-SVN: r4776 --- gcc/stor-layout.c | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index c0efe3dab89..620c0bb2b91 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1,5 +1,5 @@ /* C-compiler utilities for types and variables storage layout - Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc. This file is part of GNU CC. @@ -47,6 +47,11 @@ int maximum_field_alignment; #define GET_MODE_ALIGNMENT(MODE) \ MIN (BIGGEST_ALIGNMENT, \ MAX (1, (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))) + +static enum machine_mode smallest_mode_for_size PROTO((unsigned int, + enum mode_class)); +static tree layout_record PROTO((tree)); +static void layout_union PROTO((tree)); /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */ @@ -79,7 +84,13 @@ variable_size (size) { size = save_expr (size); - if (global_bindings_p ()) + /* If the language-processor is to take responsibility for variable-sized + items (e.g., languages which have elaboration procedures like Ada), + just return SIZE unchanged. */ + if (global_bindings_p () < 0) + return size; + + else if (global_bindings_p ()) { if (TREE_CONSTANT (size)) error ("type size can't be explicitly evaluated"); @@ -120,7 +131,7 @@ mode_for_size (size, class, limit) if (limit && size > MAX_FIXED_MODE_SIZE) return BLKmode; - /* Get the last mode which has this size, in the specified class. */ + /* Get the first mode which has this size, in the specified class. */ for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) if (GET_MODE_BITSIZE (mode) == size) @@ -129,6 +140,26 @@ mode_for_size (size, class, limit) return BLKmode; } +/* Similar, but never return BLKmode; return the narrowest mode that + contains at least the requested number of bits. */ + +static enum machine_mode +smallest_mode_for_size (size, class) + unsigned int size; + enum mode_class class; +{ + register enum machine_mode mode; + + /* Get the first mode which has at least this size, in the + specified class. */ + for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode; + mode = GET_MODE_WIDER_MODE (mode)) + if (GET_MODE_BITSIZE (mode) >= size) + return mode; + + abort (); +} + /* Return the value of VALUE, rounded up to a multiple of DIVISOR. */ tree @@ -179,8 +210,9 @@ layout_decl (decl, known_align) /* Usually the size and mode come from the data type without change. */ DECL_MODE (decl) = TYPE_MODE (type); - DECL_SIZE (decl) = TYPE_SIZE (type); TREE_UNSIGNED (decl) = TREE_UNSIGNED (type); + if (DECL_SIZE (decl) == 0) + DECL_SIZE (decl) = TYPE_SIZE (type); if (code == FIELD_DECL && DECL_BIT_FIELD (decl)) { @@ -669,11 +701,8 @@ layout_type (type) if (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) >= 0) TREE_UNSIGNED (type) = 1; - /* We pass 0 for the last arg of mode_for_size because otherwise - on the Apollo using long long causes a crash. - It seems better to use integer modes than to try to support - integer types with BLKmode. */ - TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_INT, 0); + TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type), + MODE_INT); TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type))); break; -- 2.30.2