Daily bump.
[official-gcc.git] / gcc / fortran / class.c
blob349f494f62a42fd3d2716c45a62c44c20d45878b
1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2013 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 For each derived type we set up a "vtable" entry, i.e. a structure with the
38 following fields:
39 * _hash: A hash value serving as a unique identifier for this type.
40 * _size: The size in bytes of the derived type.
41 * _extends: A pointer to the vtable entry of the parent derived type.
42 * _def_init: A pointer to a default initialized variable of this type.
43 * _copy: A procedure pointer to a copying procedure.
44 * _final: A procedure pointer to a wrapper function, which frees
45 allocatable components and calls FINAL subroutines.
47 After these follow procedure pointer components for the specific
48 type-bound procedures. */
51 #include "config.h"
52 #include "system.h"
53 #include "coretypes.h"
54 #include "gfortran.h"
55 #include "constructor.h"
57 /* Inserts a derived type component reference in a data reference chain.
58 TS: base type of the ref chain so far, in which we will pick the component
59 REF: the address of the GFC_REF pointer to update
60 NAME: name of the component to insert
61 Note that component insertion makes sense only if we are at the end of
62 the chain (*REF == NULL) or if we are adding a missing "_data" component
63 to access the actual contents of a class object. */
65 static void
66 insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
68 gfc_symbol *type_sym;
69 gfc_ref *new_ref;
71 gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
72 type_sym = ts->u.derived;
74 new_ref = gfc_get_ref ();
75 new_ref->type = REF_COMPONENT;
76 new_ref->next = *ref;
77 new_ref->u.c.sym = type_sym;
78 new_ref->u.c.component = gfc_find_component (type_sym, name, true, true);
79 gcc_assert (new_ref->u.c.component);
81 if (new_ref->next)
83 gfc_ref *next = NULL;
85 /* We need to update the base type in the trailing reference chain to
86 that of the new component. */
88 gcc_assert (strcmp (name, "_data") == 0);
90 if (new_ref->next->type == REF_COMPONENT)
91 next = new_ref->next;
92 else if (new_ref->next->type == REF_ARRAY
93 && new_ref->next->next
94 && new_ref->next->next->type == REF_COMPONENT)
95 next = new_ref->next->next;
97 if (next != NULL)
99 gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
100 || new_ref->u.c.component->ts.type == BT_DERIVED);
101 next->u.c.sym = new_ref->u.c.component->ts.u.derived;
105 *ref = new_ref;
109 /* Tells whether we need to add a "_data" reference to access REF subobject
110 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base
111 object accessed by REF is a variable; in other words it is a full object,
112 not a subobject. */
114 static bool
115 class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain)
117 /* Only class containers may need the "_data" reference. */
118 if (ts->type != BT_CLASS)
119 return false;
121 /* Accessing a class container with an array reference is certainly wrong. */
122 if (ref->type != REF_COMPONENT)
123 return true;
125 /* Accessing the class container's fields is fine. */
126 if (ref->u.c.component->name[0] == '_')
127 return false;
129 /* At this point we have a class container with a non class container's field
130 component reference. We don't want to add the "_data" component if we are
131 at the first reference and the symbol's type is an extended derived type.
132 In that case, conv_parent_component_references will do the right thing so
133 it is not absolutely necessary. Omitting it prevents a regression (see
134 class_41.f03) in the interface mapping mechanism. When evaluating string
135 lengths depending on dummy arguments, we create a fake symbol with a type
136 equal to that of the dummy type. However, because of type extension,
137 the backend type (corresponding to the actual argument) can have a
138 different (extended) type. Adding the "_data" component explicitly, using
139 the base type, confuses the gfc_conv_component_ref code which deals with
140 the extended type. */
141 if (first_ref_in_chain && ts->u.derived->attr.extension)
142 return false;
144 /* We have a class container with a non class container's field component
145 reference that doesn't fall into the above. */
146 return true;
150 /* Browse through a data reference chain and add the missing "_data" references
151 when a subobject of a class object is accessed without it.
152 Note that it doesn't add the "_data" reference when the class container
153 is the last element in the reference chain. */
155 void
156 gfc_fix_class_refs (gfc_expr *e)
158 gfc_typespec *ts;
159 gfc_ref **ref;
161 if ((e->expr_type != EXPR_VARIABLE
162 && e->expr_type != EXPR_FUNCTION)
163 || (e->expr_type == EXPR_FUNCTION
164 && e->value.function.isym != NULL))
165 return;
167 if (e->expr_type == EXPR_VARIABLE)
168 ts = &e->symtree->n.sym->ts;
169 else
171 gfc_symbol *func;
173 gcc_assert (e->expr_type == EXPR_FUNCTION);
174 if (e->value.function.esym != NULL)
175 func = e->value.function.esym;
176 else
177 func = e->symtree->n.sym;
179 if (func->result != NULL)
180 ts = &func->result->ts;
181 else
182 ts = &func->ts;
185 for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
187 if (class_data_ref_missing (ts, *ref, ref == &e->ref))
188 insert_component_ref (ts, ref, "_data");
190 if ((*ref)->type == REF_COMPONENT)
191 ts = &(*ref)->u.c.component->ts;
196 /* Insert a reference to the component of the given name.
197 Only to be used with CLASS containers and vtables. */
199 void
200 gfc_add_component_ref (gfc_expr *e, const char *name)
202 gfc_ref **tail = &(e->ref);
203 gfc_ref *next = NULL;
204 gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
205 while (*tail != NULL)
207 if ((*tail)->type == REF_COMPONENT)
209 if (strcmp ((*tail)->u.c.component->name, "_data") == 0
210 && (*tail)->next
211 && (*tail)->next->type == REF_ARRAY
212 && (*tail)->next->next == NULL)
213 return;
214 derived = (*tail)->u.c.component->ts.u.derived;
216 if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
217 break;
218 tail = &((*tail)->next);
220 if (*tail != NULL && strcmp (name, "_data") == 0)
221 next = *tail;
222 (*tail) = gfc_get_ref();
223 (*tail)->next = next;
224 (*tail)->type = REF_COMPONENT;
225 (*tail)->u.c.sym = derived;
226 (*tail)->u.c.component = gfc_find_component (derived, name, true, true);
227 gcc_assert((*tail)->u.c.component);
228 if (!next)
229 e->ts = (*tail)->u.c.component->ts;
233 /* This is used to add both the _data component reference and an array
234 reference to class expressions. Used in translation of intrinsic
235 array inquiry functions. */
237 void
238 gfc_add_class_array_ref (gfc_expr *e)
240 int rank = CLASS_DATA (e)->as->rank;
241 gfc_array_spec *as = CLASS_DATA (e)->as;
242 gfc_ref *ref = NULL;
243 gfc_add_component_ref (e, "_data");
244 e->rank = rank;
245 for (ref = e->ref; ref; ref = ref->next)
246 if (!ref->next)
247 break;
248 if (ref->type != REF_ARRAY)
250 ref->next = gfc_get_ref ();
251 ref = ref->next;
252 ref->type = REF_ARRAY;
253 ref->u.ar.type = AR_FULL;
254 ref->u.ar.as = as;
259 /* Unfortunately, class array expressions can appear in various conditions;
260 with and without both _data component and an arrayspec. This function
261 deals with that variability. The previous reference to 'ref' is to a
262 class array. */
264 static bool
265 class_array_ref_detected (gfc_ref *ref, bool *full_array)
267 bool no_data = false;
268 bool with_data = false;
270 /* An array reference with no _data component. */
271 if (ref && ref->type == REF_ARRAY
272 && !ref->next
273 && ref->u.ar.type != AR_ELEMENT)
275 if (full_array)
276 *full_array = ref->u.ar.type == AR_FULL;
277 no_data = true;
280 /* Cover cases where _data appears, with or without an array ref. */
281 if (ref && ref->type == REF_COMPONENT
282 && strcmp (ref->u.c.component->name, "_data") == 0)
284 if (!ref->next)
286 with_data = true;
287 if (full_array)
288 *full_array = true;
290 else if (ref->next && ref->next->type == REF_ARRAY
291 && !ref->next->next
292 && ref->type == REF_COMPONENT
293 && ref->next->type == REF_ARRAY
294 && ref->next->u.ar.type != AR_ELEMENT)
296 with_data = true;
297 if (full_array)
298 *full_array = ref->next->u.ar.type == AR_FULL;
302 return no_data || with_data;
306 /* Returns true if the expression contains a reference to a class
307 array. Notice that class array elements return false. */
309 bool
310 gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
312 gfc_ref *ref;
314 if (!e->rank)
315 return false;
317 if (full_array)
318 *full_array= false;
320 /* Is this a class array object? ie. Is the symbol of type class? */
321 if (e->symtree
322 && e->symtree->n.sym->ts.type == BT_CLASS
323 && CLASS_DATA (e->symtree->n.sym)
324 && CLASS_DATA (e->symtree->n.sym)->attr.dimension
325 && class_array_ref_detected (e->ref, full_array))
326 return true;
328 /* Or is this a class array component reference? */
329 for (ref = e->ref; ref; ref = ref->next)
331 if (ref->type == REF_COMPONENT
332 && ref->u.c.component->ts.type == BT_CLASS
333 && CLASS_DATA (ref->u.c.component)->attr.dimension
334 && class_array_ref_detected (ref->next, full_array))
335 return true;
338 return false;
342 /* Returns true if the expression is a reference to a class
343 scalar. This function is necessary because such expressions
344 can be dressed with a reference to the _data component and so
345 have a type other than BT_CLASS. */
347 bool
348 gfc_is_class_scalar_expr (gfc_expr *e)
350 gfc_ref *ref;
352 if (e->rank)
353 return false;
355 /* Is this a class object? */
356 if (e->symtree
357 && e->symtree->n.sym->ts.type == BT_CLASS
358 && CLASS_DATA (e->symtree->n.sym)
359 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
360 && (e->ref == NULL
361 || (strcmp (e->ref->u.c.component->name, "_data") == 0
362 && e->ref->next == NULL)))
363 return true;
365 /* Or is the final reference BT_CLASS or _data? */
366 for (ref = e->ref; ref; ref = ref->next)
368 if (ref->type == REF_COMPONENT
369 && ref->u.c.component->ts.type == BT_CLASS
370 && CLASS_DATA (ref->u.c.component)
371 && !CLASS_DATA (ref->u.c.component)->attr.dimension
372 && (ref->next == NULL
373 || (strcmp (ref->next->u.c.component->name, "_data") == 0
374 && ref->next->next == NULL)))
375 return true;
378 return false;
382 /* Tells whether the expression E is a reference to a (scalar) class container.
383 Scalar because array class containers usually have an array reference after
384 them, and gfc_fix_class_refs will add the missing "_data" component reference
385 in that case. */
387 bool
388 gfc_is_class_container_ref (gfc_expr *e)
390 gfc_ref *ref;
391 bool result;
393 if (e->expr_type != EXPR_VARIABLE)
394 return e->ts.type == BT_CLASS;
396 if (e->symtree->n.sym->ts.type == BT_CLASS)
397 result = true;
398 else
399 result = false;
401 for (ref = e->ref; ref; ref = ref->next)
403 if (ref->type != REF_COMPONENT)
404 result = false;
405 else if (ref->u.c.component->ts.type == BT_CLASS)
406 result = true;
407 else
408 result = false;
411 return result;
415 /* Build a NULL initializer for CLASS pointers,
416 initializing the _data component to NULL and
417 the _vptr component to the declared type. */
419 gfc_expr *
420 gfc_class_null_initializer (gfc_typespec *ts, gfc_expr *init_expr)
422 gfc_expr *init;
423 gfc_component *comp;
424 gfc_symbol *vtab = NULL;
425 bool is_unlimited_polymorphic;
427 is_unlimited_polymorphic = ts->u.derived
428 && ts->u.derived->components->ts.u.derived
429 && ts->u.derived->components->ts.u.derived->attr.unlimited_polymorphic;
431 if (is_unlimited_polymorphic && init_expr)
432 vtab = gfc_find_intrinsic_vtab (&ts->u.derived->components->ts);
433 else
434 vtab = gfc_find_derived_vtab (ts->u.derived);
436 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
437 &ts->u.derived->declared_at);
438 init->ts = *ts;
440 for (comp = ts->u.derived->components; comp; comp = comp->next)
442 gfc_constructor *ctor = gfc_constructor_get();
443 if (strcmp (comp->name, "_vptr") == 0 && vtab)
444 ctor->expr = gfc_lval_expr_from_sym (vtab);
445 else
446 ctor->expr = gfc_get_null_expr (NULL);
447 gfc_constructor_append (&init->value.constructor, ctor);
450 return init;
454 /* Create a unique string identifier for a derived type, composed of its name
455 and module name. This is used to construct unique names for the class
456 containers and vtab symbols. */
458 static void
459 get_unique_type_string (char *string, gfc_symbol *derived)
461 char dt_name[GFC_MAX_SYMBOL_LEN+1];
462 if (derived->attr.unlimited_polymorphic)
463 strcpy (dt_name, "STAR");
464 else
465 strcpy (dt_name, derived->name);
466 dt_name[0] = TOUPPER (dt_name[0]);
467 if (derived->attr.unlimited_polymorphic)
468 sprintf (string, "_%s", dt_name);
469 else if (derived->module)
470 sprintf (string, "%s_%s", derived->module, dt_name);
471 else if (derived->ns->proc_name)
472 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
473 else
474 sprintf (string, "_%s", dt_name);
478 /* A relative of 'get_unique_type_string' which makes sure the generated
479 string will not be too long (replacing it by a hash string if needed). */
481 static void
482 get_unique_hashed_string (char *string, gfc_symbol *derived)
484 char tmp[2*GFC_MAX_SYMBOL_LEN+2];
485 get_unique_type_string (&tmp[0], derived);
486 /* If string is too long, use hash value in hex representation (allow for
487 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
488 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
489 where %d is the (co)rank which can be up to n = 15. */
490 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
492 int h = gfc_hash_value (derived);
493 sprintf (string, "%X", h);
495 else
496 strcpy (string, tmp);
500 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
502 unsigned int
503 gfc_hash_value (gfc_symbol *sym)
505 unsigned int hash = 0;
506 char c[2*(GFC_MAX_SYMBOL_LEN+1)];
507 int i, len;
509 get_unique_type_string (&c[0], sym);
510 len = strlen (c);
512 for (i = 0; i < len; i++)
513 hash = (hash << 6) + (hash << 16) - hash + c[i];
515 /* Return the hash but take the modulus for the sake of module read,
516 even though this slightly increases the chance of collision. */
517 return (hash % 100000000);
521 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
523 unsigned int
524 gfc_intrinsic_hash_value (gfc_typespec *ts)
526 unsigned int hash = 0;
527 const char *c = gfc_typename (ts);
528 int i, len;
530 len = strlen (c);
532 for (i = 0; i < len; i++)
533 hash = (hash << 6) + (hash << 16) - hash + c[i];
535 /* Return the hash but take the modulus for the sake of module read,
536 even though this slightly increases the chance of collision. */
537 return (hash % 100000000);
541 /* Build a polymorphic CLASS entity, using the symbol that comes from
542 build_sym. A CLASS entity is represented by an encapsulating type,
543 which contains the declared type as '_data' component, plus a pointer
544 component '_vptr' which determines the dynamic type. */
546 bool
547 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
548 gfc_array_spec **as, bool delayed_vtab)
550 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
551 gfc_symbol *fclass;
552 gfc_symbol *vtab;
553 gfc_component *c;
554 gfc_namespace *ns;
555 int rank;
557 gcc_assert (as);
559 if (*as && (*as)->type == AS_ASSUMED_SIZE)
561 gfc_error ("Assumed size polymorphic objects or components, such "
562 "as that at %C, have not yet been implemented");
563 return false;
566 if (attr->class_ok)
567 /* Class container has already been built. */
568 return true;
570 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
571 || attr->select_type_temporary || attr->associate_var;
573 if (!attr->class_ok)
574 /* We can not build the class container yet. */
575 return true;
577 /* Determine the name of the encapsulating type. */
578 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
579 get_unique_hashed_string (tname, ts->u.derived);
580 if ((*as) && attr->allocatable)
581 sprintf (name, "__class_%s_%d_%da", tname, rank, (*as)->corank);
582 else if ((*as) && attr->pointer)
583 sprintf (name, "__class_%s_%d_%dp", tname, rank, (*as)->corank);
584 else if ((*as))
585 sprintf (name, "__class_%s_%d_%d", tname, rank, (*as)->corank);
586 else if (attr->pointer)
587 sprintf (name, "__class_%s_p", tname);
588 else if (attr->allocatable)
589 sprintf (name, "__class_%s_a", tname);
590 else
591 sprintf (name, "__class_%s", tname);
593 if (ts->u.derived->attr.unlimited_polymorphic)
595 /* Find the top-level namespace. */
596 for (ns = gfc_current_ns; ns; ns = ns->parent)
597 if (!ns->parent)
598 break;
600 else
601 ns = ts->u.derived->ns;
603 gfc_find_symbol (name, ns, 0, &fclass);
604 if (fclass == NULL)
606 gfc_symtree *st;
607 /* If not there, create a new symbol. */
608 fclass = gfc_new_symbol (name, ns);
609 st = gfc_new_symtree (&ns->sym_root, name);
610 st->n.sym = fclass;
611 gfc_set_sym_referenced (fclass);
612 fclass->refs++;
613 fclass->ts.type = BT_UNKNOWN;
614 if (!ts->u.derived->attr.unlimited_polymorphic)
615 fclass->attr.abstract = ts->u.derived->attr.abstract;
616 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
617 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
618 &gfc_current_locus))
619 return false;
621 /* Add component '_data'. */
622 if (!gfc_add_component (fclass, "_data", &c))
623 return false;
624 c->ts = *ts;
625 c->ts.type = BT_DERIVED;
626 c->attr.access = ACCESS_PRIVATE;
627 c->ts.u.derived = ts->u.derived;
628 c->attr.class_pointer = attr->pointer;
629 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
630 || attr->select_type_temporary;
631 c->attr.allocatable = attr->allocatable;
632 c->attr.dimension = attr->dimension;
633 c->attr.codimension = attr->codimension;
634 c->attr.abstract = fclass->attr.abstract;
635 c->as = (*as);
636 c->initializer = NULL;
638 /* Add component '_vptr'. */
639 if (!gfc_add_component (fclass, "_vptr", &c))
640 return false;
641 c->ts.type = BT_DERIVED;
642 if (delayed_vtab
643 || (ts->u.derived->f2k_derived
644 && ts->u.derived->f2k_derived->finalizers))
645 c->ts.u.derived = NULL;
646 else
648 vtab = gfc_find_derived_vtab (ts->u.derived);
649 gcc_assert (vtab);
650 c->ts.u.derived = vtab->ts.u.derived;
652 c->attr.access = ACCESS_PRIVATE;
653 c->attr.pointer = 1;
656 if (!ts->u.derived->attr.unlimited_polymorphic)
658 /* Since the extension field is 8 bit wide, we can only have
659 up to 255 extension levels. */
660 if (ts->u.derived->attr.extension == 255)
662 gfc_error ("Maximum extension level reached with type '%s' at %L",
663 ts->u.derived->name, &ts->u.derived->declared_at);
664 return false;
667 fclass->attr.extension = ts->u.derived->attr.extension + 1;
668 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
671 fclass->attr.is_class = 1;
672 ts->u.derived = fclass;
673 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
674 (*as) = NULL;
675 return true;
679 /* Add a procedure pointer component to the vtype
680 to represent a specific type-bound procedure. */
682 static void
683 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
685 gfc_component *c;
687 if (tb->non_overridable)
688 return;
690 c = gfc_find_component (vtype, name, true, true);
692 if (c == NULL)
694 /* Add procedure component. */
695 if (!gfc_add_component (vtype, name, &c))
696 return;
698 if (!c->tb)
699 c->tb = XCNEW (gfc_typebound_proc);
700 *c->tb = *tb;
701 c->tb->ppc = 1;
702 c->attr.procedure = 1;
703 c->attr.proc_pointer = 1;
704 c->attr.flavor = FL_PROCEDURE;
705 c->attr.access = ACCESS_PRIVATE;
706 c->attr.external = 1;
707 c->attr.untyped = 1;
708 c->attr.if_source = IFSRC_IFBODY;
710 else if (c->attr.proc_pointer && c->tb)
712 *c->tb = *tb;
713 c->tb->ppc = 1;
716 if (tb->u.specific)
718 c->ts.interface = tb->u.specific->n.sym;
719 if (!tb->deferred)
720 c->initializer = gfc_get_variable_expr (tb->u.specific);
725 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
727 static void
728 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
730 if (!st)
731 return;
733 if (st->left)
734 add_procs_to_declared_vtab1 (st->left, vtype);
736 if (st->right)
737 add_procs_to_declared_vtab1 (st->right, vtype);
739 if (st->n.tb && !st->n.tb->error
740 && !st->n.tb->is_generic && st->n.tb->u.specific)
741 add_proc_comp (vtype, st->name, st->n.tb);
745 /* Copy procedure pointers components from the parent type. */
747 static void
748 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
750 gfc_component *cmp;
751 gfc_symbol *vtab;
753 vtab = gfc_find_derived_vtab (declared);
755 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
757 if (gfc_find_component (vtype, cmp->name, true, true))
758 continue;
760 add_proc_comp (vtype, cmp->name, cmp->tb);
765 /* Returns true if any of its nonpointer nonallocatable components or
766 their nonpointer nonallocatable subcomponents has a finalization
767 subroutine. */
769 static bool
770 has_finalizer_component (gfc_symbol *derived)
772 gfc_component *c;
774 for (c = derived->components; c; c = c->next)
776 if (c->ts.type == BT_DERIVED && c->ts.u.derived->f2k_derived
777 && c->ts.u.derived->f2k_derived->finalizers)
778 return true;
780 if (c->ts.type == BT_DERIVED
781 && !c->attr.pointer && !c->attr.allocatable
782 && has_finalizer_component (c->ts.u.derived))
783 return true;
785 return false;
789 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
790 neither allocatable nor a pointer but has a finalizer, call it. If it
791 is a nonpointer component with allocatable components or has finalizers, walk
792 them. Either of them is required; other nonallocatables and pointers aren't
793 handled gracefully.
794 Note: If the component is allocatable, the DEALLOCATE handling takes care
795 of calling the appropriate finalizers, coarray deregistering, and
796 deallocation of allocatable subcomponents. */
798 static void
799 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
800 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code)
802 gfc_expr *e;
803 gfc_ref *ref;
805 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS
806 && !comp->attr.allocatable)
807 return;
809 if ((comp->ts.type == BT_DERIVED && comp->attr.pointer)
810 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
811 && CLASS_DATA (comp)->attr.pointer))
812 return;
814 if (comp->ts.type == BT_DERIVED && !comp->attr.allocatable
815 && (comp->ts.u.derived->f2k_derived == NULL
816 || comp->ts.u.derived->f2k_derived->finalizers == NULL)
817 && !has_finalizer_component (comp->ts.u.derived))
818 return;
820 e = gfc_copy_expr (expr);
821 if (!e->ref)
822 e->ref = ref = gfc_get_ref ();
823 else
825 for (ref = e->ref; ref->next; ref = ref->next)
827 ref->next = gfc_get_ref ();
828 ref = ref->next;
830 ref->type = REF_COMPONENT;
831 ref->u.c.sym = derived;
832 ref->u.c.component = comp;
833 e->ts = comp->ts;
835 if (comp->attr.dimension
836 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
837 && CLASS_DATA (comp)->attr.dimension))
839 ref->next = gfc_get_ref ();
840 ref->next->type = REF_ARRAY;
841 ref->next->u.ar.type = AR_FULL;
842 ref->next->u.ar.dimen = 0;
843 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
844 : comp->as;
845 e->rank = ref->next->u.ar.as->rank;
848 /* Call DEALLOCATE (comp, stat=ignore). */
849 if (comp->attr.allocatable
850 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
851 && CLASS_DATA (comp)->attr.allocatable))
853 gfc_code *dealloc, *block = NULL;
855 /* Add IF (fini_coarray). */
856 if (comp->attr.codimension
857 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
858 && CLASS_DATA (comp)->attr.allocatable))
860 block = XCNEW (gfc_code);
861 if (*code)
863 (*code)->next = block;
864 (*code) = (*code)->next;
866 else
867 (*code) = block;
869 block->loc = gfc_current_locus;
870 block->op = EXEC_IF;
872 block->block = XCNEW (gfc_code);
873 block = block->block;
874 block->loc = gfc_current_locus;
875 block->op = EXEC_IF;
876 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
879 dealloc = XCNEW (gfc_code);
880 dealloc->op = EXEC_DEALLOCATE;
881 dealloc->loc = gfc_current_locus;
883 dealloc->ext.alloc.list = gfc_get_alloc ();
884 dealloc->ext.alloc.list->expr = e;
885 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
887 if (block)
888 block->next = dealloc;
889 else if (*code)
891 (*code)->next = dealloc;
892 (*code) = (*code)->next;
894 else
895 (*code) = dealloc;
897 else if (comp->ts.type == BT_DERIVED
898 && comp->ts.u.derived->f2k_derived
899 && comp->ts.u.derived->f2k_derived->finalizers)
901 /* Call FINAL_WRAPPER (comp); */
902 gfc_code *final_wrap;
903 gfc_symbol *vtab;
904 gfc_component *c;
906 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
907 for (c = vtab->ts.u.derived->components; c; c = c->next)
908 if (strcmp (c->name, "_final") == 0)
909 break;
911 gcc_assert (c);
912 final_wrap = XCNEW (gfc_code);
913 final_wrap->op = EXEC_CALL;
914 final_wrap->loc = gfc_current_locus;
915 final_wrap->loc = gfc_current_locus;
916 final_wrap->symtree = c->initializer->symtree;
917 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
918 final_wrap->ext.actual = gfc_get_actual_arglist ();
919 final_wrap->ext.actual->expr = e;
921 if (*code)
923 (*code)->next = final_wrap;
924 (*code) = (*code)->next;
926 else
927 (*code) = final_wrap;
929 else
931 gfc_component *c;
933 for (c = comp->ts.u.derived->components; c; c = c->next)
934 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code);
935 gfc_free_expr (e);
940 /* Generate code equivalent to
941 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
942 + offset, c_ptr), ptr). */
944 static gfc_code *
945 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
946 gfc_expr *offset, gfc_namespace *sub_ns)
948 gfc_code *block;
949 gfc_expr *expr, *expr2;
951 /* C_F_POINTER(). */
952 block = XCNEW (gfc_code);
953 block->op = EXEC_CALL;
954 block->loc = gfc_current_locus;
955 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
956 block->resolved_sym = block->symtree->n.sym;
957 block->resolved_sym->attr.flavor = FL_PROCEDURE;
958 block->resolved_sym->attr.intrinsic = 1;
959 block->resolved_sym->attr.subroutine = 1;
960 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
961 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
962 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
963 gfc_commit_symbol (block->resolved_sym);
965 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
966 block->ext.actual = gfc_get_actual_arglist ();
967 block->ext.actual->next = gfc_get_actual_arglist ();
968 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
969 NULL, 0);
970 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
972 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
974 /* TRANSFER's first argument: C_LOC (array). */
975 expr = gfc_get_expr ();
976 expr->expr_type = EXPR_FUNCTION;
977 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
978 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
979 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
980 expr->symtree->n.sym->attr.intrinsic = 1;
981 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
982 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
983 expr->value.function.actual = gfc_get_actual_arglist ();
984 expr->value.function.actual->expr
985 = gfc_lval_expr_from_sym (array);
986 expr->symtree->n.sym->result = expr->symtree->n.sym;
987 gfc_commit_symbol (expr->symtree->n.sym);
988 expr->ts.type = BT_INTEGER;
989 expr->ts.kind = gfc_index_integer_kind;
991 /* TRANSFER. */
992 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
993 gfc_current_locus, 3, expr,
994 gfc_get_int_expr (gfc_index_integer_kind,
995 NULL, 0), NULL);
996 expr2->ts.type = BT_INTEGER;
997 expr2->ts.kind = gfc_index_integer_kind;
999 /* <array addr> + <offset>. */
1000 block->ext.actual->expr = gfc_get_expr ();
1001 block->ext.actual->expr->expr_type = EXPR_OP;
1002 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
1003 block->ext.actual->expr->value.op.op1 = expr2;
1004 block->ext.actual->expr->value.op.op2 = offset;
1005 block->ext.actual->expr->ts = expr->ts;
1007 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1008 block->ext.actual->next = gfc_get_actual_arglist ();
1009 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1010 block->ext.actual->next->next = gfc_get_actual_arglist ();
1012 return block;
1016 /* Calculates the offset to the (idx+1)th element of an array, taking the
1017 stride into account. It generates the code:
1018 offset = 0
1019 do idx2 = 1, rank
1020 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1021 end do
1022 offset = offset * byte_stride. */
1024 static gfc_code*
1025 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1026 gfc_symbol *strides, gfc_symbol *sizes,
1027 gfc_symbol *byte_stride, gfc_expr *rank,
1028 gfc_code *block, gfc_namespace *sub_ns)
1030 gfc_iterator *iter;
1031 gfc_expr *expr, *expr2;
1033 /* offset = 0. */
1034 block->next = XCNEW (gfc_code);
1035 block = block->next;
1036 block->op = EXEC_ASSIGN;
1037 block->loc = gfc_current_locus;
1038 block->expr1 = gfc_lval_expr_from_sym (offset);
1039 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1041 /* Create loop. */
1042 iter = gfc_get_iterator ();
1043 iter->var = gfc_lval_expr_from_sym (idx2);
1044 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1045 iter->end = gfc_copy_expr (rank);
1046 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1047 block->next = XCNEW (gfc_code);
1048 block = block->next;
1049 block->op = EXEC_DO;
1050 block->loc = gfc_current_locus;
1051 block->ext.iterator = iter;
1052 block->block = gfc_get_code ();
1053 block->block->op = EXEC_DO;
1055 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1056 * strides(idx2). */
1058 /* mod (idx, sizes(idx2)). */
1059 expr = gfc_lval_expr_from_sym (sizes);
1060 expr->ref = gfc_get_ref ();
1061 expr->ref->type = REF_ARRAY;
1062 expr->ref->u.ar.as = sizes->as;
1063 expr->ref->u.ar.type = AR_ELEMENT;
1064 expr->ref->u.ar.dimen = 1;
1065 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1066 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1068 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1069 gfc_current_locus, 2,
1070 gfc_lval_expr_from_sym (idx), expr);
1071 expr->ts = idx->ts;
1073 /* (...) / sizes(idx2-1). */
1074 expr2 = gfc_get_expr ();
1075 expr2->expr_type = EXPR_OP;
1076 expr2->value.op.op = INTRINSIC_DIVIDE;
1077 expr2->value.op.op1 = expr;
1078 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1079 expr2->value.op.op2->ref = gfc_get_ref ();
1080 expr2->value.op.op2->ref->type = REF_ARRAY;
1081 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1082 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1083 expr2->value.op.op2->ref->u.ar.dimen = 1;
1084 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1085 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1086 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1087 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1088 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1089 = gfc_lval_expr_from_sym (idx2);
1090 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1091 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1092 expr2->value.op.op2->ref->u.ar.start[0]->ts
1093 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1094 expr2->ts = idx->ts;
1096 /* ... * strides(idx2). */
1097 expr = gfc_get_expr ();
1098 expr->expr_type = EXPR_OP;
1099 expr->value.op.op = INTRINSIC_TIMES;
1100 expr->value.op.op1 = expr2;
1101 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1102 expr->value.op.op2->ref = gfc_get_ref ();
1103 expr->value.op.op2->ref->type = REF_ARRAY;
1104 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1105 expr->value.op.op2->ref->u.ar.dimen = 1;
1106 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1107 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1108 expr->value.op.op2->ref->u.ar.as = strides->as;
1109 expr->ts = idx->ts;
1111 /* offset = offset + ... */
1112 block->block->next = XCNEW (gfc_code);
1113 block->block->next->op = EXEC_ASSIGN;
1114 block->block->next->loc = gfc_current_locus;
1115 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1116 block->block->next->expr2 = gfc_get_expr ();
1117 block->block->next->expr2->expr_type = EXPR_OP;
1118 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1119 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1120 block->block->next->expr2->value.op.op2 = expr;
1121 block->block->next->expr2->ts = idx->ts;
1123 /* After the loop: offset = offset * byte_stride. */
1124 block->next = XCNEW (gfc_code);
1125 block = block->next;
1126 block->op = EXEC_ASSIGN;
1127 block->loc = gfc_current_locus;
1128 block->expr1 = gfc_lval_expr_from_sym (offset);
1129 block->expr2 = gfc_get_expr ();
1130 block->expr2->expr_type = EXPR_OP;
1131 block->expr2->value.op.op = INTRINSIC_TIMES;
1132 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1133 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1134 block->expr2->ts = block->expr2->value.op.op1->ts;
1135 return block;
1139 /* Insert code of the following form:
1141 block
1142 integer(c_intptr_t) :: i
1144 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1145 && (is_contiguous || !final_rank3->attr.contiguous
1146 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1147 || 0 == STORAGE_SIZE (array)) then
1148 call final_rank3 (array)
1149 else
1150 block
1151 integer(c_intptr_t) :: offset, j
1152 type(t) :: tmp(shape (array))
1154 do i = 0, size (array)-1
1155 offset = obtain_offset(i, strides, sizes, byte_stride)
1156 addr = transfer (c_loc (array), addr) + offset
1157 call c_f_pointer (transfer (addr, cptr), ptr)
1159 addr = transfer (c_loc (tmp), addr)
1160 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1161 call c_f_pointer (transfer (addr, cptr), ptr2)
1162 ptr2 = ptr
1163 end do
1164 call final_rank3 (tmp)
1165 end block
1166 end if
1167 block */
1169 static void
1170 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1171 gfc_symbol *array, gfc_symbol *byte_stride,
1172 gfc_symbol *idx, gfc_symbol *ptr,
1173 gfc_symbol *nelem,
1174 gfc_symbol *strides, gfc_symbol *sizes,
1175 gfc_symbol *idx2, gfc_symbol *offset,
1176 gfc_symbol *is_contiguous, gfc_expr *rank,
1177 gfc_namespace *sub_ns)
1179 gfc_symbol *tmp_array, *ptr2;
1180 gfc_expr *size_expr, *offset2, *expr;
1181 gfc_namespace *ns;
1182 gfc_iterator *iter;
1183 gfc_code *block2;
1184 int i;
1186 block->next = XCNEW (gfc_code);
1187 block = block->next;
1188 block->loc = gfc_current_locus;
1189 block->op = EXEC_IF;
1191 block->block = XCNEW (gfc_code);
1192 block = block->block;
1193 block->loc = gfc_current_locus;
1194 block->op = EXEC_IF;
1196 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1197 size_expr = gfc_get_expr ();
1198 size_expr->where = gfc_current_locus;
1199 size_expr->expr_type = EXPR_OP;
1200 size_expr->value.op.op = INTRINSIC_DIVIDE;
1202 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1203 size_expr->value.op.op1
1204 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1205 "storage_size", gfc_current_locus, 2,
1206 gfc_lval_expr_from_sym (array),
1207 gfc_get_int_expr (gfc_index_integer_kind,
1208 NULL, 0));
1210 /* NUMERIC_STORAGE_SIZE. */
1211 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1212 gfc_character_storage_size);
1213 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1214 size_expr->ts = size_expr->value.op.op1->ts;
1216 /* IF condition: (stride == size_expr
1217 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1218 || is_contiguous)
1219 || 0 == size_expr. */
1220 block->expr1 = gfc_get_expr ();
1221 block->expr1->ts.type = BT_LOGICAL;
1222 block->expr1->ts.kind = gfc_default_logical_kind;
1223 block->expr1->expr_type = EXPR_OP;
1224 block->expr1->where = gfc_current_locus;
1226 block->expr1->value.op.op = INTRINSIC_OR;
1228 /* byte_stride == size_expr */
1229 expr = gfc_get_expr ();
1230 expr->ts.type = BT_LOGICAL;
1231 expr->ts.kind = gfc_default_logical_kind;
1232 expr->expr_type = EXPR_OP;
1233 expr->where = gfc_current_locus;
1234 expr->value.op.op = INTRINSIC_EQ;
1235 expr->value.op.op1
1236 = gfc_lval_expr_from_sym (byte_stride);
1237 expr->value.op.op2 = size_expr;
1239 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1240 add is_contiguous check. */
1242 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1243 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1245 gfc_expr *expr2;
1246 expr2 = gfc_get_expr ();
1247 expr2->ts.type = BT_LOGICAL;
1248 expr2->ts.kind = gfc_default_logical_kind;
1249 expr2->expr_type = EXPR_OP;
1250 expr2->where = gfc_current_locus;
1251 expr2->value.op.op = INTRINSIC_AND;
1252 expr2->value.op.op1 = expr;
1253 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1254 expr = expr2;
1257 block->expr1->value.op.op1 = expr;
1259 /* 0 == size_expr */
1260 block->expr1->value.op.op2 = gfc_get_expr ();
1261 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1262 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1263 block->expr1->value.op.op2->expr_type = EXPR_OP;
1264 block->expr1->value.op.op2->where = gfc_current_locus;
1265 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1266 block->expr1->value.op.op2->value.op.op1 =
1267 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1268 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1270 /* IF body: call final subroutine. */
1271 block->next = XCNEW (gfc_code);
1272 block->next->op = EXEC_CALL;
1273 block->next->loc = gfc_current_locus;
1274 block->next->symtree = fini->proc_tree;
1275 block->next->resolved_sym = fini->proc_tree->n.sym;
1276 block->next->ext.actual = gfc_get_actual_arglist ();
1277 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1279 /* ELSE. */
1281 block->block = XCNEW (gfc_code);
1282 block = block->block;
1283 block->loc = gfc_current_locus;
1284 block->op = EXEC_IF;
1286 block->next = XCNEW (gfc_code);
1287 block = block->next;
1289 /* BLOCK ... END BLOCK. */
1290 block->op = EXEC_BLOCK;
1291 block->loc = gfc_current_locus;
1292 ns = gfc_build_block_ns (sub_ns);
1293 block->ext.block.ns = ns;
1294 block->ext.block.assoc = NULL;
1296 gfc_get_symbol ("ptr2", ns, &ptr2);
1297 ptr2->ts.type = BT_DERIVED;
1298 ptr2->ts.u.derived = array->ts.u.derived;
1299 ptr2->attr.flavor = FL_VARIABLE;
1300 ptr2->attr.pointer = 1;
1301 ptr2->attr.artificial = 1;
1302 gfc_set_sym_referenced (ptr2);
1303 gfc_commit_symbol (ptr2);
1305 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1306 tmp_array->ts.type = BT_DERIVED;
1307 tmp_array->ts.u.derived = array->ts.u.derived;
1308 tmp_array->attr.flavor = FL_VARIABLE;
1309 tmp_array->attr.dimension = 1;
1310 tmp_array->attr.artificial = 1;
1311 tmp_array->as = gfc_get_array_spec();
1312 tmp_array->attr.intent = INTENT_INOUT;
1313 tmp_array->as->type = AS_EXPLICIT;
1314 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1316 for (i = 0; i < tmp_array->as->rank; i++)
1318 gfc_expr *shape_expr;
1319 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1320 NULL, 1);
1321 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1322 shape_expr
1323 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1324 gfc_current_locus, 3,
1325 gfc_lval_expr_from_sym (array),
1326 gfc_get_int_expr (gfc_default_integer_kind,
1327 NULL, i+1),
1328 gfc_get_int_expr (gfc_default_integer_kind,
1329 NULL,
1330 gfc_index_integer_kind));
1331 shape_expr->ts.kind = gfc_index_integer_kind;
1332 tmp_array->as->upper[i] = shape_expr;
1334 gfc_set_sym_referenced (tmp_array);
1335 gfc_commit_symbol (tmp_array);
1337 /* Create loop. */
1338 iter = gfc_get_iterator ();
1339 iter->var = gfc_lval_expr_from_sym (idx);
1340 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1341 iter->end = gfc_lval_expr_from_sym (nelem);
1342 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1344 block = XCNEW (gfc_code);
1345 ns->code = block;
1346 block->op = EXEC_DO;
1347 block->loc = gfc_current_locus;
1348 block->ext.iterator = iter;
1349 block->block = gfc_get_code ();
1350 block->block->op = EXEC_DO;
1352 /* Offset calculation for the new array: idx * size of type (in bytes). */
1353 offset2 = gfc_get_expr ();
1354 offset2->expr_type = EXPR_OP;
1355 offset2->value.op.op = INTRINSIC_TIMES;
1356 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1357 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1358 offset2->ts = byte_stride->ts;
1360 /* Offset calculation of "array". */
1361 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1362 byte_stride, rank, block->block, sub_ns);
1364 /* Create code for
1365 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1366 + idx * stride, c_ptr), ptr). */
1367 block2->next = finalization_scalarizer (array, ptr,
1368 gfc_lval_expr_from_sym (offset),
1369 sub_ns);
1370 block2 = block2->next;
1371 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1372 block2 = block2->next;
1374 /* ptr2 = ptr. */
1375 block2->next = XCNEW (gfc_code);
1376 block2 = block2->next;
1377 block2->op = EXEC_ASSIGN;
1378 block2->loc = gfc_current_locus;
1379 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1380 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1382 /* Call now the user's final subroutine. */
1383 block->next = XCNEW (gfc_code);
1384 block = block->next;
1385 block->op = EXEC_CALL;
1386 block->loc = gfc_current_locus;
1387 block->symtree = fini->proc_tree;
1388 block->resolved_sym = fini->proc_tree->n.sym;
1389 block->ext.actual = gfc_get_actual_arglist ();
1390 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1392 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1393 return;
1395 /* Copy back. */
1397 /* Loop. */
1398 iter = gfc_get_iterator ();
1399 iter->var = gfc_lval_expr_from_sym (idx);
1400 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1401 iter->end = gfc_lval_expr_from_sym (nelem);
1402 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1404 block->next = XCNEW (gfc_code);
1405 block = block->next;
1406 block->op = EXEC_DO;
1407 block->loc = gfc_current_locus;
1408 block->ext.iterator = iter;
1409 block->block = gfc_get_code ();
1410 block->block->op = EXEC_DO;
1412 /* Offset calculation of "array". */
1413 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1414 byte_stride, rank, block->block, sub_ns);
1416 /* Create code for
1417 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1418 + offset, c_ptr), ptr). */
1419 block2->next = finalization_scalarizer (array, ptr,
1420 gfc_lval_expr_from_sym (offset),
1421 sub_ns);
1422 block2 = block2->next;
1423 block2->next = finalization_scalarizer (tmp_array, ptr2,
1424 gfc_copy_expr (offset2), sub_ns);
1425 block2 = block2->next;
1427 /* ptr = ptr2. */
1428 block2->next = XCNEW (gfc_code);
1429 block2->next->op = EXEC_ASSIGN;
1430 block2->next->loc = gfc_current_locus;
1431 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1432 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1436 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1437 derived type "derived". The function first calls the approriate FINAL
1438 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1439 components (but not the inherited ones). Last, it calls the wrapper
1440 subroutine of the parent. The generated wrapper procedure takes as argument
1441 an assumed-rank array.
1442 If neither allocatable components nor FINAL subroutines exists, the vtab
1443 will contain a NULL pointer.
1444 The generated function has the form
1445 _final(assumed-rank array, stride, skip_corarray)
1446 where the array has to be contiguous (except of the lowest dimension). The
1447 stride (in bytes) is used to allow different sizes for ancestor types by
1448 skipping over the additionally added components in the scalarizer. If
1449 "fini_coarray" is false, coarray components are not finalized to allow for
1450 the correct semantic with intrinsic assignment. */
1452 static void
1453 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1454 const char *tname, gfc_component *vtab_final)
1456 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1457 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1458 gfc_component *comp;
1459 gfc_namespace *sub_ns;
1460 gfc_code *last_code, *block;
1461 char name[GFC_MAX_SYMBOL_LEN+1];
1462 bool finalizable_comp = false;
1463 bool expr_null_wrapper = false;
1464 gfc_expr *ancestor_wrapper = NULL, *rank;
1465 gfc_iterator *iter;
1467 /* Search for the ancestor's finalizers. */
1468 if (derived->attr.extension && derived->components
1469 && (!derived->components->ts.u.derived->attr.abstract
1470 || has_finalizer_component (derived)))
1472 gfc_symbol *vtab;
1473 gfc_component *comp;
1475 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1476 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1477 if (comp->name[0] == '_' && comp->name[1] == 'f')
1479 ancestor_wrapper = comp->initializer;
1480 break;
1484 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1485 components: Return a NULL() expression; we defer this a bit to have have
1486 an interface declaration. */
1487 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1488 && !derived->attr.alloc_comp
1489 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1490 && !has_finalizer_component (derived))
1491 expr_null_wrapper = true;
1492 else
1493 /* Check whether there are new allocatable components. */
1494 for (comp = derived->components; comp; comp = comp->next)
1496 if (comp == derived->components && derived->attr.extension
1497 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1498 continue;
1500 if (comp->ts.type != BT_CLASS && !comp->attr.pointer
1501 && (comp->attr.allocatable
1502 || (comp->ts.type == BT_DERIVED
1503 && (comp->ts.u.derived->attr.alloc_comp
1504 || has_finalizer_component (comp->ts.u.derived)
1505 || (comp->ts.u.derived->f2k_derived
1506 && comp->ts.u.derived->f2k_derived->finalizers)))))
1507 finalizable_comp = true;
1508 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1509 && CLASS_DATA (comp)->attr.allocatable)
1510 finalizable_comp = true;
1513 /* If there is no new finalizer and no new allocatable, return with
1514 an expr to the ancestor's one. */
1515 if (!expr_null_wrapper && !finalizable_comp
1516 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1518 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1519 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1520 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1521 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1522 return;
1525 /* We now create a wrapper, which does the following:
1526 1. Call the suitable finalization subroutine for this type
1527 2. Loop over all noninherited allocatable components and noninherited
1528 components with allocatable components and DEALLOCATE those; this will
1529 take care of finalizers, coarray deregistering and allocatable
1530 nested components.
1531 3. Call the ancestor's finalizer. */
1533 /* Declare the wrapper function; it takes an assumed-rank array
1534 and a VALUE logical as arguments. */
1536 /* Set up the namespace. */
1537 sub_ns = gfc_get_namespace (ns, 0);
1538 sub_ns->sibling = ns->contained;
1539 if (!expr_null_wrapper)
1540 ns->contained = sub_ns;
1541 sub_ns->resolved = 1;
1543 /* Set up the procedure symbol. */
1544 sprintf (name, "__final_%s", tname);
1545 gfc_get_symbol (name, sub_ns, &final);
1546 sub_ns->proc_name = final;
1547 final->attr.flavor = FL_PROCEDURE;
1548 final->attr.function = 1;
1549 final->attr.pure = 0;
1550 final->result = final;
1551 final->ts.type = BT_INTEGER;
1552 final->ts.kind = 4;
1553 final->attr.artificial = 1;
1554 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1555 if (ns->proc_name->attr.flavor == FL_MODULE)
1556 final->module = ns->proc_name->name;
1557 gfc_set_sym_referenced (final);
1558 gfc_commit_symbol (final);
1560 /* Set up formal argument. */
1561 gfc_get_symbol ("array", sub_ns, &array);
1562 array->ts.type = BT_DERIVED;
1563 array->ts.u.derived = derived;
1564 array->attr.flavor = FL_VARIABLE;
1565 array->attr.dummy = 1;
1566 array->attr.contiguous = 1;
1567 array->attr.dimension = 1;
1568 array->attr.artificial = 1;
1569 array->as = gfc_get_array_spec();
1570 array->as->type = AS_ASSUMED_RANK;
1571 array->as->rank = -1;
1572 array->attr.intent = INTENT_INOUT;
1573 gfc_set_sym_referenced (array);
1574 final->formal = gfc_get_formal_arglist ();
1575 final->formal->sym = array;
1576 gfc_commit_symbol (array);
1578 /* Set up formal argument. */
1579 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1580 byte_stride->ts.type = BT_INTEGER;
1581 byte_stride->ts.kind = gfc_index_integer_kind;
1582 byte_stride->attr.flavor = FL_VARIABLE;
1583 byte_stride->attr.dummy = 1;
1584 byte_stride->attr.value = 1;
1585 byte_stride->attr.artificial = 1;
1586 gfc_set_sym_referenced (byte_stride);
1587 final->formal->next = gfc_get_formal_arglist ();
1588 final->formal->next->sym = byte_stride;
1589 gfc_commit_symbol (byte_stride);
1591 /* Set up formal argument. */
1592 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1593 fini_coarray->ts.type = BT_LOGICAL;
1594 fini_coarray->ts.kind = 1;
1595 fini_coarray->attr.flavor = FL_VARIABLE;
1596 fini_coarray->attr.dummy = 1;
1597 fini_coarray->attr.value = 1;
1598 fini_coarray->attr.artificial = 1;
1599 gfc_set_sym_referenced (fini_coarray);
1600 final->formal->next->next = gfc_get_formal_arglist ();
1601 final->formal->next->next->sym = fini_coarray;
1602 gfc_commit_symbol (fini_coarray);
1604 /* Return with a NULL() expression but with an interface which has
1605 the formal arguments. */
1606 if (expr_null_wrapper)
1608 vtab_final->initializer = gfc_get_null_expr (NULL);
1609 vtab_final->ts.interface = final;
1610 return;
1613 /* Local variables. */
1615 gfc_get_symbol ("idx", sub_ns, &idx);
1616 idx->ts.type = BT_INTEGER;
1617 idx->ts.kind = gfc_index_integer_kind;
1618 idx->attr.flavor = FL_VARIABLE;
1619 idx->attr.artificial = 1;
1620 gfc_set_sym_referenced (idx);
1621 gfc_commit_symbol (idx);
1623 gfc_get_symbol ("idx2", sub_ns, &idx2);
1624 idx2->ts.type = BT_INTEGER;
1625 idx2->ts.kind = gfc_index_integer_kind;
1626 idx2->attr.flavor = FL_VARIABLE;
1627 idx2->attr.artificial = 1;
1628 gfc_set_sym_referenced (idx2);
1629 gfc_commit_symbol (idx2);
1631 gfc_get_symbol ("offset", sub_ns, &offset);
1632 offset->ts.type = BT_INTEGER;
1633 offset->ts.kind = gfc_index_integer_kind;
1634 offset->attr.flavor = FL_VARIABLE;
1635 offset->attr.artificial = 1;
1636 gfc_set_sym_referenced (offset);
1637 gfc_commit_symbol (offset);
1639 /* Create RANK expression. */
1640 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1641 gfc_current_locus, 1,
1642 gfc_lval_expr_from_sym (array));
1643 gfc_convert_type (rank, &idx->ts, 2);
1645 /* Create is_contiguous variable. */
1646 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1647 is_contiguous->ts.type = BT_LOGICAL;
1648 is_contiguous->ts.kind = gfc_default_logical_kind;
1649 is_contiguous->attr.flavor = FL_VARIABLE;
1650 is_contiguous->attr.artificial = 1;
1651 gfc_set_sym_referenced (is_contiguous);
1652 gfc_commit_symbol (is_contiguous);
1654 /* Create "sizes(0..rank)" variable, which contains the multiplied
1655 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1656 sizes(2) = sizes(1) * extent(dim=2) etc. */
1657 gfc_get_symbol ("sizes", sub_ns, &sizes);
1658 sizes->ts.type = BT_INTEGER;
1659 sizes->ts.kind = gfc_index_integer_kind;
1660 sizes->attr.flavor = FL_VARIABLE;
1661 sizes->attr.dimension = 1;
1662 sizes->attr.artificial = 1;
1663 sizes->as = gfc_get_array_spec();
1664 sizes->attr.intent = INTENT_INOUT;
1665 sizes->as->type = AS_EXPLICIT;
1666 sizes->as->rank = 1;
1667 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1668 sizes->as->upper[0] = gfc_copy_expr (rank);
1669 gfc_set_sym_referenced (sizes);
1670 gfc_commit_symbol (sizes);
1672 /* Create "strides(1..rank)" variable, which contains the strides per
1673 dimension. */
1674 gfc_get_symbol ("strides", sub_ns, &strides);
1675 strides->ts.type = BT_INTEGER;
1676 strides->ts.kind = gfc_index_integer_kind;
1677 strides->attr.flavor = FL_VARIABLE;
1678 strides->attr.dimension = 1;
1679 strides->attr.artificial = 1;
1680 strides->as = gfc_get_array_spec();
1681 strides->attr.intent = INTENT_INOUT;
1682 strides->as->type = AS_EXPLICIT;
1683 strides->as->rank = 1;
1684 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1685 strides->as->upper[0] = gfc_copy_expr (rank);
1686 gfc_set_sym_referenced (strides);
1687 gfc_commit_symbol (strides);
1690 /* Set return value to 0. */
1691 last_code = XCNEW (gfc_code);
1692 last_code->op = EXEC_ASSIGN;
1693 last_code->loc = gfc_current_locus;
1694 last_code->expr1 = gfc_lval_expr_from_sym (final);
1695 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1696 sub_ns->code = last_code;
1698 /* Set: is_contiguous = .true. */
1699 last_code->next = XCNEW (gfc_code);
1700 last_code = last_code->next;
1701 last_code->op = EXEC_ASSIGN;
1702 last_code->loc = gfc_current_locus;
1703 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1704 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1705 &gfc_current_locus, true);
1707 /* Set: sizes(0) = 1. */
1708 last_code->next = XCNEW (gfc_code);
1709 last_code = last_code->next;
1710 last_code->op = EXEC_ASSIGN;
1711 last_code->loc = gfc_current_locus;
1712 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1713 last_code->expr1->ref = gfc_get_ref ();
1714 last_code->expr1->ref->type = REF_ARRAY;
1715 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1716 last_code->expr1->ref->u.ar.dimen = 1;
1717 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1718 last_code->expr1->ref->u.ar.start[0]
1719 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1720 last_code->expr1->ref->u.ar.as = sizes->as;
1721 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1723 /* Create:
1724 DO idx = 1, rank
1725 strides(idx) = _F._stride (array, dim=idx)
1726 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1727 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1728 END DO. */
1730 /* Create loop. */
1731 iter = gfc_get_iterator ();
1732 iter->var = gfc_lval_expr_from_sym (idx);
1733 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1734 iter->end = gfc_copy_expr (rank);
1735 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1736 last_code->next = XCNEW (gfc_code);
1737 last_code = last_code->next;
1738 last_code->op = EXEC_DO;
1739 last_code->loc = gfc_current_locus;
1740 last_code->ext.iterator = iter;
1741 last_code->block = gfc_get_code ();
1742 last_code->block->op = EXEC_DO;
1744 /* strides(idx) = _F._stride(array,dim=idx). */
1745 last_code->block->next = XCNEW (gfc_code);
1746 block = last_code->block->next;
1747 block->op = EXEC_ASSIGN;
1748 block->loc = gfc_current_locus;
1750 block->expr1 = gfc_lval_expr_from_sym (strides);
1751 block->expr1->ref = gfc_get_ref ();
1752 block->expr1->ref->type = REF_ARRAY;
1753 block->expr1->ref->u.ar.type = AR_ELEMENT;
1754 block->expr1->ref->u.ar.dimen = 1;
1755 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1756 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1757 block->expr1->ref->u.ar.as = strides->as;
1759 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1760 gfc_current_locus, 2,
1761 gfc_lval_expr_from_sym (array),
1762 gfc_lval_expr_from_sym (idx));
1764 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1765 block->next = XCNEW (gfc_code);
1766 block = block->next;
1767 block->op = EXEC_ASSIGN;
1768 block->loc = gfc_current_locus;
1770 /* sizes(idx) = ... */
1771 block->expr1 = gfc_lval_expr_from_sym (sizes);
1772 block->expr1->ref = gfc_get_ref ();
1773 block->expr1->ref->type = REF_ARRAY;
1774 block->expr1->ref->u.ar.type = AR_ELEMENT;
1775 block->expr1->ref->u.ar.dimen = 1;
1776 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1777 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1778 block->expr1->ref->u.ar.as = sizes->as;
1780 block->expr2 = gfc_get_expr ();
1781 block->expr2->expr_type = EXPR_OP;
1782 block->expr2->value.op.op = INTRINSIC_TIMES;
1784 /* sizes(idx-1). */
1785 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1786 block->expr2->value.op.op1->ref = gfc_get_ref ();
1787 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1788 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1789 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1790 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1791 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1792 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1793 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1794 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1795 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1796 = gfc_lval_expr_from_sym (idx);
1797 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1798 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1799 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1800 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1802 /* size(array, dim=idx, kind=index_kind). */
1803 block->expr2->value.op.op2
1804 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1805 gfc_current_locus, 3,
1806 gfc_lval_expr_from_sym (array),
1807 gfc_lval_expr_from_sym (idx),
1808 gfc_get_int_expr (gfc_index_integer_kind,
1809 NULL,
1810 gfc_index_integer_kind));
1811 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1812 block->expr2->ts = idx->ts;
1814 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1815 block->next = XCNEW (gfc_code);
1816 block = block->next;
1817 block->loc = gfc_current_locus;
1818 block->op = EXEC_IF;
1820 block->block = XCNEW (gfc_code);
1821 block = block->block;
1822 block->loc = gfc_current_locus;
1823 block->op = EXEC_IF;
1825 /* if condition: strides(idx) /= sizes(idx-1). */
1826 block->expr1 = gfc_get_expr ();
1827 block->expr1->ts.type = BT_LOGICAL;
1828 block->expr1->ts.kind = gfc_default_logical_kind;
1829 block->expr1->expr_type = EXPR_OP;
1830 block->expr1->where = gfc_current_locus;
1831 block->expr1->value.op.op = INTRINSIC_NE;
1833 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1834 block->expr1->value.op.op1->ref = gfc_get_ref ();
1835 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1836 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1837 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1838 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1839 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1840 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1842 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1843 block->expr1->value.op.op2->ref = gfc_get_ref ();
1844 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1845 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1846 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1847 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1848 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1849 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1850 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1851 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1852 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1853 = gfc_lval_expr_from_sym (idx);
1854 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1855 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1856 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1857 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1859 /* if body: is_contiguous = .false. */
1860 block->next = XCNEW (gfc_code);
1861 block = block->next;
1862 block->op = EXEC_ASSIGN;
1863 block->loc = gfc_current_locus;
1864 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1865 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1866 &gfc_current_locus, false);
1868 /* Obtain the size (number of elements) of "array" MINUS ONE,
1869 which is used in the scalarization. */
1870 gfc_get_symbol ("nelem", sub_ns, &nelem);
1871 nelem->ts.type = BT_INTEGER;
1872 nelem->ts.kind = gfc_index_integer_kind;
1873 nelem->attr.flavor = FL_VARIABLE;
1874 nelem->attr.artificial = 1;
1875 gfc_set_sym_referenced (nelem);
1876 gfc_commit_symbol (nelem);
1878 /* nelem = sizes (rank) - 1. */
1879 last_code->next = XCNEW (gfc_code);
1880 last_code = last_code->next;
1881 last_code->op = EXEC_ASSIGN;
1882 last_code->loc = gfc_current_locus;
1884 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
1886 last_code->expr2 = gfc_get_expr ();
1887 last_code->expr2->expr_type = EXPR_OP;
1888 last_code->expr2->value.op.op = INTRINSIC_MINUS;
1889 last_code->expr2->value.op.op2
1890 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1891 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
1893 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1894 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
1895 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
1896 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1897 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
1898 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1899 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
1900 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1902 /* Call final subroutines. We now generate code like:
1903 use iso_c_binding
1904 integer, pointer :: ptr
1905 type(c_ptr) :: cptr
1906 integer(c_intptr_t) :: i, addr
1908 select case (rank (array))
1909 case (3)
1910 ! If needed, the array is packed
1911 call final_rank3 (array)
1912 case default:
1913 do i = 0, size (array)-1
1914 addr = transfer (c_loc (array), addr) + i * stride
1915 call c_f_pointer (transfer (addr, cptr), ptr)
1916 call elemental_final (ptr)
1917 end do
1918 end select */
1920 if (derived->f2k_derived && derived->f2k_derived->finalizers)
1922 gfc_finalizer *fini, *fini_elem = NULL;
1924 gfc_get_symbol ("ptr", sub_ns, &ptr);
1925 ptr->ts.type = BT_DERIVED;
1926 ptr->ts.u.derived = derived;
1927 ptr->attr.flavor = FL_VARIABLE;
1928 ptr->attr.pointer = 1;
1929 ptr->attr.artificial = 1;
1930 gfc_set_sym_referenced (ptr);
1931 gfc_commit_symbol (ptr);
1933 /* SELECT CASE (RANK (array)). */
1934 last_code->next = XCNEW (gfc_code);
1935 last_code = last_code->next;
1936 last_code->op = EXEC_SELECT;
1937 last_code->loc = gfc_current_locus;
1938 last_code->expr1 = gfc_copy_expr (rank);
1939 block = NULL;
1941 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
1943 if (fini->proc_tree->n.sym->attr.elemental)
1945 fini_elem = fini;
1946 continue;
1949 /* CASE (fini_rank). */
1950 if (block)
1952 block->block = XCNEW (gfc_code);
1953 block = block->block;
1955 else
1957 block = XCNEW (gfc_code);
1958 last_code->block = block;
1960 block->loc = gfc_current_locus;
1961 block->op = EXEC_SELECT;
1962 block->ext.block.case_list = gfc_get_case ();
1963 block->ext.block.case_list->where = gfc_current_locus;
1964 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1965 block->ext.block.case_list->low
1966 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
1967 fini->proc_tree->n.sym->formal->sym->as->rank);
1968 else
1969 block->ext.block.case_list->low
1970 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1971 block->ext.block.case_list->high
1972 = gfc_copy_expr (block->ext.block.case_list->low);
1974 /* CALL fini_rank (array) - possibly with packing. */
1975 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1976 finalizer_insert_packed_call (block, fini, array, byte_stride,
1977 idx, ptr, nelem, strides,
1978 sizes, idx2, offset, is_contiguous,
1979 rank, sub_ns);
1980 else
1982 block->next = XCNEW (gfc_code);
1983 block->next->op = EXEC_CALL;
1984 block->next->loc = gfc_current_locus;
1985 block->next->symtree = fini->proc_tree;
1986 block->next->resolved_sym = fini->proc_tree->n.sym;
1987 block->next->ext.actual = gfc_get_actual_arglist ();
1988 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1992 /* Elemental call - scalarized. */
1993 if (fini_elem)
1995 /* CASE DEFAULT. */
1996 if (block)
1998 block->block = XCNEW (gfc_code);
1999 block = block->block;
2001 else
2003 block = XCNEW (gfc_code);
2004 last_code->block = block;
2006 block->loc = gfc_current_locus;
2007 block->op = EXEC_SELECT;
2008 block->ext.block.case_list = gfc_get_case ();
2010 /* Create loop. */
2011 iter = gfc_get_iterator ();
2012 iter->var = gfc_lval_expr_from_sym (idx);
2013 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2014 iter->end = gfc_lval_expr_from_sym (nelem);
2015 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2016 block->next = XCNEW (gfc_code);
2017 block = block->next;
2018 block->op = EXEC_DO;
2019 block->loc = gfc_current_locus;
2020 block->ext.iterator = iter;
2021 block->block = gfc_get_code ();
2022 block->block->op = EXEC_DO;
2024 /* Offset calculation. */
2025 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2026 byte_stride, rank, block->block,
2027 sub_ns);
2029 /* Create code for
2030 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2031 + offset, c_ptr), ptr). */
2032 block->next
2033 = finalization_scalarizer (array, ptr,
2034 gfc_lval_expr_from_sym (offset),
2035 sub_ns);
2036 block = block->next;
2038 /* CALL final_elemental (array). */
2039 block->next = XCNEW (gfc_code);
2040 block = block->next;
2041 block->op = EXEC_CALL;
2042 block->loc = gfc_current_locus;
2043 block->symtree = fini_elem->proc_tree;
2044 block->resolved_sym = fini_elem->proc_sym;
2045 block->ext.actual = gfc_get_actual_arglist ();
2046 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
2050 /* Finalize and deallocate allocatable components. The same manual
2051 scalarization is used as above. */
2053 if (finalizable_comp)
2055 gfc_symbol *stat;
2056 gfc_code *block = NULL;
2058 if (!ptr)
2060 gfc_get_symbol ("ptr", sub_ns, &ptr);
2061 ptr->ts.type = BT_DERIVED;
2062 ptr->ts.u.derived = derived;
2063 ptr->attr.flavor = FL_VARIABLE;
2064 ptr->attr.pointer = 1;
2065 ptr->attr.artificial = 1;
2066 gfc_set_sym_referenced (ptr);
2067 gfc_commit_symbol (ptr);
2070 gfc_get_symbol ("ignore", sub_ns, &stat);
2071 stat->attr.flavor = FL_VARIABLE;
2072 stat->attr.artificial = 1;
2073 stat->ts.type = BT_INTEGER;
2074 stat->ts.kind = gfc_default_integer_kind;
2075 gfc_set_sym_referenced (stat);
2076 gfc_commit_symbol (stat);
2078 /* Create loop. */
2079 iter = gfc_get_iterator ();
2080 iter->var = gfc_lval_expr_from_sym (idx);
2081 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2082 iter->end = gfc_lval_expr_from_sym (nelem);
2083 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2084 last_code->next = XCNEW (gfc_code);
2085 last_code = last_code->next;
2086 last_code->op = EXEC_DO;
2087 last_code->loc = gfc_current_locus;
2088 last_code->ext.iterator = iter;
2089 last_code->block = gfc_get_code ();
2090 last_code->block->op = EXEC_DO;
2092 /* Offset calculation. */
2093 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2094 byte_stride, rank, last_code->block,
2095 sub_ns);
2097 /* Create code for
2098 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2099 + idx * stride, c_ptr), ptr). */
2100 block->next = finalization_scalarizer (array, ptr,
2101 gfc_lval_expr_from_sym(offset),
2102 sub_ns);
2103 block = block->next;
2105 for (comp = derived->components; comp; comp = comp->next)
2107 if (comp == derived->components && derived->attr.extension
2108 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2109 continue;
2111 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2112 stat, fini_coarray, &block);
2113 if (!last_code->block->next)
2114 last_code->block->next = block;
2119 /* Call the finalizer of the ancestor. */
2120 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2122 last_code->next = XCNEW (gfc_code);
2123 last_code = last_code->next;
2124 last_code->op = EXEC_CALL;
2125 last_code->loc = gfc_current_locus;
2126 last_code->symtree = ancestor_wrapper->symtree;
2127 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2129 last_code->ext.actual = gfc_get_actual_arglist ();
2130 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2131 last_code->ext.actual->next = gfc_get_actual_arglist ();
2132 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2133 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2134 last_code->ext.actual->next->next->expr
2135 = gfc_lval_expr_from_sym (fini_coarray);
2138 gfc_free_expr (rank);
2139 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2140 vtab_final->ts.interface = final;
2144 /* Add procedure pointers for all type-bound procedures to a vtab. */
2146 static void
2147 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2149 gfc_symbol* super_type;
2151 super_type = gfc_get_derived_super_type (derived);
2153 if (super_type && (super_type != derived))
2155 /* Make sure that the PPCs appear in the same order as in the parent. */
2156 copy_vtab_proc_comps (super_type, vtype);
2157 /* Only needed to get the PPC initializers right. */
2158 add_procs_to_declared_vtab (super_type, vtype);
2161 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2162 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2164 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2165 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2169 /* Find or generate the symbol for a derived type's vtab. */
2171 gfc_symbol *
2172 gfc_find_derived_vtab (gfc_symbol *derived)
2174 gfc_namespace *ns;
2175 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2176 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2178 /* Find the top-level namespace. */
2179 for (ns = gfc_current_ns; ns; ns = ns->parent)
2180 if (!ns->parent)
2181 break;
2183 /* If the type is a class container, use the underlying derived type. */
2184 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2185 derived = gfc_get_derived_super_type (derived);
2187 if (ns)
2189 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2191 get_unique_hashed_string (tname, derived);
2192 sprintf (name, "__vtab_%s", tname);
2194 /* Look for the vtab symbol in various namespaces. */
2195 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2196 if (vtab == NULL)
2197 gfc_find_symbol (name, ns, 0, &vtab);
2198 if (vtab == NULL)
2199 gfc_find_symbol (name, derived->ns, 0, &vtab);
2201 if (vtab == NULL)
2203 gfc_get_symbol (name, ns, &vtab);
2204 vtab->ts.type = BT_DERIVED;
2205 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2206 &gfc_current_locus))
2207 goto cleanup;
2208 vtab->attr.target = 1;
2209 vtab->attr.save = SAVE_IMPLICIT;
2210 vtab->attr.vtab = 1;
2211 vtab->attr.access = ACCESS_PUBLIC;
2212 gfc_set_sym_referenced (vtab);
2213 sprintf (name, "__vtype_%s", tname);
2215 gfc_find_symbol (name, ns, 0, &vtype);
2216 if (vtype == NULL)
2218 gfc_component *c;
2219 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2221 gfc_get_symbol (name, ns, &vtype);
2222 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2223 &gfc_current_locus))
2224 goto cleanup;
2225 vtype->attr.access = ACCESS_PUBLIC;
2226 vtype->attr.vtype = 1;
2227 gfc_set_sym_referenced (vtype);
2229 /* Add component '_hash'. */
2230 if (!gfc_add_component (vtype, "_hash", &c))
2231 goto cleanup;
2232 c->ts.type = BT_INTEGER;
2233 c->ts.kind = 4;
2234 c->attr.access = ACCESS_PRIVATE;
2235 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2236 NULL, derived->hash_value);
2238 /* Add component '_size'. */
2239 if (!gfc_add_component (vtype, "_size", &c))
2240 goto cleanup;
2241 c->ts.type = BT_INTEGER;
2242 c->ts.kind = 4;
2243 c->attr.access = ACCESS_PRIVATE;
2244 /* Remember the derived type in ts.u.derived,
2245 so that the correct initializer can be set later on
2246 (in gfc_conv_structure). */
2247 c->ts.u.derived = derived;
2248 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2249 NULL, 0);
2251 /* Add component _extends. */
2252 if (!gfc_add_component (vtype, "_extends", &c))
2253 goto cleanup;
2254 c->attr.pointer = 1;
2255 c->attr.access = ACCESS_PRIVATE;
2256 if (!derived->attr.unlimited_polymorphic)
2257 parent = gfc_get_derived_super_type (derived);
2258 else
2259 parent = NULL;
2261 if (parent)
2263 parent_vtab = gfc_find_derived_vtab (parent);
2264 c->ts.type = BT_DERIVED;
2265 c->ts.u.derived = parent_vtab->ts.u.derived;
2266 c->initializer = gfc_get_expr ();
2267 c->initializer->expr_type = EXPR_VARIABLE;
2268 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2269 0, &c->initializer->symtree);
2271 else
2273 c->ts.type = BT_DERIVED;
2274 c->ts.u.derived = vtype;
2275 c->initializer = gfc_get_null_expr (NULL);
2278 if (!derived->attr.unlimited_polymorphic
2279 && derived->components == NULL
2280 && !derived->attr.zero_comp)
2282 /* At this point an error must have occurred.
2283 Prevent further errors on the vtype components. */
2284 found_sym = vtab;
2285 goto have_vtype;
2288 /* Add component _def_init. */
2289 if (!gfc_add_component (vtype, "_def_init", &c))
2290 goto cleanup;
2291 c->attr.pointer = 1;
2292 c->attr.artificial = 1;
2293 c->attr.access = ACCESS_PRIVATE;
2294 c->ts.type = BT_DERIVED;
2295 c->ts.u.derived = derived;
2296 if (derived->attr.unlimited_polymorphic
2297 || derived->attr.abstract)
2298 c->initializer = gfc_get_null_expr (NULL);
2299 else
2301 /* Construct default initialization variable. */
2302 sprintf (name, "__def_init_%s", tname);
2303 gfc_get_symbol (name, ns, &def_init);
2304 def_init->attr.target = 1;
2305 def_init->attr.artificial = 1;
2306 def_init->attr.save = SAVE_IMPLICIT;
2307 def_init->attr.access = ACCESS_PUBLIC;
2308 def_init->attr.flavor = FL_VARIABLE;
2309 gfc_set_sym_referenced (def_init);
2310 def_init->ts.type = BT_DERIVED;
2311 def_init->ts.u.derived = derived;
2312 def_init->value = gfc_default_initializer (&def_init->ts);
2314 c->initializer = gfc_lval_expr_from_sym (def_init);
2317 /* Add component _copy. */
2318 if (!gfc_add_component (vtype, "_copy", &c))
2319 goto cleanup;
2320 c->attr.proc_pointer = 1;
2321 c->attr.access = ACCESS_PRIVATE;
2322 c->tb = XCNEW (gfc_typebound_proc);
2323 c->tb->ppc = 1;
2324 if (derived->attr.unlimited_polymorphic
2325 || derived->attr.abstract)
2326 c->initializer = gfc_get_null_expr (NULL);
2327 else
2329 /* Set up namespace. */
2330 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2331 sub_ns->sibling = ns->contained;
2332 ns->contained = sub_ns;
2333 sub_ns->resolved = 1;
2334 /* Set up procedure symbol. */
2335 sprintf (name, "__copy_%s", tname);
2336 gfc_get_symbol (name, sub_ns, &copy);
2337 sub_ns->proc_name = copy;
2338 copy->attr.flavor = FL_PROCEDURE;
2339 copy->attr.subroutine = 1;
2340 copy->attr.pure = 1;
2341 copy->attr.artificial = 1;
2342 copy->attr.if_source = IFSRC_DECL;
2343 /* This is elemental so that arrays are automatically
2344 treated correctly by the scalarizer. */
2345 copy->attr.elemental = 1;
2346 if (ns->proc_name->attr.flavor == FL_MODULE)
2347 copy->module = ns->proc_name->name;
2348 gfc_set_sym_referenced (copy);
2349 /* Set up formal arguments. */
2350 gfc_get_symbol ("src", sub_ns, &src);
2351 src->ts.type = BT_DERIVED;
2352 src->ts.u.derived = derived;
2353 src->attr.flavor = FL_VARIABLE;
2354 src->attr.dummy = 1;
2355 src->attr.artificial = 1;
2356 src->attr.intent = INTENT_IN;
2357 gfc_set_sym_referenced (src);
2358 copy->formal = gfc_get_formal_arglist ();
2359 copy->formal->sym = src;
2360 gfc_get_symbol ("dst", sub_ns, &dst);
2361 dst->ts.type = BT_DERIVED;
2362 dst->ts.u.derived = derived;
2363 dst->attr.flavor = FL_VARIABLE;
2364 dst->attr.dummy = 1;
2365 dst->attr.artificial = 1;
2366 dst->attr.intent = INTENT_OUT;
2367 gfc_set_sym_referenced (dst);
2368 copy->formal->next = gfc_get_formal_arglist ();
2369 copy->formal->next->sym = dst;
2370 /* Set up code. */
2371 sub_ns->code = gfc_get_code ();
2372 sub_ns->code->op = EXEC_INIT_ASSIGN;
2373 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2374 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2375 /* Set initializer. */
2376 c->initializer = gfc_lval_expr_from_sym (copy);
2377 c->ts.interface = copy;
2380 /* Add component _final, which contains a procedure pointer to
2381 a wrapper which handles both the freeing of allocatable
2382 components and the calls to finalization subroutines.
2383 Note: The actual wrapper function can only be generated
2384 at resolution time. */
2385 /* FIXME: Enable ABI-breaking "_final" generation. */
2386 if (0)
2388 if (!gfc_add_component (vtype, "_final", &c))
2389 goto cleanup;
2390 c->attr.proc_pointer = 1;
2391 c->attr.access = ACCESS_PRIVATE;
2392 c->tb = XCNEW (gfc_typebound_proc);
2393 c->tb->ppc = 1;
2394 generate_finalization_wrapper (derived, ns, tname, c);
2397 /* Add procedure pointers for type-bound procedures. */
2398 if (!derived->attr.unlimited_polymorphic)
2399 add_procs_to_declared_vtab (derived, vtype);
2402 have_vtype:
2403 vtab->ts.u.derived = vtype;
2404 vtab->value = gfc_default_initializer (&vtab->ts);
2408 found_sym = vtab;
2410 cleanup:
2411 /* It is unexpected to have some symbols added at resolution or code
2412 generation time. We commit the changes in order to keep a clean state. */
2413 if (found_sym)
2415 gfc_commit_symbol (vtab);
2416 if (vtype)
2417 gfc_commit_symbol (vtype);
2418 if (def_init)
2419 gfc_commit_symbol (def_init);
2420 if (copy)
2421 gfc_commit_symbol (copy);
2422 if (src)
2423 gfc_commit_symbol (src);
2424 if (dst)
2425 gfc_commit_symbol (dst);
2427 else
2428 gfc_undo_symbols ();
2430 return found_sym;
2434 /* Check if a derived type is finalizable. That is the case if it
2435 (1) has a FINAL subroutine or
2436 (2) has a nonpointer nonallocatable component of finalizable type.
2437 If it is finalizable, return an expression containing the
2438 finalization wrapper. */
2440 bool
2441 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2443 gfc_symbol *vtab;
2444 gfc_component *c;
2446 /* (1) Check for FINAL subroutines. */
2447 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2448 goto yes;
2450 /* (2) Check for components of finalizable type. */
2451 for (c = derived->components; c; c = c->next)
2452 if (c->ts.type == BT_DERIVED
2453 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2454 && gfc_is_finalizable (c->ts.u.derived, NULL))
2455 goto yes;
2457 return false;
2459 yes:
2460 /* Make sure vtab is generated. */
2461 vtab = gfc_find_derived_vtab (derived);
2462 if (final_expr)
2464 /* Return finalizer expression. */
2465 gfc_component *final;
2466 final = vtab->ts.u.derived->components->next->next->next->next->next;
2467 gcc_assert (strcmp (final->name, "_final") == 0);
2468 gcc_assert (final->initializer
2469 && final->initializer->expr_type != EXPR_NULL);
2470 *final_expr = final->initializer;
2472 return true;
2476 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2477 need to support unlimited polymorphism. */
2479 gfc_symbol *
2480 gfc_find_intrinsic_vtab (gfc_typespec *ts)
2482 gfc_namespace *ns;
2483 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2484 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2485 int charlen = 0;
2487 if (ts->type == BT_CHARACTER && ts->deferred)
2489 gfc_error ("TODO: Deferred character length variable at %C cannot "
2490 "yet be associated with unlimited polymorphic entities");
2491 return NULL;
2494 if (ts->type == BT_UNKNOWN)
2495 return NULL;
2497 /* Sometimes the typespec is passed from a single call. */
2498 if (ts->type == BT_DERIVED)
2499 return gfc_find_derived_vtab (ts->u.derived);
2501 /* Find the top-level namespace. */
2502 for (ns = gfc_current_ns; ns; ns = ns->parent)
2503 if (!ns->parent)
2504 break;
2506 if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
2507 && ts->u.cl->length->expr_type == EXPR_CONSTANT)
2508 charlen = mpz_get_si (ts->u.cl->length->value.integer);
2510 if (ns)
2512 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2514 if (ts->type == BT_CHARACTER)
2515 sprintf (tname, "%s_%d_%d", gfc_basic_typename (ts->type),
2516 charlen, ts->kind);
2517 else
2518 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2520 sprintf (name, "__vtab_%s", tname);
2522 /* Look for the vtab symbol in various namespaces. */
2523 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2524 if (vtab == NULL)
2525 gfc_find_symbol (name, ns, 0, &vtab);
2527 if (vtab == NULL)
2529 gfc_get_symbol (name, ns, &vtab);
2530 vtab->ts.type = BT_DERIVED;
2531 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2532 &gfc_current_locus))
2533 goto cleanup;
2534 vtab->attr.target = 1;
2535 vtab->attr.save = SAVE_IMPLICIT;
2536 vtab->attr.vtab = 1;
2537 vtab->attr.access = ACCESS_PUBLIC;
2538 gfc_set_sym_referenced (vtab);
2539 sprintf (name, "__vtype_%s", tname);
2541 gfc_find_symbol (name, ns, 0, &vtype);
2542 if (vtype == NULL)
2544 gfc_component *c;
2545 int hash;
2546 gfc_namespace *sub_ns;
2547 gfc_namespace *contained;
2549 gfc_get_symbol (name, ns, &vtype);
2550 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2551 &gfc_current_locus))
2552 goto cleanup;
2553 vtype->attr.access = ACCESS_PUBLIC;
2554 vtype->attr.vtype = 1;
2555 gfc_set_sym_referenced (vtype);
2557 /* Add component '_hash'. */
2558 if (!gfc_add_component (vtype, "_hash", &c))
2559 goto cleanup;
2560 c->ts.type = BT_INTEGER;
2561 c->ts.kind = 4;
2562 c->attr.access = ACCESS_PRIVATE;
2563 hash = gfc_intrinsic_hash_value (ts);
2564 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2565 NULL, hash);
2567 /* Add component '_size'. */
2568 if (!gfc_add_component (vtype, "_size", &c))
2569 goto cleanup;
2570 c->ts.type = BT_INTEGER;
2571 c->ts.kind = 4;
2572 c->attr.access = ACCESS_PRIVATE;
2573 if (ts->type == BT_CHARACTER)
2574 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2575 NULL, charlen*ts->kind);
2576 else
2577 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2578 NULL, ts->kind);
2580 /* Add component _extends. */
2581 if (!gfc_add_component (vtype, "_extends", &c))
2582 goto cleanup;
2583 c->attr.pointer = 1;
2584 c->attr.access = ACCESS_PRIVATE;
2585 c->ts.type = BT_VOID;
2586 c->initializer = gfc_get_null_expr (NULL);
2588 /* Add component _def_init. */
2589 if (!gfc_add_component (vtype, "_def_init", &c))
2590 goto cleanup;
2591 c->attr.pointer = 1;
2592 c->attr.access = ACCESS_PRIVATE;
2593 c->ts.type = BT_VOID;
2594 c->initializer = gfc_get_null_expr (NULL);
2596 /* Add component _copy. */
2597 if (!gfc_add_component (vtype, "_copy", &c))
2598 goto cleanup;
2599 c->attr.proc_pointer = 1;
2600 c->attr.access = ACCESS_PRIVATE;
2601 c->tb = XCNEW (gfc_typebound_proc);
2602 c->tb->ppc = 1;
2604 /* Check to see if copy function already exists. Note
2605 that this is only used for characters of different
2606 lengths. */
2607 contained = ns->contained;
2608 for (; contained; contained = contained->sibling)
2609 if (contained->proc_name
2610 && strcmp (name, contained->proc_name->name) == 0)
2612 copy = contained->proc_name;
2613 goto got_char_copy;
2616 /* Set up namespace. */
2617 sub_ns = gfc_get_namespace (ns, 0);
2618 sub_ns->sibling = ns->contained;
2619 ns->contained = sub_ns;
2620 sub_ns->resolved = 1;
2621 /* Set up procedure symbol. */
2622 if (ts->type != BT_CHARACTER)
2623 sprintf (name, "__copy_%s", tname);
2624 else
2625 /* __copy is always the same for characters. */
2626 sprintf (name, "__copy_character_%d", ts->kind);
2627 gfc_get_symbol (name, sub_ns, &copy);
2628 sub_ns->proc_name = copy;
2629 copy->attr.flavor = FL_PROCEDURE;
2630 copy->attr.subroutine = 1;
2631 copy->attr.pure = 1;
2632 copy->attr.if_source = IFSRC_DECL;
2633 /* This is elemental so that arrays are automatically
2634 treated correctly by the scalarizer. */
2635 copy->attr.elemental = 1;
2636 if (ns->proc_name->attr.flavor == FL_MODULE)
2637 copy->module = ns->proc_name->name;
2638 gfc_set_sym_referenced (copy);
2639 /* Set up formal arguments. */
2640 gfc_get_symbol ("src", sub_ns, &src);
2641 src->ts.type = ts->type;
2642 src->ts.kind = ts->kind;
2643 src->attr.flavor = FL_VARIABLE;
2644 src->attr.dummy = 1;
2645 src->attr.intent = INTENT_IN;
2646 gfc_set_sym_referenced (src);
2647 copy->formal = gfc_get_formal_arglist ();
2648 copy->formal->sym = src;
2649 gfc_get_symbol ("dst", sub_ns, &dst);
2650 dst->ts.type = ts->type;
2651 dst->ts.kind = ts->kind;
2652 dst->attr.flavor = FL_VARIABLE;
2653 dst->attr.dummy = 1;
2654 dst->attr.intent = INTENT_OUT;
2655 gfc_set_sym_referenced (dst);
2656 copy->formal->next = gfc_get_formal_arglist ();
2657 copy->formal->next->sym = dst;
2658 /* Set up code. */
2659 sub_ns->code = gfc_get_code ();
2660 sub_ns->code->op = EXEC_INIT_ASSIGN;
2661 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2662 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2663 got_char_copy:
2664 /* Set initializer. */
2665 c->initializer = gfc_lval_expr_from_sym (copy);
2666 c->ts.interface = copy;
2668 /* Add component _final. */
2669 if (!gfc_add_component (vtype, "_final", &c))
2670 goto cleanup;
2671 c->attr.proc_pointer = 1;
2672 c->attr.access = ACCESS_PRIVATE;
2673 c->tb = XCNEW (gfc_typebound_proc);
2674 c->tb->ppc = 1;
2675 c->initializer = gfc_get_null_expr (NULL);
2677 vtab->ts.u.derived = vtype;
2678 vtab->value = gfc_default_initializer (&vtab->ts);
2682 found_sym = vtab;
2684 cleanup:
2685 /* It is unexpected to have some symbols added at resolution or code
2686 generation time. We commit the changes in order to keep a clean state. */
2687 if (found_sym)
2689 gfc_commit_symbol (vtab);
2690 if (vtype)
2691 gfc_commit_symbol (vtype);
2692 if (copy)
2693 gfc_commit_symbol (copy);
2694 if (src)
2695 gfc_commit_symbol (src);
2696 if (dst)
2697 gfc_commit_symbol (dst);
2699 else
2700 gfc_undo_symbols ();
2702 return found_sym;
2706 /* General worker function to find either a type-bound procedure or a
2707 type-bound user operator. */
2709 static gfc_symtree*
2710 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2711 const char* name, bool noaccess, bool uop,
2712 locus* where)
2714 gfc_symtree* res;
2715 gfc_symtree* root;
2717 /* Set default to failure. */
2718 if (t)
2719 *t = false;
2721 if (derived->f2k_derived)
2722 /* Set correct symbol-root. */
2723 root = (uop ? derived->f2k_derived->tb_uop_root
2724 : derived->f2k_derived->tb_sym_root);
2725 else
2726 return NULL;
2728 /* Try to find it in the current type's namespace. */
2729 res = gfc_find_symtree (root, name);
2730 if (res && res->n.tb && !res->n.tb->error)
2732 /* We found one. */
2733 if (t)
2734 *t = true;
2736 if (!noaccess && derived->attr.use_assoc
2737 && res->n.tb->access == ACCESS_PRIVATE)
2739 if (where)
2740 gfc_error ("'%s' of '%s' is PRIVATE at %L",
2741 name, derived->name, where);
2742 if (t)
2743 *t = false;
2746 return res;
2749 /* Otherwise, recurse on parent type if derived is an extension. */
2750 if (derived->attr.extension)
2752 gfc_symbol* super_type;
2753 super_type = gfc_get_derived_super_type (derived);
2754 gcc_assert (super_type);
2756 return find_typebound_proc_uop (super_type, t, name,
2757 noaccess, uop, where);
2760 /* Nothing found. */
2761 return NULL;
2765 /* Find a type-bound procedure or user operator by name for a derived-type
2766 (looking recursively through the super-types). */
2768 gfc_symtree*
2769 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
2770 const char* name, bool noaccess, locus* where)
2772 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2775 gfc_symtree*
2776 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
2777 const char* name, bool noaccess, locus* where)
2779 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2783 /* Find a type-bound intrinsic operator looking recursively through the
2784 super-type hierarchy. */
2786 gfc_typebound_proc*
2787 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
2788 gfc_intrinsic_op op, bool noaccess,
2789 locus* where)
2791 gfc_typebound_proc* res;
2793 /* Set default to failure. */
2794 if (t)
2795 *t = false;
2797 /* Try to find it in the current type's namespace. */
2798 if (derived->f2k_derived)
2799 res = derived->f2k_derived->tb_op[op];
2800 else
2801 res = NULL;
2803 /* Check access. */
2804 if (res && !res->error)
2806 /* We found one. */
2807 if (t)
2808 *t = true;
2810 if (!noaccess && derived->attr.use_assoc
2811 && res->access == ACCESS_PRIVATE)
2813 if (where)
2814 gfc_error ("'%s' of '%s' is PRIVATE at %L",
2815 gfc_op2string (op), derived->name, where);
2816 if (t)
2817 *t = false;
2820 return res;
2823 /* Otherwise, recurse on parent type if derived is an extension. */
2824 if (derived->attr.extension)
2826 gfc_symbol* super_type;
2827 super_type = gfc_get_derived_super_type (derived);
2828 gcc_assert (super_type);
2830 return gfc_find_typebound_intrinsic_op (super_type, t, op,
2831 noaccess, where);
2834 /* Nothing found. */
2835 return NULL;
2839 /* Get a typebound-procedure symtree or create and insert it if not yet
2840 present. This is like a very simplified version of gfc_get_sym_tree for
2841 tbp-symtrees rather than regular ones. */
2843 gfc_symtree*
2844 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
2846 gfc_symtree *result;
2848 result = gfc_find_symtree (*root, name);
2849 if (!result)
2851 result = gfc_new_symtree (root, name);
2852 gcc_assert (result);
2853 result->n.tb = NULL;
2856 return result;