From: Alexandre Oliva Date: Tue, 5 Feb 2002 17:56:34 +0000 (+0000) Subject: target.h (struct gcc_target): Added ms_bitfield_layout_p. X-Git-Tag: prereleases/libstdc++-3.0.97~577 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=f913c102a4836355a7d9769a7d5998f27032ed98;p=gcc.git target.h (struct gcc_target): Added ms_bitfield_layout_p. * target.h (struct gcc_target): Added ms_bitfield_layout_p. * target-def.h (TARGET_MS_BITFIELD_LAYOUT_P): New. Added to... (TARGET_INITIALIZER): this. * doc/tm.texi (TARGET_MS_BITFIELD_LAYOUT_P): Document. (BITFIELD_NBYTES_LIMITED): Markup fix. * tree.h (default_ms_bitfield_layout_p): Declare. (record_layout_info): Added prev_field. * tree.c (default_ms_bitfield_layout_p): New fn. * c-decl.c (finish_struct): Disregard EMPTY_FIELD_BOUNDARY and PCC_BITFIELD_TYPE_MATTERS for MS bit-field layout. * stor-layout.c: Include target.h. (start_record_layout): Initialize prev_field. (place_field): Handle MS bit-field layout, and disregard EMPTY_FIELD_BOUNDARY, BITFIELD_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS in this case. Update prev_field. * Makefile.in (stor-layout.o): Adjust dependencies. From-SVN: r49526 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8095d881bb7..458fccd1face 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2002-02-05 Alexandre Oliva + + * target.h (struct gcc_target): Added ms_bitfield_layout_p. + * target-def.h (TARGET_MS_BITFIELD_LAYOUT_P): New. Added to... + (TARGET_INITIALIZER): this. + * doc/tm.texi (TARGET_MS_BITFIELD_LAYOUT_P): Document. + (BITFIELD_NBYTES_LIMITED): Markup fix. + * tree.h (default_ms_bitfield_layout_p): Declare. + (record_layout_info): Added prev_field. + * tree.c (default_ms_bitfield_layout_p): New fn. + * c-decl.c (finish_struct): Disregard EMPTY_FIELD_BOUNDARY and + PCC_BITFIELD_TYPE_MATTERS for MS bit-field layout. + * stor-layout.c: Include target.h. + (start_record_layout): Initialize prev_field. + (place_field): Handle MS bit-field layout, and disregard + EMPTY_FIELD_BOUNDARY, BITFIELD_NBYTES_LIMITED and + PCC_BITFIELD_TYPE_MATTERS in this case. Update prev_field. + * Makefile.in (stor-layout.o): Adjust dependencies. + 2002-02-05 Jason Merrill * c-typeck.c (convert_for_assignment): Don't allow conversions diff --git a/gcc/Makefile.in b/gcc/Makefile.in index f0f2b646371c..4dd0a761555d 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1335,7 +1335,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \ print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H) \ langhooks.h stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \ - function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) + function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H) fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \ toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) $(TM_P_H) diagnostic.o : diagnostic.c diagnostic.h real.h diagnostic.def \ diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 073db1c7a94b..af6a2c0ef597 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -5727,7 +5727,8 @@ finish_struct (t, fieldlist, attributes) DECL_BIT_FIELD (x) = 1; SET_DECL_C_BIT_FIELD (x); - if (width == 0) + if (width == 0 + && ! (* targetm.ms_bitfield_layout_p) (t)) { /* field size 0 => force desired amount of alignment. */ #ifdef EMPTY_FIELD_BOUNDARY diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c81cd269897f..ff255238da47 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1199,8 +1199,8 @@ get from @code{PCC_BITFIELD_TYPE_MATTERS}. @findex BITFIELD_NBYTES_LIMITED @item BITFIELD_NBYTES_LIMITED -Like PCC_BITFIELD_TYPE_MATTERS except that its effect is limited to -aligning a bit-field within the structure. +Like @code{PCC_BITFIELD_TYPE_MATTERS} except that its effect is limited +to aligning a bit-field within the structure. @findex MEMBER_TYPE_FORCES_BLK @item MEMBER_TYPE_FORCES_BLK (@var{field}) @@ -1329,6 +1329,20 @@ memory is controlled by @code{FLOAT_WORDS_BIG_ENDIAN}. @end table +@deftypefn {Target Hook} bool TARGET_MS_BITFIELD_LAYOUT_P (tree @var{record_type}) +This target hook returns @code{true} if bit-fields in the given +@var{record_type} are to be laid out following the rules of Microsoft +Visual C/C++, namely: (i) a bit-field won't share the same storage +unit with the previous bit-field if their underlying types have +different sizes, and the bit-field will be aligned to the highest +alignment of the underlying types of itself and of the previous +bit-field; (ii) a zero-sized bit-field will affect the alignment of +the whole enclosing structure, even if it is unnamed; except that +(iii) a zero-sized bit-field will be disregarded unless it follows +another bit-field of non-zero size. If this hook returns @code{true}, +other macros that control bit-field layout are ignored. +@end deftypefn + @node Type Layout @section Layout of Source Language Data Types diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 91aa45461835..671d65a9c662 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "expr.h" #include "toplev.h" #include "ggc.h" +#include "target.h" /* Set to one when set_sizetype has been called. */ static int sizetype_set; @@ -503,6 +504,7 @@ start_record_layout (t) rli->offset = size_zero_node; rli->bitpos = bitsize_zero_node; + rli->prev_field = 0; rli->pending_statics = 0; rli->packed_maybe_necessary = 0; @@ -787,8 +789,26 @@ place_field (rli, field) /* Record must have at least as much alignment as any field. Otherwise, the alignment of the field within the record is meaningless. */ + if ((* targetm.ms_bitfield_layout_p) (rli->t) + && type != error_mark_node + && DECL_BIT_FIELD_TYPE (field) + && ! integer_zerop (TYPE_SIZE (type)) + && integer_zerop (DECL_SIZE (field))) + { + if (rli->prev_field + && DECL_BIT_FIELD_TYPE (rli->prev_field) + && ! integer_zerop (DECL_SIZE (rli->prev_field))) + { + rli->record_align = MAX (rli->record_align, desired_align); + rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type)); + } + else + desired_align = 1; + } + else #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node + && ! (* targetm.ms_bitfield_layout_p) (rli->t) && DECL_BIT_FIELD_TYPE (field) && ! integer_zerop (TYPE_SIZE (type))) { @@ -878,6 +898,7 @@ place_field (rli, field) variable-sized fields, we need not worry about compatibility. */ #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS + && ! (* targetm.ms_bitfield_layout_p) (rli->t) && TREE_CODE (field) == FIELD_DECL && type != error_mark_node && DECL_BIT_FIELD (field) @@ -907,6 +928,7 @@ place_field (rli, field) #ifdef BITFIELD_NBYTES_LIMITED if (BITFIELD_NBYTES_LIMITED + && ! (* targetm.ms_bitfield_layout_p) (rli->t) && TREE_CODE (field) == FIELD_DECL && type != error_mark_node && DECL_BIT_FIELD_TYPE (field) @@ -940,6 +962,50 @@ place_field (rli, field) } #endif + /* See the docs for TARGET_MS_BITFIELD_LAYOUT_P for details. */ + if ((* targetm.ms_bitfield_layout_p) (rli->t) + && TREE_CODE (field) == FIELD_DECL + && type != error_mark_node + && ! DECL_PACKED (field) + && rli->prev_field + && DECL_SIZE (field) + && host_integerp (DECL_SIZE (field), 1) + && DECL_SIZE (rli->prev_field) + && host_integerp (DECL_SIZE (rli->prev_field), 1) + && host_integerp (rli->offset, 1) + && host_integerp (TYPE_SIZE (type), 1) + && host_integerp (TYPE_SIZE (TREE_TYPE (rli->prev_field)), 1) + && ((DECL_BIT_FIELD_TYPE (rli->prev_field) + && ! integer_zerop (DECL_SIZE (rli->prev_field))) + || (DECL_BIT_FIELD_TYPE (field) + && ! integer_zerop (DECL_SIZE (field)))) + && (! simple_cst_equal (TYPE_SIZE (type), + TYPE_SIZE (TREE_TYPE (rli->prev_field))) + /* If the previous field was a zero-sized bit-field, either + it was ignored, in which case we must ensure the proper + alignment of this field here, or it already forced the + alignment of this field, in which case forcing the + alignment again is harmless. So, do it in both cases. */ + || (DECL_BIT_FIELD_TYPE (rli->prev_field) + && integer_zerop (DECL_SIZE (rli->prev_field))))) + { + unsigned int type_align = TYPE_ALIGN (type); + + if (rli->prev_field + && DECL_BIT_FIELD_TYPE (rli->prev_field) + /* If the previous bit-field is zero-sized, we've already + accounted for its alignment needs (or ignored it, if + appropriate) while placing it. */ + && ! integer_zerop (DECL_SIZE (rli->prev_field))) + type_align = MAX (type_align, + TYPE_ALIGN (TREE_TYPE (rli->prev_field))); + + if (maximum_field_alignment != 0) + type_align = MIN (type_align, maximum_field_alignment); + + rli->bitpos = round_up (rli->bitpos, type_align); + } + /* Offset so far becomes the position of this field after normalizing. */ normalize_rli (rli); DECL_FIELD_OFFSET (field) = rli->offset; @@ -966,6 +1032,8 @@ place_field (rli, field) if (known_align != actual_align) layout_decl (field, actual_align); + rli->prev_field = field; + /* Now add size of this field to the size of the record. If the size is not constant, treat the field as being a multiple of bytes and just adjust the offset, resetting the bit position. Otherwise, apportion the diff --git a/gcc/target-def.h b/gcc/target-def.h index feeb2c7aa331..bc93b507f7e9 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -1,5 +1,5 @@ /* Default initializers for a generic GCC target. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -164,6 +164,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES default_set_default_type_attributes #define TARGET_INSERT_ATTRIBUTES default_insert_attributes #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P default_function_attribute_inlinable_p +#define TARGET_MS_BITFIELD_LAYOUT_P default_ms_bitfield_layout_p /* In builtins.c. */ #define TARGET_INIT_BUILTINS default_init_builtins @@ -186,6 +187,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. TARGET_SET_DEFAULT_TYPE_ATTRIBUTES, \ TARGET_INSERT_ATTRIBUTES, \ TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P, \ + TARGET_MS_BITFIELD_LAYOUT_P, \ TARGET_INIT_BUILTINS, \ TARGET_EXPAND_BUILTIN, \ TARGET_SECTION_TYPE_FLAGS, \ diff --git a/gcc/target.h b/gcc/target.h index 355a910502cc..38ce359eea2f 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -1,5 +1,5 @@ /* Data structure definitions for a generic GCC target. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -162,6 +162,10 @@ struct gcc_target can be inlined despite its machine attributes, false otherwise. */ bool (* function_attribute_inlinable_p) PARAMS ((tree fndecl)); + /* Return true if bitfields in RECORD_TYPE should follow the + Microsoft Visual C++ bitfield layout rules. */ + bool (* ms_bitfield_layout_p) PARAMS ((tree record_type)); + /* Set up target-specific built-in functions. */ void (* init_builtins) PARAMS ((void)); diff --git a/gcc/tree.c b/gcc/tree.c index 86c0cd0036dd..28193e9e3306 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2736,6 +2736,16 @@ default_function_attribute_inlinable_p (fndecl) return false; } +/* Default value of targetm.ms_bitfield_layout_p that always returns + false. */ +bool +default_ms_bitfield_layout_p (record) + tree record ATTRIBUTE_UNUSED; +{ + /* By default, GCC does not use the MS VC++ bitfield layout rules. */ + return false; +} + /* Return non-zero if IDENT is a valid name for attribute ATTR, or zero if not. diff --git a/gcc/tree.h b/gcc/tree.h index 842c0a9924f8..6c07f5b1ebcf 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2234,6 +2234,7 @@ extern int default_comp_type_attributes PARAMS ((tree, tree)); extern void default_set_default_type_attributes PARAMS ((tree)); extern void default_insert_attributes PARAMS ((tree, tree *)); extern bool default_function_attribute_inlinable_p PARAMS ((tree)); +extern bool default_ms_bitfield_layout_p PARAMS ((tree)); /* Split a list of declspecs and attributes into two. */ @@ -2323,6 +2324,8 @@ typedef struct record_layout_info_s /* The alignment of the record so far, allowing for the record to be padded only at the end, in bits. */ unsigned int unpadded_align; + /* The previous field layed out. */ + tree prev_field; /* The static variables (i.e., class variables, as opposed to instance variables) encountered in T. */ tree pending_statics;