summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2002-02-05 17:56:34 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2002-02-05 17:56:34 +0000
commitf04f096ba67176fc3527ae02aa7c350d8389ccb3 (patch)
tree3a2fa33e655d88a836f10525dd980faa2d69aff9
parentc6d86b637864267dc54d3943ee86572dc2c7fbcf (diff)
downloadgcc-f04f096ba67176fc3527ae02aa7c350d8389ccb3.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49526 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/c-decl.c3
-rw-r--r--gcc/doc/tm.texi18
-rw-r--r--gcc/stor-layout.c68
-rw-r--r--gcc/target-def.h4
-rw-r--r--gcc/target.h6
-rw-r--r--gcc/tree.c10
-rw-r--r--gcc/tree.h3
9 files changed, 127 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a8095d881bb..458fccd1fac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f0f2b646371..4dd0a761555 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 073db1c7a94..af6a2c0ef59 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 c81cd269897..ff255238da4 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 91aa4546183..671d65a9c66 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 feeb2c7aa33..bc93b507f7e 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 355a910502c..38ce359eea2 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 86c0cd0036d..28193e9e330 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 842c0a9924f..6c07f5b1ebc 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;