aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c142
1 files changed, 93 insertions, 49 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 61ae653de2a..c9e90457803 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -367,12 +367,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
switch (kind)
{
case E_Constant:
- /* If this is a use of a deferred constant, get its full
- declaration. */
- if (!definition && Present (Full_View (gnat_entity)))
+ /* If this is a use of a deferred constant without address clause,
+ get its full definition. */
+ if (!definition
+ && No (Address_Clause (gnat_entity))
+ && Present (Full_View (gnat_entity)))
{
- gnu_decl = gnat_to_gnu_entity (Full_View (gnat_entity),
- gnu_expr, 0);
+ gnu_decl
+ = gnat_to_gnu_entity (Full_View (gnat_entity), gnu_expr, 0);
saved = true;
break;
}
@@ -391,12 +393,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
!= N_Allocator))
gnu_expr = gnat_to_gnu (Expression (Declaration_Node (gnat_entity)));
- /* Ignore deferred constant definitions; they are processed fully in the
- front-end. For deferred constant references get the full definition.
- On the other hand, constants that are renamings are handled like
- variable renamings. If No_Initialization is set, this is not a
- deferred constant but a constant whose value is built manually. */
- if (definition && !gnu_expr
+ /* Ignore deferred constant definitions without address clause since
+ they are processed fully in the front-end. If No_Initialization
+ is set, this is not a deferred constant but a constant whose value
+ is built manually. And constants that are renamings are handled
+ like variables. */
+ if (definition
+ && !gnu_expr
+ && No (Address_Clause (gnat_entity))
&& !No_Initialization (Declaration_Node (gnat_entity))
&& No (Renamed_Object (gnat_entity)))
{
@@ -404,12 +408,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
saved = true;
break;
}
- else if (!definition && IN (kind, Incomplete_Or_Private_Kind)
- && Present (Full_View (gnat_entity)))
+
+ /* Ignore constant definitions already marked with the error node. See
+ the N_Object_Declaration case of gnat_to_gnu for the rationale. */
+ if (definition
+ && gnu_expr
+ && present_gnu_tree (gnat_entity)
+ && get_gnu_tree (gnat_entity) == error_mark_node)
{
- gnu_decl = gnat_to_gnu_entity (Full_View (gnat_entity),
- NULL_TREE, 0);
- saved = true;
+ maybe_present = true;
break;
}
@@ -1037,17 +1044,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& !Is_Imported (gnat_entity) && !gnu_expr)
gnu_expr = integer_zero_node;
- /* If we are defining the object and it has an Address clause we must
- get the address expression from the saved GCC tree for the
- object if the object has a Freeze_Node. Otherwise, we elaborate
- the address expression here since the front-end has guaranteed
- in that case that the elaboration has no effects. Note that
- only the latter mechanism is currently in use. */
+ /* If we are defining the object and it has an Address clause, we must
+ either get the address expression from the saved GCC tree for the
+ object if it has a Freeze node, or elaborate the address expression
+ here since the front-end has guaranteed that the elaboration has no
+ effects in this case. */
if (definition && Present (Address_Clause (gnat_entity)))
{
tree gnu_address
- = (present_gnu_tree (gnat_entity) ? get_gnu_tree (gnat_entity)
- : gnat_to_gnu (Expression (Address_Clause (gnat_entity))));
+ = present_gnu_tree (gnat_entity)
+ ? get_gnu_tree (gnat_entity)
+ : gnat_to_gnu (Expression (Address_Clause (gnat_entity)));
save_gnu_tree (gnat_entity, NULL_TREE, false);
@@ -1064,6 +1071,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| compile_time_known_address_p (Expression (Address_Clause
(gnat_entity)));
+ /* If this is a deferred constant, the initializer is attached to
+ the full view. */
+ if (kind == E_Constant && Present (Full_View (gnat_entity)))
+ gnu_expr
+ = gnat_to_gnu
+ (Expression (Declaration_Node (Full_View (gnat_entity))));
+
/* If we don't have an initializing expression for the underlying
variable, the initializing expression for the pointer is the
specified address. Otherwise, we have to make a COMPOUND_EXPR
@@ -1536,15 +1550,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_expr, 0);
gnu_type = make_node (INTEGER_TYPE);
+ TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
+
+ /* Set the precision to the Esize except for bit-packed arrays and
+ subtypes of Standard.Boolean. */
if (Is_Packed_Array_Type (gnat_entity)
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
{
esize = UI_To_Int (RM_Size (gnat_entity));
TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
}
+ else if (TREE_CODE (TREE_TYPE (gnu_type)) == BOOLEAN_TYPE)
+ esize = 1;
TYPE_PRECISION (gnu_type) = esize;
- TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
TYPE_MIN_VALUE (gnu_type)
= convert (TREE_TYPE (gnu_type),
@@ -1596,7 +1615,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
are uninitialized. Both goals are accomplished by wrapping the
modular value in an enclosing struct. */
if (Is_Packed_Array_Type (gnat_entity)
- && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
+ && Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
{
tree gnu_field_type = gnu_type;
tree gnu_field;
@@ -3057,7 +3076,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Discard old fields that are outside the new type.
This avoids confusing code scanning it to decide
- how to pass it to functions on some platforms. */
+ how to pass it to functions on some platforms. */
if (TREE_CODE (gnu_new_pos) == INTEGER_CST
&& TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST
&& !integer_zerop (gnu_size)
@@ -3867,6 +3886,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
;
else if (By_Descriptor_Last <= mech && mech <= By_Descriptor)
mech = By_Descriptor;
+
+ else if (By_Short_Descriptor_Last <= mech &&
+ mech <= By_Short_Descriptor)
+ mech = By_Short_Descriptor;
+
else if (mech > 0)
{
if (TREE_CODE (gnu_param_type) == UNCONSTRAINED_ARRAY_TYPE
@@ -3908,7 +3932,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= chainon (gnu_param, gnu_stub_param_list);
/* Change By_Descriptor parameter to By_Reference for
the internal version of an exported subprogram. */
- if (mech == By_Descriptor)
+ if (mech == By_Descriptor || mech == By_Short_Descriptor)
{
gnu_param
= gnat_to_gnu_param (gnat_param, By_Reference,
@@ -4015,19 +4039,15 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (TREE_CODE (gnu_return_type) == VOID_TYPE)
pure_flag = false;
- /* The semantics of "pure" in Ada essentially matches that of "const"
- in the back-end. In particular, both properties are orthogonal to
- the "nothrow" property. But this is true only if the EH circuitry
- is explicit in the internal representation of the back-end. If we
- are to completely hide the EH circuitry from it, we need to declare
- that calls to pure Ada subprograms that can throw have side effects
- since they can trigger an "abnormal" transfer of control flow; thus
- they can be neither "const" nor "pure" in the back-end sense. */
+ /* The semantics of "pure" in Ada used to essentially match that of
+ "const" in the middle-end. In particular, both properties were
+ orthogonal to the "nothrow" property. This is not true in the
+ middle-end any more and we have no choice but to ignore the hint
+ at this stage. */
+
gnu_type
= build_qualified_type (gnu_type,
TYPE_QUALS (gnu_type)
- | (Exception_Mechanism == Back_End_Exceptions
- ? TYPE_QUAL_CONST * pure_flag : 0)
| (TYPE_QUAL_VOLATILE * volatile_flag));
Sloc_to_locus (Sloc (gnat_entity), &input_location);
@@ -4821,13 +4841,13 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech,
gnu_param_type
= TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (gnu_param_type))));
- /* VMS descriptors are themselves passed by reference.
- Build both a 32bit and 64bit descriptor, one of which will be chosen
- in fill_vms_descriptor based on the allocator size */
+ /* VMS descriptors are themselves passed by reference. */
if (mech == By_Descriptor)
{
+ /* Build both a 32-bit and 64-bit descriptor, one of which will be
+ chosen in fill_vms_descriptor. */
gnu_param_type_alt
- = build_pointer_type (build_vms_descriptor64 (gnu_param_type,
+ = build_pointer_type (build_vms_descriptor32 (gnu_param_type,
Mechanism (gnat_param),
gnat_subprog));
gnu_param_type
@@ -4835,6 +4855,11 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech,
Mechanism (gnat_param),
gnat_subprog));
}
+ else if (mech == By_Short_Descriptor)
+ gnu_param_type
+ = build_pointer_type (build_vms_descriptor32 (gnu_param_type,
+ Mechanism (gnat_param),
+ gnat_subprog));
/* Arrays are passed as pointers to element type for foreign conventions. */
else if (foreign
@@ -4915,6 +4940,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech,
&& !by_ref
&& (by_return
|| (mech != By_Descriptor
+ && mech != By_Short_Descriptor
&& !POINTER_TYPE_P (gnu_param_type)
&& !AGGREGATE_TYPE_P (gnu_param_type)))
&& !(Is_Array_Type (Etype (gnat_param))
@@ -4926,12 +4952,14 @@ gnat_to_gnu_param (Entity_Id gnat_param, Mechanism_Type mech,
ro_param || by_ref || by_component_ptr);
DECL_BY_REF_P (gnu_param) = by_ref;
DECL_BY_COMPONENT_PTR_P (gnu_param) = by_component_ptr;
- DECL_BY_DESCRIPTOR_P (gnu_param) = (mech == By_Descriptor);
+ DECL_BY_DESCRIPTOR_P (gnu_param) = (mech == By_Descriptor ||
+ mech == By_Short_Descriptor);
DECL_POINTS_TO_READONLY_P (gnu_param)
= (ro_param && (by_ref || by_component_ptr));
- /* Save the 64bit descriptor for later. */
- SET_DECL_PARM_ALT (gnu_param, gnu_param_type_alt);
+ /* Save the alternate descriptor type, if any. */
+ if (gnu_param_type_alt)
+ SET_DECL_PARM_ALT_TYPE (gnu_param, gnu_param_type_alt);
/* If no Mechanism was specified, indicate what we're using, then
back-annotate it. */
@@ -7106,7 +7134,8 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
if (TREE_CODE (gnu_type) == INTEGER_TYPE
&& Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
TYPE_RM_SIZE_NUM (gnu_type) = size;
- else if (TREE_CODE (gnu_type) == ENUMERAL_TYPE)
+ else if (TREE_CODE (gnu_type) == ENUMERAL_TYPE
+ || TREE_CODE (gnu_type) == BOOLEAN_TYPE)
TYPE_RM_SIZE_NUM (gnu_type) = size;
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
|| TREE_CODE (gnu_type) == UNION_TYPE
@@ -7124,7 +7153,7 @@ static tree
make_type_from_size (tree type, tree size_tree, bool for_biased)
{
unsigned HOST_WIDE_INT size;
- bool biased_p;
+ bool biased_p, boolean_p;
tree new_type;
/* If size indicates an error, just return TYPE to avoid propagating
@@ -7138,13 +7167,23 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
{
case INTEGER_TYPE:
case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
biased_p = (TREE_CODE (type) == INTEGER_TYPE
&& TYPE_BIASED_REPRESENTATION_P (type));
+ boolean_p = (TREE_CODE (type) == BOOLEAN_TYPE
+ || (TREE_CODE (type) == INTEGER_TYPE
+ && TREE_TYPE (type)
+ && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE));
+
+ if (boolean_p)
+ size = round_up_to_align (size, BITS_PER_UNIT);
+
/* Only do something if the type is not a packed array type and
doesn't already have the proper size. */
if (TYPE_PACKED_ARRAY_TYPE_P (type)
- || (TYPE_PRECISION (type) == size && biased_p == for_biased))
+ || (biased_p == for_biased && TYPE_PRECISION (type) == size)
+ || (boolean_p && compare_tree_int (TYPE_SIZE (type), size) == 0))
break;
biased_p |= for_biased;
@@ -7154,13 +7193,18 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
new_type = make_unsigned_type (size);
else
new_type = make_signed_type (size);
+ if (boolean_p)
+ TYPE_PRECISION (new_type) = 1;
TREE_TYPE (new_type) = TREE_TYPE (type) ? TREE_TYPE (type) : type;
TYPE_MIN_VALUE (new_type)
= convert (TREE_TYPE (new_type), TYPE_MIN_VALUE (type));
TYPE_MAX_VALUE (new_type)
= convert (TREE_TYPE (new_type), TYPE_MAX_VALUE (type));
TYPE_BIASED_REPRESENTATION_P (new_type) = biased_p;
- TYPE_RM_SIZE_NUM (new_type) = bitsize_int (size);
+ if (boolean_p)
+ TYPE_RM_SIZE_NUM (new_type) = bitsize_int (1);
+ else
+ TYPE_RM_SIZE_NUM (new_type) = bitsize_int (size);
return new_type;
case RECORD_TYPE: