2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / fortran / class.c
blob52b9760b271738638d0427bd0244045415db261f
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"
56 #include "target-memory.h"
58 /* Inserts a derived type component reference in a data reference chain.
59 TS: base type of the ref chain so far, in which we will pick the component
60 REF: the address of the GFC_REF pointer to update
61 NAME: name of the component to insert
62 Note that component insertion makes sense only if we are at the end of
63 the chain (*REF == NULL) or if we are adding a missing "_data" component
64 to access the actual contents of a class object. */
66 static void
67 insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
69 gfc_symbol *type_sym;
70 gfc_ref *new_ref;
72 gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
73 type_sym = ts->u.derived;
75 new_ref = gfc_get_ref ();
76 new_ref->type = REF_COMPONENT;
77 new_ref->next = *ref;
78 new_ref->u.c.sym = type_sym;
79 new_ref->u.c.component = gfc_find_component (type_sym, name, true, true);
80 gcc_assert (new_ref->u.c.component);
82 if (new_ref->next)
84 gfc_ref *next = NULL;
86 /* We need to update the base type in the trailing reference chain to
87 that of the new component. */
89 gcc_assert (strcmp (name, "_data") == 0);
91 if (new_ref->next->type == REF_COMPONENT)
92 next = new_ref->next;
93 else if (new_ref->next->type == REF_ARRAY
94 && new_ref->next->next
95 && new_ref->next->next->type == REF_COMPONENT)
96 next = new_ref->next->next;
98 if (next != NULL)
100 gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
101 || new_ref->u.c.component->ts.type == BT_DERIVED);
102 next->u.c.sym = new_ref->u.c.component->ts.u.derived;
106 *ref = new_ref;
110 /* Tells whether we need to add a "_data" reference to access REF subobject
111 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base
112 object accessed by REF is a variable; in other words it is a full object,
113 not a subobject. */
115 static bool
116 class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain)
118 /* Only class containers may need the "_data" reference. */
119 if (ts->type != BT_CLASS)
120 return false;
122 /* Accessing a class container with an array reference is certainly wrong. */
123 if (ref->type != REF_COMPONENT)
124 return true;
126 /* Accessing the class container's fields is fine. */
127 if (ref->u.c.component->name[0] == '_')
128 return false;
130 /* At this point we have a class container with a non class container's field
131 component reference. We don't want to add the "_data" component if we are
132 at the first reference and the symbol's type is an extended derived type.
133 In that case, conv_parent_component_references will do the right thing so
134 it is not absolutely necessary. Omitting it prevents a regression (see
135 class_41.f03) in the interface mapping mechanism. When evaluating string
136 lengths depending on dummy arguments, we create a fake symbol with a type
137 equal to that of the dummy type. However, because of type extension,
138 the backend type (corresponding to the actual argument) can have a
139 different (extended) type. Adding the "_data" component explicitly, using
140 the base type, confuses the gfc_conv_component_ref code which deals with
141 the extended type. */
142 if (first_ref_in_chain && ts->u.derived->attr.extension)
143 return false;
145 /* We have a class container with a non class container's field component
146 reference that doesn't fall into the above. */
147 return true;
151 /* Browse through a data reference chain and add the missing "_data" references
152 when a subobject of a class object is accessed without it.
153 Note that it doesn't add the "_data" reference when the class container
154 is the last element in the reference chain. */
156 void
157 gfc_fix_class_refs (gfc_expr *e)
159 gfc_typespec *ts;
160 gfc_ref **ref;
162 if ((e->expr_type != EXPR_VARIABLE
163 && e->expr_type != EXPR_FUNCTION)
164 || (e->expr_type == EXPR_FUNCTION
165 && e->value.function.isym != NULL))
166 return;
168 if (e->expr_type == EXPR_VARIABLE)
169 ts = &e->symtree->n.sym->ts;
170 else
172 gfc_symbol *func;
174 gcc_assert (e->expr_type == EXPR_FUNCTION);
175 if (e->value.function.esym != NULL)
176 func = e->value.function.esym;
177 else
178 func = e->symtree->n.sym;
180 if (func->result != NULL)
181 ts = &func->result->ts;
182 else
183 ts = &func->ts;
186 for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
188 if (class_data_ref_missing (ts, *ref, ref == &e->ref))
189 insert_component_ref (ts, ref, "_data");
191 if ((*ref)->type == REF_COMPONENT)
192 ts = &(*ref)->u.c.component->ts;
197 /* Insert a reference to the component of the given name.
198 Only to be used with CLASS containers and vtables. */
200 void
201 gfc_add_component_ref (gfc_expr *e, const char *name)
203 gfc_ref **tail = &(e->ref);
204 gfc_ref *next = NULL;
205 gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
206 while (*tail != NULL)
208 if ((*tail)->type == REF_COMPONENT)
210 if (strcmp ((*tail)->u.c.component->name, "_data") == 0
211 && (*tail)->next
212 && (*tail)->next->type == REF_ARRAY
213 && (*tail)->next->next == NULL)
214 return;
215 derived = (*tail)->u.c.component->ts.u.derived;
217 if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
218 break;
219 tail = &((*tail)->next);
221 if (*tail != NULL && strcmp (name, "_data") == 0)
222 next = *tail;
223 (*tail) = gfc_get_ref();
224 (*tail)->next = next;
225 (*tail)->type = REF_COMPONENT;
226 (*tail)->u.c.sym = derived;
227 (*tail)->u.c.component = gfc_find_component (derived, name, true, true);
228 gcc_assert((*tail)->u.c.component);
229 if (!next)
230 e->ts = (*tail)->u.c.component->ts;
234 /* This is used to add both the _data component reference and an array
235 reference to class expressions. Used in translation of intrinsic
236 array inquiry functions. */
238 void
239 gfc_add_class_array_ref (gfc_expr *e)
241 int rank = CLASS_DATA (e)->as->rank;
242 gfc_array_spec *as = CLASS_DATA (e)->as;
243 gfc_ref *ref = NULL;
244 gfc_add_component_ref (e, "_data");
245 e->rank = rank;
246 for (ref = e->ref; ref; ref = ref->next)
247 if (!ref->next)
248 break;
249 if (ref->type != REF_ARRAY)
251 ref->next = gfc_get_ref ();
252 ref = ref->next;
253 ref->type = REF_ARRAY;
254 ref->u.ar.type = AR_FULL;
255 ref->u.ar.as = as;
260 /* Unfortunately, class array expressions can appear in various conditions;
261 with and without both _data component and an arrayspec. This function
262 deals with that variability. The previous reference to 'ref' is to a
263 class array. */
265 static bool
266 class_array_ref_detected (gfc_ref *ref, bool *full_array)
268 bool no_data = false;
269 bool with_data = false;
271 /* An array reference with no _data component. */
272 if (ref && ref->type == REF_ARRAY
273 && !ref->next
274 && ref->u.ar.type != AR_ELEMENT)
276 if (full_array)
277 *full_array = ref->u.ar.type == AR_FULL;
278 no_data = true;
281 /* Cover cases where _data appears, with or without an array ref. */
282 if (ref && ref->type == REF_COMPONENT
283 && strcmp (ref->u.c.component->name, "_data") == 0)
285 if (!ref->next)
287 with_data = true;
288 if (full_array)
289 *full_array = true;
291 else if (ref->next && ref->next->type == REF_ARRAY
292 && !ref->next->next
293 && ref->type == REF_COMPONENT
294 && ref->next->type == REF_ARRAY
295 && ref->next->u.ar.type != AR_ELEMENT)
297 with_data = true;
298 if (full_array)
299 *full_array = ref->next->u.ar.type == AR_FULL;
303 return no_data || with_data;
307 /* Returns true if the expression contains a reference to a class
308 array. Notice that class array elements return false. */
310 bool
311 gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
313 gfc_ref *ref;
315 if (!e->rank)
316 return false;
318 if (full_array)
319 *full_array= false;
321 /* Is this a class array object? ie. Is the symbol of type class? */
322 if (e->symtree
323 && e->symtree->n.sym->ts.type == BT_CLASS
324 && CLASS_DATA (e->symtree->n.sym)
325 && CLASS_DATA (e->symtree->n.sym)->attr.dimension
326 && class_array_ref_detected (e->ref, full_array))
327 return true;
329 /* Or is this a class array component reference? */
330 for (ref = e->ref; ref; ref = ref->next)
332 if (ref->type == REF_COMPONENT
333 && ref->u.c.component->ts.type == BT_CLASS
334 && CLASS_DATA (ref->u.c.component)->attr.dimension
335 && class_array_ref_detected (ref->next, full_array))
336 return true;
339 return false;
343 /* Returns true if the expression is a reference to a class
344 scalar. This function is necessary because such expressions
345 can be dressed with a reference to the _data component and so
346 have a type other than BT_CLASS. */
348 bool
349 gfc_is_class_scalar_expr (gfc_expr *e)
351 gfc_ref *ref;
353 if (e->rank)
354 return false;
356 /* Is this a class object? */
357 if (e->symtree
358 && e->symtree->n.sym->ts.type == BT_CLASS
359 && CLASS_DATA (e->symtree->n.sym)
360 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
361 && (e->ref == NULL
362 || (strcmp (e->ref->u.c.component->name, "_data") == 0
363 && e->ref->next == NULL)))
364 return true;
366 /* Or is the final reference BT_CLASS or _data? */
367 for (ref = e->ref; ref; ref = ref->next)
369 if (ref->type == REF_COMPONENT
370 && ref->u.c.component->ts.type == BT_CLASS
371 && CLASS_DATA (ref->u.c.component)
372 && !CLASS_DATA (ref->u.c.component)->attr.dimension
373 && (ref->next == NULL
374 || (strcmp (ref->next->u.c.component->name, "_data") == 0
375 && ref->next->next == NULL)))
376 return true;
379 return false;
383 /* Tells whether the expression E is a reference to a (scalar) class container.
384 Scalar because array class containers usually have an array reference after
385 them, and gfc_fix_class_refs will add the missing "_data" component reference
386 in that case. */
388 bool
389 gfc_is_class_container_ref (gfc_expr *e)
391 gfc_ref *ref;
392 bool result;
394 if (e->expr_type != EXPR_VARIABLE)
395 return e->ts.type == BT_CLASS;
397 if (e->symtree->n.sym->ts.type == BT_CLASS)
398 result = true;
399 else
400 result = false;
402 for (ref = e->ref; ref; ref = ref->next)
404 if (ref->type != REF_COMPONENT)
405 result = false;
406 else if (ref->u.c.component->ts.type == BT_CLASS)
407 result = true;
408 else
409 result = false;
412 return result;
416 /* Build an initializer for CLASS pointers,
417 initializing the _data component to the init_expr (or NULL) and the _vptr
418 component to the corresponding type (or the declared type, given by ts). */
420 gfc_expr *
421 gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
423 gfc_expr *init;
424 gfc_component *comp;
425 gfc_symbol *vtab = NULL;
426 bool is_unlimited_polymorphic;
428 is_unlimited_polymorphic = ts->u.derived
429 && ts->u.derived->components->ts.u.derived
430 && ts->u.derived->components->ts.u.derived->attr.unlimited_polymorphic;
432 if (is_unlimited_polymorphic && init_expr)
433 vtab = gfc_find_intrinsic_vtab (&ts->u.derived->components->ts);
434 else if (init_expr && init_expr->expr_type != EXPR_NULL)
435 vtab = gfc_find_derived_vtab (init_expr->ts.u.derived);
436 else
437 vtab = gfc_find_derived_vtab (ts->u.derived);
439 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
440 &ts->u.derived->declared_at);
441 init->ts = *ts;
443 for (comp = ts->u.derived->components; comp; comp = comp->next)
445 gfc_constructor *ctor = gfc_constructor_get();
446 if (strcmp (comp->name, "_vptr") == 0 && vtab)
447 ctor->expr = gfc_lval_expr_from_sym (vtab);
448 else if (init_expr && init_expr->expr_type != EXPR_NULL)
449 ctor->expr = gfc_copy_expr (init_expr);
450 else
451 ctor->expr = gfc_get_null_expr (NULL);
452 gfc_constructor_append (&init->value.constructor, ctor);
455 return init;
459 /* Create a unique string identifier for a derived type, composed of its name
460 and module name. This is used to construct unique names for the class
461 containers and vtab symbols. */
463 static void
464 get_unique_type_string (char *string, gfc_symbol *derived)
466 char dt_name[GFC_MAX_SYMBOL_LEN+1];
467 if (derived->attr.unlimited_polymorphic)
468 strcpy (dt_name, "STAR");
469 else
470 strcpy (dt_name, derived->name);
471 dt_name[0] = TOUPPER (dt_name[0]);
472 if (derived->attr.unlimited_polymorphic)
473 sprintf (string, "_%s", dt_name);
474 else if (derived->module)
475 sprintf (string, "%s_%s", derived->module, dt_name);
476 else if (derived->ns->proc_name)
477 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
478 else
479 sprintf (string, "_%s", dt_name);
483 /* A relative of 'get_unique_type_string' which makes sure the generated
484 string will not be too long (replacing it by a hash string if needed). */
486 static void
487 get_unique_hashed_string (char *string, gfc_symbol *derived)
489 char tmp[2*GFC_MAX_SYMBOL_LEN+2];
490 get_unique_type_string (&tmp[0], derived);
491 /* If string is too long, use hash value in hex representation (allow for
492 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
493 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
494 where %d is the (co)rank which can be up to n = 15. */
495 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
497 int h = gfc_hash_value (derived);
498 sprintf (string, "%X", h);
500 else
501 strcpy (string, tmp);
505 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
507 unsigned int
508 gfc_hash_value (gfc_symbol *sym)
510 unsigned int hash = 0;
511 char c[2*(GFC_MAX_SYMBOL_LEN+1)];
512 int i, len;
514 get_unique_type_string (&c[0], sym);
515 len = strlen (c);
517 for (i = 0; i < len; i++)
518 hash = (hash << 6) + (hash << 16) - hash + c[i];
520 /* Return the hash but take the modulus for the sake of module read,
521 even though this slightly increases the chance of collision. */
522 return (hash % 100000000);
526 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
528 unsigned int
529 gfc_intrinsic_hash_value (gfc_typespec *ts)
531 unsigned int hash = 0;
532 const char *c = gfc_typename (ts);
533 int i, len;
535 len = strlen (c);
537 for (i = 0; i < len; i++)
538 hash = (hash << 6) + (hash << 16) - hash + c[i];
540 /* Return the hash but take the modulus for the sake of module read,
541 even though this slightly increases the chance of collision. */
542 return (hash % 100000000);
546 /* Build a polymorphic CLASS entity, using the symbol that comes from
547 build_sym. A CLASS entity is represented by an encapsulating type,
548 which contains the declared type as '_data' component, plus a pointer
549 component '_vptr' which determines the dynamic type. */
551 bool
552 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
553 gfc_array_spec **as, bool delayed_vtab)
555 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
556 gfc_symbol *fclass;
557 gfc_symbol *vtab;
558 gfc_component *c;
559 gfc_namespace *ns;
560 int rank;
562 gcc_assert (as);
564 if (*as && (*as)->type == AS_ASSUMED_SIZE)
566 gfc_error ("Assumed size polymorphic objects or components, such "
567 "as that at %C, have not yet been implemented");
568 return false;
571 if (attr->class_ok)
572 /* Class container has already been built. */
573 return true;
575 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
576 || attr->select_type_temporary || attr->associate_var;
578 if (!attr->class_ok)
579 /* We can not build the class container yet. */
580 return true;
582 /* Determine the name of the encapsulating type. */
583 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
584 get_unique_hashed_string (tname, ts->u.derived);
585 if ((*as) && attr->allocatable)
586 sprintf (name, "__class_%s_%d_%da", tname, rank, (*as)->corank);
587 else if ((*as) && attr->pointer)
588 sprintf (name, "__class_%s_%d_%dp", tname, rank, (*as)->corank);
589 else if ((*as))
590 sprintf (name, "__class_%s_%d_%d", tname, rank, (*as)->corank);
591 else if (attr->pointer)
592 sprintf (name, "__class_%s_p", tname);
593 else if (attr->allocatable)
594 sprintf (name, "__class_%s_a", tname);
595 else
596 sprintf (name, "__class_%s", tname);
598 if (ts->u.derived->attr.unlimited_polymorphic)
600 /* Find the top-level namespace. */
601 for (ns = gfc_current_ns; ns; ns = ns->parent)
602 if (!ns->parent)
603 break;
605 else
606 ns = ts->u.derived->ns;
608 gfc_find_symbol (name, ns, 0, &fclass);
609 if (fclass == NULL)
611 gfc_symtree *st;
612 /* If not there, create a new symbol. */
613 fclass = gfc_new_symbol (name, ns);
614 st = gfc_new_symtree (&ns->sym_root, name);
615 st->n.sym = fclass;
616 gfc_set_sym_referenced (fclass);
617 fclass->refs++;
618 fclass->ts.type = BT_UNKNOWN;
619 if (!ts->u.derived->attr.unlimited_polymorphic)
620 fclass->attr.abstract = ts->u.derived->attr.abstract;
621 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
622 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
623 &gfc_current_locus))
624 return false;
626 /* Add component '_data'. */
627 if (!gfc_add_component (fclass, "_data", &c))
628 return false;
629 c->ts = *ts;
630 c->ts.type = BT_DERIVED;
631 c->attr.access = ACCESS_PRIVATE;
632 c->ts.u.derived = ts->u.derived;
633 c->attr.class_pointer = attr->pointer;
634 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
635 || attr->select_type_temporary;
636 c->attr.allocatable = attr->allocatable;
637 c->attr.dimension = attr->dimension;
638 c->attr.codimension = attr->codimension;
639 c->attr.abstract = fclass->attr.abstract;
640 c->as = (*as);
641 c->initializer = NULL;
643 /* Add component '_vptr'. */
644 if (!gfc_add_component (fclass, "_vptr", &c))
645 return false;
646 c->ts.type = BT_DERIVED;
647 if (delayed_vtab
648 || (ts->u.derived->f2k_derived
649 && ts->u.derived->f2k_derived->finalizers))
650 c->ts.u.derived = NULL;
651 else
653 vtab = gfc_find_derived_vtab (ts->u.derived);
654 gcc_assert (vtab);
655 c->ts.u.derived = vtab->ts.u.derived;
657 c->attr.access = ACCESS_PRIVATE;
658 c->attr.pointer = 1;
661 if (!ts->u.derived->attr.unlimited_polymorphic)
663 /* Since the extension field is 8 bit wide, we can only have
664 up to 255 extension levels. */
665 if (ts->u.derived->attr.extension == 255)
667 gfc_error ("Maximum extension level reached with type '%s' at %L",
668 ts->u.derived->name, &ts->u.derived->declared_at);
669 return false;
672 fclass->attr.extension = ts->u.derived->attr.extension + 1;
673 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
674 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
677 fclass->attr.is_class = 1;
678 ts->u.derived = fclass;
679 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
680 (*as) = NULL;
681 return true;
685 /* Add a procedure pointer component to the vtype
686 to represent a specific type-bound procedure. */
688 static void
689 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
691 gfc_component *c;
693 if (tb->non_overridable)
694 return;
696 c = gfc_find_component (vtype, name, true, true);
698 if (c == NULL)
700 /* Add procedure component. */
701 if (!gfc_add_component (vtype, name, &c))
702 return;
704 if (!c->tb)
705 c->tb = XCNEW (gfc_typebound_proc);
706 *c->tb = *tb;
707 c->tb->ppc = 1;
708 c->attr.procedure = 1;
709 c->attr.proc_pointer = 1;
710 c->attr.flavor = FL_PROCEDURE;
711 c->attr.access = ACCESS_PRIVATE;
712 c->attr.external = 1;
713 c->attr.untyped = 1;
714 c->attr.if_source = IFSRC_IFBODY;
716 else if (c->attr.proc_pointer && c->tb)
718 *c->tb = *tb;
719 c->tb->ppc = 1;
722 if (tb->u.specific)
724 c->ts.interface = tb->u.specific->n.sym;
725 if (!tb->deferred)
726 c->initializer = gfc_get_variable_expr (tb->u.specific);
731 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
733 static void
734 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
736 if (!st)
737 return;
739 if (st->left)
740 add_procs_to_declared_vtab1 (st->left, vtype);
742 if (st->right)
743 add_procs_to_declared_vtab1 (st->right, vtype);
745 if (st->n.tb && !st->n.tb->error
746 && !st->n.tb->is_generic && st->n.tb->u.specific)
747 add_proc_comp (vtype, st->name, st->n.tb);
751 /* Copy procedure pointers components from the parent type. */
753 static void
754 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
756 gfc_component *cmp;
757 gfc_symbol *vtab;
759 vtab = gfc_find_derived_vtab (declared);
761 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
763 if (gfc_find_component (vtype, cmp->name, true, true))
764 continue;
766 add_proc_comp (vtype, cmp->name, cmp->tb);
771 /* Returns true if any of its nonpointer nonallocatable components or
772 their nonpointer nonallocatable subcomponents has a finalization
773 subroutine. */
775 static bool
776 has_finalizer_component (gfc_symbol *derived)
778 gfc_component *c;
780 for (c = derived->components; c; c = c->next)
782 if (c->ts.type == BT_DERIVED && c->ts.u.derived->f2k_derived
783 && c->ts.u.derived->f2k_derived->finalizers)
784 return true;
786 if (c->ts.type == BT_DERIVED
787 && !c->attr.pointer && !c->attr.allocatable
788 && has_finalizer_component (c->ts.u.derived))
789 return true;
791 return false;
795 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
796 neither allocatable nor a pointer but has a finalizer, call it. If it
797 is a nonpointer component with allocatable components or has finalizers, walk
798 them. Either of them is required; other nonallocatables and pointers aren't
799 handled gracefully.
800 Note: If the component is allocatable, the DEALLOCATE handling takes care
801 of calling the appropriate finalizers, coarray deregistering, and
802 deallocation of allocatable subcomponents. */
804 static void
805 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
806 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code)
808 gfc_expr *e;
809 gfc_ref *ref;
811 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS
812 && !comp->attr.allocatable)
813 return;
815 if ((comp->ts.type == BT_DERIVED && comp->attr.pointer)
816 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
817 && CLASS_DATA (comp)->attr.pointer))
818 return;
820 if (comp->ts.type == BT_DERIVED && !comp->attr.allocatable
821 && (comp->ts.u.derived->f2k_derived == NULL
822 || comp->ts.u.derived->f2k_derived->finalizers == NULL)
823 && !has_finalizer_component (comp->ts.u.derived))
824 return;
826 e = gfc_copy_expr (expr);
827 if (!e->ref)
828 e->ref = ref = gfc_get_ref ();
829 else
831 for (ref = e->ref; ref->next; ref = ref->next)
833 ref->next = gfc_get_ref ();
834 ref = ref->next;
836 ref->type = REF_COMPONENT;
837 ref->u.c.sym = derived;
838 ref->u.c.component = comp;
839 e->ts = comp->ts;
841 if (comp->attr.dimension || comp->attr.codimension
842 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
843 && (CLASS_DATA (comp)->attr.dimension
844 || CLASS_DATA (comp)->attr.codimension)))
846 ref->next = gfc_get_ref ();
847 ref->next->type = REF_ARRAY;
848 ref->next->u.ar.dimen = 0;
849 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
850 : comp->as;
851 e->rank = ref->next->u.ar.as->rank;
852 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
855 /* Call DEALLOCATE (comp, stat=ignore). */
856 if (comp->attr.allocatable
857 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
858 && CLASS_DATA (comp)->attr.allocatable))
860 gfc_code *dealloc, *block = NULL;
862 /* Add IF (fini_coarray). */
863 if (comp->attr.codimension
864 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
865 && CLASS_DATA (comp)->attr.allocatable))
867 block = gfc_get_code (EXEC_IF);
868 if (*code)
870 (*code)->next = block;
871 (*code) = (*code)->next;
873 else
874 (*code) = block;
876 block->block = gfc_get_code (EXEC_IF);
877 block = block->block;
878 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
881 dealloc = gfc_get_code (EXEC_DEALLOCATE);
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 = gfc_get_code (EXEC_CALL);
913 final_wrap->symtree = c->initializer->symtree;
914 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
915 final_wrap->ext.actual = gfc_get_actual_arglist ();
916 final_wrap->ext.actual->expr = e;
918 if (*code)
920 (*code)->next = final_wrap;
921 (*code) = (*code)->next;
923 else
924 (*code) = final_wrap;
926 else
928 gfc_component *c;
930 for (c = comp->ts.u.derived->components; c; c = c->next)
931 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code);
932 gfc_free_expr (e);
937 /* Generate code equivalent to
938 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
939 + offset, c_ptr), ptr). */
941 static gfc_code *
942 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
943 gfc_expr *offset, gfc_namespace *sub_ns)
945 gfc_code *block;
946 gfc_expr *expr, *expr2;
948 /* C_F_POINTER(). */
949 block = gfc_get_code (EXEC_CALL);
950 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
951 block->resolved_sym = block->symtree->n.sym;
952 block->resolved_sym->attr.flavor = FL_PROCEDURE;
953 block->resolved_sym->attr.intrinsic = 1;
954 block->resolved_sym->attr.subroutine = 1;
955 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
956 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
957 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
958 gfc_commit_symbol (block->resolved_sym);
960 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
961 block->ext.actual = gfc_get_actual_arglist ();
962 block->ext.actual->next = gfc_get_actual_arglist ();
963 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
964 NULL, 0);
965 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
967 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
969 /* TRANSFER's first argument: C_LOC (array). */
970 expr = gfc_get_expr ();
971 expr->expr_type = EXPR_FUNCTION;
972 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
973 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
974 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
975 expr->symtree->n.sym->attr.intrinsic = 1;
976 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
977 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
978 expr->value.function.actual = gfc_get_actual_arglist ();
979 expr->value.function.actual->expr
980 = gfc_lval_expr_from_sym (array);
981 expr->symtree->n.sym->result = expr->symtree->n.sym;
982 gfc_commit_symbol (expr->symtree->n.sym);
983 expr->ts.type = BT_INTEGER;
984 expr->ts.kind = gfc_index_integer_kind;
986 /* TRANSFER. */
987 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
988 gfc_current_locus, 3, expr,
989 gfc_get_int_expr (gfc_index_integer_kind,
990 NULL, 0), NULL);
991 expr2->ts.type = BT_INTEGER;
992 expr2->ts.kind = gfc_index_integer_kind;
994 /* <array addr> + <offset>. */
995 block->ext.actual->expr = gfc_get_expr ();
996 block->ext.actual->expr->expr_type = EXPR_OP;
997 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
998 block->ext.actual->expr->value.op.op1 = expr2;
999 block->ext.actual->expr->value.op.op2 = offset;
1000 block->ext.actual->expr->ts = expr->ts;
1002 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1003 block->ext.actual->next = gfc_get_actual_arglist ();
1004 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1005 block->ext.actual->next->next = gfc_get_actual_arglist ();
1007 return block;
1011 /* Calculates the offset to the (idx+1)th element of an array, taking the
1012 stride into account. It generates the code:
1013 offset = 0
1014 do idx2 = 1, rank
1015 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1016 end do
1017 offset = offset * byte_stride. */
1019 static gfc_code*
1020 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1021 gfc_symbol *strides, gfc_symbol *sizes,
1022 gfc_symbol *byte_stride, gfc_expr *rank,
1023 gfc_code *block, gfc_namespace *sub_ns)
1025 gfc_iterator *iter;
1026 gfc_expr *expr, *expr2;
1028 /* offset = 0. */
1029 block->next = gfc_get_code (EXEC_ASSIGN);
1030 block = block->next;
1031 block->expr1 = gfc_lval_expr_from_sym (offset);
1032 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1034 /* Create loop. */
1035 iter = gfc_get_iterator ();
1036 iter->var = gfc_lval_expr_from_sym (idx2);
1037 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1038 iter->end = gfc_copy_expr (rank);
1039 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1040 block->next = gfc_get_code (EXEC_DO);
1041 block = block->next;
1042 block->ext.iterator = iter;
1043 block->block = gfc_get_code (EXEC_DO);
1045 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1046 * strides(idx2). */
1048 /* mod (idx, sizes(idx2)). */
1049 expr = gfc_lval_expr_from_sym (sizes);
1050 expr->ref = gfc_get_ref ();
1051 expr->ref->type = REF_ARRAY;
1052 expr->ref->u.ar.as = sizes->as;
1053 expr->ref->u.ar.type = AR_ELEMENT;
1054 expr->ref->u.ar.dimen = 1;
1055 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1056 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1058 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1059 gfc_current_locus, 2,
1060 gfc_lval_expr_from_sym (idx), expr);
1061 expr->ts = idx->ts;
1063 /* (...) / sizes(idx2-1). */
1064 expr2 = gfc_get_expr ();
1065 expr2->expr_type = EXPR_OP;
1066 expr2->value.op.op = INTRINSIC_DIVIDE;
1067 expr2->value.op.op1 = expr;
1068 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1069 expr2->value.op.op2->ref = gfc_get_ref ();
1070 expr2->value.op.op2->ref->type = REF_ARRAY;
1071 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1072 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1073 expr2->value.op.op2->ref->u.ar.dimen = 1;
1074 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1075 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1076 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1077 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1078 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1079 = gfc_lval_expr_from_sym (idx2);
1080 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1081 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1082 expr2->value.op.op2->ref->u.ar.start[0]->ts
1083 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1084 expr2->ts = idx->ts;
1086 /* ... * strides(idx2). */
1087 expr = gfc_get_expr ();
1088 expr->expr_type = EXPR_OP;
1089 expr->value.op.op = INTRINSIC_TIMES;
1090 expr->value.op.op1 = expr2;
1091 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1092 expr->value.op.op2->ref = gfc_get_ref ();
1093 expr->value.op.op2->ref->type = REF_ARRAY;
1094 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1095 expr->value.op.op2->ref->u.ar.dimen = 1;
1096 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1097 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1098 expr->value.op.op2->ref->u.ar.as = strides->as;
1099 expr->ts = idx->ts;
1101 /* offset = offset + ... */
1102 block->block->next = gfc_get_code (EXEC_ASSIGN);
1103 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1104 block->block->next->expr2 = gfc_get_expr ();
1105 block->block->next->expr2->expr_type = EXPR_OP;
1106 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1107 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1108 block->block->next->expr2->value.op.op2 = expr;
1109 block->block->next->expr2->ts = idx->ts;
1111 /* After the loop: offset = offset * byte_stride. */
1112 block->next = gfc_get_code (EXEC_ASSIGN);
1113 block = block->next;
1114 block->expr1 = gfc_lval_expr_from_sym (offset);
1115 block->expr2 = gfc_get_expr ();
1116 block->expr2->expr_type = EXPR_OP;
1117 block->expr2->value.op.op = INTRINSIC_TIMES;
1118 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1119 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1120 block->expr2->ts = block->expr2->value.op.op1->ts;
1121 return block;
1125 /* Insert code of the following form:
1127 block
1128 integer(c_intptr_t) :: i
1130 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1131 && (is_contiguous || !final_rank3->attr.contiguous
1132 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1133 || 0 == STORAGE_SIZE (array)) then
1134 call final_rank3 (array)
1135 else
1136 block
1137 integer(c_intptr_t) :: offset, j
1138 type(t) :: tmp(shape (array))
1140 do i = 0, size (array)-1
1141 offset = obtain_offset(i, strides, sizes, byte_stride)
1142 addr = transfer (c_loc (array), addr) + offset
1143 call c_f_pointer (transfer (addr, cptr), ptr)
1145 addr = transfer (c_loc (tmp), addr)
1146 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1147 call c_f_pointer (transfer (addr, cptr), ptr2)
1148 ptr2 = ptr
1149 end do
1150 call final_rank3 (tmp)
1151 end block
1152 end if
1153 block */
1155 static void
1156 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1157 gfc_symbol *array, gfc_symbol *byte_stride,
1158 gfc_symbol *idx, gfc_symbol *ptr,
1159 gfc_symbol *nelem,
1160 gfc_symbol *strides, gfc_symbol *sizes,
1161 gfc_symbol *idx2, gfc_symbol *offset,
1162 gfc_symbol *is_contiguous, gfc_expr *rank,
1163 gfc_namespace *sub_ns)
1165 gfc_symbol *tmp_array, *ptr2;
1166 gfc_expr *size_expr, *offset2, *expr;
1167 gfc_namespace *ns;
1168 gfc_iterator *iter;
1169 gfc_code *block2;
1170 int i;
1172 block->next = gfc_get_code (EXEC_IF);
1173 block = block->next;
1175 block->block = gfc_get_code (EXEC_IF);
1176 block = block->block;
1178 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1179 size_expr = gfc_get_expr ();
1180 size_expr->where = gfc_current_locus;
1181 size_expr->expr_type = EXPR_OP;
1182 size_expr->value.op.op = INTRINSIC_DIVIDE;
1184 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1185 size_expr->value.op.op1
1186 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1187 "storage_size", gfc_current_locus, 2,
1188 gfc_lval_expr_from_sym (array),
1189 gfc_get_int_expr (gfc_index_integer_kind,
1190 NULL, 0));
1192 /* NUMERIC_STORAGE_SIZE. */
1193 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1194 gfc_character_storage_size);
1195 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1196 size_expr->ts = size_expr->value.op.op1->ts;
1198 /* IF condition: (stride == size_expr
1199 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1200 || is_contiguous)
1201 || 0 == size_expr. */
1202 block->expr1 = gfc_get_expr ();
1203 block->expr1->ts.type = BT_LOGICAL;
1204 block->expr1->ts.kind = gfc_default_logical_kind;
1205 block->expr1->expr_type = EXPR_OP;
1206 block->expr1->where = gfc_current_locus;
1208 block->expr1->value.op.op = INTRINSIC_OR;
1210 /* byte_stride == size_expr */
1211 expr = gfc_get_expr ();
1212 expr->ts.type = BT_LOGICAL;
1213 expr->ts.kind = gfc_default_logical_kind;
1214 expr->expr_type = EXPR_OP;
1215 expr->where = gfc_current_locus;
1216 expr->value.op.op = INTRINSIC_EQ;
1217 expr->value.op.op1
1218 = gfc_lval_expr_from_sym (byte_stride);
1219 expr->value.op.op2 = size_expr;
1221 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1222 add is_contiguous check. */
1224 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1225 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1227 gfc_expr *expr2;
1228 expr2 = gfc_get_expr ();
1229 expr2->ts.type = BT_LOGICAL;
1230 expr2->ts.kind = gfc_default_logical_kind;
1231 expr2->expr_type = EXPR_OP;
1232 expr2->where = gfc_current_locus;
1233 expr2->value.op.op = INTRINSIC_AND;
1234 expr2->value.op.op1 = expr;
1235 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1236 expr = expr2;
1239 block->expr1->value.op.op1 = expr;
1241 /* 0 == size_expr */
1242 block->expr1->value.op.op2 = gfc_get_expr ();
1243 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1244 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1245 block->expr1->value.op.op2->expr_type = EXPR_OP;
1246 block->expr1->value.op.op2->where = gfc_current_locus;
1247 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1248 block->expr1->value.op.op2->value.op.op1 =
1249 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1250 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1252 /* IF body: call final subroutine. */
1253 block->next = gfc_get_code (EXEC_CALL);
1254 block->next->symtree = fini->proc_tree;
1255 block->next->resolved_sym = fini->proc_tree->n.sym;
1256 block->next->ext.actual = gfc_get_actual_arglist ();
1257 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1259 /* ELSE. */
1261 block->block = gfc_get_code (EXEC_IF);
1262 block = block->block;
1264 /* BLOCK ... END BLOCK. */
1265 block->next = gfc_get_code (EXEC_BLOCK);
1266 block = block->next;
1268 ns = gfc_build_block_ns (sub_ns);
1269 block->ext.block.ns = ns;
1270 block->ext.block.assoc = NULL;
1272 gfc_get_symbol ("ptr2", ns, &ptr2);
1273 ptr2->ts.type = BT_DERIVED;
1274 ptr2->ts.u.derived = array->ts.u.derived;
1275 ptr2->attr.flavor = FL_VARIABLE;
1276 ptr2->attr.pointer = 1;
1277 ptr2->attr.artificial = 1;
1278 gfc_set_sym_referenced (ptr2);
1279 gfc_commit_symbol (ptr2);
1281 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1282 tmp_array->ts.type = BT_DERIVED;
1283 tmp_array->ts.u.derived = array->ts.u.derived;
1284 tmp_array->attr.flavor = FL_VARIABLE;
1285 tmp_array->attr.dimension = 1;
1286 tmp_array->attr.artificial = 1;
1287 tmp_array->as = gfc_get_array_spec();
1288 tmp_array->attr.intent = INTENT_INOUT;
1289 tmp_array->as->type = AS_EXPLICIT;
1290 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1292 for (i = 0; i < tmp_array->as->rank; i++)
1294 gfc_expr *shape_expr;
1295 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1296 NULL, 1);
1297 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1298 shape_expr
1299 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1300 gfc_current_locus, 3,
1301 gfc_lval_expr_from_sym (array),
1302 gfc_get_int_expr (gfc_default_integer_kind,
1303 NULL, i+1),
1304 gfc_get_int_expr (gfc_default_integer_kind,
1305 NULL,
1306 gfc_index_integer_kind));
1307 shape_expr->ts.kind = gfc_index_integer_kind;
1308 tmp_array->as->upper[i] = shape_expr;
1310 gfc_set_sym_referenced (tmp_array);
1311 gfc_commit_symbol (tmp_array);
1313 /* Create loop. */
1314 iter = gfc_get_iterator ();
1315 iter->var = gfc_lval_expr_from_sym (idx);
1316 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1317 iter->end = gfc_lval_expr_from_sym (nelem);
1318 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1320 block = gfc_get_code (EXEC_DO);
1321 ns->code = block;
1322 block->ext.iterator = iter;
1323 block->block = gfc_get_code (EXEC_DO);
1325 /* Offset calculation for the new array: idx * size of type (in bytes). */
1326 offset2 = gfc_get_expr ();
1327 offset2->expr_type = EXPR_OP;
1328 offset2->value.op.op = INTRINSIC_TIMES;
1329 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1330 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1331 offset2->ts = byte_stride->ts;
1333 /* Offset calculation of "array". */
1334 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1335 byte_stride, rank, block->block, sub_ns);
1337 /* Create code for
1338 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1339 + idx * stride, c_ptr), ptr). */
1340 block2->next = finalization_scalarizer (array, ptr,
1341 gfc_lval_expr_from_sym (offset),
1342 sub_ns);
1343 block2 = block2->next;
1344 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1345 block2 = block2->next;
1347 /* ptr2 = ptr. */
1348 block2->next = gfc_get_code (EXEC_ASSIGN);
1349 block2 = block2->next;
1350 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1351 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1353 /* Call now the user's final subroutine. */
1354 block->next = gfc_get_code (EXEC_CALL);
1355 block = block->next;
1356 block->symtree = fini->proc_tree;
1357 block->resolved_sym = fini->proc_tree->n.sym;
1358 block->ext.actual = gfc_get_actual_arglist ();
1359 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1361 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1362 return;
1364 /* Copy back. */
1366 /* Loop. */
1367 iter = gfc_get_iterator ();
1368 iter->var = gfc_lval_expr_from_sym (idx);
1369 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1370 iter->end = gfc_lval_expr_from_sym (nelem);
1371 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1373 block->next = gfc_get_code (EXEC_DO);
1374 block = block->next;
1375 block->ext.iterator = iter;
1376 block->block = gfc_get_code (EXEC_DO);
1378 /* Offset calculation of "array". */
1379 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1380 byte_stride, rank, block->block, sub_ns);
1382 /* Create code for
1383 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1384 + offset, c_ptr), ptr). */
1385 block2->next = finalization_scalarizer (array, ptr,
1386 gfc_lval_expr_from_sym (offset),
1387 sub_ns);
1388 block2 = block2->next;
1389 block2->next = finalization_scalarizer (tmp_array, ptr2,
1390 gfc_copy_expr (offset2), sub_ns);
1391 block2 = block2->next;
1393 /* ptr = ptr2. */
1394 block2->next = gfc_get_code (EXEC_ASSIGN);
1395 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1396 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1400 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1401 derived type "derived". The function first calls the approriate FINAL
1402 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1403 components (but not the inherited ones). Last, it calls the wrapper
1404 subroutine of the parent. The generated wrapper procedure takes as argument
1405 an assumed-rank array.
1406 If neither allocatable components nor FINAL subroutines exists, the vtab
1407 will contain a NULL pointer.
1408 The generated function has the form
1409 _final(assumed-rank array, stride, skip_corarray)
1410 where the array has to be contiguous (except of the lowest dimension). The
1411 stride (in bytes) is used to allow different sizes for ancestor types by
1412 skipping over the additionally added components in the scalarizer. If
1413 "fini_coarray" is false, coarray components are not finalized to allow for
1414 the correct semantic with intrinsic assignment. */
1416 static void
1417 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1418 const char *tname, gfc_component *vtab_final)
1420 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1421 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1422 gfc_component *comp;
1423 gfc_namespace *sub_ns;
1424 gfc_code *last_code, *block;
1425 char name[GFC_MAX_SYMBOL_LEN+1];
1426 bool finalizable_comp = false;
1427 bool expr_null_wrapper = false;
1428 gfc_expr *ancestor_wrapper = NULL, *rank;
1429 gfc_iterator *iter;
1431 if (derived->attr.unlimited_polymorphic)
1433 vtab_final->initializer = gfc_get_null_expr (NULL);
1434 return;
1437 /* Search for the ancestor's finalizers. */
1438 if (derived->attr.extension && derived->components
1439 && (!derived->components->ts.u.derived->attr.abstract
1440 || has_finalizer_component (derived)))
1442 gfc_symbol *vtab;
1443 gfc_component *comp;
1445 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1446 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1447 if (comp->name[0] == '_' && comp->name[1] == 'f')
1449 ancestor_wrapper = comp->initializer;
1450 break;
1454 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1455 components: Return a NULL() expression; we defer this a bit to have have
1456 an interface declaration. */
1457 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1458 && !derived->attr.alloc_comp
1459 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1460 && !has_finalizer_component (derived))
1461 expr_null_wrapper = true;
1462 else
1463 /* Check whether there are new allocatable components. */
1464 for (comp = derived->components; comp; comp = comp->next)
1466 if (comp == derived->components && derived->attr.extension
1467 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1468 continue;
1470 if (comp->ts.type != BT_CLASS && !comp->attr.pointer
1471 && (comp->attr.allocatable
1472 || (comp->ts.type == BT_DERIVED
1473 && (comp->ts.u.derived->attr.alloc_comp
1474 || has_finalizer_component (comp->ts.u.derived)
1475 || (comp->ts.u.derived->f2k_derived
1476 && comp->ts.u.derived->f2k_derived->finalizers)))))
1477 finalizable_comp = true;
1478 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1479 && CLASS_DATA (comp)->attr.allocatable)
1480 finalizable_comp = true;
1483 /* If there is no new finalizer and no new allocatable, return with
1484 an expr to the ancestor's one. */
1485 if (!expr_null_wrapper && !finalizable_comp
1486 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1488 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1489 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1490 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1491 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1492 return;
1495 /* We now create a wrapper, which does the following:
1496 1. Call the suitable finalization subroutine for this type
1497 2. Loop over all noninherited allocatable components and noninherited
1498 components with allocatable components and DEALLOCATE those; this will
1499 take care of finalizers, coarray deregistering and allocatable
1500 nested components.
1501 3. Call the ancestor's finalizer. */
1503 /* Declare the wrapper function; it takes an assumed-rank array
1504 and a VALUE logical as arguments. */
1506 /* Set up the namespace. */
1507 sub_ns = gfc_get_namespace (ns, 0);
1508 sub_ns->sibling = ns->contained;
1509 if (!expr_null_wrapper)
1510 ns->contained = sub_ns;
1511 sub_ns->resolved = 1;
1513 /* Set up the procedure symbol. */
1514 sprintf (name, "__final_%s", tname);
1515 gfc_get_symbol (name, sub_ns, &final);
1516 sub_ns->proc_name = final;
1517 final->attr.flavor = FL_PROCEDURE;
1518 final->attr.function = 1;
1519 final->attr.pure = 0;
1520 final->result = final;
1521 final->ts.type = BT_INTEGER;
1522 final->ts.kind = 4;
1523 final->attr.artificial = 1;
1524 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1525 if (ns->proc_name->attr.flavor == FL_MODULE)
1526 final->module = ns->proc_name->name;
1527 gfc_set_sym_referenced (final);
1528 gfc_commit_symbol (final);
1530 /* Set up formal argument. */
1531 gfc_get_symbol ("array", sub_ns, &array);
1532 array->ts.type = BT_DERIVED;
1533 array->ts.u.derived = derived;
1534 array->attr.flavor = FL_VARIABLE;
1535 array->attr.dummy = 1;
1536 array->attr.contiguous = 1;
1537 array->attr.dimension = 1;
1538 array->attr.artificial = 1;
1539 array->as = gfc_get_array_spec();
1540 array->as->type = AS_ASSUMED_RANK;
1541 array->as->rank = -1;
1542 array->attr.intent = INTENT_INOUT;
1543 gfc_set_sym_referenced (array);
1544 final->formal = gfc_get_formal_arglist ();
1545 final->formal->sym = array;
1546 gfc_commit_symbol (array);
1548 /* Set up formal argument. */
1549 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1550 byte_stride->ts.type = BT_INTEGER;
1551 byte_stride->ts.kind = gfc_index_integer_kind;
1552 byte_stride->attr.flavor = FL_VARIABLE;
1553 byte_stride->attr.dummy = 1;
1554 byte_stride->attr.value = 1;
1555 byte_stride->attr.artificial = 1;
1556 gfc_set_sym_referenced (byte_stride);
1557 final->formal->next = gfc_get_formal_arglist ();
1558 final->formal->next->sym = byte_stride;
1559 gfc_commit_symbol (byte_stride);
1561 /* Set up formal argument. */
1562 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1563 fini_coarray->ts.type = BT_LOGICAL;
1564 fini_coarray->ts.kind = 1;
1565 fini_coarray->attr.flavor = FL_VARIABLE;
1566 fini_coarray->attr.dummy = 1;
1567 fini_coarray->attr.value = 1;
1568 fini_coarray->attr.artificial = 1;
1569 gfc_set_sym_referenced (fini_coarray);
1570 final->formal->next->next = gfc_get_formal_arglist ();
1571 final->formal->next->next->sym = fini_coarray;
1572 gfc_commit_symbol (fini_coarray);
1574 /* Return with a NULL() expression but with an interface which has
1575 the formal arguments. */
1576 if (expr_null_wrapper)
1578 vtab_final->initializer = gfc_get_null_expr (NULL);
1579 vtab_final->ts.interface = final;
1580 return;
1583 /* Local variables. */
1585 gfc_get_symbol ("idx", sub_ns, &idx);
1586 idx->ts.type = BT_INTEGER;
1587 idx->ts.kind = gfc_index_integer_kind;
1588 idx->attr.flavor = FL_VARIABLE;
1589 idx->attr.artificial = 1;
1590 gfc_set_sym_referenced (idx);
1591 gfc_commit_symbol (idx);
1593 gfc_get_symbol ("idx2", sub_ns, &idx2);
1594 idx2->ts.type = BT_INTEGER;
1595 idx2->ts.kind = gfc_index_integer_kind;
1596 idx2->attr.flavor = FL_VARIABLE;
1597 idx2->attr.artificial = 1;
1598 gfc_set_sym_referenced (idx2);
1599 gfc_commit_symbol (idx2);
1601 gfc_get_symbol ("offset", sub_ns, &offset);
1602 offset->ts.type = BT_INTEGER;
1603 offset->ts.kind = gfc_index_integer_kind;
1604 offset->attr.flavor = FL_VARIABLE;
1605 offset->attr.artificial = 1;
1606 gfc_set_sym_referenced (offset);
1607 gfc_commit_symbol (offset);
1609 /* Create RANK expression. */
1610 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1611 gfc_current_locus, 1,
1612 gfc_lval_expr_from_sym (array));
1613 if (rank->ts.kind != idx->ts.kind)
1614 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1616 /* Create is_contiguous variable. */
1617 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1618 is_contiguous->ts.type = BT_LOGICAL;
1619 is_contiguous->ts.kind = gfc_default_logical_kind;
1620 is_contiguous->attr.flavor = FL_VARIABLE;
1621 is_contiguous->attr.artificial = 1;
1622 gfc_set_sym_referenced (is_contiguous);
1623 gfc_commit_symbol (is_contiguous);
1625 /* Create "sizes(0..rank)" variable, which contains the multiplied
1626 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1627 sizes(2) = sizes(1) * extent(dim=2) etc. */
1628 gfc_get_symbol ("sizes", sub_ns, &sizes);
1629 sizes->ts.type = BT_INTEGER;
1630 sizes->ts.kind = gfc_index_integer_kind;
1631 sizes->attr.flavor = FL_VARIABLE;
1632 sizes->attr.dimension = 1;
1633 sizes->attr.artificial = 1;
1634 sizes->as = gfc_get_array_spec();
1635 sizes->attr.intent = INTENT_INOUT;
1636 sizes->as->type = AS_EXPLICIT;
1637 sizes->as->rank = 1;
1638 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1639 sizes->as->upper[0] = gfc_copy_expr (rank);
1640 gfc_set_sym_referenced (sizes);
1641 gfc_commit_symbol (sizes);
1643 /* Create "strides(1..rank)" variable, which contains the strides per
1644 dimension. */
1645 gfc_get_symbol ("strides", sub_ns, &strides);
1646 strides->ts.type = BT_INTEGER;
1647 strides->ts.kind = gfc_index_integer_kind;
1648 strides->attr.flavor = FL_VARIABLE;
1649 strides->attr.dimension = 1;
1650 strides->attr.artificial = 1;
1651 strides->as = gfc_get_array_spec();
1652 strides->attr.intent = INTENT_INOUT;
1653 strides->as->type = AS_EXPLICIT;
1654 strides->as->rank = 1;
1655 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1656 strides->as->upper[0] = gfc_copy_expr (rank);
1657 gfc_set_sym_referenced (strides);
1658 gfc_commit_symbol (strides);
1661 /* Set return value to 0. */
1662 last_code = gfc_get_code (EXEC_ASSIGN);
1663 last_code->expr1 = gfc_lval_expr_from_sym (final);
1664 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1665 sub_ns->code = last_code;
1667 /* Set: is_contiguous = .true. */
1668 last_code->next = gfc_get_code (EXEC_ASSIGN);
1669 last_code = last_code->next;
1670 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1671 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1672 &gfc_current_locus, true);
1674 /* Set: sizes(0) = 1. */
1675 last_code->next = gfc_get_code (EXEC_ASSIGN);
1676 last_code = last_code->next;
1677 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1678 last_code->expr1->ref = gfc_get_ref ();
1679 last_code->expr1->ref->type = REF_ARRAY;
1680 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1681 last_code->expr1->ref->u.ar.dimen = 1;
1682 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1683 last_code->expr1->ref->u.ar.start[0]
1684 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1685 last_code->expr1->ref->u.ar.as = sizes->as;
1686 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1688 /* Create:
1689 DO idx = 1, rank
1690 strides(idx) = _F._stride (array, dim=idx)
1691 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1692 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1693 END DO. */
1695 /* Create loop. */
1696 iter = gfc_get_iterator ();
1697 iter->var = gfc_lval_expr_from_sym (idx);
1698 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1699 iter->end = gfc_copy_expr (rank);
1700 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1701 last_code->next = gfc_get_code (EXEC_DO);
1702 last_code = last_code->next;
1703 last_code->ext.iterator = iter;
1704 last_code->block = gfc_get_code (EXEC_DO);
1706 /* strides(idx) = _F._stride(array,dim=idx). */
1707 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1708 block = last_code->block->next;
1710 block->expr1 = gfc_lval_expr_from_sym (strides);
1711 block->expr1->ref = gfc_get_ref ();
1712 block->expr1->ref->type = REF_ARRAY;
1713 block->expr1->ref->u.ar.type = AR_ELEMENT;
1714 block->expr1->ref->u.ar.dimen = 1;
1715 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1716 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1717 block->expr1->ref->u.ar.as = strides->as;
1719 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1720 gfc_current_locus, 2,
1721 gfc_lval_expr_from_sym (array),
1722 gfc_lval_expr_from_sym (idx));
1724 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1725 block->next = gfc_get_code (EXEC_ASSIGN);
1726 block = block->next;
1728 /* sizes(idx) = ... */
1729 block->expr1 = gfc_lval_expr_from_sym (sizes);
1730 block->expr1->ref = gfc_get_ref ();
1731 block->expr1->ref->type = REF_ARRAY;
1732 block->expr1->ref->u.ar.type = AR_ELEMENT;
1733 block->expr1->ref->u.ar.dimen = 1;
1734 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1735 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1736 block->expr1->ref->u.ar.as = sizes->as;
1738 block->expr2 = gfc_get_expr ();
1739 block->expr2->expr_type = EXPR_OP;
1740 block->expr2->value.op.op = INTRINSIC_TIMES;
1742 /* sizes(idx-1). */
1743 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1744 block->expr2->value.op.op1->ref = gfc_get_ref ();
1745 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1746 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1747 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1748 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1749 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1750 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1751 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1752 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1753 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1754 = gfc_lval_expr_from_sym (idx);
1755 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1756 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1757 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1758 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1760 /* size(array, dim=idx, kind=index_kind). */
1761 block->expr2->value.op.op2
1762 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1763 gfc_current_locus, 3,
1764 gfc_lval_expr_from_sym (array),
1765 gfc_lval_expr_from_sym (idx),
1766 gfc_get_int_expr (gfc_index_integer_kind,
1767 NULL,
1768 gfc_index_integer_kind));
1769 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1770 block->expr2->ts = idx->ts;
1772 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1773 block->next = gfc_get_code (EXEC_IF);
1774 block = block->next;
1776 block->block = gfc_get_code (EXEC_IF);
1777 block = block->block;
1779 /* if condition: strides(idx) /= sizes(idx-1). */
1780 block->expr1 = gfc_get_expr ();
1781 block->expr1->ts.type = BT_LOGICAL;
1782 block->expr1->ts.kind = gfc_default_logical_kind;
1783 block->expr1->expr_type = EXPR_OP;
1784 block->expr1->where = gfc_current_locus;
1785 block->expr1->value.op.op = INTRINSIC_NE;
1787 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1788 block->expr1->value.op.op1->ref = gfc_get_ref ();
1789 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1790 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1791 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1792 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1793 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1794 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1796 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1797 block->expr1->value.op.op2->ref = gfc_get_ref ();
1798 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1799 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1800 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1801 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1802 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1803 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1804 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1805 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1806 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1807 = gfc_lval_expr_from_sym (idx);
1808 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1809 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1810 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1811 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1813 /* if body: is_contiguous = .false. */
1814 block->next = gfc_get_code (EXEC_ASSIGN);
1815 block = block->next;
1816 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1817 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1818 &gfc_current_locus, false);
1820 /* Obtain the size (number of elements) of "array" MINUS ONE,
1821 which is used in the scalarization. */
1822 gfc_get_symbol ("nelem", sub_ns, &nelem);
1823 nelem->ts.type = BT_INTEGER;
1824 nelem->ts.kind = gfc_index_integer_kind;
1825 nelem->attr.flavor = FL_VARIABLE;
1826 nelem->attr.artificial = 1;
1827 gfc_set_sym_referenced (nelem);
1828 gfc_commit_symbol (nelem);
1830 /* nelem = sizes (rank) - 1. */
1831 last_code->next = gfc_get_code (EXEC_ASSIGN);
1832 last_code = last_code->next;
1834 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
1836 last_code->expr2 = gfc_get_expr ();
1837 last_code->expr2->expr_type = EXPR_OP;
1838 last_code->expr2->value.op.op = INTRINSIC_MINUS;
1839 last_code->expr2->value.op.op2
1840 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1841 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
1843 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1844 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
1845 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
1846 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1847 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
1848 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1849 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
1850 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1852 /* Call final subroutines. We now generate code like:
1853 use iso_c_binding
1854 integer, pointer :: ptr
1855 type(c_ptr) :: cptr
1856 integer(c_intptr_t) :: i, addr
1858 select case (rank (array))
1859 case (3)
1860 ! If needed, the array is packed
1861 call final_rank3 (array)
1862 case default:
1863 do i = 0, size (array)-1
1864 addr = transfer (c_loc (array), addr) + i * stride
1865 call c_f_pointer (transfer (addr, cptr), ptr)
1866 call elemental_final (ptr)
1867 end do
1868 end select */
1870 if (derived->f2k_derived && derived->f2k_derived->finalizers)
1872 gfc_finalizer *fini, *fini_elem = NULL;
1874 gfc_get_symbol ("ptr", sub_ns, &ptr);
1875 ptr->ts.type = BT_DERIVED;
1876 ptr->ts.u.derived = derived;
1877 ptr->attr.flavor = FL_VARIABLE;
1878 ptr->attr.pointer = 1;
1879 ptr->attr.artificial = 1;
1880 gfc_set_sym_referenced (ptr);
1881 gfc_commit_symbol (ptr);
1883 /* SELECT CASE (RANK (array)). */
1884 last_code->next = gfc_get_code (EXEC_SELECT);
1885 last_code = last_code->next;
1886 last_code->expr1 = gfc_copy_expr (rank);
1887 block = NULL;
1889 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
1891 if (!fini->proc_tree)
1892 fini->proc_tree = gfc_find_sym_in_symtree (fini->proc_sym);
1893 if (fini->proc_tree->n.sym->attr.elemental)
1895 fini_elem = fini;
1896 continue;
1899 /* CASE (fini_rank). */
1900 if (block)
1902 block->block = gfc_get_code (EXEC_SELECT);
1903 block = block->block;
1905 else
1907 block = gfc_get_code (EXEC_SELECT);
1908 last_code->block = block;
1910 block->ext.block.case_list = gfc_get_case ();
1911 block->ext.block.case_list->where = gfc_current_locus;
1912 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1913 block->ext.block.case_list->low
1914 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
1915 fini->proc_tree->n.sym->formal->sym->as->rank);
1916 else
1917 block->ext.block.case_list->low
1918 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1919 block->ext.block.case_list->high
1920 = gfc_copy_expr (block->ext.block.case_list->low);
1922 /* CALL fini_rank (array) - possibly with packing. */
1923 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1924 finalizer_insert_packed_call (block, fini, array, byte_stride,
1925 idx, ptr, nelem, strides,
1926 sizes, idx2, offset, is_contiguous,
1927 rank, sub_ns);
1928 else
1930 block->next = gfc_get_code (EXEC_CALL);
1931 block->next->symtree = fini->proc_tree;
1932 block->next->resolved_sym = fini->proc_tree->n.sym;
1933 block->next->ext.actual = gfc_get_actual_arglist ();
1934 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1938 /* Elemental call - scalarized. */
1939 if (fini_elem)
1941 /* CASE DEFAULT. */
1942 if (block)
1944 block->block = gfc_get_code (EXEC_SELECT);
1945 block = block->block;
1947 else
1949 block = gfc_get_code (EXEC_SELECT);
1950 last_code->block = block;
1952 block->ext.block.case_list = gfc_get_case ();
1954 /* Create loop. */
1955 iter = gfc_get_iterator ();
1956 iter->var = gfc_lval_expr_from_sym (idx);
1957 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1958 iter->end = gfc_lval_expr_from_sym (nelem);
1959 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1960 block->next = gfc_get_code (EXEC_DO);
1961 block = block->next;
1962 block->ext.iterator = iter;
1963 block->block = gfc_get_code (EXEC_DO);
1965 /* Offset calculation. */
1966 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
1967 byte_stride, rank, block->block,
1968 sub_ns);
1970 /* Create code for
1971 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1972 + offset, c_ptr), ptr). */
1973 block->next
1974 = finalization_scalarizer (array, ptr,
1975 gfc_lval_expr_from_sym (offset),
1976 sub_ns);
1977 block = block->next;
1979 /* CALL final_elemental (array). */
1980 block->next = gfc_get_code (EXEC_CALL);
1981 block = block->next;
1982 block->symtree = fini_elem->proc_tree;
1983 block->resolved_sym = fini_elem->proc_sym;
1984 block->ext.actual = gfc_get_actual_arglist ();
1985 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
1989 /* Finalize and deallocate allocatable components. The same manual
1990 scalarization is used as above. */
1992 if (finalizable_comp)
1994 gfc_symbol *stat;
1995 gfc_code *block = NULL;
1997 if (!ptr)
1999 gfc_get_symbol ("ptr", sub_ns, &ptr);
2000 ptr->ts.type = BT_DERIVED;
2001 ptr->ts.u.derived = derived;
2002 ptr->attr.flavor = FL_VARIABLE;
2003 ptr->attr.pointer = 1;
2004 ptr->attr.artificial = 1;
2005 gfc_set_sym_referenced (ptr);
2006 gfc_commit_symbol (ptr);
2009 gfc_get_symbol ("ignore", sub_ns, &stat);
2010 stat->attr.flavor = FL_VARIABLE;
2011 stat->attr.artificial = 1;
2012 stat->ts.type = BT_INTEGER;
2013 stat->ts.kind = gfc_default_integer_kind;
2014 gfc_set_sym_referenced (stat);
2015 gfc_commit_symbol (stat);
2017 /* Create loop. */
2018 iter = gfc_get_iterator ();
2019 iter->var = gfc_lval_expr_from_sym (idx);
2020 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2021 iter->end = gfc_lval_expr_from_sym (nelem);
2022 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2023 last_code->next = gfc_get_code (EXEC_DO);
2024 last_code = last_code->next;
2025 last_code->ext.iterator = iter;
2026 last_code->block = gfc_get_code (EXEC_DO);
2028 /* Offset calculation. */
2029 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2030 byte_stride, rank, last_code->block,
2031 sub_ns);
2033 /* Create code for
2034 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2035 + idx * stride, c_ptr), ptr). */
2036 block->next = finalization_scalarizer (array, ptr,
2037 gfc_lval_expr_from_sym(offset),
2038 sub_ns);
2039 block = block->next;
2041 for (comp = derived->components; comp; comp = comp->next)
2043 if (comp == derived->components && derived->attr.extension
2044 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2045 continue;
2047 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2048 stat, fini_coarray, &block);
2049 if (!last_code->block->next)
2050 last_code->block->next = block;
2055 /* Call the finalizer of the ancestor. */
2056 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2058 last_code->next = gfc_get_code (EXEC_CALL);
2059 last_code = last_code->next;
2060 last_code->symtree = ancestor_wrapper->symtree;
2061 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2063 last_code->ext.actual = gfc_get_actual_arglist ();
2064 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2065 last_code->ext.actual->next = gfc_get_actual_arglist ();
2066 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2067 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2068 last_code->ext.actual->next->next->expr
2069 = gfc_lval_expr_from_sym (fini_coarray);
2072 gfc_free_expr (rank);
2073 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2074 vtab_final->ts.interface = final;
2078 /* Add procedure pointers for all type-bound procedures to a vtab. */
2080 static void
2081 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2083 gfc_symbol* super_type;
2085 super_type = gfc_get_derived_super_type (derived);
2087 if (super_type && (super_type != derived))
2089 /* Make sure that the PPCs appear in the same order as in the parent. */
2090 copy_vtab_proc_comps (super_type, vtype);
2091 /* Only needed to get the PPC initializers right. */
2092 add_procs_to_declared_vtab (super_type, vtype);
2095 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2096 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2098 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2099 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2103 /* Find or generate the symbol for a derived type's vtab. */
2105 gfc_symbol *
2106 gfc_find_derived_vtab (gfc_symbol *derived)
2108 gfc_namespace *ns;
2109 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2110 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2112 /* Find the top-level namespace. */
2113 for (ns = gfc_current_ns; ns; ns = ns->parent)
2114 if (!ns->parent)
2115 break;
2117 /* If the type is a class container, use the underlying derived type. */
2118 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2119 derived = gfc_get_derived_super_type (derived);
2121 if (ns)
2123 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2125 get_unique_hashed_string (tname, derived);
2126 sprintf (name, "__vtab_%s", tname);
2128 /* Look for the vtab symbol in various namespaces. */
2129 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2130 if (vtab == NULL)
2131 gfc_find_symbol (name, ns, 0, &vtab);
2132 if (vtab == NULL)
2133 gfc_find_symbol (name, derived->ns, 0, &vtab);
2135 if (vtab == NULL)
2137 gfc_get_symbol (name, ns, &vtab);
2138 vtab->ts.type = BT_DERIVED;
2139 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2140 &gfc_current_locus))
2141 goto cleanup;
2142 vtab->attr.target = 1;
2143 vtab->attr.save = SAVE_IMPLICIT;
2144 vtab->attr.vtab = 1;
2145 vtab->attr.access = ACCESS_PUBLIC;
2146 gfc_set_sym_referenced (vtab);
2147 sprintf (name, "__vtype_%s", tname);
2149 gfc_find_symbol (name, ns, 0, &vtype);
2150 if (vtype == NULL)
2152 gfc_component *c;
2153 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2155 gfc_get_symbol (name, ns, &vtype);
2156 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2157 &gfc_current_locus))
2158 goto cleanup;
2159 vtype->attr.access = ACCESS_PUBLIC;
2160 vtype->attr.vtype = 1;
2161 gfc_set_sym_referenced (vtype);
2163 /* Add component '_hash'. */
2164 if (!gfc_add_component (vtype, "_hash", &c))
2165 goto cleanup;
2166 c->ts.type = BT_INTEGER;
2167 c->ts.kind = 4;
2168 c->attr.access = ACCESS_PRIVATE;
2169 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2170 NULL, derived->hash_value);
2172 /* Add component '_size'. */
2173 if (!gfc_add_component (vtype, "_size", &c))
2174 goto cleanup;
2175 c->ts.type = BT_INTEGER;
2176 c->ts.kind = 4;
2177 c->attr.access = ACCESS_PRIVATE;
2178 /* Remember the derived type in ts.u.derived,
2179 so that the correct initializer can be set later on
2180 (in gfc_conv_structure). */
2181 c->ts.u.derived = derived;
2182 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2183 NULL, 0);
2185 /* Add component _extends. */
2186 if (!gfc_add_component (vtype, "_extends", &c))
2187 goto cleanup;
2188 c->attr.pointer = 1;
2189 c->attr.access = ACCESS_PRIVATE;
2190 if (!derived->attr.unlimited_polymorphic)
2191 parent = gfc_get_derived_super_type (derived);
2192 else
2193 parent = NULL;
2195 if (parent)
2197 parent_vtab = gfc_find_derived_vtab (parent);
2198 c->ts.type = BT_DERIVED;
2199 c->ts.u.derived = parent_vtab->ts.u.derived;
2200 c->initializer = gfc_get_expr ();
2201 c->initializer->expr_type = EXPR_VARIABLE;
2202 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2203 0, &c->initializer->symtree);
2205 else
2207 c->ts.type = BT_DERIVED;
2208 c->ts.u.derived = vtype;
2209 c->initializer = gfc_get_null_expr (NULL);
2212 if (!derived->attr.unlimited_polymorphic
2213 && derived->components == NULL
2214 && !derived->attr.zero_comp)
2216 /* At this point an error must have occurred.
2217 Prevent further errors on the vtype components. */
2218 found_sym = vtab;
2219 goto have_vtype;
2222 /* Add component _def_init. */
2223 if (!gfc_add_component (vtype, "_def_init", &c))
2224 goto cleanup;
2225 c->attr.pointer = 1;
2226 c->attr.artificial = 1;
2227 c->attr.access = ACCESS_PRIVATE;
2228 c->ts.type = BT_DERIVED;
2229 c->ts.u.derived = derived;
2230 if (derived->attr.unlimited_polymorphic
2231 || derived->attr.abstract)
2232 c->initializer = gfc_get_null_expr (NULL);
2233 else
2235 /* Construct default initialization variable. */
2236 sprintf (name, "__def_init_%s", tname);
2237 gfc_get_symbol (name, ns, &def_init);
2238 def_init->attr.target = 1;
2239 def_init->attr.artificial = 1;
2240 def_init->attr.save = SAVE_IMPLICIT;
2241 def_init->attr.access = ACCESS_PUBLIC;
2242 def_init->attr.flavor = FL_VARIABLE;
2243 gfc_set_sym_referenced (def_init);
2244 def_init->ts.type = BT_DERIVED;
2245 def_init->ts.u.derived = derived;
2246 def_init->value = gfc_default_initializer (&def_init->ts);
2248 c->initializer = gfc_lval_expr_from_sym (def_init);
2251 /* Add component _copy. */
2252 if (!gfc_add_component (vtype, "_copy", &c))
2253 goto cleanup;
2254 c->attr.proc_pointer = 1;
2255 c->attr.access = ACCESS_PRIVATE;
2256 c->tb = XCNEW (gfc_typebound_proc);
2257 c->tb->ppc = 1;
2258 if (derived->attr.unlimited_polymorphic
2259 || derived->attr.abstract)
2260 c->initializer = gfc_get_null_expr (NULL);
2261 else
2263 /* Set up namespace. */
2264 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2265 sub_ns->sibling = ns->contained;
2266 ns->contained = sub_ns;
2267 sub_ns->resolved = 1;
2268 /* Set up procedure symbol. */
2269 sprintf (name, "__copy_%s", tname);
2270 gfc_get_symbol (name, sub_ns, &copy);
2271 sub_ns->proc_name = copy;
2272 copy->attr.flavor = FL_PROCEDURE;
2273 copy->attr.subroutine = 1;
2274 copy->attr.pure = 1;
2275 copy->attr.artificial = 1;
2276 copy->attr.if_source = IFSRC_DECL;
2277 /* This is elemental so that arrays are automatically
2278 treated correctly by the scalarizer. */
2279 copy->attr.elemental = 1;
2280 if (ns->proc_name->attr.flavor == FL_MODULE)
2281 copy->module = ns->proc_name->name;
2282 gfc_set_sym_referenced (copy);
2283 /* Set up formal arguments. */
2284 gfc_get_symbol ("src", sub_ns, &src);
2285 src->ts.type = BT_DERIVED;
2286 src->ts.u.derived = derived;
2287 src->attr.flavor = FL_VARIABLE;
2288 src->attr.dummy = 1;
2289 src->attr.artificial = 1;
2290 src->attr.intent = INTENT_IN;
2291 gfc_set_sym_referenced (src);
2292 copy->formal = gfc_get_formal_arglist ();
2293 copy->formal->sym = src;
2294 gfc_get_symbol ("dst", sub_ns, &dst);
2295 dst->ts.type = BT_DERIVED;
2296 dst->ts.u.derived = derived;
2297 dst->attr.flavor = FL_VARIABLE;
2298 dst->attr.dummy = 1;
2299 dst->attr.artificial = 1;
2300 dst->attr.intent = INTENT_INOUT;
2301 gfc_set_sym_referenced (dst);
2302 copy->formal->next = gfc_get_formal_arglist ();
2303 copy->formal->next->sym = dst;
2304 /* Set up code. */
2305 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2306 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2307 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2308 /* Set initializer. */
2309 c->initializer = gfc_lval_expr_from_sym (copy);
2310 c->ts.interface = copy;
2313 /* Add component _final, which contains a procedure pointer to
2314 a wrapper which handles both the freeing of allocatable
2315 components and the calls to finalization subroutines.
2316 Note: The actual wrapper function can only be generated
2317 at resolution time. */
2318 if (!gfc_add_component (vtype, "_final", &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 generate_finalization_wrapper (derived, ns, tname, c);
2326 /* Add procedure pointers for type-bound procedures. */
2327 if (!derived->attr.unlimited_polymorphic)
2328 add_procs_to_declared_vtab (derived, vtype);
2331 have_vtype:
2332 vtab->ts.u.derived = vtype;
2333 vtab->value = gfc_default_initializer (&vtab->ts);
2337 found_sym = vtab;
2339 cleanup:
2340 /* It is unexpected to have some symbols added at resolution or code
2341 generation time. We commit the changes in order to keep a clean state. */
2342 if (found_sym)
2344 gfc_commit_symbol (vtab);
2345 if (vtype)
2346 gfc_commit_symbol (vtype);
2347 if (def_init)
2348 gfc_commit_symbol (def_init);
2349 if (copy)
2350 gfc_commit_symbol (copy);
2351 if (src)
2352 gfc_commit_symbol (src);
2353 if (dst)
2354 gfc_commit_symbol (dst);
2356 else
2357 gfc_undo_symbols ();
2359 return found_sym;
2363 /* Check if a derived type is finalizable. That is the case if it
2364 (1) has a FINAL subroutine or
2365 (2) has a nonpointer nonallocatable component of finalizable type.
2366 If it is finalizable, return an expression containing the
2367 finalization wrapper. */
2369 bool
2370 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2372 gfc_symbol *vtab;
2373 gfc_component *c;
2375 /* (1) Check for FINAL subroutines. */
2376 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2377 goto yes;
2379 /* (2) Check for components of finalizable type. */
2380 for (c = derived->components; c; c = c->next)
2381 if (c->ts.type == BT_DERIVED
2382 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2383 && gfc_is_finalizable (c->ts.u.derived, NULL))
2384 goto yes;
2386 return false;
2388 yes:
2389 /* Make sure vtab is generated. */
2390 vtab = gfc_find_derived_vtab (derived);
2391 if (final_expr)
2393 /* Return finalizer expression. */
2394 gfc_component *final;
2395 final = vtab->ts.u.derived->components->next->next->next->next->next;
2396 gcc_assert (strcmp (final->name, "_final") == 0);
2397 gcc_assert (final->initializer
2398 && final->initializer->expr_type != EXPR_NULL);
2399 *final_expr = final->initializer;
2401 return true;
2405 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2406 need to support unlimited polymorphism. */
2408 gfc_symbol *
2409 gfc_find_intrinsic_vtab (gfc_typespec *ts)
2411 gfc_namespace *ns;
2412 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2413 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2414 int charlen = 0;
2416 if (ts->type == BT_CHARACTER && ts->deferred)
2418 gfc_error ("TODO: Deferred character length variable at %C cannot "
2419 "yet be associated with unlimited polymorphic entities");
2420 return NULL;
2423 if (ts->type == BT_UNKNOWN)
2424 return NULL;
2426 /* Sometimes the typespec is passed from a single call. */
2427 if (ts->type == BT_DERIVED)
2428 return gfc_find_derived_vtab (ts->u.derived);
2430 /* Find the top-level namespace. */
2431 for (ns = gfc_current_ns; ns; ns = ns->parent)
2432 if (!ns->parent)
2433 break;
2435 if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
2436 && ts->u.cl->length->expr_type == EXPR_CONSTANT)
2437 charlen = mpz_get_si (ts->u.cl->length->value.integer);
2439 if (ns)
2441 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2443 if (ts->type == BT_CHARACTER)
2444 sprintf (tname, "%s_%d_%d", gfc_basic_typename (ts->type),
2445 charlen, ts->kind);
2446 else
2447 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2449 sprintf (name, "__vtab_%s", tname);
2451 /* Look for the vtab symbol in various namespaces. */
2452 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2453 if (vtab == NULL)
2454 gfc_find_symbol (name, ns, 0, &vtab);
2456 if (vtab == NULL)
2458 gfc_get_symbol (name, ns, &vtab);
2459 vtab->ts.type = BT_DERIVED;
2460 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2461 &gfc_current_locus))
2462 goto cleanup;
2463 vtab->attr.target = 1;
2464 vtab->attr.save = SAVE_IMPLICIT;
2465 vtab->attr.vtab = 1;
2466 vtab->attr.access = ACCESS_PUBLIC;
2467 gfc_set_sym_referenced (vtab);
2468 sprintf (name, "__vtype_%s", tname);
2470 gfc_find_symbol (name, ns, 0, &vtype);
2471 if (vtype == NULL)
2473 gfc_component *c;
2474 int hash;
2475 gfc_namespace *sub_ns;
2476 gfc_namespace *contained;
2477 gfc_expr *e;
2479 gfc_get_symbol (name, ns, &vtype);
2480 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2481 &gfc_current_locus))
2482 goto cleanup;
2483 vtype->attr.access = ACCESS_PUBLIC;
2484 vtype->attr.vtype = 1;
2485 gfc_set_sym_referenced (vtype);
2487 /* Add component '_hash'. */
2488 if (!gfc_add_component (vtype, "_hash", &c))
2489 goto cleanup;
2490 c->ts.type = BT_INTEGER;
2491 c->ts.kind = 4;
2492 c->attr.access = ACCESS_PRIVATE;
2493 hash = gfc_intrinsic_hash_value (ts);
2494 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2495 NULL, hash);
2497 /* Add component '_size'. */
2498 if (!gfc_add_component (vtype, "_size", &c))
2499 goto cleanup;
2500 c->ts.type = BT_INTEGER;
2501 c->ts.kind = 4;
2502 c->attr.access = ACCESS_PRIVATE;
2504 /* Build a minimal expression to make use of
2505 target-memory.c/gfc_element_size for 'size'. */
2506 e = gfc_get_expr ();
2507 e->ts = *ts;
2508 e->expr_type = EXPR_VARIABLE;
2509 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2510 NULL,
2511 (int)gfc_element_size (e));
2512 gfc_free_expr (e);
2514 /* Add component _extends. */
2515 if (!gfc_add_component (vtype, "_extends", &c))
2516 goto cleanup;
2517 c->attr.pointer = 1;
2518 c->attr.access = ACCESS_PRIVATE;
2519 c->ts.type = BT_VOID;
2520 c->initializer = gfc_get_null_expr (NULL);
2522 /* Add component _def_init. */
2523 if (!gfc_add_component (vtype, "_def_init", &c))
2524 goto cleanup;
2525 c->attr.pointer = 1;
2526 c->attr.access = ACCESS_PRIVATE;
2527 c->ts.type = BT_VOID;
2528 c->initializer = gfc_get_null_expr (NULL);
2530 /* Add component _copy. */
2531 if (!gfc_add_component (vtype, "_copy", &c))
2532 goto cleanup;
2533 c->attr.proc_pointer = 1;
2534 c->attr.access = ACCESS_PRIVATE;
2535 c->tb = XCNEW (gfc_typebound_proc);
2536 c->tb->ppc = 1;
2538 /* Check to see if copy function already exists. Note
2539 that this is only used for characters of different
2540 lengths. */
2541 contained = ns->contained;
2542 for (; contained; contained = contained->sibling)
2543 if (contained->proc_name
2544 && strcmp (name, contained->proc_name->name) == 0)
2546 copy = contained->proc_name;
2547 goto got_char_copy;
2550 /* Set up namespace. */
2551 sub_ns = gfc_get_namespace (ns, 0);
2552 sub_ns->sibling = ns->contained;
2553 ns->contained = sub_ns;
2554 sub_ns->resolved = 1;
2555 /* Set up procedure symbol. */
2556 if (ts->type != BT_CHARACTER)
2557 sprintf (name, "__copy_%s", tname);
2558 else
2559 /* __copy is always the same for characters. */
2560 sprintf (name, "__copy_character_%d", ts->kind);
2561 gfc_get_symbol (name, sub_ns, &copy);
2562 sub_ns->proc_name = copy;
2563 copy->attr.flavor = FL_PROCEDURE;
2564 copy->attr.subroutine = 1;
2565 copy->attr.pure = 1;
2566 copy->attr.if_source = IFSRC_DECL;
2567 /* This is elemental so that arrays are automatically
2568 treated correctly by the scalarizer. */
2569 copy->attr.elemental = 1;
2570 if (ns->proc_name->attr.flavor == FL_MODULE)
2571 copy->module = ns->proc_name->name;
2572 gfc_set_sym_referenced (copy);
2573 /* Set up formal arguments. */
2574 gfc_get_symbol ("src", sub_ns, &src);
2575 src->ts.type = ts->type;
2576 src->ts.kind = ts->kind;
2577 src->attr.flavor = FL_VARIABLE;
2578 src->attr.dummy = 1;
2579 src->attr.intent = INTENT_IN;
2580 gfc_set_sym_referenced (src);
2581 copy->formal = gfc_get_formal_arglist ();
2582 copy->formal->sym = src;
2583 gfc_get_symbol ("dst", sub_ns, &dst);
2584 dst->ts.type = ts->type;
2585 dst->ts.kind = ts->kind;
2586 dst->attr.flavor = FL_VARIABLE;
2587 dst->attr.dummy = 1;
2588 dst->attr.intent = INTENT_INOUT;
2589 gfc_set_sym_referenced (dst);
2590 copy->formal->next = gfc_get_formal_arglist ();
2591 copy->formal->next->sym = dst;
2592 /* Set up code. */
2593 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2594 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2595 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2596 got_char_copy:
2597 /* Set initializer. */
2598 c->initializer = gfc_lval_expr_from_sym (copy);
2599 c->ts.interface = copy;
2601 /* Add component _final. */
2602 if (!gfc_add_component (vtype, "_final", &c))
2603 goto cleanup;
2604 c->attr.proc_pointer = 1;
2605 c->attr.access = ACCESS_PRIVATE;
2606 c->tb = XCNEW (gfc_typebound_proc);
2607 c->tb->ppc = 1;
2608 c->initializer = gfc_get_null_expr (NULL);
2610 vtab->ts.u.derived = vtype;
2611 vtab->value = gfc_default_initializer (&vtab->ts);
2615 found_sym = vtab;
2617 cleanup:
2618 /* It is unexpected to have some symbols added at resolution or code
2619 generation time. We commit the changes in order to keep a clean state. */
2620 if (found_sym)
2622 gfc_commit_symbol (vtab);
2623 if (vtype)
2624 gfc_commit_symbol (vtype);
2625 if (copy)
2626 gfc_commit_symbol (copy);
2627 if (src)
2628 gfc_commit_symbol (src);
2629 if (dst)
2630 gfc_commit_symbol (dst);
2632 else
2633 gfc_undo_symbols ();
2635 return found_sym;
2639 /* General worker function to find either a type-bound procedure or a
2640 type-bound user operator. */
2642 static gfc_symtree*
2643 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2644 const char* name, bool noaccess, bool uop,
2645 locus* where)
2647 gfc_symtree* res;
2648 gfc_symtree* root;
2650 /* Set default to failure. */
2651 if (t)
2652 *t = false;
2654 if (derived->f2k_derived)
2655 /* Set correct symbol-root. */
2656 root = (uop ? derived->f2k_derived->tb_uop_root
2657 : derived->f2k_derived->tb_sym_root);
2658 else
2659 return NULL;
2661 /* Try to find it in the current type's namespace. */
2662 res = gfc_find_symtree (root, name);
2663 if (res && res->n.tb && !res->n.tb->error)
2665 /* We found one. */
2666 if (t)
2667 *t = true;
2669 if (!noaccess && derived->attr.use_assoc
2670 && res->n.tb->access == ACCESS_PRIVATE)
2672 if (where)
2673 gfc_error ("'%s' of '%s' is PRIVATE at %L",
2674 name, derived->name, where);
2675 if (t)
2676 *t = false;
2679 return res;
2682 /* Otherwise, recurse on parent type if derived is an extension. */
2683 if (derived->attr.extension)
2685 gfc_symbol* super_type;
2686 super_type = gfc_get_derived_super_type (derived);
2687 gcc_assert (super_type);
2689 return find_typebound_proc_uop (super_type, t, name,
2690 noaccess, uop, where);
2693 /* Nothing found. */
2694 return NULL;
2698 /* Find a type-bound procedure or user operator by name for a derived-type
2699 (looking recursively through the super-types). */
2701 gfc_symtree*
2702 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
2703 const char* name, bool noaccess, locus* where)
2705 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2708 gfc_symtree*
2709 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
2710 const char* name, bool noaccess, locus* where)
2712 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2716 /* Find a type-bound intrinsic operator looking recursively through the
2717 super-type hierarchy. */
2719 gfc_typebound_proc*
2720 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
2721 gfc_intrinsic_op op, bool noaccess,
2722 locus* where)
2724 gfc_typebound_proc* res;
2726 /* Set default to failure. */
2727 if (t)
2728 *t = false;
2730 /* Try to find it in the current type's namespace. */
2731 if (derived->f2k_derived)
2732 res = derived->f2k_derived->tb_op[op];
2733 else
2734 res = NULL;
2736 /* Check access. */
2737 if (res && !res->error)
2739 /* We found one. */
2740 if (t)
2741 *t = true;
2743 if (!noaccess && derived->attr.use_assoc
2744 && res->access == ACCESS_PRIVATE)
2746 if (where)
2747 gfc_error ("'%s' of '%s' is PRIVATE at %L",
2748 gfc_op2string (op), derived->name, where);
2749 if (t)
2750 *t = false;
2753 return res;
2756 /* Otherwise, recurse on parent type if derived is an extension. */
2757 if (derived->attr.extension)
2759 gfc_symbol* super_type;
2760 super_type = gfc_get_derived_super_type (derived);
2761 gcc_assert (super_type);
2763 return gfc_find_typebound_intrinsic_op (super_type, t, op,
2764 noaccess, where);
2767 /* Nothing found. */
2768 return NULL;
2772 /* Get a typebound-procedure symtree or create and insert it if not yet
2773 present. This is like a very simplified version of gfc_get_sym_tree for
2774 tbp-symtrees rather than regular ones. */
2776 gfc_symtree*
2777 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
2779 gfc_symtree *result;
2781 result = gfc_find_symtree (*root, name);
2782 if (!result)
2784 result = gfc_new_symtree (root, name);
2785 gcc_assert (result);
2786 result->n.tb = NULL;
2789 return result;