diff options
author | Nathan Froyd <froydnj@codesourcery.com> | 2010-08-09 00:53:48 +0000 |
---|---|---|
committer | Nathan Froyd <froydnj@gcc.gnu.org> | 2010-08-09 00:53:48 +0000 |
commit | fb7fb7010a1053e0e8de1f0af39d546993fb5f9f (patch) | |
tree | 059505b958e2fbfb28f2e73a11b28c1d76684622 /gcc/ada/gcc-interface/decl.c | |
parent | 0ec11839957f925b7db59c4c03c667ac0e99570f (diff) | |
download | gcc-fb7fb7010a1053e0e8de1f0af39d546993fb5f9f.zip gcc-fb7fb7010a1053e0e8de1f0af39d546993fb5f9f.tar.gz gcc-fb7fb7010a1053e0e8de1f0af39d546993fb5f9f.tar.bz2 |
* gcc-interface/decl.c (rec_variant). Declare. Declare a VEC of it.
(build_variant_list): Return a VEC instead of a tree. Take a
VEC instead of a tree.
(create_variant_part_from): Take a VEC instead of a tree for
variant_list. Adjust accordingly.
(gnat_to_gnu_entity): Adjust for changes to previous functions.
From-SVN: r163025
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r-- | gcc/ada/gcc-interface/decl.c | 112 |
1 files changed, 76 insertions, 36 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index b63a620..88d5716 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -112,6 +112,23 @@ typedef struct GTY(()) subst_pair_d { DEF_VEC_O(subst_pair); DEF_VEC_ALLOC_O(subst_pair,heap); +typedef struct GTY(()) variant_desc_d { + /* The type of the variant. */ + tree type; + + /* The associated field. */ + tree field; + + /* The value of the qualifier. */ + tree qual; + + /* The record associated with this variant. */ + tree record; +} 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"), param_is (struct tree_int_map))) htab_t annotate_value_cache; @@ -150,7 +167,9 @@ 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 tree build_variant_list (tree, VEC(subst_pair,heap) *, tree); +static VEC(variant_desc,heap) *build_variant_list (tree, + VEC(subst_pair,heap) *, + VEC(variant_desc,heap) *); static tree validate_size (Uint, tree, Entity_Id, enum tree_code, bool, bool); static void set_rm_size (Uint, tree, Entity_Id); static tree make_type_from_size (tree, tree, bool); @@ -161,8 +180,8 @@ static tree create_field_decl_from (tree, tree, tree, tree, tree, VEC(subst_pair,heap) *); static tree get_rep_part (tree); static tree get_variant_part (tree); -static tree create_variant_part_from (tree, tree, tree, tree, - VEC(subst_pair,heap) *); +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 void rest_of_type_decl_compilation_no_defer (tree); @@ -3045,9 +3064,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) VEC(subst_pair,heap) *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_variant_list, gnu_pos_list, gnu_field_list = NULL_TREE; + tree gnu_pos_list, gnu_field_list = NULL_TREE; bool selected_variant = false; Entity_Id gnat_field; + VEC(variant_desc,heap) *gnu_variant_list; gnu_type = make_node (RECORD_TYPE); TYPE_NAME (gnu_type) = gnu_entity_name; @@ -3075,15 +3095,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) union for the variants that are still relevant. */ if (gnu_variant_part) { + variant_desc *v; + unsigned ix; + gnu_variant_list = build_variant_list (TREE_TYPE (gnu_variant_part), - gnu_subst_list, NULL_TREE); + gnu_subst_list, NULL); /* If all the qualifiers are unconditionally true, the innermost variant is statically selected. */ selected_variant = true; - for (t = gnu_variant_list; t; t = TREE_CHAIN (t)) - if (!integer_onep (TREE_VEC_ELT (TREE_VALUE (t), 1))) + FOR_EACH_VEC_ELT_REVERSE (variant_desc, gnu_variant_list, + ix, v) + if (!integer_onep (v->qual)) { selected_variant = false; break; @@ -3091,20 +3115,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) /* Otherwise, create the new variants. */ if (!selected_variant) - for (t = gnu_variant_list; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT_REVERSE (variant_desc, gnu_variant_list, + ix, v) { - tree old_variant = TREE_PURPOSE (t); + tree old_variant = v->type; tree new_variant = make_node (RECORD_TYPE); TYPE_NAME (new_variant) = DECL_NAME (TYPE_NAME (old_variant)); copy_and_substitute_in_size (new_variant, old_variant, gnu_subst_list); - TREE_VEC_ELT (TREE_VALUE (t), 2) = new_variant; + v->record = new_variant; } } else { - gnu_variant_list = NULL_TREE; + gnu_variant_list = NULL; selected_variant = false; } @@ -3187,13 +3212,23 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition) gnu_cont_type = gnu_type; else { - t = purpose_member (gnu_context, gnu_variant_list); + variant_desc *v; + unsigned ix; + + t = NULL_TREE; + FOR_EACH_VEC_ELT_REVERSE (variant_desc, + gnu_variant_list, ix, v) + if (v->type == gnu_context) + { + t = v->type; + break; + } if (t) { if (selected_variant) gnu_cont_type = gnu_type; else - gnu_cont_type = TREE_VEC_ELT (TREE_VALUE (t), 2); + gnu_cont_type = v->record; } else /* The front-end may pass us "ghost" components if @@ -3319,6 +3354,7 @@ 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); /* Now we can finalize it. */ @@ -7547,16 +7583,15 @@ build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition) return gnu_vec; } -/* Scan all fields in QUAL_UNION_TYPE and return a TREE_LIST describing the - variants of QUAL_UNION_TYPE that are still relevant after applying the - substitutions described in SUBST_LIST. TREE_PURPOSE is the type of the - variant and TREE_VALUE is a TREE_VEC containing the field, the new value - of the qualifier and NULL_TREE respectively. GNU_LIST is a pre-existing - list to be chained to the newly created entries. */ +/* Scan all fields in QUAL_UNION_TYPE and return a VEC describing the + variants of QUAL_UNION_TYPE that are still relevant after applying + the substitutions described in SUBST_LIST. VARIANT_LIST is a + pre-existing VEC onto which newly created entries should be + pushed. */ -static tree +static VEC(variant_desc,heap) * build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list, - tree gnu_list) + VEC(variant_desc,heap) *variant_list) { tree gnu_field; @@ -7575,18 +7610,20 @@ build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list, still be accessed. */ if (!integer_zerop (qual)) { + variant_desc *v; tree variant_type = TREE_TYPE (gnu_field), variant_subpart; - tree v = make_tree_vec (3); - TREE_VEC_ELT (v, 0) = gnu_field; - TREE_VEC_ELT (v, 1) = qual; - TREE_VEC_ELT (v, 2) = NULL_TREE; - gnu_list = tree_cons (variant_type, v, gnu_list); + + v = VEC_safe_push (variant_desc, heap, variant_list, NULL); + v->type = variant_type; + v->field = gnu_field; + v->qual = qual; + v->record = NULL_TREE; /* Recurse on the variant subpart of the variant, if any. */ variant_subpart = get_variant_part (variant_type); if (variant_subpart) - gnu_list = build_variant_list (TREE_TYPE (variant_subpart), - subst_list, gnu_list); + variant_list = build_variant_list (TREE_TYPE (variant_subpart), + subst_list, variant_list); /* If the new qualifier is unconditionally true, the subsequent variants cannot be accessed. */ @@ -7595,7 +7632,7 @@ build_variant_list (tree qual_union_type, VEC(subst_pair,heap) *subst_list, } } - return gnu_list; + return variant_list; } /* UINT_SIZE is a Uint giving the specified size for an object of GNU_TYPE @@ -8319,14 +8356,17 @@ get_variant_part (tree record_type) layout. */ static tree -create_variant_part_from (tree old_variant_part, tree variant_list, +create_variant_part_from (tree old_variant_part, + VEC(variant_desc,heap) *variant_list, tree record_type, tree pos_list, VEC(subst_pair,heap) *subst_list) { tree offset = DECL_FIELD_OFFSET (old_variant_part); tree old_union_type = TREE_TYPE (old_variant_part); - tree new_union_type, new_variant_part, t; + tree new_union_type, new_variant_part; tree union_field_list = NULL_TREE; + variant_desc *v; + unsigned ix; /* First create the type of the variant part from that of the old one. */ new_union_type = make_node (QUAL_UNION_TYPE); @@ -8354,9 +8394,9 @@ create_variant_part_from (tree old_variant_part, tree variant_list, 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 (t = variant_list; t; t = TREE_CHAIN (t)) + FOR_EACH_VEC_ELT_REVERSE (variant_desc, variant_list, ix, v) { - tree old_field = TREE_VEC_ELT (TREE_VALUE (t), 0), new_field; + tree old_field = v->field, new_field; tree old_variant, old_variant_subpart, new_variant, field_list; /* Skip variants that don't belong to this nesting level. */ @@ -8364,12 +8404,12 @@ create_variant_part_from (tree old_variant_part, tree variant_list, continue; /* Retrieve the list of fields already added to the new variant. */ - new_variant = TREE_VEC_ELT (TREE_VALUE (t), 2); + new_variant = v->record; field_list = TYPE_FIELDS (new_variant); /* If the old variant had a variant subpart, we need to create a new variant subpart and add it to the field list. */ - old_variant = TREE_PURPOSE (t); + old_variant = v->type; old_variant_subpart = get_variant_part (old_variant); if (old_variant_subpart) { @@ -8391,7 +8431,7 @@ create_variant_part_from (tree old_variant_part, tree variant_list, = create_field_decl_from (old_field, new_variant, new_union_type, TYPE_SIZE (new_variant), pos_list, subst_list); - DECL_QUALIFIER (new_field) = TREE_VEC_ELT (TREE_VALUE (t), 1); + DECL_QUALIFIER (new_field) = v->qual; DECL_INTERNAL_P (new_field) = 1; DECL_CHAIN (new_field) = union_field_list; union_field_list = new_field; |