aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2016-01-20 09:01:34 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2016-01-20 09:01:34 +0000
commit825da0d20f71cd82fa58e16e92099879e9a8b8f2 (patch)
tree31f580aa64b5ca42d70c133e1b634e5d8fb6daeb /gcc/ada/gcc-interface/utils.c
parentdd6f2cf98c132d493c9ba7c5602d2ade2efa97f4 (diff)
downloadgcc-825da0d20f71cd82fa58e16e92099879e9a8b8f2.zip
gcc-825da0d20f71cd82fa58e16e92099879e9a8b8f2.tar.gz
gcc-825da0d20f71cd82fa58e16e92099879e9a8b8f2.tar.bz2
exp_ch2.adb (Expand_Current_Value): Make an appropriate character literal if the entity is of a character type.
* exp_ch2.adb (Expand_Current_Value): Make an appropriate character literal if the entity is of a character type. * gcc-interface/lang.opt (fsigned-char): New option. * gcc-interface/misc.c (gnat_handle_option): Accept it. (gnat_init): Adjust comment. * gcc-interface/gigi.h (finish_character_type): New prototype. (maybe_character_type): New inline function. (maybe_character_value): Likewise. * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Enumeration_Type>: For a character of CHAR_TYPE_SIZE, make a signed type if flag_signed_char. Set TYPE_ARTIFICIAL early and call finish_character_type on the type. <E_Enumeration_Subtype>: For a subtype of character with RM_Size and Esize equal to CHAR_TYPE_SIZE, make a signed type if flag_signed_char. Copy TYPE_STRING_FLAG from type to subtype. <E_Array_Type>: Deal with character index types. <E_Array_Subtype>: Likewise. * gcc-interface/trans.c (gigi): Replace unsigned_char_type_node with char_type_node throughout. (build_raise_check): Likewise. (get_type_length): Deal with character types. (Attribute_to_gnu) <Attr_Pos>: Likewise. Remove obsolete range check code. Minor tweak. <Attr_Pred>: Likewise. (Loop_Statement_to_gnu): Likewise. (Raise_Error_to_gnu): Likewise. <N_Indexed_Component>: Deal with character index types. Remove obsolete code. <N_Slice>: Likewise. <N_Type_Conversion>: Deal with character types. Minor tweak. <N_Unchecked_Type_Conversion>: Likewise. <N_In>: Likewise. <N_Op_Eq>: Likewise. (emit_index_check): Delete. * gcc-interface/utils.c (finish_character_type): New function. (gnat_signed_or_unsigned_type_for): Deal with built-in character types. * gcc-interface/utils2.c (expand_sloc): Replace unsigned_char_type_node with char_type_node. (build_call_raise): Likewise. (build_call_raise_column): Likewise. (build_call_raise_range): Likewise. From-SVN: r232604
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 95886f7..0ce571a 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1595,6 +1595,48 @@ record_builtin_type (const char *name, tree type, bool artificial_p)
debug_hooks->type_decl (type_decl, false);
}
+/* Finish constructing the character type CHAR_TYPE.
+
+ In Ada character types are enumeration types and, as a consequence, are
+ represented in the front-end by integral types holding the positions of
+ the enumeration values as defined by the language, which means that the
+ integral types are unsigned.
+
+ Unfortunately the signedness of 'char' in C is implementation-defined
+ and GCC even has the option -fsigned-char to toggle it at run time.
+ Since GNAT's philosophy is to be compatible with C by default, to wit
+ Interfaces.C.char is defined as a mere copy of Character, we may need
+ to declare character types as signed types in GENERIC and generate the
+ necessary adjustments to make them behave as unsigned types.
+
+ The overall strategy is as follows: if 'char' is unsigned, do nothing;
+ if 'char' is signed, translate character types of CHAR_TYPE_SIZE and
+ character subtypes with RM_Size = Esize = CHAR_TYPE_SIZE into signed
+ types. The idea is to ensure that the bit pattern contained in the
+ Esize'd objects is not changed, even though the numerical value will
+ be interpreted differently depending on the signedness.
+
+ For character types, the bounds are implicit and, therefore, need to
+ be adjusted. Morever, the debug info needs the unsigned version. */
+
+void
+finish_character_type (tree char_type)
+{
+ if (TYPE_UNSIGNED (char_type))
+ return;
+
+ /* Make a copy of the unsigned version since we'll modify it below. */
+ tree unsigned_char_type = copy_type (gnat_unsigned_type_for (char_type));
+
+ TYPE_NAME (unsigned_char_type) = TYPE_NAME (char_type);
+ TYPE_STRING_FLAG (unsigned_char_type) = TYPE_STRING_FLAG (char_type);
+ TYPE_ARTIFICIAL (unsigned_char_type) = TYPE_ARTIFICIAL (char_type);
+
+ SET_TYPE_DEBUG_TYPE (char_type, unsigned_char_type);
+ SET_TYPE_RM_MIN_VALUE (char_type, TYPE_MIN_VALUE (unsigned_char_type));
+ SET_TYPE_RM_MAX_VALUE (char_type, TYPE_MAX_VALUE (unsigned_char_type));
+}
+
/* Given a record type RECORD_TYPE and a list of FIELD_DECL nodes FIELD_LIST,
finish constructing the record type as a fat pointer type. */
@@ -3360,6 +3402,9 @@ gnat_type_for_mode (machine_mode mode, int unsignedp)
tree
gnat_signed_or_unsigned_type_for (int unsignedp, tree type_node)
{
+ if (type_node == char_type_node)
+ return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+
tree type = gnat_type_for_size (TYPE_PRECISION (type_node), unsignedp);
if (TREE_CODE (type_node) == INTEGER_TYPE && TYPE_MODULAR_P (type_node))