aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2014-07-31 13:57:42 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2014-07-31 15:57:42 +0200
commit5cb7516dca5acba3d3c4205bb4ce0f5e338015ad (patch)
treee754fc94dca3c883d6d0d66d716729543a1e2c6c /gcc/ada/gcc-interface/utils.c
parent6c26bac268904dcdf7719bdc073f288a2c06703d (diff)
downloadgcc-5cb7516dca5acba3d3c4205bb4ce0f5e338015ad.zip
gcc-5cb7516dca5acba3d3c4205bb4ce0f5e338015ad.tar.gz
gcc-5cb7516dca5acba3d3c4205bb4ce0f5e338015ad.tar.bz2
utils.c (lookup_and_insert_pad_type): New function extracted from...
2014-07-31 Eric Botcazou <ebotcazou@adacore.com> * gcc-interface/utils.c (lookup_and_insert_pad_type): New function extracted from... (maybe_pad_type): ...here. Call it to canonicalize the pad type. * gcc-interface/gigi.h: Update comment. From-SVN: r213374
Diffstat (limited to 'gcc/ada/gcc-interface/utils.c')
-rw-r--r--gcc/ada/gcc-interface/utils.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index fa6f791..f2afc73 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1037,8 +1037,39 @@ pad_type_hash_eq (const void *p1, const void *p2)
&& TYPE_ADA_SIZE (type1) == TYPE_ADA_SIZE (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. */
+
+static tree
+lookup_and_insert_pad_type (tree type)
+{
+ hashval_t hashcode;
+ struct pad_type_hash in, *h;
+ void **loc;
+
+ hashcode
+ = iterative_hash_object (TYPE_HASH (TREE_TYPE (TYPE_FIELDS (type))), 0);
+ hashcode = iterative_hash_expr (TYPE_SIZE (type), hashcode);
+ hashcode = iterative_hash_hashval_t (TYPE_ALIGN (type), hashcode);
+ hashcode = iterative_hash_expr (TYPE_ADA_SIZE (type), hashcode);
+
+ in.hash = hashcode;
+ in.type = type;
+ h = (struct pad_type_hash *)
+ htab_find_with_hash (pad_type_hash_table, &in, hashcode);
+ if (h)
+ return h->type;
+
+ h = ggc_alloc<pad_type_hash> ();
+ h->hash = hashcode;
+ h->type = type;
+ loc = htab_find_slot_with_hash (pad_type_hash_table, h, hashcode, INSERT);
+ *loc = (void *)h;
+ return NULL_TREE;
+}
+
/* Ensure that TYPE has SIZE and ALIGN. Make and return a new padded type
- if needed. We have already verified that SIZE and TYPE are large enough.
+ if needed. We have already verified that SIZE and ALIGN are large enough.
GNAT_ENTITY is used to name the resulting record and to issue a warning.
IS_COMPONENT_TYPE is true if this is being done for the component type of
an array. IS_USER_TYPE is true if the original type needs to be completed.
@@ -1158,39 +1189,19 @@ maybe_pad_type (tree type, tree size, unsigned int align,
/* 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)))
+ if (TREE_CONSTANT (TYPE_SIZE (record))
+ && (canonical_pad_type = lookup_and_insert_pad_type (record)))
{
- hashval_t hashcode;
- struct pad_type_hash in, *h;
- void **loc;
-
- hashcode = iterative_hash_object (TYPE_HASH (type), 0);
- hashcode = iterative_hash_expr (TYPE_SIZE (record), hashcode);
- hashcode = iterative_hash_hashval_t (TYPE_ALIGN (record), hashcode);
- hashcode = iterative_hash_expr (TYPE_ADA_SIZE (record), hashcode);
-
- in.hash = hashcode;
- in.type = record;
- h = (struct pad_type_hash *)
- htab_find_with_hash (pad_type_hash_table, &in, hashcode);
- if (h)
- {
- record = h->type;
- goto built;
- }
-
- h = ggc_alloc<pad_type_hash> ();
- h->hash = hashcode;
- h->type = record;
- loc = htab_find_slot_with_hash (pad_type_hash_table, h, hashcode,
- INSERT);
- *loc = (void *)h;
+ record = canonical_pad_type;
+ goto built;
}
}