summaryrefslogtreecommitdiff
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.c136
1 files changed, 86 insertions, 50 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index dfefff2e7a7..a5205ceeb66 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -106,8 +106,6 @@ typedef struct subst_pair_d {
tree replacement;
} subst_pair;
-DEF_VEC_O(subst_pair);
-DEF_VEC_ALLOC_O(subst_pair,heap);
typedef struct variant_desc_d {
/* The type of the variant. */
@@ -123,8 +121,6 @@ typedef struct variant_desc_d {
tree new_type;
} variant_desc;
-DEF_VEC_O(variant_desc);
-DEF_VEC_ALLOC_O(variant_desc,heap);
/* A hash table used to cache the result of annotate_value. */
static GTY ((if_marked ("tree_int_map_marked_p"),
@@ -153,21 +149,21 @@ static void components_to_record (tree, Node_Id, tree, int, bool, bool, bool,
static Uint annotate_value (tree);
static void annotate_rep (Entity_Id, tree);
static tree build_position_list (tree, bool, tree, tree, unsigned int, tree);
-static VEC(subst_pair,heap) *build_subst_list (Entity_Id, Entity_Id, bool);
-static VEC(variant_desc,heap) *build_variant_list (tree,
- VEC(subst_pair,heap) *,
- VEC(variant_desc,heap) *);
+static vec<subst_pair> build_subst_list (Entity_Id, Entity_Id, bool);
+static vec<variant_desc> build_variant_list (tree,
+ vec<subst_pair> ,
+ vec<variant_desc> );
static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool);
static void set_rm_size (Uint, tree, Entity_Id);
static unsigned int validate_alignment (Uint, Entity_Id, unsigned int);
static void check_ok_for_atomic (tree, Entity_Id, bool);
static tree create_field_decl_from (tree, tree, tree, tree, tree,
- VEC(subst_pair,heap) *);
+ vec<subst_pair> );
static tree create_rep_part (tree, tree, tree);
static tree get_rep_part (tree);
-static tree create_variant_part_from (tree, VEC(variant_desc,heap) *, tree,
- tree, VEC(subst_pair,heap) *);
-static void copy_and_substitute_in_size (tree, tree, VEC(subst_pair,heap) *);
+static tree create_variant_part_from (tree, vec<variant_desc> , tree,
+ tree, vec<subst_pair> );
+static void copy_and_substitute_in_size (tree, tree, vec<subst_pair> );
/* The relevant constituents of a subprogram binding to a GCC builtin. Used
to pass around calls performing profile compatibility checks. */
@@ -1157,7 +1153,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= TYPE_PADDING_P (gnu_type)
? TYPE_FIELDS (TREE_TYPE (TYPE_FIELDS (gnu_type)))
: TYPE_FIELDS (gnu_type);
- VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 1);
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, 1);
tree t = build_template (TREE_TYPE (template_field),
TREE_TYPE (DECL_CHAIN (template_field)),
NULL_TREE);
@@ -1329,8 +1326,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (gnu_alloc_type)));
if (TREE_CODE (gnu_expr) == CONSTRUCTOR
- && 1 == VEC_length (constructor_elt,
- CONSTRUCTOR_ELTS (gnu_expr)))
+ && 1 == vec_safe_length (CONSTRUCTOR_ELTS (gnu_expr)))
gnu_expr = 0;
else
gnu_expr
@@ -3293,13 +3289,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& Present (Discriminant_Constraint (gnat_entity))
&& Stored_Constraint (gnat_entity) != No_Elist)
{
- VEC(subst_pair,heap) *gnu_subst_list
+ vec<subst_pair> gnu_subst_list
= build_subst_list (gnat_entity, gnat_base_type, definition);
tree gnu_unpad_base_type, gnu_rep_part, gnu_variant_part, t;
tree gnu_pos_list, gnu_field_list = NULL_TREE;
bool selected_variant = false;
Entity_Id gnat_field;
- VEC(variant_desc,heap) *gnu_variant_list;
+ vec<variant_desc> gnu_variant_list;
gnu_type = make_node (RECORD_TYPE);
TYPE_NAME (gnu_type) = gnu_entity_name;
@@ -3330,12 +3326,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_variant_list
= build_variant_list (TREE_TYPE (gnu_variant_part),
- gnu_subst_list, NULL);
+ gnu_subst_list,
+ vNULL);
/* If all the qualifiers are unconditionally true, the
innermost variant is statically selected. */
selected_variant = true;
- FOR_EACH_VEC_ELT (variant_desc, gnu_variant_list, i, v)
+ FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
if (!integer_onep (v->qual))
{
selected_variant = false;
@@ -3344,7 +3341,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Otherwise, create the new variants. */
if (!selected_variant)
- FOR_EACH_VEC_ELT (variant_desc, gnu_variant_list, i, v)
+ FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
{
tree old_variant = v->type;
tree new_variant = make_node (RECORD_TYPE);
@@ -3362,13 +3359,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
else
{
- gnu_variant_list = NULL;
+ gnu_variant_list.create (0);
selected_variant = false;
}
gnu_pos_list
= build_position_list (gnu_unpad_base_type,
- gnu_variant_list && !selected_variant,
+ gnu_variant_list.exists ()
+ && !selected_variant,
size_zero_node, bitsize_zero_node,
BIGGEST_ALIGNMENT, NULL_TREE);
@@ -3449,7 +3447,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
unsigned int i;
t = NULL_TREE;
- FOR_EACH_VEC_ELT (variant_desc, gnu_variant_list, i, v)
+ FOR_EACH_VEC_ELT (gnu_variant_list, i, v)
if (gnu_context == v->type
|| ((gnu_rep_part = get_rep_part (v->type))
&& gnu_context == TREE_TYPE (gnu_rep_part)))
@@ -3515,7 +3513,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* If there is a variant list and no selected variant, we need
to create the nest of variant parts from the old nest. */
- if (gnu_variant_list && !selected_variant)
+ if (gnu_variant_list.exists () && !selected_variant)
{
tree new_variant_part
= create_variant_part_from (gnu_variant_part,
@@ -3587,8 +3585,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnat_entity);
}
- VEC_free (variant_desc, heap, gnu_variant_list);
- VEC_free (subst_pair, heap, gnu_subst_list);
+ gnu_variant_list.release ();
+ gnu_subst_list.release ();
/* Now we can finalize it. */
rest_of_record_type_compilation (gnu_type);
@@ -6652,6 +6650,30 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
return gnu_field;
}
+/* Return true if at least one member of COMPONENT_LIST needs strict
+ alignment. */
+
+static bool
+components_need_strict_alignment (Node_Id component_list)
+{
+ Node_Id component_decl;
+
+ for (component_decl = First_Non_Pragma (Component_Items (component_list));
+ Present (component_decl);
+ component_decl = Next_Non_Pragma (component_decl))
+ {
+ Entity_Id gnat_field = Defining_Entity (component_decl);
+
+ if (Is_Aliased (gnat_field))
+ return True;
+
+ if (Strict_Alignment (Etype (gnat_field)))
+ return True;
+ }
+
+ return False;
+}
+
/* Return true if TYPE is a type with variable size or a padding type with a
field of variable size or a record that has a field with such a type. */
@@ -6882,6 +6904,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
"XVN");
tree gnu_union_type, gnu_union_name;
tree this_first_free_pos, gnu_variant_list = NULL_TREE;
+ bool union_field_needs_strict_alignment = false;
if (TREE_CODE (gnu_name) == TYPE_DECL)
gnu_name = DECL_NAME (gnu_name);
@@ -6982,8 +7005,18 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
else
{
/* Deal with packedness like in gnat_to_gnu_field. */
- int field_packed
- = adjust_packed (gnu_variant_type, gnu_record_type, packed);
+ bool field_needs_strict_alignment
+ = components_need_strict_alignment (Component_List (variant));
+ int field_packed;
+
+ if (field_needs_strict_alignment)
+ {
+ field_packed = 0;
+ union_field_needs_strict_alignment = true;
+ }
+ else
+ field_packed
+ = adjust_packed (gnu_variant_type, gnu_record_type, packed);
/* Finalize the record type now. We used to throw away
empty records but we no longer do that because we need
@@ -6999,8 +7032,7 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
gnu_union_type,
all_rep_and_size
? TYPE_SIZE (gnu_variant_type) : 0,
- all_rep_and_size
- ? bitsize_zero_node : 0,
+ all_rep ? bitsize_zero_node : 0,
field_packed, 0);
DECL_INTERNAL_P (gnu_field) = 1;
@@ -7043,12 +7075,16 @@ components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
NULL, true, debug_info, gnat_component_list);
/* Deal with packedness like in gnat_to_gnu_field. */
- union_field_packed
- = adjust_packed (gnu_union_type, gnu_record_type, packed);
+ if (union_field_needs_strict_alignment)
+ union_field_packed = 0;
+ else
+ union_field_packed
+ = adjust_packed (gnu_union_type, gnu_record_type, packed);
gnu_variant_part
= create_field_decl (gnu_var_name, gnu_union_type, gnu_record_type,
- all_rep ? TYPE_SIZE (gnu_union_type) : 0,
+ all_rep_and_size
+ ? TYPE_SIZE (gnu_union_type) : 0,
all_rep || this_first_free_pos
? bitsize_zero_node : 0,
union_field_packed, 0);
@@ -7551,10 +7587,10 @@ build_position_list (tree gnu_type, bool do_not_flatten_variant, tree gnu_pos,
of operands to SUBSTITUTE_IN_EXPR. DEFINITION is true if this is for
a definition of GNAT_SUBTYPE. */
-static VEC(subst_pair,heap) *
+static vec<subst_pair>
build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
{
- VEC(subst_pair,heap) *gnu_list = NULL;
+ vec<subst_pair> gnu_list = vNULL;
Entity_Id gnat_discrim;
Node_Id gnat_value;
@@ -7573,7 +7609,7 @@ build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
get_entity_name (gnat_discrim),
definition, true, false));
subst_pair s = {gnu_field, replacement};
- VEC_safe_push (subst_pair, heap, gnu_list, s);
+ gnu_list.safe_push (s);
}
return gnu_list;
@@ -7584,9 +7620,9 @@ build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
the substitutions described in SUBST_LIST. GNU_LIST is a pre-existing
list to be prepended to the newly created entries. */
-static VEC(variant_desc,heap) *
-build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list,
- VEC(variant_desc,heap) *gnu_list)
+static vec<variant_desc>
+build_variant_list (tree qual_union_type, vec<subst_pair> subst_list,
+ vec<variant_desc> gnu_list)
{
tree gnu_field;
@@ -7598,7 +7634,7 @@ build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list,
unsigned int i;
subst_pair *s;
- FOR_EACH_VEC_ELT (subst_pair, subst_list, i, s)
+ FOR_EACH_VEC_ELT (subst_list, i, s)
qual = SUBSTITUTE_IN_EXPR (qual, s->discriminant, s->replacement);
/* If the new qualifier is not unconditionally false, its variant may
@@ -7608,7 +7644,7 @@ build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list,
tree variant_type = TREE_TYPE (gnu_field), variant_subpart;
variant_desc v = {variant_type, gnu_field, qual, NULL_TREE};
- VEC_safe_push (variant_desc, heap, gnu_list, v);
+ gnu_list.safe_push (v);
/* Recurse on the variant subpart of the variant, if any. */
variant_subpart = get_variant_part (variant_type);
@@ -8170,7 +8206,7 @@ intrin_profiles_compatible_p (intrin_binding_t * inb)
static tree
create_field_decl_from (tree old_field, tree field_type, tree record_type,
tree size, tree pos_list,
- VEC(subst_pair,heap) *subst_list)
+ vec<subst_pair> subst_list)
{
tree t = TREE_VALUE (purpose_member (old_field, pos_list));
tree pos = TREE_VEC_ELT (t, 0), bitpos = TREE_VEC_ELT (t, 2);
@@ -8180,7 +8216,7 @@ create_field_decl_from (tree old_field, tree field_type, tree record_type,
subst_pair *s;
if (CONTAINS_PLACEHOLDER_P (pos))
- FOR_EACH_VEC_ELT (subst_pair, subst_list, i, s)
+ FOR_EACH_VEC_ELT (subst_list, i, s)
pos = SUBSTITUTE_IN_EXPR (pos, s->discriminant, s->replacement);
/* If the position is now a constant, we can set it as the position of the
@@ -8276,9 +8312,9 @@ get_variant_part (tree record_type)
static tree
create_variant_part_from (tree old_variant_part,
- VEC(variant_desc,heap) *variant_list,
+ vec<variant_desc> variant_list,
tree record_type, tree pos_list,
- VEC(subst_pair,heap) *subst_list)
+ vec<subst_pair> subst_list)
{
tree offset = DECL_FIELD_OFFSET (old_variant_part);
tree old_union_type = TREE_TYPE (old_variant_part);
@@ -8315,7 +8351,7 @@ create_variant_part_from (tree old_variant_part,
copy_and_substitute_in_size (new_union_type, old_union_type, subst_list);
/* Now finish up the new variants and populate the union type. */
- FOR_EACH_VEC_ELT_REVERSE (variant_desc, variant_list, i, v)
+ FOR_EACH_VEC_ELT_REVERSE (variant_list, i, v)
{
tree old_field = v->field, new_field;
tree old_variant, old_variant_subpart, new_variant, field_list;
@@ -8397,7 +8433,7 @@ create_variant_part_from (tree old_variant_part,
static void
copy_and_substitute_in_size (tree new_type, tree old_type,
- VEC(subst_pair,heap) *subst_list)
+ vec<subst_pair> subst_list)
{
unsigned int i;
subst_pair *s;
@@ -8409,19 +8445,19 @@ copy_and_substitute_in_size (tree new_type, tree old_type,
relate_alias_sets (new_type, old_type, ALIAS_SET_COPY);
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (new_type)))
- FOR_EACH_VEC_ELT (subst_pair, subst_list, i, s)
+ FOR_EACH_VEC_ELT (subst_list, i, s)
TYPE_SIZE (new_type)
= SUBSTITUTE_IN_EXPR (TYPE_SIZE (new_type),
s->discriminant, s->replacement);
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (new_type)))
- FOR_EACH_VEC_ELT (subst_pair, subst_list, i, s)
+ FOR_EACH_VEC_ELT (subst_list, i, s)
TYPE_SIZE_UNIT (new_type)
= SUBSTITUTE_IN_EXPR (TYPE_SIZE_UNIT (new_type),
s->discriminant, s->replacement);
if (CONTAINS_PLACEHOLDER_P (TYPE_ADA_SIZE (new_type)))
- FOR_EACH_VEC_ELT (subst_pair, subst_list, i, s)
+ FOR_EACH_VEC_ELT (subst_list, i, s)
SET_TYPE_ADA_SIZE
(new_type, SUBSTITUTE_IN_EXPR (TYPE_ADA_SIZE (new_type),
s->discriminant, s->replacement));