aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 1a11c3b..35982e5 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1871,6 +1871,31 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
}
+/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */
+
+tree
+c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
+{
+ /* Extended integer types of the same width as a standard type have
+ lesser rank, so those of the same width as int promote to int or
+ unsigned int and are valid for printf formats expecting int or
+ unsigned int. To avoid such special cases, avoid creating
+ extended integer types for bit-fields if a standard integer type
+ is available. */
+ if (width == TYPE_PRECISION (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+ if (width == TYPE_PRECISION (signed_char_type_node))
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+ if (width == TYPE_PRECISION (short_integer_type_node))
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+ if (width == TYPE_PRECISION (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+ if (width == TYPE_PRECISION (long_long_integer_type_node))
+ return (unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+ return build_nonstandard_integer_type (width, unsignedp);
+}
+
/* The C version of the register_builtin_type langhook. */
void