Fix memory leak in tree-vect-slp.c
[official-gcc.git] / gcc / fortran / class.c
blob3627828d21f991869278ffb6a675b9f4b4d3746a
1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2016 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(4) 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->next->ts.type == BT_DERIVED &&
228 derived->components->next->ts.u.derived == NULL)
230 /* Fix up missing vtype. */
231 gfc_symbol *vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
232 gcc_assert (vtab);
233 derived->components->next->ts.u.derived = vtab->ts.u.derived;
235 if (*tail != NULL && strcmp (name, "_data") == 0)
236 next = *tail;
237 else
238 /* Avoid losing memory. */
239 gfc_free_ref_list (*tail);
240 c = gfc_find_component (derived, name, true, true, tail);
241 gcc_assert (c);
242 for (ref = *tail; ref->next; ref = ref->next)
244 ref->next = next;
245 if (!next)
246 e->ts = c->ts;
250 /* This is used to add both the _data component reference and an array
251 reference to class expressions. Used in translation of intrinsic
252 array inquiry functions. */
254 void
255 gfc_add_class_array_ref (gfc_expr *e)
257 int rank = CLASS_DATA (e)->as->rank;
258 gfc_array_spec *as = CLASS_DATA (e)->as;
259 gfc_ref *ref = NULL;
260 gfc_add_component_ref (e, "_data");
261 e->rank = rank;
262 for (ref = e->ref; ref; ref = ref->next)
263 if (!ref->next)
264 break;
265 if (ref->type != REF_ARRAY)
267 ref->next = gfc_get_ref ();
268 ref = ref->next;
269 ref->type = REF_ARRAY;
270 ref->u.ar.type = AR_FULL;
271 ref->u.ar.as = as;
276 /* Unfortunately, class array expressions can appear in various conditions;
277 with and without both _data component and an arrayspec. This function
278 deals with that variability. The previous reference to 'ref' is to a
279 class array. */
281 static bool
282 class_array_ref_detected (gfc_ref *ref, bool *full_array)
284 bool no_data = false;
285 bool with_data = false;
287 /* An array reference with no _data component. */
288 if (ref && ref->type == REF_ARRAY
289 && !ref->next
290 && ref->u.ar.type != AR_ELEMENT)
292 if (full_array)
293 *full_array = ref->u.ar.type == AR_FULL;
294 no_data = true;
297 /* Cover cases where _data appears, with or without an array ref. */
298 if (ref && ref->type == REF_COMPONENT
299 && strcmp (ref->u.c.component->name, "_data") == 0)
301 if (!ref->next)
303 with_data = true;
304 if (full_array)
305 *full_array = true;
307 else if (ref->next && ref->next->type == REF_ARRAY
308 && !ref->next->next
309 && ref->type == REF_COMPONENT
310 && ref->next->type == REF_ARRAY
311 && ref->next->u.ar.type != AR_ELEMENT)
313 with_data = true;
314 if (full_array)
315 *full_array = ref->next->u.ar.type == AR_FULL;
319 return no_data || with_data;
323 /* Returns true if the expression contains a reference to a class
324 array. Notice that class array elements return false. */
326 bool
327 gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
329 gfc_ref *ref;
331 if (!e->rank)
332 return false;
334 if (full_array)
335 *full_array= false;
337 /* Is this a class array object? ie. Is the symbol of type class? */
338 if (e->symtree
339 && e->symtree->n.sym->ts.type == BT_CLASS
340 && CLASS_DATA (e->symtree->n.sym)
341 && CLASS_DATA (e->symtree->n.sym)->attr.dimension
342 && class_array_ref_detected (e->ref, full_array))
343 return true;
345 /* Or is this a class array component reference? */
346 for (ref = e->ref; ref; ref = ref->next)
348 if (ref->type == REF_COMPONENT
349 && ref->u.c.component->ts.type == BT_CLASS
350 && CLASS_DATA (ref->u.c.component)->attr.dimension
351 && class_array_ref_detected (ref->next, full_array))
352 return true;
355 return false;
359 /* Returns true if the expression is a reference to a class
360 scalar. This function is necessary because such expressions
361 can be dressed with a reference to the _data component and so
362 have a type other than BT_CLASS. */
364 bool
365 gfc_is_class_scalar_expr (gfc_expr *e)
367 gfc_ref *ref;
369 if (e->rank)
370 return false;
372 /* Is this a class object? */
373 if (e->symtree
374 && e->symtree->n.sym->ts.type == BT_CLASS
375 && CLASS_DATA (e->symtree->n.sym)
376 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
377 && (e->ref == NULL
378 || (strcmp (e->ref->u.c.component->name, "_data") == 0
379 && e->ref->next == NULL)))
380 return true;
382 /* Or is the final reference BT_CLASS or _data? */
383 for (ref = e->ref; ref; ref = ref->next)
385 if (ref->type == REF_COMPONENT
386 && ref->u.c.component->ts.type == BT_CLASS
387 && CLASS_DATA (ref->u.c.component)
388 && !CLASS_DATA (ref->u.c.component)->attr.dimension
389 && (ref->next == NULL
390 || (strcmp (ref->next->u.c.component->name, "_data") == 0
391 && ref->next->next == NULL)))
392 return true;
395 return false;
399 /* Tells whether the expression E is a reference to a (scalar) class container.
400 Scalar because array class containers usually have an array reference after
401 them, and gfc_fix_class_refs will add the missing "_data" component reference
402 in that case. */
404 bool
405 gfc_is_class_container_ref (gfc_expr *e)
407 gfc_ref *ref;
408 bool result;
410 if (e->expr_type != EXPR_VARIABLE)
411 return e->ts.type == BT_CLASS;
413 if (e->symtree->n.sym->ts.type == BT_CLASS)
414 result = true;
415 else
416 result = false;
418 for (ref = e->ref; ref; ref = ref->next)
420 if (ref->type != REF_COMPONENT)
421 result = false;
422 else if (ref->u.c.component->ts.type == BT_CLASS)
423 result = true;
424 else
425 result = false;
428 return result;
432 /* Build an initializer for CLASS pointers,
433 initializing the _data component to the init_expr (or NULL) and the _vptr
434 component to the corresponding type (or the declared type, given by ts). */
436 gfc_expr *
437 gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
439 gfc_expr *init;
440 gfc_component *comp;
441 gfc_symbol *vtab = NULL;
443 if (init_expr && init_expr->expr_type != EXPR_NULL)
444 vtab = gfc_find_vtab (&init_expr->ts);
445 else
446 vtab = gfc_find_vtab (ts);
448 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
449 &ts->u.derived->declared_at);
450 init->ts = *ts;
452 for (comp = ts->u.derived->components; comp; comp = comp->next)
454 gfc_constructor *ctor = gfc_constructor_get();
455 if (strcmp (comp->name, "_vptr") == 0 && vtab)
456 ctor->expr = gfc_lval_expr_from_sym (vtab);
457 else if (init_expr && init_expr->expr_type != EXPR_NULL)
458 ctor->expr = gfc_copy_expr (init_expr);
459 else
460 ctor->expr = gfc_get_null_expr (NULL);
461 gfc_constructor_append (&init->value.constructor, ctor);
464 return init;
468 /* Create a unique string identifier for a derived type, composed of its name
469 and module name. This is used to construct unique names for the class
470 containers and vtab symbols. */
472 static void
473 get_unique_type_string (char *string, gfc_symbol *derived)
475 char dt_name[GFC_MAX_SYMBOL_LEN+1];
476 if (derived->attr.unlimited_polymorphic)
477 strcpy (dt_name, "STAR");
478 else
479 strcpy (dt_name, gfc_dt_upper_string (derived->name));
480 if (derived->attr.unlimited_polymorphic)
481 sprintf (string, "_%s", dt_name);
482 else if (derived->module)
483 sprintf (string, "%s_%s", derived->module, dt_name);
484 else if (derived->ns->proc_name)
485 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
486 else
487 sprintf (string, "_%s", dt_name);
491 /* A relative of 'get_unique_type_string' which makes sure the generated
492 string will not be too long (replacing it by a hash string if needed). */
494 static void
495 get_unique_hashed_string (char *string, gfc_symbol *derived)
497 char tmp[2*GFC_MAX_SYMBOL_LEN+2];
498 get_unique_type_string (&tmp[0], derived);
499 /* If string is too long, use hash value in hex representation (allow for
500 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
501 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
502 where %d is the (co)rank which can be up to n = 15. */
503 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
505 int h = gfc_hash_value (derived);
506 sprintf (string, "%X", h);
508 else
509 strcpy (string, tmp);
513 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
515 unsigned int
516 gfc_hash_value (gfc_symbol *sym)
518 unsigned int hash = 0;
519 char c[2*(GFC_MAX_SYMBOL_LEN+1)];
520 int i, len;
522 get_unique_type_string (&c[0], sym);
523 len = strlen (c);
525 for (i = 0; i < len; i++)
526 hash = (hash << 6) + (hash << 16) - hash + c[i];
528 /* Return the hash but take the modulus for the sake of module read,
529 even though this slightly increases the chance of collision. */
530 return (hash % 100000000);
534 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
536 unsigned int
537 gfc_intrinsic_hash_value (gfc_typespec *ts)
539 unsigned int hash = 0;
540 const char *c = gfc_typename (ts);
541 int i, len;
543 len = strlen (c);
545 for (i = 0; i < len; i++)
546 hash = (hash << 6) + (hash << 16) - hash + c[i];
548 /* Return the hash but take the modulus for the sake of module read,
549 even though this slightly increases the chance of collision. */
550 return (hash % 100000000);
554 /* Get the _len component from a class/derived object storing a string.
555 For unlimited polymorphic entities a ref to the _data component is available
556 while a ref to the _len component is needed. This routine traverese the
557 ref-chain and strips the last ref to a _data from it replacing it with a
558 ref to the _len component. */
560 gfc_expr *
561 gfc_get_len_component (gfc_expr *e)
563 gfc_expr *ptr;
564 gfc_ref *ref, **last;
566 ptr = gfc_copy_expr (e);
568 /* We need to remove the last _data component ref from ptr. */
569 last = &(ptr->ref);
570 ref = ptr->ref;
571 while (ref)
573 if (!ref->next
574 && ref->type == REF_COMPONENT
575 && strcmp ("_data", ref->u.c.component->name)== 0)
577 gfc_free_ref_list (ref);
578 *last = NULL;
579 break;
581 last = &(ref->next);
582 ref = ref->next;
584 /* And replace if with a ref to the _len component. */
585 gfc_add_component_ref (ptr, "_len");
586 return ptr;
590 /* Build a polymorphic CLASS entity, using the symbol that comes from
591 build_sym. A CLASS entity is represented by an encapsulating type,
592 which contains the declared type as '_data' component, plus a pointer
593 component '_vptr' which determines the dynamic type. When this CLASS
594 entity is unlimited polymorphic, then also add a component '_len' to
595 store the length of string when that is stored in it. */
597 bool
598 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
599 gfc_array_spec **as)
601 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
602 gfc_symbol *fclass;
603 gfc_symbol *vtab;
604 gfc_component *c;
605 gfc_namespace *ns;
606 int rank;
608 gcc_assert (as);
610 if (*as && (*as)->type == AS_ASSUMED_SIZE)
612 gfc_error ("Assumed size polymorphic objects or components, such "
613 "as that at %C, have not yet been implemented");
614 return false;
617 if (attr->class_ok)
618 /* Class container has already been built. */
619 return true;
621 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
622 || attr->select_type_temporary || attr->associate_var;
624 if (!attr->class_ok)
625 /* We can not build the class container yet. */
626 return true;
628 /* Determine the name of the encapsulating type. */
629 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
630 get_unique_hashed_string (tname, ts->u.derived);
631 if ((*as) && attr->allocatable)
632 sprintf (name, "__class_%s_%d_%da", tname, rank, (*as)->corank);
633 else if ((*as) && attr->pointer)
634 sprintf (name, "__class_%s_%d_%dp", tname, rank, (*as)->corank);
635 else if ((*as))
636 sprintf (name, "__class_%s_%d_%dt", tname, rank, (*as)->corank);
637 else if (attr->pointer)
638 sprintf (name, "__class_%s_p", tname);
639 else if (attr->allocatable)
640 sprintf (name, "__class_%s_a", tname);
641 else
642 sprintf (name, "__class_%s_t", tname);
644 if (ts->u.derived->attr.unlimited_polymorphic)
646 /* Find the top-level namespace. */
647 for (ns = gfc_current_ns; ns; ns = ns->parent)
648 if (!ns->parent)
649 break;
651 else
652 ns = ts->u.derived->ns;
654 gfc_find_symbol (name, ns, 0, &fclass);
655 if (fclass == NULL)
657 gfc_symtree *st;
658 /* If not there, create a new symbol. */
659 fclass = gfc_new_symbol (name, ns);
660 st = gfc_new_symtree (&ns->sym_root, name);
661 st->n.sym = fclass;
662 gfc_set_sym_referenced (fclass);
663 fclass->refs++;
664 fclass->ts.type = BT_UNKNOWN;
665 if (!ts->u.derived->attr.unlimited_polymorphic)
666 fclass->attr.abstract = ts->u.derived->attr.abstract;
667 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
668 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
669 &gfc_current_locus))
670 return false;
672 /* Add component '_data'. */
673 if (!gfc_add_component (fclass, "_data", &c))
674 return false;
675 c->ts = *ts;
676 c->ts.type = BT_DERIVED;
677 c->attr.access = ACCESS_PRIVATE;
678 c->ts.u.derived = ts->u.derived;
679 c->attr.class_pointer = attr->pointer;
680 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
681 || attr->select_type_temporary;
682 c->attr.allocatable = attr->allocatable;
683 c->attr.dimension = attr->dimension;
684 c->attr.codimension = attr->codimension;
685 c->attr.abstract = fclass->attr.abstract;
686 c->as = (*as);
687 c->initializer = NULL;
689 /* Add component '_vptr'. */
690 if (!gfc_add_component (fclass, "_vptr", &c))
691 return false;
692 c->ts.type = BT_DERIVED;
693 c->attr.access = ACCESS_PRIVATE;
694 c->attr.pointer = 1;
696 if (ts->u.derived->attr.unlimited_polymorphic)
698 vtab = gfc_find_derived_vtab (ts->u.derived);
699 gcc_assert (vtab);
700 c->ts.u.derived = vtab->ts.u.derived;
702 /* Add component '_len'. Only unlimited polymorphic pointers may
703 have a string assigned to them, i.e., only those need the _len
704 component. */
705 if (!gfc_add_component (fclass, "_len", &c))
706 return false;
707 c->ts.type = BT_INTEGER;
708 c->ts.kind = 4;
709 c->attr.access = ACCESS_PRIVATE;
710 c->attr.artificial = 1;
712 else
713 /* Build vtab later. */
714 c->ts.u.derived = NULL;
717 if (!ts->u.derived->attr.unlimited_polymorphic)
719 /* Since the extension field is 8 bit wide, we can only have
720 up to 255 extension levels. */
721 if (ts->u.derived->attr.extension == 255)
723 gfc_error ("Maximum extension level reached with type %qs at %L",
724 ts->u.derived->name, &ts->u.derived->declared_at);
725 return false;
728 fclass->attr.extension = ts->u.derived->attr.extension + 1;
729 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
730 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
733 fclass->attr.is_class = 1;
734 ts->u.derived = fclass;
735 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
736 (*as) = NULL;
737 return true;
741 /* Add a procedure pointer component to the vtype
742 to represent a specific type-bound procedure. */
744 static void
745 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
747 gfc_component *c;
749 if (tb->non_overridable)
750 return;
752 c = gfc_find_component (vtype, name, true, true, NULL);
754 if (c == NULL)
756 /* Add procedure component. */
757 if (!gfc_add_component (vtype, name, &c))
758 return;
760 if (!c->tb)
761 c->tb = XCNEW (gfc_typebound_proc);
762 *c->tb = *tb;
763 c->tb->ppc = 1;
764 c->attr.procedure = 1;
765 c->attr.proc_pointer = 1;
766 c->attr.flavor = FL_PROCEDURE;
767 c->attr.access = ACCESS_PRIVATE;
768 c->attr.external = 1;
769 c->attr.untyped = 1;
770 c->attr.if_source = IFSRC_IFBODY;
772 else if (c->attr.proc_pointer && c->tb)
774 *c->tb = *tb;
775 c->tb->ppc = 1;
778 if (tb->u.specific)
780 gfc_symbol *ifc = tb->u.specific->n.sym;
781 c->ts.interface = ifc;
782 if (!tb->deferred)
783 c->initializer = gfc_get_variable_expr (tb->u.specific);
784 c->attr.pure = ifc->attr.pure;
789 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
791 static void
792 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
794 if (!st)
795 return;
797 if (st->left)
798 add_procs_to_declared_vtab1 (st->left, vtype);
800 if (st->right)
801 add_procs_to_declared_vtab1 (st->right, vtype);
803 if (st->n.tb && !st->n.tb->error
804 && !st->n.tb->is_generic && st->n.tb->u.specific)
805 add_proc_comp (vtype, st->name, st->n.tb);
809 /* Copy procedure pointers components from the parent type. */
811 static void
812 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
814 gfc_component *cmp;
815 gfc_symbol *vtab;
817 vtab = gfc_find_derived_vtab (declared);
819 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
821 if (gfc_find_component (vtype, cmp->name, true, true, NULL))
822 continue;
824 add_proc_comp (vtype, cmp->name, cmp->tb);
829 /* Returns true if any of its nonpointer nonallocatable components or
830 their nonpointer nonallocatable subcomponents has a finalization
831 subroutine. */
833 static bool
834 has_finalizer_component (gfc_symbol *derived)
836 gfc_component *c;
838 for (c = derived->components; c; c = c->next)
840 if (c->ts.type == BT_DERIVED && c->ts.u.derived->f2k_derived
841 && c->ts.u.derived->f2k_derived->finalizers)
842 return true;
844 /* Stop infinite recursion through this function by inhibiting
845 calls when the derived type and that of the component are
846 the same. */
847 if (c->ts.type == BT_DERIVED
848 && !gfc_compare_derived_types (derived, c->ts.u.derived)
849 && !c->attr.pointer && !c->attr.allocatable
850 && has_finalizer_component (c->ts.u.derived))
851 return true;
853 return false;
857 static bool
858 comp_is_finalizable (gfc_component *comp)
860 if (comp->attr.proc_pointer)
861 return false;
862 else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
863 return true;
864 else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
865 && (comp->ts.u.derived->attr.alloc_comp
866 || has_finalizer_component (comp->ts.u.derived)
867 || (comp->ts.u.derived->f2k_derived
868 && comp->ts.u.derived->f2k_derived->finalizers)))
869 return true;
870 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
871 && CLASS_DATA (comp)->attr.allocatable)
872 return true;
873 else
874 return false;
878 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
879 neither allocatable nor a pointer but has a finalizer, call it. If it
880 is a nonpointer component with allocatable components or has finalizers, walk
881 them. Either of them is required; other nonallocatables and pointers aren't
882 handled gracefully.
883 Note: If the component is allocatable, the DEALLOCATE handling takes care
884 of calling the appropriate finalizers, coarray deregistering, and
885 deallocation of allocatable subcomponents. */
887 static void
888 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
889 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
890 gfc_namespace *sub_ns)
892 gfc_expr *e;
893 gfc_ref *ref;
895 if (!comp_is_finalizable (comp))
896 return;
898 e = gfc_copy_expr (expr);
899 if (!e->ref)
900 e->ref = ref = gfc_get_ref ();
901 else
903 for (ref = e->ref; ref->next; ref = ref->next)
905 ref->next = gfc_get_ref ();
906 ref = ref->next;
908 ref->type = REF_COMPONENT;
909 ref->u.c.sym = derived;
910 ref->u.c.component = comp;
911 e->ts = comp->ts;
913 if (comp->attr.dimension || comp->attr.codimension
914 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
915 && (CLASS_DATA (comp)->attr.dimension
916 || CLASS_DATA (comp)->attr.codimension)))
918 ref->next = gfc_get_ref ();
919 ref->next->type = REF_ARRAY;
920 ref->next->u.ar.dimen = 0;
921 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
922 : comp->as;
923 e->rank = ref->next->u.ar.as->rank;
924 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
927 /* Call DEALLOCATE (comp, stat=ignore). */
928 if (comp->attr.allocatable
929 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
930 && CLASS_DATA (comp)->attr.allocatable))
932 gfc_code *dealloc, *block = NULL;
934 /* Add IF (fini_coarray). */
935 if (comp->attr.codimension
936 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
937 && CLASS_DATA (comp)->attr.codimension))
939 block = gfc_get_code (EXEC_IF);
940 if (*code)
942 (*code)->next = block;
943 (*code) = (*code)->next;
945 else
946 (*code) = block;
948 block->block = gfc_get_code (EXEC_IF);
949 block = block->block;
950 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
953 dealloc = gfc_get_code (EXEC_DEALLOCATE);
955 dealloc->ext.alloc.list = gfc_get_alloc ();
956 dealloc->ext.alloc.list->expr = e;
957 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
959 gfc_code *cond = gfc_get_code (EXEC_IF);
960 cond->block = gfc_get_code (EXEC_IF);
961 cond->block->expr1 = gfc_get_expr ();
962 cond->block->expr1->expr_type = EXPR_FUNCTION;
963 gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
964 cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
965 cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
966 cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
967 gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
968 cond->block->expr1->ts.type = BT_LOGICAL;
969 cond->block->expr1->ts.kind = gfc_default_logical_kind;
970 cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
971 cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
972 cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
973 cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
974 cond->block->next = dealloc;
976 if (block)
977 block->next = cond;
978 else if (*code)
980 (*code)->next = cond;
981 (*code) = (*code)->next;
983 else
984 (*code) = cond;
986 else if (comp->ts.type == BT_DERIVED
987 && comp->ts.u.derived->f2k_derived
988 && comp->ts.u.derived->f2k_derived->finalizers)
990 /* Call FINAL_WRAPPER (comp); */
991 gfc_code *final_wrap;
992 gfc_symbol *vtab;
993 gfc_component *c;
995 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
996 for (c = vtab->ts.u.derived->components; c; c = c->next)
997 if (strcmp (c->name, "_final") == 0)
998 break;
1000 gcc_assert (c);
1001 final_wrap = gfc_get_code (EXEC_CALL);
1002 final_wrap->symtree = c->initializer->symtree;
1003 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
1004 final_wrap->ext.actual = gfc_get_actual_arglist ();
1005 final_wrap->ext.actual->expr = e;
1007 if (*code)
1009 (*code)->next = final_wrap;
1010 (*code) = (*code)->next;
1012 else
1013 (*code) = final_wrap;
1015 else
1017 gfc_component *c;
1019 for (c = comp->ts.u.derived->components; c; c = c->next)
1020 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code,
1021 sub_ns);
1022 gfc_free_expr (e);
1027 /* Generate code equivalent to
1028 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1029 + offset, c_ptr), ptr). */
1031 static gfc_code *
1032 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
1033 gfc_expr *offset, gfc_namespace *sub_ns)
1035 gfc_code *block;
1036 gfc_expr *expr, *expr2;
1038 /* C_F_POINTER(). */
1039 block = gfc_get_code (EXEC_CALL);
1040 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
1041 block->resolved_sym = block->symtree->n.sym;
1042 block->resolved_sym->attr.flavor = FL_PROCEDURE;
1043 block->resolved_sym->attr.intrinsic = 1;
1044 block->resolved_sym->attr.subroutine = 1;
1045 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
1046 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
1047 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
1048 gfc_commit_symbol (block->resolved_sym);
1050 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
1051 block->ext.actual = gfc_get_actual_arglist ();
1052 block->ext.actual->next = gfc_get_actual_arglist ();
1053 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
1054 NULL, 0);
1055 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
1057 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
1059 /* TRANSFER's first argument: C_LOC (array). */
1060 expr = gfc_get_expr ();
1061 expr->expr_type = EXPR_FUNCTION;
1062 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
1063 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1064 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
1065 expr->symtree->n.sym->attr.intrinsic = 1;
1066 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
1067 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
1068 expr->value.function.actual = gfc_get_actual_arglist ();
1069 expr->value.function.actual->expr
1070 = gfc_lval_expr_from_sym (array);
1071 expr->symtree->n.sym->result = expr->symtree->n.sym;
1072 gfc_commit_symbol (expr->symtree->n.sym);
1073 expr->ts.type = BT_INTEGER;
1074 expr->ts.kind = gfc_index_integer_kind;
1076 /* TRANSFER. */
1077 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
1078 gfc_current_locus, 3, expr,
1079 gfc_get_int_expr (gfc_index_integer_kind,
1080 NULL, 0), NULL);
1081 expr2->ts.type = BT_INTEGER;
1082 expr2->ts.kind = gfc_index_integer_kind;
1084 /* <array addr> + <offset>. */
1085 block->ext.actual->expr = gfc_get_expr ();
1086 block->ext.actual->expr->expr_type = EXPR_OP;
1087 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
1088 block->ext.actual->expr->value.op.op1 = expr2;
1089 block->ext.actual->expr->value.op.op2 = offset;
1090 block->ext.actual->expr->ts = expr->ts;
1092 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1093 block->ext.actual->next = gfc_get_actual_arglist ();
1094 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1095 block->ext.actual->next->next = gfc_get_actual_arglist ();
1097 return block;
1101 /* Calculates the offset to the (idx+1)th element of an array, taking the
1102 stride into account. It generates the code:
1103 offset = 0
1104 do idx2 = 1, rank
1105 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1106 end do
1107 offset = offset * byte_stride. */
1109 static gfc_code*
1110 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1111 gfc_symbol *strides, gfc_symbol *sizes,
1112 gfc_symbol *byte_stride, gfc_expr *rank,
1113 gfc_code *block, gfc_namespace *sub_ns)
1115 gfc_iterator *iter;
1116 gfc_expr *expr, *expr2;
1118 /* offset = 0. */
1119 block->next = gfc_get_code (EXEC_ASSIGN);
1120 block = block->next;
1121 block->expr1 = gfc_lval_expr_from_sym (offset);
1122 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1124 /* Create loop. */
1125 iter = gfc_get_iterator ();
1126 iter->var = gfc_lval_expr_from_sym (idx2);
1127 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1128 iter->end = gfc_copy_expr (rank);
1129 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1130 block->next = gfc_get_code (EXEC_DO);
1131 block = block->next;
1132 block->ext.iterator = iter;
1133 block->block = gfc_get_code (EXEC_DO);
1135 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1136 * strides(idx2). */
1138 /* mod (idx, sizes(idx2)). */
1139 expr = gfc_lval_expr_from_sym (sizes);
1140 expr->ref = gfc_get_ref ();
1141 expr->ref->type = REF_ARRAY;
1142 expr->ref->u.ar.as = sizes->as;
1143 expr->ref->u.ar.type = AR_ELEMENT;
1144 expr->ref->u.ar.dimen = 1;
1145 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1146 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1148 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1149 gfc_current_locus, 2,
1150 gfc_lval_expr_from_sym (idx), expr);
1151 expr->ts = idx->ts;
1153 /* (...) / sizes(idx2-1). */
1154 expr2 = gfc_get_expr ();
1155 expr2->expr_type = EXPR_OP;
1156 expr2->value.op.op = INTRINSIC_DIVIDE;
1157 expr2->value.op.op1 = expr;
1158 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1159 expr2->value.op.op2->ref = gfc_get_ref ();
1160 expr2->value.op.op2->ref->type = REF_ARRAY;
1161 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1162 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1163 expr2->value.op.op2->ref->u.ar.dimen = 1;
1164 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1165 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1166 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1167 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1168 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1169 = gfc_lval_expr_from_sym (idx2);
1170 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1171 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1172 expr2->value.op.op2->ref->u.ar.start[0]->ts
1173 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1174 expr2->ts = idx->ts;
1176 /* ... * strides(idx2). */
1177 expr = gfc_get_expr ();
1178 expr->expr_type = EXPR_OP;
1179 expr->value.op.op = INTRINSIC_TIMES;
1180 expr->value.op.op1 = expr2;
1181 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1182 expr->value.op.op2->ref = gfc_get_ref ();
1183 expr->value.op.op2->ref->type = REF_ARRAY;
1184 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1185 expr->value.op.op2->ref->u.ar.dimen = 1;
1186 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1187 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1188 expr->value.op.op2->ref->u.ar.as = strides->as;
1189 expr->ts = idx->ts;
1191 /* offset = offset + ... */
1192 block->block->next = gfc_get_code (EXEC_ASSIGN);
1193 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1194 block->block->next->expr2 = gfc_get_expr ();
1195 block->block->next->expr2->expr_type = EXPR_OP;
1196 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1197 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1198 block->block->next->expr2->value.op.op2 = expr;
1199 block->block->next->expr2->ts = idx->ts;
1201 /* After the loop: offset = offset * byte_stride. */
1202 block->next = gfc_get_code (EXEC_ASSIGN);
1203 block = block->next;
1204 block->expr1 = gfc_lval_expr_from_sym (offset);
1205 block->expr2 = gfc_get_expr ();
1206 block->expr2->expr_type = EXPR_OP;
1207 block->expr2->value.op.op = INTRINSIC_TIMES;
1208 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1209 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1210 block->expr2->ts = block->expr2->value.op.op1->ts;
1211 return block;
1215 /* Insert code of the following form:
1217 block
1218 integer(c_intptr_t) :: i
1220 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1221 && (is_contiguous || !final_rank3->attr.contiguous
1222 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1223 || 0 == STORAGE_SIZE (array)) then
1224 call final_rank3 (array)
1225 else
1226 block
1227 integer(c_intptr_t) :: offset, j
1228 type(t) :: tmp(shape (array))
1230 do i = 0, size (array)-1
1231 offset = obtain_offset(i, strides, sizes, byte_stride)
1232 addr = transfer (c_loc (array), addr) + offset
1233 call c_f_pointer (transfer (addr, cptr), ptr)
1235 addr = transfer (c_loc (tmp), addr)
1236 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1237 call c_f_pointer (transfer (addr, cptr), ptr2)
1238 ptr2 = ptr
1239 end do
1240 call final_rank3 (tmp)
1241 end block
1242 end if
1243 block */
1245 static void
1246 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1247 gfc_symbol *array, gfc_symbol *byte_stride,
1248 gfc_symbol *idx, gfc_symbol *ptr,
1249 gfc_symbol *nelem,
1250 gfc_symbol *strides, gfc_symbol *sizes,
1251 gfc_symbol *idx2, gfc_symbol *offset,
1252 gfc_symbol *is_contiguous, gfc_expr *rank,
1253 gfc_namespace *sub_ns)
1255 gfc_symbol *tmp_array, *ptr2;
1256 gfc_expr *size_expr, *offset2, *expr;
1257 gfc_namespace *ns;
1258 gfc_iterator *iter;
1259 gfc_code *block2;
1260 int i;
1262 block->next = gfc_get_code (EXEC_IF);
1263 block = block->next;
1265 block->block = gfc_get_code (EXEC_IF);
1266 block = block->block;
1268 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1269 size_expr = gfc_get_expr ();
1270 size_expr->where = gfc_current_locus;
1271 size_expr->expr_type = EXPR_OP;
1272 size_expr->value.op.op = INTRINSIC_DIVIDE;
1274 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1275 size_expr->value.op.op1
1276 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1277 "storage_size", gfc_current_locus, 2,
1278 gfc_lval_expr_from_sym (array),
1279 gfc_get_int_expr (gfc_index_integer_kind,
1280 NULL, 0));
1282 /* NUMERIC_STORAGE_SIZE. */
1283 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1284 gfc_character_storage_size);
1285 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1286 size_expr->ts = size_expr->value.op.op1->ts;
1288 /* IF condition: (stride == size_expr
1289 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1290 || is_contiguous)
1291 || 0 == size_expr. */
1292 block->expr1 = gfc_get_expr ();
1293 block->expr1->ts.type = BT_LOGICAL;
1294 block->expr1->ts.kind = gfc_default_logical_kind;
1295 block->expr1->expr_type = EXPR_OP;
1296 block->expr1->where = gfc_current_locus;
1298 block->expr1->value.op.op = INTRINSIC_OR;
1300 /* byte_stride == size_expr */
1301 expr = gfc_get_expr ();
1302 expr->ts.type = BT_LOGICAL;
1303 expr->ts.kind = gfc_default_logical_kind;
1304 expr->expr_type = EXPR_OP;
1305 expr->where = gfc_current_locus;
1306 expr->value.op.op = INTRINSIC_EQ;
1307 expr->value.op.op1
1308 = gfc_lval_expr_from_sym (byte_stride);
1309 expr->value.op.op2 = size_expr;
1311 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1312 add is_contiguous check. */
1314 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1315 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1317 gfc_expr *expr2;
1318 expr2 = gfc_get_expr ();
1319 expr2->ts.type = BT_LOGICAL;
1320 expr2->ts.kind = gfc_default_logical_kind;
1321 expr2->expr_type = EXPR_OP;
1322 expr2->where = gfc_current_locus;
1323 expr2->value.op.op = INTRINSIC_AND;
1324 expr2->value.op.op1 = expr;
1325 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1326 expr = expr2;
1329 block->expr1->value.op.op1 = expr;
1331 /* 0 == size_expr */
1332 block->expr1->value.op.op2 = gfc_get_expr ();
1333 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1334 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1335 block->expr1->value.op.op2->expr_type = EXPR_OP;
1336 block->expr1->value.op.op2->where = gfc_current_locus;
1337 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1338 block->expr1->value.op.op2->value.op.op1 =
1339 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1340 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1342 /* IF body: call final subroutine. */
1343 block->next = gfc_get_code (EXEC_CALL);
1344 block->next->symtree = fini->proc_tree;
1345 block->next->resolved_sym = fini->proc_tree->n.sym;
1346 block->next->ext.actual = gfc_get_actual_arglist ();
1347 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1349 /* ELSE. */
1351 block->block = gfc_get_code (EXEC_IF);
1352 block = block->block;
1354 /* BLOCK ... END BLOCK. */
1355 block->next = gfc_get_code (EXEC_BLOCK);
1356 block = block->next;
1358 ns = gfc_build_block_ns (sub_ns);
1359 block->ext.block.ns = ns;
1360 block->ext.block.assoc = NULL;
1362 gfc_get_symbol ("ptr2", ns, &ptr2);
1363 ptr2->ts.type = BT_DERIVED;
1364 ptr2->ts.u.derived = array->ts.u.derived;
1365 ptr2->attr.flavor = FL_VARIABLE;
1366 ptr2->attr.pointer = 1;
1367 ptr2->attr.artificial = 1;
1368 gfc_set_sym_referenced (ptr2);
1369 gfc_commit_symbol (ptr2);
1371 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1372 tmp_array->ts.type = BT_DERIVED;
1373 tmp_array->ts.u.derived = array->ts.u.derived;
1374 tmp_array->attr.flavor = FL_VARIABLE;
1375 tmp_array->attr.dimension = 1;
1376 tmp_array->attr.artificial = 1;
1377 tmp_array->as = gfc_get_array_spec();
1378 tmp_array->attr.intent = INTENT_INOUT;
1379 tmp_array->as->type = AS_EXPLICIT;
1380 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1382 for (i = 0; i < tmp_array->as->rank; i++)
1384 gfc_expr *shape_expr;
1385 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1386 NULL, 1);
1387 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1388 shape_expr
1389 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1390 gfc_current_locus, 3,
1391 gfc_lval_expr_from_sym (array),
1392 gfc_get_int_expr (gfc_default_integer_kind,
1393 NULL, i+1),
1394 gfc_get_int_expr (gfc_default_integer_kind,
1395 NULL,
1396 gfc_index_integer_kind));
1397 shape_expr->ts.kind = gfc_index_integer_kind;
1398 tmp_array->as->upper[i] = shape_expr;
1400 gfc_set_sym_referenced (tmp_array);
1401 gfc_commit_symbol (tmp_array);
1403 /* Create loop. */
1404 iter = gfc_get_iterator ();
1405 iter->var = gfc_lval_expr_from_sym (idx);
1406 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1407 iter->end = gfc_lval_expr_from_sym (nelem);
1408 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1410 block = gfc_get_code (EXEC_DO);
1411 ns->code = block;
1412 block->ext.iterator = iter;
1413 block->block = gfc_get_code (EXEC_DO);
1415 /* Offset calculation for the new array: idx * size of type (in bytes). */
1416 offset2 = gfc_get_expr ();
1417 offset2->expr_type = EXPR_OP;
1418 offset2->value.op.op = INTRINSIC_TIMES;
1419 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1420 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1421 offset2->ts = byte_stride->ts;
1423 /* Offset calculation of "array". */
1424 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1425 byte_stride, rank, block->block, sub_ns);
1427 /* Create code for
1428 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1429 + idx * stride, c_ptr), ptr). */
1430 block2->next = finalization_scalarizer (array, ptr,
1431 gfc_lval_expr_from_sym (offset),
1432 sub_ns);
1433 block2 = block2->next;
1434 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1435 block2 = block2->next;
1437 /* ptr2 = ptr. */
1438 block2->next = gfc_get_code (EXEC_ASSIGN);
1439 block2 = block2->next;
1440 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1441 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1443 /* Call now the user's final subroutine. */
1444 block->next = gfc_get_code (EXEC_CALL);
1445 block = block->next;
1446 block->symtree = fini->proc_tree;
1447 block->resolved_sym = fini->proc_tree->n.sym;
1448 block->ext.actual = gfc_get_actual_arglist ();
1449 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1451 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1452 return;
1454 /* Copy back. */
1456 /* Loop. */
1457 iter = gfc_get_iterator ();
1458 iter->var = gfc_lval_expr_from_sym (idx);
1459 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1460 iter->end = gfc_lval_expr_from_sym (nelem);
1461 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1463 block->next = gfc_get_code (EXEC_DO);
1464 block = block->next;
1465 block->ext.iterator = iter;
1466 block->block = gfc_get_code (EXEC_DO);
1468 /* Offset calculation of "array". */
1469 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1470 byte_stride, rank, block->block, sub_ns);
1472 /* Create code for
1473 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1474 + offset, c_ptr), ptr). */
1475 block2->next = finalization_scalarizer (array, ptr,
1476 gfc_lval_expr_from_sym (offset),
1477 sub_ns);
1478 block2 = block2->next;
1479 block2->next = finalization_scalarizer (tmp_array, ptr2,
1480 gfc_copy_expr (offset2), sub_ns);
1481 block2 = block2->next;
1483 /* ptr = ptr2. */
1484 block2->next = gfc_get_code (EXEC_ASSIGN);
1485 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1486 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1490 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1491 derived type "derived". The function first calls the approriate FINAL
1492 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1493 components (but not the inherited ones). Last, it calls the wrapper
1494 subroutine of the parent. The generated wrapper procedure takes as argument
1495 an assumed-rank array.
1496 If neither allocatable components nor FINAL subroutines exists, the vtab
1497 will contain a NULL pointer.
1498 The generated function has the form
1499 _final(assumed-rank array, stride, skip_corarray)
1500 where the array has to be contiguous (except of the lowest dimension). The
1501 stride (in bytes) is used to allow different sizes for ancestor types by
1502 skipping over the additionally added components in the scalarizer. If
1503 "fini_coarray" is false, coarray components are not finalized to allow for
1504 the correct semantic with intrinsic assignment. */
1506 static void
1507 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1508 const char *tname, gfc_component *vtab_final)
1510 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1511 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1512 gfc_component *comp;
1513 gfc_namespace *sub_ns;
1514 gfc_code *last_code, *block;
1515 char name[GFC_MAX_SYMBOL_LEN+1];
1516 bool finalizable_comp = false;
1517 bool expr_null_wrapper = false;
1518 gfc_expr *ancestor_wrapper = NULL, *rank;
1519 gfc_iterator *iter;
1521 if (derived->attr.unlimited_polymorphic)
1523 vtab_final->initializer = gfc_get_null_expr (NULL);
1524 return;
1527 /* Search for the ancestor's finalizers. */
1528 if (derived->attr.extension && derived->components
1529 && (!derived->components->ts.u.derived->attr.abstract
1530 || has_finalizer_component (derived)))
1532 gfc_symbol *vtab;
1533 gfc_component *comp;
1535 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1536 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1537 if (comp->name[0] == '_' && comp->name[1] == 'f')
1539 ancestor_wrapper = comp->initializer;
1540 break;
1544 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1545 components: Return a NULL() expression; we defer this a bit to have have
1546 an interface declaration. */
1547 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1548 && !derived->attr.alloc_comp
1549 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1550 && !has_finalizer_component (derived))
1551 expr_null_wrapper = true;
1552 else
1553 /* Check whether there are new allocatable components. */
1554 for (comp = derived->components; comp; comp = comp->next)
1556 if (comp == derived->components && derived->attr.extension
1557 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1558 continue;
1560 finalizable_comp |= comp_is_finalizable (comp);
1563 /* If there is no new finalizer and no new allocatable, return with
1564 an expr to the ancestor's one. */
1565 if (!expr_null_wrapper && !finalizable_comp
1566 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1568 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1569 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1570 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1571 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1572 return;
1575 /* We now create a wrapper, which does the following:
1576 1. Call the suitable finalization subroutine for this type
1577 2. Loop over all noninherited allocatable components and noninherited
1578 components with allocatable components and DEALLOCATE those; this will
1579 take care of finalizers, coarray deregistering and allocatable
1580 nested components.
1581 3. Call the ancestor's finalizer. */
1583 /* Declare the wrapper function; it takes an assumed-rank array
1584 and a VALUE logical as arguments. */
1586 /* Set up the namespace. */
1587 sub_ns = gfc_get_namespace (ns, 0);
1588 sub_ns->sibling = ns->contained;
1589 if (!expr_null_wrapper)
1590 ns->contained = sub_ns;
1591 sub_ns->resolved = 1;
1593 /* Set up the procedure symbol. */
1594 sprintf (name, "__final_%s", tname);
1595 gfc_get_symbol (name, sub_ns, &final);
1596 sub_ns->proc_name = final;
1597 final->attr.flavor = FL_PROCEDURE;
1598 final->attr.function = 1;
1599 final->attr.pure = 0;
1600 final->result = final;
1601 final->ts.type = BT_INTEGER;
1602 final->ts.kind = 4;
1603 final->attr.artificial = 1;
1604 final->attr.always_explicit = 1;
1605 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1606 if (ns->proc_name->attr.flavor == FL_MODULE)
1607 final->module = ns->proc_name->name;
1608 gfc_set_sym_referenced (final);
1609 gfc_commit_symbol (final);
1611 /* Set up formal argument. */
1612 gfc_get_symbol ("array", sub_ns, &array);
1613 array->ts.type = BT_DERIVED;
1614 array->ts.u.derived = derived;
1615 array->attr.flavor = FL_VARIABLE;
1616 array->attr.dummy = 1;
1617 array->attr.contiguous = 1;
1618 array->attr.dimension = 1;
1619 array->attr.artificial = 1;
1620 array->as = gfc_get_array_spec();
1621 array->as->type = AS_ASSUMED_RANK;
1622 array->as->rank = -1;
1623 array->attr.intent = INTENT_INOUT;
1624 gfc_set_sym_referenced (array);
1625 final->formal = gfc_get_formal_arglist ();
1626 final->formal->sym = array;
1627 gfc_commit_symbol (array);
1629 /* Set up formal argument. */
1630 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1631 byte_stride->ts.type = BT_INTEGER;
1632 byte_stride->ts.kind = gfc_index_integer_kind;
1633 byte_stride->attr.flavor = FL_VARIABLE;
1634 byte_stride->attr.dummy = 1;
1635 byte_stride->attr.value = 1;
1636 byte_stride->attr.artificial = 1;
1637 gfc_set_sym_referenced (byte_stride);
1638 final->formal->next = gfc_get_formal_arglist ();
1639 final->formal->next->sym = byte_stride;
1640 gfc_commit_symbol (byte_stride);
1642 /* Set up formal argument. */
1643 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1644 fini_coarray->ts.type = BT_LOGICAL;
1645 fini_coarray->ts.kind = 1;
1646 fini_coarray->attr.flavor = FL_VARIABLE;
1647 fini_coarray->attr.dummy = 1;
1648 fini_coarray->attr.value = 1;
1649 fini_coarray->attr.artificial = 1;
1650 gfc_set_sym_referenced (fini_coarray);
1651 final->formal->next->next = gfc_get_formal_arglist ();
1652 final->formal->next->next->sym = fini_coarray;
1653 gfc_commit_symbol (fini_coarray);
1655 /* Return with a NULL() expression but with an interface which has
1656 the formal arguments. */
1657 if (expr_null_wrapper)
1659 vtab_final->initializer = gfc_get_null_expr (NULL);
1660 vtab_final->ts.interface = final;
1661 return;
1664 /* Local variables. */
1666 gfc_get_symbol ("idx", sub_ns, &idx);
1667 idx->ts.type = BT_INTEGER;
1668 idx->ts.kind = gfc_index_integer_kind;
1669 idx->attr.flavor = FL_VARIABLE;
1670 idx->attr.artificial = 1;
1671 gfc_set_sym_referenced (idx);
1672 gfc_commit_symbol (idx);
1674 gfc_get_symbol ("idx2", sub_ns, &idx2);
1675 idx2->ts.type = BT_INTEGER;
1676 idx2->ts.kind = gfc_index_integer_kind;
1677 idx2->attr.flavor = FL_VARIABLE;
1678 idx2->attr.artificial = 1;
1679 gfc_set_sym_referenced (idx2);
1680 gfc_commit_symbol (idx2);
1682 gfc_get_symbol ("offset", sub_ns, &offset);
1683 offset->ts.type = BT_INTEGER;
1684 offset->ts.kind = gfc_index_integer_kind;
1685 offset->attr.flavor = FL_VARIABLE;
1686 offset->attr.artificial = 1;
1687 gfc_set_sym_referenced (offset);
1688 gfc_commit_symbol (offset);
1690 /* Create RANK expression. */
1691 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1692 gfc_current_locus, 1,
1693 gfc_lval_expr_from_sym (array));
1694 if (rank->ts.kind != idx->ts.kind)
1695 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1697 /* Create is_contiguous variable. */
1698 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1699 is_contiguous->ts.type = BT_LOGICAL;
1700 is_contiguous->ts.kind = gfc_default_logical_kind;
1701 is_contiguous->attr.flavor = FL_VARIABLE;
1702 is_contiguous->attr.artificial = 1;
1703 gfc_set_sym_referenced (is_contiguous);
1704 gfc_commit_symbol (is_contiguous);
1706 /* Create "sizes(0..rank)" variable, which contains the multiplied
1707 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1708 sizes(2) = sizes(1) * extent(dim=2) etc. */
1709 gfc_get_symbol ("sizes", sub_ns, &sizes);
1710 sizes->ts.type = BT_INTEGER;
1711 sizes->ts.kind = gfc_index_integer_kind;
1712 sizes->attr.flavor = FL_VARIABLE;
1713 sizes->attr.dimension = 1;
1714 sizes->attr.artificial = 1;
1715 sizes->as = gfc_get_array_spec();
1716 sizes->attr.intent = INTENT_INOUT;
1717 sizes->as->type = AS_EXPLICIT;
1718 sizes->as->rank = 1;
1719 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1720 sizes->as->upper[0] = gfc_copy_expr (rank);
1721 gfc_set_sym_referenced (sizes);
1722 gfc_commit_symbol (sizes);
1724 /* Create "strides(1..rank)" variable, which contains the strides per
1725 dimension. */
1726 gfc_get_symbol ("strides", sub_ns, &strides);
1727 strides->ts.type = BT_INTEGER;
1728 strides->ts.kind = gfc_index_integer_kind;
1729 strides->attr.flavor = FL_VARIABLE;
1730 strides->attr.dimension = 1;
1731 strides->attr.artificial = 1;
1732 strides->as = gfc_get_array_spec();
1733 strides->attr.intent = INTENT_INOUT;
1734 strides->as->type = AS_EXPLICIT;
1735 strides->as->rank = 1;
1736 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1737 strides->as->upper[0] = gfc_copy_expr (rank);
1738 gfc_set_sym_referenced (strides);
1739 gfc_commit_symbol (strides);
1742 /* Set return value to 0. */
1743 last_code = gfc_get_code (EXEC_ASSIGN);
1744 last_code->expr1 = gfc_lval_expr_from_sym (final);
1745 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1746 sub_ns->code = last_code;
1748 /* Set: is_contiguous = .true. */
1749 last_code->next = gfc_get_code (EXEC_ASSIGN);
1750 last_code = last_code->next;
1751 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1752 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1753 &gfc_current_locus, true);
1755 /* Set: sizes(0) = 1. */
1756 last_code->next = gfc_get_code (EXEC_ASSIGN);
1757 last_code = last_code->next;
1758 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1759 last_code->expr1->ref = gfc_get_ref ();
1760 last_code->expr1->ref->type = REF_ARRAY;
1761 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1762 last_code->expr1->ref->u.ar.dimen = 1;
1763 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1764 last_code->expr1->ref->u.ar.start[0]
1765 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1766 last_code->expr1->ref->u.ar.as = sizes->as;
1767 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1769 /* Create:
1770 DO idx = 1, rank
1771 strides(idx) = _F._stride (array, dim=idx)
1772 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1773 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1774 END DO. */
1776 /* Create loop. */
1777 iter = gfc_get_iterator ();
1778 iter->var = gfc_lval_expr_from_sym (idx);
1779 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1780 iter->end = gfc_copy_expr (rank);
1781 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1782 last_code->next = gfc_get_code (EXEC_DO);
1783 last_code = last_code->next;
1784 last_code->ext.iterator = iter;
1785 last_code->block = gfc_get_code (EXEC_DO);
1787 /* strides(idx) = _F._stride(array,dim=idx). */
1788 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1789 block = last_code->block->next;
1791 block->expr1 = gfc_lval_expr_from_sym (strides);
1792 block->expr1->ref = gfc_get_ref ();
1793 block->expr1->ref->type = REF_ARRAY;
1794 block->expr1->ref->u.ar.type = AR_ELEMENT;
1795 block->expr1->ref->u.ar.dimen = 1;
1796 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1797 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1798 block->expr1->ref->u.ar.as = strides->as;
1800 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1801 gfc_current_locus, 2,
1802 gfc_lval_expr_from_sym (array),
1803 gfc_lval_expr_from_sym (idx));
1805 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1806 block->next = gfc_get_code (EXEC_ASSIGN);
1807 block = block->next;
1809 /* sizes(idx) = ... */
1810 block->expr1 = gfc_lval_expr_from_sym (sizes);
1811 block->expr1->ref = gfc_get_ref ();
1812 block->expr1->ref->type = REF_ARRAY;
1813 block->expr1->ref->u.ar.type = AR_ELEMENT;
1814 block->expr1->ref->u.ar.dimen = 1;
1815 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1816 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1817 block->expr1->ref->u.ar.as = sizes->as;
1819 block->expr2 = gfc_get_expr ();
1820 block->expr2->expr_type = EXPR_OP;
1821 block->expr2->value.op.op = INTRINSIC_TIMES;
1823 /* sizes(idx-1). */
1824 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1825 block->expr2->value.op.op1->ref = gfc_get_ref ();
1826 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1827 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1828 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1829 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1830 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1831 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1832 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1833 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1834 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1835 = gfc_lval_expr_from_sym (idx);
1836 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1837 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1838 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1839 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1841 /* size(array, dim=idx, kind=index_kind). */
1842 block->expr2->value.op.op2
1843 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1844 gfc_current_locus, 3,
1845 gfc_lval_expr_from_sym (array),
1846 gfc_lval_expr_from_sym (idx),
1847 gfc_get_int_expr (gfc_index_integer_kind,
1848 NULL,
1849 gfc_index_integer_kind));
1850 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1851 block->expr2->ts = idx->ts;
1853 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1854 block->next = gfc_get_code (EXEC_IF);
1855 block = block->next;
1857 block->block = gfc_get_code (EXEC_IF);
1858 block = block->block;
1860 /* if condition: strides(idx) /= sizes(idx-1). */
1861 block->expr1 = gfc_get_expr ();
1862 block->expr1->ts.type = BT_LOGICAL;
1863 block->expr1->ts.kind = gfc_default_logical_kind;
1864 block->expr1->expr_type = EXPR_OP;
1865 block->expr1->where = gfc_current_locus;
1866 block->expr1->value.op.op = INTRINSIC_NE;
1868 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1869 block->expr1->value.op.op1->ref = gfc_get_ref ();
1870 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1871 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1872 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1873 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1874 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1875 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1877 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1878 block->expr1->value.op.op2->ref = gfc_get_ref ();
1879 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1880 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1881 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1882 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1883 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1884 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1885 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1886 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1887 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1888 = gfc_lval_expr_from_sym (idx);
1889 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1890 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1891 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1892 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1894 /* if body: is_contiguous = .false. */
1895 block->next = gfc_get_code (EXEC_ASSIGN);
1896 block = block->next;
1897 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1898 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1899 &gfc_current_locus, false);
1901 /* Obtain the size (number of elements) of "array" MINUS ONE,
1902 which is used in the scalarization. */
1903 gfc_get_symbol ("nelem", sub_ns, &nelem);
1904 nelem->ts.type = BT_INTEGER;
1905 nelem->ts.kind = gfc_index_integer_kind;
1906 nelem->attr.flavor = FL_VARIABLE;
1907 nelem->attr.artificial = 1;
1908 gfc_set_sym_referenced (nelem);
1909 gfc_commit_symbol (nelem);
1911 /* nelem = sizes (rank) - 1. */
1912 last_code->next = gfc_get_code (EXEC_ASSIGN);
1913 last_code = last_code->next;
1915 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
1917 last_code->expr2 = gfc_get_expr ();
1918 last_code->expr2->expr_type = EXPR_OP;
1919 last_code->expr2->value.op.op = INTRINSIC_MINUS;
1920 last_code->expr2->value.op.op2
1921 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1922 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
1924 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1925 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
1926 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
1927 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1928 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
1929 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1930 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
1931 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1933 /* Call final subroutines. We now generate code like:
1934 use iso_c_binding
1935 integer, pointer :: ptr
1936 type(c_ptr) :: cptr
1937 integer(c_intptr_t) :: i, addr
1939 select case (rank (array))
1940 case (3)
1941 ! If needed, the array is packed
1942 call final_rank3 (array)
1943 case default:
1944 do i = 0, size (array)-1
1945 addr = transfer (c_loc (array), addr) + i * stride
1946 call c_f_pointer (transfer (addr, cptr), ptr)
1947 call elemental_final (ptr)
1948 end do
1949 end select */
1951 if (derived->f2k_derived && derived->f2k_derived->finalizers)
1953 gfc_finalizer *fini, *fini_elem = NULL;
1955 gfc_get_symbol ("ptr1", sub_ns, &ptr);
1956 ptr->ts.type = BT_DERIVED;
1957 ptr->ts.u.derived = derived;
1958 ptr->attr.flavor = FL_VARIABLE;
1959 ptr->attr.pointer = 1;
1960 ptr->attr.artificial = 1;
1961 gfc_set_sym_referenced (ptr);
1962 gfc_commit_symbol (ptr);
1964 /* SELECT CASE (RANK (array)). */
1965 last_code->next = gfc_get_code (EXEC_SELECT);
1966 last_code = last_code->next;
1967 last_code->expr1 = gfc_copy_expr (rank);
1968 block = NULL;
1970 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
1972 gcc_assert (fini->proc_tree); /* Should have been set in gfc_resolve_finalizers. */
1973 if (fini->proc_tree->n.sym->attr.elemental)
1975 fini_elem = fini;
1976 continue;
1979 /* CASE (fini_rank). */
1980 if (block)
1982 block->block = gfc_get_code (EXEC_SELECT);
1983 block = block->block;
1985 else
1987 block = gfc_get_code (EXEC_SELECT);
1988 last_code->block = block;
1990 block->ext.block.case_list = gfc_get_case ();
1991 block->ext.block.case_list->where = gfc_current_locus;
1992 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1993 block->ext.block.case_list->low
1994 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
1995 fini->proc_tree->n.sym->formal->sym->as->rank);
1996 else
1997 block->ext.block.case_list->low
1998 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1999 block->ext.block.case_list->high
2000 = gfc_copy_expr (block->ext.block.case_list->low);
2002 /* CALL fini_rank (array) - possibly with packing. */
2003 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2004 finalizer_insert_packed_call (block, fini, array, byte_stride,
2005 idx, ptr, nelem, strides,
2006 sizes, idx2, offset, is_contiguous,
2007 rank, sub_ns);
2008 else
2010 block->next = gfc_get_code (EXEC_CALL);
2011 block->next->symtree = fini->proc_tree;
2012 block->next->resolved_sym = fini->proc_tree->n.sym;
2013 block->next->ext.actual = gfc_get_actual_arglist ();
2014 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
2018 /* Elemental call - scalarized. */
2019 if (fini_elem)
2021 /* CASE DEFAULT. */
2022 if (block)
2024 block->block = gfc_get_code (EXEC_SELECT);
2025 block = block->block;
2027 else
2029 block = gfc_get_code (EXEC_SELECT);
2030 last_code->block = block;
2032 block->ext.block.case_list = gfc_get_case ();
2034 /* Create loop. */
2035 iter = gfc_get_iterator ();
2036 iter->var = gfc_lval_expr_from_sym (idx);
2037 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2038 iter->end = gfc_lval_expr_from_sym (nelem);
2039 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2040 block->next = gfc_get_code (EXEC_DO);
2041 block = block->next;
2042 block->ext.iterator = iter;
2043 block->block = gfc_get_code (EXEC_DO);
2045 /* Offset calculation. */
2046 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2047 byte_stride, rank, block->block,
2048 sub_ns);
2050 /* Create code for
2051 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2052 + offset, c_ptr), ptr). */
2053 block->next
2054 = finalization_scalarizer (array, ptr,
2055 gfc_lval_expr_from_sym (offset),
2056 sub_ns);
2057 block = block->next;
2059 /* CALL final_elemental (array). */
2060 block->next = gfc_get_code (EXEC_CALL);
2061 block = block->next;
2062 block->symtree = fini_elem->proc_tree;
2063 block->resolved_sym = fini_elem->proc_sym;
2064 block->ext.actual = gfc_get_actual_arglist ();
2065 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
2069 /* Finalize and deallocate allocatable components. The same manual
2070 scalarization is used as above. */
2072 if (finalizable_comp)
2074 gfc_symbol *stat;
2075 gfc_code *block = NULL;
2077 if (!ptr)
2079 gfc_get_symbol ("ptr2", sub_ns, &ptr);
2080 ptr->ts.type = BT_DERIVED;
2081 ptr->ts.u.derived = derived;
2082 ptr->attr.flavor = FL_VARIABLE;
2083 ptr->attr.pointer = 1;
2084 ptr->attr.artificial = 1;
2085 gfc_set_sym_referenced (ptr);
2086 gfc_commit_symbol (ptr);
2089 gfc_get_symbol ("ignore", sub_ns, &stat);
2090 stat->attr.flavor = FL_VARIABLE;
2091 stat->attr.artificial = 1;
2092 stat->ts.type = BT_INTEGER;
2093 stat->ts.kind = gfc_default_integer_kind;
2094 gfc_set_sym_referenced (stat);
2095 gfc_commit_symbol (stat);
2097 /* Create loop. */
2098 iter = gfc_get_iterator ();
2099 iter->var = gfc_lval_expr_from_sym (idx);
2100 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2101 iter->end = gfc_lval_expr_from_sym (nelem);
2102 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2103 last_code->next = gfc_get_code (EXEC_DO);
2104 last_code = last_code->next;
2105 last_code->ext.iterator = iter;
2106 last_code->block = gfc_get_code (EXEC_DO);
2108 /* Offset calculation. */
2109 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2110 byte_stride, rank, last_code->block,
2111 sub_ns);
2113 /* Create code for
2114 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2115 + idx * stride, c_ptr), ptr). */
2116 block->next = finalization_scalarizer (array, ptr,
2117 gfc_lval_expr_from_sym(offset),
2118 sub_ns);
2119 block = block->next;
2121 for (comp = derived->components; comp; comp = comp->next)
2123 if (comp == derived->components && derived->attr.extension
2124 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2125 continue;
2127 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2128 stat, fini_coarray, &block, sub_ns);
2129 if (!last_code->block->next)
2130 last_code->block->next = block;
2135 /* Call the finalizer of the ancestor. */
2136 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2138 last_code->next = gfc_get_code (EXEC_CALL);
2139 last_code = last_code->next;
2140 last_code->symtree = ancestor_wrapper->symtree;
2141 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2143 last_code->ext.actual = gfc_get_actual_arglist ();
2144 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2145 last_code->ext.actual->next = gfc_get_actual_arglist ();
2146 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2147 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2148 last_code->ext.actual->next->next->expr
2149 = gfc_lval_expr_from_sym (fini_coarray);
2152 gfc_free_expr (rank);
2153 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2154 vtab_final->ts.interface = final;
2158 /* Add procedure pointers for all type-bound procedures to a vtab. */
2160 static void
2161 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2163 gfc_symbol* super_type;
2165 super_type = gfc_get_derived_super_type (derived);
2167 if (super_type && (super_type != derived))
2169 /* Make sure that the PPCs appear in the same order as in the parent. */
2170 copy_vtab_proc_comps (super_type, vtype);
2171 /* Only needed to get the PPC initializers right. */
2172 add_procs_to_declared_vtab (super_type, vtype);
2175 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2176 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2178 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2179 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2183 /* Find or generate the symbol for a derived type's vtab. */
2185 gfc_symbol *
2186 gfc_find_derived_vtab (gfc_symbol *derived)
2188 gfc_namespace *ns;
2189 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2190 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2192 /* Find the top-level namespace. */
2193 for (ns = gfc_current_ns; ns; ns = ns->parent)
2194 if (!ns->parent)
2195 break;
2197 /* If the type is a class container, use the underlying derived type. */
2198 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2199 derived = gfc_get_derived_super_type (derived);
2201 if (ns)
2203 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2205 get_unique_hashed_string (tname, derived);
2206 sprintf (name, "__vtab_%s", tname);
2208 /* Look for the vtab symbol in various namespaces. */
2209 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2210 if (vtab == NULL)
2211 gfc_find_symbol (name, ns, 0, &vtab);
2212 if (vtab == NULL)
2213 gfc_find_symbol (name, derived->ns, 0, &vtab);
2215 if (vtab == NULL)
2217 gfc_get_symbol (name, ns, &vtab);
2218 vtab->ts.type = BT_DERIVED;
2219 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2220 &gfc_current_locus))
2221 goto cleanup;
2222 vtab->attr.target = 1;
2223 vtab->attr.save = SAVE_IMPLICIT;
2224 vtab->attr.vtab = 1;
2225 vtab->attr.access = ACCESS_PUBLIC;
2226 gfc_set_sym_referenced (vtab);
2227 sprintf (name, "__vtype_%s", tname);
2229 gfc_find_symbol (name, ns, 0, &vtype);
2230 if (vtype == NULL)
2232 gfc_component *c;
2233 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2235 gfc_get_symbol (name, ns, &vtype);
2236 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2237 &gfc_current_locus))
2238 goto cleanup;
2239 vtype->attr.access = ACCESS_PUBLIC;
2240 vtype->attr.vtype = 1;
2241 gfc_set_sym_referenced (vtype);
2243 /* Add component '_hash'. */
2244 if (!gfc_add_component (vtype, "_hash", &c))
2245 goto cleanup;
2246 c->ts.type = BT_INTEGER;
2247 c->ts.kind = 4;
2248 c->attr.access = ACCESS_PRIVATE;
2249 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2250 NULL, derived->hash_value);
2252 /* Add component '_size'. */
2253 if (!gfc_add_component (vtype, "_size", &c))
2254 goto cleanup;
2255 c->ts.type = BT_INTEGER;
2256 c->ts.kind = 4;
2257 c->attr.access = ACCESS_PRIVATE;
2258 /* Remember the derived type in ts.u.derived,
2259 so that the correct initializer can be set later on
2260 (in gfc_conv_structure). */
2261 c->ts.u.derived = derived;
2262 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2263 NULL, 0);
2265 /* Add component _extends. */
2266 if (!gfc_add_component (vtype, "_extends", &c))
2267 goto cleanup;
2268 c->attr.pointer = 1;
2269 c->attr.access = ACCESS_PRIVATE;
2270 if (!derived->attr.unlimited_polymorphic)
2271 parent = gfc_get_derived_super_type (derived);
2272 else
2273 parent = NULL;
2275 if (parent)
2277 parent_vtab = gfc_find_derived_vtab (parent);
2278 c->ts.type = BT_DERIVED;
2279 c->ts.u.derived = parent_vtab->ts.u.derived;
2280 c->initializer = gfc_get_expr ();
2281 c->initializer->expr_type = EXPR_VARIABLE;
2282 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2283 0, &c->initializer->symtree);
2285 else
2287 c->ts.type = BT_DERIVED;
2288 c->ts.u.derived = vtype;
2289 c->initializer = gfc_get_null_expr (NULL);
2292 if (!derived->attr.unlimited_polymorphic
2293 && derived->components == NULL
2294 && !derived->attr.zero_comp)
2296 /* At this point an error must have occurred.
2297 Prevent further errors on the vtype components. */
2298 found_sym = vtab;
2299 goto have_vtype;
2302 /* Add component _def_init. */
2303 if (!gfc_add_component (vtype, "_def_init", &c))
2304 goto cleanup;
2305 c->attr.pointer = 1;
2306 c->attr.artificial = 1;
2307 c->attr.access = ACCESS_PRIVATE;
2308 c->ts.type = BT_DERIVED;
2309 c->ts.u.derived = derived;
2310 if (derived->attr.unlimited_polymorphic
2311 || derived->attr.abstract)
2312 c->initializer = gfc_get_null_expr (NULL);
2313 else
2315 /* Construct default initialization variable. */
2316 sprintf (name, "__def_init_%s", tname);
2317 gfc_get_symbol (name, ns, &def_init);
2318 def_init->attr.target = 1;
2319 def_init->attr.artificial = 1;
2320 def_init->attr.save = SAVE_IMPLICIT;
2321 def_init->attr.access = ACCESS_PUBLIC;
2322 def_init->attr.flavor = FL_VARIABLE;
2323 gfc_set_sym_referenced (def_init);
2324 def_init->ts.type = BT_DERIVED;
2325 def_init->ts.u.derived = derived;
2326 def_init->value = gfc_default_initializer (&def_init->ts);
2328 c->initializer = gfc_lval_expr_from_sym (def_init);
2331 /* Add component _copy. */
2332 if (!gfc_add_component (vtype, "_copy", &c))
2333 goto cleanup;
2334 c->attr.proc_pointer = 1;
2335 c->attr.access = ACCESS_PRIVATE;
2336 c->tb = XCNEW (gfc_typebound_proc);
2337 c->tb->ppc = 1;
2338 if (derived->attr.unlimited_polymorphic
2339 || derived->attr.abstract)
2340 c->initializer = gfc_get_null_expr (NULL);
2341 else
2343 /* Set up namespace. */
2344 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2345 sub_ns->sibling = ns->contained;
2346 ns->contained = sub_ns;
2347 sub_ns->resolved = 1;
2348 /* Set up procedure symbol. */
2349 sprintf (name, "__copy_%s", tname);
2350 gfc_get_symbol (name, sub_ns, &copy);
2351 sub_ns->proc_name = copy;
2352 copy->attr.flavor = FL_PROCEDURE;
2353 copy->attr.subroutine = 1;
2354 copy->attr.pure = 1;
2355 copy->attr.artificial = 1;
2356 copy->attr.if_source = IFSRC_DECL;
2357 /* This is elemental so that arrays are automatically
2358 treated correctly by the scalarizer. */
2359 copy->attr.elemental = 1;
2360 if (ns->proc_name->attr.flavor == FL_MODULE)
2361 copy->module = ns->proc_name->name;
2362 gfc_set_sym_referenced (copy);
2363 /* Set up formal arguments. */
2364 gfc_get_symbol ("src", sub_ns, &src);
2365 src->ts.type = BT_DERIVED;
2366 src->ts.u.derived = derived;
2367 src->attr.flavor = FL_VARIABLE;
2368 src->attr.dummy = 1;
2369 src->attr.artificial = 1;
2370 src->attr.intent = INTENT_IN;
2371 gfc_set_sym_referenced (src);
2372 copy->formal = gfc_get_formal_arglist ();
2373 copy->formal->sym = src;
2374 gfc_get_symbol ("dst", sub_ns, &dst);
2375 dst->ts.type = BT_DERIVED;
2376 dst->ts.u.derived = derived;
2377 dst->attr.flavor = FL_VARIABLE;
2378 dst->attr.dummy = 1;
2379 dst->attr.artificial = 1;
2380 dst->attr.intent = INTENT_INOUT;
2381 gfc_set_sym_referenced (dst);
2382 copy->formal->next = gfc_get_formal_arglist ();
2383 copy->formal->next->sym = dst;
2384 /* Set up code. */
2385 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2386 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2387 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2388 /* Set initializer. */
2389 c->initializer = gfc_lval_expr_from_sym (copy);
2390 c->ts.interface = copy;
2393 /* Add component _final, which contains a procedure pointer to
2394 a wrapper which handles both the freeing of allocatable
2395 components and the calls to finalization subroutines.
2396 Note: The actual wrapper function can only be generated
2397 at resolution time. */
2398 if (!gfc_add_component (vtype, "_final", &c))
2399 goto cleanup;
2400 c->attr.proc_pointer = 1;
2401 c->attr.access = ACCESS_PRIVATE;
2402 c->tb = XCNEW (gfc_typebound_proc);
2403 c->tb->ppc = 1;
2404 generate_finalization_wrapper (derived, ns, tname, c);
2406 /* Add procedure pointers for type-bound procedures. */
2407 if (!derived->attr.unlimited_polymorphic)
2408 add_procs_to_declared_vtab (derived, vtype);
2411 have_vtype:
2412 vtab->ts.u.derived = vtype;
2413 vtab->value = gfc_default_initializer (&vtab->ts);
2417 found_sym = vtab;
2419 cleanup:
2420 /* It is unexpected to have some symbols added at resolution or code
2421 generation time. We commit the changes in order to keep a clean state. */
2422 if (found_sym)
2424 gfc_commit_symbol (vtab);
2425 if (vtype)
2426 gfc_commit_symbol (vtype);
2427 if (def_init)
2428 gfc_commit_symbol (def_init);
2429 if (copy)
2430 gfc_commit_symbol (copy);
2431 if (src)
2432 gfc_commit_symbol (src);
2433 if (dst)
2434 gfc_commit_symbol (dst);
2436 else
2437 gfc_undo_symbols ();
2439 return found_sym;
2443 /* Check if a derived type is finalizable. That is the case if it
2444 (1) has a FINAL subroutine or
2445 (2) has a nonpointer nonallocatable component of finalizable type.
2446 If it is finalizable, return an expression containing the
2447 finalization wrapper. */
2449 bool
2450 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2452 gfc_symbol *vtab;
2453 gfc_component *c;
2455 /* (1) Check for FINAL subroutines. */
2456 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2457 goto yes;
2459 /* (2) Check for components of finalizable type. */
2460 for (c = derived->components; c; c = c->next)
2461 if (c->ts.type == BT_DERIVED
2462 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2463 && gfc_is_finalizable (c->ts.u.derived, NULL))
2464 goto yes;
2466 return false;
2468 yes:
2469 /* Make sure vtab is generated. */
2470 vtab = gfc_find_derived_vtab (derived);
2471 if (final_expr)
2473 /* Return finalizer expression. */
2474 gfc_component *final;
2475 final = vtab->ts.u.derived->components->next->next->next->next->next;
2476 gcc_assert (strcmp (final->name, "_final") == 0);
2477 gcc_assert (final->initializer
2478 && final->initializer->expr_type != EXPR_NULL);
2479 *final_expr = final->initializer;
2481 return true;
2485 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2486 needed to support unlimited polymorphism. */
2488 static gfc_symbol *
2489 find_intrinsic_vtab (gfc_typespec *ts)
2491 gfc_namespace *ns;
2492 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2493 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2494 int charlen = 0;
2496 if (ts->type == BT_CHARACTER && !ts->deferred && ts->u.cl && ts->u.cl->length
2497 && ts->u.cl->length->expr_type == EXPR_CONSTANT)
2498 charlen = mpz_get_si (ts->u.cl->length->value.integer);
2500 /* Find the top-level namespace. */
2501 for (ns = gfc_current_ns; ns; ns = ns->parent)
2502 if (!ns->parent)
2503 break;
2505 if (ns)
2507 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2509 if (ts->type == BT_CHARACTER)
2510 sprintf (tname, "%s_%d_%d", gfc_basic_typename (ts->type),
2511 charlen, ts->kind);
2512 else
2513 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2515 sprintf (name, "__vtab_%s", tname);
2517 /* Look for the vtab symbol in the top-level namespace only. */
2518 gfc_find_symbol (name, ns, 0, &vtab);
2520 if (vtab == NULL)
2522 gfc_get_symbol (name, ns, &vtab);
2523 vtab->ts.type = BT_DERIVED;
2524 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2525 &gfc_current_locus))
2526 goto cleanup;
2527 vtab->attr.target = 1;
2528 vtab->attr.save = SAVE_IMPLICIT;
2529 vtab->attr.vtab = 1;
2530 vtab->attr.access = ACCESS_PUBLIC;
2531 gfc_set_sym_referenced (vtab);
2532 sprintf (name, "__vtype_%s", tname);
2534 gfc_find_symbol (name, ns, 0, &vtype);
2535 if (vtype == NULL)
2537 gfc_component *c;
2538 int hash;
2539 gfc_namespace *sub_ns;
2540 gfc_namespace *contained;
2541 gfc_expr *e;
2543 gfc_get_symbol (name, ns, &vtype);
2544 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2545 &gfc_current_locus))
2546 goto cleanup;
2547 vtype->attr.access = ACCESS_PUBLIC;
2548 vtype->attr.vtype = 1;
2549 gfc_set_sym_referenced (vtype);
2551 /* Add component '_hash'. */
2552 if (!gfc_add_component (vtype, "_hash", &c))
2553 goto cleanup;
2554 c->ts.type = BT_INTEGER;
2555 c->ts.kind = 4;
2556 c->attr.access = ACCESS_PRIVATE;
2557 hash = gfc_intrinsic_hash_value (ts);
2558 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2559 NULL, hash);
2561 /* Add component '_size'. */
2562 if (!gfc_add_component (vtype, "_size", &c))
2563 goto cleanup;
2564 c->ts.type = BT_INTEGER;
2565 c->ts.kind = 4;
2566 c->attr.access = ACCESS_PRIVATE;
2568 /* Build a minimal expression to make use of
2569 target-memory.c/gfc_element_size for 'size'. Special handling
2570 for character arrays, that are not constant sized: to support
2571 len (str) * kind, only the kind information is stored in the
2572 vtab. */
2573 e = gfc_get_expr ();
2574 e->ts = *ts;
2575 e->expr_type = EXPR_VARIABLE;
2576 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2577 NULL,
2578 ts->type == BT_CHARACTER
2579 && charlen == 0 ?
2580 ts->kind :
2581 (int)gfc_element_size (e));
2582 gfc_free_expr (e);
2584 /* Add component _extends. */
2585 if (!gfc_add_component (vtype, "_extends", &c))
2586 goto cleanup;
2587 c->attr.pointer = 1;
2588 c->attr.access = ACCESS_PRIVATE;
2589 c->ts.type = BT_VOID;
2590 c->initializer = gfc_get_null_expr (NULL);
2592 /* Add component _def_init. */
2593 if (!gfc_add_component (vtype, "_def_init", &c))
2594 goto cleanup;
2595 c->attr.pointer = 1;
2596 c->attr.access = ACCESS_PRIVATE;
2597 c->ts.type = BT_VOID;
2598 c->initializer = gfc_get_null_expr (NULL);
2600 /* Add component _copy. */
2601 if (!gfc_add_component (vtype, "_copy", &c))
2602 goto cleanup;
2603 c->attr.proc_pointer = 1;
2604 c->attr.access = ACCESS_PRIVATE;
2605 c->tb = XCNEW (gfc_typebound_proc);
2606 c->tb->ppc = 1;
2608 if (ts->type != BT_CHARACTER)
2609 sprintf (name, "__copy_%s", tname);
2610 else
2612 /* __copy is always the same for characters.
2613 Check to see if copy function already exists. */
2614 sprintf (name, "__copy_character_%d", ts->kind);
2615 contained = ns->contained;
2616 for (; contained; contained = contained->sibling)
2617 if (contained->proc_name
2618 && strcmp (name, contained->proc_name->name) == 0)
2620 copy = contained->proc_name;
2621 goto got_char_copy;
2625 /* Set up namespace. */
2626 sub_ns = gfc_get_namespace (ns, 0);
2627 sub_ns->sibling = ns->contained;
2628 ns->contained = sub_ns;
2629 sub_ns->resolved = 1;
2630 /* Set up procedure symbol. */
2631 gfc_get_symbol (name, sub_ns, &copy);
2632 sub_ns->proc_name = copy;
2633 copy->attr.flavor = FL_PROCEDURE;
2634 copy->attr.subroutine = 1;
2635 copy->attr.pure = 1;
2636 copy->attr.if_source = IFSRC_DECL;
2637 /* This is elemental so that arrays are automatically
2638 treated correctly by the scalarizer. */
2639 copy->attr.elemental = 1;
2640 if (ns->proc_name->attr.flavor == FL_MODULE)
2641 copy->module = ns->proc_name->name;
2642 gfc_set_sym_referenced (copy);
2643 /* Set up formal arguments. */
2644 gfc_get_symbol ("src", sub_ns, &src);
2645 src->ts.type = ts->type;
2646 src->ts.kind = ts->kind;
2647 src->attr.flavor = FL_VARIABLE;
2648 src->attr.dummy = 1;
2649 src->attr.intent = INTENT_IN;
2650 gfc_set_sym_referenced (src);
2651 copy->formal = gfc_get_formal_arglist ();
2652 copy->formal->sym = src;
2653 gfc_get_symbol ("dst", sub_ns, &dst);
2654 dst->ts.type = ts->type;
2655 dst->ts.kind = ts->kind;
2656 dst->attr.flavor = FL_VARIABLE;
2657 dst->attr.dummy = 1;
2658 dst->attr.intent = INTENT_INOUT;
2659 gfc_set_sym_referenced (dst);
2660 copy->formal->next = gfc_get_formal_arglist ();
2661 copy->formal->next->sym = dst;
2662 /* Set up code. */
2663 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2664 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2665 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2666 got_char_copy:
2667 /* Set initializer. */
2668 c->initializer = gfc_lval_expr_from_sym (copy);
2669 c->ts.interface = copy;
2671 /* Add component _final. */
2672 if (!gfc_add_component (vtype, "_final", &c))
2673 goto cleanup;
2674 c->attr.proc_pointer = 1;
2675 c->attr.access = ACCESS_PRIVATE;
2676 c->tb = XCNEW (gfc_typebound_proc);
2677 c->tb->ppc = 1;
2678 c->initializer = gfc_get_null_expr (NULL);
2680 vtab->ts.u.derived = vtype;
2681 vtab->value = gfc_default_initializer (&vtab->ts);
2685 found_sym = vtab;
2687 cleanup:
2688 /* It is unexpected to have some symbols added at resolution or code
2689 generation time. We commit the changes in order to keep a clean state. */
2690 if (found_sym)
2692 gfc_commit_symbol (vtab);
2693 if (vtype)
2694 gfc_commit_symbol (vtype);
2695 if (copy)
2696 gfc_commit_symbol (copy);
2697 if (src)
2698 gfc_commit_symbol (src);
2699 if (dst)
2700 gfc_commit_symbol (dst);
2702 else
2703 gfc_undo_symbols ();
2705 return found_sym;
2709 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
2711 gfc_symbol *
2712 gfc_find_vtab (gfc_typespec *ts)
2714 switch (ts->type)
2716 case BT_UNKNOWN:
2717 return NULL;
2718 case BT_DERIVED:
2719 return gfc_find_derived_vtab (ts->u.derived);
2720 case BT_CLASS:
2721 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
2722 default:
2723 return find_intrinsic_vtab (ts);
2728 /* General worker function to find either a type-bound procedure or a
2729 type-bound user operator. */
2731 static gfc_symtree*
2732 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2733 const char* name, bool noaccess, bool uop,
2734 locus* where)
2736 gfc_symtree* res;
2737 gfc_symtree* root;
2739 /* Set default to failure. */
2740 if (t)
2741 *t = false;
2743 if (derived->f2k_derived)
2744 /* Set correct symbol-root. */
2745 root = (uop ? derived->f2k_derived->tb_uop_root
2746 : derived->f2k_derived->tb_sym_root);
2747 else
2748 return NULL;
2750 /* Try to find it in the current type's namespace. */
2751 res = gfc_find_symtree (root, name);
2752 if (res && res->n.tb && !res->n.tb->error)
2754 /* We found one. */
2755 if (t)
2756 *t = true;
2758 if (!noaccess && derived->attr.use_assoc
2759 && res->n.tb->access == ACCESS_PRIVATE)
2761 if (where)
2762 gfc_error ("%qs of %qs is PRIVATE at %L",
2763 name, derived->name, where);
2764 if (t)
2765 *t = false;
2768 return res;
2771 /* Otherwise, recurse on parent type if derived is an extension. */
2772 if (derived->attr.extension)
2774 gfc_symbol* super_type;
2775 super_type = gfc_get_derived_super_type (derived);
2776 gcc_assert (super_type);
2778 return find_typebound_proc_uop (super_type, t, name,
2779 noaccess, uop, where);
2782 /* Nothing found. */
2783 return NULL;
2787 /* Find a type-bound procedure or user operator by name for a derived-type
2788 (looking recursively through the super-types). */
2790 gfc_symtree*
2791 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
2792 const char* name, bool noaccess, locus* where)
2794 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2797 gfc_symtree*
2798 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
2799 const char* name, bool noaccess, locus* where)
2801 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2805 /* Find a type-bound intrinsic operator looking recursively through the
2806 super-type hierarchy. */
2808 gfc_typebound_proc*
2809 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
2810 gfc_intrinsic_op op, bool noaccess,
2811 locus* where)
2813 gfc_typebound_proc* res;
2815 /* Set default to failure. */
2816 if (t)
2817 *t = false;
2819 /* Try to find it in the current type's namespace. */
2820 if (derived->f2k_derived)
2821 res = derived->f2k_derived->tb_op[op];
2822 else
2823 res = NULL;
2825 /* Check access. */
2826 if (res && !res->error)
2828 /* We found one. */
2829 if (t)
2830 *t = true;
2832 if (!noaccess && derived->attr.use_assoc
2833 && res->access == ACCESS_PRIVATE)
2835 if (where)
2836 gfc_error ("%qs of %qs is PRIVATE at %L",
2837 gfc_op2string (op), derived->name, where);
2838 if (t)
2839 *t = false;
2842 return res;
2845 /* Otherwise, recurse on parent type if derived is an extension. */
2846 if (derived->attr.extension)
2848 gfc_symbol* super_type;
2849 super_type = gfc_get_derived_super_type (derived);
2850 gcc_assert (super_type);
2852 return gfc_find_typebound_intrinsic_op (super_type, t, op,
2853 noaccess, where);
2856 /* Nothing found. */
2857 return NULL;
2861 /* Get a typebound-procedure symtree or create and insert it if not yet
2862 present. This is like a very simplified version of gfc_get_sym_tree for
2863 tbp-symtrees rather than regular ones. */
2865 gfc_symtree*
2866 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
2868 gfc_symtree *result;
2870 result = gfc_find_symtree (*root, name);
2871 if (!result)
2873 result = gfc_new_symtree (root, name);
2874 gcc_assert (result);
2875 result->n.tb = NULL;
2878 return result;