aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-types.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/trans-types.c')
-rw-r--r--gcc/fortran/trans-types.c163
1 files changed, 76 insertions, 87 deletions
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 2f5b759886d..34efa9ad82c 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -30,7 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h" /* For iso-c-bindings.def. */
#include "target.h"
#include "ggc.h"
-#include "toplev.h" /* For rest_of_decl_compilation/fatal_error. */
+#include "diagnostic-core.h" /* For fatal_error. */
+#include "toplev.h" /* For rest_of_decl_compilation. */
#include "gfortran.h"
#include "trans.h"
#include "trans-types.h"
@@ -86,6 +87,7 @@ gfc_character_info gfc_character_kinds[MAX_CHARACTER_KINDS + 1];
static GTY(()) tree gfc_character_types[MAX_CHARACTER_KINDS + 1];
static GTY(()) tree gfc_pcharacter_types[MAX_CHARACTER_KINDS + 1];
+static tree gfc_add_field_to_struct_1 (tree, tree, tree, tree **);
/* The integer kind to use for array indices. This will be set to the
proper value based on target information from the backend. */
@@ -1232,8 +1234,7 @@ static tree
gfc_get_desc_dim_type (void)
{
tree type;
- tree decl;
- tree fieldlist;
+ tree decl, *chain = NULL;
if (gfc_desc_dim_type)
return gfc_desc_dim_type;
@@ -1245,30 +1246,22 @@ gfc_get_desc_dim_type (void)
TYPE_PACKED (type) = 1;
/* Consists of the stride, lbound and ubound members. */
- decl = build_decl (input_location,
- FIELD_DECL,
- get_identifier ("stride"), gfc_array_index_type);
- DECL_CONTEXT (decl) = type;
+ decl = gfc_add_field_to_struct_1 (type,
+ get_identifier ("stride"),
+ gfc_array_index_type, &chain);
TREE_NO_WARNING (decl) = 1;
- fieldlist = decl;
- decl = build_decl (input_location,
- FIELD_DECL,
- get_identifier ("lbound"), gfc_array_index_type);
- DECL_CONTEXT (decl) = type;
+ decl = gfc_add_field_to_struct_1 (type,
+ get_identifier ("lbound"),
+ gfc_array_index_type, &chain);
TREE_NO_WARNING (decl) = 1;
- fieldlist = chainon (fieldlist, decl);
- decl = build_decl (input_location,
- FIELD_DECL,
- get_identifier ("ubound"), gfc_array_index_type);
- DECL_CONTEXT (decl) = type;
+ decl = gfc_add_field_to_struct_1 (type,
+ get_identifier ("ubound"),
+ gfc_array_index_type, &chain);
TREE_NO_WARNING (decl) = 1;
- fieldlist = chainon (fieldlist, decl);
/* Finish off the type. */
- TYPE_FIELDS (type) = fieldlist;
-
gfc_finish_type (type);
TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) = 1;
@@ -1540,7 +1533,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
static tree
gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted)
{
- tree fat_type, fieldlist, decl, arraytype;
+ tree fat_type, decl, arraytype, *chain = NULL;
char name[16 + 2*GFC_RANK_DIGITS + 1 + 1];
int idx = 2 * (codimen + dimen - 1) + restricted;
@@ -1553,30 +1546,26 @@ gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted)
sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT, dimen + codimen);
TYPE_NAME (fat_type) = get_identifier (name);
+ TYPE_NAMELESS (fat_type) = 1;
/* Add the data member as the first element of the descriptor. */
- decl = build_decl (input_location,
- FIELD_DECL, get_identifier ("data"),
- restricted ? prvoid_type_node : ptr_type_node);
-
- DECL_CONTEXT (decl) = fat_type;
- fieldlist = decl;
+ decl = gfc_add_field_to_struct_1 (fat_type,
+ get_identifier ("data"),
+ (restricted
+ ? prvoid_type_node
+ : ptr_type_node), &chain);
/* Add the base component. */
- decl = build_decl (input_location,
- FIELD_DECL, get_identifier ("offset"),
- gfc_array_index_type);
- DECL_CONTEXT (decl) = fat_type;
+ decl = gfc_add_field_to_struct_1 (fat_type,
+ get_identifier ("offset"),
+ gfc_array_index_type, &chain);
TREE_NO_WARNING (decl) = 1;
- fieldlist = chainon (fieldlist, decl);
/* Add the dtype component. */
- decl = build_decl (input_location,
- FIELD_DECL, get_identifier ("dtype"),
- gfc_array_index_type);
- DECL_CONTEXT (decl) = fat_type;
+ decl = gfc_add_field_to_struct_1 (fat_type,
+ get_identifier ("dtype"),
+ gfc_array_index_type, &chain);
TREE_NO_WARNING (decl) = 1;
- fieldlist = chainon (fieldlist, decl);
/* Build the array type for the stride and bound components. */
arraytype =
@@ -1585,15 +1574,12 @@ gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted)
gfc_index_zero_node,
gfc_rank_cst[codimen + dimen - 1]));
- decl = build_decl (input_location,
- FIELD_DECL, get_identifier ("dim"), arraytype);
- DECL_CONTEXT (decl) = fat_type;
+ decl = gfc_add_field_to_struct_1 (fat_type,
+ get_identifier ("dim"),
+ arraytype, &chain);
TREE_NO_WARNING (decl) = 1;
- fieldlist = chainon (fieldlist, decl);
/* Finish off the type. */
- TYPE_FIELDS (fat_type) = fieldlist;
-
gfc_finish_type (fat_type);
TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (fat_type)) = 1;
@@ -1631,6 +1617,7 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen + codimen,
GFC_MAX_SYMBOL_LEN, type_name);
TYPE_NAME (fat_type) = get_identifier (name);
+ TYPE_NAMELESS (fat_type) = 1;
GFC_DESCRIPTOR_TYPE_P (fat_type) = 1;
TYPE_LANG_SPECIFIC (fat_type)
@@ -1853,26 +1840,41 @@ gfc_finish_type (tree type)
}
/* Add a field of given NAME and TYPE to the context of a UNION_TYPE
- or RECORD_TYPE pointed to by STYPE. The new field is chained
- to the fieldlist pointed to by FIELDLIST.
+ or RECORD_TYPE pointed to by CONTEXT. The new field is chained
+ to the end of the field list pointed to by *CHAIN.
Returns a pointer to the new field. */
-tree
-gfc_add_field_to_struct (tree *fieldlist, tree context,
- tree name, tree type)
+static tree
+gfc_add_field_to_struct_1 (tree context, tree name, tree type, tree **chain)
{
- tree decl;
-
- decl = build_decl (input_location,
- FIELD_DECL, name, type);
+ tree decl = build_decl (input_location, FIELD_DECL, name, type);
DECL_CONTEXT (decl) = context;
+ DECL_CHAIN (decl) = NULL_TREE;
+ if (TYPE_FIELDS (context) == NULL_TREE)
+ TYPE_FIELDS (context) = decl;
+ if (chain != NULL)
+ {
+ if (*chain != NULL)
+ **chain = decl;
+ *chain = &DECL_CHAIN (decl);
+ }
+
+ return decl;
+}
+
+/* Like `gfc_add_field_to_struct_1', but adds alignment
+ information. */
+
+tree
+gfc_add_field_to_struct (tree context, tree name, tree type, tree **chain)
+{
+ tree decl = gfc_add_field_to_struct_1 (context, name, type, chain);
+
DECL_INITIAL (decl) = 0;
DECL_ALIGN (decl) = 0;
DECL_USER_ALIGN (decl) = 0;
- TREE_CHAIN (decl) = NULL_TREE;
- *fieldlist = chainon (*fieldlist, decl);
return decl;
}
@@ -1948,8 +1950,9 @@ gfc_get_ppc_type (gfc_component* c)
tree
gfc_get_derived_type (gfc_symbol * derived)
{
- tree typenode = NULL, field = NULL, field_type = NULL, fieldlist = NULL;
+ tree typenode = NULL, field = NULL, field_type = NULL;
tree canonical = NULL_TREE;
+ tree *chain = NULL;
bool got_canonical = false;
gfc_component *c;
gfc_dt_list *dt;
@@ -1969,14 +1972,6 @@ gfc_get_derived_type (gfc_symbol * derived)
else
derived->backend_decl = pfunc_type_node;
- /* Create a backend_decl for the __c_ptr_c_address field. */
- derived->components->backend_decl =
- gfc_add_field_to_struct (&(derived->backend_decl->type.values),
- derived->backend_decl,
- get_identifier (derived->components->name),
- gfc_typenode_for_spec (
- &(derived->components->ts)));
-
derived->ts.kind = gfc_index_integer_kind;
derived->ts.type = BT_INTEGER;
/* Set the f90_type to BT_VOID as a way to recognize something of type
@@ -2098,7 +2093,6 @@ gfc_get_derived_type (gfc_symbol * derived)
/* Build the type member list. Install the newly created RECORD_TYPE
node as DECL_CONTEXT of each FIELD_DECL. */
- fieldlist = NULL_TREE;
for (c = derived->components; c; c = c->next)
{
if (c->attr.proc_pointer)
@@ -2145,8 +2139,14 @@ gfc_get_derived_type (gfc_symbol * derived)
&& !c->attr.proc_pointer)
field_type = build_pointer_type (field_type);
- field = gfc_add_field_to_struct (&fieldlist, typenode,
- get_identifier (c->name), field_type);
+ /* vtype fields can point to different types to the base type. */
+ if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.vtype)
+ field_type = build_pointer_type_for_mode (TREE_TYPE (field_type),
+ ptr_mode, true);
+
+ field = gfc_add_field_to_struct (typenode,
+ get_identifier (c->name),
+ field_type, &chain);
if (c->loc.lb)
gfc_set_decl_location (field, &c->loc);
else if (derived->declared_at.lb)
@@ -2159,9 +2159,7 @@ gfc_get_derived_type (gfc_symbol * derived)
c->backend_decl = field;
}
- /* Now we have the final fieldlist. Record it, then lay out the
- derived type, including the fields. */
- TYPE_FIELDS (typenode) = fieldlist;
+ /* Now lay out the derived type, including the fields. */
if (canonical)
TYPE_CANONICAL (typenode) = canonical;
@@ -2224,8 +2222,7 @@ static tree
gfc_get_mixed_entry_union (gfc_namespace *ns)
{
tree type;
- tree decl;
- tree fieldlist;
+ tree *chain = NULL;
char name[GFC_MAX_SYMBOL_LEN + 1];
gfc_entry_list *el, *el2;
@@ -2238,7 +2235,6 @@ gfc_get_mixed_entry_union (gfc_namespace *ns)
type = make_node (UNION_TYPE);
TYPE_NAME (type) = get_identifier (name);
- fieldlist = NULL;
for (el = ns->entries; el; el = el->next)
{
@@ -2248,19 +2244,12 @@ gfc_get_mixed_entry_union (gfc_namespace *ns)
break;
if (el == el2)
- {
- decl = build_decl (input_location,
- FIELD_DECL,
- get_identifier (el->sym->result->name),
- gfc_sym_type (el->sym->result));
- DECL_CONTEXT (decl) = type;
- fieldlist = chainon (fieldlist, decl);
- }
+ gfc_add_field_to_struct_1 (type,
+ get_identifier (el->sym->result->name),
+ gfc_sym_type (el->sym->result), &chain);
}
/* Finish off the type. */
- TYPE_FIELDS (type) = fieldlist;
-
gfc_finish_type (type);
TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) = 1;
return type;
@@ -2552,16 +2541,16 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
elem_size = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (etype));
field = TYPE_FIELDS (TYPE_MAIN_VARIANT (type));
data_off = byte_position (field);
- field = TREE_CHAIN (field);
- field = TREE_CHAIN (field);
- field = TREE_CHAIN (field);
+ field = DECL_CHAIN (field);
+ field = DECL_CHAIN (field);
+ field = DECL_CHAIN (field);
dim_off = byte_position (field);
dim_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (field)));
field = TYPE_FIELDS (TREE_TYPE (TREE_TYPE (field)));
stride_suboff = byte_position (field);
- field = TREE_CHAIN (field);
+ field = DECL_CHAIN (field);
lower_suboff = byte_position (field);
- field = TREE_CHAIN (field);
+ field = DECL_CHAIN (field);
upper_suboff = byte_position (field);
t = base_decl;