struct Elist_Header *elists_ptr, struct Elmt_Item *elmts_ptr,
struct String_Entry *strings_ptr, Char_Code *string_chars_ptr,
struct List_Header *list_headers_ptr, Nat number_file,
- struct File_Info_Type *file_info_ptr, Entity_Id standard_boolean,
- Entity_Id standard_integer, Entity_Id standard_long_long_float,
+ struct File_Info_Type *file_info_ptr,
+ Entity_Id standard_boolean, Entity_Id standard_integer,
+ Entity_Id standard_character, Entity_Id standard_long_long_float,
Entity_Id standard_exception_type, Int gigi_operating_mode)
{
Entity_Id gnat_literal;
double_float_alignment = get_target_double_float_alignment ();
double_scalar_alignment = get_target_double_scalar_alignment ();
- /* Record the builtin types. Define `integer' and `unsigned char' first so
- that dbx will output them first. */
+ /* Record the builtin types. Define `integer' and `character' first so that
+ dbx will output them first. */
record_builtin_type ("integer", integer_type_node);
- record_builtin_type ("unsigned char", char_type_node);
- record_builtin_type ("long integer", long_integer_type_node);
- unsigned_type_node = gnat_type_for_size (INT_TYPE_SIZE, 1);
- record_builtin_type ("unsigned int", unsigned_type_node);
- record_builtin_type (SIZE_TYPE, sizetype);
+ record_builtin_type ("character", unsigned_char_type_node);
record_builtin_type ("boolean", boolean_type_node);
record_builtin_type ("void", void_type_node);
/* Save the type we made for integer as the type for Standard.Integer. */
- save_gnu_tree (Base_Type (standard_integer), TYPE_NAME (integer_type_node),
+ save_gnu_tree (Base_Type (standard_integer),
+ TYPE_NAME (integer_type_node),
false);
- /* Save the type we made for boolean as the type for Standard.Boolean. */
- save_gnu_tree (Base_Type (standard_boolean), TYPE_NAME (boolean_type_node),
+ /* Likewise for character as the type for Standard.Character. */
+ save_gnu_tree (Base_Type (standard_character),
+ TYPE_NAME (unsigned_char_type_node),
+ false);
+
+ /* Likewise for boolean as the type for Standard.Boolean. */
+ save_gnu_tree (Base_Type (standard_boolean),
+ TYPE_NAME (boolean_type_node),
false);
gnat_literal = First_Literal (Base_Type (standard_boolean));
t = UI_To_gnu (Enumeration_Rep (gnat_literal), boolean_type_node);
(get_identifier ("__gnat_last_chance_handler"), NULL_TREE,
build_function_type (void_type_node,
tree_cons (NULL_TREE,
- build_pointer_type (char_type_node),
+ build_pointer_type
+ (unsigned_char_type_node),
tree_cons (NULL_TREE,
integer_type_node,
t))),
build_function_type (void_type_node,
tree_cons (NULL_TREE,
build_pointer_type
- (char_type_node),
+ (unsigned_char_type_node),
tree_cons (NULL_TREE,
integer_type_node,
t))),
TYPE_QUAL_VOLATILE);
}
- /* Set the types that GCC and Gigi use from the front end. We would
- like to do this for char_type_node, but it needs to correspond to
- the C char type. */
+ /* Set the types that GCC and Gigi use from the front end. */
exception_type
= gnat_to_gnu_entity (Base_Type (standard_exception_type), NULL_TREE, 0);
except_type_node = TREE_TYPE (exception_type);
for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; j++)
{
- tree field = create_field_decl (NULL_TREE, ptr_void_ftype,
- fdesc_type_node, 0, 0, 0, 1);
+ tree field
+ = create_field_decl (NULL_TREE, ptr_void_ftype, fdesc_type_node,
+ NULL_TREE, NULL_TREE, 0, 1);
TREE_CHAIN (field) = field_list;
field_list = field;
null_list = tree_cons (field, null_node, null_list);
gnu_expr = gnat_protect_expr (gnu_expr);
gnu_expr
= emit_check
- (build_binary_op (EQ_EXPR, integer_type_node,
+ (build_binary_op (EQ_EXPR, boolean_type_node,
gnu_expr,
attribute == Attr_Pred
? TYPE_MIN_VALUE (gnu_result_type)
if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
{
- tree gnu_char_ptr_type = build_pointer_type (char_type_node);
+ tree gnu_char_ptr_type
+ = build_pointer_type (unsigned_char_type_node);
tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
- tree gnu_byte_offset
- = convert (sizetype,
- size_diffop (size_zero_node, gnu_pos));
- gnu_byte_offset
- = fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
-
gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
- gnu_ptr, gnu_byte_offset);
+ gnu_ptr, gnu_pos);
}
gnu_result = convert (gnu_result_type, gnu_ptr);
gnu_type
= build_unc_object_type_from_ptr (gnu_ptr_type,
gnu_actual_obj_type,
- get_identifier ("SIZE"));
+ get_identifier ("SIZE"),
+ false);
}
gnu_result = TYPE_SIZE (gnu_type);
gnu_result
= build_cond_expr (comp_type,
build_binary_op (GE_EXPR,
- integer_type_node,
+ boolean_type_node,
hb, lb),
gnu_result,
convert (comp_type, integer_zero_node));
test_code = NE_EXPR;
gnu_cond_expr
= build3 (COND_EXPR, void_type_node,
- build_binary_op (LE_EXPR, integer_type_node,
+ build_binary_op (LE_EXPR, boolean_type_node,
gnu_low, gnu_high),
NULL_TREE, alloc_stmt_list ());
set_expr_location_from_node (gnu_cond_expr, gnat_loop_spec);
/* Set either the top or bottom exit condition. */
LOOP_STMT_COND (gnu_loop_stmt)
- = build_binary_op (test_code, integer_type_node, gnu_loop_var,
+ = build_binary_op (test_code, boolean_type_node, gnu_loop_var,
gnu_last);
/* Set either the top or bottom update statement and give it the source
gnat_vms_condition_handler_decl
= create_subprog_decl (get_identifier ("__gnat_handle_vms_condition"),
NULL_TREE,
- build_function_type_list (integer_type_node,
+ build_function_type_list (boolean_type_node,
ptr_void_type_node,
ptr_void_type_node,
NULL_TREE),
tree gnu_subprog_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_subprog);
Entity_Id gnat_formal;
Node_Id gnat_actual;
- tree gnu_actual_list = NULL_TREE;
+ VEC(tree,gc) *gnu_actual_vec = NULL;
tree gnu_name_list = NULL_TREE;
tree gnu_before_list = NULL_TREE;
tree gnu_after_list = NULL_TREE;
gnu_actual = convert (DECL_ARG_TYPE (gnu_formal), gnu_actual);
}
- gnu_actual_list = tree_cons (NULL_TREE, gnu_actual, gnu_actual_list);
+ VEC_safe_push (tree, gc, gnu_actual_vec, gnu_actual);
}
gnu_call = build_call_list (TREE_TYPE (gnu_subprog_type), gnu_subprog_addr,
else
this_choice
= build_binary_op
- (EQ_EXPR, integer_type_node,
+ (EQ_EXPR, boolean_type_node,
convert
(integer_type_node,
build_component_ref
this_choice
= build_binary_op
- (EQ_EXPR, integer_type_node, TREE_VALUE (gnu_except_ptr_stack),
+ (EQ_EXPR, boolean_type_node, TREE_VALUE (gnu_except_ptr_stack),
convert (TREE_TYPE (TREE_VALUE (gnu_except_ptr_stack)),
build_unary_op (ADDR_EXPR, NULL_TREE, gnu_expr)));
this_choice
= build_binary_op
- (TRUTH_ORIF_EXPR, integer_type_node,
- build_binary_op (EQ_EXPR, integer_type_node, gnu_comp,
+ (TRUTH_ORIF_EXPR, boolean_type_node,
+ build_binary_op (EQ_EXPR, boolean_type_node, gnu_comp,
build_int_cst (TREE_TYPE (gnu_comp), 'V')),
this_choice);
}
else
gcc_unreachable ();
- gnu_choice = build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
+ gnu_choice = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
gnu_choice, this_choice);
}
start_stmt_group ();
gnat_pushlevel ();
+ current_function_decl = NULL_TREE;
+
+ start_stmt_group ();
+ gnat_pushlevel ();
+
/* For a body, first process the spec if there is one. */
if (Nkind (Unit (gnat_node)) == N_Package_Body
|| (Nkind (Unit (gnat_node)) == N_Subprogram_Body
could de facto ensure type consistency and this should be preserved. */
if (!(Nkind (Parent (gnat_node)) == N_Assignment_Statement
&& Name (Parent (gnat_node)) == gnat_node)
- && !(Nkind (Parent (gnat_node)) == N_Procedure_Call_Statement
+ && !((Nkind (Parent (gnat_node)) == N_Procedure_Call_Statement
+ || Nkind (Parent (gnat_node)) == N_Function_Call)
&& Name (Parent (gnat_node)) != gnat_node))
return false;
if (to_type == from_type)
return true;
- /* For an array type, the conversion to the PAT is a no-op. */
+ /* For an array subtype, the conversion to the PAT is a no-op. */
if (Ekind (from_type) == E_Array_Subtype
&& to_type == Packed_Array_Type (from_type))
return true;
+ /* For a record subtype, the conversion to the type is a no-op. */
+ if (Ekind (from_type) == E_Record_Subtype
+ && to_type == Etype (from_type))
+ return true;
+
return false;
}
gnu_expr_type = get_base_type (gnu_index_type);
/* Test whether the minimum slice value is too small. */
- gnu_expr_l = build_binary_op (LT_EXPR, integer_type_node,
+ gnu_expr_l = build_binary_op (LT_EXPR, boolean_type_node,
convert (gnu_expr_type,
gnu_min_expr),
convert (gnu_expr_type,
gnu_base_min_expr));
/* Test whether the maximum slice value is too large. */
- gnu_expr_h = build_binary_op (GT_EXPR, integer_type_node,
+ gnu_expr_h = build_binary_op (GT_EXPR, boolean_type_node,
convert (gnu_expr_type,
gnu_max_expr),
convert (gnu_expr_type,
/* Build a slice index check that returns the low bound,
assuming the slice is not empty. */
gnu_expr = emit_check
- (build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
+ (build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
gnu_expr_l, gnu_expr_h),
gnu_min_expr, CE_Index_Check_Failed, gnat_node);
case N_Attribute_Reference:
{
- /* The attribute designator (like an enumeration value). */
- int attribute = Get_Attribute_Id (Attribute_Name (gnat_node));
-
- /* The Elab_Spec and Elab_Body attributes are special in that
- Prefix is a unit, not an object with a GCC equivalent. Similarly
- for Elaborated, since that variable isn't otherwise known. */
- if (attribute == Attr_Elab_Body || attribute == Attr_Elab_Spec)
- return (create_subprog_decl
- (create_concat_name (Entity (Prefix (gnat_node)),
- attribute == Attr_Elab_Body
- ? "elabb" : "elabs"),
- NULL_TREE, void_ftype, NULL_TREE, false, true, true, NULL,
- gnat_node));
-
- gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attribute);
+ /* The attribute designator. */
+ const int attr = Get_Attribute_Id (Attribute_Name (gnat_node));
+
+ /* The Elab_Spec and Elab_Body attributes are special in that Prefix
+ is a unit, not an object with a GCC equivalent. */
+ if (attr == Attr_Elab_Spec || attr == Attr_Elab_Body)
+ return
+ create_subprog_decl (create_concat_name
+ (Entity (Prefix (gnat_node)),
+ attr == Attr_Elab_Body ? "elabb" : "elabs"),
+ NULL_TREE, void_ftype, NULL_TREE, false,
+ true, true, NULL, gnat_node);
+
+ gnu_result = Attribute_to_gnu (gnat_node, &gnu_result_type, attr);
}
break;
gnu_result
= build_cond_expr
(gnu_type,
- build_binary_op (GE_EXPR, integer_type_node,
+ build_binary_op (GE_EXPR, boolean_type_node,
gnu_rhs,
convert (TREE_TYPE (gnu_rhs),
TYPE_SIZE (gnu_type))),
gnu_result
= build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_lhs, gnu_rhs);
- /* If the type being assigned is an array type and the two sides
- are not completely disjoint, play safe and use memmove. */
+ /* If the type being assigned is an array type and the two sides are
+ not completely disjoint, play safe and use memmove. But don't do
+ it for a bit-packed array as it might not be byte-aligned. */
if (TREE_CODE (gnu_result) == MODIFY_EXPR
&& Is_Array_Type (Etype (Name (gnat_node)))
+ && !Is_Bit_Packed_Array (Etype (Name (gnat_node)))
&& !(Forwards_OK (gnat_node) && Backwards_OK (gnat_node)))
{
tree to, from, size, to_ptr, from_ptr, t;
if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
{
- tree gnu_char_ptr_type = build_pointer_type (char_type_node);
+ tree gnu_char_ptr_type
+ = build_pointer_type (unsigned_char_type_node);
tree gnu_pos = byte_position (TYPE_FIELDS (gnu_obj_type));
- tree gnu_byte_offset
- = convert (sizetype,
- size_diffop (size_zero_node, gnu_pos));
- gnu_byte_offset
- = fold_build1 (NEGATE_EXPR, sizetype, gnu_byte_offset);
-
gnu_ptr = convert (gnu_char_ptr_type, gnu_ptr);
gnu_ptr = build_binary_op (POINTER_PLUS_EXPR, gnu_char_ptr_type,
- gnu_ptr, gnu_byte_offset);
+ gnu_ptr, gnu_pos);
}
gnu_result
the reference is in an elaboration procedure. */
if (TREE_CONSTANT (op))
{
- tree new_var = create_tmp_var_raw (TREE_TYPE (op), "C");
- TREE_ADDRESSABLE (new_var) = 1;
- gimple_add_tmp_var (new_var);
-
- TREE_READONLY (new_var) = 1;
- TREE_STATIC (new_var) = 1;
- DECL_INITIAL (new_var) = op;
-
- TREE_OPERAND (expr, 0) = new_var;
- recompute_tree_invariant_for_addr_expr (expr);
+ tree addr = build_fold_addr_expr (tree_output_constant_def (op));
+ *expr_p = fold_convert (TREE_TYPE (expr), addr);
}
/* Otherwise explicitly create the local temporary. That's required
operand = gnat_protect_expr (operand);
- return emit_check (build_binary_op (EQ_EXPR, integer_type_node,
+ return emit_check (build_binary_op (EQ_EXPR, boolean_type_node,
operand, TYPE_MIN_VALUE (gnu_type)),
build_unary_op (code, gnu_type, operand),
CE_Overflow_Check_Failed, gnat_node);
}
rhs_lt_zero = tree_expr_nonnegative_p (rhs)
- ? integer_zero_node
- : build_binary_op (LT_EXPR, integer_type_node, rhs, zero);
+ ? boolean_false_node
+ : build_binary_op (LT_EXPR, boolean_type_node, rhs, zero);
/* ??? Should use more efficient check for operand_equal_p (lhs, rhs, 0) */
convert (wide_type, rhs));
tree check = build_binary_op
- (TRUTH_ORIF_EXPR, integer_type_node,
- build_binary_op (LT_EXPR, integer_type_node, wide_result,
+ (TRUTH_ORIF_EXPR, boolean_type_node,
+ build_binary_op (LT_EXPR, boolean_type_node, wide_result,
convert (wide_type, type_min)),
- build_binary_op (GT_EXPR, integer_type_node, wide_result,
+ build_binary_op (GT_EXPR, boolean_type_node, wide_result,
convert (wide_type, type_max)));
tree result = convert (gnu_type, wide_result);
/* Overflow when (rhs < 0) ^ (wrapped_expr < lhs)), for addition
or when (rhs < 0) ^ (wrapped_expr > lhs) for subtraction. */
tree check = build_binary_op
- (TRUTH_XOR_EXPR, integer_type_node, rhs_lt_zero,
+ (TRUTH_XOR_EXPR, boolean_type_node, rhs_lt_zero,
build_binary_op (code == PLUS_EXPR ? LT_EXPR : GT_EXPR,
- integer_type_node, wrapped_expr, lhs));
+ boolean_type_node, wrapped_expr, lhs));
return
emit_check (check, result, CE_Overflow_Check_Failed, gnat_node);
{
case PLUS_EXPR:
/* When rhs >= 0, overflow when lhs > type_max - rhs. */
- check_pos = build_binary_op (GT_EXPR, integer_type_node, lhs,
+ check_pos = build_binary_op (GT_EXPR, boolean_type_node, lhs,
build_binary_op (MINUS_EXPR, gnu_type,
type_max, rhs)),
/* When rhs < 0, overflow when lhs < type_min - rhs. */
- check_neg = build_binary_op (LT_EXPR, integer_type_node, lhs,
+ check_neg = build_binary_op (LT_EXPR, boolean_type_node, lhs,
build_binary_op (MINUS_EXPR, gnu_type,
type_min, rhs));
break;
case MINUS_EXPR:
/* When rhs >= 0, overflow when lhs < type_min + rhs. */
- check_pos = build_binary_op (LT_EXPR, integer_type_node, lhs,
+ check_pos = build_binary_op (LT_EXPR, boolean_type_node, lhs,
build_binary_op (PLUS_EXPR, gnu_type,
type_min, rhs)),
/* When rhs < 0, overflow when lhs > type_max + rhs. */
- check_neg = build_binary_op (GT_EXPR, integer_type_node, lhs,
+ check_neg = build_binary_op (GT_EXPR, boolean_type_node, lhs,
build_binary_op (PLUS_EXPR, gnu_type,
type_max, rhs));
break;
tmp1 = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_max, rhs);
tmp2 = build_binary_op (TRUNC_DIV_EXPR, gnu_type, type_min, rhs);
- check_pos = build_binary_op (TRUTH_ANDIF_EXPR, integer_type_node,
- build_binary_op (NE_EXPR, integer_type_node, zero, rhs),
- build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
- build_binary_op (GT_EXPR, integer_type_node, lhs, tmp1),
- build_binary_op (LT_EXPR, integer_type_node, lhs, tmp2)));
-
- check_neg = fold_build3 (COND_EXPR, integer_type_node,
- build_binary_op (EQ_EXPR, integer_type_node, rhs,
- build_int_cst (gnu_type, -1)),
- build_binary_op (EQ_EXPR, integer_type_node, lhs, type_min),
- build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
- build_binary_op (GT_EXPR, integer_type_node, lhs, tmp2),
- build_binary_op (LT_EXPR, integer_type_node, lhs, tmp1)));
+ check_pos
+ = build_binary_op (TRUTH_ANDIF_EXPR, boolean_type_node,
+ build_binary_op (NE_EXPR, boolean_type_node, zero,
+ rhs),
+ build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
+ build_binary_op (GT_EXPR,
+ boolean_type_node,
+ lhs, tmp1),
+ build_binary_op (LT_EXPR,
+ boolean_type_node,
+ lhs, tmp2)));
+
+ check_neg
+ = fold_build3 (COND_EXPR, boolean_type_node,
+ build_binary_op (EQ_EXPR, boolean_type_node, rhs,
+ build_int_cst (gnu_type, -1)),
+ build_binary_op (EQ_EXPR, boolean_type_node, lhs,
+ type_min),
+ build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
+ build_binary_op (GT_EXPR,
+ boolean_type_node,
+ lhs, tmp2),
+ build_binary_op (LT_EXPR,
+ boolean_type_node,
+ lhs, tmp1)));
break;
default:
if (TREE_CONSTANT (gnu_expr))
return gnu_expr;
- check = fold_build3 (COND_EXPR, integer_type_node,
- rhs_lt_zero, check_neg, check_pos);
+ check = fold_build3 (COND_EXPR, boolean_type_node, rhs_lt_zero, check_neg,
+ check_pos);
return emit_check (check, gnu_expr, CE_Overflow_Check_Failed, gnat_node);
}
/* Checked expressions must be evaluated only once. */
gnu_expr = gnat_protect_expr (gnu_expr);
- /* There's no good type to use here, so we might as well use
- integer_type_node. Note that the form of the check is
+ /* Note that the form of the check is
(not (expr >= lo)) or (not (expr <= hi))
the reason for this slightly convoluted form is that NaNs
are not considered to be in range in the float case. */
return emit_check
- (build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
+ (build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
invert_truthvalue
- (build_binary_op (GE_EXPR, integer_type_node,
+ (build_binary_op (GE_EXPR, boolean_type_node,
convert (gnu_compare_type, gnu_expr),
convert (gnu_compare_type, gnu_low))),
invert_truthvalue
- (build_binary_op (LE_EXPR, integer_type_node,
+ (build_binary_op (LE_EXPR, boolean_type_node,
convert (gnu_compare_type, gnu_expr),
convert (gnu_compare_type,
gnu_high)))),
gnu_low = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_low, gnu_array_object);
gnu_high = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_high, gnu_array_object);
- /* There's no good type to use here, so we might as well use
- integer_type_node. */
return emit_check
- (build_binary_op (TRUTH_ORIF_EXPR, integer_type_node,
- build_binary_op (LT_EXPR, integer_type_node,
+ (build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node,
+ build_binary_op (LT_EXPR, boolean_type_node,
gnu_expr_check,
convert (TREE_TYPE (gnu_expr_check),
gnu_low)),
- build_binary_op (GT_EXPR, integer_type_node,
+ build_binary_op (GT_EXPR, boolean_type_node,
gnu_expr_check,
convert (TREE_TYPE (gnu_expr_check),
gnu_high))),
: 1))
gnu_cond
= invert_truthvalue
- (build_binary_op (GE_EXPR, integer_type_node,
+ (build_binary_op (GE_EXPR, boolean_type_node,
gnu_input, convert (gnu_in_basetype,
gnu_out_lb)));
TREE_REAL_CST (gnu_in_lb))
: 1))
gnu_cond
- = build_binary_op (TRUTH_ORIF_EXPR, integer_type_node, gnu_cond,
+ = build_binary_op (TRUTH_ORIF_EXPR, boolean_type_node, gnu_cond,
invert_truthvalue
- (build_binary_op (LE_EXPR, integer_type_node,
+ (build_binary_op (LE_EXPR, boolean_type_node,
gnu_input,
convert (gnu_in_basetype,
gnu_out_ub))));
gnu_result = gnat_protect_expr (gnu_result);
gnu_conv = convert (calc_type, gnu_result);
gnu_comp
- = fold_build2 (GE_EXPR, integer_type_node, gnu_result, gnu_zero);
+ = fold_build2 (GE_EXPR, boolean_type_node, gnu_result, gnu_zero);
gnu_add_pred_half
= fold_build2 (PLUS_EXPR, calc_type, gnu_conv, gnu_pred_half);
gnu_subtract_pred_half