Fix oversight in handling of reverse SSO in SRA pass
[official-gcc.git] / gcc / fortran / class.c
blob93118ad3455f2cac543e534ba4a50d46a0b37d3b
1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2021 Free Software Foundation, Inc.
3 Contributed by Paul Richard Thomas <pault@gcc.gnu.org>
4 and Janus Weil <janus@gcc.gnu.org>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* class.c -- This file contains the front end functions needed to service
24 the implementation of Fortran 2003 polymorphism and other
25 object-oriented features. */
28 /* Outline of the internal representation:
30 Each CLASS variable is encapsulated by a class container, which is a
31 structure with two fields:
32 * _data: A pointer to the actual data of the variable. This field has the
33 declared type of the class variable and its attributes
34 (pointer/allocatable/dimension/...).
35 * _vptr: A pointer to the vtable entry (see below) of the dynamic type.
37 Only for unlimited polymorphic classes:
38 * _len: An integer(C_SIZE_T) to store the string length when the unlimited
39 polymorphic pointer is used to point to a char array. The '_len'
40 component will be zero when no character array is stored in
41 '_data'.
43 For each derived type we set up a "vtable" entry, i.e. a structure with the
44 following fields:
45 * _hash: A hash value serving as a unique identifier for this type.
46 * _size: The size in bytes of the derived type.
47 * _extends: A pointer to the vtable entry of the parent derived type.
48 * _def_init: A pointer to a default initialized variable of this type.
49 * _copy: A procedure pointer to a copying procedure.
50 * _final: A procedure pointer to a wrapper function, which frees
51 allocatable components and calls FINAL subroutines.
52 * _deallocate: A procedure pointer to a deallocation procedure; nonnull
53 only for a recursive derived type.
55 After these follow procedure pointer components for the specific
56 type-bound procedures. */
59 #include "config.h"
60 #include "system.h"
61 #include "coretypes.h"
62 #include "gfortran.h"
63 #include "constructor.h"
64 #include "target-memory.h"
66 /* Inserts a derived type component reference in a data reference chain.
67 TS: base type of the ref chain so far, in which we will pick the component
68 REF: the address of the GFC_REF pointer to update
69 NAME: name of the component to insert
70 Note that component insertion makes sense only if we are at the end of
71 the chain (*REF == NULL) or if we are adding a missing "_data" component
72 to access the actual contents of a class object. */
74 static void
75 insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
77 gfc_ref *new_ref;
78 int wcnt, ecnt;
80 gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
82 gfc_find_component (ts->u.derived, name, true, true, &new_ref);
84 gfc_get_errors (&wcnt, &ecnt);
85 if (ecnt > 0 && !new_ref)
86 return;
87 gcc_assert (new_ref->u.c.component);
89 while (new_ref->next)
90 new_ref = new_ref->next;
91 new_ref->next = *ref;
93 if (new_ref->next)
95 gfc_ref *next = NULL;
97 /* We need to update the base type in the trailing reference chain to
98 that of the new component. */
100 gcc_assert (strcmp (name, "_data") == 0);
102 if (new_ref->next->type == REF_COMPONENT)
103 next = new_ref->next;
104 else if (new_ref->next->type == REF_ARRAY
105 && new_ref->next->next
106 && new_ref->next->next->type == REF_COMPONENT)
107 next = new_ref->next->next;
109 if (next != NULL)
111 gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
112 || new_ref->u.c.component->ts.type == BT_DERIVED);
113 next->u.c.sym = new_ref->u.c.component->ts.u.derived;
117 *ref = new_ref;
121 /* Tells whether we need to add a "_data" reference to access REF subobject
122 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base
123 object accessed by REF is a variable; in other words it is a full object,
124 not a subobject. */
126 static bool
127 class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain)
129 /* Only class containers may need the "_data" reference. */
130 if (ts->type != BT_CLASS)
131 return false;
133 /* Accessing a class container with an array reference is certainly wrong. */
134 if (ref->type != REF_COMPONENT)
135 return true;
137 /* Accessing the class container's fields is fine. */
138 if (ref->u.c.component->name[0] == '_')
139 return false;
141 /* At this point we have a class container with a non class container's field
142 component reference. We don't want to add the "_data" component if we are
143 at the first reference and the symbol's type is an extended derived type.
144 In that case, conv_parent_component_references will do the right thing so
145 it is not absolutely necessary. Omitting it prevents a regression (see
146 class_41.f03) in the interface mapping mechanism. When evaluating string
147 lengths depending on dummy arguments, we create a fake symbol with a type
148 equal to that of the dummy type. However, because of type extension,
149 the backend type (corresponding to the actual argument) can have a
150 different (extended) type. Adding the "_data" component explicitly, using
151 the base type, confuses the gfc_conv_component_ref code which deals with
152 the extended type. */
153 if (first_ref_in_chain && ts->u.derived->attr.extension)
154 return false;
156 /* We have a class container with a non class container's field component
157 reference that doesn't fall into the above. */
158 return true;
162 /* Browse through a data reference chain and add the missing "_data" references
163 when a subobject of a class object is accessed without it.
164 Note that it doesn't add the "_data" reference when the class container
165 is the last element in the reference chain. */
167 void
168 gfc_fix_class_refs (gfc_expr *e)
170 gfc_typespec *ts;
171 gfc_ref **ref;
173 if ((e->expr_type != EXPR_VARIABLE
174 && e->expr_type != EXPR_FUNCTION)
175 || (e->expr_type == EXPR_FUNCTION
176 && e->value.function.isym != NULL))
177 return;
179 if (e->expr_type == EXPR_VARIABLE)
180 ts = &e->symtree->n.sym->ts;
181 else
183 gfc_symbol *func;
185 gcc_assert (e->expr_type == EXPR_FUNCTION);
186 if (e->value.function.esym != NULL)
187 func = e->value.function.esym;
188 else
189 func = e->symtree->n.sym;
191 if (func->result != NULL)
192 ts = &func->result->ts;
193 else
194 ts = &func->ts;
197 for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
199 if (class_data_ref_missing (ts, *ref, ref == &e->ref))
200 insert_component_ref (ts, ref, "_data");
202 if ((*ref)->type == REF_COMPONENT)
203 ts = &(*ref)->u.c.component->ts;
208 /* Insert a reference to the component of the given name.
209 Only to be used with CLASS containers and vtables. */
211 void
212 gfc_add_component_ref (gfc_expr *e, const char *name)
214 gfc_component *c;
215 gfc_ref **tail = &(e->ref);
216 gfc_ref *ref, *next = NULL;
217 gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
218 while (*tail != NULL)
220 if ((*tail)->type == REF_COMPONENT)
222 if (strcmp ((*tail)->u.c.component->name, "_data") == 0
223 && (*tail)->next
224 && (*tail)->next->type == REF_ARRAY
225 && (*tail)->next->next == NULL)
226 return;
227 derived = (*tail)->u.c.component->ts.u.derived;
229 if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
230 break;
231 tail = &((*tail)->next);
233 if (derived && derived->components && derived->components->next &&
234 derived->components->next->ts.type == BT_DERIVED &&
235 derived->components->next->ts.u.derived == NULL)
237 /* Fix up missing vtype. */
238 gfc_symbol *vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
239 gcc_assert (vtab);
240 derived->components->next->ts.u.derived = vtab->ts.u.derived;
242 if (*tail != NULL && strcmp (name, "_data") == 0)
243 next = *tail;
244 else
245 /* Avoid losing memory. */
246 gfc_free_ref_list (*tail);
247 c = gfc_find_component (derived, name, true, true, tail);
249 if (c) {
250 for (ref = *tail; ref->next; ref = ref->next)
252 ref->next = next;
253 if (!next)
254 e->ts = c->ts;
259 /* This is used to add both the _data component reference and an array
260 reference to class expressions. Used in translation of intrinsic
261 array inquiry functions. */
263 void
264 gfc_add_class_array_ref (gfc_expr *e)
266 int rank = CLASS_DATA (e)->as->rank;
267 gfc_array_spec *as = CLASS_DATA (e)->as;
268 gfc_ref *ref = NULL;
269 gfc_add_data_component (e);
270 e->rank = rank;
271 for (ref = e->ref; ref; ref = ref->next)
272 if (!ref->next)
273 break;
274 if (ref->type != REF_ARRAY)
276 ref->next = gfc_get_ref ();
277 ref = ref->next;
278 ref->type = REF_ARRAY;
279 ref->u.ar.type = AR_FULL;
280 ref->u.ar.as = as;
285 /* Unfortunately, class array expressions can appear in various conditions;
286 with and without both _data component and an arrayspec. This function
287 deals with that variability. The previous reference to 'ref' is to a
288 class array. */
290 static bool
291 class_array_ref_detected (gfc_ref *ref, bool *full_array)
293 bool no_data = false;
294 bool with_data = false;
296 /* An array reference with no _data component. */
297 if (ref && ref->type == REF_ARRAY
298 && !ref->next
299 && ref->u.ar.type != AR_ELEMENT)
301 if (full_array)
302 *full_array = ref->u.ar.type == AR_FULL;
303 no_data = true;
306 /* Cover cases where _data appears, with or without an array ref. */
307 if (ref && ref->type == REF_COMPONENT
308 && strcmp (ref->u.c.component->name, "_data") == 0)
310 if (!ref->next)
312 with_data = true;
313 if (full_array)
314 *full_array = true;
316 else if (ref->next && ref->next->type == REF_ARRAY
317 && ref->type == REF_COMPONENT
318 && ref->next->u.ar.type != AR_ELEMENT)
320 with_data = true;
321 if (full_array)
322 *full_array = ref->next->u.ar.type == AR_FULL;
326 return no_data || with_data;
330 /* Returns true if the expression contains a reference to a class
331 array. Notice that class array elements return false. */
333 bool
334 gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
336 gfc_ref *ref;
338 if (!e->rank)
339 return false;
341 if (full_array)
342 *full_array= false;
344 /* Is this a class array object? ie. Is the symbol of type class? */
345 if (e->symtree
346 && e->symtree->n.sym->ts.type == BT_CLASS
347 && CLASS_DATA (e->symtree->n.sym)
348 && CLASS_DATA (e->symtree->n.sym)->attr.dimension
349 && class_array_ref_detected (e->ref, full_array))
350 return true;
352 /* Or is this a class array component reference? */
353 for (ref = e->ref; ref; ref = ref->next)
355 if (ref->type == REF_COMPONENT
356 && ref->u.c.component->ts.type == BT_CLASS
357 && CLASS_DATA (ref->u.c.component)->attr.dimension
358 && class_array_ref_detected (ref->next, full_array))
359 return true;
362 return false;
366 /* Returns true if the expression is a reference to a class
367 scalar. This function is necessary because such expressions
368 can be dressed with a reference to the _data component and so
369 have a type other than BT_CLASS. */
371 bool
372 gfc_is_class_scalar_expr (gfc_expr *e)
374 gfc_ref *ref;
376 if (e->rank)
377 return false;
379 /* Is this a class object? */
380 if (e->symtree
381 && e->symtree->n.sym->ts.type == BT_CLASS
382 && CLASS_DATA (e->symtree->n.sym)
383 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
384 && (e->ref == NULL
385 || (e->ref->type == REF_COMPONENT
386 && strcmp (e->ref->u.c.component->name, "_data") == 0
387 && e->ref->next == NULL)))
388 return true;
390 /* Or is the final reference BT_CLASS or _data? */
391 for (ref = e->ref; ref; ref = ref->next)
393 if (ref->type == REF_COMPONENT
394 && ref->u.c.component->ts.type == BT_CLASS
395 && CLASS_DATA (ref->u.c.component)
396 && !CLASS_DATA (ref->u.c.component)->attr.dimension
397 && (ref->next == NULL
398 || (ref->next->type == REF_COMPONENT
399 && strcmp (ref->next->u.c.component->name, "_data") == 0
400 && ref->next->next == NULL)))
401 return true;
404 return false;
408 /* Tells whether the expression E is a reference to a (scalar) class container.
409 Scalar because array class containers usually have an array reference after
410 them, and gfc_fix_class_refs will add the missing "_data" component reference
411 in that case. */
413 bool
414 gfc_is_class_container_ref (gfc_expr *e)
416 gfc_ref *ref;
417 bool result;
419 if (e->expr_type != EXPR_VARIABLE)
420 return e->ts.type == BT_CLASS;
422 if (e->symtree->n.sym->ts.type == BT_CLASS)
423 result = true;
424 else
425 result = false;
427 for (ref = e->ref; ref; ref = ref->next)
429 if (ref->type != REF_COMPONENT)
430 result = false;
431 else if (ref->u.c.component->ts.type == BT_CLASS)
432 result = true;
433 else
434 result = false;
437 return result;
441 /* Build an initializer for CLASS pointers,
442 initializing the _data component to the init_expr (or NULL) and the _vptr
443 component to the corresponding type (or the declared type, given by ts). */
445 gfc_expr *
446 gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
448 gfc_expr *init;
449 gfc_component *comp;
450 gfc_symbol *vtab = NULL;
452 if (init_expr && init_expr->expr_type != EXPR_NULL)
453 vtab = gfc_find_vtab (&init_expr->ts);
454 else
455 vtab = gfc_find_vtab (ts);
457 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
458 &ts->u.derived->declared_at);
459 init->ts = *ts;
461 for (comp = ts->u.derived->components; comp; comp = comp->next)
463 gfc_constructor *ctor = gfc_constructor_get();
464 if (strcmp (comp->name, "_vptr") == 0 && vtab)
465 ctor->expr = gfc_lval_expr_from_sym (vtab);
466 else if (init_expr && init_expr->expr_type != EXPR_NULL)
467 ctor->expr = gfc_copy_expr (init_expr);
468 else
469 ctor->expr = gfc_get_null_expr (NULL);
470 gfc_constructor_append (&init->value.constructor, ctor);
473 return init;
477 /* Create a unique string identifier for a derived type, composed of its name
478 and module name. This is used to construct unique names for the class
479 containers and vtab symbols. */
481 static char *
482 get_unique_type_string (gfc_symbol *derived)
484 const char *dt_name;
485 char *string;
486 size_t len;
487 if (derived->attr.unlimited_polymorphic)
488 dt_name = "STAR";
489 else
490 dt_name = gfc_dt_upper_string (derived->name);
491 len = strlen (dt_name) + 2;
492 if (derived->attr.unlimited_polymorphic)
494 string = XNEWVEC (char, len);
495 sprintf (string, "_%s", dt_name);
497 else if (derived->module)
499 string = XNEWVEC (char, strlen (derived->module) + len);
500 sprintf (string, "%s_%s", derived->module, dt_name);
502 else if (derived->ns->proc_name)
504 string = XNEWVEC (char, strlen (derived->ns->proc_name->name) + len);
505 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
507 else
509 string = XNEWVEC (char, len);
510 sprintf (string, "_%s", dt_name);
512 return string;
516 /* A relative of 'get_unique_type_string' which makes sure the generated
517 string will not be too long (replacing it by a hash string if needed). */
519 static void
520 get_unique_hashed_string (char *string, gfc_symbol *derived)
522 /* Provide sufficient space to hold "symbol.symbol_symbol". */
523 char *tmp;
524 tmp = get_unique_type_string (derived);
525 /* If string is too long, use hash value in hex representation (allow for
526 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
527 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
528 where %d is the (co)rank which can be up to n = 15. */
529 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
531 int h = gfc_hash_value (derived);
532 sprintf (string, "%X", h);
534 else
535 strcpy (string, tmp);
536 free (tmp);
540 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
542 unsigned int
543 gfc_hash_value (gfc_symbol *sym)
545 unsigned int hash = 0;
546 /* Provide sufficient space to hold "symbol.symbol_symbol". */
547 char *c;
548 int i, len;
550 c = get_unique_type_string (sym);
551 len = strlen (c);
553 for (i = 0; i < len; i++)
554 hash = (hash << 6) + (hash << 16) - hash + c[i];
556 free (c);
557 /* Return the hash but take the modulus for the sake of module read,
558 even though this slightly increases the chance of collision. */
559 return (hash % 100000000);
563 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
565 unsigned int
566 gfc_intrinsic_hash_value (gfc_typespec *ts)
568 unsigned int hash = 0;
569 const char *c = gfc_typename (ts, true);
570 int i, len;
572 len = strlen (c);
574 for (i = 0; i < len; i++)
575 hash = (hash << 6) + (hash << 16) - hash + c[i];
577 /* Return the hash but take the modulus for the sake of module read,
578 even though this slightly increases the chance of collision. */
579 return (hash % 100000000);
583 /* Get the _len component from a class/derived object storing a string.
584 For unlimited polymorphic entities a ref to the _data component is available
585 while a ref to the _len component is needed. This routine traverese the
586 ref-chain and strips the last ref to a _data from it replacing it with a
587 ref to the _len component. */
589 gfc_expr *
590 gfc_get_len_component (gfc_expr *e, int k)
592 gfc_expr *ptr;
593 gfc_ref *ref, **last;
595 ptr = gfc_copy_expr (e);
597 /* We need to remove the last _data component ref from ptr. */
598 last = &(ptr->ref);
599 ref = ptr->ref;
600 while (ref)
602 if (!ref->next
603 && ref->type == REF_COMPONENT
604 && strcmp ("_data", ref->u.c.component->name)== 0)
606 gfc_free_ref_list (ref);
607 *last = NULL;
608 break;
610 last = &(ref->next);
611 ref = ref->next;
613 /* And replace if with a ref to the _len component. */
614 gfc_add_len_component (ptr);
615 if (k != ptr->ts.kind)
617 gfc_typespec ts;
618 gfc_clear_ts (&ts);
619 ts.type = BT_INTEGER;
620 ts.kind = k;
621 gfc_convert_type_warn (ptr, &ts, 2, 0);
623 return ptr;
627 /* Build a polymorphic CLASS entity, using the symbol that comes from
628 build_sym. A CLASS entity is represented by an encapsulating type,
629 which contains the declared type as '_data' component, plus a pointer
630 component '_vptr' which determines the dynamic type. When this CLASS
631 entity is unlimited polymorphic, then also add a component '_len' to
632 store the length of string when that is stored in it. */
633 static int ctr = 0;
635 bool
636 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
637 gfc_array_spec **as)
639 char tname[GFC_MAX_SYMBOL_LEN+1];
640 char *name;
641 gfc_symbol *fclass;
642 gfc_symbol *vtab;
643 gfc_component *c;
644 gfc_namespace *ns;
645 int rank;
647 gcc_assert (as);
649 if (attr->class_ok)
650 /* Class container has already been built. */
651 return true;
653 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
654 || attr->select_type_temporary || attr->associate_var;
656 if (!attr->class_ok)
657 /* We cannot build the class container yet. */
658 return true;
660 /* Determine the name of the encapsulating type. */
661 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
663 if (!ts->u.derived)
664 return false;
666 get_unique_hashed_string (tname, ts->u.derived);
667 if ((*as) && attr->allocatable)
668 name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
669 else if ((*as) && attr->pointer)
670 name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
671 else if ((*as))
672 name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
673 else if (attr->pointer)
674 name = xasprintf ("__class_%s_p", tname);
675 else if (attr->allocatable)
676 name = xasprintf ("__class_%s_a", tname);
677 else
678 name = xasprintf ("__class_%s_t", tname);
680 if (ts->u.derived->attr.unlimited_polymorphic)
682 /* Find the top-level namespace. */
683 for (ns = gfc_current_ns; ns; ns = ns->parent)
684 if (!ns->parent)
685 break;
687 else
688 ns = ts->u.derived->ns;
690 /* Although this might seem to be counterintuitive, we can build separate
691 class types with different array specs because the TKR interface checks
692 work on the declared type. All array type other than deferred shape or
693 assumed rank are added to the function namespace to ensure that they
694 are properly distinguished. */
695 if (attr->dummy && !attr->codimension && (*as)
696 && !((*as)->type == AS_DEFERRED || (*as)->type == AS_ASSUMED_RANK))
698 char *sname;
699 ns = gfc_current_ns;
700 gfc_find_symbol (name, ns, 0, &fclass);
701 /* If a local class type with this name already exists, update the
702 name with an index. */
703 if (fclass)
705 fclass = NULL;
706 sname = xasprintf ("%s_%d", name, ++ctr);
707 free (name);
708 name = sname;
711 else
712 gfc_find_symbol (name, ns, 0, &fclass);
714 if (fclass == NULL)
716 gfc_symtree *st;
717 /* If not there, create a new symbol. */
718 fclass = gfc_new_symbol (name, ns);
719 st = gfc_new_symtree (&ns->sym_root, name);
720 st->n.sym = fclass;
721 gfc_set_sym_referenced (fclass);
722 fclass->refs++;
723 fclass->ts.type = BT_UNKNOWN;
724 if (!ts->u.derived->attr.unlimited_polymorphic)
725 fclass->attr.abstract = ts->u.derived->attr.abstract;
726 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
727 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
728 &gfc_current_locus))
729 return false;
731 /* Add component '_data'. */
732 if (!gfc_add_component (fclass, "_data", &c))
733 return false;
734 c->ts = *ts;
735 c->ts.type = BT_DERIVED;
736 c->attr.access = ACCESS_PRIVATE;
737 c->ts.u.derived = ts->u.derived;
738 c->attr.class_pointer = attr->pointer;
739 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
740 || attr->select_type_temporary;
741 c->attr.allocatable = attr->allocatable;
742 c->attr.dimension = attr->dimension;
743 c->attr.codimension = attr->codimension;
744 c->attr.abstract = fclass->attr.abstract;
745 c->as = (*as);
746 c->initializer = NULL;
748 /* Add component '_vptr'. */
749 if (!gfc_add_component (fclass, "_vptr", &c))
750 return false;
751 c->ts.type = BT_DERIVED;
752 c->attr.access = ACCESS_PRIVATE;
753 c->attr.pointer = 1;
755 if (ts->u.derived->attr.unlimited_polymorphic)
757 vtab = gfc_find_derived_vtab (ts->u.derived);
758 gcc_assert (vtab);
759 c->ts.u.derived = vtab->ts.u.derived;
761 /* Add component '_len'. Only unlimited polymorphic pointers may
762 have a string assigned to them, i.e., only those need the _len
763 component. */
764 if (!gfc_add_component (fclass, "_len", &c))
765 return false;
766 c->ts.type = BT_INTEGER;
767 c->ts.kind = gfc_charlen_int_kind;
768 c->attr.access = ACCESS_PRIVATE;
769 c->attr.artificial = 1;
771 else
772 /* Build vtab later. */
773 c->ts.u.derived = NULL;
776 if (!ts->u.derived->attr.unlimited_polymorphic)
778 /* Since the extension field is 8 bit wide, we can only have
779 up to 255 extension levels. */
780 if (ts->u.derived->attr.extension == 255)
782 gfc_error ("Maximum extension level reached with type %qs at %L",
783 ts->u.derived->name, &ts->u.derived->declared_at);
784 return false;
787 fclass->attr.extension = ts->u.derived->attr.extension + 1;
788 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
789 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
792 fclass->attr.is_class = 1;
793 ts->u.derived = fclass;
794 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
795 (*as) = NULL;
796 free (name);
797 return true;
801 /* Add a procedure pointer component to the vtype
802 to represent a specific type-bound procedure. */
804 static void
805 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
807 gfc_component *c;
809 if (tb->non_overridable && !tb->overridden)
810 return;
812 c = gfc_find_component (vtype, name, true, true, NULL);
814 if (c == NULL)
816 /* Add procedure component. */
817 if (!gfc_add_component (vtype, name, &c))
818 return;
820 if (!c->tb)
821 c->tb = XCNEW (gfc_typebound_proc);
822 *c->tb = *tb;
823 c->tb->ppc = 1;
824 c->attr.procedure = 1;
825 c->attr.proc_pointer = 1;
826 c->attr.flavor = FL_PROCEDURE;
827 c->attr.access = ACCESS_PRIVATE;
828 c->attr.external = 1;
829 c->attr.untyped = 1;
830 c->attr.if_source = IFSRC_IFBODY;
832 else if (c->attr.proc_pointer && c->tb)
834 *c->tb = *tb;
835 c->tb->ppc = 1;
838 if (tb->u.specific)
840 gfc_symbol *ifc = tb->u.specific->n.sym;
841 c->ts.interface = ifc;
842 if (!tb->deferred)
843 c->initializer = gfc_get_variable_expr (tb->u.specific);
844 c->attr.pure = ifc->attr.pure;
849 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
851 static void
852 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
854 if (!st)
855 return;
857 if (st->left)
858 add_procs_to_declared_vtab1 (st->left, vtype);
860 if (st->right)
861 add_procs_to_declared_vtab1 (st->right, vtype);
863 if (st->n.tb && !st->n.tb->error
864 && !st->n.tb->is_generic && st->n.tb->u.specific)
865 add_proc_comp (vtype, st->name, st->n.tb);
869 /* Copy procedure pointers components from the parent type. */
871 static void
872 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
874 gfc_component *cmp;
875 gfc_symbol *vtab;
877 vtab = gfc_find_derived_vtab (declared);
879 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
881 if (gfc_find_component (vtype, cmp->name, true, true, NULL))
882 continue;
884 add_proc_comp (vtype, cmp->name, cmp->tb);
889 /* Returns true if any of its nonpointer nonallocatable components or
890 their nonpointer nonallocatable subcomponents has a finalization
891 subroutine. */
893 static bool
894 has_finalizer_component (gfc_symbol *derived)
896 gfc_component *c;
898 for (c = derived->components; c; c = c->next)
899 if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable)
901 if (c->ts.u.derived->f2k_derived
902 && c->ts.u.derived->f2k_derived->finalizers)
903 return true;
905 /* Stop infinite recursion through this function by inhibiting
906 calls when the derived type and that of the component are
907 the same. */
908 if (!gfc_compare_derived_types (derived, c->ts.u.derived)
909 && has_finalizer_component (c->ts.u.derived))
910 return true;
912 return false;
916 static bool
917 comp_is_finalizable (gfc_component *comp)
919 if (comp->attr.proc_pointer)
920 return false;
921 else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
922 return true;
923 else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
924 && (comp->ts.u.derived->attr.alloc_comp
925 || has_finalizer_component (comp->ts.u.derived)
926 || (comp->ts.u.derived->f2k_derived
927 && comp->ts.u.derived->f2k_derived->finalizers)))
928 return true;
929 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
930 && CLASS_DATA (comp)->attr.allocatable)
931 return true;
932 else
933 return false;
937 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
938 neither allocatable nor a pointer but has a finalizer, call it. If it
939 is a nonpointer component with allocatable components or has finalizers, walk
940 them. Either of them is required; other nonallocatables and pointers aren't
941 handled gracefully.
942 Note: If the component is allocatable, the DEALLOCATE handling takes care
943 of calling the appropriate finalizers, coarray deregistering, and
944 deallocation of allocatable subcomponents. */
946 static void
947 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
948 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
949 gfc_namespace *sub_ns)
951 gfc_expr *e;
952 gfc_ref *ref;
953 gfc_was_finalized *f;
955 if (!comp_is_finalizable (comp))
956 return;
958 /* If this expression with this component has been finalized
959 already in this namespace, there is nothing to do. */
960 for (f = sub_ns->was_finalized; f; f = f->next)
962 if (f->e == expr && f->c == comp)
963 return;
966 e = gfc_copy_expr (expr);
967 if (!e->ref)
968 e->ref = ref = gfc_get_ref ();
969 else
971 for (ref = e->ref; ref->next; ref = ref->next)
973 ref->next = gfc_get_ref ();
974 ref = ref->next;
976 ref->type = REF_COMPONENT;
977 ref->u.c.sym = derived;
978 ref->u.c.component = comp;
979 e->ts = comp->ts;
981 if (comp->attr.dimension || comp->attr.codimension
982 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
983 && (CLASS_DATA (comp)->attr.dimension
984 || CLASS_DATA (comp)->attr.codimension)))
986 ref->next = gfc_get_ref ();
987 ref->next->type = REF_ARRAY;
988 ref->next->u.ar.dimen = 0;
989 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
990 : comp->as;
991 e->rank = ref->next->u.ar.as->rank;
992 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
995 /* Call DEALLOCATE (comp, stat=ignore). */
996 if (comp->attr.allocatable
997 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
998 && CLASS_DATA (comp)->attr.allocatable))
1000 gfc_code *dealloc, *block = NULL;
1002 /* Add IF (fini_coarray). */
1003 if (comp->attr.codimension
1004 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1005 && CLASS_DATA (comp)->attr.codimension))
1007 block = gfc_get_code (EXEC_IF);
1008 if (*code)
1010 (*code)->next = block;
1011 (*code) = (*code)->next;
1013 else
1014 (*code) = block;
1016 block->block = gfc_get_code (EXEC_IF);
1017 block = block->block;
1018 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
1021 dealloc = gfc_get_code (EXEC_DEALLOCATE);
1023 dealloc->ext.alloc.list = gfc_get_alloc ();
1024 dealloc->ext.alloc.list->expr = e;
1025 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
1027 gfc_code *cond = gfc_get_code (EXEC_IF);
1028 cond->block = gfc_get_code (EXEC_IF);
1029 cond->block->expr1 = gfc_get_expr ();
1030 cond->block->expr1->expr_type = EXPR_FUNCTION;
1031 cond->block->expr1->where = gfc_current_locus;
1032 gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
1033 cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1034 cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
1035 cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
1036 gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
1037 cond->block->expr1->ts.type = BT_LOGICAL;
1038 cond->block->expr1->ts.kind = gfc_default_logical_kind;
1039 cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
1040 cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
1041 cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
1042 cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
1043 cond->block->next = dealloc;
1045 if (block)
1046 block->next = cond;
1047 else if (*code)
1049 (*code)->next = cond;
1050 (*code) = (*code)->next;
1052 else
1053 (*code) = cond;
1056 else if (comp->ts.type == BT_DERIVED
1057 && comp->ts.u.derived->f2k_derived
1058 && comp->ts.u.derived->f2k_derived->finalizers)
1060 /* Call FINAL_WRAPPER (comp); */
1061 gfc_code *final_wrap;
1062 gfc_symbol *vtab;
1063 gfc_component *c;
1065 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
1066 for (c = vtab->ts.u.derived->components; c; c = c->next)
1067 if (strcmp (c->name, "_final") == 0)
1068 break;
1070 gcc_assert (c);
1071 final_wrap = gfc_get_code (EXEC_CALL);
1072 final_wrap->symtree = c->initializer->symtree;
1073 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
1074 final_wrap->ext.actual = gfc_get_actual_arglist ();
1075 final_wrap->ext.actual->expr = e;
1077 if (*code)
1079 (*code)->next = final_wrap;
1080 (*code) = (*code)->next;
1082 else
1083 (*code) = final_wrap;
1085 else
1087 gfc_component *c;
1089 for (c = comp->ts.u.derived->components; c; c = c->next)
1090 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code,
1091 sub_ns);
1092 gfc_free_expr (e);
1095 /* Record that this was finalized already in this namespace. */
1096 f = sub_ns->was_finalized;
1097 sub_ns->was_finalized = XCNEW (gfc_was_finalized);
1098 sub_ns->was_finalized->e = expr;
1099 sub_ns->was_finalized->c = comp;
1100 sub_ns->was_finalized->next = f;
1104 /* Generate code equivalent to
1105 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1106 + offset, c_ptr), ptr). */
1108 static gfc_code *
1109 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
1110 gfc_expr *offset, gfc_namespace *sub_ns)
1112 gfc_code *block;
1113 gfc_expr *expr, *expr2;
1115 /* C_F_POINTER(). */
1116 block = gfc_get_code (EXEC_CALL);
1117 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
1118 block->resolved_sym = block->symtree->n.sym;
1119 block->resolved_sym->attr.flavor = FL_PROCEDURE;
1120 block->resolved_sym->attr.intrinsic = 1;
1121 block->resolved_sym->attr.subroutine = 1;
1122 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
1123 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
1124 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
1125 gfc_commit_symbol (block->resolved_sym);
1127 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
1128 block->ext.actual = gfc_get_actual_arglist ();
1129 block->ext.actual->next = gfc_get_actual_arglist ();
1130 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
1131 NULL, 0);
1132 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
1134 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
1136 /* TRANSFER's first argument: C_LOC (array). */
1137 expr = gfc_get_expr ();
1138 expr->expr_type = EXPR_FUNCTION;
1139 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
1140 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1141 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
1142 expr->symtree->n.sym->attr.intrinsic = 1;
1143 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
1144 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
1145 expr->value.function.actual = gfc_get_actual_arglist ();
1146 expr->value.function.actual->expr
1147 = gfc_lval_expr_from_sym (array);
1148 expr->symtree->n.sym->result = expr->symtree->n.sym;
1149 gfc_commit_symbol (expr->symtree->n.sym);
1150 expr->ts.type = BT_INTEGER;
1151 expr->ts.kind = gfc_index_integer_kind;
1152 expr->where = gfc_current_locus;
1154 /* TRANSFER. */
1155 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
1156 gfc_current_locus, 3, expr,
1157 gfc_get_int_expr (gfc_index_integer_kind,
1158 NULL, 0), NULL);
1159 expr2->ts.type = BT_INTEGER;
1160 expr2->ts.kind = gfc_index_integer_kind;
1162 /* <array addr> + <offset>. */
1163 block->ext.actual->expr = gfc_get_expr ();
1164 block->ext.actual->expr->expr_type = EXPR_OP;
1165 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
1166 block->ext.actual->expr->value.op.op1 = expr2;
1167 block->ext.actual->expr->value.op.op2 = offset;
1168 block->ext.actual->expr->ts = expr->ts;
1169 block->ext.actual->expr->where = gfc_current_locus;
1171 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1172 block->ext.actual->next = gfc_get_actual_arglist ();
1173 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1174 block->ext.actual->next->next = gfc_get_actual_arglist ();
1176 return block;
1180 /* Calculates the offset to the (idx+1)th element of an array, taking the
1181 stride into account. It generates the code:
1182 offset = 0
1183 do idx2 = 1, rank
1184 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1185 end do
1186 offset = offset * byte_stride. */
1188 static gfc_code*
1189 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1190 gfc_symbol *strides, gfc_symbol *sizes,
1191 gfc_symbol *byte_stride, gfc_expr *rank,
1192 gfc_code *block, gfc_namespace *sub_ns)
1194 gfc_iterator *iter;
1195 gfc_expr *expr, *expr2;
1197 /* offset = 0. */
1198 block->next = gfc_get_code (EXEC_ASSIGN);
1199 block = block->next;
1200 block->expr1 = gfc_lval_expr_from_sym (offset);
1201 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1203 /* Create loop. */
1204 iter = gfc_get_iterator ();
1205 iter->var = gfc_lval_expr_from_sym (idx2);
1206 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1207 iter->end = gfc_copy_expr (rank);
1208 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1209 block->next = gfc_get_code (EXEC_DO);
1210 block = block->next;
1211 block->ext.iterator = iter;
1212 block->block = gfc_get_code (EXEC_DO);
1214 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1215 * strides(idx2). */
1217 /* mod (idx, sizes(idx2)). */
1218 expr = gfc_lval_expr_from_sym (sizes);
1219 expr->ref = gfc_get_ref ();
1220 expr->ref->type = REF_ARRAY;
1221 expr->ref->u.ar.as = sizes->as;
1222 expr->ref->u.ar.type = AR_ELEMENT;
1223 expr->ref->u.ar.dimen = 1;
1224 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1225 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1226 expr->where = sizes->declared_at;
1228 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1229 gfc_current_locus, 2,
1230 gfc_lval_expr_from_sym (idx), expr);
1231 expr->ts = idx->ts;
1233 /* (...) / sizes(idx2-1). */
1234 expr2 = gfc_get_expr ();
1235 expr2->expr_type = EXPR_OP;
1236 expr2->value.op.op = INTRINSIC_DIVIDE;
1237 expr2->value.op.op1 = expr;
1238 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1239 expr2->value.op.op2->ref = gfc_get_ref ();
1240 expr2->value.op.op2->ref->type = REF_ARRAY;
1241 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1242 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1243 expr2->value.op.op2->ref->u.ar.dimen = 1;
1244 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1245 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1246 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1247 expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1248 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1249 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1250 = gfc_lval_expr_from_sym (idx2);
1251 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1252 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1253 expr2->value.op.op2->ref->u.ar.start[0]->ts
1254 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1255 expr2->ts = idx->ts;
1256 expr2->where = gfc_current_locus;
1258 /* ... * strides(idx2). */
1259 expr = gfc_get_expr ();
1260 expr->expr_type = EXPR_OP;
1261 expr->value.op.op = INTRINSIC_TIMES;
1262 expr->value.op.op1 = expr2;
1263 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1264 expr->value.op.op2->ref = gfc_get_ref ();
1265 expr->value.op.op2->ref->type = REF_ARRAY;
1266 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1267 expr->value.op.op2->ref->u.ar.dimen = 1;
1268 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1269 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1270 expr->value.op.op2->ref->u.ar.as = strides->as;
1271 expr->ts = idx->ts;
1272 expr->where = gfc_current_locus;
1274 /* offset = offset + ... */
1275 block->block->next = gfc_get_code (EXEC_ASSIGN);
1276 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1277 block->block->next->expr2 = gfc_get_expr ();
1278 block->block->next->expr2->expr_type = EXPR_OP;
1279 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1280 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1281 block->block->next->expr2->value.op.op2 = expr;
1282 block->block->next->expr2->ts = idx->ts;
1283 block->block->next->expr2->where = gfc_current_locus;
1285 /* After the loop: offset = offset * byte_stride. */
1286 block->next = gfc_get_code (EXEC_ASSIGN);
1287 block = block->next;
1288 block->expr1 = gfc_lval_expr_from_sym (offset);
1289 block->expr2 = gfc_get_expr ();
1290 block->expr2->expr_type = EXPR_OP;
1291 block->expr2->value.op.op = INTRINSIC_TIMES;
1292 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1293 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1294 block->expr2->ts = block->expr2->value.op.op1->ts;
1295 block->expr2->where = gfc_current_locus;
1296 return block;
1300 /* Insert code of the following form:
1302 block
1303 integer(c_intptr_t) :: i
1305 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1306 && (is_contiguous || !final_rank3->attr.contiguous
1307 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1308 || 0 == STORAGE_SIZE (array)) then
1309 call final_rank3 (array)
1310 else
1311 block
1312 integer(c_intptr_t) :: offset, j
1313 type(t) :: tmp(shape (array))
1315 do i = 0, size (array)-1
1316 offset = obtain_offset(i, strides, sizes, byte_stride)
1317 addr = transfer (c_loc (array), addr) + offset
1318 call c_f_pointer (transfer (addr, cptr), ptr)
1320 addr = transfer (c_loc (tmp), addr)
1321 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1322 call c_f_pointer (transfer (addr, cptr), ptr2)
1323 ptr2 = ptr
1324 end do
1325 call final_rank3 (tmp)
1326 end block
1327 end if
1328 block */
1330 static void
1331 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1332 gfc_symbol *array, gfc_symbol *byte_stride,
1333 gfc_symbol *idx, gfc_symbol *ptr,
1334 gfc_symbol *nelem,
1335 gfc_symbol *strides, gfc_symbol *sizes,
1336 gfc_symbol *idx2, gfc_symbol *offset,
1337 gfc_symbol *is_contiguous, gfc_expr *rank,
1338 gfc_namespace *sub_ns)
1340 gfc_symbol *tmp_array, *ptr2;
1341 gfc_expr *size_expr, *offset2, *expr;
1342 gfc_namespace *ns;
1343 gfc_iterator *iter;
1344 gfc_code *block2;
1345 int i;
1347 block->next = gfc_get_code (EXEC_IF);
1348 block = block->next;
1350 block->block = gfc_get_code (EXEC_IF);
1351 block = block->block;
1353 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1354 size_expr = gfc_get_expr ();
1355 size_expr->where = gfc_current_locus;
1356 size_expr->expr_type = EXPR_OP;
1357 size_expr->value.op.op = INTRINSIC_DIVIDE;
1359 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1360 size_expr->value.op.op1
1361 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1362 "storage_size", gfc_current_locus, 2,
1363 gfc_lval_expr_from_sym (array),
1364 gfc_get_int_expr (gfc_index_integer_kind,
1365 NULL, 0));
1367 /* NUMERIC_STORAGE_SIZE. */
1368 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1369 gfc_character_storage_size);
1370 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1371 size_expr->ts = size_expr->value.op.op1->ts;
1373 /* IF condition: (stride == size_expr
1374 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1375 || is_contiguous)
1376 || 0 == size_expr. */
1377 block->expr1 = gfc_get_expr ();
1378 block->expr1->ts.type = BT_LOGICAL;
1379 block->expr1->ts.kind = gfc_default_logical_kind;
1380 block->expr1->expr_type = EXPR_OP;
1381 block->expr1->where = gfc_current_locus;
1383 block->expr1->value.op.op = INTRINSIC_OR;
1385 /* byte_stride == size_expr */
1386 expr = gfc_get_expr ();
1387 expr->ts.type = BT_LOGICAL;
1388 expr->ts.kind = gfc_default_logical_kind;
1389 expr->expr_type = EXPR_OP;
1390 expr->where = gfc_current_locus;
1391 expr->value.op.op = INTRINSIC_EQ;
1392 expr->value.op.op1
1393 = gfc_lval_expr_from_sym (byte_stride);
1394 expr->value.op.op2 = size_expr;
1396 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1397 add is_contiguous check. */
1399 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1400 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1402 gfc_expr *expr2;
1403 expr2 = gfc_get_expr ();
1404 expr2->ts.type = BT_LOGICAL;
1405 expr2->ts.kind = gfc_default_logical_kind;
1406 expr2->expr_type = EXPR_OP;
1407 expr2->where = gfc_current_locus;
1408 expr2->value.op.op = INTRINSIC_AND;
1409 expr2->value.op.op1 = expr;
1410 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1411 expr = expr2;
1414 block->expr1->value.op.op1 = expr;
1416 /* 0 == size_expr */
1417 block->expr1->value.op.op2 = gfc_get_expr ();
1418 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1419 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1420 block->expr1->value.op.op2->expr_type = EXPR_OP;
1421 block->expr1->value.op.op2->where = gfc_current_locus;
1422 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1423 block->expr1->value.op.op2->value.op.op1 =
1424 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1425 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1427 /* IF body: call final subroutine. */
1428 block->next = gfc_get_code (EXEC_CALL);
1429 block->next->symtree = fini->proc_tree;
1430 block->next->resolved_sym = fini->proc_tree->n.sym;
1431 block->next->ext.actual = gfc_get_actual_arglist ();
1432 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1433 block->next->ext.actual->next = gfc_get_actual_arglist ();
1434 block->next->ext.actual->next->expr = gfc_copy_expr (size_expr);
1436 /* ELSE. */
1438 block->block = gfc_get_code (EXEC_IF);
1439 block = block->block;
1441 /* BLOCK ... END BLOCK. */
1442 block->next = gfc_get_code (EXEC_BLOCK);
1443 block = block->next;
1445 ns = gfc_build_block_ns (sub_ns);
1446 block->ext.block.ns = ns;
1447 block->ext.block.assoc = NULL;
1449 gfc_get_symbol ("ptr2", ns, &ptr2);
1450 ptr2->ts.type = BT_DERIVED;
1451 ptr2->ts.u.derived = array->ts.u.derived;
1452 ptr2->attr.flavor = FL_VARIABLE;
1453 ptr2->attr.pointer = 1;
1454 ptr2->attr.artificial = 1;
1455 gfc_set_sym_referenced (ptr2);
1456 gfc_commit_symbol (ptr2);
1458 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1459 tmp_array->ts.type = BT_DERIVED;
1460 tmp_array->ts.u.derived = array->ts.u.derived;
1461 tmp_array->attr.flavor = FL_VARIABLE;
1462 tmp_array->attr.dimension = 1;
1463 tmp_array->attr.artificial = 1;
1464 tmp_array->as = gfc_get_array_spec();
1465 tmp_array->attr.intent = INTENT_INOUT;
1466 tmp_array->as->type = AS_EXPLICIT;
1467 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1469 for (i = 0; i < tmp_array->as->rank; i++)
1471 gfc_expr *shape_expr;
1472 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1473 NULL, 1);
1474 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1475 shape_expr
1476 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1477 gfc_current_locus, 3,
1478 gfc_lval_expr_from_sym (array),
1479 gfc_get_int_expr (gfc_default_integer_kind,
1480 NULL, i+1),
1481 gfc_get_int_expr (gfc_default_integer_kind,
1482 NULL,
1483 gfc_index_integer_kind));
1484 shape_expr->ts.kind = gfc_index_integer_kind;
1485 tmp_array->as->upper[i] = shape_expr;
1487 gfc_set_sym_referenced (tmp_array);
1488 gfc_commit_symbol (tmp_array);
1490 /* Create loop. */
1491 iter = gfc_get_iterator ();
1492 iter->var = gfc_lval_expr_from_sym (idx);
1493 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1494 iter->end = gfc_lval_expr_from_sym (nelem);
1495 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1497 block = gfc_get_code (EXEC_DO);
1498 ns->code = block;
1499 block->ext.iterator = iter;
1500 block->block = gfc_get_code (EXEC_DO);
1502 /* Offset calculation for the new array: idx * size of type (in bytes). */
1503 offset2 = gfc_get_expr ();
1504 offset2->expr_type = EXPR_OP;
1505 offset2->where = gfc_current_locus;
1506 offset2->value.op.op = INTRINSIC_TIMES;
1507 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1508 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1509 offset2->ts = byte_stride->ts;
1511 /* Offset calculation of "array". */
1512 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1513 byte_stride, rank, block->block, sub_ns);
1515 /* Create code for
1516 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1517 + idx * stride, c_ptr), ptr). */
1518 block2->next = finalization_scalarizer (array, ptr,
1519 gfc_lval_expr_from_sym (offset),
1520 sub_ns);
1521 block2 = block2->next;
1522 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1523 block2 = block2->next;
1525 /* ptr2 = ptr. */
1526 block2->next = gfc_get_code (EXEC_ASSIGN);
1527 block2 = block2->next;
1528 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1529 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1531 /* Call now the user's final subroutine. */
1532 block->next = gfc_get_code (EXEC_CALL);
1533 block = block->next;
1534 block->symtree = fini->proc_tree;
1535 block->resolved_sym = fini->proc_tree->n.sym;
1536 block->ext.actual = gfc_get_actual_arglist ();
1537 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1539 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1540 return;
1542 /* Copy back. */
1544 /* Loop. */
1545 iter = gfc_get_iterator ();
1546 iter->var = gfc_lval_expr_from_sym (idx);
1547 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1548 iter->end = gfc_lval_expr_from_sym (nelem);
1549 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1551 block->next = gfc_get_code (EXEC_DO);
1552 block = block->next;
1553 block->ext.iterator = iter;
1554 block->block = gfc_get_code (EXEC_DO);
1556 /* Offset calculation of "array". */
1557 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1558 byte_stride, rank, block->block, sub_ns);
1560 /* Create code for
1561 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1562 + offset, c_ptr), ptr). */
1563 block2->next = finalization_scalarizer (array, ptr,
1564 gfc_lval_expr_from_sym (offset),
1565 sub_ns);
1566 block2 = block2->next;
1567 block2->next = finalization_scalarizer (tmp_array, ptr2,
1568 gfc_copy_expr (offset2), sub_ns);
1569 block2 = block2->next;
1571 /* ptr = ptr2. */
1572 block2->next = gfc_get_code (EXEC_ASSIGN);
1573 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1574 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1578 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1579 derived type "derived". The function first calls the approriate FINAL
1580 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1581 components (but not the inherited ones). Last, it calls the wrapper
1582 subroutine of the parent. The generated wrapper procedure takes as argument
1583 an assumed-rank array.
1584 If neither allocatable components nor FINAL subroutines exists, the vtab
1585 will contain a NULL pointer.
1586 The generated function has the form
1587 _final(assumed-rank array, stride, skip_corarray)
1588 where the array has to be contiguous (except of the lowest dimension). The
1589 stride (in bytes) is used to allow different sizes for ancestor types by
1590 skipping over the additionally added components in the scalarizer. If
1591 "fini_coarray" is false, coarray components are not finalized to allow for
1592 the correct semantic with intrinsic assignment. */
1594 static void
1595 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1596 const char *tname, gfc_component *vtab_final)
1598 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1599 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1600 gfc_component *comp;
1601 gfc_namespace *sub_ns;
1602 gfc_code *last_code, *block;
1603 char *name;
1604 bool finalizable_comp = false;
1605 bool expr_null_wrapper = false;
1606 gfc_expr *ancestor_wrapper = NULL, *rank;
1607 gfc_iterator *iter;
1609 if (derived->attr.unlimited_polymorphic)
1611 vtab_final->initializer = gfc_get_null_expr (NULL);
1612 return;
1615 /* Search for the ancestor's finalizers. */
1616 if (derived->attr.extension && derived->components
1617 && (!derived->components->ts.u.derived->attr.abstract
1618 || has_finalizer_component (derived)))
1620 gfc_symbol *vtab;
1621 gfc_component *comp;
1623 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1624 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1625 if (comp->name[0] == '_' && comp->name[1] == 'f')
1627 ancestor_wrapper = comp->initializer;
1628 break;
1632 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1633 components: Return a NULL() expression; we defer this a bit to have
1634 an interface declaration. */
1635 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1636 && !derived->attr.alloc_comp
1637 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1638 && !has_finalizer_component (derived))
1639 expr_null_wrapper = true;
1640 else
1641 /* Check whether there are new allocatable components. */
1642 for (comp = derived->components; comp; comp = comp->next)
1644 if (comp == derived->components && derived->attr.extension
1645 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1646 continue;
1648 finalizable_comp |= comp_is_finalizable (comp);
1651 /* If there is no new finalizer and no new allocatable, return with
1652 an expr to the ancestor's one. */
1653 if (!expr_null_wrapper && !finalizable_comp
1654 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1656 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1657 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1658 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1659 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1660 return;
1663 /* We now create a wrapper, which does the following:
1664 1. Call the suitable finalization subroutine for this type
1665 2. Loop over all noninherited allocatable components and noninherited
1666 components with allocatable components and DEALLOCATE those; this will
1667 take care of finalizers, coarray deregistering and allocatable
1668 nested components.
1669 3. Call the ancestor's finalizer. */
1671 /* Declare the wrapper function; it takes an assumed-rank array
1672 and a VALUE logical as arguments. */
1674 /* Set up the namespace. */
1675 sub_ns = gfc_get_namespace (ns, 0);
1676 sub_ns->sibling = ns->contained;
1677 if (!expr_null_wrapper)
1678 ns->contained = sub_ns;
1679 sub_ns->resolved = 1;
1681 /* Set up the procedure symbol. */
1682 name = xasprintf ("__final_%s", tname);
1683 gfc_get_symbol (name, sub_ns, &final);
1684 sub_ns->proc_name = final;
1685 final->attr.flavor = FL_PROCEDURE;
1686 final->attr.function = 1;
1687 final->attr.pure = 0;
1688 final->attr.recursive = 1;
1689 final->result = final;
1690 final->ts.type = BT_INTEGER;
1691 final->ts.kind = 4;
1692 final->attr.artificial = 1;
1693 final->attr.always_explicit = 1;
1694 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1695 if (ns->proc_name->attr.flavor == FL_MODULE)
1696 final->module = ns->proc_name->name;
1697 gfc_set_sym_referenced (final);
1698 gfc_commit_symbol (final);
1700 /* Set up formal argument. */
1701 gfc_get_symbol ("array", sub_ns, &array);
1702 array->ts.type = BT_DERIVED;
1703 array->ts.u.derived = derived;
1704 array->attr.flavor = FL_VARIABLE;
1705 array->attr.dummy = 1;
1706 array->attr.contiguous = 1;
1707 array->attr.dimension = 1;
1708 array->attr.artificial = 1;
1709 array->as = gfc_get_array_spec();
1710 array->as->type = AS_ASSUMED_RANK;
1711 array->as->rank = -1;
1712 array->attr.intent = INTENT_INOUT;
1713 gfc_set_sym_referenced (array);
1714 final->formal = gfc_get_formal_arglist ();
1715 final->formal->sym = array;
1716 gfc_commit_symbol (array);
1718 /* Set up formal argument. */
1719 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1720 byte_stride->ts.type = BT_INTEGER;
1721 byte_stride->ts.kind = gfc_index_integer_kind;
1722 byte_stride->attr.flavor = FL_VARIABLE;
1723 byte_stride->attr.dummy = 1;
1724 byte_stride->attr.value = 1;
1725 byte_stride->attr.artificial = 1;
1726 gfc_set_sym_referenced (byte_stride);
1727 final->formal->next = gfc_get_formal_arglist ();
1728 final->formal->next->sym = byte_stride;
1729 gfc_commit_symbol (byte_stride);
1731 /* Set up formal argument. */
1732 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1733 fini_coarray->ts.type = BT_LOGICAL;
1734 fini_coarray->ts.kind = 1;
1735 fini_coarray->attr.flavor = FL_VARIABLE;
1736 fini_coarray->attr.dummy = 1;
1737 fini_coarray->attr.value = 1;
1738 fini_coarray->attr.artificial = 1;
1739 gfc_set_sym_referenced (fini_coarray);
1740 final->formal->next->next = gfc_get_formal_arglist ();
1741 final->formal->next->next->sym = fini_coarray;
1742 gfc_commit_symbol (fini_coarray);
1744 /* Return with a NULL() expression but with an interface which has
1745 the formal arguments. */
1746 if (expr_null_wrapper)
1748 vtab_final->initializer = gfc_get_null_expr (NULL);
1749 vtab_final->ts.interface = final;
1750 return;
1753 /* Local variables. */
1755 gfc_get_symbol ("idx", sub_ns, &idx);
1756 idx->ts.type = BT_INTEGER;
1757 idx->ts.kind = gfc_index_integer_kind;
1758 idx->attr.flavor = FL_VARIABLE;
1759 idx->attr.artificial = 1;
1760 gfc_set_sym_referenced (idx);
1761 gfc_commit_symbol (idx);
1763 gfc_get_symbol ("idx2", sub_ns, &idx2);
1764 idx2->ts.type = BT_INTEGER;
1765 idx2->ts.kind = gfc_index_integer_kind;
1766 idx2->attr.flavor = FL_VARIABLE;
1767 idx2->attr.artificial = 1;
1768 gfc_set_sym_referenced (idx2);
1769 gfc_commit_symbol (idx2);
1771 gfc_get_symbol ("offset", sub_ns, &offset);
1772 offset->ts.type = BT_INTEGER;
1773 offset->ts.kind = gfc_index_integer_kind;
1774 offset->attr.flavor = FL_VARIABLE;
1775 offset->attr.artificial = 1;
1776 gfc_set_sym_referenced (offset);
1777 gfc_commit_symbol (offset);
1779 /* Create RANK expression. */
1780 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1781 gfc_current_locus, 1,
1782 gfc_lval_expr_from_sym (array));
1783 if (rank->ts.kind != idx->ts.kind)
1784 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1786 /* Create is_contiguous variable. */
1787 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1788 is_contiguous->ts.type = BT_LOGICAL;
1789 is_contiguous->ts.kind = gfc_default_logical_kind;
1790 is_contiguous->attr.flavor = FL_VARIABLE;
1791 is_contiguous->attr.artificial = 1;
1792 gfc_set_sym_referenced (is_contiguous);
1793 gfc_commit_symbol (is_contiguous);
1795 /* Create "sizes(0..rank)" variable, which contains the multiplied
1796 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1797 sizes(2) = sizes(1) * extent(dim=2) etc. */
1798 gfc_get_symbol ("sizes", sub_ns, &sizes);
1799 sizes->ts.type = BT_INTEGER;
1800 sizes->ts.kind = gfc_index_integer_kind;
1801 sizes->attr.flavor = FL_VARIABLE;
1802 sizes->attr.dimension = 1;
1803 sizes->attr.artificial = 1;
1804 sizes->as = gfc_get_array_spec();
1805 sizes->attr.intent = INTENT_INOUT;
1806 sizes->as->type = AS_EXPLICIT;
1807 sizes->as->rank = 1;
1808 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1809 sizes->as->upper[0] = gfc_copy_expr (rank);
1810 gfc_set_sym_referenced (sizes);
1811 gfc_commit_symbol (sizes);
1813 /* Create "strides(1..rank)" variable, which contains the strides per
1814 dimension. */
1815 gfc_get_symbol ("strides", sub_ns, &strides);
1816 strides->ts.type = BT_INTEGER;
1817 strides->ts.kind = gfc_index_integer_kind;
1818 strides->attr.flavor = FL_VARIABLE;
1819 strides->attr.dimension = 1;
1820 strides->attr.artificial = 1;
1821 strides->as = gfc_get_array_spec();
1822 strides->attr.intent = INTENT_INOUT;
1823 strides->as->type = AS_EXPLICIT;
1824 strides->as->rank = 1;
1825 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1826 strides->as->upper[0] = gfc_copy_expr (rank);
1827 gfc_set_sym_referenced (strides);
1828 gfc_commit_symbol (strides);
1831 /* Set return value to 0. */
1832 last_code = gfc_get_code (EXEC_ASSIGN);
1833 last_code->expr1 = gfc_lval_expr_from_sym (final);
1834 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1835 sub_ns->code = last_code;
1837 /* Set: is_contiguous = .true. */
1838 last_code->next = gfc_get_code (EXEC_ASSIGN);
1839 last_code = last_code->next;
1840 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1841 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1842 &gfc_current_locus, true);
1844 /* Set: sizes(0) = 1. */
1845 last_code->next = gfc_get_code (EXEC_ASSIGN);
1846 last_code = last_code->next;
1847 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1848 last_code->expr1->ref = gfc_get_ref ();
1849 last_code->expr1->ref->type = REF_ARRAY;
1850 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1851 last_code->expr1->ref->u.ar.dimen = 1;
1852 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1853 last_code->expr1->ref->u.ar.start[0]
1854 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1855 last_code->expr1->ref->u.ar.as = sizes->as;
1856 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1858 /* Create:
1859 DO idx = 1, rank
1860 strides(idx) = _F._stride (array, dim=idx)
1861 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1862 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1863 END DO. */
1865 /* Create loop. */
1866 iter = gfc_get_iterator ();
1867 iter->var = gfc_lval_expr_from_sym (idx);
1868 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1869 iter->end = gfc_copy_expr (rank);
1870 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1871 last_code->next = gfc_get_code (EXEC_DO);
1872 last_code = last_code->next;
1873 last_code->ext.iterator = iter;
1874 last_code->block = gfc_get_code (EXEC_DO);
1876 /* strides(idx) = _F._stride(array,dim=idx). */
1877 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1878 block = last_code->block->next;
1880 block->expr1 = gfc_lval_expr_from_sym (strides);
1881 block->expr1->ref = gfc_get_ref ();
1882 block->expr1->ref->type = REF_ARRAY;
1883 block->expr1->ref->u.ar.type = AR_ELEMENT;
1884 block->expr1->ref->u.ar.dimen = 1;
1885 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1886 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1887 block->expr1->ref->u.ar.as = strides->as;
1889 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1890 gfc_current_locus, 2,
1891 gfc_lval_expr_from_sym (array),
1892 gfc_lval_expr_from_sym (idx));
1894 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1895 block->next = gfc_get_code (EXEC_ASSIGN);
1896 block = block->next;
1898 /* sizes(idx) = ... */
1899 block->expr1 = gfc_lval_expr_from_sym (sizes);
1900 block->expr1->ref = gfc_get_ref ();
1901 block->expr1->ref->type = REF_ARRAY;
1902 block->expr1->ref->u.ar.type = AR_ELEMENT;
1903 block->expr1->ref->u.ar.dimen = 1;
1904 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1905 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1906 block->expr1->ref->u.ar.as = sizes->as;
1908 block->expr2 = gfc_get_expr ();
1909 block->expr2->expr_type = EXPR_OP;
1910 block->expr2->value.op.op = INTRINSIC_TIMES;
1911 block->expr2->where = gfc_current_locus;
1913 /* sizes(idx-1). */
1914 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1915 block->expr2->value.op.op1->ref = gfc_get_ref ();
1916 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1917 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1918 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1919 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1920 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1921 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1922 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1923 block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus;
1924 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1925 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1926 = gfc_lval_expr_from_sym (idx);
1927 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1928 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1929 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1930 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1932 /* size(array, dim=idx, kind=index_kind). */
1933 block->expr2->value.op.op2
1934 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1935 gfc_current_locus, 3,
1936 gfc_lval_expr_from_sym (array),
1937 gfc_lval_expr_from_sym (idx),
1938 gfc_get_int_expr (gfc_index_integer_kind,
1939 NULL,
1940 gfc_index_integer_kind));
1941 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1942 block->expr2->ts = idx->ts;
1944 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1945 block->next = gfc_get_code (EXEC_IF);
1946 block = block->next;
1948 block->block = gfc_get_code (EXEC_IF);
1949 block = block->block;
1951 /* if condition: strides(idx) /= sizes(idx-1). */
1952 block->expr1 = gfc_get_expr ();
1953 block->expr1->ts.type = BT_LOGICAL;
1954 block->expr1->ts.kind = gfc_default_logical_kind;
1955 block->expr1->expr_type = EXPR_OP;
1956 block->expr1->where = gfc_current_locus;
1957 block->expr1->value.op.op = INTRINSIC_NE;
1959 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1960 block->expr1->value.op.op1->ref = gfc_get_ref ();
1961 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1962 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1963 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1964 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1965 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1966 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1968 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1969 block->expr1->value.op.op2->ref = gfc_get_ref ();
1970 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1971 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1972 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1973 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1974 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1975 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1976 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1977 block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1978 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1979 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1980 = gfc_lval_expr_from_sym (idx);
1981 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1982 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1983 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1984 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1986 /* if body: is_contiguous = .false. */
1987 block->next = gfc_get_code (EXEC_ASSIGN);
1988 block = block->next;
1989 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1990 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1991 &gfc_current_locus, false);
1993 /* Obtain the size (number of elements) of "array" MINUS ONE,
1994 which is used in the scalarization. */
1995 gfc_get_symbol ("nelem", sub_ns, &nelem);
1996 nelem->ts.type = BT_INTEGER;
1997 nelem->ts.kind = gfc_index_integer_kind;
1998 nelem->attr.flavor = FL_VARIABLE;
1999 nelem->attr.artificial = 1;
2000 gfc_set_sym_referenced (nelem);
2001 gfc_commit_symbol (nelem);
2003 /* nelem = sizes (rank) - 1. */
2004 last_code->next = gfc_get_code (EXEC_ASSIGN);
2005 last_code = last_code->next;
2007 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
2009 last_code->expr2 = gfc_get_expr ();
2010 last_code->expr2->expr_type = EXPR_OP;
2011 last_code->expr2->value.op.op = INTRINSIC_MINUS;
2012 last_code->expr2->value.op.op2
2013 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2014 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
2015 last_code->expr2->where = gfc_current_locus;
2017 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
2018 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
2019 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
2020 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
2021 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
2022 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2023 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
2024 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
2026 /* Call final subroutines. We now generate code like:
2027 use iso_c_binding
2028 integer, pointer :: ptr
2029 type(c_ptr) :: cptr
2030 integer(c_intptr_t) :: i, addr
2032 select case (rank (array))
2033 case (3)
2034 ! If needed, the array is packed
2035 call final_rank3 (array)
2036 case default:
2037 do i = 0, size (array)-1
2038 addr = transfer (c_loc (array), addr) + i * stride
2039 call c_f_pointer (transfer (addr, cptr), ptr)
2040 call elemental_final (ptr)
2041 end do
2042 end select */
2044 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2046 gfc_finalizer *fini, *fini_elem = NULL;
2048 gfc_get_symbol ("ptr1", sub_ns, &ptr);
2049 ptr->ts.type = BT_DERIVED;
2050 ptr->ts.u.derived = derived;
2051 ptr->attr.flavor = FL_VARIABLE;
2052 ptr->attr.pointer = 1;
2053 ptr->attr.artificial = 1;
2054 gfc_set_sym_referenced (ptr);
2055 gfc_commit_symbol (ptr);
2057 /* SELECT CASE (RANK (array)). */
2058 last_code->next = gfc_get_code (EXEC_SELECT);
2059 last_code = last_code->next;
2060 last_code->expr1 = gfc_copy_expr (rank);
2061 block = NULL;
2063 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
2065 gcc_assert (fini->proc_tree); /* Should have been set in gfc_resolve_finalizers. */
2066 if (fini->proc_tree->n.sym->attr.elemental)
2068 fini_elem = fini;
2069 continue;
2072 /* CASE (fini_rank). */
2073 if (block)
2075 block->block = gfc_get_code (EXEC_SELECT);
2076 block = block->block;
2078 else
2080 block = gfc_get_code (EXEC_SELECT);
2081 last_code->block = block;
2083 block->ext.block.case_list = gfc_get_case ();
2084 block->ext.block.case_list->where = gfc_current_locus;
2085 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2086 block->ext.block.case_list->low
2087 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2088 fini->proc_tree->n.sym->formal->sym->as->rank);
2089 else
2090 block->ext.block.case_list->low
2091 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2092 block->ext.block.case_list->high
2093 = gfc_copy_expr (block->ext.block.case_list->low);
2095 /* CALL fini_rank (array) - possibly with packing. */
2096 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2097 finalizer_insert_packed_call (block, fini, array, byte_stride,
2098 idx, ptr, nelem, strides,
2099 sizes, idx2, offset, is_contiguous,
2100 rank, sub_ns);
2101 else
2103 block->next = gfc_get_code (EXEC_CALL);
2104 block->next->symtree = fini->proc_tree;
2105 block->next->resolved_sym = fini->proc_tree->n.sym;
2106 block->next->ext.actual = gfc_get_actual_arglist ();
2107 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
2111 /* Elemental call - scalarized. */
2112 if (fini_elem)
2114 /* CASE DEFAULT. */
2115 if (block)
2117 block->block = gfc_get_code (EXEC_SELECT);
2118 block = block->block;
2120 else
2122 block = gfc_get_code (EXEC_SELECT);
2123 last_code->block = block;
2125 block->ext.block.case_list = gfc_get_case ();
2127 /* Create loop. */
2128 iter = gfc_get_iterator ();
2129 iter->var = gfc_lval_expr_from_sym (idx);
2130 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2131 iter->end = gfc_lval_expr_from_sym (nelem);
2132 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2133 block->next = gfc_get_code (EXEC_DO);
2134 block = block->next;
2135 block->ext.iterator = iter;
2136 block->block = gfc_get_code (EXEC_DO);
2138 /* Offset calculation. */
2139 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2140 byte_stride, rank, block->block,
2141 sub_ns);
2143 /* Create code for
2144 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2145 + offset, c_ptr), ptr). */
2146 block->next
2147 = finalization_scalarizer (array, ptr,
2148 gfc_lval_expr_from_sym (offset),
2149 sub_ns);
2150 block = block->next;
2152 /* CALL final_elemental (array). */
2153 block->next = gfc_get_code (EXEC_CALL);
2154 block = block->next;
2155 block->symtree = fini_elem->proc_tree;
2156 block->resolved_sym = fini_elem->proc_sym;
2157 block->ext.actual = gfc_get_actual_arglist ();
2158 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
2162 /* Finalize and deallocate allocatable components. The same manual
2163 scalarization is used as above. */
2165 if (finalizable_comp)
2167 gfc_symbol *stat;
2168 gfc_code *block = NULL;
2170 if (!ptr)
2172 gfc_get_symbol ("ptr2", sub_ns, &ptr);
2173 ptr->ts.type = BT_DERIVED;
2174 ptr->ts.u.derived = derived;
2175 ptr->attr.flavor = FL_VARIABLE;
2176 ptr->attr.pointer = 1;
2177 ptr->attr.artificial = 1;
2178 gfc_set_sym_referenced (ptr);
2179 gfc_commit_symbol (ptr);
2182 gfc_get_symbol ("ignore", sub_ns, &stat);
2183 stat->attr.flavor = FL_VARIABLE;
2184 stat->attr.artificial = 1;
2185 stat->ts.type = BT_INTEGER;
2186 stat->ts.kind = gfc_default_integer_kind;
2187 gfc_set_sym_referenced (stat);
2188 gfc_commit_symbol (stat);
2190 /* Create loop. */
2191 iter = gfc_get_iterator ();
2192 iter->var = gfc_lval_expr_from_sym (idx);
2193 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2194 iter->end = gfc_lval_expr_from_sym (nelem);
2195 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2196 last_code->next = gfc_get_code (EXEC_DO);
2197 last_code = last_code->next;
2198 last_code->ext.iterator = iter;
2199 last_code->block = gfc_get_code (EXEC_DO);
2201 /* Offset calculation. */
2202 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2203 byte_stride, rank, last_code->block,
2204 sub_ns);
2206 /* Create code for
2207 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2208 + idx * stride, c_ptr), ptr). */
2209 block->next = finalization_scalarizer (array, ptr,
2210 gfc_lval_expr_from_sym(offset),
2211 sub_ns);
2212 block = block->next;
2214 for (comp = derived->components; comp; comp = comp->next)
2216 if (comp == derived->components && derived->attr.extension
2217 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2218 continue;
2220 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2221 stat, fini_coarray, &block, sub_ns);
2222 if (!last_code->block->next)
2223 last_code->block->next = block;
2228 /* Call the finalizer of the ancestor. */
2229 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2231 last_code->next = gfc_get_code (EXEC_CALL);
2232 last_code = last_code->next;
2233 last_code->symtree = ancestor_wrapper->symtree;
2234 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2236 last_code->ext.actual = gfc_get_actual_arglist ();
2237 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2238 last_code->ext.actual->next = gfc_get_actual_arglist ();
2239 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2240 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2241 last_code->ext.actual->next->next->expr
2242 = gfc_lval_expr_from_sym (fini_coarray);
2245 gfc_free_expr (rank);
2246 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2247 vtab_final->ts.interface = final;
2248 free (name);
2252 /* Add procedure pointers for all type-bound procedures to a vtab. */
2254 static void
2255 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2257 gfc_symbol* super_type;
2259 super_type = gfc_get_derived_super_type (derived);
2261 if (super_type && (super_type != derived))
2263 /* Make sure that the PPCs appear in the same order as in the parent. */
2264 copy_vtab_proc_comps (super_type, vtype);
2265 /* Only needed to get the PPC initializers right. */
2266 add_procs_to_declared_vtab (super_type, vtype);
2269 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2270 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2272 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2273 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2277 /* Find or generate the symbol for a derived type's vtab. */
2279 gfc_symbol *
2280 gfc_find_derived_vtab (gfc_symbol *derived)
2282 gfc_namespace *ns;
2283 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2284 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2285 gfc_gsymbol *gsym = NULL;
2286 gfc_symbol *dealloc = NULL, *arg = NULL;
2288 if (derived->attr.pdt_template)
2289 return NULL;
2291 /* Find the top-level namespace. */
2292 for (ns = gfc_current_ns; ns; ns = ns->parent)
2293 if (!ns->parent)
2294 break;
2296 /* If the type is a class container, use the underlying derived type. */
2297 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2298 derived = gfc_get_derived_super_type (derived);
2300 if (!derived)
2301 return NULL;
2303 if (!derived->name)
2304 return NULL;
2306 /* Find the gsymbol for the module of use associated derived types. */
2307 if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
2308 && !derived->attr.vtype && !derived->attr.is_class)
2309 gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module);
2310 else
2311 gsym = NULL;
2313 /* Work in the gsymbol namespace if the top-level namespace is a module.
2314 This ensures that the vtable is unique, which is required since we use
2315 its address in SELECT TYPE. */
2316 if (gsym && gsym->ns && ns && ns->proc_name
2317 && ns->proc_name->attr.flavor == FL_MODULE)
2318 ns = gsym->ns;
2320 if (ns)
2322 char tname[GFC_MAX_SYMBOL_LEN+1];
2323 char *name;
2325 get_unique_hashed_string (tname, derived);
2326 name = xasprintf ("__vtab_%s", tname);
2328 /* Look for the vtab symbol in various namespaces. */
2329 if (gsym && gsym->ns)
2331 gfc_find_symbol (name, gsym->ns, 0, &vtab);
2332 if (vtab)
2333 ns = gsym->ns;
2335 if (vtab == NULL)
2336 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2337 if (vtab == NULL)
2338 gfc_find_symbol (name, ns, 0, &vtab);
2339 if (vtab == NULL)
2340 gfc_find_symbol (name, derived->ns, 0, &vtab);
2342 if (vtab == NULL)
2344 gfc_get_symbol (name, ns, &vtab);
2345 vtab->ts.type = BT_DERIVED;
2346 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2347 &gfc_current_locus))
2348 goto cleanup;
2349 vtab->attr.target = 1;
2350 vtab->attr.save = SAVE_IMPLICIT;
2351 vtab->attr.vtab = 1;
2352 vtab->attr.access = ACCESS_PUBLIC;
2353 gfc_set_sym_referenced (vtab);
2354 name = xasprintf ("__vtype_%s", tname);
2356 gfc_find_symbol (name, ns, 0, &vtype);
2357 if (vtype == NULL)
2359 gfc_component *c;
2360 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2361 bool rdt = false;
2363 /* Is this a derived type with recursive allocatable
2364 components? */
2365 c = (derived->attr.unlimited_polymorphic
2366 || derived->attr.abstract) ?
2367 NULL : derived->components;
2368 for (; c; c= c->next)
2369 if (c->ts.type == BT_DERIVED
2370 && c->ts.u.derived == derived)
2372 rdt = true;
2373 break;
2376 gfc_get_symbol (name, ns, &vtype);
2377 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2378 &gfc_current_locus))
2379 goto cleanup;
2380 vtype->attr.access = ACCESS_PUBLIC;
2381 vtype->attr.vtype = 1;
2382 gfc_set_sym_referenced (vtype);
2384 /* Add component '_hash'. */
2385 if (!gfc_add_component (vtype, "_hash", &c))
2386 goto cleanup;
2387 c->ts.type = BT_INTEGER;
2388 c->ts.kind = 4;
2389 c->attr.access = ACCESS_PRIVATE;
2390 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2391 NULL, derived->hash_value);
2393 /* Add component '_size'. */
2394 if (!gfc_add_component (vtype, "_size", &c))
2395 goto cleanup;
2396 c->ts.type = BT_INTEGER;
2397 c->ts.kind = gfc_size_kind;
2398 c->attr.access = ACCESS_PRIVATE;
2399 /* Remember the derived type in ts.u.derived,
2400 so that the correct initializer can be set later on
2401 (in gfc_conv_structure). */
2402 c->ts.u.derived = derived;
2403 c->initializer = gfc_get_int_expr (gfc_size_kind,
2404 NULL, 0);
2406 /* Add component _extends. */
2407 if (!gfc_add_component (vtype, "_extends", &c))
2408 goto cleanup;
2409 c->attr.pointer = 1;
2410 c->attr.access = ACCESS_PRIVATE;
2411 if (!derived->attr.unlimited_polymorphic)
2412 parent = gfc_get_derived_super_type (derived);
2413 else
2414 parent = NULL;
2416 if (parent)
2418 parent_vtab = gfc_find_derived_vtab (parent);
2419 c->ts.type = BT_DERIVED;
2420 c->ts.u.derived = parent_vtab->ts.u.derived;
2421 c->initializer = gfc_get_expr ();
2422 c->initializer->expr_type = EXPR_VARIABLE;
2423 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2424 0, &c->initializer->symtree);
2426 else
2428 c->ts.type = BT_DERIVED;
2429 c->ts.u.derived = vtype;
2430 c->initializer = gfc_get_null_expr (NULL);
2433 if (!derived->attr.unlimited_polymorphic
2434 && derived->components == NULL
2435 && !derived->attr.zero_comp)
2437 /* At this point an error must have occurred.
2438 Prevent further errors on the vtype components. */
2439 found_sym = vtab;
2440 goto have_vtype;
2443 /* Add component _def_init. */
2444 if (!gfc_add_component (vtype, "_def_init", &c))
2445 goto cleanup;
2446 c->attr.pointer = 1;
2447 c->attr.artificial = 1;
2448 c->attr.access = ACCESS_PRIVATE;
2449 c->ts.type = BT_DERIVED;
2450 c->ts.u.derived = derived;
2451 if (derived->attr.unlimited_polymorphic
2452 || derived->attr.abstract)
2453 c->initializer = gfc_get_null_expr (NULL);
2454 else
2456 /* Construct default initialization variable. */
2457 name = xasprintf ("__def_init_%s", tname);
2458 gfc_get_symbol (name, ns, &def_init);
2459 def_init->attr.target = 1;
2460 def_init->attr.artificial = 1;
2461 def_init->attr.save = SAVE_IMPLICIT;
2462 def_init->attr.access = ACCESS_PUBLIC;
2463 def_init->attr.flavor = FL_VARIABLE;
2464 gfc_set_sym_referenced (def_init);
2465 def_init->ts.type = BT_DERIVED;
2466 def_init->ts.u.derived = derived;
2467 def_init->value = gfc_default_initializer (&def_init->ts);
2469 c->initializer = gfc_lval_expr_from_sym (def_init);
2472 /* Add component _copy. */
2473 if (!gfc_add_component (vtype, "_copy", &c))
2474 goto cleanup;
2475 c->attr.proc_pointer = 1;
2476 c->attr.access = ACCESS_PRIVATE;
2477 c->tb = XCNEW (gfc_typebound_proc);
2478 c->tb->ppc = 1;
2479 if (derived->attr.unlimited_polymorphic
2480 || derived->attr.abstract)
2481 c->initializer = gfc_get_null_expr (NULL);
2482 else
2484 /* Set up namespace. */
2485 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2486 sub_ns->sibling = ns->contained;
2487 ns->contained = sub_ns;
2488 sub_ns->resolved = 1;
2489 /* Set up procedure symbol. */
2490 name = xasprintf ("__copy_%s", tname);
2491 gfc_get_symbol (name, sub_ns, &copy);
2492 sub_ns->proc_name = copy;
2493 copy->attr.flavor = FL_PROCEDURE;
2494 copy->attr.subroutine = 1;
2495 copy->attr.pure = 1;
2496 copy->attr.artificial = 1;
2497 copy->attr.if_source = IFSRC_DECL;
2498 /* This is elemental so that arrays are automatically
2499 treated correctly by the scalarizer. */
2500 copy->attr.elemental = 1;
2501 if (ns->proc_name->attr.flavor == FL_MODULE)
2502 copy->module = ns->proc_name->name;
2503 gfc_set_sym_referenced (copy);
2504 /* Set up formal arguments. */
2505 gfc_get_symbol ("src", sub_ns, &src);
2506 src->ts.type = BT_DERIVED;
2507 src->ts.u.derived = derived;
2508 src->attr.flavor = FL_VARIABLE;
2509 src->attr.dummy = 1;
2510 src->attr.artificial = 1;
2511 src->attr.intent = INTENT_IN;
2512 gfc_set_sym_referenced (src);
2513 copy->formal = gfc_get_formal_arglist ();
2514 copy->formal->sym = src;
2515 gfc_get_symbol ("dst", sub_ns, &dst);
2516 dst->ts.type = BT_DERIVED;
2517 dst->ts.u.derived = derived;
2518 dst->attr.flavor = FL_VARIABLE;
2519 dst->attr.dummy = 1;
2520 dst->attr.artificial = 1;
2521 dst->attr.intent = INTENT_INOUT;
2522 gfc_set_sym_referenced (dst);
2523 copy->formal->next = gfc_get_formal_arglist ();
2524 copy->formal->next->sym = dst;
2525 /* Set up code. */
2526 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2527 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2528 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2529 /* Set initializer. */
2530 c->initializer = gfc_lval_expr_from_sym (copy);
2531 c->ts.interface = copy;
2534 /* Add component _final, which contains a procedure pointer to
2535 a wrapper which handles both the freeing of allocatable
2536 components and the calls to finalization subroutines.
2537 Note: The actual wrapper function can only be generated
2538 at resolution time. */
2539 if (!gfc_add_component (vtype, "_final", &c))
2540 goto cleanup;
2541 c->attr.proc_pointer = 1;
2542 c->attr.access = ACCESS_PRIVATE;
2543 c->attr.artificial = 1;
2544 c->tb = XCNEW (gfc_typebound_proc);
2545 c->tb->ppc = 1;
2546 generate_finalization_wrapper (derived, ns, tname, c);
2548 /* Add component _deallocate. */
2549 if (!gfc_add_component (vtype, "_deallocate", &c))
2550 goto cleanup;
2551 c->attr.proc_pointer = 1;
2552 c->attr.access = ACCESS_PRIVATE;
2553 c->tb = XCNEW (gfc_typebound_proc);
2554 c->tb->ppc = 1;
2555 if (derived->attr.unlimited_polymorphic
2556 || derived->attr.abstract
2557 || !rdt)
2558 c->initializer = gfc_get_null_expr (NULL);
2559 else
2561 /* Set up namespace. */
2562 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2564 sub_ns->sibling = ns->contained;
2565 ns->contained = sub_ns;
2566 sub_ns->resolved = 1;
2567 /* Set up procedure symbol. */
2568 name = xasprintf ("__deallocate_%s", tname);
2569 gfc_get_symbol (name, sub_ns, &dealloc);
2570 sub_ns->proc_name = dealloc;
2571 dealloc->attr.flavor = FL_PROCEDURE;
2572 dealloc->attr.subroutine = 1;
2573 dealloc->attr.pure = 1;
2574 dealloc->attr.artificial = 1;
2575 dealloc->attr.if_source = IFSRC_DECL;
2577 if (ns->proc_name->attr.flavor == FL_MODULE)
2578 dealloc->module = ns->proc_name->name;
2579 gfc_set_sym_referenced (dealloc);
2580 /* Set up formal argument. */
2581 gfc_get_symbol ("arg", sub_ns, &arg);
2582 arg->ts.type = BT_DERIVED;
2583 arg->ts.u.derived = derived;
2584 arg->attr.flavor = FL_VARIABLE;
2585 arg->attr.dummy = 1;
2586 arg->attr.artificial = 1;
2587 arg->attr.intent = INTENT_INOUT;
2588 arg->attr.dimension = 1;
2589 arg->attr.allocatable = 1;
2590 arg->as = gfc_get_array_spec();
2591 arg->as->type = AS_ASSUMED_SHAPE;
2592 arg->as->rank = 1;
2593 arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
2594 NULL, 1);
2595 gfc_set_sym_referenced (arg);
2596 dealloc->formal = gfc_get_formal_arglist ();
2597 dealloc->formal->sym = arg;
2598 /* Set up code. */
2599 sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
2600 sub_ns->code->ext.alloc.list = gfc_get_alloc ();
2601 sub_ns->code->ext.alloc.list->expr
2602 = gfc_lval_expr_from_sym (arg);
2603 /* Set initializer. */
2604 c->initializer = gfc_lval_expr_from_sym (dealloc);
2605 c->ts.interface = dealloc;
2608 /* Add procedure pointers for type-bound procedures. */
2609 if (!derived->attr.unlimited_polymorphic)
2610 add_procs_to_declared_vtab (derived, vtype);
2613 have_vtype:
2614 vtab->ts.u.derived = vtype;
2615 vtab->value = gfc_default_initializer (&vtab->ts);
2617 free (name);
2620 found_sym = vtab;
2622 cleanup:
2623 /* It is unexpected to have some symbols added at resolution or code
2624 generation time. We commit the changes in order to keep a clean state. */
2625 if (found_sym)
2627 gfc_commit_symbol (vtab);
2628 if (vtype)
2629 gfc_commit_symbol (vtype);
2630 if (def_init)
2631 gfc_commit_symbol (def_init);
2632 if (copy)
2633 gfc_commit_symbol (copy);
2634 if (src)
2635 gfc_commit_symbol (src);
2636 if (dst)
2637 gfc_commit_symbol (dst);
2638 if (dealloc)
2639 gfc_commit_symbol (dealloc);
2640 if (arg)
2641 gfc_commit_symbol (arg);
2643 else
2644 gfc_undo_symbols ();
2646 return found_sym;
2650 /* Check if a derived type is finalizable. That is the case if it
2651 (1) has a FINAL subroutine or
2652 (2) has a nonpointer nonallocatable component of finalizable type.
2653 If it is finalizable, return an expression containing the
2654 finalization wrapper. */
2656 bool
2657 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2659 gfc_symbol *vtab;
2660 gfc_component *c;
2662 /* (1) Check for FINAL subroutines. */
2663 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2664 goto yes;
2666 /* (2) Check for components of finalizable type. */
2667 for (c = derived->components; c; c = c->next)
2668 if (c->ts.type == BT_DERIVED
2669 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2670 && gfc_is_finalizable (c->ts.u.derived, NULL))
2671 goto yes;
2673 return false;
2675 yes:
2676 /* Make sure vtab is generated. */
2677 vtab = gfc_find_derived_vtab (derived);
2678 if (final_expr)
2680 /* Return finalizer expression. */
2681 gfc_component *final;
2682 final = vtab->ts.u.derived->components->next->next->next->next->next;
2683 gcc_assert (strcmp (final->name, "_final") == 0);
2684 gcc_assert (final->initializer
2685 && final->initializer->expr_type != EXPR_NULL);
2686 *final_expr = final->initializer;
2688 return true;
2692 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2693 needed to support unlimited polymorphism. */
2695 static gfc_symbol *
2696 find_intrinsic_vtab (gfc_typespec *ts)
2698 gfc_namespace *ns;
2699 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2700 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2702 /* Find the top-level namespace. */
2703 for (ns = gfc_current_ns; ns; ns = ns->parent)
2704 if (!ns->parent)
2705 break;
2707 if (ns)
2709 char tname[GFC_MAX_SYMBOL_LEN+1];
2710 char *name;
2712 /* Encode all types as TYPENAME_KIND_ including especially character
2713 arrays, whose length is now consistently stored in the _len component
2714 of the class-variable. */
2715 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2716 name = xasprintf ("__vtab_%s", tname);
2718 /* Look for the vtab symbol in the top-level namespace only. */
2719 gfc_find_symbol (name, ns, 0, &vtab);
2721 if (vtab == NULL)
2723 gfc_get_symbol (name, ns, &vtab);
2724 vtab->ts.type = BT_DERIVED;
2725 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2726 &gfc_current_locus))
2727 goto cleanup;
2728 vtab->attr.target = 1;
2729 vtab->attr.save = SAVE_IMPLICIT;
2730 vtab->attr.vtab = 1;
2731 vtab->attr.access = ACCESS_PUBLIC;
2732 gfc_set_sym_referenced (vtab);
2733 name = xasprintf ("__vtype_%s", tname);
2735 gfc_find_symbol (name, ns, 0, &vtype);
2736 if (vtype == NULL)
2738 gfc_component *c;
2739 int hash;
2740 gfc_namespace *sub_ns;
2741 gfc_namespace *contained;
2742 gfc_expr *e;
2743 size_t e_size;
2745 gfc_get_symbol (name, ns, &vtype);
2746 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2747 &gfc_current_locus))
2748 goto cleanup;
2749 vtype->attr.access = ACCESS_PUBLIC;
2750 vtype->attr.vtype = 1;
2751 gfc_set_sym_referenced (vtype);
2753 /* Add component '_hash'. */
2754 if (!gfc_add_component (vtype, "_hash", &c))
2755 goto cleanup;
2756 c->ts.type = BT_INTEGER;
2757 c->ts.kind = 4;
2758 c->attr.access = ACCESS_PRIVATE;
2759 hash = gfc_intrinsic_hash_value (ts);
2760 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2761 NULL, hash);
2763 /* Add component '_size'. */
2764 if (!gfc_add_component (vtype, "_size", &c))
2765 goto cleanup;
2766 c->ts.type = BT_INTEGER;
2767 c->ts.kind = gfc_size_kind;
2768 c->attr.access = ACCESS_PRIVATE;
2770 /* Build a minimal expression to make use of
2771 target-memory.c/gfc_element_size for 'size'. Special handling
2772 for character arrays, that are not constant sized: to support
2773 len (str) * kind, only the kind information is stored in the
2774 vtab. */
2775 e = gfc_get_expr ();
2776 e->ts = *ts;
2777 e->expr_type = EXPR_VARIABLE;
2778 if (ts->type == BT_CHARACTER)
2779 e_size = ts->kind;
2780 else
2781 gfc_element_size (e, &e_size);
2782 c->initializer = gfc_get_int_expr (gfc_size_kind,
2783 NULL,
2784 e_size);
2785 gfc_free_expr (e);
2787 /* Add component _extends. */
2788 if (!gfc_add_component (vtype, "_extends", &c))
2789 goto cleanup;
2790 c->attr.pointer = 1;
2791 c->attr.access = ACCESS_PRIVATE;
2792 c->ts.type = BT_VOID;
2793 c->initializer = gfc_get_null_expr (NULL);
2795 /* Add component _def_init. */
2796 if (!gfc_add_component (vtype, "_def_init", &c))
2797 goto cleanup;
2798 c->attr.pointer = 1;
2799 c->attr.access = ACCESS_PRIVATE;
2800 c->ts.type = BT_VOID;
2801 c->initializer = gfc_get_null_expr (NULL);
2803 /* Add component _copy. */
2804 if (!gfc_add_component (vtype, "_copy", &c))
2805 goto cleanup;
2806 c->attr.proc_pointer = 1;
2807 c->attr.access = ACCESS_PRIVATE;
2808 c->tb = XCNEW (gfc_typebound_proc);
2809 c->tb->ppc = 1;
2811 if (ts->type != BT_CHARACTER)
2812 name = xasprintf ("__copy_%s", tname);
2813 else
2815 /* __copy is always the same for characters.
2816 Check to see if copy function already exists. */
2817 name = xasprintf ("__copy_character_%d", ts->kind);
2818 contained = ns->contained;
2819 for (; contained; contained = contained->sibling)
2820 if (contained->proc_name
2821 && strcmp (name, contained->proc_name->name) == 0)
2823 copy = contained->proc_name;
2824 goto got_char_copy;
2828 /* Set up namespace. */
2829 sub_ns = gfc_get_namespace (ns, 0);
2830 sub_ns->sibling = ns->contained;
2831 ns->contained = sub_ns;
2832 sub_ns->resolved = 1;
2833 /* Set up procedure symbol. */
2834 gfc_get_symbol (name, sub_ns, &copy);
2835 sub_ns->proc_name = copy;
2836 copy->attr.flavor = FL_PROCEDURE;
2837 copy->attr.subroutine = 1;
2838 copy->attr.pure = 1;
2839 copy->attr.if_source = IFSRC_DECL;
2840 /* This is elemental so that arrays are automatically
2841 treated correctly by the scalarizer. */
2842 copy->attr.elemental = 1;
2843 if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
2844 copy->module = ns->proc_name->name;
2845 gfc_set_sym_referenced (copy);
2846 /* Set up formal arguments. */
2847 gfc_get_symbol ("src", sub_ns, &src);
2848 src->ts.type = ts->type;
2849 src->ts.kind = ts->kind;
2850 src->attr.flavor = FL_VARIABLE;
2851 src->attr.dummy = 1;
2852 src->attr.intent = INTENT_IN;
2853 gfc_set_sym_referenced (src);
2854 copy->formal = gfc_get_formal_arglist ();
2855 copy->formal->sym = src;
2856 gfc_get_symbol ("dst", sub_ns, &dst);
2857 dst->ts.type = ts->type;
2858 dst->ts.kind = ts->kind;
2859 dst->attr.flavor = FL_VARIABLE;
2860 dst->attr.dummy = 1;
2861 dst->attr.intent = INTENT_INOUT;
2862 gfc_set_sym_referenced (dst);
2863 copy->formal->next = gfc_get_formal_arglist ();
2864 copy->formal->next->sym = dst;
2865 /* Set up code. */
2866 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2867 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2868 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2869 got_char_copy:
2870 /* Set initializer. */
2871 c->initializer = gfc_lval_expr_from_sym (copy);
2872 c->ts.interface = copy;
2874 /* Add component _final. */
2875 if (!gfc_add_component (vtype, "_final", &c))
2876 goto cleanup;
2877 c->attr.proc_pointer = 1;
2878 c->attr.access = ACCESS_PRIVATE;
2879 c->attr.artificial = 1;
2880 c->tb = XCNEW (gfc_typebound_proc);
2881 c->tb->ppc = 1;
2882 c->initializer = gfc_get_null_expr (NULL);
2884 vtab->ts.u.derived = vtype;
2885 vtab->value = gfc_default_initializer (&vtab->ts);
2887 free (name);
2890 found_sym = vtab;
2892 cleanup:
2893 /* It is unexpected to have some symbols added at resolution or code
2894 generation time. We commit the changes in order to keep a clean state. */
2895 if (found_sym)
2897 gfc_commit_symbol (vtab);
2898 if (vtype)
2899 gfc_commit_symbol (vtype);
2900 if (copy)
2901 gfc_commit_symbol (copy);
2902 if (src)
2903 gfc_commit_symbol (src);
2904 if (dst)
2905 gfc_commit_symbol (dst);
2907 else
2908 gfc_undo_symbols ();
2910 return found_sym;
2914 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
2916 gfc_symbol *
2917 gfc_find_vtab (gfc_typespec *ts)
2919 switch (ts->type)
2921 case BT_UNKNOWN:
2922 return NULL;
2923 case BT_DERIVED:
2924 return gfc_find_derived_vtab (ts->u.derived);
2925 case BT_CLASS:
2926 if (ts->u.derived->attr.is_class
2927 && ts->u.derived->components
2928 && ts->u.derived->components->ts.u.derived)
2929 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
2930 else
2931 return NULL;
2932 default:
2933 return find_intrinsic_vtab (ts);
2938 /* General worker function to find either a type-bound procedure or a
2939 type-bound user operator. */
2941 static gfc_symtree*
2942 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2943 const char* name, bool noaccess, bool uop,
2944 locus* where)
2946 gfc_symtree* res;
2947 gfc_symtree* root;
2949 /* Set default to failure. */
2950 if (t)
2951 *t = false;
2953 if (derived->f2k_derived)
2954 /* Set correct symbol-root. */
2955 root = (uop ? derived->f2k_derived->tb_uop_root
2956 : derived->f2k_derived->tb_sym_root);
2957 else
2958 return NULL;
2960 /* Try to find it in the current type's namespace. */
2961 res = gfc_find_symtree (root, name);
2962 if (res && res->n.tb && !res->n.tb->error)
2964 /* We found one. */
2965 if (t)
2966 *t = true;
2968 if (!noaccess && derived->attr.use_assoc
2969 && res->n.tb->access == ACCESS_PRIVATE)
2971 if (where)
2972 gfc_error ("%qs of %qs is PRIVATE at %L",
2973 name, derived->name, where);
2974 if (t)
2975 *t = false;
2978 return res;
2981 /* Otherwise, recurse on parent type if derived is an extension. */
2982 if (derived->attr.extension)
2984 gfc_symbol* super_type;
2985 super_type = gfc_get_derived_super_type (derived);
2986 gcc_assert (super_type);
2988 return find_typebound_proc_uop (super_type, t, name,
2989 noaccess, uop, where);
2992 /* Nothing found. */
2993 return NULL;
2997 /* Find a type-bound procedure or user operator by name for a derived-type
2998 (looking recursively through the super-types). */
3000 gfc_symtree*
3001 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
3002 const char* name, bool noaccess, locus* where)
3004 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
3007 gfc_symtree*
3008 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
3009 const char* name, bool noaccess, locus* where)
3011 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
3015 /* Find a type-bound intrinsic operator looking recursively through the
3016 super-type hierarchy. */
3018 gfc_typebound_proc*
3019 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
3020 gfc_intrinsic_op op, bool noaccess,
3021 locus* where)
3023 gfc_typebound_proc* res;
3025 /* Set default to failure. */
3026 if (t)
3027 *t = false;
3029 /* Try to find it in the current type's namespace. */
3030 if (derived->f2k_derived)
3031 res = derived->f2k_derived->tb_op[op];
3032 else
3033 res = NULL;
3035 /* Check access. */
3036 if (res && !res->error)
3038 /* We found one. */
3039 if (t)
3040 *t = true;
3042 if (!noaccess && derived->attr.use_assoc
3043 && res->access == ACCESS_PRIVATE)
3045 if (where)
3046 gfc_error ("%qs of %qs is PRIVATE at %L",
3047 gfc_op2string (op), derived->name, where);
3048 if (t)
3049 *t = false;
3052 return res;
3055 /* Otherwise, recurse on parent type if derived is an extension. */
3056 if (derived->attr.extension)
3058 gfc_symbol* super_type;
3059 super_type = gfc_get_derived_super_type (derived);
3060 gcc_assert (super_type);
3062 return gfc_find_typebound_intrinsic_op (super_type, t, op,
3063 noaccess, where);
3066 /* Nothing found. */
3067 return NULL;
3071 /* Get a typebound-procedure symtree or create and insert it if not yet
3072 present. This is like a very simplified version of gfc_get_sym_tree for
3073 tbp-symtrees rather than regular ones. */
3075 gfc_symtree*
3076 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
3078 gfc_symtree *result = gfc_find_symtree (*root, name);
3079 return result ? result : gfc_new_symtree (root, name);