diff options
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 25 |
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 |