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.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index f1a61cd..42fc250 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -2162,6 +2162,104 @@ type_for_mode (mode, unsignedp)
return 0;
}
+
+/* Return an unsigned type the same as TYPE in other respects. */
+tree
+unsigned_type (type)
+ tree type;
+{
+ tree type1 = TYPE_MAIN_VARIANT (type);
+ if (type1 == signed_char_type_node || type1 == char_type_node)
+ return unsigned_char_type_node;
+ if (type1 == integer_type_node)
+ return unsigned_type_node;
+ if (type1 == short_integer_type_node)
+ return short_unsigned_type_node;
+ if (type1 == long_integer_type_node)
+ return long_unsigned_type_node;
+ if (type1 == long_long_integer_type_node)
+ return long_long_unsigned_type_node;
+ if (type1 == widest_integer_literal_type_node)
+ return widest_unsigned_literal_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if (type1 == intTI_type_node)
+ return unsigned_intTI_type_node;
+#endif
+ if (type1 == intDI_type_node)
+ return unsigned_intDI_type_node;
+ if (type1 == intSI_type_node)
+ return unsigned_intSI_type_node;
+ if (type1 == intHI_type_node)
+ return unsigned_intHI_type_node;
+ if (type1 == intQI_type_node)
+ return unsigned_intQI_type_node;
+
+ return signed_or_unsigned_type (1, type);
+}
+
+/* Return a signed type the same as TYPE in other respects. */
+
+tree
+signed_type (type)
+ tree type;
+{
+ tree type1 = TYPE_MAIN_VARIANT (type);
+ if (type1 == unsigned_char_type_node || type1 == char_type_node)
+ return signed_char_type_node;
+ if (type1 == unsigned_type_node)
+ return integer_type_node;
+ if (type1 == short_unsigned_type_node)
+ return short_integer_type_node;
+ if (type1 == long_unsigned_type_node)
+ return long_integer_type_node;
+ if (type1 == long_long_unsigned_type_node)
+ return long_long_integer_type_node;
+ if (type1 == widest_unsigned_literal_type_node)
+ return widest_integer_literal_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
+ if (type1 == unsigned_intTI_type_node)
+ return intTI_type_node;
+#endif
+ if (type1 == unsigned_intDI_type_node)
+ return intDI_type_node;
+ if (type1 == unsigned_intSI_type_node)
+ return intSI_type_node;
+ if (type1 == unsigned_intHI_type_node)
+ return intHI_type_node;
+ if (type1 == unsigned_intQI_type_node)
+ return intQI_type_node;
+
+ return signed_or_unsigned_type (0, type);
+}
+
+/* Return a type the same as TYPE except unsigned or
+ signed according to UNSIGNEDP. */
+
+tree
+signed_or_unsigned_type (unsignedp, type)
+ int unsignedp;
+ tree type;
+{
+ if (! INTEGRAL_TYPE_P (type)
+ || TREE_UNSIGNED (type) == unsignedp)
+ return type;
+
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+ return unsignedp ? unsigned_type_node : integer_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
+ return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
+ return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
+ return (unsignedp ? long_long_unsigned_type_node
+ : long_long_integer_type_node);
+ if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
+ return (unsignedp ? widest_unsigned_literal_type_node
+ : widest_integer_literal_type_node);
+ return type;
+}
/* Return the minimum number of bits needed to represent VALUE in a
signed or unsigned type, UNSIGNEDP says which. */