Remove unused variable and field
[official-gcc.git] / gcc / fortran / class.c
blob629b052fb32dddc9cd0601cfe7238d868178a11f
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 an initializer for CLASS pointers,
416 initializing the _data component to the init_expr (or NULL) and the _vptr
417 component to the corresponding type (or the declared type, given by ts). */
419 gfc_expr *
420 gfc_class_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 if (init_expr && init_expr->expr_type != EXPR_NULL)
434 vtab = gfc_find_derived_vtab (init_expr->ts.u.derived);
435 else
436 vtab = gfc_find_derived_vtab (ts->u.derived);
438 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
439 &ts->u.derived->declared_at);
440 init->ts = *ts;
442 for (comp = ts->u.derived->components; comp; comp = comp->next)
444 gfc_constructor *ctor = gfc_constructor_get();
445 if (strcmp (comp->name, "_vptr") == 0 && vtab)
446 ctor->expr = gfc_lval_expr_from_sym (vtab);
447 else if (init_expr && init_expr->expr_type != EXPR_NULL)
448 ctor->expr = gfc_copy_expr (init_expr);
449 else
450 ctor->expr = gfc_get_null_expr (NULL);
451 gfc_constructor_append (&init->value.constructor, ctor);
454 return init;
458 /* Create a unique string identifier for a derived type, composed of its name
459 and module name. This is used to construct unique names for the class
460 containers and vtab symbols. */
462 static void
463 get_unique_type_string (char *string, gfc_symbol *derived)
465 char dt_name[GFC_MAX_SYMBOL_LEN+1];
466 if (derived->attr.unlimited_polymorphic)
467 strcpy (dt_name, "STAR");
468 else
469 strcpy (dt_name, derived->name);
470 dt_name[0] = TOUPPER (dt_name[0]);
471 if (derived->attr.unlimited_polymorphic)
472 sprintf (string, "_%s", dt_name);
473 else if (derived->module)
474 sprintf (string, "%s_%s", derived->module, dt_name);
475 else if (derived->ns->proc_name)
476 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
477 else
478 sprintf (string, "_%s", dt_name);
482 /* A relative of 'get_unique_type_string' which makes sure the generated
483 string will not be too long (replacing it by a hash string if needed). */
485 static void
486 get_unique_hashed_string (char *string, gfc_symbol *derived)
488 char tmp[2*GFC_MAX_SYMBOL_LEN+2];
489 get_unique_type_string (&tmp[0], derived);
490 /* If string is too long, use hash value in hex representation (allow for
491 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
492 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
493 where %d is the (co)rank which can be up to n = 15. */
494 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
496 int h = gfc_hash_value (derived);
497 sprintf (string, "%X", h);
499 else
500 strcpy (string, tmp);
504 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
506 unsigned int
507 gfc_hash_value (gfc_symbol *sym)
509 unsigned int hash = 0;
510 char c[2*(GFC_MAX_SYMBOL_LEN+1)];
511 int i, len;
513 get_unique_type_string (&c[0], sym);
514 len = strlen (c);
516 for (i = 0; i < len; i++)
517 hash = (hash << 6) + (hash << 16) - hash + c[i];
519 /* Return the hash but take the modulus for the sake of module read,
520 even though this slightly increases the chance of collision. */
521 return (hash % 100000000);
525 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
527 unsigned int
528 gfc_intrinsic_hash_value (gfc_typespec *ts)
530 unsigned int hash = 0;
531 const char *c = gfc_typename (ts);
532 int i, len;
534 len = strlen (c);
536 for (i = 0; i < len; i++)
537 hash = (hash << 6) + (hash << 16) - hash + c[i];
539 /* Return the hash but take the modulus for the sake of module read,
540 even though this slightly increases the chance of collision. */
541 return (hash % 100000000);
545 /* Build a polymorphic CLASS entity, using the symbol that comes from
546 build_sym. A CLASS entity is represented by an encapsulating type,
547 which contains the declared type as '_data' component, plus a pointer
548 component '_vptr' which determines the dynamic type. */
550 bool
551 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
552 gfc_array_spec **as, bool delayed_vtab)
554 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
555 gfc_symbol *fclass;
556 gfc_symbol *vtab;
557 gfc_component *c;
558 gfc_namespace *ns;
559 int rank;
561 gcc_assert (as);
563 if (*as && (*as)->type == AS_ASSUMED_SIZE)
565 gfc_error ("Assumed size polymorphic objects or components, such "
566 "as that at %C, have not yet been implemented");
567 return false;
570 if (attr->class_ok)
571 /* Class container has already been built. */
572 return true;
574 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
575 || attr->select_type_temporary || attr->associate_var;
577 if (!attr->class_ok)
578 /* We can not build the class container yet. */
579 return true;
581 /* Determine the name of the encapsulating type. */
582 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
583 get_unique_hashed_string (tname, ts->u.derived);
584 if ((*as) && attr->allocatable)
585 sprintf (name, "__class_%s_%d_%da", tname, rank, (*as)->corank);
586 else if ((*as) && attr->pointer)
587 sprintf (name, "__class_%s_%d_%dp", tname, rank, (*as)->corank);
588 else if ((*as))
589 sprintf (name, "__class_%s_%d_%d", tname, rank, (*as)->corank);
590 else if (attr->pointer)
591 sprintf (name, "__class_%s_p", tname);
592 else if (attr->allocatable)
593 sprintf (name, "__class_%s_a", tname);
594 else
595 sprintf (name, "__class_%s", tname);
597 if (ts->u.derived->attr.unlimited_polymorphic)
599 /* Find the top-level namespace. */
600 for (ns = gfc_current_ns; ns; ns = ns->parent)
601 if (!ns->parent)
602 break;
604 else
605 ns = ts->u.derived->ns;
607 gfc_find_symbol (name, ns, 0, &fclass);
608 if (fclass == NULL)
610 gfc_symtree *st;
611 /* If not there, create a new symbol. */
612 fclass = gfc_new_symbol (name, ns);
613 st = gfc_new_symtree (&ns->sym_root, name);
614 st->n.sym = fclass;
615 gfc_set_sym_referenced (fclass);
616 fclass->refs++;
617 fclass->ts.type = BT_UNKNOWN;
618 if (!ts->u.derived->attr.unlimited_polymorphic)
619 fclass->attr.abstract = ts->u.derived->attr.abstract;
620 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
621 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
622 &gfc_current_locus))
623 return false;
625 /* Add component '_data'. */
626 if (!gfc_add_component (fclass, "_data", &c))
627 return false;
628 c->ts = *ts;
629 c->ts.type = BT_DERIVED;
630 c->attr.access = ACCESS_PRIVATE;
631 c->ts.u.derived = ts->u.derived;
632 c->attr.class_pointer = attr->pointer;
633 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
634 || attr->select_type_temporary;
635 c->attr.allocatable = attr->allocatable;
636 c->attr.dimension = attr->dimension;
637 c->attr.codimension = attr->codimension;
638 c->attr.abstract = fclass->attr.abstract;
639 c->as = (*as);
640 c->initializer = NULL;
642 /* Add component '_vptr'. */
643 if (!gfc_add_component (fclass, "_vptr", &c))
644 return false;
645 c->ts.type = BT_DERIVED;
646 if (delayed_vtab
647 || (ts->u.derived->f2k_derived
648 && ts->u.derived->f2k_derived->finalizers))
649 c->ts.u.derived = NULL;
650 else
652 vtab = gfc_find_derived_vtab (ts->u.derived);
653 gcc_assert (vtab);
654 c->ts.u.derived = vtab->ts.u.derived;
656 c->attr.access = ACCESS_PRIVATE;
657 c->attr.pointer = 1;
660 if (!ts->u.derived->attr.unlimited_polymorphic)
662 /* Since the extension field is 8 bit wide, we can only have
663 up to 255 extension levels. */
664 if (ts->u.derived->attr.extension == 255)
666 gfc_error ("Maximum extension level reached with type '%s' at %L",
667 ts->u.derived->name, &ts->u.derived->declared_at);
668 return false;
671 fclass->attr.extension = ts->u.derived->attr.extension + 1;
672 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
673 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
676 fclass->attr.is_class = 1;
677 ts->u.derived = fclass;
678 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
679 (*as) = NULL;
680 return true;
684 /* Add a procedure pointer component to the vtype
685 to represent a specific type-bound procedure. */
687 static void
688 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
690 gfc_component *c;
692 if (tb->non_overridable)
693 return;
695 c = gfc_find_component (vtype, name, true, true);
697 if (c == NULL)
699 /* Add procedure component. */
700 if (!gfc_add_component (vtype, name, &c))
701 return;
703 if (!c->tb)
704 c->tb = XCNEW (gfc_typebound_proc);
705 *c->tb = *tb;
706 c->tb->ppc = 1;
707 c->attr.procedure = 1;
708 c->attr.proc_pointer = 1;
709 c->attr.flavor = FL_PROCEDURE;
710 c->attr.access = ACCESS_PRIVATE;
711 c->attr.external = 1;
712 c->attr.untyped = 1;
713 c->attr.if_source = IFSRC_IFBODY;
715 else if (c->attr.proc_pointer && c->tb)
717 *c->tb = *tb;
718 c->tb->ppc = 1;
721 if (tb->u.specific)
723 c->ts.interface = tb->u.specific->n.sym;
724 if (!tb->deferred)
725 c->initializer = gfc_get_variable_expr (tb->u.specific);
730 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
732 static void
733 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
735 if (!st)
736 return;
738 if (st->left)
739 add_procs_to_declared_vtab1 (st->left, vtype);
741 if (st->right)
742 add_procs_to_declared_vtab1 (st->right, vtype);
744 if (st->n.tb && !st->n.tb->error
745 && !st->n.tb->is_generic && st->n.tb->u.specific)
746 add_proc_comp (vtype, st->name, st->n.tb);
750 /* Copy procedure pointers components from the parent type. */
752 static void
753 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
755 gfc_component *cmp;
756 gfc_symbol *vtab;
758 vtab = gfc_find_derived_vtab (declared);
760 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
762 if (gfc_find_component (vtype, cmp->name, true, true))
763 continue;
765 add_proc_comp (vtype, cmp->name, cmp->tb);
770 /* Returns true if any of its nonpointer nonallocatable components or
771 their nonpointer nonallocatable subcomponents has a finalization
772 subroutine. */
774 static bool
775 has_finalizer_component (gfc_symbol *derived)
777 gfc_component *c;
779 for (c = derived->components; c; c = c->next)
781 if (c->ts.type == BT_DERIVED && c->ts.u.derived->f2k_derived
782 && c->ts.u.derived->f2k_derived->finalizers)
783 return true;
785 if (c->ts.type == BT_DERIVED
786 && !c->attr.pointer && !c->attr.allocatable
787 && has_finalizer_component (c->ts.u.derived))
788 return true;
790 return false;
794 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
795 neither allocatable nor a pointer but has a finalizer, call it. If it
796 is a nonpointer component with allocatable components or has finalizers, walk
797 them. Either of them is required; other nonallocatables and pointers aren't
798 handled gracefully.
799 Note: If the component is allocatable, the DEALLOCATE handling takes care
800 of calling the appropriate finalizers, coarray deregistering, and
801 deallocation of allocatable subcomponents. */
803 static void
804 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
805 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code)
807 gfc_expr *e;
808 gfc_ref *ref;
810 if (comp->ts.type != BT_DERIVED && comp->ts.type != BT_CLASS
811 && !comp->attr.allocatable)
812 return;
814 if ((comp->ts.type == BT_DERIVED && comp->attr.pointer)
815 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
816 && CLASS_DATA (comp)->attr.pointer))
817 return;
819 if (comp->ts.type == BT_DERIVED && !comp->attr.allocatable
820 && (comp->ts.u.derived->f2k_derived == NULL
821 || comp->ts.u.derived->f2k_derived->finalizers == NULL)
822 && !has_finalizer_component (comp->ts.u.derived))
823 return;
825 e = gfc_copy_expr (expr);
826 if (!e->ref)
827 e->ref = ref = gfc_get_ref ();
828 else
830 for (ref = e->ref; ref->next; ref = ref->next)
832 ref->next = gfc_get_ref ();
833 ref = ref->next;
835 ref->type = REF_COMPONENT;
836 ref->u.c.sym = derived;
837 ref->u.c.component = comp;
838 e->ts = comp->ts;
840 if (comp->attr.dimension || comp->attr.codimension
841 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
842 && (CLASS_DATA (comp)->attr.dimension
843 || CLASS_DATA (comp)->attr.codimension)))
845 ref->next = gfc_get_ref ();
846 ref->next->type = REF_ARRAY;
847 ref->next->u.ar.dimen = 0;
848 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
849 : comp->as;
850 e->rank = ref->next->u.ar.as->rank;
851 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
854 /* Call DEALLOCATE (comp, stat=ignore). */
855 if (comp->attr.allocatable
856 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
857 && CLASS_DATA (comp)->attr.allocatable))
859 gfc_code *dealloc, *block = NULL;
861 /* Add IF (fini_coarray). */
862 if (comp->attr.codimension
863 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
864 && CLASS_DATA (comp)->attr.allocatable))
866 block = gfc_get_code (EXEC_IF);
867 if (*code)
869 (*code)->next = block;
870 (*code) = (*code)->next;
872 else
873 (*code) = block;
875 block->block = gfc_get_code (EXEC_IF);
876 block = block->block;
877 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
880 dealloc = gfc_get_code (EXEC_DEALLOCATE);
882 dealloc->ext.alloc.list = gfc_get_alloc ();
883 dealloc->ext.alloc.list->expr = e;
884 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
886 if (block)
887 block->next = dealloc;
888 else if (*code)
890 (*code)->next = dealloc;
891 (*code) = (*code)->next;
893 else
894 (*code) = dealloc;
896 else if (comp->ts.type == BT_DERIVED
897 && comp->ts.u.derived->f2k_derived
898 && comp->ts.u.derived->f2k_derived->finalizers)
900 /* Call FINAL_WRAPPER (comp); */
901 gfc_code *final_wrap;
902 gfc_symbol *vtab;
903 gfc_component *c;
905 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
906 for (c = vtab->ts.u.derived->components; c; c = c->next)
907 if (strcmp (c->name, "_final") == 0)
908 break;
910 gcc_assert (c);
911 final_wrap = gfc_get_code (EXEC_CALL);
912 final_wrap->symtree = c->initializer->symtree;
913 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
914 final_wrap->ext.actual = gfc_get_actual_arglist ();
915 final_wrap->ext.actual->expr = e;
917 if (*code)
919 (*code)->next = final_wrap;
920 (*code) = (*code)->next;
922 else
923 (*code) = final_wrap;
925 else
927 gfc_component *c;
929 for (c = comp->ts.u.derived->components; c; c = c->next)
930 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code);
931 gfc_free_expr (e);
936 /* Generate code equivalent to
937 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
938 + offset, c_ptr), ptr). */
940 static gfc_code *
941 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
942 gfc_expr *offset, gfc_namespace *sub_ns)
944 gfc_code *block;
945 gfc_expr *expr, *expr2;
947 /* C_F_POINTER(). */
948 block = gfc_get_code (EXEC_CALL);
949 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
950 block->resolved_sym = block->symtree->n.sym;
951 block->resolved_sym->attr.flavor = FL_PROCEDURE;
952 block->resolved_sym->attr.intrinsic = 1;
953 block->resolved_sym->attr.subroutine = 1;
954 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
955 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
956 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
957 gfc_commit_symbol (block->resolved_sym);
959 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
960 block->ext.actual = gfc_get_actual_arglist ();
961 block->ext.actual->next = gfc_get_actual_arglist ();
962 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
963 NULL, 0);
964 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
966 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
968 /* TRANSFER's first argument: C_LOC (array). */
969 expr = gfc_get_expr ();
970 expr->expr_type = EXPR_FUNCTION;
971 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
972 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
973 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
974 expr->symtree->n.sym->attr.intrinsic = 1;
975 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
976 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
977 expr->value.function.actual = gfc_get_actual_arglist ();
978 expr->value.function.actual->expr
979 = gfc_lval_expr_from_sym (array);
980 expr->symtree->n.sym->result = expr->symtree->n.sym;
981 gfc_commit_symbol (expr->symtree->n.sym);
982 expr->ts.type = BT_INTEGER;
983 expr->ts.kind = gfc_index_integer_kind;
985 /* TRANSFER. */
986 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
987 gfc_current_locus, 3, expr,
988 gfc_get_int_expr (gfc_index_integer_kind,
989 NULL, 0), NULL);
990 expr2->ts.type = BT_INTEGER;
991 expr2->ts.kind = gfc_index_integer_kind;
993 /* <array addr> + <offset>. */
994 block->ext.actual->expr = gfc_get_expr ();
995 block->ext.actual->expr->expr_type = EXPR_OP;
996 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
997 block->ext.actual->expr->value.op.op1 = expr2;
998 block->ext.actual->expr->value.op.op2 = offset;
999 block->ext.actual->expr->ts = expr->ts;
1001 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1002 block->ext.actual->next = gfc_get_actual_arglist ();
1003 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1004 block->ext.actual->next->next = gfc_get_actual_arglist ();
1006 return block;
1010 /* Calculates the offset to the (idx+1)th element of an array, taking the
1011 stride into account. It generates the code:
1012 offset = 0
1013 do idx2 = 1, rank
1014 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1015 end do
1016 offset = offset * byte_stride. */
1018 static gfc_code*
1019 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1020 gfc_symbol *strides, gfc_symbol *sizes,
1021 gfc_symbol *byte_stride, gfc_expr *rank,
1022 gfc_code *block, gfc_namespace *sub_ns)
1024 gfc_iterator *iter;
1025 gfc_expr *expr, *expr2;
1027 /* offset = 0. */
1028 block->next = gfc_get_code (EXEC_ASSIGN);
1029 block = block->next;
1030 block->expr1 = gfc_lval_expr_from_sym (offset);
1031 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1033 /* Create loop. */
1034 iter = gfc_get_iterator ();
1035 iter->var = gfc_lval_expr_from_sym (idx2);
1036 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1037 iter->end = gfc_copy_expr (rank);
1038 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1039 block->next = gfc_get_code (EXEC_DO);
1040 block = block->next;
1041 block->ext.iterator = iter;
1042 block->block = gfc_get_code (EXEC_DO);
1044 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1045 * strides(idx2). */
1047 /* mod (idx, sizes(idx2)). */
1048 expr = gfc_lval_expr_from_sym (sizes);
1049 expr->ref = gfc_get_ref ();
1050 expr->ref->type = REF_ARRAY;
1051 expr->ref->u.ar.as = sizes->as;
1052 expr->ref->u.ar.type = AR_ELEMENT;
1053 expr->ref->u.ar.dimen = 1;
1054 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1055 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1057 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1058 gfc_current_locus, 2,
1059 gfc_lval_expr_from_sym (idx), expr);
1060 expr->ts = idx->ts;
1062 /* (...) / sizes(idx2-1). */
1063 expr2 = gfc_get_expr ();
1064 expr2->expr_type = EXPR_OP;
1065 expr2->value.op.op = INTRINSIC_DIVIDE;
1066 expr2->value.op.op1 = expr;
1067 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1068 expr2->value.op.op2->ref = gfc_get_ref ();
1069 expr2->value.op.op2->ref->type = REF_ARRAY;
1070 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1071 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1072 expr2->value.op.op2->ref->u.ar.dimen = 1;
1073 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1074 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1075 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1076 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1077 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1078 = gfc_lval_expr_from_sym (idx2);
1079 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1080 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1081 expr2->value.op.op2->ref->u.ar.start[0]->ts
1082 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1083 expr2->ts = idx->ts;
1085 /* ... * strides(idx2). */
1086 expr = gfc_get_expr ();
1087 expr->expr_type = EXPR_OP;
1088 expr->value.op.op = INTRINSIC_TIMES;
1089 expr->value.op.op1 = expr2;
1090 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1091 expr->value.op.op2->ref = gfc_get_ref ();
1092 expr->value.op.op2->ref->type = REF_ARRAY;
1093 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1094 expr->value.op.op2->ref->u.ar.dimen = 1;
1095 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1096 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1097 expr->value.op.op2->ref->u.ar.as = strides->as;
1098 expr->ts = idx->ts;
1100 /* offset = offset + ... */
1101 block->block->next = gfc_get_code (EXEC_ASSIGN);
1102 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1103 block->block->next->expr2 = gfc_get_expr ();
1104 block->block->next->expr2->expr_type = EXPR_OP;
1105 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1106 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1107 block->block->next->expr2->value.op.op2 = expr;
1108 block->block->next->expr2->ts = idx->ts;
1110 /* After the loop: offset = offset * byte_stride. */
1111 block->next = gfc_get_code (EXEC_ASSIGN);
1112 block = block->next;
1113 block->expr1 = gfc_lval_expr_from_sym (offset);
1114 block->expr2 = gfc_get_expr ();
1115 block->expr2->expr_type = EXPR_OP;
1116 block->expr2->value.op.op = INTRINSIC_TIMES;
1117 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1118 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1119 block->expr2->ts = block->expr2->value.op.op1->ts;
1120 return block;
1124 /* Insert code of the following form:
1126 block
1127 integer(c_intptr_t) :: i
1129 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1130 && (is_contiguous || !final_rank3->attr.contiguous
1131 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1132 || 0 == STORAGE_SIZE (array)) then
1133 call final_rank3 (array)
1134 else
1135 block
1136 integer(c_intptr_t) :: offset, j
1137 type(t) :: tmp(shape (array))
1139 do i = 0, size (array)-1
1140 offset = obtain_offset(i, strides, sizes, byte_stride)
1141 addr = transfer (c_loc (array), addr) + offset
1142 call c_f_pointer (transfer (addr, cptr), ptr)
1144 addr = transfer (c_loc (tmp), addr)
1145 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1146 call c_f_pointer (transfer (addr, cptr), ptr2)
1147 ptr2 = ptr
1148 end do
1149 call final_rank3 (tmp)
1150 end block
1151 end if
1152 block */
1154 static void
1155 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1156 gfc_symbol *array, gfc_symbol *byte_stride,
1157 gfc_symbol *idx, gfc_symbol *ptr,
1158 gfc_symbol *nelem,
1159 gfc_symbol *strides, gfc_symbol *sizes,
1160 gfc_symbol *idx2, gfc_symbol *offset,
1161 gfc_symbol *is_contiguous, gfc_expr *rank,
1162 gfc_namespace *sub_ns)
1164 gfc_symbol *tmp_array, *ptr2;
1165 gfc_expr *size_expr, *offset2, *expr;
1166 gfc_namespace *ns;
1167 gfc_iterator *iter;
1168 gfc_code *block2;
1169 int i;
1171 block->next = gfc_get_code (EXEC_IF);
1172 block = block->next;
1174 block->block = gfc_get_code (EXEC_IF);
1175 block = block->block;
1177 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1178 size_expr = gfc_get_expr ();
1179 size_expr->where = gfc_current_locus;
1180 size_expr->expr_type = EXPR_OP;
1181 size_expr->value.op.op = INTRINSIC_DIVIDE;
1183 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1184 size_expr->value.op.op1
1185 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1186 "storage_size", gfc_current_locus, 2,
1187 gfc_lval_expr_from_sym (array),
1188 gfc_get_int_expr (gfc_index_integer_kind,
1189 NULL, 0));
1191 /* NUMERIC_STORAGE_SIZE. */
1192 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1193 gfc_character_storage_size);
1194 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1195 size_expr->ts = size_expr->value.op.op1->ts;
1197 /* IF condition: (stride == size_expr
1198 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1199 || is_contiguous)
1200 || 0 == size_expr. */
1201 block->expr1 = gfc_get_expr ();
1202 block->expr1->ts.type = BT_LOGICAL;
1203 block->expr1->ts.kind = gfc_default_logical_kind;
1204 block->expr1->expr_type = EXPR_OP;
1205 block->expr1->where = gfc_current_locus;
1207 block->expr1->value.op.op = INTRINSIC_OR;
1209 /* byte_stride == size_expr */
1210 expr = gfc_get_expr ();
1211 expr->ts.type = BT_LOGICAL;
1212 expr->ts.kind = gfc_default_logical_kind;
1213 expr->expr_type = EXPR_OP;
1214 expr->where = gfc_current_locus;
1215 expr->value.op.op = INTRINSIC_EQ;
1216 expr->value.op.op1
1217 = gfc_lval_expr_from_sym (byte_stride);
1218 expr->value.op.op2 = size_expr;
1220 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1221 add is_contiguous check. */
1223 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1224 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1226 gfc_expr *expr2;
1227 expr2 = gfc_get_expr ();
1228 expr2->ts.type = BT_LOGICAL;
1229 expr2->ts.kind = gfc_default_logical_kind;
1230 expr2->expr_type = EXPR_OP;
1231 expr2->where = gfc_current_locus;
1232 expr2->value.op.op = INTRINSIC_AND;
1233 expr2->value.op.op1 = expr;
1234 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1235 expr = expr2;
1238 block->expr1->value.op.op1 = expr;
1240 /* 0 == size_expr */
1241 block->expr1->value.op.op2 = gfc_get_expr ();
1242 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1243 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1244 block->expr1->value.op.op2->expr_type = EXPR_OP;
1245 block->expr1->value.op.op2->where = gfc_current_locus;
1246 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1247 block->expr1->value.op.op2->value.op.op1 =
1248 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1249 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1251 /* IF body: call final subroutine. */
1252 block->next = gfc_get_code (EXEC_CALL);
1253 block->next->symtree = fini->proc_tree;
1254 block->next->resolved_sym = fini->proc_tree->n.sym;
1255 block->next->ext.actual = gfc_get_actual_arglist ();
1256 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1258 /* ELSE. */
1260 block->block = gfc_get_code (EXEC_IF);
1261 block = block->block;
1263 /* BLOCK ... END BLOCK. */
1264 block->next = gfc_get_code (EXEC_BLOCK);
1265 block = block->next;
1267 ns = gfc_build_block_ns (sub_ns);
1268 block->ext.block.ns = ns;
1269 block->ext.block.assoc = NULL;
1271 gfc_get_symbol ("ptr2", ns, &ptr2);
1272 ptr2->ts.type = BT_DERIVED;
1273 ptr2->ts.u.derived = array->ts.u.derived;
1274 ptr2->attr.flavor = FL_VARIABLE;
1275 ptr2->attr.pointer = 1;
1276 ptr2->attr.artificial = 1;
1277 gfc_set_sym_referenced (ptr2);
1278 gfc_commit_symbol (ptr2);
1280 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1281 tmp_array->ts.type = BT_DERIVED;
1282 tmp_array->ts.u.derived = array->ts.u.derived;
1283 tmp_array->attr.flavor = FL_VARIABLE;
1284 tmp_array->attr.dimension = 1;
1285 tmp_array->attr.artificial = 1;
1286 tmp_array->as = gfc_get_array_spec();
1287 tmp_array->attr.intent = INTENT_INOUT;
1288 tmp_array->as->type = AS_EXPLICIT;
1289 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1291 for (i = 0; i < tmp_array->as->rank; i++)
1293 gfc_expr *shape_expr;
1294 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1295 NULL, 1);
1296 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1297 shape_expr
1298 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1299 gfc_current_locus, 3,
1300 gfc_lval_expr_from_sym (array),
1301 gfc_get_int_expr (gfc_default_integer_kind,
1302 NULL, i+1),
1303 gfc_get_int_expr (gfc_default_integer_kind,
1304 NULL,
1305 gfc_index_integer_kind));
1306 shape_expr->ts.kind = gfc_index_integer_kind;
1307 tmp_array->as->upper[i] = shape_expr;
1309 gfc_set_sym_referenced (tmp_array);
1310 gfc_commit_symbol (tmp_array);
1312 /* Create loop. */
1313 iter = gfc_get_iterator ();
1314 iter->var = gfc_lval_expr_from_sym (idx);
1315 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1316 iter->end = gfc_lval_expr_from_sym (nelem);
1317 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1319 block = gfc_get_code (EXEC_DO);
1320 ns->code = block;
1321 block->ext.iterator = iter;
1322 block->block = gfc_get_code (EXEC_DO);
1324 /* Offset calculation for the new array: idx * size of type (in bytes). */
1325 offset2 = gfc_get_expr ();
1326 offset2->expr_type = EXPR_OP;
1327 offset2->value.op.op = INTRINSIC_TIMES;
1328 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1329 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1330 offset2->ts = byte_stride->ts;
1332 /* Offset calculation of "array". */
1333 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1334 byte_stride, rank, block->block, sub_ns);
1336 /* Create code for
1337 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1338 + idx * stride, c_ptr), ptr). */
1339 block2->next = finalization_scalarizer (array, ptr,
1340 gfc_lval_expr_from_sym (offset),
1341 sub_ns);
1342 block2 = block2->next;
1343 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1344 block2 = block2->next;
1346 /* ptr2 = ptr. */
1347 block2->next = gfc_get_code (EXEC_ASSIGN);
1348 block2 = block2->next;
1349 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1350 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1352 /* Call now the user's final subroutine. */
1353 block->next = gfc_get_code (EXEC_CALL);
1354 block = block->next;
1355 block->symtree = fini->proc_tree;
1356 block->resolved_sym = fini->proc_tree->n.sym;
1357 block->ext.actual = gfc_get_actual_arglist ();
1358 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1360 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1361 return;
1363 /* Copy back. */
1365 /* Loop. */
1366 iter = gfc_get_iterator ();
1367 iter->var = gfc_lval_expr_from_sym (idx);
1368 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1369 iter->end = gfc_lval_expr_from_sym (nelem);
1370 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1372 block->next = gfc_get_code (EXEC_DO);
1373 block = block->next;
1374 block->ext.iterator = iter;
1375 block->block = gfc_get_code (EXEC_DO);
1377 /* Offset calculation of "array". */
1378 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1379 byte_stride, rank, block->block, sub_ns);
1381 /* Create code for
1382 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1383 + offset, c_ptr), ptr). */
1384 block2->next = finalization_scalarizer (array, ptr,
1385 gfc_lval_expr_from_sym (offset),
1386 sub_ns);
1387 block2 = block2->next;
1388 block2->next = finalization_scalarizer (tmp_array, ptr2,
1389 gfc_copy_expr (offset2), sub_ns);
1390 block2 = block2->next;
1392 /* ptr = ptr2. */
1393 block2->next = gfc_get_code (EXEC_ASSIGN);
1394 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1395 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1399 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1400 derived type "derived". The function first calls the approriate FINAL
1401 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1402 components (but not the inherited ones). Last, it calls the wrapper
1403 subroutine of the parent. The generated wrapper procedure takes as argument
1404 an assumed-rank array.
1405 If neither allocatable components nor FINAL subroutines exists, the vtab
1406 will contain a NULL pointer.
1407 The generated function has the form
1408 _final(assumed-rank array, stride, skip_corarray)
1409 where the array has to be contiguous (except of the lowest dimension). The
1410 stride (in bytes) is used to allow different sizes for ancestor types by
1411 skipping over the additionally added components in the scalarizer. If
1412 "fini_coarray" is false, coarray components are not finalized to allow for
1413 the correct semantic with intrinsic assignment. */
1415 static void
1416 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1417 const char *tname, gfc_component *vtab_final)
1419 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1420 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1421 gfc_component *comp;
1422 gfc_namespace *sub_ns;
1423 gfc_code *last_code, *block;
1424 char name[GFC_MAX_SYMBOL_LEN+1];
1425 bool finalizable_comp = false;
1426 bool expr_null_wrapper = false;
1427 gfc_expr *ancestor_wrapper = NULL, *rank;
1428 gfc_iterator *iter;
1430 /* Search for the ancestor's finalizers. */
1431 if (derived->attr.extension && derived->components
1432 && (!derived->components->ts.u.derived->attr.abstract
1433 || has_finalizer_component (derived)))
1435 gfc_symbol *vtab;
1436 gfc_component *comp;
1438 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1439 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1440 if (comp->name[0] == '_' && comp->name[1] == 'f')
1442 ancestor_wrapper = comp->initializer;
1443 break;
1447 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1448 components: Return a NULL() expression; we defer this a bit to have have
1449 an interface declaration. */
1450 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1451 && !derived->attr.alloc_comp
1452 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1453 && !has_finalizer_component (derived))
1454 expr_null_wrapper = true;
1455 else
1456 /* Check whether there are new allocatable components. */
1457 for (comp = derived->components; comp; comp = comp->next)
1459 if (comp == derived->components && derived->attr.extension
1460 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1461 continue;
1463 if (comp->ts.type != BT_CLASS && !comp->attr.pointer
1464 && (comp->attr.allocatable
1465 || (comp->ts.type == BT_DERIVED
1466 && (comp->ts.u.derived->attr.alloc_comp
1467 || has_finalizer_component (comp->ts.u.derived)
1468 || (comp->ts.u.derived->f2k_derived
1469 && comp->ts.u.derived->f2k_derived->finalizers)))))
1470 finalizable_comp = true;
1471 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1472 && CLASS_DATA (comp)->attr.allocatable)
1473 finalizable_comp = true;
1476 /* If there is no new finalizer and no new allocatable, return with
1477 an expr to the ancestor's one. */
1478 if (!expr_null_wrapper && !finalizable_comp
1479 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1481 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1482 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1483 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1484 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1485 return;
1488 /* We now create a wrapper, which does the following:
1489 1. Call the suitable finalization subroutine for this type
1490 2. Loop over all noninherited allocatable components and noninherited
1491 components with allocatable components and DEALLOCATE those; this will
1492 take care of finalizers, coarray deregistering and allocatable
1493 nested components.
1494 3. Call the ancestor's finalizer. */
1496 /* Declare the wrapper function; it takes an assumed-rank array
1497 and a VALUE logical as arguments. */
1499 /* Set up the namespace. */
1500 sub_ns = gfc_get_namespace (ns, 0);
1501 sub_ns->sibling = ns->contained;
1502 if (!expr_null_wrapper)
1503 ns->contained = sub_ns;
1504 sub_ns->resolved = 1;
1506 /* Set up the procedure symbol. */
1507 sprintf (name, "__final_%s", tname);
1508 gfc_get_symbol (name, sub_ns, &final);
1509 sub_ns->proc_name = final;
1510 final->attr.flavor = FL_PROCEDURE;
1511 final->attr.function = 1;
1512 final->attr.pure = 0;
1513 final->result = final;
1514 final->ts.type = BT_INTEGER;
1515 final->ts.kind = 4;
1516 final->attr.artificial = 1;
1517 final->attr.if_source = expr_null_wrapper ? IFSRC_IFBODY : IFSRC_DECL;
1518 if (ns->proc_name->attr.flavor == FL_MODULE)
1519 final->module = ns->proc_name->name;
1520 gfc_set_sym_referenced (final);
1521 gfc_commit_symbol (final);
1523 /* Set up formal argument. */
1524 gfc_get_symbol ("array", sub_ns, &array);
1525 array->ts.type = BT_DERIVED;
1526 array->ts.u.derived = derived;
1527 array->attr.flavor = FL_VARIABLE;
1528 array->attr.dummy = 1;
1529 array->attr.contiguous = 1;
1530 array->attr.dimension = 1;
1531 array->attr.artificial = 1;
1532 array->as = gfc_get_array_spec();
1533 array->as->type = AS_ASSUMED_RANK;
1534 array->as->rank = -1;
1535 array->attr.intent = INTENT_INOUT;
1536 gfc_set_sym_referenced (array);
1537 final->formal = gfc_get_formal_arglist ();
1538 final->formal->sym = array;
1539 gfc_commit_symbol (array);
1541 /* Set up formal argument. */
1542 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1543 byte_stride->ts.type = BT_INTEGER;
1544 byte_stride->ts.kind = gfc_index_integer_kind;
1545 byte_stride->attr.flavor = FL_VARIABLE;
1546 byte_stride->attr.dummy = 1;
1547 byte_stride->attr.value = 1;
1548 byte_stride->attr.artificial = 1;
1549 gfc_set_sym_referenced (byte_stride);
1550 final->formal->next = gfc_get_formal_arglist ();
1551 final->formal->next->sym = byte_stride;
1552 gfc_commit_symbol (byte_stride);
1554 /* Set up formal argument. */
1555 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1556 fini_coarray->ts.type = BT_LOGICAL;
1557 fini_coarray->ts.kind = 1;
1558 fini_coarray->attr.flavor = FL_VARIABLE;
1559 fini_coarray->attr.dummy = 1;
1560 fini_coarray->attr.value = 1;
1561 fini_coarray->attr.artificial = 1;
1562 gfc_set_sym_referenced (fini_coarray);
1563 final->formal->next->next = gfc_get_formal_arglist ();
1564 final->formal->next->next->sym = fini_coarray;
1565 gfc_commit_symbol (fini_coarray);
1567 /* Return with a NULL() expression but with an interface which has
1568 the formal arguments. */
1569 if (expr_null_wrapper)
1571 vtab_final->initializer = gfc_get_null_expr (NULL);
1572 vtab_final->ts.interface = final;
1573 return;
1576 /* Local variables. */
1578 gfc_get_symbol ("idx", sub_ns, &idx);
1579 idx->ts.type = BT_INTEGER;
1580 idx->ts.kind = gfc_index_integer_kind;
1581 idx->attr.flavor = FL_VARIABLE;
1582 idx->attr.artificial = 1;
1583 gfc_set_sym_referenced (idx);
1584 gfc_commit_symbol (idx);
1586 gfc_get_symbol ("idx2", sub_ns, &idx2);
1587 idx2->ts.type = BT_INTEGER;
1588 idx2->ts.kind = gfc_index_integer_kind;
1589 idx2->attr.flavor = FL_VARIABLE;
1590 idx2->attr.artificial = 1;
1591 gfc_set_sym_referenced (idx2);
1592 gfc_commit_symbol (idx2);
1594 gfc_get_symbol ("offset", sub_ns, &offset);
1595 offset->ts.type = BT_INTEGER;
1596 offset->ts.kind = gfc_index_integer_kind;
1597 offset->attr.flavor = FL_VARIABLE;
1598 offset->attr.artificial = 1;
1599 gfc_set_sym_referenced (offset);
1600 gfc_commit_symbol (offset);
1602 /* Create RANK expression. */
1603 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1604 gfc_current_locus, 1,
1605 gfc_lval_expr_from_sym (array));
1606 if (rank->ts.kind != idx->ts.kind)
1607 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1609 /* Create is_contiguous variable. */
1610 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1611 is_contiguous->ts.type = BT_LOGICAL;
1612 is_contiguous->ts.kind = gfc_default_logical_kind;
1613 is_contiguous->attr.flavor = FL_VARIABLE;
1614 is_contiguous->attr.artificial = 1;
1615 gfc_set_sym_referenced (is_contiguous);
1616 gfc_commit_symbol (is_contiguous);
1618 /* Create "sizes(0..rank)" variable, which contains the multiplied
1619 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1620 sizes(2) = sizes(1) * extent(dim=2) etc. */
1621 gfc_get_symbol ("sizes", sub_ns, &sizes);
1622 sizes->ts.type = BT_INTEGER;
1623 sizes->ts.kind = gfc_index_integer_kind;
1624 sizes->attr.flavor = FL_VARIABLE;
1625 sizes->attr.dimension = 1;
1626 sizes->attr.artificial = 1;
1627 sizes->as = gfc_get_array_spec();
1628 sizes->attr.intent = INTENT_INOUT;
1629 sizes->as->type = AS_EXPLICIT;
1630 sizes->as->rank = 1;
1631 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1632 sizes->as->upper[0] = gfc_copy_expr (rank);
1633 gfc_set_sym_referenced (sizes);
1634 gfc_commit_symbol (sizes);
1636 /* Create "strides(1..rank)" variable, which contains the strides per
1637 dimension. */
1638 gfc_get_symbol ("strides", sub_ns, &strides);
1639 strides->ts.type = BT_INTEGER;
1640 strides->ts.kind = gfc_index_integer_kind;
1641 strides->attr.flavor = FL_VARIABLE;
1642 strides->attr.dimension = 1;
1643 strides->attr.artificial = 1;
1644 strides->as = gfc_get_array_spec();
1645 strides->attr.intent = INTENT_INOUT;
1646 strides->as->type = AS_EXPLICIT;
1647 strides->as->rank = 1;
1648 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1649 strides->as->upper[0] = gfc_copy_expr (rank);
1650 gfc_set_sym_referenced (strides);
1651 gfc_commit_symbol (strides);
1654 /* Set return value to 0. */
1655 last_code = gfc_get_code (EXEC_ASSIGN);
1656 last_code->expr1 = gfc_lval_expr_from_sym (final);
1657 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1658 sub_ns->code = last_code;
1660 /* Set: is_contiguous = .true. */
1661 last_code->next = gfc_get_code (EXEC_ASSIGN);
1662 last_code = last_code->next;
1663 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1664 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1665 &gfc_current_locus, true);
1667 /* Set: sizes(0) = 1. */
1668 last_code->next = gfc_get_code (EXEC_ASSIGN);
1669 last_code = last_code->next;
1670 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1671 last_code->expr1->ref = gfc_get_ref ();
1672 last_code->expr1->ref->type = REF_ARRAY;
1673 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1674 last_code->expr1->ref->u.ar.dimen = 1;
1675 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1676 last_code->expr1->ref->u.ar.start[0]
1677 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1678 last_code->expr1->ref->u.ar.as = sizes->as;
1679 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1681 /* Create:
1682 DO idx = 1, rank
1683 strides(idx) = _F._stride (array, dim=idx)
1684 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1685 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1686 END DO. */
1688 /* Create loop. */
1689 iter = gfc_get_iterator ();
1690 iter->var = gfc_lval_expr_from_sym (idx);
1691 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1692 iter->end = gfc_copy_expr (rank);
1693 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1694 last_code->next = gfc_get_code (EXEC_DO);
1695 last_code = last_code->next;
1696 last_code->ext.iterator = iter;
1697 last_code->block = gfc_get_code (EXEC_DO);
1699 /* strides(idx) = _F._stride(array,dim=idx). */
1700 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1701 block = last_code->block->next;
1703 block->expr1 = gfc_lval_expr_from_sym (strides);
1704 block->expr1->ref = gfc_get_ref ();
1705 block->expr1->ref->type = REF_ARRAY;
1706 block->expr1->ref->u.ar.type = AR_ELEMENT;
1707 block->expr1->ref->u.ar.dimen = 1;
1708 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1709 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1710 block->expr1->ref->u.ar.as = strides->as;
1712 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
1713 gfc_current_locus, 2,
1714 gfc_lval_expr_from_sym (array),
1715 gfc_lval_expr_from_sym (idx));
1717 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
1718 block->next = gfc_get_code (EXEC_ASSIGN);
1719 block = block->next;
1721 /* sizes(idx) = ... */
1722 block->expr1 = gfc_lval_expr_from_sym (sizes);
1723 block->expr1->ref = gfc_get_ref ();
1724 block->expr1->ref->type = REF_ARRAY;
1725 block->expr1->ref->u.ar.type = AR_ELEMENT;
1726 block->expr1->ref->u.ar.dimen = 1;
1727 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1728 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1729 block->expr1->ref->u.ar.as = sizes->as;
1731 block->expr2 = gfc_get_expr ();
1732 block->expr2->expr_type = EXPR_OP;
1733 block->expr2->value.op.op = INTRINSIC_TIMES;
1735 /* sizes(idx-1). */
1736 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1737 block->expr2->value.op.op1->ref = gfc_get_ref ();
1738 block->expr2->value.op.op1->ref->type = REF_ARRAY;
1739 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1740 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1741 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
1742 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1743 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
1744 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
1745 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1746 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
1747 = gfc_lval_expr_from_sym (idx);
1748 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
1749 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1750 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
1751 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
1753 /* size(array, dim=idx, kind=index_kind). */
1754 block->expr2->value.op.op2
1755 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1756 gfc_current_locus, 3,
1757 gfc_lval_expr_from_sym (array),
1758 gfc_lval_expr_from_sym (idx),
1759 gfc_get_int_expr (gfc_index_integer_kind,
1760 NULL,
1761 gfc_index_integer_kind));
1762 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
1763 block->expr2->ts = idx->ts;
1765 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
1766 block->next = gfc_get_code (EXEC_IF);
1767 block = block->next;
1769 block->block = gfc_get_code (EXEC_IF);
1770 block = block->block;
1772 /* if condition: strides(idx) /= sizes(idx-1). */
1773 block->expr1 = gfc_get_expr ();
1774 block->expr1->ts.type = BT_LOGICAL;
1775 block->expr1->ts.kind = gfc_default_logical_kind;
1776 block->expr1->expr_type = EXPR_OP;
1777 block->expr1->where = gfc_current_locus;
1778 block->expr1->value.op.op = INTRINSIC_NE;
1780 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
1781 block->expr1->value.op.op1->ref = gfc_get_ref ();
1782 block->expr1->value.op.op1->ref->type = REF_ARRAY;
1783 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1784 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
1785 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1786 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
1787 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
1789 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1790 block->expr1->value.op.op2->ref = gfc_get_ref ();
1791 block->expr1->value.op.op2->ref->type = REF_ARRAY;
1792 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
1793 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1794 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
1795 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1796 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1797 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1798 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1799 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
1800 = gfc_lval_expr_from_sym (idx);
1801 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
1802 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1803 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
1804 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1806 /* if body: is_contiguous = .false. */
1807 block->next = gfc_get_code (EXEC_ASSIGN);
1808 block = block->next;
1809 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1810 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1811 &gfc_current_locus, false);
1813 /* Obtain the size (number of elements) of "array" MINUS ONE,
1814 which is used in the scalarization. */
1815 gfc_get_symbol ("nelem", sub_ns, &nelem);
1816 nelem->ts.type = BT_INTEGER;
1817 nelem->ts.kind = gfc_index_integer_kind;
1818 nelem->attr.flavor = FL_VARIABLE;
1819 nelem->attr.artificial = 1;
1820 gfc_set_sym_referenced (nelem);
1821 gfc_commit_symbol (nelem);
1823 /* nelem = sizes (rank) - 1. */
1824 last_code->next = gfc_get_code (EXEC_ASSIGN);
1825 last_code = last_code->next;
1827 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
1829 last_code->expr2 = gfc_get_expr ();
1830 last_code->expr2->expr_type = EXPR_OP;
1831 last_code->expr2->value.op.op = INTRINSIC_MINUS;
1832 last_code->expr2->value.op.op2
1833 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1834 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
1836 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
1837 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
1838 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
1839 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
1840 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
1841 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1842 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
1843 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
1845 /* Call final subroutines. We now generate code like:
1846 use iso_c_binding
1847 integer, pointer :: ptr
1848 type(c_ptr) :: cptr
1849 integer(c_intptr_t) :: i, addr
1851 select case (rank (array))
1852 case (3)
1853 ! If needed, the array is packed
1854 call final_rank3 (array)
1855 case default:
1856 do i = 0, size (array)-1
1857 addr = transfer (c_loc (array), addr) + i * stride
1858 call c_f_pointer (transfer (addr, cptr), ptr)
1859 call elemental_final (ptr)
1860 end do
1861 end select */
1863 if (derived->f2k_derived && derived->f2k_derived->finalizers)
1865 gfc_finalizer *fini, *fini_elem = NULL;
1867 gfc_get_symbol ("ptr", sub_ns, &ptr);
1868 ptr->ts.type = BT_DERIVED;
1869 ptr->ts.u.derived = derived;
1870 ptr->attr.flavor = FL_VARIABLE;
1871 ptr->attr.pointer = 1;
1872 ptr->attr.artificial = 1;
1873 gfc_set_sym_referenced (ptr);
1874 gfc_commit_symbol (ptr);
1876 /* SELECT CASE (RANK (array)). */
1877 last_code->next = gfc_get_code (EXEC_SELECT);
1878 last_code = last_code->next;
1879 last_code->expr1 = gfc_copy_expr (rank);
1880 block = NULL;
1882 for (fini = derived->f2k_derived->finalizers; fini; fini = fini->next)
1884 if (fini->proc_tree->n.sym->attr.elemental)
1886 fini_elem = fini;
1887 continue;
1890 /* CASE (fini_rank). */
1891 if (block)
1893 block->block = gfc_get_code (EXEC_SELECT);
1894 block = block->block;
1896 else
1898 block = gfc_get_code (EXEC_SELECT);
1899 last_code->block = block;
1901 block->ext.block.case_list = gfc_get_case ();
1902 block->ext.block.case_list->where = gfc_current_locus;
1903 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1904 block->ext.block.case_list->low
1905 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
1906 fini->proc_tree->n.sym->formal->sym->as->rank);
1907 else
1908 block->ext.block.case_list->low
1909 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
1910 block->ext.block.case_list->high
1911 = gfc_copy_expr (block->ext.block.case_list->low);
1913 /* CALL fini_rank (array) - possibly with packing. */
1914 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
1915 finalizer_insert_packed_call (block, fini, array, byte_stride,
1916 idx, ptr, nelem, strides,
1917 sizes, idx2, offset, is_contiguous,
1918 rank, sub_ns);
1919 else
1921 block->next = gfc_get_code (EXEC_CALL);
1922 block->next->symtree = fini->proc_tree;
1923 block->next->resolved_sym = fini->proc_tree->n.sym;
1924 block->next->ext.actual = gfc_get_actual_arglist ();
1925 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1929 /* Elemental call - scalarized. */
1930 if (fini_elem)
1932 /* CASE DEFAULT. */
1933 if (block)
1935 block->block = gfc_get_code (EXEC_SELECT);
1936 block = block->block;
1938 else
1940 block = gfc_get_code (EXEC_SELECT);
1941 last_code->block = block;
1943 block->ext.block.case_list = gfc_get_case ();
1945 /* Create loop. */
1946 iter = gfc_get_iterator ();
1947 iter->var = gfc_lval_expr_from_sym (idx);
1948 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1949 iter->end = gfc_lval_expr_from_sym (nelem);
1950 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1951 block->next = gfc_get_code (EXEC_DO);
1952 block = block->next;
1953 block->ext.iterator = iter;
1954 block->block = gfc_get_code (EXEC_DO);
1956 /* Offset calculation. */
1957 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
1958 byte_stride, rank, block->block,
1959 sub_ns);
1961 /* Create code for
1962 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1963 + offset, c_ptr), ptr). */
1964 block->next
1965 = finalization_scalarizer (array, ptr,
1966 gfc_lval_expr_from_sym (offset),
1967 sub_ns);
1968 block = block->next;
1970 /* CALL final_elemental (array). */
1971 block->next = gfc_get_code (EXEC_CALL);
1972 block = block->next;
1973 block->symtree = fini_elem->proc_tree;
1974 block->resolved_sym = fini_elem->proc_sym;
1975 block->ext.actual = gfc_get_actual_arglist ();
1976 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
1980 /* Finalize and deallocate allocatable components. The same manual
1981 scalarization is used as above. */
1983 if (finalizable_comp)
1985 gfc_symbol *stat;
1986 gfc_code *block = NULL;
1988 if (!ptr)
1990 gfc_get_symbol ("ptr", sub_ns, &ptr);
1991 ptr->ts.type = BT_DERIVED;
1992 ptr->ts.u.derived = derived;
1993 ptr->attr.flavor = FL_VARIABLE;
1994 ptr->attr.pointer = 1;
1995 ptr->attr.artificial = 1;
1996 gfc_set_sym_referenced (ptr);
1997 gfc_commit_symbol (ptr);
2000 gfc_get_symbol ("ignore", sub_ns, &stat);
2001 stat->attr.flavor = FL_VARIABLE;
2002 stat->attr.artificial = 1;
2003 stat->ts.type = BT_INTEGER;
2004 stat->ts.kind = gfc_default_integer_kind;
2005 gfc_set_sym_referenced (stat);
2006 gfc_commit_symbol (stat);
2008 /* Create loop. */
2009 iter = gfc_get_iterator ();
2010 iter->var = gfc_lval_expr_from_sym (idx);
2011 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2012 iter->end = gfc_lval_expr_from_sym (nelem);
2013 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2014 last_code->next = gfc_get_code (EXEC_DO);
2015 last_code = last_code->next;
2016 last_code->ext.iterator = iter;
2017 last_code->block = gfc_get_code (EXEC_DO);
2019 /* Offset calculation. */
2020 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2021 byte_stride, rank, last_code->block,
2022 sub_ns);
2024 /* Create code for
2025 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2026 + idx * stride, c_ptr), ptr). */
2027 block->next = finalization_scalarizer (array, ptr,
2028 gfc_lval_expr_from_sym(offset),
2029 sub_ns);
2030 block = block->next;
2032 for (comp = derived->components; comp; comp = comp->next)
2034 if (comp == derived->components && derived->attr.extension
2035 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2036 continue;
2038 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2039 stat, fini_coarray, &block);
2040 if (!last_code->block->next)
2041 last_code->block->next = block;
2046 /* Call the finalizer of the ancestor. */
2047 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2049 last_code->next = gfc_get_code (EXEC_CALL);
2050 last_code = last_code->next;
2051 last_code->symtree = ancestor_wrapper->symtree;
2052 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2054 last_code->ext.actual = gfc_get_actual_arglist ();
2055 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2056 last_code->ext.actual->next = gfc_get_actual_arglist ();
2057 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2058 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2059 last_code->ext.actual->next->next->expr
2060 = gfc_lval_expr_from_sym (fini_coarray);
2063 gfc_free_expr (rank);
2064 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2065 vtab_final->ts.interface = final;
2069 /* Add procedure pointers for all type-bound procedures to a vtab. */
2071 static void
2072 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2074 gfc_symbol* super_type;
2076 super_type = gfc_get_derived_super_type (derived);
2078 if (super_type && (super_type != derived))
2080 /* Make sure that the PPCs appear in the same order as in the parent. */
2081 copy_vtab_proc_comps (super_type, vtype);
2082 /* Only needed to get the PPC initializers right. */
2083 add_procs_to_declared_vtab (super_type, vtype);
2086 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2087 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2089 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2090 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2094 /* Find or generate the symbol for a derived type's vtab. */
2096 gfc_symbol *
2097 gfc_find_derived_vtab (gfc_symbol *derived)
2099 gfc_namespace *ns;
2100 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2101 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2103 /* Find the top-level namespace. */
2104 for (ns = gfc_current_ns; ns; ns = ns->parent)
2105 if (!ns->parent)
2106 break;
2108 /* If the type is a class container, use the underlying derived type. */
2109 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2110 derived = gfc_get_derived_super_type (derived);
2112 if (ns)
2114 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2116 get_unique_hashed_string (tname, derived);
2117 sprintf (name, "__vtab_%s", tname);
2119 /* Look for the vtab symbol in various namespaces. */
2120 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2121 if (vtab == NULL)
2122 gfc_find_symbol (name, ns, 0, &vtab);
2123 if (vtab == NULL)
2124 gfc_find_symbol (name, derived->ns, 0, &vtab);
2126 if (vtab == NULL)
2128 gfc_get_symbol (name, ns, &vtab);
2129 vtab->ts.type = BT_DERIVED;
2130 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2131 &gfc_current_locus))
2132 goto cleanup;
2133 vtab->attr.target = 1;
2134 vtab->attr.save = SAVE_IMPLICIT;
2135 vtab->attr.vtab = 1;
2136 vtab->attr.access = ACCESS_PUBLIC;
2137 gfc_set_sym_referenced (vtab);
2138 sprintf (name, "__vtype_%s", tname);
2140 gfc_find_symbol (name, ns, 0, &vtype);
2141 if (vtype == NULL)
2143 gfc_component *c;
2144 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2146 gfc_get_symbol (name, ns, &vtype);
2147 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2148 &gfc_current_locus))
2149 goto cleanup;
2150 vtype->attr.access = ACCESS_PUBLIC;
2151 vtype->attr.vtype = 1;
2152 gfc_set_sym_referenced (vtype);
2154 /* Add component '_hash'. */
2155 if (!gfc_add_component (vtype, "_hash", &c))
2156 goto cleanup;
2157 c->ts.type = BT_INTEGER;
2158 c->ts.kind = 4;
2159 c->attr.access = ACCESS_PRIVATE;
2160 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2161 NULL, derived->hash_value);
2163 /* Add component '_size'. */
2164 if (!gfc_add_component (vtype, "_size", &c))
2165 goto cleanup;
2166 c->ts.type = BT_INTEGER;
2167 c->ts.kind = 4;
2168 c->attr.access = ACCESS_PRIVATE;
2169 /* Remember the derived type in ts.u.derived,
2170 so that the correct initializer can be set later on
2171 (in gfc_conv_structure). */
2172 c->ts.u.derived = derived;
2173 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2174 NULL, 0);
2176 /* Add component _extends. */
2177 if (!gfc_add_component (vtype, "_extends", &c))
2178 goto cleanup;
2179 c->attr.pointer = 1;
2180 c->attr.access = ACCESS_PRIVATE;
2181 if (!derived->attr.unlimited_polymorphic)
2182 parent = gfc_get_derived_super_type (derived);
2183 else
2184 parent = NULL;
2186 if (parent)
2188 parent_vtab = gfc_find_derived_vtab (parent);
2189 c->ts.type = BT_DERIVED;
2190 c->ts.u.derived = parent_vtab->ts.u.derived;
2191 c->initializer = gfc_get_expr ();
2192 c->initializer->expr_type = EXPR_VARIABLE;
2193 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2194 0, &c->initializer->symtree);
2196 else
2198 c->ts.type = BT_DERIVED;
2199 c->ts.u.derived = vtype;
2200 c->initializer = gfc_get_null_expr (NULL);
2203 if (!derived->attr.unlimited_polymorphic
2204 && derived->components == NULL
2205 && !derived->attr.zero_comp)
2207 /* At this point an error must have occurred.
2208 Prevent further errors on the vtype components. */
2209 found_sym = vtab;
2210 goto have_vtype;
2213 /* Add component _def_init. */
2214 if (!gfc_add_component (vtype, "_def_init", &c))
2215 goto cleanup;
2216 c->attr.pointer = 1;
2217 c->attr.artificial = 1;
2218 c->attr.access = ACCESS_PRIVATE;
2219 c->ts.type = BT_DERIVED;
2220 c->ts.u.derived = derived;
2221 if (derived->attr.unlimited_polymorphic
2222 || derived->attr.abstract)
2223 c->initializer = gfc_get_null_expr (NULL);
2224 else
2226 /* Construct default initialization variable. */
2227 sprintf (name, "__def_init_%s", tname);
2228 gfc_get_symbol (name, ns, &def_init);
2229 def_init->attr.target = 1;
2230 def_init->attr.artificial = 1;
2231 def_init->attr.save = SAVE_IMPLICIT;
2232 def_init->attr.access = ACCESS_PUBLIC;
2233 def_init->attr.flavor = FL_VARIABLE;
2234 gfc_set_sym_referenced (def_init);
2235 def_init->ts.type = BT_DERIVED;
2236 def_init->ts.u.derived = derived;
2237 def_init->value = gfc_default_initializer (&def_init->ts);
2239 c->initializer = gfc_lval_expr_from_sym (def_init);
2242 /* Add component _copy. */
2243 if (!gfc_add_component (vtype, "_copy", &c))
2244 goto cleanup;
2245 c->attr.proc_pointer = 1;
2246 c->attr.access = ACCESS_PRIVATE;
2247 c->tb = XCNEW (gfc_typebound_proc);
2248 c->tb->ppc = 1;
2249 if (derived->attr.unlimited_polymorphic
2250 || derived->attr.abstract)
2251 c->initializer = gfc_get_null_expr (NULL);
2252 else
2254 /* Set up namespace. */
2255 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2256 sub_ns->sibling = ns->contained;
2257 ns->contained = sub_ns;
2258 sub_ns->resolved = 1;
2259 /* Set up procedure symbol. */
2260 sprintf (name, "__copy_%s", tname);
2261 gfc_get_symbol (name, sub_ns, &copy);
2262 sub_ns->proc_name = copy;
2263 copy->attr.flavor = FL_PROCEDURE;
2264 copy->attr.subroutine = 1;
2265 copy->attr.pure = 1;
2266 copy->attr.artificial = 1;
2267 copy->attr.if_source = IFSRC_DECL;
2268 /* This is elemental so that arrays are automatically
2269 treated correctly by the scalarizer. */
2270 copy->attr.elemental = 1;
2271 if (ns->proc_name->attr.flavor == FL_MODULE)
2272 copy->module = ns->proc_name->name;
2273 gfc_set_sym_referenced (copy);
2274 /* Set up formal arguments. */
2275 gfc_get_symbol ("src", sub_ns, &src);
2276 src->ts.type = BT_DERIVED;
2277 src->ts.u.derived = derived;
2278 src->attr.flavor = FL_VARIABLE;
2279 src->attr.dummy = 1;
2280 src->attr.artificial = 1;
2281 src->attr.intent = INTENT_IN;
2282 gfc_set_sym_referenced (src);
2283 copy->formal = gfc_get_formal_arglist ();
2284 copy->formal->sym = src;
2285 gfc_get_symbol ("dst", sub_ns, &dst);
2286 dst->ts.type = BT_DERIVED;
2287 dst->ts.u.derived = derived;
2288 dst->attr.flavor = FL_VARIABLE;
2289 dst->attr.dummy = 1;
2290 dst->attr.artificial = 1;
2291 dst->attr.intent = INTENT_INOUT;
2292 gfc_set_sym_referenced (dst);
2293 copy->formal->next = gfc_get_formal_arglist ();
2294 copy->formal->next->sym = dst;
2295 /* Set up code. */
2296 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2297 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2298 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2299 /* Set initializer. */
2300 c->initializer = gfc_lval_expr_from_sym (copy);
2301 c->ts.interface = copy;
2304 /* Add component _final, which contains a procedure pointer to
2305 a wrapper which handles both the freeing of allocatable
2306 components and the calls to finalization subroutines.
2307 Note: The actual wrapper function can only be generated
2308 at resolution time. */
2309 if (!gfc_add_component (vtype, "_final", &c))
2310 goto cleanup;
2311 c->attr.proc_pointer = 1;
2312 c->attr.access = ACCESS_PRIVATE;
2313 c->tb = XCNEW (gfc_typebound_proc);
2314 c->tb->ppc = 1;
2315 generate_finalization_wrapper (derived, ns, tname, c);
2317 /* Add procedure pointers for type-bound procedures. */
2318 if (!derived->attr.unlimited_polymorphic)
2319 add_procs_to_declared_vtab (derived, vtype);
2322 have_vtype:
2323 vtab->ts.u.derived = vtype;
2324 vtab->value = gfc_default_initializer (&vtab->ts);
2328 found_sym = vtab;
2330 cleanup:
2331 /* It is unexpected to have some symbols added at resolution or code
2332 generation time. We commit the changes in order to keep a clean state. */
2333 if (found_sym)
2335 gfc_commit_symbol (vtab);
2336 if (vtype)
2337 gfc_commit_symbol (vtype);
2338 if (def_init)
2339 gfc_commit_symbol (def_init);
2340 if (copy)
2341 gfc_commit_symbol (copy);
2342 if (src)
2343 gfc_commit_symbol (src);
2344 if (dst)
2345 gfc_commit_symbol (dst);
2347 else
2348 gfc_undo_symbols ();
2350 return found_sym;
2354 /* Check if a derived type is finalizable. That is the case if it
2355 (1) has a FINAL subroutine or
2356 (2) has a nonpointer nonallocatable component of finalizable type.
2357 If it is finalizable, return an expression containing the
2358 finalization wrapper. */
2360 bool
2361 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2363 gfc_symbol *vtab;
2364 gfc_component *c;
2366 /* (1) Check for FINAL subroutines. */
2367 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2368 goto yes;
2370 /* (2) Check for components of finalizable type. */
2371 for (c = derived->components; c; c = c->next)
2372 if (c->ts.type == BT_DERIVED
2373 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2374 && gfc_is_finalizable (c->ts.u.derived, NULL))
2375 goto yes;
2377 return false;
2379 yes:
2380 /* Make sure vtab is generated. */
2381 vtab = gfc_find_derived_vtab (derived);
2382 if (final_expr)
2384 /* Return finalizer expression. */
2385 gfc_component *final;
2386 final = vtab->ts.u.derived->components->next->next->next->next->next;
2387 gcc_assert (strcmp (final->name, "_final") == 0);
2388 gcc_assert (final->initializer
2389 && final->initializer->expr_type != EXPR_NULL);
2390 *final_expr = final->initializer;
2392 return true;
2396 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2397 need to support unlimited polymorphism. */
2399 gfc_symbol *
2400 gfc_find_intrinsic_vtab (gfc_typespec *ts)
2402 gfc_namespace *ns;
2403 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2404 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2405 int charlen = 0;
2407 if (ts->type == BT_CHARACTER && ts->deferred)
2409 gfc_error ("TODO: Deferred character length variable at %C cannot "
2410 "yet be associated with unlimited polymorphic entities");
2411 return NULL;
2414 if (ts->type == BT_UNKNOWN)
2415 return NULL;
2417 /* Sometimes the typespec is passed from a single call. */
2418 if (ts->type == BT_DERIVED)
2419 return gfc_find_derived_vtab (ts->u.derived);
2421 /* Find the top-level namespace. */
2422 for (ns = gfc_current_ns; ns; ns = ns->parent)
2423 if (!ns->parent)
2424 break;
2426 if (ts->type == BT_CHARACTER && ts->u.cl && ts->u.cl->length
2427 && ts->u.cl->length->expr_type == EXPR_CONSTANT)
2428 charlen = mpz_get_si (ts->u.cl->length->value.integer);
2430 if (ns)
2432 char name[GFC_MAX_SYMBOL_LEN+1], tname[GFC_MAX_SYMBOL_LEN+1];
2434 if (ts->type == BT_CHARACTER)
2435 sprintf (tname, "%s_%d_%d", gfc_basic_typename (ts->type),
2436 charlen, ts->kind);
2437 else
2438 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2440 sprintf (name, "__vtab_%s", tname);
2442 /* Look for the vtab symbol in various namespaces. */
2443 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2444 if (vtab == NULL)
2445 gfc_find_symbol (name, ns, 0, &vtab);
2447 if (vtab == NULL)
2449 gfc_get_symbol (name, ns, &vtab);
2450 vtab->ts.type = BT_DERIVED;
2451 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2452 &gfc_current_locus))
2453 goto cleanup;
2454 vtab->attr.target = 1;
2455 vtab->attr.save = SAVE_IMPLICIT;
2456 vtab->attr.vtab = 1;
2457 vtab->attr.access = ACCESS_PUBLIC;
2458 gfc_set_sym_referenced (vtab);
2459 sprintf (name, "__vtype_%s", tname);
2461 gfc_find_symbol (name, ns, 0, &vtype);
2462 if (vtype == NULL)
2464 gfc_component *c;
2465 int hash;
2466 gfc_namespace *sub_ns;
2467 gfc_namespace *contained;
2469 gfc_get_symbol (name, ns, &vtype);
2470 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2471 &gfc_current_locus))
2472 goto cleanup;
2473 vtype->attr.access = ACCESS_PUBLIC;
2474 vtype->attr.vtype = 1;
2475 gfc_set_sym_referenced (vtype);
2477 /* Add component '_hash'. */
2478 if (!gfc_add_component (vtype, "_hash", &c))
2479 goto cleanup;
2480 c->ts.type = BT_INTEGER;
2481 c->ts.kind = 4;
2482 c->attr.access = ACCESS_PRIVATE;
2483 hash = gfc_intrinsic_hash_value (ts);
2484 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2485 NULL, hash);
2487 /* Add component '_size'. */
2488 if (!gfc_add_component (vtype, "_size", &c))
2489 goto cleanup;
2490 c->ts.type = BT_INTEGER;
2491 c->ts.kind = 4;
2492 c->attr.access = ACCESS_PRIVATE;
2493 if (ts->type == BT_CHARACTER)
2494 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2495 NULL, charlen*ts->kind);
2496 else
2497 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2498 NULL, ts->kind);
2500 /* Add component _extends. */
2501 if (!gfc_add_component (vtype, "_extends", &c))
2502 goto cleanup;
2503 c->attr.pointer = 1;
2504 c->attr.access = ACCESS_PRIVATE;
2505 c->ts.type = BT_VOID;
2506 c->initializer = gfc_get_null_expr (NULL);
2508 /* Add component _def_init. */
2509 if (!gfc_add_component (vtype, "_def_init", &c))
2510 goto cleanup;
2511 c->attr.pointer = 1;
2512 c->attr.access = ACCESS_PRIVATE;
2513 c->ts.type = BT_VOID;
2514 c->initializer = gfc_get_null_expr (NULL);
2516 /* Add component _copy. */
2517 if (!gfc_add_component (vtype, "_copy", &c))
2518 goto cleanup;
2519 c->attr.proc_pointer = 1;
2520 c->attr.access = ACCESS_PRIVATE;
2521 c->tb = XCNEW (gfc_typebound_proc);
2522 c->tb->ppc = 1;
2524 /* Check to see if copy function already exists. Note
2525 that this is only used for characters of different
2526 lengths. */
2527 contained = ns->contained;
2528 for (; contained; contained = contained->sibling)
2529 if (contained->proc_name
2530 && strcmp (name, contained->proc_name->name) == 0)
2532 copy = contained->proc_name;
2533 goto got_char_copy;
2536 /* Set up namespace. */
2537 sub_ns = gfc_get_namespace (ns, 0);
2538 sub_ns->sibling = ns->contained;
2539 ns->contained = sub_ns;
2540 sub_ns->resolved = 1;
2541 /* Set up procedure symbol. */
2542 if (ts->type != BT_CHARACTER)
2543 sprintf (name, "__copy_%s", tname);
2544 else
2545 /* __copy is always the same for characters. */
2546 sprintf (name, "__copy_character_%d", ts->kind);
2547 gfc_get_symbol (name, sub_ns, &copy);
2548 sub_ns->proc_name = copy;
2549 copy->attr.flavor = FL_PROCEDURE;
2550 copy->attr.subroutine = 1;
2551 copy->attr.pure = 1;
2552 copy->attr.if_source = IFSRC_DECL;
2553 /* This is elemental so that arrays are automatically
2554 treated correctly by the scalarizer. */
2555 copy->attr.elemental = 1;
2556 if (ns->proc_name->attr.flavor == FL_MODULE)
2557 copy->module = ns->proc_name->name;
2558 gfc_set_sym_referenced (copy);
2559 /* Set up formal arguments. */
2560 gfc_get_symbol ("src", sub_ns, &src);
2561 src->ts.type = ts->type;
2562 src->ts.kind = ts->kind;
2563 src->attr.flavor = FL_VARIABLE;
2564 src->attr.dummy = 1;
2565 src->attr.intent = INTENT_IN;
2566 gfc_set_sym_referenced (src);
2567 copy->formal = gfc_get_formal_arglist ();
2568 copy->formal->sym = src;
2569 gfc_get_symbol ("dst", sub_ns, &dst);
2570 dst->ts.type = ts->type;
2571 dst->ts.kind = ts->kind;
2572 dst->attr.flavor = FL_VARIABLE;
2573 dst->attr.dummy = 1;
2574 dst->attr.intent = INTENT_INOUT;
2575 gfc_set_sym_referenced (dst);
2576 copy->formal->next = gfc_get_formal_arglist ();
2577 copy->formal->next->sym = dst;
2578 /* Set up code. */
2579 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2580 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2581 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2582 got_char_copy:
2583 /* Set initializer. */
2584 c->initializer = gfc_lval_expr_from_sym (copy);
2585 c->ts.interface = copy;
2587 /* Add component _final. */
2588 if (!gfc_add_component (vtype, "_final", &c))
2589 goto cleanup;
2590 c->attr.proc_pointer = 1;
2591 c->attr.access = ACCESS_PRIVATE;
2592 c->tb = XCNEW (gfc_typebound_proc);
2593 c->tb->ppc = 1;
2594 c->initializer = gfc_get_null_expr (NULL);
2596 vtab->ts.u.derived = vtype;
2597 vtab->value = gfc_default_initializer (&vtab->ts);
2601 found_sym = vtab;
2603 cleanup:
2604 /* It is unexpected to have some symbols added at resolution or code
2605 generation time. We commit the changes in order to keep a clean state. */
2606 if (found_sym)
2608 gfc_commit_symbol (vtab);
2609 if (vtype)
2610 gfc_commit_symbol (vtype);
2611 if (copy)
2612 gfc_commit_symbol (copy);
2613 if (src)
2614 gfc_commit_symbol (src);
2615 if (dst)
2616 gfc_commit_symbol (dst);
2618 else
2619 gfc_undo_symbols ();
2621 return found_sym;
2625 /* General worker function to find either a type-bound procedure or a
2626 type-bound user operator. */
2628 static gfc_symtree*
2629 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
2630 const char* name, bool noaccess, bool uop,
2631 locus* where)
2633 gfc_symtree* res;
2634 gfc_symtree* root;
2636 /* Set default to failure. */
2637 if (t)
2638 *t = false;
2640 if (derived->f2k_derived)
2641 /* Set correct symbol-root. */
2642 root = (uop ? derived->f2k_derived->tb_uop_root
2643 : derived->f2k_derived->tb_sym_root);
2644 else
2645 return NULL;
2647 /* Try to find it in the current type's namespace. */
2648 res = gfc_find_symtree (root, name);
2649 if (res && res->n.tb && !res->n.tb->error)
2651 /* We found one. */
2652 if (t)
2653 *t = true;
2655 if (!noaccess && derived->attr.use_assoc
2656 && res->n.tb->access == ACCESS_PRIVATE)
2658 if (where)
2659 gfc_error ("'%s' of '%s' is PRIVATE at %L",
2660 name, derived->name, where);
2661 if (t)
2662 *t = false;
2665 return res;
2668 /* Otherwise, recurse on parent type if derived is an extension. */
2669 if (derived->attr.extension)
2671 gfc_symbol* super_type;
2672 super_type = gfc_get_derived_super_type (derived);
2673 gcc_assert (super_type);
2675 return find_typebound_proc_uop (super_type, t, name,
2676 noaccess, uop, where);
2679 /* Nothing found. */
2680 return NULL;
2684 /* Find a type-bound procedure or user operator by name for a derived-type
2685 (looking recursively through the super-types). */
2687 gfc_symtree*
2688 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
2689 const char* name, bool noaccess, locus* where)
2691 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2694 gfc_symtree*
2695 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
2696 const char* name, bool noaccess, locus* where)
2698 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2702 /* Find a type-bound intrinsic operator looking recursively through the
2703 super-type hierarchy. */
2705 gfc_typebound_proc*
2706 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
2707 gfc_intrinsic_op op, bool noaccess,
2708 locus* where)
2710 gfc_typebound_proc* res;
2712 /* Set default to failure. */
2713 if (t)
2714 *t = false;
2716 /* Try to find it in the current type's namespace. */
2717 if (derived->f2k_derived)
2718 res = derived->f2k_derived->tb_op[op];
2719 else
2720 res = NULL;
2722 /* Check access. */
2723 if (res && !res->error)
2725 /* We found one. */
2726 if (t)
2727 *t = true;
2729 if (!noaccess && derived->attr.use_assoc
2730 && res->access == ACCESS_PRIVATE)
2732 if (where)
2733 gfc_error ("'%s' of '%s' is PRIVATE at %L",
2734 gfc_op2string (op), derived->name, where);
2735 if (t)
2736 *t = false;
2739 return res;
2742 /* Otherwise, recurse on parent type if derived is an extension. */
2743 if (derived->attr.extension)
2745 gfc_symbol* super_type;
2746 super_type = gfc_get_derived_super_type (derived);
2747 gcc_assert (super_type);
2749 return gfc_find_typebound_intrinsic_op (super_type, t, op,
2750 noaccess, where);
2753 /* Nothing found. */
2754 return NULL;
2758 /* Get a typebound-procedure symtree or create and insert it if not yet
2759 present. This is like a very simplified version of gfc_get_sym_tree for
2760 tbp-symtrees rather than regular ones. */
2762 gfc_symtree*
2763 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
2765 gfc_symtree *result;
2767 result = gfc_find_symtree (*root, name);
2768 if (!result)
2770 result = gfc_new_symtree (root, name);
2771 gcc_assert (result);
2772 result->n.tb = NULL;
2775 return result;