libgo: update to Go 1.15.4 release
[official-gcc.git] / gcc / fortran / class.c
blob5677d920239f97a1f988faceb22ef6e590b36d6b
1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2020 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. */
634 bool
635 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
636 gfc_array_spec **as)
638 char tname[GFC_MAX_SYMBOL_LEN+1];
639 char *name;
640 gfc_symbol *fclass;
641 gfc_symbol *vtab;
642 gfc_component *c;
643 gfc_namespace *ns;
644 int rank;
646 gcc_assert (as);
648 if (*as && (*as)->type == AS_ASSUMED_SIZE)
650 gfc_error ("Assumed size polymorphic objects or components, such "
651 "as that at %C, have not yet been implemented");
652 return false;
655 if (attr->class_ok)
656 /* Class container has already been built. */
657 return true;
659 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
660 || attr->select_type_temporary || attr->associate_var;
662 if (!attr->class_ok)
663 /* We cannot build the class container yet. */
664 return true;
666 /* Determine the name of the encapsulating type. */
667 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
669 if (!ts->u.derived)
670 return false;
672 get_unique_hashed_string (tname, ts->u.derived);
673 if ((*as) && attr->allocatable)
674 name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
675 else if ((*as) && attr->pointer)
676 name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
677 else if ((*as))
678 name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
679 else if (attr->pointer)
680 name = xasprintf ("__class_%s_p", tname);
681 else if (attr->allocatable)
682 name = xasprintf ("__class_%s_a", tname);
683 else
684 name = xasprintf ("__class_%s_t", tname);
686 if (ts->u.derived->attr.unlimited_polymorphic)
688 /* Find the top-level namespace. */
689 for (ns = gfc_current_ns; ns; ns = ns->parent)
690 if (!ns->parent)
691 break;
693 else
694 ns = ts->u.derived->ns;
696 gfc_find_symbol (name, ns, 0, &fclass);
697 if (fclass == NULL)
699 gfc_symtree *st;
700 /* If not there, create a new symbol. */
701 fclass = gfc_new_symbol (name, ns);
702 st = gfc_new_symtree (&ns->sym_root, name);
703 st->n.sym = fclass;
704 gfc_set_sym_referenced (fclass);
705 fclass->refs++;
706 fclass->ts.type = BT_UNKNOWN;
707 if (!ts->u.derived->attr.unlimited_polymorphic)
708 fclass->attr.abstract = ts->u.derived->attr.abstract;
709 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
710 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
711 &gfc_current_locus))
712 return false;
714 /* Add component '_data'. */
715 if (!gfc_add_component (fclass, "_data", &c))
716 return false;
717 c->ts = *ts;
718 c->ts.type = BT_DERIVED;
719 c->attr.access = ACCESS_PRIVATE;
720 c->ts.u.derived = ts->u.derived;
721 c->attr.class_pointer = attr->pointer;
722 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
723 || attr->select_type_temporary;
724 c->attr.allocatable = attr->allocatable;
725 c->attr.dimension = attr->dimension;
726 c->attr.codimension = attr->codimension;
727 c->attr.abstract = fclass->attr.abstract;
728 c->as = (*as);
729 c->initializer = NULL;
731 /* Add component '_vptr'. */
732 if (!gfc_add_component (fclass, "_vptr", &c))
733 return false;
734 c->ts.type = BT_DERIVED;
735 c->attr.access = ACCESS_PRIVATE;
736 c->attr.pointer = 1;
738 if (ts->u.derived->attr.unlimited_polymorphic)
740 vtab = gfc_find_derived_vtab (ts->u.derived);
741 gcc_assert (vtab);
742 c->ts.u.derived = vtab->ts.u.derived;
744 /* Add component '_len'. Only unlimited polymorphic pointers may
745 have a string assigned to them, i.e., only those need the _len
746 component. */
747 if (!gfc_add_component (fclass, "_len", &c))
748 return false;
749 c->ts.type = BT_INTEGER;
750 c->ts.kind = gfc_charlen_int_kind;
751 c->attr.access = ACCESS_PRIVATE;
752 c->attr.artificial = 1;
754 else
755 /* Build vtab later. */
756 c->ts.u.derived = NULL;
759 if (!ts->u.derived->attr.unlimited_polymorphic)
761 /* Since the extension field is 8 bit wide, we can only have
762 up to 255 extension levels. */
763 if (ts->u.derived->attr.extension == 255)
765 gfc_error ("Maximum extension level reached with type %qs at %L",
766 ts->u.derived->name, &ts->u.derived->declared_at);
767 return false;
770 fclass->attr.extension = ts->u.derived->attr.extension + 1;
771 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
772 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
775 fclass->attr.is_class = 1;
776 ts->u.derived = fclass;
777 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
778 (*as) = NULL;
779 free (name);
780 return true;
784 /* Add a procedure pointer component to the vtype
785 to represent a specific type-bound procedure. */
787 static void
788 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
790 gfc_component *c;
792 if (tb->non_overridable && !tb->overridden)
793 return;
795 c = gfc_find_component (vtype, name, true, true, NULL);
797 if (c == NULL)
799 /* Add procedure component. */
800 if (!gfc_add_component (vtype, name, &c))
801 return;
803 if (!c->tb)
804 c->tb = XCNEW (gfc_typebound_proc);
805 *c->tb = *tb;
806 c->tb->ppc = 1;
807 c->attr.procedure = 1;
808 c->attr.proc_pointer = 1;
809 c->attr.flavor = FL_PROCEDURE;
810 c->attr.access = ACCESS_PRIVATE;
811 c->attr.external = 1;
812 c->attr.untyped = 1;
813 c->attr.if_source = IFSRC_IFBODY;
815 else if (c->attr.proc_pointer && c->tb)
817 *c->tb = *tb;
818 c->tb->ppc = 1;
821 if (tb->u.specific)
823 gfc_symbol *ifc = tb->u.specific->n.sym;
824 c->ts.interface = ifc;
825 if (!tb->deferred)
826 c->initializer = gfc_get_variable_expr (tb->u.specific);
827 c->attr.pure = ifc->attr.pure;
832 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
834 static void
835 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
837 if (!st)
838 return;
840 if (st->left)
841 add_procs_to_declared_vtab1 (st->left, vtype);
843 if (st->right)
844 add_procs_to_declared_vtab1 (st->right, vtype);
846 if (st->n.tb && !st->n.tb->error
847 && !st->n.tb->is_generic && st->n.tb->u.specific)
848 add_proc_comp (vtype, st->name, st->n.tb);
852 /* Copy procedure pointers components from the parent type. */
854 static void
855 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
857 gfc_component *cmp;
858 gfc_symbol *vtab;
860 vtab = gfc_find_derived_vtab (declared);
862 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
864 if (gfc_find_component (vtype, cmp->name, true, true, NULL))
865 continue;
867 add_proc_comp (vtype, cmp->name, cmp->tb);
872 /* Returns true if any of its nonpointer nonallocatable components or
873 their nonpointer nonallocatable subcomponents has a finalization
874 subroutine. */
876 static bool
877 has_finalizer_component (gfc_symbol *derived)
879 gfc_component *c;
881 for (c = derived->components; c; c = c->next)
882 if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable)
884 if (c->ts.u.derived->f2k_derived
885 && c->ts.u.derived->f2k_derived->finalizers)
886 return true;
888 /* Stop infinite recursion through this function by inhibiting
889 calls when the derived type and that of the component are
890 the same. */
891 if (!gfc_compare_derived_types (derived, c->ts.u.derived)
892 && has_finalizer_component (c->ts.u.derived))
893 return true;
895 return false;
899 static bool
900 comp_is_finalizable (gfc_component *comp)
902 if (comp->attr.proc_pointer)
903 return false;
904 else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
905 return true;
906 else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
907 && (comp->ts.u.derived->attr.alloc_comp
908 || has_finalizer_component (comp->ts.u.derived)
909 || (comp->ts.u.derived->f2k_derived
910 && comp->ts.u.derived->f2k_derived->finalizers)))
911 return true;
912 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
913 && CLASS_DATA (comp)->attr.allocatable)
914 return true;
915 else
916 return false;
920 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
921 neither allocatable nor a pointer but has a finalizer, call it. If it
922 is a nonpointer component with allocatable components or has finalizers, walk
923 them. Either of them is required; other nonallocatables and pointers aren't
924 handled gracefully.
925 Note: If the component is allocatable, the DEALLOCATE handling takes care
926 of calling the appropriate finalizers, coarray deregistering, and
927 deallocation of allocatable subcomponents. */
929 static void
930 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
931 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
932 gfc_namespace *sub_ns)
934 gfc_expr *e;
935 gfc_ref *ref;
936 gfc_was_finalized *f;
938 if (!comp_is_finalizable (comp))
939 return;
941 /* If this expression with this component has been finalized
942 already in this namespace, there is nothing to do. */
943 for (f = sub_ns->was_finalized; f; f = f->next)
945 if (f->e == expr && f->c == comp)
946 return;
949 e = gfc_copy_expr (expr);
950 if (!e->ref)
951 e->ref = ref = gfc_get_ref ();
952 else
954 for (ref = e->ref; ref->next; ref = ref->next)
956 ref->next = gfc_get_ref ();
957 ref = ref->next;
959 ref->type = REF_COMPONENT;
960 ref->u.c.sym = derived;
961 ref->u.c.component = comp;
962 e->ts = comp->ts;
964 if (comp->attr.dimension || comp->attr.codimension
965 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
966 && (CLASS_DATA (comp)->attr.dimension
967 || CLASS_DATA (comp)->attr.codimension)))
969 ref->next = gfc_get_ref ();
970 ref->next->type = REF_ARRAY;
971 ref->next->u.ar.dimen = 0;
972 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
973 : comp->as;
974 e->rank = ref->next->u.ar.as->rank;
975 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
978 /* Call DEALLOCATE (comp, stat=ignore). */
979 if (comp->attr.allocatable
980 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
981 && CLASS_DATA (comp)->attr.allocatable))
983 gfc_code *dealloc, *block = NULL;
985 /* Add IF (fini_coarray). */
986 if (comp->attr.codimension
987 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
988 && CLASS_DATA (comp)->attr.codimension))
990 block = gfc_get_code (EXEC_IF);
991 if (*code)
993 (*code)->next = block;
994 (*code) = (*code)->next;
996 else
997 (*code) = block;
999 block->block = gfc_get_code (EXEC_IF);
1000 block = block->block;
1001 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
1004 dealloc = gfc_get_code (EXEC_DEALLOCATE);
1006 dealloc->ext.alloc.list = gfc_get_alloc ();
1007 dealloc->ext.alloc.list->expr = e;
1008 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
1010 gfc_code *cond = gfc_get_code (EXEC_IF);
1011 cond->block = gfc_get_code (EXEC_IF);
1012 cond->block->expr1 = gfc_get_expr ();
1013 cond->block->expr1->expr_type = EXPR_FUNCTION;
1014 cond->block->expr1->where = gfc_current_locus;
1015 gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
1016 cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1017 cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
1018 cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
1019 gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
1020 cond->block->expr1->ts.type = BT_LOGICAL;
1021 cond->block->expr1->ts.kind = gfc_default_logical_kind;
1022 cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
1023 cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
1024 cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
1025 cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
1026 cond->block->next = dealloc;
1028 if (block)
1029 block->next = cond;
1030 else if (*code)
1032 (*code)->next = cond;
1033 (*code) = (*code)->next;
1035 else
1036 (*code) = cond;
1039 else if (comp->ts.type == BT_DERIVED
1040 && comp->ts.u.derived->f2k_derived
1041 && comp->ts.u.derived->f2k_derived->finalizers)
1043 /* Call FINAL_WRAPPER (comp); */
1044 gfc_code *final_wrap;
1045 gfc_symbol *vtab;
1046 gfc_component *c;
1048 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
1049 for (c = vtab->ts.u.derived->components; c; c = c->next)
1050 if (strcmp (c->name, "_final") == 0)
1051 break;
1053 gcc_assert (c);
1054 final_wrap = gfc_get_code (EXEC_CALL);
1055 final_wrap->symtree = c->initializer->symtree;
1056 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
1057 final_wrap->ext.actual = gfc_get_actual_arglist ();
1058 final_wrap->ext.actual->expr = e;
1060 if (*code)
1062 (*code)->next = final_wrap;
1063 (*code) = (*code)->next;
1065 else
1066 (*code) = final_wrap;
1068 else
1070 gfc_component *c;
1072 for (c = comp->ts.u.derived->components; c; c = c->next)
1073 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code,
1074 sub_ns);
1075 gfc_free_expr (e);
1078 /* Record that this was finalized already in this namespace. */
1079 f = sub_ns->was_finalized;
1080 sub_ns->was_finalized = XCNEW (gfc_was_finalized);
1081 sub_ns->was_finalized->e = expr;
1082 sub_ns->was_finalized->c = comp;
1083 sub_ns->was_finalized->next = f;
1087 /* Generate code equivalent to
1088 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1089 + offset, c_ptr), ptr). */
1091 static gfc_code *
1092 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
1093 gfc_expr *offset, gfc_namespace *sub_ns)
1095 gfc_code *block;
1096 gfc_expr *expr, *expr2;
1098 /* C_F_POINTER(). */
1099 block = gfc_get_code (EXEC_CALL);
1100 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
1101 block->resolved_sym = block->symtree->n.sym;
1102 block->resolved_sym->attr.flavor = FL_PROCEDURE;
1103 block->resolved_sym->attr.intrinsic = 1;
1104 block->resolved_sym->attr.subroutine = 1;
1105 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
1106 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
1107 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
1108 gfc_commit_symbol (block->resolved_sym);
1110 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
1111 block->ext.actual = gfc_get_actual_arglist ();
1112 block->ext.actual->next = gfc_get_actual_arglist ();
1113 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
1114 NULL, 0);
1115 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
1117 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
1119 /* TRANSFER's first argument: C_LOC (array). */
1120 expr = gfc_get_expr ();
1121 expr->expr_type = EXPR_FUNCTION;
1122 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
1123 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1124 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
1125 expr->symtree->n.sym->attr.intrinsic = 1;
1126 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
1127 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
1128 expr->value.function.actual = gfc_get_actual_arglist ();
1129 expr->value.function.actual->expr
1130 = gfc_lval_expr_from_sym (array);
1131 expr->symtree->n.sym->result = expr->symtree->n.sym;
1132 gfc_commit_symbol (expr->symtree->n.sym);
1133 expr->ts.type = BT_INTEGER;
1134 expr->ts.kind = gfc_index_integer_kind;
1135 expr->where = gfc_current_locus;
1137 /* TRANSFER. */
1138 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
1139 gfc_current_locus, 3, expr,
1140 gfc_get_int_expr (gfc_index_integer_kind,
1141 NULL, 0), NULL);
1142 expr2->ts.type = BT_INTEGER;
1143 expr2->ts.kind = gfc_index_integer_kind;
1145 /* <array addr> + <offset>. */
1146 block->ext.actual->expr = gfc_get_expr ();
1147 block->ext.actual->expr->expr_type = EXPR_OP;
1148 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
1149 block->ext.actual->expr->value.op.op1 = expr2;
1150 block->ext.actual->expr->value.op.op2 = offset;
1151 block->ext.actual->expr->ts = expr->ts;
1152 block->ext.actual->expr->where = gfc_current_locus;
1154 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1155 block->ext.actual->next = gfc_get_actual_arglist ();
1156 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1157 block->ext.actual->next->next = gfc_get_actual_arglist ();
1159 return block;
1163 /* Calculates the offset to the (idx+1)th element of an array, taking the
1164 stride into account. It generates the code:
1165 offset = 0
1166 do idx2 = 1, rank
1167 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1168 end do
1169 offset = offset * byte_stride. */
1171 static gfc_code*
1172 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1173 gfc_symbol *strides, gfc_symbol *sizes,
1174 gfc_symbol *byte_stride, gfc_expr *rank,
1175 gfc_code *block, gfc_namespace *sub_ns)
1177 gfc_iterator *iter;
1178 gfc_expr *expr, *expr2;
1180 /* offset = 0. */
1181 block->next = gfc_get_code (EXEC_ASSIGN);
1182 block = block->next;
1183 block->expr1 = gfc_lval_expr_from_sym (offset);
1184 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1186 /* Create loop. */
1187 iter = gfc_get_iterator ();
1188 iter->var = gfc_lval_expr_from_sym (idx2);
1189 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1190 iter->end = gfc_copy_expr (rank);
1191 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1192 block->next = gfc_get_code (EXEC_DO);
1193 block = block->next;
1194 block->ext.iterator = iter;
1195 block->block = gfc_get_code (EXEC_DO);
1197 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1198 * strides(idx2). */
1200 /* mod (idx, sizes(idx2)). */
1201 expr = gfc_lval_expr_from_sym (sizes);
1202 expr->ref = gfc_get_ref ();
1203 expr->ref->type = REF_ARRAY;
1204 expr->ref->u.ar.as = sizes->as;
1205 expr->ref->u.ar.type = AR_ELEMENT;
1206 expr->ref->u.ar.dimen = 1;
1207 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1208 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1209 expr->where = sizes->declared_at;
1211 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1212 gfc_current_locus, 2,
1213 gfc_lval_expr_from_sym (idx), expr);
1214 expr->ts = idx->ts;
1216 /* (...) / sizes(idx2-1). */
1217 expr2 = gfc_get_expr ();
1218 expr2->expr_type = EXPR_OP;
1219 expr2->value.op.op = INTRINSIC_DIVIDE;
1220 expr2->value.op.op1 = expr;
1221 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1222 expr2->value.op.op2->ref = gfc_get_ref ();
1223 expr2->value.op.op2->ref->type = REF_ARRAY;
1224 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1225 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1226 expr2->value.op.op2->ref->u.ar.dimen = 1;
1227 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1228 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1229 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1230 expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1231 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1232 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1233 = gfc_lval_expr_from_sym (idx2);
1234 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1235 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1236 expr2->value.op.op2->ref->u.ar.start[0]->ts
1237 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1238 expr2->ts = idx->ts;
1239 expr2->where = gfc_current_locus;
1241 /* ... * strides(idx2). */
1242 expr = gfc_get_expr ();
1243 expr->expr_type = EXPR_OP;
1244 expr->value.op.op = INTRINSIC_TIMES;
1245 expr->value.op.op1 = expr2;
1246 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1247 expr->value.op.op2->ref = gfc_get_ref ();
1248 expr->value.op.op2->ref->type = REF_ARRAY;
1249 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1250 expr->value.op.op2->ref->u.ar.dimen = 1;
1251 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1252 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1253 expr->value.op.op2->ref->u.ar.as = strides->as;
1254 expr->ts = idx->ts;
1255 expr->where = gfc_current_locus;
1257 /* offset = offset + ... */
1258 block->block->next = gfc_get_code (EXEC_ASSIGN);
1259 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1260 block->block->next->expr2 = gfc_get_expr ();
1261 block->block->next->expr2->expr_type = EXPR_OP;
1262 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1263 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1264 block->block->next->expr2->value.op.op2 = expr;
1265 block->block->next->expr2->ts = idx->ts;
1266 block->block->next->expr2->where = gfc_current_locus;
1268 /* After the loop: offset = offset * byte_stride. */
1269 block->next = gfc_get_code (EXEC_ASSIGN);
1270 block = block->next;
1271 block->expr1 = gfc_lval_expr_from_sym (offset);
1272 block->expr2 = gfc_get_expr ();
1273 block->expr2->expr_type = EXPR_OP;
1274 block->expr2->value.op.op = INTRINSIC_TIMES;
1275 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1276 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1277 block->expr2->ts = block->expr2->value.op.op1->ts;
1278 block->expr2->where = gfc_current_locus;
1279 return block;
1283 /* Insert code of the following form:
1285 block
1286 integer(c_intptr_t) :: i
1288 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1289 && (is_contiguous || !final_rank3->attr.contiguous
1290 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1291 || 0 == STORAGE_SIZE (array)) then
1292 call final_rank3 (array)
1293 else
1294 block
1295 integer(c_intptr_t) :: offset, j
1296 type(t) :: tmp(shape (array))
1298 do i = 0, size (array)-1
1299 offset = obtain_offset(i, strides, sizes, byte_stride)
1300 addr = transfer (c_loc (array), addr) + offset
1301 call c_f_pointer (transfer (addr, cptr), ptr)
1303 addr = transfer (c_loc (tmp), addr)
1304 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1305 call c_f_pointer (transfer (addr, cptr), ptr2)
1306 ptr2 = ptr
1307 end do
1308 call final_rank3 (tmp)
1309 end block
1310 end if
1311 block */
1313 static void
1314 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1315 gfc_symbol *array, gfc_symbol *byte_stride,
1316 gfc_symbol *idx, gfc_symbol *ptr,
1317 gfc_symbol *nelem,
1318 gfc_symbol *strides, gfc_symbol *sizes,
1319 gfc_symbol *idx2, gfc_symbol *offset,
1320 gfc_symbol *is_contiguous, gfc_expr *rank,
1321 gfc_namespace *sub_ns)
1323 gfc_symbol *tmp_array, *ptr2;
1324 gfc_expr *size_expr, *offset2, *expr;
1325 gfc_namespace *ns;
1326 gfc_iterator *iter;
1327 gfc_code *block2;
1328 int i;
1330 block->next = gfc_get_code (EXEC_IF);
1331 block = block->next;
1333 block->block = gfc_get_code (EXEC_IF);
1334 block = block->block;
1336 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1337 size_expr = gfc_get_expr ();
1338 size_expr->where = gfc_current_locus;
1339 size_expr->expr_type = EXPR_OP;
1340 size_expr->value.op.op = INTRINSIC_DIVIDE;
1342 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1343 size_expr->value.op.op1
1344 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1345 "storage_size", gfc_current_locus, 2,
1346 gfc_lval_expr_from_sym (array),
1347 gfc_get_int_expr (gfc_index_integer_kind,
1348 NULL, 0));
1350 /* NUMERIC_STORAGE_SIZE. */
1351 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1352 gfc_character_storage_size);
1353 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1354 size_expr->ts = size_expr->value.op.op1->ts;
1356 /* IF condition: (stride == size_expr
1357 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1358 || is_contiguous)
1359 || 0 == size_expr. */
1360 block->expr1 = gfc_get_expr ();
1361 block->expr1->ts.type = BT_LOGICAL;
1362 block->expr1->ts.kind = gfc_default_logical_kind;
1363 block->expr1->expr_type = EXPR_OP;
1364 block->expr1->where = gfc_current_locus;
1366 block->expr1->value.op.op = INTRINSIC_OR;
1368 /* byte_stride == size_expr */
1369 expr = gfc_get_expr ();
1370 expr->ts.type = BT_LOGICAL;
1371 expr->ts.kind = gfc_default_logical_kind;
1372 expr->expr_type = EXPR_OP;
1373 expr->where = gfc_current_locus;
1374 expr->value.op.op = INTRINSIC_EQ;
1375 expr->value.op.op1
1376 = gfc_lval_expr_from_sym (byte_stride);
1377 expr->value.op.op2 = size_expr;
1379 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1380 add is_contiguous check. */
1382 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1383 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1385 gfc_expr *expr2;
1386 expr2 = gfc_get_expr ();
1387 expr2->ts.type = BT_LOGICAL;
1388 expr2->ts.kind = gfc_default_logical_kind;
1389 expr2->expr_type = EXPR_OP;
1390 expr2->where = gfc_current_locus;
1391 expr2->value.op.op = INTRINSIC_AND;
1392 expr2->value.op.op1 = expr;
1393 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1394 expr = expr2;
1397 block->expr1->value.op.op1 = expr;
1399 /* 0 == size_expr */
1400 block->expr1->value.op.op2 = gfc_get_expr ();
1401 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1402 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1403 block->expr1->value.op.op2->expr_type = EXPR_OP;
1404 block->expr1->value.op.op2->where = gfc_current_locus;
1405 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1406 block->expr1->value.op.op2->value.op.op1 =
1407 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1408 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1410 /* IF body: call final subroutine. */
1411 block->next = gfc_get_code (EXEC_CALL);
1412 block->next->symtree = fini->proc_tree;
1413 block->next->resolved_sym = fini->proc_tree->n.sym;
1414 block->next->ext.actual = gfc_get_actual_arglist ();
1415 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1416 block->next->ext.actual->next = gfc_get_actual_arglist ();
1417 block->next->ext.actual->next->expr = gfc_copy_expr (size_expr);
1419 /* ELSE. */
1421 block->block = gfc_get_code (EXEC_IF);
1422 block = block->block;
1424 /* BLOCK ... END BLOCK. */
1425 block->next = gfc_get_code (EXEC_BLOCK);
1426 block = block->next;
1428 ns = gfc_build_block_ns (sub_ns);
1429 block->ext.block.ns = ns;
1430 block->ext.block.assoc = NULL;
1432 gfc_get_symbol ("ptr2", ns, &ptr2);
1433 ptr2->ts.type = BT_DERIVED;
1434 ptr2->ts.u.derived = array->ts.u.derived;
1435 ptr2->attr.flavor = FL_VARIABLE;
1436 ptr2->attr.pointer = 1;
1437 ptr2->attr.artificial = 1;
1438 gfc_set_sym_referenced (ptr2);
1439 gfc_commit_symbol (ptr2);
1441 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1442 tmp_array->ts.type = BT_DERIVED;
1443 tmp_array->ts.u.derived = array->ts.u.derived;
1444 tmp_array->attr.flavor = FL_VARIABLE;
1445 tmp_array->attr.dimension = 1;
1446 tmp_array->attr.artificial = 1;
1447 tmp_array->as = gfc_get_array_spec();
1448 tmp_array->attr.intent = INTENT_INOUT;
1449 tmp_array->as->type = AS_EXPLICIT;
1450 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1452 for (i = 0; i < tmp_array->as->rank; i++)
1454 gfc_expr *shape_expr;
1455 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1456 NULL, 1);
1457 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1458 shape_expr
1459 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1460 gfc_current_locus, 3,
1461 gfc_lval_expr_from_sym (array),
1462 gfc_get_int_expr (gfc_default_integer_kind,
1463 NULL, i+1),
1464 gfc_get_int_expr (gfc_default_integer_kind,
1465 NULL,
1466 gfc_index_integer_kind));
1467 shape_expr->ts.kind = gfc_index_integer_kind;
1468 tmp_array->as->upper[i] = shape_expr;
1470 gfc_set_sym_referenced (tmp_array);
1471 gfc_commit_symbol (tmp_array);
1473 /* Create loop. */
1474 iter = gfc_get_iterator ();
1475 iter->var = gfc_lval_expr_from_sym (idx);
1476 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1477 iter->end = gfc_lval_expr_from_sym (nelem);
1478 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1480 block = gfc_get_code (EXEC_DO);
1481 ns->code = block;
1482 block->ext.iterator = iter;
1483 block->block = gfc_get_code (EXEC_DO);
1485 /* Offset calculation for the new array: idx * size of type (in bytes). */
1486 offset2 = gfc_get_expr ();
1487 offset2->expr_type = EXPR_OP;
1488 offset2->where = gfc_current_locus;
1489 offset2->value.op.op = INTRINSIC_TIMES;
1490 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1491 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1492 offset2->ts = byte_stride->ts;
1494 /* Offset calculation of "array". */
1495 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1496 byte_stride, rank, block->block, sub_ns);
1498 /* Create code for
1499 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1500 + idx * stride, c_ptr), ptr). */
1501 block2->next = finalization_scalarizer (array, ptr,
1502 gfc_lval_expr_from_sym (offset),
1503 sub_ns);
1504 block2 = block2->next;
1505 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1506 block2 = block2->next;
1508 /* ptr2 = ptr. */
1509 block2->next = gfc_get_code (EXEC_ASSIGN);
1510 block2 = block2->next;
1511 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1512 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1514 /* Call now the user's final subroutine. */
1515 block->next = gfc_get_code (EXEC_CALL);
1516 block = block->next;
1517 block->symtree = fini->proc_tree;
1518 block->resolved_sym = fini->proc_tree->n.sym;
1519 block->ext.actual = gfc_get_actual_arglist ();
1520 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1522 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1523 return;
1525 /* Copy back. */
1527 /* Loop. */
1528 iter = gfc_get_iterator ();
1529 iter->var = gfc_lval_expr_from_sym (idx);
1530 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1531 iter->end = gfc_lval_expr_from_sym (nelem);
1532 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1534 block->next = gfc_get_code (EXEC_DO);
1535 block = block->next;
1536 block->ext.iterator = iter;
1537 block->block = gfc_get_code (EXEC_DO);
1539 /* Offset calculation of "array". */
1540 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1541 byte_stride, rank, block->block, sub_ns);
1543 /* Create code for
1544 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1545 + offset, c_ptr), ptr). */
1546 block2->next = finalization_scalarizer (array, ptr,
1547 gfc_lval_expr_from_sym (offset),
1548 sub_ns);
1549 block2 = block2->next;
1550 block2->next = finalization_scalarizer (tmp_array, ptr2,
1551 gfc_copy_expr (offset2), sub_ns);
1552 block2 = block2->next;
1554 /* ptr = ptr2. */
1555 block2->next = gfc_get_code (EXEC_ASSIGN);
1556 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1557 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1561 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1562 derived type "derived". The function first calls the approriate FINAL
1563 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1564 components (but not the inherited ones). Last, it calls the wrapper
1565 subroutine of the parent. The generated wrapper procedure takes as argument
1566 an assumed-rank array.
1567 If neither allocatable components nor FINAL subroutines exists, the vtab
1568 will contain a NULL pointer.
1569 The generated function has the form
1570 _final(assumed-rank array, stride, skip_corarray)
1571 where the array has to be contiguous (except of the lowest dimension). The
1572 stride (in bytes) is used to allow different sizes for ancestor types by
1573 skipping over the additionally added components in the scalarizer. If
1574 "fini_coarray" is false, coarray components are not finalized to allow for
1575 the correct semantic with intrinsic assignment. */
1577 static void
1578 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1579 const char *tname, gfc_component *vtab_final)
1581 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1582 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1583 gfc_component *comp;
1584 gfc_namespace *sub_ns;
1585 gfc_code *last_code, *block;
1586 char *name;
1587 bool finalizable_comp = false;
1588 bool expr_null_wrapper = false;
1589 gfc_expr *ancestor_wrapper = NULL, *rank;
1590 gfc_iterator *iter;
1592 if (derived->attr.unlimited_polymorphic)
1594 vtab_final->initializer = gfc_get_null_expr (NULL);
1595 return;
1598 /* Search for the ancestor's finalizers. */
1599 if (derived->attr.extension && derived->components
1600 && (!derived->components->ts.u.derived->attr.abstract
1601 || has_finalizer_component (derived)))
1603 gfc_symbol *vtab;
1604 gfc_component *comp;
1606 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1607 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1608 if (comp->name[0] == '_' && comp->name[1] == 'f')
1610 ancestor_wrapper = comp->initializer;
1611 break;
1615 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1616 components: Return a NULL() expression; we defer this a bit to have
1617 an interface declaration. */
1618 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1619 && !derived->attr.alloc_comp
1620 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1621 && !has_finalizer_component (derived))
1622 expr_null_wrapper = true;
1623 else
1624 /* Check whether there are new allocatable components. */
1625 for (comp = derived->components; comp; comp = comp->next)
1627 if (comp == derived->components && derived->attr.extension
1628 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1629 continue;
1631 finalizable_comp |= comp_is_finalizable (comp);
1634 /* If there is no new finalizer and no new allocatable, return with
1635 an expr to the ancestor's one. */
1636 if (!expr_null_wrapper && !finalizable_comp
1637 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1639 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1640 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1641 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1642 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1643 return;
1646 /* We now create a wrapper, which does the following:
1647 1. Call the suitable finalization subroutine for this type
1648 2. Loop over all noninherited allocatable components and noninherited
1649 components with allocatable components and DEALLOCATE those; this will
1650 take care of finalizers, coarray deregistering and allocatable
1651 nested components.
1652 3. Call the ancestor's finalizer. */
1654 /* Declare the wrapper function; it takes an assumed-rank array
1655 and a VALUE logical as arguments. */
1657 /* Set up the namespace. */
1658 sub_ns = gfc_get_namespace (ns, 0);
1659 sub_ns->sibling = ns->contained;
1660 if (!expr_null_wrapper)
1661 ns->contained = sub_ns;
1662 sub_ns->resolved = 1;
1664 /* Set up the procedure symbol. */
1665 name = xasprintf ("__final_%s", tname);
1666 gfc_get_symbol (name, sub_ns, &final);
1667 sub_ns->proc_name = final;
1668 final->attr.flavor = FL_PROCEDURE;
1669 final->attr.function = 1;
1670 final->attr.pure = 0;
1671 final->attr.recursive = 1;
1672 final->result = final;
1673 final->ts.type = BT_INTEGER;
1674 final->ts.kind = 4;
1675 final->attr.artificial = 1;
1676 final->attr.always_explicit = 1;
1677 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1678 if (ns->proc_name->attr.flavor == FL_MODULE)
1679 final->module = ns->proc_name->name;
1680 gfc_set_sym_referenced (final);
1681 gfc_commit_symbol (final);
1683 /* Set up formal argument. */
1684 gfc_get_symbol ("array", sub_ns, &array);
1685 array->ts.type = BT_DERIVED;
1686 array->ts.u.derived = derived;
1687 array->attr.flavor = FL_VARIABLE;
1688 array->attr.dummy = 1;
1689 array->attr.contiguous = 1;
1690 array->attr.dimension = 1;
1691 array->attr.artificial = 1;
1692 array->as = gfc_get_array_spec();
1693 array->as->type = AS_ASSUMED_RANK;
1694 array->as->rank = -1;
1695 array->attr.intent = INTENT_INOUT;
1696 gfc_set_sym_referenced (array);
1697 final->formal = gfc_get_formal_arglist ();
1698 final->formal->sym = array;
1699 gfc_commit_symbol (array);
1701 /* Set up formal argument. */
1702 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1703 byte_stride->ts.type = BT_INTEGER;
1704 byte_stride->ts.kind = gfc_index_integer_kind;
1705 byte_stride->attr.flavor = FL_VARIABLE;
1706 byte_stride->attr.dummy = 1;
1707 byte_stride->attr.value = 1;
1708 byte_stride->attr.artificial = 1;
1709 gfc_set_sym_referenced (byte_stride);
1710 final->formal->next = gfc_get_formal_arglist ();
1711 final->formal->next->sym = byte_stride;
1712 gfc_commit_symbol (byte_stride);
1714 /* Set up formal argument. */
1715 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1716 fini_coarray->ts.type = BT_LOGICAL;
1717 fini_coarray->ts.kind = 1;
1718 fini_coarray->attr.flavor = FL_VARIABLE;
1719 fini_coarray->attr.dummy = 1;
1720 fini_coarray->attr.value = 1;
1721 fini_coarray->attr.artificial = 1;
1722 gfc_set_sym_referenced (fini_coarray);
1723 final->formal->next->next = gfc_get_formal_arglist ();
1724 final->formal->next->next->sym = fini_coarray;
1725 gfc_commit_symbol (fini_coarray);
1727 /* Return with a NULL() expression but with an interface which has
1728 the formal arguments. */
1729 if (expr_null_wrapper)
1731 vtab_final->initializer = gfc_get_null_expr (NULL);
1732 vtab_final->ts.interface = final;
1733 return;
1736 /* Local variables. */
1738 gfc_get_symbol ("idx", sub_ns, &idx);
1739 idx->ts.type = BT_INTEGER;
1740 idx->ts.kind = gfc_index_integer_kind;
1741 idx->attr.flavor = FL_VARIABLE;
1742 idx->attr.artificial = 1;
1743 gfc_set_sym_referenced (idx);
1744 gfc_commit_symbol (idx);
1746 gfc_get_symbol ("idx2", sub_ns, &idx2);
1747 idx2->ts.type = BT_INTEGER;
1748 idx2->ts.kind = gfc_index_integer_kind;
1749 idx2->attr.flavor = FL_VARIABLE;
1750 idx2->attr.artificial = 1;
1751 gfc_set_sym_referenced (idx2);
1752 gfc_commit_symbol (idx2);
1754 gfc_get_symbol ("offset", sub_ns, &offset);
1755 offset->ts.type = BT_INTEGER;
1756 offset->ts.kind = gfc_index_integer_kind;
1757 offset->attr.flavor = FL_VARIABLE;
1758 offset->attr.artificial = 1;
1759 gfc_set_sym_referenced (offset);
1760 gfc_commit_symbol (offset);
1762 /* Create RANK expression. */
1763 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1764 gfc_current_locus, 1,
1765 gfc_lval_expr_from_sym (array));
1766 if (rank->ts.kind != idx->ts.kind)
1767 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1769 /* Create is_contiguous variable. */
1770 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1771 is_contiguous->ts.type = BT_LOGICAL;
1772 is_contiguous->ts.kind = gfc_default_logical_kind;
1773 is_contiguous->attr.flavor = FL_VARIABLE;
1774 is_contiguous->attr.artificial = 1;
1775 gfc_set_sym_referenced (is_contiguous);
1776 gfc_commit_symbol (is_contiguous);
1778 /* Create "sizes(0..rank)" variable, which contains the multiplied
1779 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1780 sizes(2) = sizes(1) * extent(dim=2) etc. */
1781 gfc_get_symbol ("sizes", sub_ns, &sizes);
1782 sizes->ts.type = BT_INTEGER;
1783 sizes->ts.kind = gfc_index_integer_kind;
1784 sizes->attr.flavor = FL_VARIABLE;
1785 sizes->attr.dimension = 1;
1786 sizes->attr.artificial = 1;
1787 sizes->as = gfc_get_array_spec();
1788 sizes->attr.intent = INTENT_INOUT;
1789 sizes->as->type = AS_EXPLICIT;
1790 sizes->as->rank = 1;
1791 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1792 sizes->as->upper[0] = gfc_copy_expr (rank);
1793 gfc_set_sym_referenced (sizes);
1794 gfc_commit_symbol (sizes);
1796 /* Create "strides(1..rank)" variable, which contains the strides per
1797 dimension. */
1798 gfc_get_symbol ("strides", sub_ns, &strides);
1799 strides->ts.type = BT_INTEGER;
1800 strides->ts.kind = gfc_index_integer_kind;
1801 strides->attr.flavor = FL_VARIABLE;
1802 strides->attr.dimension = 1;
1803 strides->attr.artificial = 1;
1804 strides->as = gfc_get_array_spec();
1805 strides->attr.intent = INTENT_INOUT;
1806 strides->as->type = AS_EXPLICIT;
1807 strides->as->rank = 1;
1808 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1809 strides->as->upper[0] = gfc_copy_expr (rank);
1810 gfc_set_sym_referenced (strides);
1811 gfc_commit_symbol (strides);
1814 /* Set return value to 0. */
1815 last_code = gfc_get_code (EXEC_ASSIGN);
1816 last_code->expr1 = gfc_lval_expr_from_sym (final);
1817 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1818 sub_ns->code = last_code;
1820 /* Set: is_contiguous = .true. */
1821 last_code->next = gfc_get_code (EXEC_ASSIGN);
1822 last_code = last_code->next;
1823 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1824 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1825 &gfc_current_locus, true);
1827 /* Set: sizes(0) = 1. */
1828 last_code->next = gfc_get_code (EXEC_ASSIGN);
1829 last_code = last_code->next;
1830 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1831 last_code->expr1->ref = gfc_get_ref ();
1832 last_code->expr1->ref->type = REF_ARRAY;
1833 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1834 last_code->expr1->ref->u.ar.dimen = 1;
1835 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1836 last_code->expr1->ref->u.ar.start[0]
1837 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1838 last_code->expr1->ref->u.ar.as = sizes->as;
1839 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1841 /* Create:
1842 DO idx = 1, rank
1843 strides(idx) = _F._stride (array, dim=idx)
1844 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1845 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1846 END DO. */
1848 /* Create loop. */
1849 iter = gfc_get_iterator ();
1850 iter->var = gfc_lval_expr_from_sym (idx);
1851 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1852 iter->end = gfc_copy_expr (rank);
1853 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1854 last_code->next = gfc_get_code (EXEC_DO);
1855 last_code = last_code->next;
1856 last_code->ext.iterator = iter;
1857 last_code->block = gfc_get_code (EXEC_DO);
1859 /* strides(idx) = _F._stride(array,dim=idx). */
1860 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1861 block = last_code->block->next;
1863 block->expr1 = gfc_lval_expr_from_sym (strides);
1864 block->expr1->ref = gfc_get_ref ();
1865 block->expr1->ref->type = REF_ARRAY;
1866 block->expr1->ref->u.ar.type = AR_ELEMENT;
1867 block->expr1->ref->u.ar.dimen = 1;
1868 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1869 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1870 block->expr1->ref->u.ar.as = strides->as;
1872 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1873 gfc_current_locus, 2,
1874 gfc_lval_expr_from_sym (array),
1875 gfc_lval_expr_from_sym (idx));
1877 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1878 block->next = gfc_get_code (EXEC_ASSIGN);
1879 block = block->next;
1881 /* sizes(idx) = ... */
1882 block->expr1 = gfc_lval_expr_from_sym (sizes);
1883 block->expr1->ref = gfc_get_ref ();
1884 block->expr1->ref->type = REF_ARRAY;
1885 block->expr1->ref->u.ar.type = AR_ELEMENT;
1886 block->expr1->ref->u.ar.dimen = 1;
1887 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1888 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1889 block->expr1->ref->u.ar.as = sizes->as;
1891 block->expr2 = gfc_get_expr ();
1892 block->expr2->expr_type = EXPR_OP;
1893 block->expr2->value.op.op = INTRINSIC_TIMES;
1894 block->expr2->where = gfc_current_locus;
1896 /* sizes(idx-1). */
1897 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1898 block->expr2->value.op.op1->ref = gfc_get_ref ();
1899 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1900 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1901 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1902 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1903 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1904 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1905 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1906 block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus;
1907 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1908 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1909 = gfc_lval_expr_from_sym (idx);
1910 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1911 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1912 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1913 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1915 /* size(array, dim=idx, kind=index_kind). */
1916 block->expr2->value.op.op2
1917 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1918 gfc_current_locus, 3,
1919 gfc_lval_expr_from_sym (array),
1920 gfc_lval_expr_from_sym (idx),
1921 gfc_get_int_expr (gfc_index_integer_kind,
1922 NULL,
1923 gfc_index_integer_kind));
1924 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1925 block->expr2->ts = idx->ts;
1927 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1928 block->next = gfc_get_code (EXEC_IF);
1929 block = block->next;
1931 block->block = gfc_get_code (EXEC_IF);
1932 block = block->block;
1934 /* if condition: strides(idx) /= sizes(idx-1). */
1935 block->expr1 = gfc_get_expr ();
1936 block->expr1->ts.type = BT_LOGICAL;
1937 block->expr1->ts.kind = gfc_default_logical_kind;
1938 block->expr1->expr_type = EXPR_OP;
1939 block->expr1->where = gfc_current_locus;
1940 block->expr1->value.op.op = INTRINSIC_NE;
1942 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1943 block->expr1->value.op.op1->ref = gfc_get_ref ();
1944 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1945 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1946 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1947 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1948 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1949 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1951 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1952 block->expr1->value.op.op2->ref = gfc_get_ref ();
1953 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1954 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1955 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1956 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1957 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1958 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1959 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1960 block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1961 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1962 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1963 = gfc_lval_expr_from_sym (idx);
1964 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1965 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1966 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1967 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1969 /* if body: is_contiguous = .false. */
1970 block->next = gfc_get_code (EXEC_ASSIGN);
1971 block = block->next;
1972 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1973 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1974 &gfc_current_locus, false);
1976 /* Obtain the size (number of elements) of "array" MINUS ONE,
1977 which is used in the scalarization. */
1978 gfc_get_symbol ("nelem", sub_ns, &nelem);
1979 nelem->ts.type = BT_INTEGER;
1980 nelem->ts.kind = gfc_index_integer_kind;
1981 nelem->attr.flavor = FL_VARIABLE;
1982 nelem->attr.artificial = 1;
1983 gfc_set_sym_referenced (nelem);
1984 gfc_commit_symbol (nelem);
1986 /* nelem = sizes (rank) - 1. */
1987 last_code->next = gfc_get_code (EXEC_ASSIGN);
1988 last_code = last_code->next;
1990 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
1992 last_code->expr2 = gfc_get_expr ();
1993 last_code->expr2->expr_type = EXPR_OP;
1994 last_code->expr2->value.op.op = INTRINSIC_MINUS;
1995 last_code->expr2->value.op.op2
1996 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1997 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
1998 last_code->expr2->where = gfc_current_locus;
2000 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
2001 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
2002 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
2003 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
2004 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
2005 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2006 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
2007 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
2009 /* Call final subroutines. We now generate code like:
2010 use iso_c_binding
2011 integer, pointer :: ptr
2012 type(c_ptr) :: cptr
2013 integer(c_intptr_t) :: i, addr
2015 select case (rank (array))
2016 case (3)
2017 ! If needed, the array is packed
2018 call final_rank3 (array)
2019 case default:
2020 do i = 0, size (array)-1
2021 addr = transfer (c_loc (array), addr) + i * stride
2022 call c_f_pointer (transfer (addr, cptr), ptr)
2023 call elemental_final (ptr)
2024 end do
2025 end select */
2027 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2029 gfc_finalizer *fini, *fini_elem = NULL;
2031 gfc_get_symbol ("ptr1", sub_ns, &ptr);
2032 ptr->ts.type = BT_DERIVED;
2033 ptr->ts.u.derived = derived;
2034 ptr->attr.flavor = FL_VARIABLE;
2035 ptr->attr.pointer = 1;
2036 ptr->attr.artificial = 1;
2037 gfc_set_sym_referenced (ptr);
2038 gfc_commit_symbol (ptr);
2040 /* SELECT CASE (RANK (array)). */
2041 last_code->next = gfc_get_code (EXEC_SELECT);
2042 last_code = last_code->next;
2043 last_code->expr1 = gfc_copy_expr (rank);
2044 block = NULL;
2046 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
2048 gcc_assert (fini->proc_tree); /* Should have been set in gfc_resolve_finalizers. */
2049 if (fini->proc_tree->n.sym->attr.elemental)
2051 fini_elem = fini;
2052 continue;
2055 /* CASE (fini_rank). */
2056 if (block)
2058 block->block = gfc_get_code (EXEC_SELECT);
2059 block = block->block;
2061 else
2063 block = gfc_get_code (EXEC_SELECT);
2064 last_code->block = block;
2066 block->ext.block.case_list = gfc_get_case ();
2067 block->ext.block.case_list->where = gfc_current_locus;
2068 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2069 block->ext.block.case_list->low
2070 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2071 fini->proc_tree->n.sym->formal->sym->as->rank);
2072 else
2073 block->ext.block.case_list->low
2074 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2075 block->ext.block.case_list->high
2076 = gfc_copy_expr (block->ext.block.case_list->low);
2078 /* CALL fini_rank (array) - possibly with packing. */
2079 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2080 finalizer_insert_packed_call (block, fini, array, byte_stride,
2081 idx, ptr, nelem, strides,
2082 sizes, idx2, offset, is_contiguous,
2083 rank, sub_ns);
2084 else
2086 block->next = gfc_get_code (EXEC_CALL);
2087 block->next->symtree = fini->proc_tree;
2088 block->next->resolved_sym = fini->proc_tree->n.sym;
2089 block->next->ext.actual = gfc_get_actual_arglist ();
2090 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
2094 /* Elemental call - scalarized. */
2095 if (fini_elem)
2097 /* CASE DEFAULT. */
2098 if (block)
2100 block->block = gfc_get_code (EXEC_SELECT);
2101 block = block->block;
2103 else
2105 block = gfc_get_code (EXEC_SELECT);
2106 last_code->block = block;
2108 block->ext.block.case_list = gfc_get_case ();
2110 /* Create loop. */
2111 iter = gfc_get_iterator ();
2112 iter->var = gfc_lval_expr_from_sym (idx);
2113 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2114 iter->end = gfc_lval_expr_from_sym (nelem);
2115 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2116 block->next = gfc_get_code (EXEC_DO);
2117 block = block->next;
2118 block->ext.iterator = iter;
2119 block->block = gfc_get_code (EXEC_DO);
2121 /* Offset calculation. */
2122 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2123 byte_stride, rank, block->block,
2124 sub_ns);
2126 /* Create code for
2127 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2128 + offset, c_ptr), ptr). */
2129 block->next
2130 = finalization_scalarizer (array, ptr,
2131 gfc_lval_expr_from_sym (offset),
2132 sub_ns);
2133 block = block->next;
2135 /* CALL final_elemental (array). */
2136 block->next = gfc_get_code (EXEC_CALL);
2137 block = block->next;
2138 block->symtree = fini_elem->proc_tree;
2139 block->resolved_sym = fini_elem->proc_sym;
2140 block->ext.actual = gfc_get_actual_arglist ();
2141 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
2145 /* Finalize and deallocate allocatable components. The same manual
2146 scalarization is used as above. */
2148 if (finalizable_comp)
2150 gfc_symbol *stat;
2151 gfc_code *block = NULL;
2153 if (!ptr)
2155 gfc_get_symbol ("ptr2", sub_ns, &ptr);
2156 ptr->ts.type = BT_DERIVED;
2157 ptr->ts.u.derived = derived;
2158 ptr->attr.flavor = FL_VARIABLE;
2159 ptr->attr.pointer = 1;
2160 ptr->attr.artificial = 1;
2161 gfc_set_sym_referenced (ptr);
2162 gfc_commit_symbol (ptr);
2165 gfc_get_symbol ("ignore", sub_ns, &stat);
2166 stat->attr.flavor = FL_VARIABLE;
2167 stat->attr.artificial = 1;
2168 stat->ts.type = BT_INTEGER;
2169 stat->ts.kind = gfc_default_integer_kind;
2170 gfc_set_sym_referenced (stat);
2171 gfc_commit_symbol (stat);
2173 /* Create loop. */
2174 iter = gfc_get_iterator ();
2175 iter->var = gfc_lval_expr_from_sym (idx);
2176 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2177 iter->end = gfc_lval_expr_from_sym (nelem);
2178 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2179 last_code->next = gfc_get_code (EXEC_DO);
2180 last_code = last_code->next;
2181 last_code->ext.iterator = iter;
2182 last_code->block = gfc_get_code (EXEC_DO);
2184 /* Offset calculation. */
2185 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2186 byte_stride, rank, last_code->block,
2187 sub_ns);
2189 /* Create code for
2190 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2191 + idx * stride, c_ptr), ptr). */
2192 block->next = finalization_scalarizer (array, ptr,
2193 gfc_lval_expr_from_sym(offset),
2194 sub_ns);
2195 block = block->next;
2197 for (comp = derived->components; comp; comp = comp->next)
2199 if (comp == derived->components && derived->attr.extension
2200 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2201 continue;
2203 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2204 stat, fini_coarray, &block, sub_ns);
2205 if (!last_code->block->next)
2206 last_code->block->next = block;
2211 /* Call the finalizer of the ancestor. */
2212 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2214 last_code->next = gfc_get_code (EXEC_CALL);
2215 last_code = last_code->next;
2216 last_code->symtree = ancestor_wrapper->symtree;
2217 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2219 last_code->ext.actual = gfc_get_actual_arglist ();
2220 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2221 last_code->ext.actual->next = gfc_get_actual_arglist ();
2222 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2223 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2224 last_code->ext.actual->next->next->expr
2225 = gfc_lval_expr_from_sym (fini_coarray);
2228 gfc_free_expr (rank);
2229 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2230 vtab_final->ts.interface = final;
2231 free (name);
2235 /* Add procedure pointers for all type-bound procedures to a vtab. */
2237 static void
2238 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2240 gfc_symbol* super_type;
2242 super_type = gfc_get_derived_super_type (derived);
2244 if (super_type && (super_type != derived))
2246 /* Make sure that the PPCs appear in the same order as in the parent. */
2247 copy_vtab_proc_comps (super_type, vtype);
2248 /* Only needed to get the PPC initializers right. */
2249 add_procs_to_declared_vtab (super_type, vtype);
2252 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2253 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2255 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2256 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2260 /* Find or generate the symbol for a derived type's vtab. */
2262 gfc_symbol *
2263 gfc_find_derived_vtab (gfc_symbol *derived)
2265 gfc_namespace *ns;
2266 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2267 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2268 gfc_gsymbol *gsym = NULL;
2269 gfc_symbol *dealloc = NULL, *arg = NULL;
2271 if (derived->attr.pdt_template)
2272 return NULL;
2274 /* Find the top-level namespace. */
2275 for (ns = gfc_current_ns; ns; ns = ns->parent)
2276 if (!ns->parent)
2277 break;
2279 /* If the type is a class container, use the underlying derived type. */
2280 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2281 derived = gfc_get_derived_super_type (derived);
2283 if (!derived)
2284 return NULL;
2286 if (!derived->name)
2287 return NULL;
2289 /* Find the gsymbol for the module of use associated derived types. */
2290 if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
2291 && !derived->attr.vtype && !derived->attr.is_class)
2292 gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module);
2293 else
2294 gsym = NULL;
2296 /* Work in the gsymbol namespace if the top-level namespace is a module.
2297 This ensures that the vtable is unique, which is required since we use
2298 its address in SELECT TYPE. */
2299 if (gsym && gsym->ns && ns && ns->proc_name
2300 && ns->proc_name->attr.flavor == FL_MODULE)
2301 ns = gsym->ns;
2303 if (ns)
2305 char tname[GFC_MAX_SYMBOL_LEN+1];
2306 char *name;
2308 get_unique_hashed_string (tname, derived);
2309 name = xasprintf ("__vtab_%s", tname);
2311 /* Look for the vtab symbol in various namespaces. */
2312 if (gsym && gsym->ns)
2314 gfc_find_symbol (name, gsym->ns, 0, &vtab);
2315 if (vtab)
2316 ns = gsym->ns;
2318 if (vtab == NULL)
2319 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2320 if (vtab == NULL)
2321 gfc_find_symbol (name, ns, 0, &vtab);
2322 if (vtab == NULL)
2323 gfc_find_symbol (name, derived->ns, 0, &vtab);
2325 if (vtab == NULL)
2327 gfc_get_symbol (name, ns, &vtab);
2328 vtab->ts.type = BT_DERIVED;
2329 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2330 &gfc_current_locus))
2331 goto cleanup;
2332 vtab->attr.target = 1;
2333 vtab->attr.save = SAVE_IMPLICIT;
2334 vtab->attr.vtab = 1;
2335 vtab->attr.access = ACCESS_PUBLIC;
2336 gfc_set_sym_referenced (vtab);
2337 name = xasprintf ("__vtype_%s", tname);
2339 gfc_find_symbol (name, ns, 0, &vtype);
2340 if (vtype == NULL)
2342 gfc_component *c;
2343 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2344 bool rdt = false;
2346 /* Is this a derived type with recursive allocatable
2347 components? */
2348 c = (derived->attr.unlimited_polymorphic
2349 || derived->attr.abstract) ?
2350 NULL : derived->components;
2351 for (; c; c= c->next)
2352 if (c->ts.type == BT_DERIVED
2353 && c->ts.u.derived == derived)
2355 rdt = true;
2356 break;
2359 gfc_get_symbol (name, ns, &vtype);
2360 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2361 &gfc_current_locus))
2362 goto cleanup;
2363 vtype->attr.access = ACCESS_PUBLIC;
2364 vtype->attr.vtype = 1;
2365 gfc_set_sym_referenced (vtype);
2367 /* Add component '_hash'. */
2368 if (!gfc_add_component (vtype, "_hash", &c))
2369 goto cleanup;
2370 c->ts.type = BT_INTEGER;
2371 c->ts.kind = 4;
2372 c->attr.access = ACCESS_PRIVATE;
2373 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2374 NULL, derived->hash_value);
2376 /* Add component '_size'. */
2377 if (!gfc_add_component (vtype, "_size", &c))
2378 goto cleanup;
2379 c->ts.type = BT_INTEGER;
2380 c->ts.kind = gfc_size_kind;
2381 c->attr.access = ACCESS_PRIVATE;
2382 /* Remember the derived type in ts.u.derived,
2383 so that the correct initializer can be set later on
2384 (in gfc_conv_structure). */
2385 c->ts.u.derived = derived;
2386 c->initializer = gfc_get_int_expr (gfc_size_kind,
2387 NULL, 0);
2389 /* Add component _extends. */
2390 if (!gfc_add_component (vtype, "_extends", &c))
2391 goto cleanup;
2392 c->attr.pointer = 1;
2393 c->attr.access = ACCESS_PRIVATE;
2394 if (!derived->attr.unlimited_polymorphic)
2395 parent = gfc_get_derived_super_type (derived);
2396 else
2397 parent = NULL;
2399 if (parent)
2401 parent_vtab = gfc_find_derived_vtab (parent);
2402 c->ts.type = BT_DERIVED;
2403 c->ts.u.derived = parent_vtab->ts.u.derived;
2404 c->initializer = gfc_get_expr ();
2405 c->initializer->expr_type = EXPR_VARIABLE;
2406 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2407 0, &c->initializer->symtree);
2409 else
2411 c->ts.type = BT_DERIVED;
2412 c->ts.u.derived = vtype;
2413 c->initializer = gfc_get_null_expr (NULL);
2416 if (!derived->attr.unlimited_polymorphic
2417 && derived->components == NULL
2418 && !derived->attr.zero_comp)
2420 /* At this point an error must have occurred.
2421 Prevent further errors on the vtype components. */
2422 found_sym = vtab;
2423 goto have_vtype;
2426 /* Add component _def_init. */
2427 if (!gfc_add_component (vtype, "_def_init", &c))
2428 goto cleanup;
2429 c->attr.pointer = 1;
2430 c->attr.artificial = 1;
2431 c->attr.access = ACCESS_PRIVATE;
2432 c->ts.type = BT_DERIVED;
2433 c->ts.u.derived = derived;
2434 if (derived->attr.unlimited_polymorphic
2435 || derived->attr.abstract)
2436 c->initializer = gfc_get_null_expr (NULL);
2437 else
2439 /* Construct default initialization variable. */
2440 name = xasprintf ("__def_init_%s", tname);
2441 gfc_get_symbol (name, ns, &def_init);
2442 def_init->attr.target = 1;
2443 def_init->attr.artificial = 1;
2444 def_init->attr.save = SAVE_IMPLICIT;
2445 def_init->attr.access = ACCESS_PUBLIC;
2446 def_init->attr.flavor = FL_VARIABLE;
2447 gfc_set_sym_referenced (def_init);
2448 def_init->ts.type = BT_DERIVED;
2449 def_init->ts.u.derived = derived;
2450 def_init->value = gfc_default_initializer (&def_init->ts);
2452 c->initializer = gfc_lval_expr_from_sym (def_init);
2455 /* Add component _copy. */
2456 if (!gfc_add_component (vtype, "_copy", &c))
2457 goto cleanup;
2458 c->attr.proc_pointer = 1;
2459 c->attr.access = ACCESS_PRIVATE;
2460 c->tb = XCNEW (gfc_typebound_proc);
2461 c->tb->ppc = 1;
2462 if (derived->attr.unlimited_polymorphic
2463 || derived->attr.abstract)
2464 c->initializer = gfc_get_null_expr (NULL);
2465 else
2467 /* Set up namespace. */
2468 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2469 sub_ns->sibling = ns->contained;
2470 ns->contained = sub_ns;
2471 sub_ns->resolved = 1;
2472 /* Set up procedure symbol. */
2473 name = xasprintf ("__copy_%s", tname);
2474 gfc_get_symbol (name, sub_ns, &copy);
2475 sub_ns->proc_name = copy;
2476 copy->attr.flavor = FL_PROCEDURE;
2477 copy->attr.subroutine = 1;
2478 copy->attr.pure = 1;
2479 copy->attr.artificial = 1;
2480 copy->attr.if_source = IFSRC_DECL;
2481 /* This is elemental so that arrays are automatically
2482 treated correctly by the scalarizer. */
2483 copy->attr.elemental = 1;
2484 if (ns->proc_name->attr.flavor == FL_MODULE)
2485 copy->module = ns->proc_name->name;
2486 gfc_set_sym_referenced (copy);
2487 /* Set up formal arguments. */
2488 gfc_get_symbol ("src", sub_ns, &src);
2489 src->ts.type = BT_DERIVED;
2490 src->ts.u.derived = derived;
2491 src->attr.flavor = FL_VARIABLE;
2492 src->attr.dummy = 1;
2493 src->attr.artificial = 1;
2494 src->attr.intent = INTENT_IN;
2495 gfc_set_sym_referenced (src);
2496 copy->formal = gfc_get_formal_arglist ();
2497 copy->formal->sym = src;
2498 gfc_get_symbol ("dst", sub_ns, &dst);
2499 dst->ts.type = BT_DERIVED;
2500 dst->ts.u.derived = derived;
2501 dst->attr.flavor = FL_VARIABLE;
2502 dst->attr.dummy = 1;
2503 dst->attr.artificial = 1;
2504 dst->attr.intent = INTENT_INOUT;
2505 gfc_set_sym_referenced (dst);
2506 copy->formal->next = gfc_get_formal_arglist ();
2507 copy->formal->next->sym = dst;
2508 /* Set up code. */
2509 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2510 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2511 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2512 /* Set initializer. */
2513 c->initializer = gfc_lval_expr_from_sym (copy);
2514 c->ts.interface = copy;
2517 /* Add component _final, which contains a procedure pointer to
2518 a wrapper which handles both the freeing of allocatable
2519 components and the calls to finalization subroutines.
2520 Note: The actual wrapper function can only be generated
2521 at resolution time. */
2522 if (!gfc_add_component (vtype, "_final", &c))
2523 goto cleanup;
2524 c->attr.proc_pointer = 1;
2525 c->attr.access = ACCESS_PRIVATE;
2526 c->attr.artificial = 1;
2527 c->tb = XCNEW (gfc_typebound_proc);
2528 c->tb->ppc = 1;
2529 generate_finalization_wrapper (derived, ns, tname, c);
2531 /* Add component _deallocate. */
2532 if (!gfc_add_component (vtype, "_deallocate", &c))
2533 goto cleanup;
2534 c->attr.proc_pointer = 1;
2535 c->attr.access = ACCESS_PRIVATE;
2536 c->tb = XCNEW (gfc_typebound_proc);
2537 c->tb->ppc = 1;
2538 if (derived->attr.unlimited_polymorphic
2539 || derived->attr.abstract
2540 || !rdt)
2541 c->initializer = gfc_get_null_expr (NULL);
2542 else
2544 /* Set up namespace. */
2545 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2547 sub_ns->sibling = ns->contained;
2548 ns->contained = sub_ns;
2549 sub_ns->resolved = 1;
2550 /* Set up procedure symbol. */
2551 name = xasprintf ("__deallocate_%s", tname);
2552 gfc_get_symbol (name, sub_ns, &dealloc);
2553 sub_ns->proc_name = dealloc;
2554 dealloc->attr.flavor = FL_PROCEDURE;
2555 dealloc->attr.subroutine = 1;
2556 dealloc->attr.pure = 1;
2557 dealloc->attr.artificial = 1;
2558 dealloc->attr.if_source = IFSRC_DECL;
2560 if (ns->proc_name->attr.flavor == FL_MODULE)
2561 dealloc->module = ns->proc_name->name;
2562 gfc_set_sym_referenced (dealloc);
2563 /* Set up formal argument. */
2564 gfc_get_symbol ("arg", sub_ns, &arg);
2565 arg->ts.type = BT_DERIVED;
2566 arg->ts.u.derived = derived;
2567 arg->attr.flavor = FL_VARIABLE;
2568 arg->attr.dummy = 1;
2569 arg->attr.artificial = 1;
2570 arg->attr.intent = INTENT_INOUT;
2571 arg->attr.dimension = 1;
2572 arg->attr.allocatable = 1;
2573 arg->as = gfc_get_array_spec();
2574 arg->as->type = AS_ASSUMED_SHAPE;
2575 arg->as->rank = 1;
2576 arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
2577 NULL, 1);
2578 gfc_set_sym_referenced (arg);
2579 dealloc->formal = gfc_get_formal_arglist ();
2580 dealloc->formal->sym = arg;
2581 /* Set up code. */
2582 sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
2583 sub_ns->code->ext.alloc.list = gfc_get_alloc ();
2584 sub_ns->code->ext.alloc.list->expr
2585 = gfc_lval_expr_from_sym (arg);
2586 /* Set initializer. */
2587 c->initializer = gfc_lval_expr_from_sym (dealloc);
2588 c->ts.interface = dealloc;
2591 /* Add procedure pointers for type-bound procedures. */
2592 if (!derived->attr.unlimited_polymorphic)
2593 add_procs_to_declared_vtab (derived, vtype);
2596 have_vtype:
2597 vtab->ts.u.derived = vtype;
2598 vtab->value = gfc_default_initializer (&vtab->ts);
2600 free (name);
2603 found_sym = vtab;
2605 cleanup:
2606 /* It is unexpected to have some symbols added at resolution or code
2607 generation time. We commit the changes in order to keep a clean state. */
2608 if (found_sym)
2610 gfc_commit_symbol (vtab);
2611 if (vtype)
2612 gfc_commit_symbol (vtype);
2613 if (def_init)
2614 gfc_commit_symbol (def_init);
2615 if (copy)
2616 gfc_commit_symbol (copy);
2617 if (src)
2618 gfc_commit_symbol (src);
2619 if (dst)
2620 gfc_commit_symbol (dst);
2621 if (dealloc)
2622 gfc_commit_symbol (dealloc);
2623 if (arg)
2624 gfc_commit_symbol (arg);
2626 else
2627 gfc_undo_symbols ();
2629 return found_sym;
2633 /* Check if a derived type is finalizable. That is the case if it
2634 (1) has a FINAL subroutine or
2635 (2) has a nonpointer nonallocatable component of finalizable type.
2636 If it is finalizable, return an expression containing the
2637 finalization wrapper. */
2639 bool
2640 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2642 gfc_symbol *vtab;
2643 gfc_component *c;
2645 /* (1) Check for FINAL subroutines. */
2646 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2647 goto yes;
2649 /* (2) Check for components of finalizable type. */
2650 for (c = derived->components; c; c = c->next)
2651 if (c->ts.type == BT_DERIVED
2652 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2653 && gfc_is_finalizable (c->ts.u.derived, NULL))
2654 goto yes;
2656 return false;
2658 yes:
2659 /* Make sure vtab is generated. */
2660 vtab = gfc_find_derived_vtab (derived);
2661 if (final_expr)
2663 /* Return finalizer expression. */
2664 gfc_component *final;
2665 final = vtab->ts.u.derived->components->next->next->next->next->next;
2666 gcc_assert (strcmp (final->name, "_final") == 0);
2667 gcc_assert (final->initializer
2668 && final->initializer->expr_type != EXPR_NULL);
2669 *final_expr = final->initializer;
2671 return true;
2675 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2676 needed to support unlimited polymorphism. */
2678 static gfc_symbol *
2679 find_intrinsic_vtab (gfc_typespec *ts)
2681 gfc_namespace *ns;
2682 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2683 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2685 /* Find the top-level namespace. */
2686 for (ns = gfc_current_ns; ns; ns = ns->parent)
2687 if (!ns->parent)
2688 break;
2690 if (ns)
2692 char tname[GFC_MAX_SYMBOL_LEN+1];
2693 char *name;
2695 /* Encode all types as TYPENAME_KIND_ including especially character
2696 arrays, whose length is now consistently stored in the _len component
2697 of the class-variable. */
2698 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2699 name = xasprintf ("__vtab_%s", tname);
2701 /* Look for the vtab symbol in the top-level namespace only. */
2702 gfc_find_symbol (name, ns, 0, &vtab);
2704 if (vtab == NULL)
2706 gfc_get_symbol (name, ns, &vtab);
2707 vtab->ts.type = BT_DERIVED;
2708 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2709 &gfc_current_locus))
2710 goto cleanup;
2711 vtab->attr.target = 1;
2712 vtab->attr.save = SAVE_IMPLICIT;
2713 vtab->attr.vtab = 1;
2714 vtab->attr.access = ACCESS_PUBLIC;
2715 gfc_set_sym_referenced (vtab);
2716 name = xasprintf ("__vtype_%s", tname);
2718 gfc_find_symbol (name, ns, 0, &vtype);
2719 if (vtype == NULL)
2721 gfc_component *c;
2722 int hash;
2723 gfc_namespace *sub_ns;
2724 gfc_namespace *contained;
2725 gfc_expr *e;
2726 size_t e_size;
2728 gfc_get_symbol (name, ns, &vtype);
2729 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2730 &gfc_current_locus))
2731 goto cleanup;
2732 vtype->attr.access = ACCESS_PUBLIC;
2733 vtype->attr.vtype = 1;
2734 gfc_set_sym_referenced (vtype);
2736 /* Add component '_hash'. */
2737 if (!gfc_add_component (vtype, "_hash", &c))
2738 goto cleanup;
2739 c->ts.type = BT_INTEGER;
2740 c->ts.kind = 4;
2741 c->attr.access = ACCESS_PRIVATE;
2742 hash = gfc_intrinsic_hash_value (ts);
2743 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2744 NULL, hash);
2746 /* Add component '_size'. */
2747 if (!gfc_add_component (vtype, "_size", &c))
2748 goto cleanup;
2749 c->ts.type = BT_INTEGER;
2750 c->ts.kind = gfc_size_kind;
2751 c->attr.access = ACCESS_PRIVATE;
2753 /* Build a minimal expression to make use of
2754 target-memory.c/gfc_element_size for 'size'. Special handling
2755 for character arrays, that are not constant sized: to support
2756 len (str) * kind, only the kind information is stored in the
2757 vtab. */
2758 e = gfc_get_expr ();
2759 e->ts = *ts;
2760 e->expr_type = EXPR_VARIABLE;
2761 if (ts->type == BT_CHARACTER)
2762 e_size = ts->kind;
2763 else
2764 gfc_element_size (e, &e_size);
2765 c->initializer = gfc_get_int_expr (gfc_size_kind,
2766 NULL,
2767 e_size);
2768 gfc_free_expr (e);
2770 /* Add component _extends. */
2771 if (!gfc_add_component (vtype, "_extends", &c))
2772 goto cleanup;
2773 c->attr.pointer = 1;
2774 c->attr.access = ACCESS_PRIVATE;
2775 c->ts.type = BT_VOID;
2776 c->initializer = gfc_get_null_expr (NULL);
2778 /* Add component _def_init. */
2779 if (!gfc_add_component (vtype, "_def_init", &c))
2780 goto cleanup;
2781 c->attr.pointer = 1;
2782 c->attr.access = ACCESS_PRIVATE;
2783 c->ts.type = BT_VOID;
2784 c->initializer = gfc_get_null_expr (NULL);
2786 /* Add component _copy. */
2787 if (!gfc_add_component (vtype, "_copy", &c))
2788 goto cleanup;
2789 c->attr.proc_pointer = 1;
2790 c->attr.access = ACCESS_PRIVATE;
2791 c->tb = XCNEW (gfc_typebound_proc);
2792 c->tb->ppc = 1;
2794 if (ts->type != BT_CHARACTER)
2795 name = xasprintf ("__copy_%s", tname);
2796 else
2798 /* __copy is always the same for characters.
2799 Check to see if copy function already exists. */
2800 name = xasprintf ("__copy_character_%d", ts->kind);
2801 contained = ns->contained;
2802 for (; contained; contained = contained->sibling)
2803 if (contained->proc_name
2804 && strcmp (name, contained->proc_name->name) == 0)
2806 copy = contained->proc_name;
2807 goto got_char_copy;
2811 /* Set up namespace. */
2812 sub_ns = gfc_get_namespace (ns, 0);
2813 sub_ns->sibling = ns->contained;
2814 ns->contained = sub_ns;
2815 sub_ns->resolved = 1;
2816 /* Set up procedure symbol. */
2817 gfc_get_symbol (name, sub_ns, &copy);
2818 sub_ns->proc_name = copy;
2819 copy->attr.flavor = FL_PROCEDURE;
2820 copy->attr.subroutine = 1;
2821 copy->attr.pure = 1;
2822 copy->attr.if_source = IFSRC_DECL;
2823 /* This is elemental so that arrays are automatically
2824 treated correctly by the scalarizer. */
2825 copy->attr.elemental = 1;
2826 if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
2827 copy->module = ns->proc_name->name;
2828 gfc_set_sym_referenced (copy);
2829 /* Set up formal arguments. */
2830 gfc_get_symbol ("src", sub_ns, &src);
2831 src->ts.type = ts->type;
2832 src->ts.kind = ts->kind;
2833 src->attr.flavor = FL_VARIABLE;
2834 src->attr.dummy = 1;
2835 src->attr.intent = INTENT_IN;
2836 gfc_set_sym_referenced (src);
2837 copy->formal = gfc_get_formal_arglist ();
2838 copy->formal->sym = src;
2839 gfc_get_symbol ("dst", sub_ns, &dst);
2840 dst->ts.type = ts->type;
2841 dst->ts.kind = ts->kind;
2842 dst->attr.flavor = FL_VARIABLE;
2843 dst->attr.dummy = 1;
2844 dst->attr.intent = INTENT_INOUT;
2845 gfc_set_sym_referenced (dst);
2846 copy->formal->next = gfc_get_formal_arglist ();
2847 copy->formal->next->sym = dst;
2848 /* Set up code. */
2849 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2850 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2851 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2852 got_char_copy:
2853 /* Set initializer. */
2854 c->initializer = gfc_lval_expr_from_sym (copy);
2855 c->ts.interface = copy;
2857 /* Add component _final. */
2858 if (!gfc_add_component (vtype, "_final", &c))
2859 goto cleanup;
2860 c->attr.proc_pointer = 1;
2861 c->attr.access = ACCESS_PRIVATE;
2862 c->attr.artificial = 1;
2863 c->tb = XCNEW (gfc_typebound_proc);
2864 c->tb->ppc = 1;
2865 c->initializer = gfc_get_null_expr (NULL);
2867 vtab->ts.u.derived = vtype;
2868 vtab->value = gfc_default_initializer (&vtab->ts);
2870 free (name);
2873 found_sym = vtab;
2875 cleanup:
2876 /* It is unexpected to have some symbols added at resolution or code
2877 generation time. We commit the changes in order to keep a clean state. */
2878 if (found_sym)
2880 gfc_commit_symbol (vtab);
2881 if (vtype)
2882 gfc_commit_symbol (vtype);
2883 if (copy)
2884 gfc_commit_symbol (copy);
2885 if (src)
2886 gfc_commit_symbol (src);
2887 if (dst)
2888 gfc_commit_symbol (dst);
2890 else
2891 gfc_undo_symbols ();
2893 return found_sym;
2897 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
2899 gfc_symbol *
2900 gfc_find_vtab (gfc_typespec *ts)
2902 switch (ts->type)
2904 case BT_UNKNOWN:
2905 return NULL;
2906 case BT_DERIVED:
2907 return gfc_find_derived_vtab (ts->u.derived);
2908 case BT_CLASS:
2909 if (ts->u.derived->components && ts->u.derived->components->ts.u.derived)
2910 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
2911 else
2912 return NULL;
2913 default:
2914 return find_intrinsic_vtab (ts);
2919 /* General worker function to find either a type-bound procedure or a
2920 type-bound user operator. */
2922 static gfc_symtree*
2923 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2924 const char* name, bool noaccess, bool uop,
2925 locus* where)
2927 gfc_symtree* res;
2928 gfc_symtree* root;
2930 /* Set default to failure. */
2931 if (t)
2932 *t = false;
2934 if (derived->f2k_derived)
2935 /* Set correct symbol-root. */
2936 root = (uop ? derived->f2k_derived->tb_uop_root
2937 : derived->f2k_derived->tb_sym_root);
2938 else
2939 return NULL;
2941 /* Try to find it in the current type's namespace. */
2942 res = gfc_find_symtree (root, name);
2943 if (res && res->n.tb && !res->n.tb->error)
2945 /* We found one. */
2946 if (t)
2947 *t = true;
2949 if (!noaccess && derived->attr.use_assoc
2950 && res->n.tb->access == ACCESS_PRIVATE)
2952 if (where)
2953 gfc_error ("%qs of %qs is PRIVATE at %L",
2954 name, derived->name, where);
2955 if (t)
2956 *t = false;
2959 return res;
2962 /* Otherwise, recurse on parent type if derived is an extension. */
2963 if (derived->attr.extension)
2965 gfc_symbol* super_type;
2966 super_type = gfc_get_derived_super_type (derived);
2967 gcc_assert (super_type);
2969 return find_typebound_proc_uop (super_type, t, name,
2970 noaccess, uop, where);
2973 /* Nothing found. */
2974 return NULL;
2978 /* Find a type-bound procedure or user operator by name for a derived-type
2979 (looking recursively through the super-types). */
2981 gfc_symtree*
2982 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
2983 const char* name, bool noaccess, locus* where)
2985 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2988 gfc_symtree*
2989 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
2990 const char* name, bool noaccess, locus* where)
2992 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2996 /* Find a type-bound intrinsic operator looking recursively through the
2997 super-type hierarchy. */
2999 gfc_typebound_proc*
3000 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
3001 gfc_intrinsic_op op, bool noaccess,
3002 locus* where)
3004 gfc_typebound_proc* res;
3006 /* Set default to failure. */
3007 if (t)
3008 *t = false;
3010 /* Try to find it in the current type's namespace. */
3011 if (derived->f2k_derived)
3012 res = derived->f2k_derived->tb_op[op];
3013 else
3014 res = NULL;
3016 /* Check access. */
3017 if (res && !res->error)
3019 /* We found one. */
3020 if (t)
3021 *t = true;
3023 if (!noaccess && derived->attr.use_assoc
3024 && res->access == ACCESS_PRIVATE)
3026 if (where)
3027 gfc_error ("%qs of %qs is PRIVATE at %L",
3028 gfc_op2string (op), derived->name, where);
3029 if (t)
3030 *t = false;
3033 return res;
3036 /* Otherwise, recurse on parent type if derived is an extension. */
3037 if (derived->attr.extension)
3039 gfc_symbol* super_type;
3040 super_type = gfc_get_derived_super_type (derived);
3041 gcc_assert (super_type);
3043 return gfc_find_typebound_intrinsic_op (super_type, t, op,
3044 noaccess, where);
3047 /* Nothing found. */
3048 return NULL;
3052 /* Get a typebound-procedure symtree or create and insert it if not yet
3053 present. This is like a very simplified version of gfc_get_sym_tree for
3054 tbp-symtrees rather than regular ones. */
3056 gfc_symtree*
3057 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
3059 gfc_symtree *result = gfc_find_symtree (*root, name);
3060 return result ? result : gfc_new_symtree (root, name);