]> gcc.gnu.org Git - gcc.git/commitdiff
target.h (struct gcc_target): Added ms_bitfield_layout_p.
authorAlexandre Oliva <aoliva@redhat.com>
Tue, 5 Feb 2002 17:56:34 +0000 (17:56 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Tue, 5 Feb 2002 17:56:34 +0000 (17:56 +0000)
* 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

gcc/ChangeLog
gcc/Makefile.in
gcc/c-decl.c
gcc/doc/tm.texi
gcc/stor-layout.c
gcc/target-def.h
gcc/target.h
gcc/tree.c
gcc/tree.h

index a8095d881bb7a530131a6d8eefae35db001f6288..458fccd1face1e08ac1258444e25567f38717f46 100644 (file)
@@ -1,3 +1,22 @@
+2002-02-05  Alexandre Oliva  <aoliva@redhat.com>
+
+       * 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  <jason@redhat.com>
 
        * c-typeck.c (convert_for_assignment): Don't allow conversions
index f0f2b646371c7e348be40055140795219f726718..4dd0a761555d8bbba51b1c9012d1a3524da71ac7 100644 (file)
@@ -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 \
index 073db1c7a94b7b9cb197b23bdb8a8e4c6c9161fb..af6a2c0ef597ead60758d1e06d805609d27b5982 100644 (file)
@@ -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
index c81cd269897f67d489b799a774c1687e95494295..ff255238da4786f497d61a26f5baa9cdabc76b54 100644 (file)
@@ -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
 
index 91aa454618357c796cfc6d9ee4445be789e1f987..671d65a9c66215199348e530ea26fa4f26aefa2f 100644 (file)
@@ -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
index feeb2c7aa33161afa94142d2c3d2f8b16361ed7f..bc93b507f7e935752aa8b3a6b0ac95bf5d0bdd3c 100644 (file)
@@ -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,                   \
index 355a910502cc44a007ccab660009b7377bb54e3a..38ce359eea2fc7cdcc29900bc4a71ac5b1e68af6 100644 (file)
@@ -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));
 
index 86c0cd0036dd814e042003b88c8c2ae6a5c27148..28193e9e33063ae51c14f128e13dbf37a375dabb 100644 (file)
@@ -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.
 
index 842c0a9924f82d88a511a938fc6d90ebb44da923..6c07f5b1ebcf86711ecb74169dbd89b923c08684 100644 (file)
@@ -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;
This page took 0.097441 seconds and 5 git commands to generate.