Allow gather loads to be used for grouped accesses
[official-gcc.git] / gcc / fortran / class.c
blob50d25b550a11cf5776e320bbc2bf4e9b4e4f8f79
1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2018 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.
53 After these follow procedure pointer components for the specific
54 type-bound procedures. */
57 #include "config.h"
58 #include "system.h"
59 #include "coretypes.h"
60 #include "gfortran.h"
61 #include "constructor.h"
62 #include "target-memory.h"
64 /* Inserts a derived type component reference in a data reference chain.
65 TS: base type of the ref chain so far, in which we will pick the component
66 REF: the address of the GFC_REF pointer to update
67 NAME: name of the component to insert
68 Note that component insertion makes sense only if we are at the end of
69 the chain (*REF == NULL) or if we are adding a missing "_data" component
70 to access the actual contents of a class object. */
72 static void
73 insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
75 gfc_symbol *type_sym;
76 gfc_ref *new_ref;
78 gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
79 type_sym = ts->u.derived;
81 gfc_find_component (type_sym, name, true, true, &new_ref);
82 gcc_assert (new_ref->u.c.component);
83 while (new_ref->next)
84 new_ref = new_ref->next;
85 new_ref->next = *ref;
87 if (new_ref->next)
89 gfc_ref *next = NULL;
91 /* We need to update the base type in the trailing reference chain to
92 that of the new component. */
94 gcc_assert (strcmp (name, "_data") == 0);
96 if (new_ref->next->type == REF_COMPONENT)
97 next = new_ref->next;
98 else if (new_ref->next->type == REF_ARRAY
99 && new_ref->next->next
100 && new_ref->next->next->type == REF_COMPONENT)
101 next = new_ref->next->next;
103 if (next != NULL)
105 gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
106 || new_ref->u.c.component->ts.type == BT_DERIVED);
107 next->u.c.sym = new_ref->u.c.component->ts.u.derived;
111 *ref = new_ref;
115 /* Tells whether we need to add a "_data" reference to access REF subobject
116 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base
117 object accessed by REF is a variable; in other words it is a full object,
118 not a subobject. */
120 static bool
121 class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain)
123 /* Only class containers may need the "_data" reference. */
124 if (ts->type != BT_CLASS)
125 return false;
127 /* Accessing a class container with an array reference is certainly wrong. */
128 if (ref->type != REF_COMPONENT)
129 return true;
131 /* Accessing the class container's fields is fine. */
132 if (ref->u.c.component->name[0] == '_')
133 return false;
135 /* At this point we have a class container with a non class container's field
136 component reference. We don't want to add the "_data" component if we are
137 at the first reference and the symbol's type is an extended derived type.
138 In that case, conv_parent_component_references will do the right thing so
139 it is not absolutely necessary. Omitting it prevents a regression (see
140 class_41.f03) in the interface mapping mechanism. When evaluating string
141 lengths depending on dummy arguments, we create a fake symbol with a type
142 equal to that of the dummy type. However, because of type extension,
143 the backend type (corresponding to the actual argument) can have a
144 different (extended) type. Adding the "_data" component explicitly, using
145 the base type, confuses the gfc_conv_component_ref code which deals with
146 the extended type. */
147 if (first_ref_in_chain && ts->u.derived->attr.extension)
148 return false;
150 /* We have a class container with a non class container's field component
151 reference that doesn't fall into the above. */
152 return true;
156 /* Browse through a data reference chain and add the missing "_data" references
157 when a subobject of a class object is accessed without it.
158 Note that it doesn't add the "_data" reference when the class container
159 is the last element in the reference chain. */
161 void
162 gfc_fix_class_refs (gfc_expr *e)
164 gfc_typespec *ts;
165 gfc_ref **ref;
167 if ((e->expr_type != EXPR_VARIABLE
168 && e->expr_type != EXPR_FUNCTION)
169 || (e->expr_type == EXPR_FUNCTION
170 && e->value.function.isym != NULL))
171 return;
173 if (e->expr_type == EXPR_VARIABLE)
174 ts = &e->symtree->n.sym->ts;
175 else
177 gfc_symbol *func;
179 gcc_assert (e->expr_type == EXPR_FUNCTION);
180 if (e->value.function.esym != NULL)
181 func = e->value.function.esym;
182 else
183 func = e->symtree->n.sym;
185 if (func->result != NULL)
186 ts = &func->result->ts;
187 else
188 ts = &func->ts;
191 for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
193 if (class_data_ref_missing (ts, *ref, ref == &e->ref))
194 insert_component_ref (ts, ref, "_data");
196 if ((*ref)->type == REF_COMPONENT)
197 ts = &(*ref)->u.c.component->ts;
202 /* Insert a reference to the component of the given name.
203 Only to be used with CLASS containers and vtables. */
205 void
206 gfc_add_component_ref (gfc_expr *e, const char *name)
208 gfc_component *c;
209 gfc_ref **tail = &(e->ref);
210 gfc_ref *ref, *next = NULL;
211 gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
212 while (*tail != NULL)
214 if ((*tail)->type == REF_COMPONENT)
216 if (strcmp ((*tail)->u.c.component->name, "_data") == 0
217 && (*tail)->next
218 && (*tail)->next->type == REF_ARRAY
219 && (*tail)->next->next == NULL)
220 return;
221 derived = (*tail)->u.c.component->ts.u.derived;
223 if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
224 break;
225 tail = &((*tail)->next);
227 if (derived->components && derived->components->next &&
228 derived->components->next->ts.type == BT_DERIVED &&
229 derived->components->next->ts.u.derived == NULL)
231 /* Fix up missing vtype. */
232 gfc_symbol *vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
233 gcc_assert (vtab);
234 derived->components->next->ts.u.derived = vtab->ts.u.derived;
236 if (*tail != NULL && strcmp (name, "_data") == 0)
237 next = *tail;
238 else
239 /* Avoid losing memory. */
240 gfc_free_ref_list (*tail);
241 c = gfc_find_component (derived, name, true, true, tail);
243 if (c) {
244 for (ref = *tail; ref->next; ref = ref->next)
246 ref->next = next;
247 if (!next)
248 e->ts = c->ts;
253 /* This is used to add both the _data component reference and an array
254 reference to class expressions. Used in translation of intrinsic
255 array inquiry functions. */
257 void
258 gfc_add_class_array_ref (gfc_expr *e)
260 int rank = CLASS_DATA (e)->as->rank;
261 gfc_array_spec *as = CLASS_DATA (e)->as;
262 gfc_ref *ref = NULL;
263 gfc_add_data_component (e);
264 e->rank = rank;
265 for (ref = e->ref; ref; ref = ref->next)
266 if (!ref->next)
267 break;
268 if (ref->type != REF_ARRAY)
270 ref->next = gfc_get_ref ();
271 ref = ref->next;
272 ref->type = REF_ARRAY;
273 ref->u.ar.type = AR_FULL;
274 ref->u.ar.as = as;
279 /* Unfortunately, class array expressions can appear in various conditions;
280 with and without both _data component and an arrayspec. This function
281 deals with that variability. The previous reference to 'ref' is to a
282 class array. */
284 static bool
285 class_array_ref_detected (gfc_ref *ref, bool *full_array)
287 bool no_data = false;
288 bool with_data = false;
290 /* An array reference with no _data component. */
291 if (ref && ref->type == REF_ARRAY
292 && !ref->next
293 && ref->u.ar.type != AR_ELEMENT)
295 if (full_array)
296 *full_array = ref->u.ar.type == AR_FULL;
297 no_data = true;
300 /* Cover cases where _data appears, with or without an array ref. */
301 if (ref && ref->type == REF_COMPONENT
302 && strcmp (ref->u.c.component->name, "_data") == 0)
304 if (!ref->next)
306 with_data = true;
307 if (full_array)
308 *full_array = true;
310 else if (ref->next && ref->next->type == REF_ARRAY
311 && !ref->next->next
312 && ref->type == REF_COMPONENT
313 && ref->next->u.ar.type != AR_ELEMENT)
315 with_data = true;
316 if (full_array)
317 *full_array = ref->next->u.ar.type == AR_FULL;
321 return no_data || with_data;
325 /* Returns true if the expression contains a reference to a class
326 array. Notice that class array elements return false. */
328 bool
329 gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
331 gfc_ref *ref;
333 if (!e->rank)
334 return false;
336 if (full_array)
337 *full_array= false;
339 /* Is this a class array object? ie. Is the symbol of type class? */
340 if (e->symtree
341 && e->symtree->n.sym->ts.type == BT_CLASS
342 && CLASS_DATA (e->symtree->n.sym)
343 && CLASS_DATA (e->symtree->n.sym)->attr.dimension
344 && class_array_ref_detected (e->ref, full_array))
345 return true;
347 /* Or is this a class array component reference? */
348 for (ref = e->ref; ref; ref = ref->next)
350 if (ref->type == REF_COMPONENT
351 && ref->u.c.component->ts.type == BT_CLASS
352 && CLASS_DATA (ref->u.c.component)->attr.dimension
353 && class_array_ref_detected (ref->next, full_array))
354 return true;
357 return false;
361 /* Returns true if the expression is a reference to a class
362 scalar. This function is necessary because such expressions
363 can be dressed with a reference to the _data component and so
364 have a type other than BT_CLASS. */
366 bool
367 gfc_is_class_scalar_expr (gfc_expr *e)
369 gfc_ref *ref;
371 if (e->rank)
372 return false;
374 /* Is this a class object? */
375 if (e->symtree
376 && e->symtree->n.sym->ts.type == BT_CLASS
377 && CLASS_DATA (e->symtree->n.sym)
378 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
379 && (e->ref == NULL
380 || (e->ref->type == REF_COMPONENT
381 && strcmp (e->ref->u.c.component->name, "_data") == 0
382 && e->ref->next == NULL)))
383 return true;
385 /* Or is the final reference BT_CLASS or _data? */
386 for (ref = e->ref; ref; ref = ref->next)
388 if (ref->type == REF_COMPONENT
389 && ref->u.c.component->ts.type == BT_CLASS
390 && CLASS_DATA (ref->u.c.component)
391 && !CLASS_DATA (ref->u.c.component)->attr.dimension
392 && (ref->next == NULL
393 || (ref->next->type == REF_COMPONENT
394 && strcmp (ref->next->u.c.component->name, "_data") == 0
395 && ref->next->next == NULL)))
396 return true;
399 return false;
403 /* Tells whether the expression E is a reference to a (scalar) class container.
404 Scalar because array class containers usually have an array reference after
405 them, and gfc_fix_class_refs will add the missing "_data" component reference
406 in that case. */
408 bool
409 gfc_is_class_container_ref (gfc_expr *e)
411 gfc_ref *ref;
412 bool result;
414 if (e->expr_type != EXPR_VARIABLE)
415 return e->ts.type == BT_CLASS;
417 if (e->symtree->n.sym->ts.type == BT_CLASS)
418 result = true;
419 else
420 result = false;
422 for (ref = e->ref; ref; ref = ref->next)
424 if (ref->type != REF_COMPONENT)
425 result = false;
426 else if (ref->u.c.component->ts.type == BT_CLASS)
427 result = true;
428 else
429 result = false;
432 return result;
436 /* Build an initializer for CLASS pointers,
437 initializing the _data component to the init_expr (or NULL) and the _vptr
438 component to the corresponding type (or the declared type, given by ts). */
440 gfc_expr *
441 gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
443 gfc_expr *init;
444 gfc_component *comp;
445 gfc_symbol *vtab = NULL;
447 if (init_expr && init_expr->expr_type != EXPR_NULL)
448 vtab = gfc_find_vtab (&init_expr->ts);
449 else
450 vtab = gfc_find_vtab (ts);
452 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
453 &ts->u.derived->declared_at);
454 init->ts = *ts;
456 for (comp = ts->u.derived->components; comp; comp = comp->next)
458 gfc_constructor *ctor = gfc_constructor_get();
459 if (strcmp (comp->name, "_vptr") == 0 && vtab)
460 ctor->expr = gfc_lval_expr_from_sym (vtab);
461 else if (init_expr && init_expr->expr_type != EXPR_NULL)
462 ctor->expr = gfc_copy_expr (init_expr);
463 else
464 ctor->expr = gfc_get_null_expr (NULL);
465 gfc_constructor_append (&init->value.constructor, ctor);
468 return init;
472 /* Create a unique string identifier for a derived type, composed of its name
473 and module name. This is used to construct unique names for the class
474 containers and vtab symbols. */
476 static void
477 get_unique_type_string (char *string, gfc_symbol *derived)
479 char dt_name[GFC_MAX_SYMBOL_LEN+1];
480 if (derived->attr.unlimited_polymorphic)
481 strcpy (dt_name, "STAR");
482 else
483 strcpy (dt_name, gfc_dt_upper_string (derived->name));
484 if (derived->attr.unlimited_polymorphic)
485 sprintf (string, "_%s", dt_name);
486 else if (derived->module)
487 sprintf (string, "%s_%s", derived->module, dt_name);
488 else if (derived->ns->proc_name)
489 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
490 else
491 sprintf (string, "_%s", dt_name);
495 /* A relative of 'get_unique_type_string' which makes sure the generated
496 string will not be too long (replacing it by a hash string if needed). */
498 static void
499 get_unique_hashed_string (char *string, gfc_symbol *derived)
501 char tmp[2*GFC_MAX_SYMBOL_LEN+2];
502 get_unique_type_string (&tmp[0], derived);
503 /* If string is too long, use hash value in hex representation (allow for
504 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
505 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
506 where %d is the (co)rank which can be up to n = 15. */
507 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
509 int h = gfc_hash_value (derived);
510 sprintf (string, "%X", h);
512 else
513 strcpy (string, tmp);
517 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
519 unsigned int
520 gfc_hash_value (gfc_symbol *sym)
522 unsigned int hash = 0;
523 char c[2*(GFC_MAX_SYMBOL_LEN+1)];
524 int i, len;
526 get_unique_type_string (&c[0], sym);
527 len = strlen (c);
529 for (i = 0; i < len; i++)
530 hash = (hash << 6) + (hash << 16) - hash + c[i];
532 /* Return the hash but take the modulus for the sake of module read,
533 even though this slightly increases the chance of collision. */
534 return (hash % 100000000);
538 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
540 unsigned int
541 gfc_intrinsic_hash_value (gfc_typespec *ts)
543 unsigned int hash = 0;
544 const char *c = gfc_typename (ts);
545 int i, len;
547 len = strlen (c);
549 for (i = 0; i < len; i++)
550 hash = (hash << 6) + (hash << 16) - hash + c[i];
552 /* Return the hash but take the modulus for the sake of module read,
553 even though this slightly increases the chance of collision. */
554 return (hash % 100000000);
558 /* Get the _len component from a class/derived object storing a string.
559 For unlimited polymorphic entities a ref to the _data component is available
560 while a ref to the _len component is needed. This routine traverese the
561 ref-chain and strips the last ref to a _data from it replacing it with a
562 ref to the _len component. */
564 gfc_expr *
565 gfc_get_len_component (gfc_expr *e)
567 gfc_expr *ptr;
568 gfc_ref *ref, **last;
570 ptr = gfc_copy_expr (e);
572 /* We need to remove the last _data component ref from ptr. */
573 last = &(ptr->ref);
574 ref = ptr->ref;
575 while (ref)
577 if (!ref->next
578 && ref->type == REF_COMPONENT
579 && strcmp ("_data", ref->u.c.component->name)== 0)
581 gfc_free_ref_list (ref);
582 *last = NULL;
583 break;
585 last = &(ref->next);
586 ref = ref->next;
588 /* And replace if with a ref to the _len component. */
589 gfc_add_len_component (ptr);
590 return ptr;
594 /* Build a polymorphic CLASS entity, using the symbol that comes from
595 build_sym. A CLASS entity is represented by an encapsulating type,
596 which contains the declared type as '_data' component, plus a pointer
597 component '_vptr' which determines the dynamic type. When this CLASS
598 entity is unlimited polymorphic, then also add a component '_len' to
599 store the length of string when that is stored in it. */
601 bool
602 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
603 gfc_array_spec **as)
605 char tname[GFC_MAX_SYMBOL_LEN+1];
606 char *name;
607 gfc_symbol *fclass;
608 gfc_symbol *vtab;
609 gfc_component *c;
610 gfc_namespace *ns;
611 int rank;
613 gcc_assert (as);
615 if (*as && (*as)->type == AS_ASSUMED_SIZE)
617 gfc_error ("Assumed size polymorphic objects or components, such "
618 "as that at %C, have not yet been implemented");
619 return false;
622 if (attr->class_ok)
623 /* Class container has already been built. */
624 return true;
626 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
627 || attr->select_type_temporary || attr->associate_var;
629 if (!attr->class_ok)
630 /* We can not build the class container yet. */
631 return true;
633 /* Determine the name of the encapsulating type. */
634 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
635 get_unique_hashed_string (tname, ts->u.derived);
636 if ((*as) && attr->allocatable)
637 name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
638 else if ((*as) && attr->pointer)
639 name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
640 else if ((*as))
641 name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
642 else if (attr->pointer)
643 name = xasprintf ("__class_%s_p", tname);
644 else if (attr->allocatable)
645 name = xasprintf ("__class_%s_a", tname);
646 else
647 name = xasprintf ("__class_%s_t", tname);
649 if (ts->u.derived->attr.unlimited_polymorphic)
651 /* Find the top-level namespace. */
652 for (ns = gfc_current_ns; ns; ns = ns->parent)
653 if (!ns->parent)
654 break;
656 else
657 ns = ts->u.derived->ns;
659 gfc_find_symbol (name, ns, 0, &fclass);
660 if (fclass == NULL)
662 gfc_symtree *st;
663 /* If not there, create a new symbol. */
664 fclass = gfc_new_symbol (name, ns);
665 st = gfc_new_symtree (&ns->sym_root, name);
666 st->n.sym = fclass;
667 gfc_set_sym_referenced (fclass);
668 fclass->refs++;
669 fclass->ts.type = BT_UNKNOWN;
670 if (!ts->u.derived->attr.unlimited_polymorphic)
671 fclass->attr.abstract = ts->u.derived->attr.abstract;
672 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
673 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
674 &gfc_current_locus))
675 return false;
677 /* Add component '_data'. */
678 if (!gfc_add_component (fclass, "_data", &c))
679 return false;
680 c->ts = *ts;
681 c->ts.type = BT_DERIVED;
682 c->attr.access = ACCESS_PRIVATE;
683 c->ts.u.derived = ts->u.derived;
684 c->attr.class_pointer = attr->pointer;
685 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
686 || attr->select_type_temporary;
687 c->attr.allocatable = attr->allocatable;
688 c->attr.dimension = attr->dimension;
689 c->attr.codimension = attr->codimension;
690 c->attr.abstract = fclass->attr.abstract;
691 c->as = (*as);
692 c->initializer = NULL;
694 /* Add component '_vptr'. */
695 if (!gfc_add_component (fclass, "_vptr", &c))
696 return false;
697 c->ts.type = BT_DERIVED;
698 c->attr.access = ACCESS_PRIVATE;
699 c->attr.pointer = 1;
701 if (ts->u.derived->attr.unlimited_polymorphic)
703 vtab = gfc_find_derived_vtab (ts->u.derived);
704 gcc_assert (vtab);
705 c->ts.u.derived = vtab->ts.u.derived;
707 /* Add component '_len'. Only unlimited polymorphic pointers may
708 have a string assigned to them, i.e., only those need the _len
709 component. */
710 if (!gfc_add_component (fclass, "_len", &c))
711 return false;
712 c->ts.type = BT_INTEGER;
713 c->ts.kind = gfc_charlen_int_kind;
714 c->attr.access = ACCESS_PRIVATE;
715 c->attr.artificial = 1;
717 else
718 /* Build vtab later. */
719 c->ts.u.derived = NULL;
722 if (!ts->u.derived->attr.unlimited_polymorphic)
724 /* Since the extension field is 8 bit wide, we can only have
725 up to 255 extension levels. */
726 if (ts->u.derived->attr.extension == 255)
728 gfc_error ("Maximum extension level reached with type %qs at %L",
729 ts->u.derived->name, &ts->u.derived->declared_at);
730 return false;
733 fclass->attr.extension = ts->u.derived->attr.extension + 1;
734 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
735 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
738 fclass->attr.is_class = 1;
739 ts->u.derived = fclass;
740 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
741 (*as) = NULL;
742 free (name);
743 return true;
747 /* Add a procedure pointer component to the vtype
748 to represent a specific type-bound procedure. */
750 static void
751 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
753 gfc_component *c;
755 if (tb->non_overridable && !tb->overridden)
756 return;
758 c = gfc_find_component (vtype, name, true, true, NULL);
760 if (c == NULL)
762 /* Add procedure component. */
763 if (!gfc_add_component (vtype, name, &c))
764 return;
766 if (!c->tb)
767 c->tb = XCNEW (gfc_typebound_proc);
768 *c->tb = *tb;
769 c->tb->ppc = 1;
770 c->attr.procedure = 1;
771 c->attr.proc_pointer = 1;
772 c->attr.flavor = FL_PROCEDURE;
773 c->attr.access = ACCESS_PRIVATE;
774 c->attr.external = 1;
775 c->attr.untyped = 1;
776 c->attr.if_source = IFSRC_IFBODY;
778 else if (c->attr.proc_pointer && c->tb)
780 *c->tb = *tb;
781 c->tb->ppc = 1;
784 if (tb->u.specific)
786 gfc_symbol *ifc = tb->u.specific->n.sym;
787 c->ts.interface = ifc;
788 if (!tb->deferred)
789 c->initializer = gfc_get_variable_expr (tb->u.specific);
790 c->attr.pure = ifc->attr.pure;
795 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
797 static void
798 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
800 if (!st)
801 return;
803 if (st->left)
804 add_procs_to_declared_vtab1 (st->left, vtype);
806 if (st->right)
807 add_procs_to_declared_vtab1 (st->right, vtype);
809 if (st->n.tb && !st->n.tb->error
810 && !st->n.tb->is_generic && st->n.tb->u.specific)
811 add_proc_comp (vtype, st->name, st->n.tb);
815 /* Copy procedure pointers components from the parent type. */
817 static void
818 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
820 gfc_component *cmp;
821 gfc_symbol *vtab;
823 vtab = gfc_find_derived_vtab (declared);
825 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
827 if (gfc_find_component (vtype, cmp->name, true, true, NULL))
828 continue;
830 add_proc_comp (vtype, cmp->name, cmp->tb);
835 /* Returns true if any of its nonpointer nonallocatable components or
836 their nonpointer nonallocatable subcomponents has a finalization
837 subroutine. */
839 static bool
840 has_finalizer_component (gfc_symbol *derived)
842 gfc_component *c;
844 for (c = derived->components; c; c = c->next)
845 if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable)
847 if (c->ts.u.derived->f2k_derived
848 && c->ts.u.derived->f2k_derived->finalizers)
849 return true;
851 /* Stop infinite recursion through this function by inhibiting
852 calls when the derived type and that of the component are
853 the same. */
854 if (!gfc_compare_derived_types (derived, c->ts.u.derived)
855 && has_finalizer_component (c->ts.u.derived))
856 return true;
858 return false;
862 static bool
863 comp_is_finalizable (gfc_component *comp)
865 if (comp->attr.proc_pointer)
866 return false;
867 else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
868 return true;
869 else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
870 && (comp->ts.u.derived->attr.alloc_comp
871 || has_finalizer_component (comp->ts.u.derived)
872 || (comp->ts.u.derived->f2k_derived
873 && comp->ts.u.derived->f2k_derived->finalizers)))
874 return true;
875 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
876 && CLASS_DATA (comp)->attr.allocatable)
877 return true;
878 else
879 return false;
883 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
884 neither allocatable nor a pointer but has a finalizer, call it. If it
885 is a nonpointer component with allocatable components or has finalizers, walk
886 them. Either of them is required; other nonallocatables and pointers aren't
887 handled gracefully.
888 Note: If the component is allocatable, the DEALLOCATE handling takes care
889 of calling the appropriate finalizers, coarray deregistering, and
890 deallocation of allocatable subcomponents. */
892 static void
893 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
894 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
895 gfc_namespace *sub_ns)
897 gfc_expr *e;
898 gfc_ref *ref;
900 if (!comp_is_finalizable (comp))
901 return;
903 e = gfc_copy_expr (expr);
904 if (!e->ref)
905 e->ref = ref = gfc_get_ref ();
906 else
908 for (ref = e->ref; ref->next; ref = ref->next)
910 ref->next = gfc_get_ref ();
911 ref = ref->next;
913 ref->type = REF_COMPONENT;
914 ref->u.c.sym = derived;
915 ref->u.c.component = comp;
916 e->ts = comp->ts;
918 if (comp->attr.dimension || comp->attr.codimension
919 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
920 && (CLASS_DATA (comp)->attr.dimension
921 || CLASS_DATA (comp)->attr.codimension)))
923 ref->next = gfc_get_ref ();
924 ref->next->type = REF_ARRAY;
925 ref->next->u.ar.dimen = 0;
926 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
927 : comp->as;
928 e->rank = ref->next->u.ar.as->rank;
929 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
932 /* Call DEALLOCATE (comp, stat=ignore). */
933 if (comp->attr.allocatable
934 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
935 && CLASS_DATA (comp)->attr.allocatable))
937 gfc_code *dealloc, *block = NULL;
939 /* Add IF (fini_coarray). */
940 if (comp->attr.codimension
941 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
942 && CLASS_DATA (comp)->attr.codimension))
944 block = gfc_get_code (EXEC_IF);
945 if (*code)
947 (*code)->next = block;
948 (*code) = (*code)->next;
950 else
951 (*code) = block;
953 block->block = gfc_get_code (EXEC_IF);
954 block = block->block;
955 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
958 dealloc = gfc_get_code (EXEC_DEALLOCATE);
960 dealloc->ext.alloc.list = gfc_get_alloc ();
961 dealloc->ext.alloc.list->expr = e;
962 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
964 gfc_code *cond = gfc_get_code (EXEC_IF);
965 cond->block = gfc_get_code (EXEC_IF);
966 cond->block->expr1 = gfc_get_expr ();
967 cond->block->expr1->expr_type = EXPR_FUNCTION;
968 cond->block->expr1->where = gfc_current_locus;
969 gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
970 cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
971 cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
972 cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
973 gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
974 cond->block->expr1->ts.type = BT_LOGICAL;
975 cond->block->expr1->ts.kind = gfc_default_logical_kind;
976 cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
977 cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
978 cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
979 cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
980 cond->block->next = dealloc;
982 if (block)
983 block->next = cond;
984 else if (*code)
986 (*code)->next = cond;
987 (*code) = (*code)->next;
989 else
990 (*code) = cond;
992 else if (comp->ts.type == BT_DERIVED
993 && comp->ts.u.derived->f2k_derived
994 && comp->ts.u.derived->f2k_derived->finalizers)
996 /* Call FINAL_WRAPPER (comp); */
997 gfc_code *final_wrap;
998 gfc_symbol *vtab;
999 gfc_component *c;
1001 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
1002 for (c = vtab->ts.u.derived->components; c; c = c->next)
1003 if (strcmp (c->name, "_final") == 0)
1004 break;
1006 gcc_assert (c);
1007 final_wrap = gfc_get_code (EXEC_CALL);
1008 final_wrap->symtree = c->initializer->symtree;
1009 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
1010 final_wrap->ext.actual = gfc_get_actual_arglist ();
1011 final_wrap->ext.actual->expr = e;
1013 if (*code)
1015 (*code)->next = final_wrap;
1016 (*code) = (*code)->next;
1018 else
1019 (*code) = final_wrap;
1021 else
1023 gfc_component *c;
1025 for (c = comp->ts.u.derived->components; c; c = c->next)
1026 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code,
1027 sub_ns);
1028 gfc_free_expr (e);
1033 /* Generate code equivalent to
1034 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1035 + offset, c_ptr), ptr). */
1037 static gfc_code *
1038 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
1039 gfc_expr *offset, gfc_namespace *sub_ns)
1041 gfc_code *block;
1042 gfc_expr *expr, *expr2;
1044 /* C_F_POINTER(). */
1045 block = gfc_get_code (EXEC_CALL);
1046 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
1047 block->resolved_sym = block->symtree->n.sym;
1048 block->resolved_sym->attr.flavor = FL_PROCEDURE;
1049 block->resolved_sym->attr.intrinsic = 1;
1050 block->resolved_sym->attr.subroutine = 1;
1051 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
1052 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
1053 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
1054 gfc_commit_symbol (block->resolved_sym);
1056 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
1057 block->ext.actual = gfc_get_actual_arglist ();
1058 block->ext.actual->next = gfc_get_actual_arglist ();
1059 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
1060 NULL, 0);
1061 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
1063 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
1065 /* TRANSFER's first argument: C_LOC (array). */
1066 expr = gfc_get_expr ();
1067 expr->expr_type = EXPR_FUNCTION;
1068 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
1069 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1070 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
1071 expr->symtree->n.sym->attr.intrinsic = 1;
1072 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
1073 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
1074 expr->value.function.actual = gfc_get_actual_arglist ();
1075 expr->value.function.actual->expr
1076 = gfc_lval_expr_from_sym (array);
1077 expr->symtree->n.sym->result = expr->symtree->n.sym;
1078 gfc_commit_symbol (expr->symtree->n.sym);
1079 expr->ts.type = BT_INTEGER;
1080 expr->ts.kind = gfc_index_integer_kind;
1081 expr->where = gfc_current_locus;
1083 /* TRANSFER. */
1084 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
1085 gfc_current_locus, 3, expr,
1086 gfc_get_int_expr (gfc_index_integer_kind,
1087 NULL, 0), NULL);
1088 expr2->ts.type = BT_INTEGER;
1089 expr2->ts.kind = gfc_index_integer_kind;
1091 /* <array addr> + <offset>. */
1092 block->ext.actual->expr = gfc_get_expr ();
1093 block->ext.actual->expr->expr_type = EXPR_OP;
1094 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
1095 block->ext.actual->expr->value.op.op1 = expr2;
1096 block->ext.actual->expr->value.op.op2 = offset;
1097 block->ext.actual->expr->ts = expr->ts;
1098 block->ext.actual->expr->where = gfc_current_locus;
1100 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1101 block->ext.actual->next = gfc_get_actual_arglist ();
1102 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1103 block->ext.actual->next->next = gfc_get_actual_arglist ();
1105 return block;
1109 /* Calculates the offset to the (idx+1)th element of an array, taking the
1110 stride into account. It generates the code:
1111 offset = 0
1112 do idx2 = 1, rank
1113 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1114 end do
1115 offset = offset * byte_stride. */
1117 static gfc_code*
1118 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1119 gfc_symbol *strides, gfc_symbol *sizes,
1120 gfc_symbol *byte_stride, gfc_expr *rank,
1121 gfc_code *block, gfc_namespace *sub_ns)
1123 gfc_iterator *iter;
1124 gfc_expr *expr, *expr2;
1126 /* offset = 0. */
1127 block->next = gfc_get_code (EXEC_ASSIGN);
1128 block = block->next;
1129 block->expr1 = gfc_lval_expr_from_sym (offset);
1130 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1132 /* Create loop. */
1133 iter = gfc_get_iterator ();
1134 iter->var = gfc_lval_expr_from_sym (idx2);
1135 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1136 iter->end = gfc_copy_expr (rank);
1137 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1138 block->next = gfc_get_code (EXEC_DO);
1139 block = block->next;
1140 block->ext.iterator = iter;
1141 block->block = gfc_get_code (EXEC_DO);
1143 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1144 * strides(idx2). */
1146 /* mod (idx, sizes(idx2)). */
1147 expr = gfc_lval_expr_from_sym (sizes);
1148 expr->ref = gfc_get_ref ();
1149 expr->ref->type = REF_ARRAY;
1150 expr->ref->u.ar.as = sizes->as;
1151 expr->ref->u.ar.type = AR_ELEMENT;
1152 expr->ref->u.ar.dimen = 1;
1153 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1154 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1155 expr->where = sizes->declared_at;
1157 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1158 gfc_current_locus, 2,
1159 gfc_lval_expr_from_sym (idx), expr);
1160 expr->ts = idx->ts;
1162 /* (...) / sizes(idx2-1). */
1163 expr2 = gfc_get_expr ();
1164 expr2->expr_type = EXPR_OP;
1165 expr2->value.op.op = INTRINSIC_DIVIDE;
1166 expr2->value.op.op1 = expr;
1167 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1168 expr2->value.op.op2->ref = gfc_get_ref ();
1169 expr2->value.op.op2->ref->type = REF_ARRAY;
1170 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1171 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1172 expr2->value.op.op2->ref->u.ar.dimen = 1;
1173 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1174 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1175 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1176 expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1177 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1178 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1179 = gfc_lval_expr_from_sym (idx2);
1180 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1181 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1182 expr2->value.op.op2->ref->u.ar.start[0]->ts
1183 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1184 expr2->ts = idx->ts;
1185 expr2->where = gfc_current_locus;
1187 /* ... * strides(idx2). */
1188 expr = gfc_get_expr ();
1189 expr->expr_type = EXPR_OP;
1190 expr->value.op.op = INTRINSIC_TIMES;
1191 expr->value.op.op1 = expr2;
1192 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1193 expr->value.op.op2->ref = gfc_get_ref ();
1194 expr->value.op.op2->ref->type = REF_ARRAY;
1195 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1196 expr->value.op.op2->ref->u.ar.dimen = 1;
1197 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1198 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1199 expr->value.op.op2->ref->u.ar.as = strides->as;
1200 expr->ts = idx->ts;
1201 expr->where = gfc_current_locus;
1203 /* offset = offset + ... */
1204 block->block->next = gfc_get_code (EXEC_ASSIGN);
1205 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1206 block->block->next->expr2 = gfc_get_expr ();
1207 block->block->next->expr2->expr_type = EXPR_OP;
1208 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1209 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1210 block->block->next->expr2->value.op.op2 = expr;
1211 block->block->next->expr2->ts = idx->ts;
1212 block->block->next->expr2->where = gfc_current_locus;
1214 /* After the loop: offset = offset * byte_stride. */
1215 block->next = gfc_get_code (EXEC_ASSIGN);
1216 block = block->next;
1217 block->expr1 = gfc_lval_expr_from_sym (offset);
1218 block->expr2 = gfc_get_expr ();
1219 block->expr2->expr_type = EXPR_OP;
1220 block->expr2->value.op.op = INTRINSIC_TIMES;
1221 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1222 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1223 block->expr2->ts = block->expr2->value.op.op1->ts;
1224 block->expr2->where = gfc_current_locus;
1225 return block;
1229 /* Insert code of the following form:
1231 block
1232 integer(c_intptr_t) :: i
1234 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1235 && (is_contiguous || !final_rank3->attr.contiguous
1236 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1237 || 0 == STORAGE_SIZE (array)) then
1238 call final_rank3 (array)
1239 else
1240 block
1241 integer(c_intptr_t) :: offset, j
1242 type(t) :: tmp(shape (array))
1244 do i = 0, size (array)-1
1245 offset = obtain_offset(i, strides, sizes, byte_stride)
1246 addr = transfer (c_loc (array), addr) + offset
1247 call c_f_pointer (transfer (addr, cptr), ptr)
1249 addr = transfer (c_loc (tmp), addr)
1250 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1251 call c_f_pointer (transfer (addr, cptr), ptr2)
1252 ptr2 = ptr
1253 end do
1254 call final_rank3 (tmp)
1255 end block
1256 end if
1257 block */
1259 static void
1260 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1261 gfc_symbol *array, gfc_symbol *byte_stride,
1262 gfc_symbol *idx, gfc_symbol *ptr,
1263 gfc_symbol *nelem,
1264 gfc_symbol *strides, gfc_symbol *sizes,
1265 gfc_symbol *idx2, gfc_symbol *offset,
1266 gfc_symbol *is_contiguous, gfc_expr *rank,
1267 gfc_namespace *sub_ns)
1269 gfc_symbol *tmp_array, *ptr2;
1270 gfc_expr *size_expr, *offset2, *expr;
1271 gfc_namespace *ns;
1272 gfc_iterator *iter;
1273 gfc_code *block2;
1274 int i;
1276 block->next = gfc_get_code (EXEC_IF);
1277 block = block->next;
1279 block->block = gfc_get_code (EXEC_IF);
1280 block = block->block;
1282 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1283 size_expr = gfc_get_expr ();
1284 size_expr->where = gfc_current_locus;
1285 size_expr->expr_type = EXPR_OP;
1286 size_expr->value.op.op = INTRINSIC_DIVIDE;
1288 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1289 size_expr->value.op.op1
1290 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1291 "storage_size", gfc_current_locus, 2,
1292 gfc_lval_expr_from_sym (array),
1293 gfc_get_int_expr (gfc_index_integer_kind,
1294 NULL, 0));
1296 /* NUMERIC_STORAGE_SIZE. */
1297 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1298 gfc_character_storage_size);
1299 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1300 size_expr->ts = size_expr->value.op.op1->ts;
1302 /* IF condition: (stride == size_expr
1303 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1304 || is_contiguous)
1305 || 0 == size_expr. */
1306 block->expr1 = gfc_get_expr ();
1307 block->expr1->ts.type = BT_LOGICAL;
1308 block->expr1->ts.kind = gfc_default_logical_kind;
1309 block->expr1->expr_type = EXPR_OP;
1310 block->expr1->where = gfc_current_locus;
1312 block->expr1->value.op.op = INTRINSIC_OR;
1314 /* byte_stride == size_expr */
1315 expr = gfc_get_expr ();
1316 expr->ts.type = BT_LOGICAL;
1317 expr->ts.kind = gfc_default_logical_kind;
1318 expr->expr_type = EXPR_OP;
1319 expr->where = gfc_current_locus;
1320 expr->value.op.op = INTRINSIC_EQ;
1321 expr->value.op.op1
1322 = gfc_lval_expr_from_sym (byte_stride);
1323 expr->value.op.op2 = size_expr;
1325 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1326 add is_contiguous check. */
1328 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1329 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1331 gfc_expr *expr2;
1332 expr2 = gfc_get_expr ();
1333 expr2->ts.type = BT_LOGICAL;
1334 expr2->ts.kind = gfc_default_logical_kind;
1335 expr2->expr_type = EXPR_OP;
1336 expr2->where = gfc_current_locus;
1337 expr2->value.op.op = INTRINSIC_AND;
1338 expr2->value.op.op1 = expr;
1339 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1340 expr = expr2;
1343 block->expr1->value.op.op1 = expr;
1345 /* 0 == size_expr */
1346 block->expr1->value.op.op2 = gfc_get_expr ();
1347 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1348 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1349 block->expr1->value.op.op2->expr_type = EXPR_OP;
1350 block->expr1->value.op.op2->where = gfc_current_locus;
1351 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1352 block->expr1->value.op.op2->value.op.op1 =
1353 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1354 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1356 /* IF body: call final subroutine. */
1357 block->next = gfc_get_code (EXEC_CALL);
1358 block->next->symtree = fini->proc_tree;
1359 block->next->resolved_sym = fini->proc_tree->n.sym;
1360 block->next->ext.actual = gfc_get_actual_arglist ();
1361 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1362 block->next->ext.actual->next = gfc_get_actual_arglist ();
1363 block->next->ext.actual->next->expr = gfc_copy_expr (size_expr);
1365 /* ELSE. */
1367 block->block = gfc_get_code (EXEC_IF);
1368 block = block->block;
1370 /* BLOCK ... END BLOCK. */
1371 block->next = gfc_get_code (EXEC_BLOCK);
1372 block = block->next;
1374 ns = gfc_build_block_ns (sub_ns);
1375 block->ext.block.ns = ns;
1376 block->ext.block.assoc = NULL;
1378 gfc_get_symbol ("ptr2", ns, &ptr2);
1379 ptr2->ts.type = BT_DERIVED;
1380 ptr2->ts.u.derived = array->ts.u.derived;
1381 ptr2->attr.flavor = FL_VARIABLE;
1382 ptr2->attr.pointer = 1;
1383 ptr2->attr.artificial = 1;
1384 gfc_set_sym_referenced (ptr2);
1385 gfc_commit_symbol (ptr2);
1387 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1388 tmp_array->ts.type = BT_DERIVED;
1389 tmp_array->ts.u.derived = array->ts.u.derived;
1390 tmp_array->attr.flavor = FL_VARIABLE;
1391 tmp_array->attr.dimension = 1;
1392 tmp_array->attr.artificial = 1;
1393 tmp_array->as = gfc_get_array_spec();
1394 tmp_array->attr.intent = INTENT_INOUT;
1395 tmp_array->as->type = AS_EXPLICIT;
1396 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1398 for (i = 0; i < tmp_array->as->rank; i++)
1400 gfc_expr *shape_expr;
1401 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1402 NULL, 1);
1403 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1404 shape_expr
1405 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1406 gfc_current_locus, 3,
1407 gfc_lval_expr_from_sym (array),
1408 gfc_get_int_expr (gfc_default_integer_kind,
1409 NULL, i+1),
1410 gfc_get_int_expr (gfc_default_integer_kind,
1411 NULL,
1412 gfc_index_integer_kind));
1413 shape_expr->ts.kind = gfc_index_integer_kind;
1414 tmp_array->as->upper[i] = shape_expr;
1416 gfc_set_sym_referenced (tmp_array);
1417 gfc_commit_symbol (tmp_array);
1419 /* Create loop. */
1420 iter = gfc_get_iterator ();
1421 iter->var = gfc_lval_expr_from_sym (idx);
1422 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1423 iter->end = gfc_lval_expr_from_sym (nelem);
1424 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1426 block = gfc_get_code (EXEC_DO);
1427 ns->code = block;
1428 block->ext.iterator = iter;
1429 block->block = gfc_get_code (EXEC_DO);
1431 /* Offset calculation for the new array: idx * size of type (in bytes). */
1432 offset2 = gfc_get_expr ();
1433 offset2->expr_type = EXPR_OP;
1434 offset2->where = gfc_current_locus;
1435 offset2->value.op.op = INTRINSIC_TIMES;
1436 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1437 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1438 offset2->ts = byte_stride->ts;
1440 /* Offset calculation of "array". */
1441 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1442 byte_stride, rank, block->block, sub_ns);
1444 /* Create code for
1445 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1446 + idx * stride, c_ptr), ptr). */
1447 block2->next = finalization_scalarizer (array, ptr,
1448 gfc_lval_expr_from_sym (offset),
1449 sub_ns);
1450 block2 = block2->next;
1451 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1452 block2 = block2->next;
1454 /* ptr2 = ptr. */
1455 block2->next = gfc_get_code (EXEC_ASSIGN);
1456 block2 = block2->next;
1457 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1458 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1460 /* Call now the user's final subroutine. */
1461 block->next = gfc_get_code (EXEC_CALL);
1462 block = block->next;
1463 block->symtree = fini->proc_tree;
1464 block->resolved_sym = fini->proc_tree->n.sym;
1465 block->ext.actual = gfc_get_actual_arglist ();
1466 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1468 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1469 return;
1471 /* Copy back. */
1473 /* 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->next = gfc_get_code (EXEC_DO);
1481 block = block->next;
1482 block->ext.iterator = iter;
1483 block->block = gfc_get_code (EXEC_DO);
1485 /* Offset calculation of "array". */
1486 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1487 byte_stride, rank, block->block, sub_ns);
1489 /* Create code for
1490 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1491 + offset, c_ptr), ptr). */
1492 block2->next = finalization_scalarizer (array, ptr,
1493 gfc_lval_expr_from_sym (offset),
1494 sub_ns);
1495 block2 = block2->next;
1496 block2->next = finalization_scalarizer (tmp_array, ptr2,
1497 gfc_copy_expr (offset2), sub_ns);
1498 block2 = block2->next;
1500 /* ptr = ptr2. */
1501 block2->next = gfc_get_code (EXEC_ASSIGN);
1502 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1503 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1507 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1508 derived type "derived". The function first calls the approriate FINAL
1509 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1510 components (but not the inherited ones). Last, it calls the wrapper
1511 subroutine of the parent. The generated wrapper procedure takes as argument
1512 an assumed-rank array.
1513 If neither allocatable components nor FINAL subroutines exists, the vtab
1514 will contain a NULL pointer.
1515 The generated function has the form
1516 _final(assumed-rank array, stride, skip_corarray)
1517 where the array has to be contiguous (except of the lowest dimension). The
1518 stride (in bytes) is used to allow different sizes for ancestor types by
1519 skipping over the additionally added components in the scalarizer. If
1520 "fini_coarray" is false, coarray components are not finalized to allow for
1521 the correct semantic with intrinsic assignment. */
1523 static void
1524 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1525 const char *tname, gfc_component *vtab_final)
1527 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1528 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1529 gfc_component *comp;
1530 gfc_namespace *sub_ns;
1531 gfc_code *last_code, *block;
1532 char *name;
1533 bool finalizable_comp = false;
1534 bool expr_null_wrapper = false;
1535 gfc_expr *ancestor_wrapper = NULL, *rank;
1536 gfc_iterator *iter;
1538 if (derived->attr.unlimited_polymorphic)
1540 vtab_final->initializer = gfc_get_null_expr (NULL);
1541 return;
1544 /* Search for the ancestor's finalizers. */
1545 if (derived->attr.extension && derived->components
1546 && (!derived->components->ts.u.derived->attr.abstract
1547 || has_finalizer_component (derived)))
1549 gfc_symbol *vtab;
1550 gfc_component *comp;
1552 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1553 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1554 if (comp->name[0] == '_' && comp->name[1] == 'f')
1556 ancestor_wrapper = comp->initializer;
1557 break;
1561 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1562 components: Return a NULL() expression; we defer this a bit to have have
1563 an interface declaration. */
1564 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1565 && !derived->attr.alloc_comp
1566 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1567 && !has_finalizer_component (derived))
1568 expr_null_wrapper = true;
1569 else
1570 /* Check whether there are new allocatable components. */
1571 for (comp = derived->components; comp; comp = comp->next)
1573 if (comp == derived->components && derived->attr.extension
1574 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1575 continue;
1577 finalizable_comp |= comp_is_finalizable (comp);
1580 /* If there is no new finalizer and no new allocatable, return with
1581 an expr to the ancestor's one. */
1582 if (!expr_null_wrapper && !finalizable_comp
1583 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1585 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1586 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1587 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1588 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1589 return;
1592 /* We now create a wrapper, which does the following:
1593 1. Call the suitable finalization subroutine for this type
1594 2. Loop over all noninherited allocatable components and noninherited
1595 components with allocatable components and DEALLOCATE those; this will
1596 take care of finalizers, coarray deregistering and allocatable
1597 nested components.
1598 3. Call the ancestor's finalizer. */
1600 /* Declare the wrapper function; it takes an assumed-rank array
1601 and a VALUE logical as arguments. */
1603 /* Set up the namespace. */
1604 sub_ns = gfc_get_namespace (ns, 0);
1605 sub_ns->sibling = ns->contained;
1606 if (!expr_null_wrapper)
1607 ns->contained = sub_ns;
1608 sub_ns->resolved = 1;
1610 /* Set up the procedure symbol. */
1611 name = xasprintf ("__final_%s", tname);
1612 gfc_get_symbol (name, sub_ns, &final);
1613 sub_ns->proc_name = final;
1614 final->attr.flavor = FL_PROCEDURE;
1615 final->attr.function = 1;
1616 final->attr.pure = 0;
1617 final->attr.recursive = 1;
1618 final->result = final;
1619 final->ts.type = BT_INTEGER;
1620 final->ts.kind = 4;
1621 final->attr.artificial = 1;
1622 final->attr.always_explicit = 1;
1623 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1624 if (ns->proc_name->attr.flavor == FL_MODULE)
1625 final->module = ns->proc_name->name;
1626 gfc_set_sym_referenced (final);
1627 gfc_commit_symbol (final);
1629 /* Set up formal argument. */
1630 gfc_get_symbol ("array", sub_ns, &array);
1631 array->ts.type = BT_DERIVED;
1632 array->ts.u.derived = derived;
1633 array->attr.flavor = FL_VARIABLE;
1634 array->attr.dummy = 1;
1635 array->attr.contiguous = 1;
1636 array->attr.dimension = 1;
1637 array->attr.artificial = 1;
1638 array->as = gfc_get_array_spec();
1639 array->as->type = AS_ASSUMED_RANK;
1640 array->as->rank = -1;
1641 array->attr.intent = INTENT_INOUT;
1642 gfc_set_sym_referenced (array);
1643 final->formal = gfc_get_formal_arglist ();
1644 final->formal->sym = array;
1645 gfc_commit_symbol (array);
1647 /* Set up formal argument. */
1648 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1649 byte_stride->ts.type = BT_INTEGER;
1650 byte_stride->ts.kind = gfc_index_integer_kind;
1651 byte_stride->attr.flavor = FL_VARIABLE;
1652 byte_stride->attr.dummy = 1;
1653 byte_stride->attr.value = 1;
1654 byte_stride->attr.artificial = 1;
1655 gfc_set_sym_referenced (byte_stride);
1656 final->formal->next = gfc_get_formal_arglist ();
1657 final->formal->next->sym = byte_stride;
1658 gfc_commit_symbol (byte_stride);
1660 /* Set up formal argument. */
1661 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1662 fini_coarray->ts.type = BT_LOGICAL;
1663 fini_coarray->ts.kind = 1;
1664 fini_coarray->attr.flavor = FL_VARIABLE;
1665 fini_coarray->attr.dummy = 1;
1666 fini_coarray->attr.value = 1;
1667 fini_coarray->attr.artificial = 1;
1668 gfc_set_sym_referenced (fini_coarray);
1669 final->formal->next->next = gfc_get_formal_arglist ();
1670 final->formal->next->next->sym = fini_coarray;
1671 gfc_commit_symbol (fini_coarray);
1673 /* Return with a NULL() expression but with an interface which has
1674 the formal arguments. */
1675 if (expr_null_wrapper)
1677 vtab_final->initializer = gfc_get_null_expr (NULL);
1678 vtab_final->ts.interface = final;
1679 return;
1682 /* Local variables. */
1684 gfc_get_symbol ("idx", sub_ns, &idx);
1685 idx->ts.type = BT_INTEGER;
1686 idx->ts.kind = gfc_index_integer_kind;
1687 idx->attr.flavor = FL_VARIABLE;
1688 idx->attr.artificial = 1;
1689 gfc_set_sym_referenced (idx);
1690 gfc_commit_symbol (idx);
1692 gfc_get_symbol ("idx2", sub_ns, &idx2);
1693 idx2->ts.type = BT_INTEGER;
1694 idx2->ts.kind = gfc_index_integer_kind;
1695 idx2->attr.flavor = FL_VARIABLE;
1696 idx2->attr.artificial = 1;
1697 gfc_set_sym_referenced (idx2);
1698 gfc_commit_symbol (idx2);
1700 gfc_get_symbol ("offset", sub_ns, &offset);
1701 offset->ts.type = BT_INTEGER;
1702 offset->ts.kind = gfc_index_integer_kind;
1703 offset->attr.flavor = FL_VARIABLE;
1704 offset->attr.artificial = 1;
1705 gfc_set_sym_referenced (offset);
1706 gfc_commit_symbol (offset);
1708 /* Create RANK expression. */
1709 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1710 gfc_current_locus, 1,
1711 gfc_lval_expr_from_sym (array));
1712 if (rank->ts.kind != idx->ts.kind)
1713 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1715 /* Create is_contiguous variable. */
1716 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1717 is_contiguous->ts.type = BT_LOGICAL;
1718 is_contiguous->ts.kind = gfc_default_logical_kind;
1719 is_contiguous->attr.flavor = FL_VARIABLE;
1720 is_contiguous->attr.artificial = 1;
1721 gfc_set_sym_referenced (is_contiguous);
1722 gfc_commit_symbol (is_contiguous);
1724 /* Create "sizes(0..rank)" variable, which contains the multiplied
1725 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1726 sizes(2) = sizes(1) * extent(dim=2) etc. */
1727 gfc_get_symbol ("sizes", sub_ns, &sizes);
1728 sizes->ts.type = BT_INTEGER;
1729 sizes->ts.kind = gfc_index_integer_kind;
1730 sizes->attr.flavor = FL_VARIABLE;
1731 sizes->attr.dimension = 1;
1732 sizes->attr.artificial = 1;
1733 sizes->as = gfc_get_array_spec();
1734 sizes->attr.intent = INTENT_INOUT;
1735 sizes->as->type = AS_EXPLICIT;
1736 sizes->as->rank = 1;
1737 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1738 sizes->as->upper[0] = gfc_copy_expr (rank);
1739 gfc_set_sym_referenced (sizes);
1740 gfc_commit_symbol (sizes);
1742 /* Create "strides(1..rank)" variable, which contains the strides per
1743 dimension. */
1744 gfc_get_symbol ("strides", sub_ns, &strides);
1745 strides->ts.type = BT_INTEGER;
1746 strides->ts.kind = gfc_index_integer_kind;
1747 strides->attr.flavor = FL_VARIABLE;
1748 strides->attr.dimension = 1;
1749 strides->attr.artificial = 1;
1750 strides->as = gfc_get_array_spec();
1751 strides->attr.intent = INTENT_INOUT;
1752 strides->as->type = AS_EXPLICIT;
1753 strides->as->rank = 1;
1754 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1755 strides->as->upper[0] = gfc_copy_expr (rank);
1756 gfc_set_sym_referenced (strides);
1757 gfc_commit_symbol (strides);
1760 /* Set return value to 0. */
1761 last_code = gfc_get_code (EXEC_ASSIGN);
1762 last_code->expr1 = gfc_lval_expr_from_sym (final);
1763 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1764 sub_ns->code = last_code;
1766 /* Set: is_contiguous = .true. */
1767 last_code->next = gfc_get_code (EXEC_ASSIGN);
1768 last_code = last_code->next;
1769 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1770 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1771 &gfc_current_locus, true);
1773 /* Set: sizes(0) = 1. */
1774 last_code->next = gfc_get_code (EXEC_ASSIGN);
1775 last_code = last_code->next;
1776 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1777 last_code->expr1->ref = gfc_get_ref ();
1778 last_code->expr1->ref->type = REF_ARRAY;
1779 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1780 last_code->expr1->ref->u.ar.dimen = 1;
1781 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1782 last_code->expr1->ref->u.ar.start[0]
1783 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1784 last_code->expr1->ref->u.ar.as = sizes->as;
1785 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1787 /* Create:
1788 DO idx = 1, rank
1789 strides(idx) = _F._stride (array, dim=idx)
1790 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1791 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1792 END DO. */
1794 /* Create loop. */
1795 iter = gfc_get_iterator ();
1796 iter->var = gfc_lval_expr_from_sym (idx);
1797 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1798 iter->end = gfc_copy_expr (rank);
1799 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1800 last_code->next = gfc_get_code (EXEC_DO);
1801 last_code = last_code->next;
1802 last_code->ext.iterator = iter;
1803 last_code->block = gfc_get_code (EXEC_DO);
1805 /* strides(idx) = _F._stride(array,dim=idx). */
1806 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1807 block = last_code->block->next;
1809 block->expr1 = gfc_lval_expr_from_sym (strides);
1810 block->expr1->ref = gfc_get_ref ();
1811 block->expr1->ref->type = REF_ARRAY;
1812 block->expr1->ref->u.ar.type = AR_ELEMENT;
1813 block->expr1->ref->u.ar.dimen = 1;
1814 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1815 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1816 block->expr1->ref->u.ar.as = strides->as;
1818 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1819 gfc_current_locus, 2,
1820 gfc_lval_expr_from_sym (array),
1821 gfc_lval_expr_from_sym (idx));
1823 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1824 block->next = gfc_get_code (EXEC_ASSIGN);
1825 block = block->next;
1827 /* sizes(idx) = ... */
1828 block->expr1 = gfc_lval_expr_from_sym (sizes);
1829 block->expr1->ref = gfc_get_ref ();
1830 block->expr1->ref->type = REF_ARRAY;
1831 block->expr1->ref->u.ar.type = AR_ELEMENT;
1832 block->expr1->ref->u.ar.dimen = 1;
1833 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1834 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1835 block->expr1->ref->u.ar.as = sizes->as;
1837 block->expr2 = gfc_get_expr ();
1838 block->expr2->expr_type = EXPR_OP;
1839 block->expr2->value.op.op = INTRINSIC_TIMES;
1840 block->expr2->where = gfc_current_locus;
1842 /* sizes(idx-1). */
1843 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1844 block->expr2->value.op.op1->ref = gfc_get_ref ();
1845 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1846 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1847 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1848 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1849 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1850 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1851 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1852 block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus;
1853 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1854 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1855 = gfc_lval_expr_from_sym (idx);
1856 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1857 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1858 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1859 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1861 /* size(array, dim=idx, kind=index_kind). */
1862 block->expr2->value.op.op2
1863 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1864 gfc_current_locus, 3,
1865 gfc_lval_expr_from_sym (array),
1866 gfc_lval_expr_from_sym (idx),
1867 gfc_get_int_expr (gfc_index_integer_kind,
1868 NULL,
1869 gfc_index_integer_kind));
1870 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1871 block->expr2->ts = idx->ts;
1873 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1874 block->next = gfc_get_code (EXEC_IF);
1875 block = block->next;
1877 block->block = gfc_get_code (EXEC_IF);
1878 block = block->block;
1880 /* if condition: strides(idx) /= sizes(idx-1). */
1881 block->expr1 = gfc_get_expr ();
1882 block->expr1->ts.type = BT_LOGICAL;
1883 block->expr1->ts.kind = gfc_default_logical_kind;
1884 block->expr1->expr_type = EXPR_OP;
1885 block->expr1->where = gfc_current_locus;
1886 block->expr1->value.op.op = INTRINSIC_NE;
1888 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1889 block->expr1->value.op.op1->ref = gfc_get_ref ();
1890 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1891 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1892 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1893 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1894 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1895 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1897 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1898 block->expr1->value.op.op2->ref = gfc_get_ref ();
1899 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1900 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1901 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1902 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1903 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1904 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1905 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1906 block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1907 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1908 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1909 = gfc_lval_expr_from_sym (idx);
1910 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1911 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1912 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1913 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1915 /* if body: is_contiguous = .false. */
1916 block->next = gfc_get_code (EXEC_ASSIGN);
1917 block = block->next;
1918 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1919 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1920 &gfc_current_locus, false);
1922 /* Obtain the size (number of elements) of "array" MINUS ONE,
1923 which is used in the scalarization. */
1924 gfc_get_symbol ("nelem", sub_ns, &nelem);
1925 nelem->ts.type = BT_INTEGER;
1926 nelem->ts.kind = gfc_index_integer_kind;
1927 nelem->attr.flavor = FL_VARIABLE;
1928 nelem->attr.artificial = 1;
1929 gfc_set_sym_referenced (nelem);
1930 gfc_commit_symbol (nelem);
1932 /* nelem = sizes (rank) - 1. */
1933 last_code->next = gfc_get_code (EXEC_ASSIGN);
1934 last_code = last_code->next;
1936 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
1938 last_code->expr2 = gfc_get_expr ();
1939 last_code->expr2->expr_type = EXPR_OP;
1940 last_code->expr2->value.op.op = INTRINSIC_MINUS;
1941 last_code->expr2->value.op.op2
1942 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1943 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
1944 last_code->expr2->where = gfc_current_locus;
1946 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1947 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
1948 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
1949 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1950 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
1951 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1952 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
1953 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1955 /* Call final subroutines. We now generate code like:
1956 use iso_c_binding
1957 integer, pointer :: ptr
1958 type(c_ptr) :: cptr
1959 integer(c_intptr_t) :: i, addr
1961 select case (rank (array))
1962 case (3)
1963 ! If needed, the array is packed
1964 call final_rank3 (array)
1965 case default:
1966 do i = 0, size (array)-1
1967 addr = transfer (c_loc (array), addr) + i * stride
1968 call c_f_pointer (transfer (addr, cptr), ptr)
1969 call elemental_final (ptr)
1970 end do
1971 end select */
1973 if (derived->f2k_derived && derived->f2k_derived->finalizers)
1975 gfc_finalizer *fini, *fini_elem = NULL;
1977 gfc_get_symbol ("ptr1", sub_ns, &ptr);
1978 ptr->ts.type = BT_DERIVED;
1979 ptr->ts.u.derived = derived;
1980 ptr->attr.flavor = FL_VARIABLE;
1981 ptr->attr.pointer = 1;
1982 ptr->attr.artificial = 1;
1983 gfc_set_sym_referenced (ptr);
1984 gfc_commit_symbol (ptr);
1986 /* SELECT CASE (RANK (array)). */
1987 last_code->next = gfc_get_code (EXEC_SELECT);
1988 last_code = last_code->next;
1989 last_code->expr1 = gfc_copy_expr (rank);
1990 block = NULL;
1992 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
1994 gcc_assert (fini->proc_tree); /* Should have been set in gfc_resolve_finalizers. */
1995 if (fini->proc_tree->n.sym->attr.elemental)
1997 fini_elem = fini;
1998 continue;
2001 /* CASE (fini_rank). */
2002 if (block)
2004 block->block = gfc_get_code (EXEC_SELECT);
2005 block = block->block;
2007 else
2009 block = gfc_get_code (EXEC_SELECT);
2010 last_code->block = block;
2012 block->ext.block.case_list = gfc_get_case ();
2013 block->ext.block.case_list->where = gfc_current_locus;
2014 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2015 block->ext.block.case_list->low
2016 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2017 fini->proc_tree->n.sym->formal->sym->as->rank);
2018 else
2019 block->ext.block.case_list->low
2020 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2021 block->ext.block.case_list->high
2022 = gfc_copy_expr (block->ext.block.case_list->low);
2024 /* CALL fini_rank (array) - possibly with packing. */
2025 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2026 finalizer_insert_packed_call (block, fini, array, byte_stride,
2027 idx, ptr, nelem, strides,
2028 sizes, idx2, offset, is_contiguous,
2029 rank, sub_ns);
2030 else
2032 block->next = gfc_get_code (EXEC_CALL);
2033 block->next->symtree = fini->proc_tree;
2034 block->next->resolved_sym = fini->proc_tree->n.sym;
2035 block->next->ext.actual = gfc_get_actual_arglist ();
2036 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
2040 /* Elemental call - scalarized. */
2041 if (fini_elem)
2043 /* CASE DEFAULT. */
2044 if (block)
2046 block->block = gfc_get_code (EXEC_SELECT);
2047 block = block->block;
2049 else
2051 block = gfc_get_code (EXEC_SELECT);
2052 last_code->block = block;
2054 block->ext.block.case_list = gfc_get_case ();
2056 /* Create loop. */
2057 iter = gfc_get_iterator ();
2058 iter->var = gfc_lval_expr_from_sym (idx);
2059 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2060 iter->end = gfc_lval_expr_from_sym (nelem);
2061 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2062 block->next = gfc_get_code (EXEC_DO);
2063 block = block->next;
2064 block->ext.iterator = iter;
2065 block->block = gfc_get_code (EXEC_DO);
2067 /* Offset calculation. */
2068 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2069 byte_stride, rank, block->block,
2070 sub_ns);
2072 /* Create code for
2073 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2074 + offset, c_ptr), ptr). */
2075 block->next
2076 = finalization_scalarizer (array, ptr,
2077 gfc_lval_expr_from_sym (offset),
2078 sub_ns);
2079 block = block->next;
2081 /* CALL final_elemental (array). */
2082 block->next = gfc_get_code (EXEC_CALL);
2083 block = block->next;
2084 block->symtree = fini_elem->proc_tree;
2085 block->resolved_sym = fini_elem->proc_sym;
2086 block->ext.actual = gfc_get_actual_arglist ();
2087 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
2091 /* Finalize and deallocate allocatable components. The same manual
2092 scalarization is used as above. */
2094 if (finalizable_comp)
2096 gfc_symbol *stat;
2097 gfc_code *block = NULL;
2099 if (!ptr)
2101 gfc_get_symbol ("ptr2", sub_ns, &ptr);
2102 ptr->ts.type = BT_DERIVED;
2103 ptr->ts.u.derived = derived;
2104 ptr->attr.flavor = FL_VARIABLE;
2105 ptr->attr.pointer = 1;
2106 ptr->attr.artificial = 1;
2107 gfc_set_sym_referenced (ptr);
2108 gfc_commit_symbol (ptr);
2111 gfc_get_symbol ("ignore", sub_ns, &stat);
2112 stat->attr.flavor = FL_VARIABLE;
2113 stat->attr.artificial = 1;
2114 stat->ts.type = BT_INTEGER;
2115 stat->ts.kind = gfc_default_integer_kind;
2116 gfc_set_sym_referenced (stat);
2117 gfc_commit_symbol (stat);
2119 /* Create loop. */
2120 iter = gfc_get_iterator ();
2121 iter->var = gfc_lval_expr_from_sym (idx);
2122 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2123 iter->end = gfc_lval_expr_from_sym (nelem);
2124 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2125 last_code->next = gfc_get_code (EXEC_DO);
2126 last_code = last_code->next;
2127 last_code->ext.iterator = iter;
2128 last_code->block = gfc_get_code (EXEC_DO);
2130 /* Offset calculation. */
2131 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2132 byte_stride, rank, last_code->block,
2133 sub_ns);
2135 /* Create code for
2136 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2137 + idx * stride, c_ptr), ptr). */
2138 block->next = finalization_scalarizer (array, ptr,
2139 gfc_lval_expr_from_sym(offset),
2140 sub_ns);
2141 block = block->next;
2143 for (comp = derived->components; comp; comp = comp->next)
2145 if (comp == derived->components && derived->attr.extension
2146 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2147 continue;
2149 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2150 stat, fini_coarray, &block, sub_ns);
2151 if (!last_code->block->next)
2152 last_code->block->next = block;
2157 /* Call the finalizer of the ancestor. */
2158 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2160 last_code->next = gfc_get_code (EXEC_CALL);
2161 last_code = last_code->next;
2162 last_code->symtree = ancestor_wrapper->symtree;
2163 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2165 last_code->ext.actual = gfc_get_actual_arglist ();
2166 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2167 last_code->ext.actual->next = gfc_get_actual_arglist ();
2168 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2169 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2170 last_code->ext.actual->next->next->expr
2171 = gfc_lval_expr_from_sym (fini_coarray);
2174 gfc_free_expr (rank);
2175 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2176 vtab_final->ts.interface = final;
2177 free (name);
2181 /* Add procedure pointers for all type-bound procedures to a vtab. */
2183 static void
2184 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2186 gfc_symbol* super_type;
2188 super_type = gfc_get_derived_super_type (derived);
2190 if (super_type && (super_type != derived))
2192 /* Make sure that the PPCs appear in the same order as in the parent. */
2193 copy_vtab_proc_comps (super_type, vtype);
2194 /* Only needed to get the PPC initializers right. */
2195 add_procs_to_declared_vtab (super_type, vtype);
2198 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2199 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2201 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2202 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2206 /* Find or generate the symbol for a derived type's vtab. */
2208 gfc_symbol *
2209 gfc_find_derived_vtab (gfc_symbol *derived)
2211 gfc_namespace *ns;
2212 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2213 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2214 gfc_gsymbol *gsym = NULL;
2215 gfc_symbol *dealloc = NULL, *arg = NULL;
2217 if (derived->attr.pdt_template)
2218 return NULL;
2220 /* Find the top-level namespace. */
2221 for (ns = gfc_current_ns; ns; ns = ns->parent)
2222 if (!ns->parent)
2223 break;
2225 /* If the type is a class container, use the underlying derived type. */
2226 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2227 derived = gfc_get_derived_super_type (derived);
2229 /* Find the gsymbol for the module of use associated derived types. */
2230 if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
2231 && !derived->attr.vtype && !derived->attr.is_class)
2232 gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module);
2233 else
2234 gsym = NULL;
2236 /* Work in the gsymbol namespace if the top-level namespace is a module.
2237 This ensures that the vtable is unique, which is required since we use
2238 its address in SELECT TYPE. */
2239 if (gsym && gsym->ns && ns && ns->proc_name
2240 && ns->proc_name->attr.flavor == FL_MODULE)
2241 ns = gsym->ns;
2243 if (ns)
2245 char tname[GFC_MAX_SYMBOL_LEN+1];
2246 char *name;
2248 get_unique_hashed_string (tname, derived);
2249 name = xasprintf ("__vtab_%s", tname);
2251 /* Look for the vtab symbol in various namespaces. */
2252 if (gsym && gsym->ns)
2254 gfc_find_symbol (name, gsym->ns, 0, &vtab);
2255 if (vtab)
2256 ns = gsym->ns;
2258 if (vtab == NULL)
2259 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2260 if (vtab == NULL)
2261 gfc_find_symbol (name, ns, 0, &vtab);
2262 if (vtab == NULL)
2263 gfc_find_symbol (name, derived->ns, 0, &vtab);
2265 if (vtab == NULL)
2267 gfc_get_symbol (name, ns, &vtab);
2268 vtab->ts.type = BT_DERIVED;
2269 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2270 &gfc_current_locus))
2271 goto cleanup;
2272 vtab->attr.target = 1;
2273 vtab->attr.save = SAVE_IMPLICIT;
2274 vtab->attr.vtab = 1;
2275 vtab->attr.access = ACCESS_PUBLIC;
2276 gfc_set_sym_referenced (vtab);
2277 name = xasprintf ("__vtype_%s", tname);
2279 gfc_find_symbol (name, ns, 0, &vtype);
2280 if (vtype == NULL)
2282 gfc_component *c;
2283 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2284 bool rdt = false;
2286 /* Is this a derived type with recursive allocatable
2287 components? */
2288 c = (derived->attr.unlimited_polymorphic
2289 || derived->attr.abstract) ?
2290 NULL : derived->components;
2291 for (; c; c= c->next)
2292 if (c->ts.type == BT_DERIVED
2293 && c->ts.u.derived == derived)
2295 rdt = true;
2296 break;
2299 gfc_get_symbol (name, ns, &vtype);
2300 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2301 &gfc_current_locus))
2302 goto cleanup;
2303 vtype->attr.access = ACCESS_PUBLIC;
2304 vtype->attr.vtype = 1;
2305 gfc_set_sym_referenced (vtype);
2307 /* Add component '_hash'. */
2308 if (!gfc_add_component (vtype, "_hash", &c))
2309 goto cleanup;
2310 c->ts.type = BT_INTEGER;
2311 c->ts.kind = 4;
2312 c->attr.access = ACCESS_PRIVATE;
2313 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2314 NULL, derived->hash_value);
2316 /* Add component '_size'. */
2317 if (!gfc_add_component (vtype, "_size", &c))
2318 goto cleanup;
2319 c->ts.type = BT_INTEGER;
2320 c->ts.kind = gfc_size_kind;
2321 c->attr.access = ACCESS_PRIVATE;
2322 /* Remember the derived type in ts.u.derived,
2323 so that the correct initializer can be set later on
2324 (in gfc_conv_structure). */
2325 c->ts.u.derived = derived;
2326 c->initializer = gfc_get_int_expr (gfc_size_kind,
2327 NULL, 0);
2329 /* Add component _extends. */
2330 if (!gfc_add_component (vtype, "_extends", &c))
2331 goto cleanup;
2332 c->attr.pointer = 1;
2333 c->attr.access = ACCESS_PRIVATE;
2334 if (!derived->attr.unlimited_polymorphic)
2335 parent = gfc_get_derived_super_type (derived);
2336 else
2337 parent = NULL;
2339 if (parent)
2341 parent_vtab = gfc_find_derived_vtab (parent);
2342 c->ts.type = BT_DERIVED;
2343 c->ts.u.derived = parent_vtab->ts.u.derived;
2344 c->initializer = gfc_get_expr ();
2345 c->initializer->expr_type = EXPR_VARIABLE;
2346 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2347 0, &c->initializer->symtree);
2349 else
2351 c->ts.type = BT_DERIVED;
2352 c->ts.u.derived = vtype;
2353 c->initializer = gfc_get_null_expr (NULL);
2356 if (!derived->attr.unlimited_polymorphic
2357 && derived->components == NULL
2358 && !derived->attr.zero_comp)
2360 /* At this point an error must have occurred.
2361 Prevent further errors on the vtype components. */
2362 found_sym = vtab;
2363 goto have_vtype;
2366 /* Add component _def_init. */
2367 if (!gfc_add_component (vtype, "_def_init", &c))
2368 goto cleanup;
2369 c->attr.pointer = 1;
2370 c->attr.artificial = 1;
2371 c->attr.access = ACCESS_PRIVATE;
2372 c->ts.type = BT_DERIVED;
2373 c->ts.u.derived = derived;
2374 if (derived->attr.unlimited_polymorphic
2375 || derived->attr.abstract)
2376 c->initializer = gfc_get_null_expr (NULL);
2377 else
2379 /* Construct default initialization variable. */
2380 name = xasprintf ("__def_init_%s", tname);
2381 gfc_get_symbol (name, ns, &def_init);
2382 def_init->attr.target = 1;
2383 def_init->attr.artificial = 1;
2384 def_init->attr.save = SAVE_IMPLICIT;
2385 def_init->attr.access = ACCESS_PUBLIC;
2386 def_init->attr.flavor = FL_VARIABLE;
2387 gfc_set_sym_referenced (def_init);
2388 def_init->ts.type = BT_DERIVED;
2389 def_init->ts.u.derived = derived;
2390 def_init->value = gfc_default_initializer (&def_init->ts);
2392 c->initializer = gfc_lval_expr_from_sym (def_init);
2395 /* Add component _copy. */
2396 if (!gfc_add_component (vtype, "_copy", &c))
2397 goto cleanup;
2398 c->attr.proc_pointer = 1;
2399 c->attr.access = ACCESS_PRIVATE;
2400 c->tb = XCNEW (gfc_typebound_proc);
2401 c->tb->ppc = 1;
2402 if (derived->attr.unlimited_polymorphic
2403 || derived->attr.abstract)
2404 c->initializer = gfc_get_null_expr (NULL);
2405 else
2407 /* Set up namespace. */
2408 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2409 sub_ns->sibling = ns->contained;
2410 ns->contained = sub_ns;
2411 sub_ns->resolved = 1;
2412 /* Set up procedure symbol. */
2413 name = xasprintf ("__copy_%s", tname);
2414 gfc_get_symbol (name, sub_ns, &copy);
2415 sub_ns->proc_name = copy;
2416 copy->attr.flavor = FL_PROCEDURE;
2417 copy->attr.subroutine = 1;
2418 copy->attr.pure = 1;
2419 copy->attr.artificial = 1;
2420 copy->attr.if_source = IFSRC_DECL;
2421 /* This is elemental so that arrays are automatically
2422 treated correctly by the scalarizer. */
2423 copy->attr.elemental = 1;
2424 if (ns->proc_name->attr.flavor == FL_MODULE)
2425 copy->module = ns->proc_name->name;
2426 gfc_set_sym_referenced (copy);
2427 /* Set up formal arguments. */
2428 gfc_get_symbol ("src", sub_ns, &src);
2429 src->ts.type = BT_DERIVED;
2430 src->ts.u.derived = derived;
2431 src->attr.flavor = FL_VARIABLE;
2432 src->attr.dummy = 1;
2433 src->attr.artificial = 1;
2434 src->attr.intent = INTENT_IN;
2435 gfc_set_sym_referenced (src);
2436 copy->formal = gfc_get_formal_arglist ();
2437 copy->formal->sym = src;
2438 gfc_get_symbol ("dst", sub_ns, &dst);
2439 dst->ts.type = BT_DERIVED;
2440 dst->ts.u.derived = derived;
2441 dst->attr.flavor = FL_VARIABLE;
2442 dst->attr.dummy = 1;
2443 dst->attr.artificial = 1;
2444 dst->attr.intent = INTENT_INOUT;
2445 gfc_set_sym_referenced (dst);
2446 copy->formal->next = gfc_get_formal_arglist ();
2447 copy->formal->next->sym = dst;
2448 /* Set up code. */
2449 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2450 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2451 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2452 /* Set initializer. */
2453 c->initializer = gfc_lval_expr_from_sym (copy);
2454 c->ts.interface = copy;
2457 /* Add component _final, which contains a procedure pointer to
2458 a wrapper which handles both the freeing of allocatable
2459 components and the calls to finalization subroutines.
2460 Note: The actual wrapper function can only be generated
2461 at resolution time. */
2462 if (!gfc_add_component (vtype, "_final", &c))
2463 goto cleanup;
2464 c->attr.proc_pointer = 1;
2465 c->attr.access = ACCESS_PRIVATE;
2466 c->tb = XCNEW (gfc_typebound_proc);
2467 c->tb->ppc = 1;
2468 generate_finalization_wrapper (derived, ns, tname, c);
2470 /* Add component _deallocate. */
2471 if (!gfc_add_component (vtype, "_deallocate", &c))
2472 goto cleanup;
2473 c->attr.proc_pointer = 1;
2474 c->attr.access = ACCESS_PRIVATE;
2475 c->tb = XCNEW (gfc_typebound_proc);
2476 c->tb->ppc = 1;
2477 if (derived->attr.unlimited_polymorphic
2478 || derived->attr.abstract
2479 || !rdt)
2480 c->initializer = gfc_get_null_expr (NULL);
2481 else
2483 /* Set up namespace. */
2484 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2486 sub_ns->sibling = ns->contained;
2487 ns->contained = sub_ns;
2488 sub_ns->resolved = 1;
2489 /* Set up procedure symbol. */
2490 name = xasprintf ("__deallocate_%s", tname);
2491 gfc_get_symbol (name, sub_ns, &dealloc);
2492 sub_ns->proc_name = dealloc;
2493 dealloc->attr.flavor = FL_PROCEDURE;
2494 dealloc->attr.subroutine = 1;
2495 dealloc->attr.pure = 1;
2496 dealloc->attr.artificial = 1;
2497 dealloc->attr.if_source = IFSRC_DECL;
2499 if (ns->proc_name->attr.flavor == FL_MODULE)
2500 dealloc->module = ns->proc_name->name;
2501 gfc_set_sym_referenced (dealloc);
2502 /* Set up formal argument. */
2503 gfc_get_symbol ("arg", sub_ns, &arg);
2504 arg->ts.type = BT_DERIVED;
2505 arg->ts.u.derived = derived;
2506 arg->attr.flavor = FL_VARIABLE;
2507 arg->attr.dummy = 1;
2508 arg->attr.artificial = 1;
2509 arg->attr.intent = INTENT_INOUT;
2510 arg->attr.dimension = 1;
2511 arg->attr.allocatable = 1;
2512 arg->as = gfc_get_array_spec();
2513 arg->as->type = AS_ASSUMED_SHAPE;
2514 arg->as->rank = 1;
2515 arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
2516 NULL, 1);
2517 gfc_set_sym_referenced (arg);
2518 dealloc->formal = gfc_get_formal_arglist ();
2519 dealloc->formal->sym = arg;
2520 /* Set up code. */
2521 sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
2522 sub_ns->code->ext.alloc.list = gfc_get_alloc ();
2523 sub_ns->code->ext.alloc.list->expr
2524 = gfc_lval_expr_from_sym (arg);
2525 /* Set initializer. */
2526 c->initializer = gfc_lval_expr_from_sym (dealloc);
2527 c->ts.interface = dealloc;
2530 /* Add procedure pointers for type-bound procedures. */
2531 if (!derived->attr.unlimited_polymorphic)
2532 add_procs_to_declared_vtab (derived, vtype);
2535 have_vtype:
2536 vtab->ts.u.derived = vtype;
2537 vtab->value = gfc_default_initializer (&vtab->ts);
2539 free (name);
2542 found_sym = vtab;
2544 cleanup:
2545 /* It is unexpected to have some symbols added at resolution or code
2546 generation time. We commit the changes in order to keep a clean state. */
2547 if (found_sym)
2549 gfc_commit_symbol (vtab);
2550 if (vtype)
2551 gfc_commit_symbol (vtype);
2552 if (def_init)
2553 gfc_commit_symbol (def_init);
2554 if (copy)
2555 gfc_commit_symbol (copy);
2556 if (src)
2557 gfc_commit_symbol (src);
2558 if (dst)
2559 gfc_commit_symbol (dst);
2560 if (dealloc)
2561 gfc_commit_symbol (dealloc);
2562 if (arg)
2563 gfc_commit_symbol (arg);
2565 else
2566 gfc_undo_symbols ();
2568 return found_sym;
2572 /* Check if a derived type is finalizable. That is the case if it
2573 (1) has a FINAL subroutine or
2574 (2) has a nonpointer nonallocatable component of finalizable type.
2575 If it is finalizable, return an expression containing the
2576 finalization wrapper. */
2578 bool
2579 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2581 gfc_symbol *vtab;
2582 gfc_component *c;
2584 /* (1) Check for FINAL subroutines. */
2585 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2586 goto yes;
2588 /* (2) Check for components of finalizable type. */
2589 for (c = derived->components; c; c = c->next)
2590 if (c->ts.type == BT_DERIVED
2591 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2592 && gfc_is_finalizable (c->ts.u.derived, NULL))
2593 goto yes;
2595 return false;
2597 yes:
2598 /* Make sure vtab is generated. */
2599 vtab = gfc_find_derived_vtab (derived);
2600 if (final_expr)
2602 /* Return finalizer expression. */
2603 gfc_component *final;
2604 final = vtab->ts.u.derived->components->next->next->next->next->next;
2605 gcc_assert (strcmp (final->name, "_final") == 0);
2606 gcc_assert (final->initializer
2607 && final->initializer->expr_type != EXPR_NULL);
2608 *final_expr = final->initializer;
2610 return true;
2614 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2615 needed to support unlimited polymorphism. */
2617 static gfc_symbol *
2618 find_intrinsic_vtab (gfc_typespec *ts)
2620 gfc_namespace *ns;
2621 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2622 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2624 /* Find the top-level namespace. */
2625 for (ns = gfc_current_ns; ns; ns = ns->parent)
2626 if (!ns->parent)
2627 break;
2629 if (ns)
2631 char tname[GFC_MAX_SYMBOL_LEN+1];
2632 char *name;
2634 /* Encode all types as TYPENAME_KIND_ including especially character
2635 arrays, whose length is now consistently stored in the _len component
2636 of the class-variable. */
2637 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2638 name = xasprintf ("__vtab_%s", tname);
2640 /* Look for the vtab symbol in the top-level namespace only. */
2641 gfc_find_symbol (name, ns, 0, &vtab);
2643 if (vtab == NULL)
2645 gfc_get_symbol (name, ns, &vtab);
2646 vtab->ts.type = BT_DERIVED;
2647 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2648 &gfc_current_locus))
2649 goto cleanup;
2650 vtab->attr.target = 1;
2651 vtab->attr.save = SAVE_IMPLICIT;
2652 vtab->attr.vtab = 1;
2653 vtab->attr.access = ACCESS_PUBLIC;
2654 gfc_set_sym_referenced (vtab);
2655 name = xasprintf ("__vtype_%s", tname);
2657 gfc_find_symbol (name, ns, 0, &vtype);
2658 if (vtype == NULL)
2660 gfc_component *c;
2661 int hash;
2662 gfc_namespace *sub_ns;
2663 gfc_namespace *contained;
2664 gfc_expr *e;
2666 gfc_get_symbol (name, ns, &vtype);
2667 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2668 &gfc_current_locus))
2669 goto cleanup;
2670 vtype->attr.access = ACCESS_PUBLIC;
2671 vtype->attr.vtype = 1;
2672 gfc_set_sym_referenced (vtype);
2674 /* Add component '_hash'. */
2675 if (!gfc_add_component (vtype, "_hash", &c))
2676 goto cleanup;
2677 c->ts.type = BT_INTEGER;
2678 c->ts.kind = 4;
2679 c->attr.access = ACCESS_PRIVATE;
2680 hash = gfc_intrinsic_hash_value (ts);
2681 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2682 NULL, hash);
2684 /* Add component '_size'. */
2685 if (!gfc_add_component (vtype, "_size", &c))
2686 goto cleanup;
2687 c->ts.type = BT_INTEGER;
2688 c->ts.kind = gfc_size_kind;
2689 c->attr.access = ACCESS_PRIVATE;
2691 /* Build a minimal expression to make use of
2692 target-memory.c/gfc_element_size for 'size'. Special handling
2693 for character arrays, that are not constant sized: to support
2694 len (str) * kind, only the kind information is stored in the
2695 vtab. */
2696 e = gfc_get_expr ();
2697 e->ts = *ts;
2698 e->expr_type = EXPR_VARIABLE;
2699 c->initializer = gfc_get_int_expr (gfc_size_kind,
2700 NULL,
2701 ts->type == BT_CHARACTER
2702 ? ts->kind
2703 : gfc_element_size (e));
2704 gfc_free_expr (e);
2706 /* Add component _extends. */
2707 if (!gfc_add_component (vtype, "_extends", &c))
2708 goto cleanup;
2709 c->attr.pointer = 1;
2710 c->attr.access = ACCESS_PRIVATE;
2711 c->ts.type = BT_VOID;
2712 c->initializer = gfc_get_null_expr (NULL);
2714 /* Add component _def_init. */
2715 if (!gfc_add_component (vtype, "_def_init", &c))
2716 goto cleanup;
2717 c->attr.pointer = 1;
2718 c->attr.access = ACCESS_PRIVATE;
2719 c->ts.type = BT_VOID;
2720 c->initializer = gfc_get_null_expr (NULL);
2722 /* Add component _copy. */
2723 if (!gfc_add_component (vtype, "_copy", &c))
2724 goto cleanup;
2725 c->attr.proc_pointer = 1;
2726 c->attr.access = ACCESS_PRIVATE;
2727 c->tb = XCNEW (gfc_typebound_proc);
2728 c->tb->ppc = 1;
2730 if (ts->type != BT_CHARACTER)
2731 name = xasprintf ("__copy_%s", tname);
2732 else
2734 /* __copy is always the same for characters.
2735 Check to see if copy function already exists. */
2736 name = xasprintf ("__copy_character_%d", ts->kind);
2737 contained = ns->contained;
2738 for (; contained; contained = contained->sibling)
2739 if (contained->proc_name
2740 && strcmp (name, contained->proc_name->name) == 0)
2742 copy = contained->proc_name;
2743 goto got_char_copy;
2747 /* Set up namespace. */
2748 sub_ns = gfc_get_namespace (ns, 0);
2749 sub_ns->sibling = ns->contained;
2750 ns->contained = sub_ns;
2751 sub_ns->resolved = 1;
2752 /* Set up procedure symbol. */
2753 gfc_get_symbol (name, sub_ns, &copy);
2754 sub_ns->proc_name = copy;
2755 copy->attr.flavor = FL_PROCEDURE;
2756 copy->attr.subroutine = 1;
2757 copy->attr.pure = 1;
2758 copy->attr.if_source = IFSRC_DECL;
2759 /* This is elemental so that arrays are automatically
2760 treated correctly by the scalarizer. */
2761 copy->attr.elemental = 1;
2762 if (ns->proc_name->attr.flavor == FL_MODULE)
2763 copy->module = ns->proc_name->name;
2764 gfc_set_sym_referenced (copy);
2765 /* Set up formal arguments. */
2766 gfc_get_symbol ("src", sub_ns, &src);
2767 src->ts.type = ts->type;
2768 src->ts.kind = ts->kind;
2769 src->attr.flavor = FL_VARIABLE;
2770 src->attr.dummy = 1;
2771 src->attr.intent = INTENT_IN;
2772 gfc_set_sym_referenced (src);
2773 copy->formal = gfc_get_formal_arglist ();
2774 copy->formal->sym = src;
2775 gfc_get_symbol ("dst", sub_ns, &dst);
2776 dst->ts.type = ts->type;
2777 dst->ts.kind = ts->kind;
2778 dst->attr.flavor = FL_VARIABLE;
2779 dst->attr.dummy = 1;
2780 dst->attr.intent = INTENT_INOUT;
2781 gfc_set_sym_referenced (dst);
2782 copy->formal->next = gfc_get_formal_arglist ();
2783 copy->formal->next->sym = dst;
2784 /* Set up code. */
2785 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2786 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2787 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2788 got_char_copy:
2789 /* Set initializer. */
2790 c->initializer = gfc_lval_expr_from_sym (copy);
2791 c->ts.interface = copy;
2793 /* Add component _final. */
2794 if (!gfc_add_component (vtype, "_final", &c))
2795 goto cleanup;
2796 c->attr.proc_pointer = 1;
2797 c->attr.access = ACCESS_PRIVATE;
2798 c->tb = XCNEW (gfc_typebound_proc);
2799 c->tb->ppc = 1;
2800 c->initializer = gfc_get_null_expr (NULL);
2802 vtab->ts.u.derived = vtype;
2803 vtab->value = gfc_default_initializer (&vtab->ts);
2805 free (name);
2808 found_sym = vtab;
2810 cleanup:
2811 /* It is unexpected to have some symbols added at resolution or code
2812 generation time. We commit the changes in order to keep a clean state. */
2813 if (found_sym)
2815 gfc_commit_symbol (vtab);
2816 if (vtype)
2817 gfc_commit_symbol (vtype);
2818 if (copy)
2819 gfc_commit_symbol (copy);
2820 if (src)
2821 gfc_commit_symbol (src);
2822 if (dst)
2823 gfc_commit_symbol (dst);
2825 else
2826 gfc_undo_symbols ();
2828 return found_sym;
2832 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
2834 gfc_symbol *
2835 gfc_find_vtab (gfc_typespec *ts)
2837 switch (ts->type)
2839 case BT_UNKNOWN:
2840 return NULL;
2841 case BT_DERIVED:
2842 return gfc_find_derived_vtab (ts->u.derived);
2843 case BT_CLASS:
2844 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
2845 default:
2846 return find_intrinsic_vtab (ts);
2851 /* General worker function to find either a type-bound procedure or a
2852 type-bound user operator. */
2854 static gfc_symtree*
2855 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2856 const char* name, bool noaccess, bool uop,
2857 locus* where)
2859 gfc_symtree* res;
2860 gfc_symtree* root;
2862 /* Set default to failure. */
2863 if (t)
2864 *t = false;
2866 if (derived->f2k_derived)
2867 /* Set correct symbol-root. */
2868 root = (uop ? derived->f2k_derived->tb_uop_root
2869 : derived->f2k_derived->tb_sym_root);
2870 else
2871 return NULL;
2873 /* Try to find it in the current type's namespace. */
2874 res = gfc_find_symtree (root, name);
2875 if (res && res->n.tb && !res->n.tb->error)
2877 /* We found one. */
2878 if (t)
2879 *t = true;
2881 if (!noaccess && derived->attr.use_assoc
2882 && res->n.tb->access == ACCESS_PRIVATE)
2884 if (where)
2885 gfc_error ("%qs of %qs is PRIVATE at %L",
2886 name, derived->name, where);
2887 if (t)
2888 *t = false;
2891 return res;
2894 /* Otherwise, recurse on parent type if derived is an extension. */
2895 if (derived->attr.extension)
2897 gfc_symbol* super_type;
2898 super_type = gfc_get_derived_super_type (derived);
2899 gcc_assert (super_type);
2901 return find_typebound_proc_uop (super_type, t, name,
2902 noaccess, uop, where);
2905 /* Nothing found. */
2906 return NULL;
2910 /* Find a type-bound procedure or user operator by name for a derived-type
2911 (looking recursively through the super-types). */
2913 gfc_symtree*
2914 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
2915 const char* name, bool noaccess, locus* where)
2917 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2920 gfc_symtree*
2921 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
2922 const char* name, bool noaccess, locus* where)
2924 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2928 /* Find a type-bound intrinsic operator looking recursively through the
2929 super-type hierarchy. */
2931 gfc_typebound_proc*
2932 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
2933 gfc_intrinsic_op op, bool noaccess,
2934 locus* where)
2936 gfc_typebound_proc* res;
2938 /* Set default to failure. */
2939 if (t)
2940 *t = false;
2942 /* Try to find it in the current type's namespace. */
2943 if (derived->f2k_derived)
2944 res = derived->f2k_derived->tb_op[op];
2945 else
2946 res = NULL;
2948 /* Check access. */
2949 if (res && !res->error)
2951 /* We found one. */
2952 if (t)
2953 *t = true;
2955 if (!noaccess && derived->attr.use_assoc
2956 && res->access == ACCESS_PRIVATE)
2958 if (where)
2959 gfc_error ("%qs of %qs is PRIVATE at %L",
2960 gfc_op2string (op), derived->name, where);
2961 if (t)
2962 *t = false;
2965 return res;
2968 /* Otherwise, recurse on parent type if derived is an extension. */
2969 if (derived->attr.extension)
2971 gfc_symbol* super_type;
2972 super_type = gfc_get_derived_super_type (derived);
2973 gcc_assert (super_type);
2975 return gfc_find_typebound_intrinsic_op (super_type, t, op,
2976 noaccess, where);
2979 /* Nothing found. */
2980 return NULL;
2984 /* Get a typebound-procedure symtree or create and insert it if not yet
2985 present. This is like a very simplified version of gfc_get_sym_tree for
2986 tbp-symtrees rather than regular ones. */
2988 gfc_symtree*
2989 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
2991 gfc_symtree *result = gfc_find_symtree (*root, name);
2992 return result ? result : gfc_new_symtree (root, name);