This is the C front-end + C family part.
* doc/extend.texi (type attributes): Document scalar_storage_order.
(Structure-Packing Pragmas): Rename into...
(Structure-Layout Pragmas): ...this. Document scalar_storage_order.
* doc/invoke.texi (C Dialect Options): Document -fsso-struct
(Warnings): Document -Wno-scalar-storage-order.
* flag-types.h (enum scalar_storage_order_kind): New enumeration.
c-family/
* c-common.c (c_common_attributes): Add scalar_storage_order.
(handle_scalar_storage_order_attribute): New function.
* c-pragma.c (global_sso): New variable.
(maybe_apply_pragma_scalar_storage_order): New function.
(handle_pragma_scalar_storage_order): Likewise.
(init_pragma): Register scalar_storage_order.
* c-pragma.h (maybe_apply_pragma_scalar_storage_order): Declare.
* c.opt (Wscalar-storage-order): New warning.
(fsso-struct=): New option.
c/
* c-decl.c (finish_struct): If the structure has reverse storage
order, rewrite the type of array fields with scalar component. Call
maybe_apply_pragma_scalar_storage_order on entry.
* c-typeck.c (build_unary_op) <ADDR_EXPR>: Remove left-overs. Issue
errors on bit-fields and reverse SSO here and not...
(c_mark_addressable): ...here.
(output_init_element): Adjust call to initializer_constant_valid_p.
(c_build_qualified_type): Propagate TYPE_REVERSE_STORAGE_ORDER.
doc/extend.texi | 69 ++++++++++++++++++++++++++++++++++++++++++--------
doc/invoke.texi | 22 +++++++++++++++-
flag-types.h | 9 +++++-
c-family/c.opt | 17 ++++++++++++
c-family/c-common.c | 47 ++++++++++++++++++++++++++++++++++-
c-family/c-pragma.c | 50 +++++++++++++++++++++++++++++++++++++
c-family/c-pragma.h | 1
c/c-typeck.c | 66 ++++++++++++++++++++++++++++++++++---------------
c/c-decl.c | 48 +++++++++++++++++++++++++-----------
8 files changed, 273 insertions(+), 47 deletions(-)
--
Eric Botcazou
Index: doc/extend.texi
===================================================================
--- doc/extend.texi (.../trunk/gcc) (revision 228112)
+++ doc/extend.texi (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -6310,6 +6310,42 @@ of the structure or union is placed to m
attached to an @code{enum} definition, it indicates that the smallest
integral type should be used.
+@item scalar_storage_order ("@var{endianness}")
+@cindex @code{scalar_storage_order} type attribute
+When attached to a @code{union} or a @code{struct}, this attribute sets
+the storage order, aka endianness, of the scalar fields of the type, as
+well as the array fields whose component is scalar. The supported
+endianness are @code{big-endian} and @code{little-endian}. The attribute
+has no effects on fields which are themselves a @code{union}, a @code{struct}
+or an array whose component is a @code{union} or a @code{struct}, and it is
+possible to have fields with a different scalar storage order than the
+enclosing type.
+
+This attribute is supported only for targets that use a uniform default
+scalar storage order (fortunately, most of them), i.e. targets that store
+the scalars either all in big-endian or all in little-endian.
+
+Additional restrictions are enforced for types with the reverse scalar
+storage order with regard to the scalar storage order of the target:
+
+@itemize
+@item Taking the address of a scalar field of a @code{union} or a
+@code{struct} with reverse scalar storage order is not permitted and will
+yield an error
+@item Taking the address of an array field, whose component is scalar, of
+a @code{union} or a @code{struct} with reverse scalar storage order is
+permitted but will yield a warning, unless @option{-Wno-scalar-storage-order}
+is specified
+@item Taking the address of a @code{union} or a @code{struct} with reverse
+scalar storage order is permitted
+@end itemize
+
+These restrictions exist because the storage order attribute is lost when
+the address of a scalar or the address of an array with scalar component
+is taken, so storing indirectly through this address will generally not work.
+The second case is nevertheless allowed to be able to perform a block copy
+from or to the array.
+
@item transparent_union
@cindex @code{transparent_union} type attribute
@@ -18326,7 +18362,7 @@ for further explanation.
* Darwin Pragmas::
* Solaris Pragmas::
* Symbol-Renaming Pragmas::
-* Structure-Packing Pragmas::
+* Structure-Layout Pragmas::
* Weak Pragmas::
* Diagnostic Pragmas::
* Visibility Pragmas::
@@ -18602,8 +18638,8 @@ the name does not change.
always the C-language name.
@end enumerate
-@node Structure-Packing Pragmas
-@subsection Structure-Packing Pragmas
+@node Structure-Layout Pragmas
+@subsection Structure-Layout Pragmas
For compatibility with Microsoft Windows compilers, GCC supports a
set of @code{#pragma} directives that change the maximum alignment of
@@ -18626,17 +18662,30 @@ multiple @code{#pragma pack(@var{n})} in
@code{#pragma pack(pop)}.
@end enumerate
-Some targets, e.g.@: x86 and PowerPC, support the @code{ms_struct}
-@code{#pragma} which lays out a structure as the documented
-@code{__attribute__ ((ms_struct))}.
+Some targets, e.g.@: x86 and PowerPC, support the @code{#pragma ms_struct}
+directive which lays out structures, unions and classes subsequently defined
+as the documented @code{__attribute__ ((ms_struct))}.
+
@enumerate
-@item @code{#pragma ms_struct on} turns on the layout for structures
-declared.
-@item @code{#pragma ms_struct off} turns off the layout for structures
-declared.
+@item @code{#pragma ms_struct on} turns on the Microsoft layout.
+@item @code{#pragma ms_struct off} turns off the Microsoft layout.
@item @code{#pragma ms_struct reset} goes back to the default layout.
@end enumerate
+Most targets also support the @code{#pragma scalar_storage_order} directive
+which lays out structures, unions and classes subsequently defined as the
+documented @code{__attribute__ ((scalar_storage_order))}.
+
+@enumerate
+@item @code{#pragma scalar_storage_order big-endian} sets the storage order
+of the scalar fields to big-endian.
+@item @code{#pragma scalar_storage_order little-endian} sets the storage order
+of the scalar fields to little-endian.
+@item @code{#pragma scalar_storage_order default} goes back to the endianness
+that was in effect when compilation started (see also command-line option
+@option{-fsso-struct=@var{endianness}} @pxref{C Dialect Options}).
+@end enumerate
+
@node Weak Pragmas
@subsection Weak Pragmas
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi (.../trunk/gcc) (revision 228112)
+++ doc/invoke.texi (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -169,10 +169,11 @@ in the following sections.
-aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} @gol
-fhosted -ffreestanding -fopenacc -fopenmp -fopenmp-simd @gol
--fms-extensions -fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
+-fms-extensions -fplan9-extensions -fsso-struct=@var{endianness}
-fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
-fsigned-bitfields -fsigned-char @gol
--funsigned-bitfields -funsigned-char}
+-funsigned-bitfields -funsigned-char @gol
+-trigraphs -traditional -traditional-cpp}
@item C++ Language Options
@xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
@@ -278,6 +279,7 @@ Objective-C and Objective-C++ Dialects}.
-Wshift-overflow -Wshift-overflow=@var{n} @gol
-Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol
-Wsign-compare -Wsign-conversion -Wfloat-conversion @gol
+-Wno-scalar-storage-order @gol
-Wsizeof-pointer-memaccess -Wsizeof-array-argument @gol
-Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
-Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol
@@ -2069,6 +2071,17 @@ These options control whether a bit-fiel
declaration does not use either @code{signed} or @code{unsigned}. By
default, such a bit-field is signed, because this is consistent: the
basic integer types such as @code{int} are signed types.
+
+@item -fsso-struct=@var{endianness}
+@opindex fsso-struct
+Set the default scalar storage order of structures, unions and classes to
+the specified endianness. The accepted values are @samp{big-endian} and
+@samp{little-endian}. If the option is not passed, the compiler uses the
+native endianness of the target.
+
+@strong{Warning:} the @option{-fsso-struct} switch causes GCC to generate
+code that is not binary compatible with code generated without it if the
+specified endianness is not the native endianness of the target.
@end table
@node C++ Dialect Options
@@ -5087,6 +5100,11 @@ This includes conversions from real to i
real to lower precision real values. This option is also enabled by
@option{-Wconversion}.
+@item -Wno-scalar-storage-order
+@opindex -Wno-scalar-storage-order
+@opindex -Wscalar-storage-order
+Do not warn on suspicious constructs involving reverse scalar storage order.
+
@item -Wsized-deallocation @r{(C++ and Objective-C++ only)}
@opindex Wsized-deallocation
@opindex Wno-sized-deallocation
Index: flag-types.h
===================================================================
--- flag-types.h (.../trunk/gcc) (revision 228112)
+++ flag-types.h (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -158,7 +158,6 @@ enum stack_check_type
/* Names for the different levels of -Wstrict-overflow=N. The numeric
values here correspond to N. */
-
enum warn_strict_overflow_code
{
/* Overflow warning that should be issued with -Wall: a questionable
@@ -188,6 +187,13 @@ enum fp_contract_mode {
FP_CONTRACT_FAST = 2
};
+/* Scalar storage order kind. */
+enum scalar_storage_order_kind {
+ SSO_NATIVE = 0,
+ SSO_BIG_ENDIAN,
+ SSO_LITTLE_ENDIAN
+};
+
/* Vectorizer cost-model. */
enum vect_cost_model {
VECT_COST_MODEL_UNLIMITED = 0,
@@ -196,7 +202,6 @@ enum vect_cost_model {
VECT_COST_MODEL_DEFAULT = 3
};
-
/* Different instrumentation modes. */
enum sanitize_code {
/* AddressSanitizer. */
Index: c-family/c.opt
===================================================================
--- c-family/c.opt (.../trunk/gcc) (revision 228112)
+++ c-family/c.opt (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -784,6 +784,10 @@ Wreturn-type
C ObjC C++ ObjC++ Var(warn_return_type) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)
+Wscalar-storage-order
+C ObjC C++ ObjC++ Init(1) Warning
+Warn on suspicious constructs involving reverse scalar storage order
+
Wselector
ObjC ObjC++ Var(warn_selector) Warning
Warn if a selector has multiple methods
@@ -1447,6 +1451,19 @@ Enable C++14 sized deallocation support
fsquangle
C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
+fsso-struct=
+C C++ Joined RejectNegative Enum(sso_struct) Var(default_sso) Init(SSO_NATIVE)
+-fsso-struct=[big-endian|little-endian] Set the default scalar storage order
+
+Enum
+Name(sso_struct) Type(enum scalar_storage_order_kind) UnknownError(unrecognized scalar storage order value %qs)
+
+EnumValue
+Enum(sso_struct) String(big-endian) Value(SSO_BIG_ENDIAN)
+
+EnumValue
+Enum(sso_struct) String(little-endian) Value(SSO_LITTLE_ENDIAN)
+
fstats
C++ ObjC++ Var(flag_detailed_statistics)
Display statistics accumulated during compilation
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c (.../trunk/gcc) (revision 228112)
+++ c-family/c-common.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -344,6 +344,8 @@ static tree handle_no_reorder_attribute
static tree handle_const_attribute (tree *, tree, tree, int, bool *);
static tree handle_transparent_union_attribute (tree *, tree, tree,
int, bool *);
+static tree handle_scalar_storage_order_attribute (tree *, tree, tree,
+ int, bool *);
static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
@@ -692,6 +694,8 @@ const struct attribute_spec c_common_att
/* The same comments as for noreturn attributes apply to const ones. */
{ "const", 0, 0, true, false, false,
handle_const_attribute, false },
+ { "scalar_storage_order", 1, 1, false, false, false,
+ handle_scalar_storage_order_attribute, false },
{ "transparent_union", 0, 0, false, false, false,
handle_transparent_union_attribute, false },
{ "constructor", 0, 1, true, false, false,
@@ -7636,6 +7640,48 @@ handle_const_attribute (tree *node, tree
return NULL_TREE;
}
+/* Handle a "scalar_storage_order" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_scalar_storage_order_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+{
+ tree id = TREE_VALUE (args);
+ tree type;
+
+ if (TREE_CODE (*node) == TYPE_DECL
+ && ! (flags & ATTR_FLAG_CXX11))
+ node = &TREE_TYPE (*node);
+ type = *node;
+
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ error ("scalar_storage_order is not supported");
+
+ if (RECORD_OR_UNION_TYPE_P (type))
+ {
+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
+ goto ignored;
+
+ if (TREE_CODE (id) == STRING_CST
+ && strcmp (TREE_STRING_POINTER (id), "big-endian") == 0)
+ TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
+ else if (TREE_CODE (id) == STRING_CST
+ && strcmp (TREE_STRING_POINTER (id), "little-endian") == 0)
+ TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
+ else
+ error ("scalar_storage_order argument must be one of \"big-endian\" "
+ "or \"little-endian\"");
+
+ return NULL_TREE;
+ }
+
+ ignored:
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+}
+
/* Handle a "transparent_union" attribute; arguments as in
struct attribute_spec.handler. */
@@ -7648,7 +7694,6 @@ handle_transparent_union_attribute (tree
*no_add_attrs = true;
-
if (TREE_CODE (*node) == TYPE_DECL
&& ! (flags & ATTR_FLAG_CXX11))
node = &TREE_TYPE (*node);
Index: c-family/c-pragma.c
===================================================================
--- c-family/c-pragma.c (.../trunk/gcc) (revision 228112)
+++ c-family/c-pragma.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -394,6 +394,51 @@ handle_pragma_weak (cpp_reader * ARG_UNU
}
}
+static enum scalar_storage_order_kind global_sso;
+
+void
+maybe_apply_pragma_scalar_storage_order (tree type)
+{
+ if (global_sso == SSO_NATIVE)
+ return;
+
+ gcc_assert (RECORD_OR_UNION_TYPE_P (type));
+
+ if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
+ return;
+
+ if (global_sso == SSO_BIG_ENDIAN)
+ TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
+ else if (global_sso == SSO_LITTLE_ENDIAN)
+ TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
+ else
+ gcc_unreachable ();
+}
+
+static void
+handle_pragma_scalar_storage_order (cpp_reader *ARG_UNUSED(dummy))
+{
+ const char *kind_string;
+ enum cpp_ttype token;
+ tree x;
+
+ if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ error ("scalar_storage_order is not supported");
+
+ token = pragma_lex (&x);
+ if (token != CPP_NAME)
+ GCC_BAD ("missing [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
+ kind_string = IDENTIFIER_POINTER (x);
+ if (strcmp (kind_string, "default") == 0)
+ global_sso = default_sso;
+ else if (strcmp (kind_string, "big") == 0)
+ global_sso = SSO_BIG_ENDIAN;
+ else if (strcmp (kind_string, "little") == 0)
+ global_sso = SSO_LITTLE_ENDIAN;
+ else
+ GCC_BAD ("expected [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
+}
+
/* GCC supports two #pragma directives for renaming the external
symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
compatibility with the Solaris and VMS system headers. GCC also
@@ -1485,6 +1530,7 @@ init_pragma (void)
c_register_pragma (0, "pack", handle_pragma_pack);
#endif
c_register_pragma (0, "weak", handle_pragma_weak);
+
c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
@@ -1506,6 +1552,10 @@ init_pragma (void)
REGISTER_TARGET_PRAGMAS ();
#endif
+ global_sso = default_sso;
+ c_register_pragma (0, "scalar_storage_order",
+ handle_pragma_scalar_storage_order);
+
/* Allow plugins to register their own pragmas. */
invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
}
Index: c-family/c-pragma.h
===================================================================
--- c-family/c-pragma.h (.../trunk/gcc) (revision 228112)
+++ c-family/c-pragma.h (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -210,6 +210,7 @@ extern void c_invoke_pragma_handler (uns
extern void maybe_apply_pragma_weak (tree);
extern void maybe_apply_pending_pragma_weaks (void);
extern tree maybe_apply_renaming_pragma (tree, tree);
+extern void maybe_apply_pragma_scalar_storage_order (tree);
extern void add_to_renaming_pragma_list (tree, tree);
extern enum cpp_ttype pragma_lex (tree *, location_t *loc = NULL);
Index: c/c-typeck.c
===================================================================
--- c/c-typeck.c (.../trunk/gcc) (revision 228112)
+++ c/c-typeck.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -4173,18 +4173,10 @@ build_unary_op (location_t location,
goto return_build_unary_op;
}
- /* For &x[y], return x+y */
- if (TREE_CODE (arg) == ARRAY_REF)
- {
- tree op0 = TREE_OPERAND (arg, 0);
- if (!c_mark_addressable (op0))
- return error_mark_node;
- }
-
/* Anything not already handled and not a true memory reference
or a non-lvalue array is an error. */
- else if (typecode != FUNCTION_TYPE && !flag
- && !lvalue_or_else (location, arg, lv_addressof))
+ if (typecode != FUNCTION_TYPE && !flag
+ && !lvalue_or_else (location, arg, lv_addressof))
return error_mark_node;
/* Move address operations inside C_MAYBE_CONST_EXPR to simplify
@@ -4222,6 +4214,39 @@ build_unary_op (location_t location,
argtype = c_build_qualified_type (argtype, quals);
}
+ switch (TREE_CODE (arg))
+ {
+ case COMPONENT_REF:
+ if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
+ {
+ error ("cannot take address of bit-field %qD",
+ TREE_OPERAND (arg, 1));
+ return error_mark_node;
+ }
+
+ /* ... fall through ... */
+
+ case ARRAY_REF:
+ if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (arg, 0))))
+ {
+ if (!AGGREGATE_TYPE_P (TREE_TYPE (arg))
+ && !VECTOR_TYPE_P (TREE_TYPE (arg)))
+ {
+ error ("cannot take address of scalar with reverse storage "
+ "order");
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
+ && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (arg)))
+ warning (OPT_Wscalar_storage_order, "address of array with "
+ "reverse scalar storage order requested");
+ }
+
+ default:
+ break;
+ }
+
if (!c_mark_addressable (arg))
return error_mark_node;
@@ -4364,15 +4389,6 @@ c_mark_addressable (tree exp)
switch (TREE_CODE (x))
{
case COMPONENT_REF:
- if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
- {
- error
- ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1));
- return false;
- }
-
- /* ... fall through ... */
-
case ADDR_EXPR:
case ARRAY_REF:
case REALPART_EXPR:
@@ -8423,7 +8439,11 @@ output_init_element (location_t loc, tre
constructor_erroneous = 1;
else if (!TREE_CONSTANT (value))
constructor_constant = 0;
- else if (!initializer_constant_valid_p (value, TREE_TYPE (value))
+ else if (!initializer_constant_valid_p (value,
+ TREE_TYPE (value),
+ AGGREGATE_TYPE_P (constructor_type)
+ && TYPE_REVERSE_STORAGE_ORDER
+ (constructor_type))
|| ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& DECL_C_BIT_FIELD (field)
@@ -12661,6 +12681,12 @@ c_build_qualified_type (tree type, int t
= build_array_type (TYPE_CANONICAL (element_type),
domain? TYPE_CANONICAL (domain)
: NULL_TREE);
+ if (TYPE_REVERSE_STORAGE_ORDER (type))
+ {
+ unqualified_canon
+ = build_distinct_type_copy (unqualified_canon);
+ TYPE_REVERSE_STORAGE_ORDER (unqualified_canon) = 1;
+ }
TYPE_CANONICAL (t)
= c_build_qualified_type (unqualified_canon, type_quals);
}
Index: c/c-decl.c
===================================================================
--- c/c-decl.c (.../trunk/gcc) (revision 228112)
+++ c/c-decl.c (.../branches/scalar-storage-order/gcc) (revision 228133)
@@ -7723,6 +7723,8 @@ finish_struct (location_t loc, tree t, t
TYPE_FIELDS (t) = fieldlist;
+ maybe_apply_pragma_scalar_storage_order (t);
+
layout_type (t);
if (TYPE_SIZE_UNIT (t)
@@ -7731,27 +7733,45 @@ finish_struct (location_t loc, tree t, t
&& !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
error ("type %qT is too large", t);
- /* Give bit-fields their proper types. */
- {
- tree *fieldlistp = &fieldlist;
- while (*fieldlistp)
- if (TREE_CODE (*fieldlistp) == FIELD_DECL && DECL_INITIAL (*fieldlistp)
- && TREE_TYPE (*fieldlistp) != error_mark_node)
+ /* Give bit-fields their proper types and rewrite the type of array fields
+ with scalar component if the enclosing type has reverse storage order. */
+ for (tree field = fieldlist; field; field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL
+ && DECL_INITIAL (field)
+ && TREE_TYPE (field) != error_mark_node)
{
unsigned HOST_WIDE_INT width
- = tree_to_uhwi (DECL_INITIAL (*fieldlistp));
- tree type = TREE_TYPE (*fieldlistp);
+ = tree_to_uhwi (DECL_INITIAL (field));
+ tree type = TREE_TYPE (field);
if (width != TYPE_PRECISION (type))
{
- TREE_TYPE (*fieldlistp)
+ TREE_TYPE (field)
= c_build_bitfield_integer_type (width, TYPE_UNSIGNED (type));
- DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
+ DECL_MODE (field) = TYPE_MODE (TREE_TYPE (field));
+ }
+ DECL_INITIAL (field) = 0;
+ }
+ else if (TYPE_REVERSE_STORAGE_ORDER (t)
+ && TREE_CODE (field) == FIELD_DECL
+ && TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+ {
+ tree ftype = TREE_TYPE (field);
+ tree ctype = strip_array_types (ftype);
+ if (!RECORD_OR_UNION_TYPE_P (ctype) && TYPE_MODE (ctype) != QImode)
+ {
+ tree fmain_type = TYPE_MAIN_VARIANT (ftype);
+ tree *typep = &fmain_type;
+ do {
+ *typep = build_distinct_type_copy (*typep);
+ TYPE_REVERSE_STORAGE_ORDER (*typep) = 1;
+ typep = &TREE_TYPE (*typep);
+ } while (TREE_CODE (*typep) == ARRAY_TYPE);
+ TREE_TYPE (field)
+ = c_build_qualified_type (fmain_type, TYPE_QUALS (ftype));
}
- DECL_INITIAL (*fieldlistp) = 0;
}
- else
- fieldlistp = &DECL_CHAIN (*fieldlistp);
- }
+ }
/* Now we have the truly final field list.
Store it in this type and in the variants. */