diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2017-12-14 11:47:24 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2017-12-14 11:47:24 +0000 |
commit | 4d39941ea9e6fe059084be9f5dea7e29e055db91 (patch) | |
tree | cb51425855d3854723367fc3c5edb23fca63211e /gcc/ada/gcc-interface/utils.c | |
parent | 02aee327674dae6359d7b1e1a7434f039ba0c3d3 (diff) | |
download | gcc-4d39941ea9e6fe059084be9f5dea7e29e055db91.zip gcc-4d39941ea9e6fe059084be9f5dea7e29e055db91.tar.gz gcc-4d39941ea9e6fe059084be9f5dea7e29e055db91.tar.bz2 |
gigi.h (pad_type_has_rm_size): Declare.
* gcc-interface/gigi.h (pad_type_has_rm_size): Declare.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Do not build
a padding type for the alignment before validating the size.
Flip conditional construct and add a comment.
* gcc-interface/trans.c (Attribute_to_gnu) <Attr_Size>: Make sure to
apply the exception for padded objects to the type of the object.
* gcc-interface/utils.c (hash_pad_type): New static function.
(lookup_and_insert_pad_type): Rename into...
(canonicalize_pad_type): ...this. Call hash_pad_type, do only one
lookup with insertion and always return the canonical type.
(maybe_pad_type): Adjust to above changes. Set debug type later.
(pad_type_has_rm_size): New predicate.
(set_reverse_storage_order_on_pad_type): Adjust to above changes.
From-SVN: r255631
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r-- | gcc/ada/gcc-interface/utils.c | 84 |
1 files changed, 57 insertions, 27 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c index d1f8035..eae23d2 100644 --- a/gcc/ada/gcc-interface/utils.c +++ b/gcc/ada/gcc-interface/utils.c @@ -1224,14 +1224,12 @@ pad_type_hasher::equal (pad_type_hash *t1, pad_type_hash *t2) && TYPE_REVERSE_STORAGE_ORDER (type1) == TYPE_REVERSE_STORAGE_ORDER (type2); } -/* Look up the padded TYPE in the hash table and return its canonical version - if it exists; otherwise, insert it into the hash table. */ +/* Compute the hash value for the padded TYPE. */ -static tree -lookup_and_insert_pad_type (tree type) +static hashval_t +hash_pad_type (tree type) { hashval_t hashcode; - struct pad_type_hash in, *h; hashcode = iterative_hash_object (TYPE_HASH (TREE_TYPE (TYPE_FIELDS (type))), 0); @@ -1239,17 +1237,31 @@ lookup_and_insert_pad_type (tree type) hashcode = iterative_hash_hashval_t (TYPE_ALIGN (type), hashcode); hashcode = iterative_hash_expr (TYPE_ADA_SIZE (type), hashcode); + return hashcode; +} + +/* Look up the padded TYPE in the hash table and return its canonical version + if it exists; otherwise, insert it into the hash table. */ + +static tree +canonicalize_pad_type (tree type) +{ + const hashval_t hashcode = hash_pad_type (type); + struct pad_type_hash in, *h, **slot; + in.hash = hashcode; in.type = type; - h = pad_type_hash_table->find_with_hash (&in, hashcode); - if (h) - return h->type; + slot = pad_type_hash_table->find_slot_with_hash (&in, hashcode, INSERT); + h = *slot; + if (!h) + { + h = ggc_alloc<pad_type_hash> (); + h->hash = hashcode; + h->type = type; + *slot = h; + } - h = ggc_alloc<pad_type_hash> (); - h->hash = hashcode; - h->type = type; - *pad_type_hash_table->find_slot_with_hash (h, hashcode, INSERT) = h; - return NULL_TREE; + return h->type; } /* Ensure that TYPE has SIZE and ALIGN. Make and return a new padded type @@ -1380,28 +1392,29 @@ maybe_pad_type (tree type, tree size, unsigned int align, /* We will output additional debug info manually below. */ finish_record_type (record, field, 1, false); - if (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) - SET_TYPE_DEBUG_TYPE (record, type); - /* Set the RM size if requested. */ if (set_rm_size) { - tree canonical_pad_type; - SET_TYPE_ADA_SIZE (record, size ? size : orig_size); /* If the padded type is complete and has constant size, we canonicalize it by means of the hash table. This is consistent with the language semantics and ensures that gigi and the middle-end have a common view of these padded types. */ - if (TREE_CONSTANT (TYPE_SIZE (record)) - && (canonical_pad_type = lookup_and_insert_pad_type (record))) + if (TREE_CONSTANT (TYPE_SIZE (record))) { - record = canonical_pad_type; - goto built; + tree canonical = canonicalize_pad_type (record); + if (canonical != record) + { + record = canonical; + goto built; + } } } + if (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) + SET_TYPE_DEBUG_TYPE (record, type); + /* Unless debugging information isn't being written for the input type, write a record that shows what we are a subtype of and also make a variable that indicates our size, if still variable. */ @@ -1520,13 +1533,31 @@ built: return record; } +/* Return true if padded TYPE was built with an RM size. */ + +bool +pad_type_has_rm_size (tree type) +{ + /* This is required for the lookup. */ + if (!TREE_CONSTANT (TYPE_SIZE (type))) + return false; + + const hashval_t hashcode = hash_pad_type (type); + struct pad_type_hash in, *h; + + in.hash = hashcode; + in.type = type; + h = pad_type_hash_table->find_with_hash (&in, hashcode); + + /* The types built with an RM size are the canonicalized ones. */ + return h && h->type == type; +} + /* Return a copy of the padded TYPE but with reverse storage order. */ tree set_reverse_storage_order_on_pad_type (tree type) { - tree field, canonical_pad_type; - if (flag_checking) { /* If the inner type is not scalar then the function does nothing. */ @@ -1538,13 +1569,12 @@ set_reverse_storage_order_on_pad_type (tree type) /* This is required for the canonicalization. */ gcc_assert (TREE_CONSTANT (TYPE_SIZE (type))); - field = copy_node (TYPE_FIELDS (type)); + tree field = copy_node (TYPE_FIELDS (type)); type = copy_type (type); DECL_CONTEXT (field) = type; TYPE_FIELDS (type) = field; TYPE_REVERSE_STORAGE_ORDER (type) = 1; - canonical_pad_type = lookup_and_insert_pad_type (type); - return canonical_pad_type ? canonical_pad_type : type; + return canonicalize_pad_type (type); } /* Relate the alias sets of GNU_NEW_TYPE and GNU_OLD_TYPE according to OP. |