libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / fortran / class.cc
blobf9e0d416e487624a0307aa31439bca9c8f4cd50f
1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2024 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.cc -- This file contains the front end functions needed to service
24 the implementation of Fortran 2003 polymorphism and other
25 object-oriented features. */
28 /* Outline of the internal representation:
30 Each CLASS variable is encapsulated by a class container, which is a
31 structure with two fields:
32 * _data: A pointer to the actual data of the variable. This field has the
33 declared type of the class variable and its attributes
34 (pointer/allocatable/dimension/...).
35 * _vptr: A pointer to the vtable entry (see below) of the dynamic type.
37 Only for unlimited polymorphic classes:
38 * _len: An integer(C_SIZE_T) to store the string length when the unlimited
39 polymorphic pointer is used to point to a char array. The '_len'
40 component will be zero when no character array is stored in
41 '_data'.
43 For each derived type we set up a "vtable" entry, i.e. a structure with the
44 following fields:
45 * _hash: A hash value serving as a unique identifier for this type.
46 * _size: The size in bytes of the derived type.
47 * _extends: A pointer to the vtable entry of the parent derived type.
48 * _def_init: A pointer to a default initialized variable of this type.
49 * _copy: A procedure pointer to a copying procedure.
50 * _final: A procedure pointer to a wrapper function, which frees
51 allocatable components and calls FINAL subroutines.
52 * _deallocate: A procedure pointer to a deallocation procedure; nonnull
53 only for a recursive derived type.
55 After these follow procedure pointer components for the specific
56 type-bound procedures. */
59 #include "config.h"
60 #include "system.h"
61 #include "coretypes.h"
62 #include "gfortran.h"
63 #include "constructor.h"
64 #include "target-memory.h"
66 /* Inserts a derived type component reference in a data reference chain.
67 TS: base type of the ref chain so far, in which we will pick the component
68 REF: the address of the GFC_REF pointer to update
69 NAME: name of the component to insert
70 Note that component insertion makes sense only if we are at the end of
71 the chain (*REF == NULL) or if we are adding a missing "_data" component
72 to access the actual contents of a class object. */
74 static void
75 insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
77 gfc_ref *new_ref;
78 int wcnt, ecnt;
80 gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
82 gfc_find_component (ts->u.derived, name, true, true, &new_ref);
84 gfc_get_errors (&wcnt, &ecnt);
85 if (ecnt > 0 && !new_ref)
86 return;
87 gcc_assert (new_ref->u.c.component);
89 while (new_ref->next)
90 new_ref = new_ref->next;
91 new_ref->next = *ref;
93 if (new_ref->next)
95 gfc_ref *next = NULL;
97 /* We need to update the base type in the trailing reference chain to
98 that of the new component. */
100 gcc_assert (strcmp (name, "_data") == 0);
102 if (new_ref->next->type == REF_COMPONENT)
103 next = new_ref->next;
104 else if (new_ref->next->type == REF_ARRAY
105 && new_ref->next->next
106 && new_ref->next->next->type == REF_COMPONENT)
107 next = new_ref->next->next;
109 if (next != NULL)
111 gcc_assert (new_ref->u.c.component->ts.type == BT_CLASS
112 || new_ref->u.c.component->ts.type == BT_DERIVED);
113 next->u.c.sym = new_ref->u.c.component->ts.u.derived;
117 *ref = new_ref;
121 /* Tells whether we need to add a "_data" reference to access REF subobject
122 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base
123 object accessed by REF is a variable; in other words it is a full object,
124 not a subobject. */
126 static bool
127 class_data_ref_missing (gfc_typespec *ts, gfc_ref *ref, bool first_ref_in_chain)
129 /* Only class containers may need the "_data" reference. */
130 if (ts->type != BT_CLASS)
131 return false;
133 /* Accessing a class container with an array reference is certainly wrong. */
134 if (ref->type != REF_COMPONENT)
135 return true;
137 /* Accessing the class container's fields is fine. */
138 if (ref->u.c.component->name[0] == '_')
139 return false;
141 /* At this point we have a class container with a non class container's field
142 component reference. We don't want to add the "_data" component if we are
143 at the first reference and the symbol's type is an extended derived type.
144 In that case, conv_parent_component_references will do the right thing so
145 it is not absolutely necessary. Omitting it prevents a regression (see
146 class_41.f03) in the interface mapping mechanism. When evaluating string
147 lengths depending on dummy arguments, we create a fake symbol with a type
148 equal to that of the dummy type. However, because of type extension,
149 the backend type (corresponding to the actual argument) can have a
150 different (extended) type. Adding the "_data" component explicitly, using
151 the base type, confuses the gfc_conv_component_ref code which deals with
152 the extended type. */
153 if (first_ref_in_chain && ts->u.derived->attr.extension)
154 return false;
156 /* We have a class container with a non class container's field component
157 reference that doesn't fall into the above. */
158 return true;
162 /* Browse through a data reference chain and add the missing "_data" references
163 when a subobject of a class object is accessed without it.
164 Note that it doesn't add the "_data" reference when the class container
165 is the last element in the reference chain. */
167 void
168 gfc_fix_class_refs (gfc_expr *e)
170 gfc_typespec *ts;
171 gfc_ref **ref;
173 if ((e->expr_type != EXPR_VARIABLE
174 && e->expr_type != EXPR_FUNCTION)
175 || (e->expr_type == EXPR_FUNCTION
176 && e->value.function.isym != NULL))
177 return;
179 if (e->expr_type == EXPR_VARIABLE)
180 ts = &e->symtree->n.sym->ts;
181 else
183 gfc_symbol *func;
185 gcc_assert (e->expr_type == EXPR_FUNCTION);
186 if (e->value.function.esym != NULL)
187 func = e->value.function.esym;
188 else
189 func = e->symtree->n.sym;
191 if (func->result != NULL)
192 ts = &func->result->ts;
193 else
194 ts = &func->ts;
197 for (ref = &e->ref; *ref != NULL; ref = &(*ref)->next)
199 if (class_data_ref_missing (ts, *ref, ref == &e->ref))
200 insert_component_ref (ts, ref, "_data");
202 if ((*ref)->type == REF_COMPONENT)
203 ts = &(*ref)->u.c.component->ts;
208 /* Insert a reference to the component of the given name.
209 Only to be used with CLASS containers and vtables. */
211 void
212 gfc_add_component_ref (gfc_expr *e, const char *name)
214 gfc_component *c;
215 gfc_ref **tail = &(e->ref);
216 gfc_ref *ref, *next = NULL;
217 gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
218 while (*tail != NULL)
220 if ((*tail)->type == REF_COMPONENT)
222 if (strcmp ((*tail)->u.c.component->name, "_data") == 0
223 && (*tail)->next
224 && (*tail)->next->type == REF_ARRAY
225 && (*tail)->next->next == NULL)
226 return;
227 derived = (*tail)->u.c.component->ts.u.derived;
229 if ((*tail)->type == REF_ARRAY && (*tail)->next == NULL)
230 break;
231 tail = &((*tail)->next);
233 if (derived && derived->components && derived->components->next &&
234 derived->components->next->ts.type == BT_DERIVED &&
235 derived->components->next->ts.u.derived == NULL)
237 /* Fix up missing vtype. */
238 gfc_symbol *vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
239 gcc_assert (vtab);
240 derived->components->next->ts.u.derived = vtab->ts.u.derived;
242 if (*tail != NULL && strcmp (name, "_data") == 0)
243 next = *tail;
244 else
245 /* Avoid losing memory. */
246 gfc_free_ref_list (*tail);
247 c = gfc_find_component (derived, name, true, true, tail);
249 if (c) {
250 for (ref = *tail; ref->next; ref = ref->next)
252 ref->next = next;
253 if (!next)
254 e->ts = c->ts;
259 /* This is used to add both the _data component reference and an array
260 reference to class expressions. Used in translation of intrinsic
261 array inquiry functions. */
263 void
264 gfc_add_class_array_ref (gfc_expr *e)
266 int rank = CLASS_DATA (e)->as->rank;
267 int corank = CLASS_DATA (e)->as->corank;
268 gfc_array_spec *as = CLASS_DATA (e)->as;
269 gfc_ref *ref = NULL;
270 gfc_add_data_component (e);
271 e->rank = rank;
272 e->corank = corank;
273 for (ref = e->ref; ref; ref = ref->next)
274 if (!ref->next)
275 break;
276 if (ref->type != REF_ARRAY)
278 ref->next = gfc_get_ref ();
279 ref = ref->next;
280 ref->type = REF_ARRAY;
281 ref->u.ar.type = AR_FULL;
282 ref->u.ar.as = as;
287 /* Unfortunately, class array expressions can appear in various conditions;
288 with and without both _data component and an arrayspec. This function
289 deals with that variability. The previous reference to 'ref' is to a
290 class array. */
292 static bool
293 class_array_ref_detected (gfc_ref *ref, bool *full_array)
295 bool no_data = false;
296 bool with_data = false;
298 /* An array reference with no _data component. */
299 if (ref && ref->type == REF_ARRAY
300 && !ref->next
301 && ref->u.ar.type != AR_ELEMENT)
303 if (full_array)
304 *full_array = ref->u.ar.type == AR_FULL;
305 no_data = true;
308 /* Cover cases where _data appears, with or without an array ref. */
309 if (ref && ref->type == REF_COMPONENT
310 && strcmp (ref->u.c.component->name, "_data") == 0)
312 if (!ref->next)
314 with_data = true;
315 if (full_array)
316 *full_array = true;
318 else if (ref->next && ref->next->type == REF_ARRAY
319 && ref->type == REF_COMPONENT
320 && ref->next->u.ar.type != AR_ELEMENT)
322 with_data = true;
323 if (full_array)
324 *full_array = ref->next->u.ar.type == AR_FULL;
328 return no_data || with_data;
332 /* Returns true if the expression contains a reference to a class
333 array. Notice that class array elements return false. */
335 bool
336 gfc_is_class_array_ref (gfc_expr *e, bool *full_array)
338 gfc_ref *ref;
340 if (!e->rank)
341 return false;
343 if (full_array)
344 *full_array= false;
346 /* Is this a class array object? ie. Is the symbol of type class? */
347 if (e->symtree
348 && e->symtree->n.sym->ts.type == BT_CLASS
349 && CLASS_DATA (e->symtree->n.sym)
350 && CLASS_DATA (e->symtree->n.sym)->attr.dimension
351 && class_array_ref_detected (e->ref, full_array))
352 return true;
354 /* Or is this a class array component reference? */
355 for (ref = e->ref; ref; ref = ref->next)
357 if (ref->type == REF_COMPONENT
358 && ref->u.c.component->ts.type == BT_CLASS
359 && CLASS_DATA (ref->u.c.component)->attr.dimension
360 && class_array_ref_detected (ref->next, full_array))
361 return true;
364 return false;
368 /* Returns true if the expression is a reference to a class
369 scalar. This function is necessary because such expressions
370 can be dressed with a reference to the _data component and so
371 have a type other than BT_CLASS. */
373 bool
374 gfc_is_class_scalar_expr (gfc_expr *e)
376 gfc_ref *ref;
378 if (e->rank)
379 return false;
381 /* Is this a class object? */
382 if (e->symtree && e->symtree->n.sym->ts.type == BT_CLASS
383 && CLASS_DATA (e->symtree->n.sym)
384 && !CLASS_DATA (e->symtree->n.sym)->attr.dimension
385 && (e->ref == NULL
386 || (e->ref->type == REF_COMPONENT
387 && strcmp (e->ref->u.c.component->name, "_data") == 0
388 && (e->ref->next == NULL
389 || (e->ref->next->type == REF_ARRAY
390 && e->ref->next->u.ar.codimen > 0
391 && e->ref->next->u.ar.dimen == 0
392 && e->ref->next->next == NULL)))))
393 return true;
395 /* Or is the final reference BT_CLASS or _data? */
396 for (ref = e->ref; ref; ref = ref->next)
398 if (ref->type == REF_COMPONENT && ref->u.c.component->ts.type == BT_CLASS
399 && CLASS_DATA (ref->u.c.component)
400 && !CLASS_DATA (ref->u.c.component)->attr.dimension
401 && (ref->next == NULL
402 || (ref->next->type == REF_COMPONENT
403 && strcmp (ref->next->u.c.component->name, "_data") == 0
404 && (ref->next->next == NULL
405 || (ref->next->next->type == REF_ARRAY
406 && ref->next->next->u.ar.codimen > 0
407 && ref->next->next->u.ar.dimen == 0
408 && ref->next->next->next == NULL)))))
409 return true;
412 return false;
416 /* Tells whether the expression E is a reference to a (scalar) class container.
417 Scalar because array class containers usually have an array reference after
418 them, and gfc_fix_class_refs will add the missing "_data" component reference
419 in that case. */
421 bool
422 gfc_is_class_container_ref (gfc_expr *e)
424 gfc_ref *ref;
425 bool result;
427 if (e->expr_type != EXPR_VARIABLE)
428 return e->ts.type == BT_CLASS;
430 if (e->symtree->n.sym->ts.type == BT_CLASS)
431 result = true;
432 else
433 result = false;
435 for (ref = e->ref; ref; ref = ref->next)
437 if (ref->type != REF_COMPONENT)
438 result = false;
439 else if (ref->u.c.component->ts.type == BT_CLASS)
440 result = true;
441 else
442 result = false;
445 return result;
449 /* Build an initializer for CLASS pointers,
450 initializing the _data component to the init_expr (or NULL) and the _vptr
451 component to the corresponding type (or the declared type, given by ts). */
453 gfc_expr *
454 gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
456 gfc_expr *init;
457 gfc_component *comp;
458 gfc_symbol *vtab = NULL;
460 if (init_expr && init_expr->expr_type != EXPR_NULL)
461 vtab = gfc_find_vtab (&init_expr->ts);
462 else
463 vtab = gfc_find_vtab (ts);
465 init = gfc_get_structure_constructor_expr (ts->type, ts->kind,
466 &ts->u.derived->declared_at);
467 init->ts = *ts;
469 for (comp = ts->u.derived->components; comp; comp = comp->next)
471 gfc_constructor *ctor = gfc_constructor_get();
472 if (strcmp (comp->name, "_vptr") == 0 && vtab)
473 ctor->expr = gfc_lval_expr_from_sym (vtab);
474 else if (init_expr && init_expr->expr_type != EXPR_NULL)
475 ctor->expr = gfc_copy_expr (init_expr);
476 else
477 ctor->expr = gfc_get_null_expr (NULL);
478 gfc_constructor_append (&init->value.constructor, ctor);
481 return init;
485 /* Create a unique string identifier for a derived type, composed of its name
486 and module name. This is used to construct unique names for the class
487 containers and vtab symbols. */
489 static char *
490 get_unique_type_string (gfc_symbol *derived)
492 const char *dt_name;
493 char *string;
494 size_t len;
495 if (derived->attr.unlimited_polymorphic)
496 dt_name = "STAR";
497 else
498 dt_name = gfc_dt_upper_string (derived->name);
499 len = strlen (dt_name) + 2;
500 if (derived->attr.unlimited_polymorphic)
502 string = XNEWVEC (char, len);
503 sprintf (string, "_%s", dt_name);
505 else if (derived->module)
507 string = XNEWVEC (char, strlen (derived->module) + len);
508 sprintf (string, "%s_%s", derived->module, dt_name);
510 else if (derived->ns->proc_name)
512 string = XNEWVEC (char, strlen (derived->ns->proc_name->name) + len);
513 sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
515 else
517 string = XNEWVEC (char, len);
518 sprintf (string, "_%s", dt_name);
520 return string;
524 /* A relative of 'get_unique_type_string' which makes sure the generated
525 string will not be too long (replacing it by a hash string if needed). */
527 static void
528 get_unique_hashed_string (char *string, gfc_symbol *derived)
530 /* Provide sufficient space to hold "symbol.symbol_symbol". */
531 char *tmp;
532 tmp = get_unique_type_string (derived);
533 /* If string is too long, use hash value in hex representation (allow for
534 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
535 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
536 where %d is the (co)rank which can be up to n = 15. */
537 if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 15)
539 int h = gfc_hash_value (derived);
540 sprintf (string, "%X", h);
542 else
543 strcpy (string, tmp);
544 free (tmp);
548 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
550 unsigned int
551 gfc_hash_value (gfc_symbol *sym)
553 unsigned int hash = 0;
554 /* Provide sufficient space to hold "symbol.symbol_symbol". */
555 char *c;
556 int i, len;
558 c = get_unique_type_string (sym);
559 len = strlen (c);
561 for (i = 0; i < len; i++)
562 hash = (hash << 6) + (hash << 16) - hash + c[i];
564 free (c);
565 /* Return the hash but take the modulus for the sake of module read,
566 even though this slightly increases the chance of collision. */
567 return (hash % 100000000);
571 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
573 unsigned int
574 gfc_intrinsic_hash_value (gfc_typespec *ts)
576 unsigned int hash = 0;
577 const char *c = gfc_typename (ts, true);
578 int i, len;
580 len = strlen (c);
582 for (i = 0; i < len; i++)
583 hash = (hash << 6) + (hash << 16) - hash + c[i];
585 /* Return the hash but take the modulus for the sake of module read,
586 even though this slightly increases the chance of collision. */
587 return (hash % 100000000);
591 /* Get the _len component from a class/derived object storing a string.
592 For unlimited polymorphic entities a ref to the _data component is available
593 while a ref to the _len component is needed. This routine traverese the
594 ref-chain and strips the last ref to a _data from it replacing it with a
595 ref to the _len component. */
597 gfc_expr *
598 gfc_get_len_component (gfc_expr *e, int k)
600 gfc_expr *ptr;
601 gfc_ref *ref, **last;
603 ptr = gfc_copy_expr (e);
605 /* We need to remove the last _data component ref from ptr. */
606 last = &(ptr->ref);
607 ref = ptr->ref;
608 while (ref)
610 if (!ref->next
611 && ref->type == REF_COMPONENT
612 && strcmp ("_data", ref->u.c.component->name)== 0)
614 gfc_free_ref_list (ref);
615 *last = NULL;
616 break;
618 last = &(ref->next);
619 ref = ref->next;
621 /* And replace if with a ref to the _len component. */
622 gfc_add_len_component (ptr);
623 if (k != ptr->ts.kind)
625 gfc_typespec ts;
626 gfc_clear_ts (&ts);
627 ts.type = BT_INTEGER;
628 ts.kind = k;
629 gfc_convert_type_warn (ptr, &ts, 2, 0);
631 return ptr;
635 /* Build a polymorphic CLASS entity, using the symbol that comes from
636 build_sym. A CLASS entity is represented by an encapsulating type,
637 which contains the declared type as '_data' component, plus a pointer
638 component '_vptr' which determines the dynamic type. When this CLASS
639 entity is unlimited polymorphic, then also add a component '_len' to
640 store the length of string when that is stored in it. */
641 static int ctr = 0;
643 bool
644 gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
645 gfc_array_spec **as)
647 char tname[GFC_MAX_SYMBOL_LEN+1];
648 char *name;
649 gfc_typespec *orig_ts = ts;
650 gfc_symbol *fclass;
651 gfc_symbol *vtab;
652 gfc_component *c;
653 gfc_namespace *ns;
654 int rank;
656 gcc_assert (as);
658 /* We cannot build the class container now. */
659 if (attr->class_ok && (!ts->u.derived || !ts->u.derived->components))
660 return false;
662 /* Class container has already been built with same name. */
663 if (attr->class_ok
664 && ts->u.derived->components->attr.dimension >= attr->dimension
665 && ts->u.derived->components->attr.codimension >= attr->codimension
666 && ts->u.derived->components->attr.class_pointer >= attr->pointer
667 && ts->u.derived->components->attr.allocatable >= attr->allocatable)
668 return true;
669 if (attr->class_ok)
671 attr->dimension |= ts->u.derived->components->attr.dimension;
672 attr->codimension |= ts->u.derived->components->attr.codimension;
673 attr->pointer |= ts->u.derived->components->attr.class_pointer;
674 attr->allocatable |= ts->u.derived->components->attr.allocatable;
675 ts = &ts->u.derived->components->ts;
678 attr->class_ok = attr->dummy || attr->pointer || attr->allocatable
679 || attr->select_type_temporary || attr->associate_var;
681 if (!attr->class_ok)
682 /* We cannot build the class container yet. */
683 return true;
685 /* Determine the name of the encapsulating type. */
686 rank = !(*as) || (*as)->rank == -1 ? GFC_MAX_DIMENSIONS : (*as)->rank;
688 if (!ts->u.derived)
689 return false;
691 get_unique_hashed_string (tname, ts->u.derived);
692 if ((*as) && attr->allocatable)
693 name = xasprintf ("__class_%s_%d_%da", tname, rank, (*as)->corank);
694 else if ((*as) && attr->pointer)
695 name = xasprintf ("__class_%s_%d_%dp", tname, rank, (*as)->corank);
696 else if ((*as))
697 name = xasprintf ("__class_%s_%d_%dt", tname, rank, (*as)->corank);
698 else if (attr->pointer)
699 name = xasprintf ("__class_%s_p", tname);
700 else if (attr->allocatable)
701 name = xasprintf ("__class_%s_a", tname);
702 else
703 name = xasprintf ("__class_%s_t", tname);
705 if (ts->u.derived->attr.unlimited_polymorphic)
707 /* Find the top-level namespace. */
708 for (ns = gfc_current_ns; ns; ns = ns->parent)
709 if (!ns->parent)
710 break;
712 else
713 ns = ts->u.derived->ns;
715 /* Although this might seem to be counterintuitive, we can build separate
716 class types with different array specs because the TKR interface checks
717 work on the declared type. All array type other than deferred shape or
718 assumed rank are added to the function namespace to ensure that they
719 are properly distinguished. */
720 if (attr->dummy && (*as)
721 && ((!attr->codimension
722 && !((*as)->type == AS_DEFERRED || (*as)->type == AS_ASSUMED_RANK))
723 || (attr->codimension
724 && !((*as)->cotype == AS_DEFERRED
725 || (*as)->cotype == AS_ASSUMED_RANK))))
727 char *sname;
728 ns = gfc_current_ns;
729 gfc_find_symbol (name, ns, 0, &fclass);
730 /* If a local class type with this name already exists, update the
731 name with an index. */
732 if (fclass)
734 fclass = NULL;
735 sname = xasprintf ("%s_%d", name, ++ctr);
736 free (name);
737 name = sname;
740 else
741 gfc_find_symbol (name, ns, 0, &fclass);
743 if (fclass == NULL)
745 gfc_symtree *st;
746 /* If not there, create a new symbol. */
747 fclass = gfc_new_symbol (name, ns);
748 st = gfc_new_symtree (&ns->sym_root, name);
749 st->n.sym = fclass;
750 gfc_set_sym_referenced (fclass);
751 fclass->refs++;
752 fclass->ts.type = BT_UNKNOWN;
753 if (!ts->u.derived->attr.unlimited_polymorphic)
754 fclass->attr.abstract = ts->u.derived->attr.abstract;
755 fclass->f2k_derived = gfc_get_namespace (NULL, 0);
756 if (!gfc_add_flavor (&fclass->attr, FL_DERIVED, NULL,
757 &gfc_current_locus))
758 return false;
760 /* Add component '_data'. */
761 if (!gfc_add_component (fclass, "_data", &c))
762 return false;
763 c->ts = *ts;
764 c->ts.type = BT_DERIVED;
765 c->attr.access = ACCESS_PRIVATE;
766 c->ts.u.derived = ts->u.derived;
767 c->attr.class_pointer = attr->pointer;
768 c->attr.pointer = attr->pointer || (attr->dummy && !attr->allocatable)
769 || attr->select_type_temporary;
770 c->attr.allocatable = attr->allocatable;
771 c->attr.dimension = attr->dimension;
772 c->attr.codimension = attr->codimension;
773 c->attr.abstract = fclass->attr.abstract;
774 c->as = (*as);
775 c->initializer = NULL;
777 /* Add component '_vptr'. */
778 if (!gfc_add_component (fclass, "_vptr", &c))
779 return false;
780 c->ts.type = BT_DERIVED;
781 c->attr.access = ACCESS_PRIVATE;
782 c->attr.pointer = 1;
784 if (ts->u.derived->attr.unlimited_polymorphic)
786 vtab = gfc_find_derived_vtab (ts->u.derived);
787 gcc_assert (vtab);
788 c->ts.u.derived = vtab->ts.u.derived;
790 /* Add component '_len'. Only unlimited polymorphic pointers may
791 have a string assigned to them, i.e., only those need the _len
792 component. */
793 if (!gfc_add_component (fclass, "_len", &c))
794 return false;
795 c->ts.type = BT_INTEGER;
796 c->ts.kind = gfc_charlen_int_kind;
797 c->attr.access = ACCESS_PRIVATE;
798 c->attr.artificial = 1;
800 else
801 /* Build vtab later. */
802 c->ts.u.derived = NULL;
805 if (!ts->u.derived->attr.unlimited_polymorphic)
807 /* Since the extension field is 8 bit wide, we can only have
808 up to 255 extension levels. */
809 if (ts->u.derived->attr.extension == 255)
811 gfc_error ("Maximum extension level reached with type %qs at %L",
812 ts->u.derived->name, &ts->u.derived->declared_at);
813 return false;
816 fclass->attr.extension = ts->u.derived->attr.extension + 1;
817 fclass->attr.alloc_comp = ts->u.derived->attr.alloc_comp;
818 fclass->attr.coarray_comp = ts->u.derived->attr.coarray_comp;
821 fclass->attr.is_class = 1;
822 orig_ts->u.derived = fclass;
823 attr->allocatable = attr->pointer = attr->dimension = attr->codimension = 0;
824 (*as) = NULL;
825 free (name);
826 return true;
830 /* Change class, using gfc_build_class_symbol. This is needed for associate
831 names, when rank changes or a derived type is produced by resolution. */
833 void
834 gfc_change_class (gfc_typespec *ts, symbol_attribute *sym_attr,
835 gfc_array_spec *sym_as, int rank, int corank)
837 symbol_attribute attr;
838 gfc_component *c;
839 gfc_array_spec *as = NULL;
840 gfc_symbol *der = ts->u.derived;
842 ts->type = BT_CLASS;
843 attr = *sym_attr;
844 attr.class_ok = 0;
845 attr.associate_var = 1;
846 attr.class_pointer = 1;
847 attr.allocatable = 0;
848 attr.pointer = 1;
849 attr.dimension = rank ? 1 : 0;
850 if (rank)
852 if (sym_as)
853 as = gfc_copy_array_spec (sym_as);
854 else
856 as = gfc_get_array_spec ();
857 as->rank = rank;
858 as->type = AS_DEFERRED;
859 as->corank = corank;
862 if (as && as->corank != 0)
863 attr.codimension = 1;
865 if (!gfc_build_class_symbol (ts, &attr, &as))
866 gcc_unreachable ();
868 gfc_set_sym_referenced (ts->u.derived);
870 /* Make sure the _vptr is set. */
871 c = gfc_find_component (ts->u.derived, "_vptr", true, true, NULL);
872 if (c->ts.u.derived == NULL)
873 c->ts.u.derived = gfc_find_derived_vtab (der);
874 /* _vptr now has the _vtab in it, change it to the _vtype. */
875 if (c->ts.u.derived->attr.vtab)
876 c->ts.u.derived = c->ts.u.derived->ts.u.derived;
880 /* Add a procedure pointer component to the vtype
881 to represent a specific type-bound procedure. */
883 static void
884 add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
886 gfc_component *c;
888 if (tb->non_overridable && !tb->overridden)
889 return;
891 c = gfc_find_component (vtype, name, true, true, NULL);
893 if (c == NULL)
895 /* Add procedure component. */
896 if (!gfc_add_component (vtype, name, &c))
897 return;
899 if (!c->tb)
900 c->tb = XCNEW (gfc_typebound_proc);
901 *c->tb = *tb;
902 c->tb->ppc = 1;
903 c->attr.procedure = 1;
904 c->attr.proc_pointer = 1;
905 c->attr.flavor = FL_PROCEDURE;
906 c->attr.access = ACCESS_PRIVATE;
907 c->attr.external = 1;
908 c->attr.untyped = 1;
909 c->attr.if_source = IFSRC_IFBODY;
911 else if (c->attr.proc_pointer && c->tb)
913 *c->tb = *tb;
914 c->tb->ppc = 1;
917 if (tb->u.specific)
919 gfc_symbol *ifc = tb->u.specific->n.sym;
920 c->ts.interface = ifc;
921 if (!tb->deferred)
922 c->initializer = gfc_get_variable_expr (tb->u.specific);
923 c->attr.pure = ifc->attr.pure;
928 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
930 static void
931 add_procs_to_declared_vtab1 (gfc_symtree *st, gfc_symbol *vtype)
933 if (!st)
934 return;
936 if (st->left)
937 add_procs_to_declared_vtab1 (st->left, vtype);
939 if (st->right)
940 add_procs_to_declared_vtab1 (st->right, vtype);
942 if (st->n.tb && !st->n.tb->error
943 && !st->n.tb->is_generic && st->n.tb->u.specific)
944 add_proc_comp (vtype, st->name, st->n.tb);
948 /* Copy procedure pointers components from the parent type. */
950 static void
951 copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
953 gfc_component *cmp;
954 gfc_symbol *vtab;
956 vtab = gfc_find_derived_vtab (declared);
958 for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
960 if (gfc_find_component (vtype, cmp->name, true, true, NULL))
961 continue;
963 add_proc_comp (vtype, cmp->name, cmp->tb);
968 /* Returns true if any of its nonpointer nonallocatable components or
969 their nonpointer nonallocatable subcomponents has a finalization
970 subroutine. */
972 static bool
973 has_finalizer_component (gfc_symbol *derived)
975 gfc_component *c;
977 for (c = derived->components; c; c = c->next)
978 if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.allocatable
979 && c->attr.flavor != FL_PROCEDURE)
981 if (c->ts.u.derived->f2k_derived
982 && c->ts.u.derived->f2k_derived->finalizers)
983 return true;
985 /* Stop infinite recursion through this function by inhibiting
986 calls when the derived type and that of the component are
987 the same. */
988 if (!gfc_compare_derived_types (derived, c->ts.u.derived)
989 && has_finalizer_component (c->ts.u.derived))
990 return true;
992 return false;
996 static bool
997 comp_is_finalizable (gfc_component *comp)
999 if (comp->attr.proc_pointer)
1000 return false;
1001 else if (comp->attr.allocatable && comp->ts.type != BT_CLASS)
1002 return true;
1003 else if (comp->ts.type == BT_DERIVED && !comp->attr.pointer
1004 && (comp->ts.u.derived->attr.alloc_comp
1005 || has_finalizer_component (comp->ts.u.derived)
1006 || (comp->ts.u.derived->f2k_derived
1007 && comp->ts.u.derived->f2k_derived->finalizers)))
1008 return true;
1009 else if (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1010 && CLASS_DATA (comp)->attr.allocatable)
1011 return true;
1012 else
1013 return false;
1017 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
1018 neither allocatable nor a pointer but has a finalizer, call it. If it
1019 is a nonpointer component with allocatable components or has finalizers, walk
1020 them. Either of them is required; other nonallocatables and pointers aren't
1021 handled gracefully.
1022 Note: If the component is allocatable, the DEALLOCATE handling takes care
1023 of calling the appropriate finalizers, coarray deregistering, and
1024 deallocation of allocatable subcomponents. */
1026 static void
1027 finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
1028 gfc_symbol *stat, gfc_symbol *fini_coarray, gfc_code **code,
1029 gfc_namespace *sub_ns)
1031 gfc_expr *e;
1032 gfc_ref *ref;
1033 gfc_was_finalized *f;
1035 if (!comp_is_finalizable (comp))
1036 return;
1038 /* If this expression with this component has been finalized
1039 already in this namespace, there is nothing to do. */
1040 for (f = sub_ns->was_finalized; f; f = f->next)
1042 if (f->e == expr && f->c == comp)
1043 return;
1046 e = gfc_copy_expr (expr);
1047 if (!e->ref)
1048 e->ref = ref = gfc_get_ref ();
1049 else
1051 for (ref = e->ref; ref->next; ref = ref->next)
1053 ref->next = gfc_get_ref ();
1054 ref = ref->next;
1056 ref->type = REF_COMPONENT;
1057 ref->u.c.sym = derived;
1058 ref->u.c.component = comp;
1059 e->ts = comp->ts;
1061 if (comp->attr.dimension || comp->attr.codimension
1062 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1063 && (CLASS_DATA (comp)->attr.dimension
1064 || CLASS_DATA (comp)->attr.codimension)))
1066 ref->next = gfc_get_ref ();
1067 ref->next->type = REF_ARRAY;
1068 ref->next->u.ar.dimen = 0;
1069 ref->next->u.ar.as = comp->ts.type == BT_CLASS ? CLASS_DATA (comp)->as
1070 : comp->as;
1071 e->rank = ref->next->u.ar.as->rank;
1072 e->corank = ref->next->u.ar.as->corank;
1073 ref->next->u.ar.type = e->rank ? AR_FULL : AR_ELEMENT;
1076 /* Call DEALLOCATE (comp, stat=ignore). */
1077 if (comp->attr.allocatable
1078 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1079 && CLASS_DATA (comp)->attr.allocatable))
1081 gfc_code *dealloc, *block = NULL;
1083 /* Add IF (fini_coarray). */
1084 if (comp->attr.codimension
1085 || (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
1086 && CLASS_DATA (comp)->attr.codimension))
1088 block = gfc_get_code (EXEC_IF);
1089 if (*code)
1091 (*code)->next = block;
1092 (*code) = (*code)->next;
1094 else
1095 (*code) = block;
1097 block->block = gfc_get_code (EXEC_IF);
1098 block = block->block;
1099 block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
1102 dealloc = gfc_get_code (EXEC_DEALLOCATE);
1104 dealloc->ext.alloc.list = gfc_get_alloc ();
1105 dealloc->ext.alloc.list->expr = e;
1106 dealloc->expr1 = gfc_lval_expr_from_sym (stat);
1108 gfc_code *cond = gfc_get_code (EXEC_IF);
1109 cond->block = gfc_get_code (EXEC_IF);
1110 cond->block->expr1 = gfc_get_expr ();
1111 cond->block->expr1->expr_type = EXPR_FUNCTION;
1112 cond->block->expr1->where = gfc_current_locus;
1113 gfc_get_sym_tree ("associated", sub_ns, &cond->block->expr1->symtree, false);
1114 cond->block->expr1->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1115 cond->block->expr1->symtree->n.sym->attr.intrinsic = 1;
1116 cond->block->expr1->symtree->n.sym->result = cond->block->expr1->symtree->n.sym;
1117 gfc_commit_symbol (cond->block->expr1->symtree->n.sym);
1118 cond->block->expr1->ts.type = BT_LOGICAL;
1119 cond->block->expr1->ts.kind = gfc_default_logical_kind;
1120 cond->block->expr1->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED);
1121 cond->block->expr1->value.function.actual = gfc_get_actual_arglist ();
1122 cond->block->expr1->value.function.actual->expr = gfc_copy_expr (expr);
1123 cond->block->expr1->value.function.actual->next = gfc_get_actual_arglist ();
1124 cond->block->next = dealloc;
1126 if (block)
1127 block->next = cond;
1128 else if (*code)
1130 (*code)->next = cond;
1131 (*code) = (*code)->next;
1133 else
1134 (*code) = cond;
1137 else if (comp->ts.type == BT_DERIVED
1138 && comp->ts.u.derived->f2k_derived
1139 && comp->ts.u.derived->f2k_derived->finalizers)
1141 /* Call FINAL_WRAPPER (comp); */
1142 gfc_code *final_wrap;
1143 gfc_symbol *vtab, *byte_stride;
1144 gfc_expr *scalar, *size_expr, *fini_coarray_expr;
1145 gfc_component *c;
1147 vtab = gfc_find_derived_vtab (comp->ts.u.derived);
1148 for (c = vtab->ts.u.derived->components; c; c = c->next)
1149 if (strcmp (c->name, "_final") == 0)
1150 break;
1152 gcc_assert (c);
1154 /* Set scalar argument for storage_size. */
1155 gfc_get_symbol ("comp_byte_stride", sub_ns, &byte_stride);
1156 byte_stride->ts = e->ts;
1157 byte_stride->attr.flavor = FL_VARIABLE;
1158 byte_stride->attr.value = 1;
1159 byte_stride->attr.artificial = 1;
1160 gfc_set_sym_referenced (byte_stride);
1161 gfc_commit_symbol (byte_stride);
1162 scalar = gfc_lval_expr_from_sym (byte_stride);
1164 final_wrap = gfc_get_code (EXEC_CALL);
1165 final_wrap->symtree = c->initializer->symtree;
1166 final_wrap->resolved_sym = c->initializer->symtree->n.sym;
1167 final_wrap->ext.actual = gfc_get_actual_arglist ();
1168 final_wrap->ext.actual->expr = e;
1170 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1171 size_expr = gfc_get_expr ();
1172 size_expr->where = gfc_current_locus;
1173 size_expr->expr_type = EXPR_OP;
1174 size_expr->value.op.op = INTRINSIC_DIVIDE;
1176 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1177 size_expr->value.op.op1
1178 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1179 "storage_size", gfc_current_locus, 2,
1180 scalar,
1181 gfc_get_int_expr (gfc_index_integer_kind,
1182 NULL, 0));
1184 /* NUMERIC_STORAGE_SIZE. */
1185 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1186 gfc_character_storage_size);
1187 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1188 size_expr->ts = size_expr->value.op.op1->ts;
1190 /* Which provides the argument 'byte_stride'..... */
1191 final_wrap->ext.actual->next = gfc_get_actual_arglist ();
1192 final_wrap->ext.actual->next->expr = size_expr;
1194 /* ...and last of all the 'fini_coarray' argument. */
1195 fini_coarray_expr = gfc_lval_expr_from_sym (fini_coarray);
1196 final_wrap->ext.actual->next->next = gfc_get_actual_arglist ();
1197 final_wrap->ext.actual->next->next->expr = fini_coarray_expr;
1201 if (*code)
1203 (*code)->next = final_wrap;
1204 (*code) = (*code)->next;
1206 else
1207 (*code) = final_wrap;
1209 else
1211 gfc_component *c;
1213 for (c = comp->ts.u.derived->components; c; c = c->next)
1214 finalize_component (e, comp->ts.u.derived, c, stat, fini_coarray, code,
1215 sub_ns);
1216 gfc_free_expr (e);
1219 /* Record that this was finalized already in this namespace. */
1220 f = sub_ns->was_finalized;
1221 sub_ns->was_finalized = XCNEW (gfc_was_finalized);
1222 sub_ns->was_finalized->e = expr;
1223 sub_ns->was_finalized->c = comp;
1224 sub_ns->was_finalized->next = f;
1228 /* Generate code equivalent to
1229 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1230 + offset, c_ptr), ptr). */
1232 static gfc_code *
1233 finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
1234 gfc_expr *offset, gfc_namespace *sub_ns)
1236 gfc_code *block;
1237 gfc_expr *expr, *expr2;
1239 /* C_F_POINTER(). */
1240 block = gfc_get_code (EXEC_CALL);
1241 gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
1242 block->resolved_sym = block->symtree->n.sym;
1243 block->resolved_sym->attr.flavor = FL_PROCEDURE;
1244 block->resolved_sym->attr.intrinsic = 1;
1245 block->resolved_sym->attr.subroutine = 1;
1246 block->resolved_sym->from_intmod = INTMOD_ISO_C_BINDING;
1247 block->resolved_sym->intmod_sym_id = ISOCBINDING_F_POINTER;
1248 block->resolved_isym = gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER);
1249 gfc_commit_symbol (block->resolved_sym);
1251 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
1252 block->ext.actual = gfc_get_actual_arglist ();
1253 block->ext.actual->next = gfc_get_actual_arglist ();
1254 block->ext.actual->next->expr = gfc_get_int_expr (gfc_index_integer_kind,
1255 NULL, 0);
1256 block->ext.actual->next->next = gfc_get_actual_arglist (); /* SIZE. */
1258 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
1260 /* TRANSFER's first argument: C_LOC (array). */
1261 expr = gfc_get_expr ();
1262 expr->expr_type = EXPR_FUNCTION;
1263 gfc_get_sym_tree ("c_loc", sub_ns, &expr->symtree, false);
1264 expr->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1265 expr->symtree->n.sym->intmod_sym_id = ISOCBINDING_LOC;
1266 expr->symtree->n.sym->attr.intrinsic = 1;
1267 expr->symtree->n.sym->from_intmod = INTMOD_ISO_C_BINDING;
1268 expr->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC);
1269 expr->value.function.actual = gfc_get_actual_arglist ();
1270 expr->value.function.actual->expr
1271 = gfc_lval_expr_from_sym (array);
1272 expr->symtree->n.sym->result = expr->symtree->n.sym;
1273 gfc_commit_symbol (expr->symtree->n.sym);
1274 expr->ts.type = BT_INTEGER;
1275 expr->ts.kind = gfc_index_integer_kind;
1276 expr->where = gfc_current_locus;
1278 /* TRANSFER. */
1279 expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_TRANSFER, "transfer",
1280 gfc_current_locus, 3, expr,
1281 gfc_get_int_expr (gfc_index_integer_kind,
1282 NULL, 0), NULL);
1283 expr2->ts.type = BT_INTEGER;
1284 expr2->ts.kind = gfc_index_integer_kind;
1286 /* <array addr> + <offset>. */
1287 block->ext.actual->expr = gfc_get_expr ();
1288 block->ext.actual->expr->expr_type = EXPR_OP;
1289 block->ext.actual->expr->value.op.op = INTRINSIC_PLUS;
1290 block->ext.actual->expr->value.op.op1 = expr2;
1291 block->ext.actual->expr->value.op.op2 = offset;
1292 block->ext.actual->expr->ts = expr->ts;
1293 block->ext.actual->expr->where = gfc_current_locus;
1295 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1296 block->ext.actual->next = gfc_get_actual_arglist ();
1297 block->ext.actual->next->expr = gfc_lval_expr_from_sym (ptr);
1298 block->ext.actual->next->next = gfc_get_actual_arglist ();
1300 return block;
1304 /* Calculates the offset to the (idx+1)th element of an array, taking the
1305 stride into account. It generates the code:
1306 offset = 0
1307 do idx2 = 1, rank
1308 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1309 end do
1310 offset = offset * byte_stride. */
1312 static gfc_code*
1313 finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
1314 gfc_symbol *strides, gfc_symbol *sizes,
1315 gfc_symbol *byte_stride, gfc_expr *rank,
1316 gfc_code *block, gfc_namespace *sub_ns)
1318 gfc_iterator *iter;
1319 gfc_expr *expr, *expr2;
1321 /* offset = 0. */
1322 block->next = gfc_get_code (EXEC_ASSIGN);
1323 block = block->next;
1324 block->expr1 = gfc_lval_expr_from_sym (offset);
1325 block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1327 /* Create loop. */
1328 iter = gfc_get_iterator ();
1329 iter->var = gfc_lval_expr_from_sym (idx2);
1330 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1331 iter->end = gfc_copy_expr (rank);
1332 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1333 block->next = gfc_get_code (EXEC_DO);
1334 block = block->next;
1335 block->ext.iterator = iter;
1336 block->block = gfc_get_code (EXEC_DO);
1338 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1339 * strides(idx2). */
1341 /* mod (idx, sizes(idx2)). */
1342 expr = gfc_lval_expr_from_sym (sizes);
1343 expr->ref = gfc_get_ref ();
1344 expr->ref->type = REF_ARRAY;
1345 expr->ref->u.ar.as = sizes->as;
1346 expr->ref->u.ar.type = AR_ELEMENT;
1347 expr->ref->u.ar.dimen = 1;
1348 expr->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1349 expr->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1350 expr->where = sizes->declared_at;
1352 expr = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_MOD, "mod",
1353 gfc_current_locus, 2,
1354 gfc_lval_expr_from_sym (idx), expr);
1355 expr->ts = idx->ts;
1357 /* (...) / sizes(idx2-1). */
1358 expr2 = gfc_get_expr ();
1359 expr2->expr_type = EXPR_OP;
1360 expr2->value.op.op = INTRINSIC_DIVIDE;
1361 expr2->value.op.op1 = expr;
1362 expr2->value.op.op2 = gfc_lval_expr_from_sym (sizes);
1363 expr2->value.op.op2->ref = gfc_get_ref ();
1364 expr2->value.op.op2->ref->type = REF_ARRAY;
1365 expr2->value.op.op2->ref->u.ar.as = sizes->as;
1366 expr2->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1367 expr2->value.op.op2->ref->u.ar.dimen = 1;
1368 expr2->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1369 expr2->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
1370 expr2->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
1371 expr2->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
1372 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
1373 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1
1374 = gfc_lval_expr_from_sym (idx2);
1375 expr2->value.op.op2->ref->u.ar.start[0]->value.op.op2
1376 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1377 expr2->value.op.op2->ref->u.ar.start[0]->ts
1378 = expr2->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
1379 expr2->ts = idx->ts;
1380 expr2->where = gfc_current_locus;
1382 /* ... * strides(idx2). */
1383 expr = gfc_get_expr ();
1384 expr->expr_type = EXPR_OP;
1385 expr->value.op.op = INTRINSIC_TIMES;
1386 expr->value.op.op1 = expr2;
1387 expr->value.op.op2 = gfc_lval_expr_from_sym (strides);
1388 expr->value.op.op2->ref = gfc_get_ref ();
1389 expr->value.op.op2->ref->type = REF_ARRAY;
1390 expr->value.op.op2->ref->u.ar.type = AR_ELEMENT;
1391 expr->value.op.op2->ref->u.ar.dimen = 1;
1392 expr->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1393 expr->value.op.op2->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx2);
1394 expr->value.op.op2->ref->u.ar.as = strides->as;
1395 expr->ts = idx->ts;
1396 expr->where = gfc_current_locus;
1398 /* offset = offset + ... */
1399 block->block->next = gfc_get_code (EXEC_ASSIGN);
1400 block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
1401 block->block->next->expr2 = gfc_get_expr ();
1402 block->block->next->expr2->expr_type = EXPR_OP;
1403 block->block->next->expr2->value.op.op = INTRINSIC_PLUS;
1404 block->block->next->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1405 block->block->next->expr2->value.op.op2 = expr;
1406 block->block->next->expr2->ts = idx->ts;
1407 block->block->next->expr2->where = gfc_current_locus;
1409 /* After the loop: offset = offset * byte_stride. */
1410 block->next = gfc_get_code (EXEC_ASSIGN);
1411 block = block->next;
1412 block->expr1 = gfc_lval_expr_from_sym (offset);
1413 block->expr2 = gfc_get_expr ();
1414 block->expr2->expr_type = EXPR_OP;
1415 block->expr2->value.op.op = INTRINSIC_TIMES;
1416 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (offset);
1417 block->expr2->value.op.op2 = gfc_lval_expr_from_sym (byte_stride);
1418 block->expr2->ts = block->expr2->value.op.op1->ts;
1419 block->expr2->where = gfc_current_locus;
1420 return block;
1424 /* Insert code of the following form:
1426 block
1427 integer(c_intptr_t) :: i
1429 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1430 && (is_contiguous || !final_rank3->attr.contiguous
1431 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1432 || 0 == STORAGE_SIZE (array)) then
1433 call final_rank3 (array)
1434 else
1435 block
1436 integer(c_intptr_t) :: offset, j
1437 type(t) :: tmp(shape (array))
1439 do i = 0, size (array)-1
1440 offset = obtain_offset(i, strides, sizes, byte_stride)
1441 addr = transfer (c_loc (array), addr) + offset
1442 call c_f_pointer (transfer (addr, cptr), ptr)
1444 addr = transfer (c_loc (tmp), addr)
1445 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1446 call c_f_pointer (transfer (addr, cptr), ptr2)
1447 ptr2 = ptr
1448 end do
1449 call final_rank3 (tmp)
1450 end block
1451 end if
1452 block */
1454 static void
1455 finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
1456 gfc_symbol *array, gfc_symbol *byte_stride,
1457 gfc_symbol *idx, gfc_symbol *ptr,
1458 gfc_symbol *nelem,
1459 gfc_symbol *strides, gfc_symbol *sizes,
1460 gfc_symbol *idx2, gfc_symbol *offset,
1461 gfc_symbol *is_contiguous, gfc_expr *rank,
1462 gfc_namespace *sub_ns)
1464 gfc_symbol *tmp_array, *ptr2;
1465 gfc_expr *size_expr, *offset2, *expr;
1466 gfc_namespace *ns;
1467 gfc_iterator *iter;
1468 gfc_code *block2;
1469 int i;
1471 block->next = gfc_get_code (EXEC_IF);
1472 block = block->next;
1474 block->block = gfc_get_code (EXEC_IF);
1475 block = block->block;
1477 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1478 size_expr = gfc_get_expr ();
1479 size_expr->where = gfc_current_locus;
1480 size_expr->expr_type = EXPR_OP;
1481 size_expr->value.op.op = INTRINSIC_DIVIDE;
1483 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1484 size_expr->value.op.op1
1485 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STORAGE_SIZE,
1486 "storage_size", gfc_current_locus, 2,
1487 gfc_lval_expr_from_sym (array),
1488 gfc_get_int_expr (gfc_index_integer_kind,
1489 NULL, 0));
1491 /* NUMERIC_STORAGE_SIZE. */
1492 size_expr->value.op.op2 = gfc_get_int_expr (gfc_index_integer_kind, NULL,
1493 gfc_character_storage_size);
1494 size_expr->value.op.op1->ts = size_expr->value.op.op2->ts;
1495 size_expr->ts = size_expr->value.op.op1->ts;
1497 /* IF condition: (stride == size_expr
1498 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1499 || is_contiguous)
1500 || 0 == size_expr. */
1501 block->expr1 = gfc_get_expr ();
1502 block->expr1->ts.type = BT_LOGICAL;
1503 block->expr1->ts.kind = gfc_default_logical_kind;
1504 block->expr1->expr_type = EXPR_OP;
1505 block->expr1->where = gfc_current_locus;
1507 block->expr1->value.op.op = INTRINSIC_OR;
1509 /* byte_stride == size_expr */
1510 expr = gfc_get_expr ();
1511 expr->ts.type = BT_LOGICAL;
1512 expr->ts.kind = gfc_default_logical_kind;
1513 expr->expr_type = EXPR_OP;
1514 expr->where = gfc_current_locus;
1515 expr->value.op.op = INTRINSIC_EQ;
1516 expr->value.op.op1
1517 = gfc_lval_expr_from_sym (byte_stride);
1518 expr->value.op.op2 = size_expr;
1520 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1521 add is_contiguous check. */
1523 if (fini->proc_tree->n.sym->formal->sym->as->type != AS_ASSUMED_SHAPE
1524 || fini->proc_tree->n.sym->formal->sym->attr.contiguous)
1526 gfc_expr *expr2;
1527 expr2 = gfc_get_expr ();
1528 expr2->ts.type = BT_LOGICAL;
1529 expr2->ts.kind = gfc_default_logical_kind;
1530 expr2->expr_type = EXPR_OP;
1531 expr2->where = gfc_current_locus;
1532 expr2->value.op.op = INTRINSIC_AND;
1533 expr2->value.op.op1 = expr;
1534 expr2->value.op.op2 = gfc_lval_expr_from_sym (is_contiguous);
1535 expr = expr2;
1538 block->expr1->value.op.op1 = expr;
1540 /* 0 == size_expr */
1541 block->expr1->value.op.op2 = gfc_get_expr ();
1542 block->expr1->value.op.op2->ts.type = BT_LOGICAL;
1543 block->expr1->value.op.op2->ts.kind = gfc_default_logical_kind;
1544 block->expr1->value.op.op2->expr_type = EXPR_OP;
1545 block->expr1->value.op.op2->where = gfc_current_locus;
1546 block->expr1->value.op.op2->value.op.op = INTRINSIC_EQ;
1547 block->expr1->value.op.op2->value.op.op1 =
1548 gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1549 block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
1551 /* IF body: call final subroutine. */
1552 block->next = gfc_get_code (EXEC_CALL);
1553 block->next->symtree = fini->proc_tree;
1554 block->next->resolved_sym = fini->proc_tree->n.sym;
1555 block->next->ext.actual = gfc_get_actual_arglist ();
1556 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
1558 /* ELSE. */
1560 block->block = gfc_get_code (EXEC_IF);
1561 block = block->block;
1563 /* BLOCK ... END BLOCK. */
1564 block->next = gfc_get_code (EXEC_BLOCK);
1565 block = block->next;
1567 ns = gfc_build_block_ns (sub_ns);
1568 block->ext.block.ns = ns;
1569 block->ext.block.assoc = NULL;
1571 gfc_get_symbol ("ptr2", ns, &ptr2);
1572 ptr2->ts.type = BT_DERIVED;
1573 ptr2->ts.u.derived = array->ts.u.derived;
1574 ptr2->attr.flavor = FL_VARIABLE;
1575 ptr2->attr.pointer = 1;
1576 ptr2->attr.artificial = 1;
1577 gfc_set_sym_referenced (ptr2);
1578 gfc_commit_symbol (ptr2);
1580 gfc_get_symbol ("tmp_array", ns, &tmp_array);
1581 tmp_array->ts.type = BT_DERIVED;
1582 tmp_array->ts.u.derived = array->ts.u.derived;
1583 tmp_array->attr.flavor = FL_VARIABLE;
1584 tmp_array->attr.dimension = 1;
1585 tmp_array->attr.artificial = 1;
1586 tmp_array->as = gfc_get_array_spec();
1587 tmp_array->attr.intent = INTENT_INOUT;
1588 tmp_array->as->type = AS_EXPLICIT;
1589 tmp_array->as->rank = fini->proc_tree->n.sym->formal->sym->as->rank;
1591 for (i = 0; i < tmp_array->as->rank; i++)
1593 gfc_expr *shape_expr;
1594 tmp_array->as->lower[i] = gfc_get_int_expr (gfc_default_integer_kind,
1595 NULL, 1);
1596 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1597 shape_expr
1598 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
1599 gfc_current_locus, 3,
1600 gfc_lval_expr_from_sym (array),
1601 gfc_get_int_expr (gfc_default_integer_kind,
1602 NULL, i+1),
1603 gfc_get_int_expr (gfc_default_integer_kind,
1604 NULL,
1605 gfc_index_integer_kind));
1606 shape_expr->ts.kind = gfc_index_integer_kind;
1607 tmp_array->as->upper[i] = shape_expr;
1609 gfc_set_sym_referenced (tmp_array);
1610 gfc_commit_symbol (tmp_array);
1612 /* Create loop. */
1613 iter = gfc_get_iterator ();
1614 iter->var = gfc_lval_expr_from_sym (idx);
1615 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1616 iter->end = gfc_lval_expr_from_sym (nelem);
1617 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1619 block = gfc_get_code (EXEC_DO);
1620 ns->code = block;
1621 block->ext.iterator = iter;
1622 block->block = gfc_get_code (EXEC_DO);
1624 /* Offset calculation for the new array: idx * size of type (in bytes). */
1625 offset2 = gfc_get_expr ();
1626 offset2->expr_type = EXPR_OP;
1627 offset2->where = gfc_current_locus;
1628 offset2->value.op.op = INTRINSIC_TIMES;
1629 offset2->value.op.op1 = gfc_lval_expr_from_sym (idx);
1630 offset2->value.op.op2 = gfc_copy_expr (size_expr);
1631 offset2->ts = byte_stride->ts;
1633 /* Offset calculation of "array". */
1634 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1635 byte_stride, rank, block->block, sub_ns);
1637 /* Create code for
1638 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1639 + idx * stride, c_ptr), ptr). */
1640 block2->next = finalization_scalarizer (array, ptr,
1641 gfc_lval_expr_from_sym (offset),
1642 sub_ns);
1643 block2 = block2->next;
1644 block2->next = finalization_scalarizer (tmp_array, ptr2, offset2, sub_ns);
1645 block2 = block2->next;
1647 /* ptr2 = ptr. */
1648 block2->next = gfc_get_code (EXEC_ASSIGN);
1649 block2 = block2->next;
1650 block2->expr1 = gfc_lval_expr_from_sym (ptr2);
1651 block2->expr2 = gfc_lval_expr_from_sym (ptr);
1653 /* Call now the user's final subroutine. */
1654 block->next = gfc_get_code (EXEC_CALL);
1655 block = block->next;
1656 block->symtree = fini->proc_tree;
1657 block->resolved_sym = fini->proc_tree->n.sym;
1658 block->ext.actual = gfc_get_actual_arglist ();
1659 block->ext.actual->expr = gfc_lval_expr_from_sym (tmp_array);
1661 if (fini->proc_tree->n.sym->formal->sym->attr.intent == INTENT_IN)
1662 return;
1664 /* Copy back. */
1666 /* Loop. */
1667 iter = gfc_get_iterator ();
1668 iter->var = gfc_lval_expr_from_sym (idx);
1669 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1670 iter->end = gfc_lval_expr_from_sym (nelem);
1671 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1673 block->next = gfc_get_code (EXEC_DO);
1674 block = block->next;
1675 block->ext.iterator = iter;
1676 block->block = gfc_get_code (EXEC_DO);
1678 /* Offset calculation of "array". */
1679 block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
1680 byte_stride, rank, block->block, sub_ns);
1682 /* Create code for
1683 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1684 + offset, c_ptr), ptr). */
1685 block2->next = finalization_scalarizer (array, ptr,
1686 gfc_lval_expr_from_sym (offset),
1687 sub_ns);
1688 block2 = block2->next;
1689 block2->next = finalization_scalarizer (tmp_array, ptr2,
1690 gfc_copy_expr (offset2), sub_ns);
1691 block2 = block2->next;
1693 /* ptr = ptr2. */
1694 block2->next = gfc_get_code (EXEC_ASSIGN);
1695 block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
1696 block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
1700 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1701 derived type "derived". The function first calls the appropriate FINAL
1702 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1703 components (but not the inherited ones). Last, it calls the wrapper
1704 subroutine of the parent. The generated wrapper procedure takes as argument
1705 an assumed-rank array.
1706 If neither allocatable components nor FINAL subroutines exists, the vtab
1707 will contain a NULL pointer.
1708 The generated function has the form
1709 _final(assumed-rank array, stride, skip_corarray)
1710 where the array has to be contiguous (except of the lowest dimension). The
1711 stride (in bytes) is used to allow different sizes for ancestor types by
1712 skipping over the additionally added components in the scalarizer. If
1713 "fini_coarray" is false, coarray components are not finalized to allow for
1714 the correct semantic with intrinsic assignment. */
1716 static void
1717 generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
1718 const char *tname, gfc_component *vtab_final)
1720 gfc_symbol *final, *array, *fini_coarray, *byte_stride, *sizes, *strides;
1721 gfc_symbol *ptr = NULL, *idx, *idx2, *is_contiguous, *offset, *nelem;
1722 gfc_component *comp;
1723 gfc_namespace *sub_ns;
1724 gfc_code *last_code, *block;
1725 char *name;
1726 bool finalizable_comp = false;
1727 gfc_expr *ancestor_wrapper = NULL, *rank;
1728 gfc_iterator *iter;
1730 if (derived->attr.unlimited_polymorphic)
1732 vtab_final->initializer = gfc_get_null_expr (NULL);
1733 return;
1736 /* Search for the ancestor's finalizers. */
1737 if (derived->attr.extension && derived->components
1738 && (!derived->components->ts.u.derived->attr.abstract
1739 || has_finalizer_component (derived)))
1741 gfc_symbol *vtab;
1742 gfc_component *comp;
1744 vtab = gfc_find_derived_vtab (derived->components->ts.u.derived);
1745 for (comp = vtab->ts.u.derived->components; comp; comp = comp->next)
1746 if (comp->name[0] == '_' && comp->name[1] == 'f')
1748 ancestor_wrapper = comp->initializer;
1749 break;
1753 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1754 components: Return a NULL() expression; we defer this a bit to have
1755 an interface declaration. */
1756 if ((!ancestor_wrapper || ancestor_wrapper->expr_type == EXPR_NULL)
1757 && !derived->attr.alloc_comp
1758 && (!derived->f2k_derived || !derived->f2k_derived->finalizers)
1759 && !has_finalizer_component (derived))
1761 vtab_final->initializer = gfc_get_null_expr (NULL);
1762 gcc_assert (vtab_final->ts.interface == NULL);
1763 return;
1765 else
1766 /* Check whether there are new allocatable components. */
1767 for (comp = derived->components; comp; comp = comp->next)
1769 if (comp == derived->components && derived->attr.extension
1770 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
1771 continue;
1773 finalizable_comp |= comp_is_finalizable (comp);
1776 /* If there is no new finalizer and no new allocatable, return with
1777 an expr to the ancestor's one. */
1778 if (!finalizable_comp
1779 && (!derived->f2k_derived || !derived->f2k_derived->finalizers))
1781 gcc_assert (ancestor_wrapper && ancestor_wrapper->ref == NULL
1782 && ancestor_wrapper->expr_type == EXPR_VARIABLE);
1783 vtab_final->initializer = gfc_copy_expr (ancestor_wrapper);
1784 vtab_final->ts.interface = vtab_final->initializer->symtree->n.sym;
1785 return;
1788 /* We now create a wrapper, which does the following:
1789 1. Call the suitable finalization subroutine for this type
1790 2. Loop over all noninherited allocatable components and noninherited
1791 components with allocatable components and DEALLOCATE those; this will
1792 take care of finalizers, coarray deregistering and allocatable
1793 nested components.
1794 3. Call the ancestor's finalizer. */
1796 /* Declare the wrapper function; it takes an assumed-rank array
1797 and a VALUE logical as arguments. */
1799 /* Set up the namespace. */
1800 sub_ns = gfc_get_namespace (ns, 0);
1801 sub_ns->sibling = ns->contained;
1802 ns->contained = sub_ns;
1803 sub_ns->resolved = 1;
1805 /* Set up the procedure symbol. */
1806 name = xasprintf ("__final_%s", tname);
1807 gfc_get_symbol (name, sub_ns, &final);
1808 sub_ns->proc_name = final;
1809 final->attr.flavor = FL_PROCEDURE;
1810 final->attr.function = 1;
1811 final->attr.pure = 0;
1812 final->attr.recursive = 1;
1813 final->result = final;
1814 final->ts.type = BT_INTEGER;
1815 final->ts.kind = 4;
1816 final->attr.artificial = 1;
1817 final->attr.always_explicit = 1;
1818 final->attr.if_source = IFSRC_DECL;
1819 if (ns->proc_name->attr.flavor == FL_MODULE)
1820 final->module = ns->proc_name->name;
1821 gfc_set_sym_referenced (final);
1822 gfc_commit_symbol (final);
1824 /* Set up formal argument. */
1825 gfc_get_symbol ("array", sub_ns, &array);
1826 array->ts.type = BT_DERIVED;
1827 array->ts.u.derived = derived;
1828 array->attr.flavor = FL_VARIABLE;
1829 array->attr.dummy = 1;
1830 array->attr.contiguous = 1;
1831 array->attr.dimension = 1;
1832 array->attr.artificial = 1;
1833 array->as = gfc_get_array_spec();
1834 array->as->type = AS_ASSUMED_RANK;
1835 array->as->rank = -1;
1836 array->attr.intent = INTENT_INOUT;
1837 gfc_set_sym_referenced (array);
1838 final->formal = gfc_get_formal_arglist ();
1839 final->formal->sym = array;
1840 gfc_commit_symbol (array);
1842 /* Set up formal argument. */
1843 gfc_get_symbol ("byte_stride", sub_ns, &byte_stride);
1844 byte_stride->ts.type = BT_INTEGER;
1845 byte_stride->ts.kind = gfc_index_integer_kind;
1846 byte_stride->attr.flavor = FL_VARIABLE;
1847 byte_stride->attr.dummy = 1;
1848 byte_stride->attr.value = 1;
1849 byte_stride->attr.artificial = 1;
1850 gfc_set_sym_referenced (byte_stride);
1851 final->formal->next = gfc_get_formal_arglist ();
1852 final->formal->next->sym = byte_stride;
1853 gfc_commit_symbol (byte_stride);
1855 /* Set up formal argument. */
1856 gfc_get_symbol ("fini_coarray", sub_ns, &fini_coarray);
1857 fini_coarray->ts.type = BT_LOGICAL;
1858 fini_coarray->ts.kind = 1;
1859 fini_coarray->attr.flavor = FL_VARIABLE;
1860 fini_coarray->attr.dummy = 1;
1861 fini_coarray->attr.value = 1;
1862 fini_coarray->attr.artificial = 1;
1863 gfc_set_sym_referenced (fini_coarray);
1864 final->formal->next->next = gfc_get_formal_arglist ();
1865 final->formal->next->next->sym = fini_coarray;
1866 gfc_commit_symbol (fini_coarray);
1868 /* Local variables. */
1870 gfc_get_symbol ("idx", sub_ns, &idx);
1871 idx->ts.type = BT_INTEGER;
1872 idx->ts.kind = gfc_index_integer_kind;
1873 idx->attr.flavor = FL_VARIABLE;
1874 idx->attr.artificial = 1;
1875 gfc_set_sym_referenced (idx);
1876 gfc_commit_symbol (idx);
1878 gfc_get_symbol ("idx2", sub_ns, &idx2);
1879 idx2->ts.type = BT_INTEGER;
1880 idx2->ts.kind = gfc_index_integer_kind;
1881 idx2->attr.flavor = FL_VARIABLE;
1882 idx2->attr.artificial = 1;
1883 gfc_set_sym_referenced (idx2);
1884 gfc_commit_symbol (idx2);
1886 gfc_get_symbol ("offset", sub_ns, &offset);
1887 offset->ts.type = BT_INTEGER;
1888 offset->ts.kind = gfc_index_integer_kind;
1889 offset->attr.flavor = FL_VARIABLE;
1890 offset->attr.artificial = 1;
1891 gfc_set_sym_referenced (offset);
1892 gfc_commit_symbol (offset);
1894 /* Create RANK expression. */
1895 rank = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_RANK, "rank",
1896 gfc_current_locus, 1,
1897 gfc_lval_expr_from_sym (array));
1898 if (rank->ts.kind != idx->ts.kind)
1899 gfc_convert_type_warn (rank, &idx->ts, 2, 0);
1901 /* Create is_contiguous variable. */
1902 gfc_get_symbol ("is_contiguous", sub_ns, &is_contiguous);
1903 is_contiguous->ts.type = BT_LOGICAL;
1904 is_contiguous->ts.kind = gfc_default_logical_kind;
1905 is_contiguous->attr.flavor = FL_VARIABLE;
1906 is_contiguous->attr.artificial = 1;
1907 gfc_set_sym_referenced (is_contiguous);
1908 gfc_commit_symbol (is_contiguous);
1910 /* Create "sizes(0..rank)" variable, which contains the multiplied
1911 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1912 sizes(2) = sizes(1) * extent(dim=2) etc. */
1913 gfc_get_symbol ("sizes", sub_ns, &sizes);
1914 sizes->ts.type = BT_INTEGER;
1915 sizes->ts.kind = gfc_index_integer_kind;
1916 sizes->attr.flavor = FL_VARIABLE;
1917 sizes->attr.dimension = 1;
1918 sizes->attr.artificial = 1;
1919 sizes->as = gfc_get_array_spec();
1920 sizes->attr.intent = INTENT_INOUT;
1921 sizes->as->type = AS_EXPLICIT;
1922 sizes->as->rank = 1;
1923 sizes->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1924 sizes->as->upper[0] = gfc_copy_expr (rank);
1925 gfc_set_sym_referenced (sizes);
1926 gfc_commit_symbol (sizes);
1928 /* Create "strides(1..rank)" variable, which contains the strides per
1929 dimension. */
1930 gfc_get_symbol ("strides", sub_ns, &strides);
1931 strides->ts.type = BT_INTEGER;
1932 strides->ts.kind = gfc_index_integer_kind;
1933 strides->attr.flavor = FL_VARIABLE;
1934 strides->attr.dimension = 1;
1935 strides->attr.artificial = 1;
1936 strides->as = gfc_get_array_spec();
1937 strides->attr.intent = INTENT_INOUT;
1938 strides->as->type = AS_EXPLICIT;
1939 strides->as->rank = 1;
1940 strides->as->lower[0] = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1941 strides->as->upper[0] = gfc_copy_expr (rank);
1942 gfc_set_sym_referenced (strides);
1943 gfc_commit_symbol (strides);
1946 /* Set return value to 0. */
1947 last_code = gfc_get_code (EXEC_ASSIGN);
1948 last_code->expr1 = gfc_lval_expr_from_sym (final);
1949 last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
1950 sub_ns->code = last_code;
1952 /* Set: is_contiguous = .true. */
1953 last_code->next = gfc_get_code (EXEC_ASSIGN);
1954 last_code = last_code->next;
1955 last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
1956 last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
1957 &gfc_current_locus, true);
1959 /* Set: sizes(0) = 1. */
1960 last_code->next = gfc_get_code (EXEC_ASSIGN);
1961 last_code = last_code->next;
1962 last_code->expr1 = gfc_lval_expr_from_sym (sizes);
1963 last_code->expr1->ref = gfc_get_ref ();
1964 last_code->expr1->ref->type = REF_ARRAY;
1965 last_code->expr1->ref->u.ar.type = AR_ELEMENT;
1966 last_code->expr1->ref->u.ar.dimen = 1;
1967 last_code->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
1968 last_code->expr1->ref->u.ar.start[0]
1969 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
1970 last_code->expr1->ref->u.ar.as = sizes->as;
1971 last_code->expr2 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1973 /* Create:
1974 DO idx = 1, rank
1975 strides(idx) = _F._stride (array, dim=idx)
1976 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1977 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1978 END DO. */
1980 /* Create loop. */
1981 iter = gfc_get_iterator ();
1982 iter->var = gfc_lval_expr_from_sym (idx);
1983 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1984 iter->end = gfc_copy_expr (rank);
1985 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
1986 last_code->next = gfc_get_code (EXEC_DO);
1987 last_code = last_code->next;
1988 last_code->ext.iterator = iter;
1989 last_code->block = gfc_get_code (EXEC_DO);
1991 /* strides(idx) = _F._stride(array,dim=idx). */
1992 last_code->block->next = gfc_get_code (EXEC_ASSIGN);
1993 block = last_code->block->next;
1995 block->expr1 = gfc_lval_expr_from_sym (strides);
1996 block->expr1->ref = gfc_get_ref ();
1997 block->expr1->ref->type = REF_ARRAY;
1998 block->expr1->ref->u.ar.type = AR_ELEMENT;
1999 block->expr1->ref->u.ar.dimen = 1;
2000 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2001 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
2002 block->expr1->ref->u.ar.as = strides->as;
2004 block->expr2 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_STRIDE, "stride",
2005 gfc_current_locus, 2,
2006 gfc_lval_expr_from_sym (array),
2007 gfc_lval_expr_from_sym (idx));
2009 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
2010 block->next = gfc_get_code (EXEC_ASSIGN);
2011 block = block->next;
2013 /* sizes(idx) = ... */
2014 block->expr1 = gfc_lval_expr_from_sym (sizes);
2015 block->expr1->ref = gfc_get_ref ();
2016 block->expr1->ref->type = REF_ARRAY;
2017 block->expr1->ref->u.ar.type = AR_ELEMENT;
2018 block->expr1->ref->u.ar.dimen = 1;
2019 block->expr1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2020 block->expr1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
2021 block->expr1->ref->u.ar.as = sizes->as;
2023 block->expr2 = gfc_get_expr ();
2024 block->expr2->expr_type = EXPR_OP;
2025 block->expr2->value.op.op = INTRINSIC_TIMES;
2026 block->expr2->where = gfc_current_locus;
2028 /* sizes(idx-1). */
2029 block->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
2030 block->expr2->value.op.op1->ref = gfc_get_ref ();
2031 block->expr2->value.op.op1->ref->type = REF_ARRAY;
2032 block->expr2->value.op.op1->ref->u.ar.as = sizes->as;
2033 block->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
2034 block->expr2->value.op.op1->ref->u.ar.dimen = 1;
2035 block->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2036 block->expr2->value.op.op1->ref->u.ar.start[0] = gfc_get_expr ();
2037 block->expr2->value.op.op1->ref->u.ar.start[0]->expr_type = EXPR_OP;
2038 block->expr2->value.op.op1->ref->u.ar.start[0]->where = gfc_current_locus;
2039 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
2040 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1
2041 = gfc_lval_expr_from_sym (idx);
2042 block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op2
2043 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2044 block->expr2->value.op.op1->ref->u.ar.start[0]->ts
2045 = block->expr2->value.op.op1->ref->u.ar.start[0]->value.op.op1->ts;
2047 /* size(array, dim=idx, kind=index_kind). */
2048 block->expr2->value.op.op2
2049 = gfc_build_intrinsic_call (sub_ns, GFC_ISYM_SIZE, "size",
2050 gfc_current_locus, 3,
2051 gfc_lval_expr_from_sym (array),
2052 gfc_lval_expr_from_sym (idx),
2053 gfc_get_int_expr (gfc_index_integer_kind,
2054 NULL,
2055 gfc_index_integer_kind));
2056 block->expr2->value.op.op2->ts.kind = gfc_index_integer_kind;
2057 block->expr2->ts = idx->ts;
2059 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
2060 block->next = gfc_get_code (EXEC_IF);
2061 block = block->next;
2063 block->block = gfc_get_code (EXEC_IF);
2064 block = block->block;
2066 /* if condition: strides(idx) /= sizes(idx-1). */
2067 block->expr1 = gfc_get_expr ();
2068 block->expr1->ts.type = BT_LOGICAL;
2069 block->expr1->ts.kind = gfc_default_logical_kind;
2070 block->expr1->expr_type = EXPR_OP;
2071 block->expr1->where = gfc_current_locus;
2072 block->expr1->value.op.op = INTRINSIC_NE;
2074 block->expr1->value.op.op1 = gfc_lval_expr_from_sym (strides);
2075 block->expr1->value.op.op1->ref = gfc_get_ref ();
2076 block->expr1->value.op.op1->ref->type = REF_ARRAY;
2077 block->expr1->value.op.op1->ref->u.ar.type = AR_ELEMENT;
2078 block->expr1->value.op.op1->ref->u.ar.dimen = 1;
2079 block->expr1->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2080 block->expr1->value.op.op1->ref->u.ar.start[0] = gfc_lval_expr_from_sym (idx);
2081 block->expr1->value.op.op1->ref->u.ar.as = strides->as;
2083 block->expr1->value.op.op2 = gfc_lval_expr_from_sym (sizes);
2084 block->expr1->value.op.op2->ref = gfc_get_ref ();
2085 block->expr1->value.op.op2->ref->type = REF_ARRAY;
2086 block->expr1->value.op.op2->ref->u.ar.as = sizes->as;
2087 block->expr1->value.op.op2->ref->u.ar.type = AR_ELEMENT;
2088 block->expr1->value.op.op2->ref->u.ar.dimen = 1;
2089 block->expr1->value.op.op2->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2090 block->expr1->value.op.op2->ref->u.ar.start[0] = gfc_get_expr ();
2091 block->expr1->value.op.op2->ref->u.ar.start[0]->expr_type = EXPR_OP;
2092 block->expr1->value.op.op2->ref->u.ar.start[0]->where = gfc_current_locus;
2093 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op = INTRINSIC_MINUS;
2094 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1
2095 = gfc_lval_expr_from_sym (idx);
2096 block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op2
2097 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2098 block->expr1->value.op.op2->ref->u.ar.start[0]->ts
2099 = block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
2101 /* if body: is_contiguous = .false. */
2102 block->next = gfc_get_code (EXEC_ASSIGN);
2103 block = block->next;
2104 block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
2105 block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
2106 &gfc_current_locus, false);
2108 /* Obtain the size (number of elements) of "array" MINUS ONE,
2109 which is used in the scalarization. */
2110 gfc_get_symbol ("nelem", sub_ns, &nelem);
2111 nelem->ts.type = BT_INTEGER;
2112 nelem->ts.kind = gfc_index_integer_kind;
2113 nelem->attr.flavor = FL_VARIABLE;
2114 nelem->attr.artificial = 1;
2115 gfc_set_sym_referenced (nelem);
2116 gfc_commit_symbol (nelem);
2118 /* nelem = sizes (rank) - 1. */
2119 last_code->next = gfc_get_code (EXEC_ASSIGN);
2120 last_code = last_code->next;
2122 last_code->expr1 = gfc_lval_expr_from_sym (nelem);
2124 last_code->expr2 = gfc_get_expr ();
2125 last_code->expr2->expr_type = EXPR_OP;
2126 last_code->expr2->value.op.op = INTRINSIC_MINUS;
2127 last_code->expr2->value.op.op2
2128 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2129 last_code->expr2->ts = last_code->expr2->value.op.op2->ts;
2130 last_code->expr2->where = gfc_current_locus;
2132 last_code->expr2->value.op.op1 = gfc_lval_expr_from_sym (sizes);
2133 last_code->expr2->value.op.op1->ref = gfc_get_ref ();
2134 last_code->expr2->value.op.op1->ref->type = REF_ARRAY;
2135 last_code->expr2->value.op.op1->ref->u.ar.type = AR_ELEMENT;
2136 last_code->expr2->value.op.op1->ref->u.ar.dimen = 1;
2137 last_code->expr2->value.op.op1->ref->u.ar.dimen_type[0] = DIMEN_ELEMENT;
2138 last_code->expr2->value.op.op1->ref->u.ar.start[0] = gfc_copy_expr (rank);
2139 last_code->expr2->value.op.op1->ref->u.ar.as = sizes->as;
2141 /* Call final subroutines. We now generate code like:
2142 use iso_c_binding
2143 integer, pointer :: ptr
2144 type(c_ptr) :: cptr
2145 integer(c_intptr_t) :: i, addr
2147 select case (rank (array))
2148 case (3)
2149 ! If needed, the array is packed
2150 call final_rank3 (array)
2151 case default:
2152 do i = 0, size (array)-1
2153 addr = transfer (c_loc (array), addr) + i * stride
2154 call c_f_pointer (transfer (addr, cptr), ptr)
2155 call elemental_final (ptr)
2156 end do
2157 end select */
2159 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2161 gfc_finalizer *fini, *fini_elem = NULL;
2163 gfc_get_symbol ("ptr1", sub_ns, &ptr);
2164 ptr->ts.type = BT_DERIVED;
2165 ptr->ts.u.derived = derived;
2166 ptr->attr.flavor = FL_VARIABLE;
2167 ptr->attr.pointer = 1;
2168 ptr->attr.artificial = 1;
2169 gfc_set_sym_referenced (ptr);
2170 gfc_commit_symbol (ptr);
2172 fini = derived->f2k_derived->finalizers;
2174 /* Assumed rank finalizers can be called directly. The call takes care
2175 of setting up the descriptor. resolve_finalizers has already checked
2176 that this is the only finalizer for this kind/type (F2018: C790). */
2177 if (fini->proc_tree && fini->proc_tree->n.sym->formal->sym->as
2178 && fini->proc_tree->n.sym->formal->sym->as->type == AS_ASSUMED_RANK)
2180 last_code->next = gfc_get_code (EXEC_CALL);
2181 last_code->next->symtree = fini->proc_tree;
2182 last_code->next->resolved_sym = fini->proc_tree->n.sym;
2183 last_code->next->ext.actual = gfc_get_actual_arglist ();
2184 last_code->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
2186 last_code = last_code->next;
2187 goto finish_assumed_rank;
2190 /* SELECT CASE (RANK (array)). */
2191 last_code->next = gfc_get_code (EXEC_SELECT);
2192 last_code = last_code->next;
2193 last_code->expr1 = gfc_copy_expr (rank);
2194 block = NULL;
2197 for (; fini; fini = fini->next)
2199 gcc_assert (fini->proc_tree); /* Should have been set in gfc_resolve_finalizers. */
2200 if (fini->proc_tree->n.sym->attr.elemental)
2202 fini_elem = fini;
2203 continue;
2206 /* CASE (fini_rank). */
2207 if (block)
2209 block->block = gfc_get_code (EXEC_SELECT);
2210 block = block->block;
2212 else
2214 block = gfc_get_code (EXEC_SELECT);
2215 last_code->block = block;
2217 block->ext.block.case_list = gfc_get_case ();
2218 block->ext.block.case_list->where = gfc_current_locus;
2219 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2220 block->ext.block.case_list->low
2221 = gfc_get_int_expr (gfc_default_integer_kind, NULL,
2222 fini->proc_tree->n.sym->formal->sym->as->rank);
2223 else
2224 block->ext.block.case_list->low
2225 = gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
2226 block->ext.block.case_list->high
2227 = gfc_copy_expr (block->ext.block.case_list->low);
2229 /* CALL fini_rank (array) - possibly with packing. */
2230 if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
2231 finalizer_insert_packed_call (block, fini, array, byte_stride,
2232 idx, ptr, nelem, strides,
2233 sizes, idx2, offset, is_contiguous,
2234 rank, sub_ns);
2235 else
2237 block->next = gfc_get_code (EXEC_CALL);
2238 block->next->symtree = fini->proc_tree;
2239 block->next->resolved_sym = fini->proc_tree->n.sym;
2240 block->next->ext.actual = gfc_get_actual_arglist ();
2241 block->next->ext.actual->expr = gfc_lval_expr_from_sym (array);
2245 /* Elemental call - scalarized. */
2246 if (fini_elem)
2248 /* CASE DEFAULT. */
2249 if (block)
2251 block->block = gfc_get_code (EXEC_SELECT);
2252 block = block->block;
2254 else
2256 block = gfc_get_code (EXEC_SELECT);
2257 last_code->block = block;
2259 block->ext.block.case_list = gfc_get_case ();
2261 /* Create loop. */
2262 iter = gfc_get_iterator ();
2263 iter->var = gfc_lval_expr_from_sym (idx);
2264 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2265 iter->end = gfc_lval_expr_from_sym (nelem);
2266 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2267 block->next = gfc_get_code (EXEC_DO);
2268 block = block->next;
2269 block->ext.iterator = iter;
2270 block->block = gfc_get_code (EXEC_DO);
2272 /* Offset calculation. */
2273 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2274 byte_stride, rank, block->block,
2275 sub_ns);
2277 /* Create code for
2278 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2279 + offset, c_ptr), ptr). */
2280 block->next
2281 = finalization_scalarizer (array, ptr,
2282 gfc_lval_expr_from_sym (offset),
2283 sub_ns);
2284 block = block->next;
2286 /* CALL final_elemental (array). */
2287 block->next = gfc_get_code (EXEC_CALL);
2288 block = block->next;
2289 block->symtree = fini_elem->proc_tree;
2290 block->resolved_sym = fini_elem->proc_sym;
2291 block->ext.actual = gfc_get_actual_arglist ();
2292 block->ext.actual->expr = gfc_lval_expr_from_sym (ptr);
2296 finish_assumed_rank:
2298 /* Finalize and deallocate allocatable components. The same manual
2299 scalarization is used as above. */
2301 if (finalizable_comp)
2303 gfc_symbol *stat;
2304 gfc_code *block = NULL;
2306 if (!ptr)
2308 gfc_get_symbol ("ptr2", sub_ns, &ptr);
2309 ptr->ts.type = BT_DERIVED;
2310 ptr->ts.u.derived = derived;
2311 ptr->attr.flavor = FL_VARIABLE;
2312 ptr->attr.pointer = 1;
2313 ptr->attr.artificial = 1;
2314 gfc_set_sym_referenced (ptr);
2315 gfc_commit_symbol (ptr);
2318 gfc_get_symbol ("ignore", sub_ns, &stat);
2319 stat->attr.flavor = FL_VARIABLE;
2320 stat->attr.artificial = 1;
2321 stat->ts.type = BT_INTEGER;
2322 stat->ts.kind = gfc_default_integer_kind;
2323 gfc_set_sym_referenced (stat);
2324 gfc_commit_symbol (stat);
2326 /* Create loop. */
2327 iter = gfc_get_iterator ();
2328 iter->var = gfc_lval_expr_from_sym (idx);
2329 iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
2330 iter->end = gfc_lval_expr_from_sym (nelem);
2331 iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
2332 last_code->next = gfc_get_code (EXEC_DO);
2333 last_code = last_code->next;
2334 last_code->ext.iterator = iter;
2335 last_code->block = gfc_get_code (EXEC_DO);
2337 /* Offset calculation. */
2338 block = finalization_get_offset (idx, idx2, offset, strides, sizes,
2339 byte_stride, rank, last_code->block,
2340 sub_ns);
2342 /* Create code for
2343 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2344 + idx * stride, c_ptr), ptr). */
2345 block->next = finalization_scalarizer (array, ptr,
2346 gfc_lval_expr_from_sym(offset),
2347 sub_ns);
2348 block = block->next;
2350 for (comp = derived->components; comp; comp = comp->next)
2352 if (comp == derived->components && derived->attr.extension
2353 && ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2354 continue;
2356 finalize_component (gfc_lval_expr_from_sym (ptr), derived, comp,
2357 stat, fini_coarray, &block, sub_ns);
2358 if (!last_code->block->next)
2359 last_code->block->next = block;
2364 /* Call the finalizer of the ancestor. */
2365 if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
2367 last_code->next = gfc_get_code (EXEC_CALL);
2368 last_code = last_code->next;
2369 last_code->symtree = ancestor_wrapper->symtree;
2370 last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
2372 last_code->ext.actual = gfc_get_actual_arglist ();
2373 last_code->ext.actual->expr = gfc_lval_expr_from_sym (array);
2374 last_code->ext.actual->next = gfc_get_actual_arglist ();
2375 last_code->ext.actual->next->expr = gfc_lval_expr_from_sym (byte_stride);
2376 last_code->ext.actual->next->next = gfc_get_actual_arglist ();
2377 last_code->ext.actual->next->next->expr
2378 = gfc_lval_expr_from_sym (fini_coarray);
2381 gfc_free_expr (rank);
2382 vtab_final->initializer = gfc_lval_expr_from_sym (final);
2383 vtab_final->ts.interface = final;
2384 free (name);
2388 /* Add procedure pointers for all type-bound procedures to a vtab. */
2390 static void
2391 add_procs_to_declared_vtab (gfc_symbol *derived, gfc_symbol *vtype)
2393 gfc_symbol* super_type;
2395 super_type = gfc_get_derived_super_type (derived);
2397 if (super_type && (super_type != derived))
2399 /* Make sure that the PPCs appear in the same order as in the parent. */
2400 copy_vtab_proc_comps (super_type, vtype);
2401 /* Only needed to get the PPC initializers right. */
2402 add_procs_to_declared_vtab (super_type, vtype);
2405 if (derived->f2k_derived && derived->f2k_derived->tb_sym_root)
2406 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_sym_root, vtype);
2408 if (derived->f2k_derived && derived->f2k_derived->tb_uop_root)
2409 add_procs_to_declared_vtab1 (derived->f2k_derived->tb_uop_root, vtype);
2413 /* Find or generate the symbol for a derived type's vtab. */
2415 gfc_symbol *
2416 gfc_find_derived_vtab (gfc_symbol *derived)
2418 gfc_namespace *ns;
2419 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL, *def_init = NULL;
2420 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2421 gfc_gsymbol *gsym = NULL;
2422 gfc_symbol *dealloc = NULL, *arg = NULL;
2424 if (derived->attr.pdt_template)
2425 return NULL;
2427 /* Find the top-level namespace. */
2428 for (ns = gfc_current_ns; ns; ns = ns->parent)
2429 if (!ns->parent)
2430 break;
2432 /* If the type is a class container, use the underlying derived type. */
2433 if (!derived->attr.unlimited_polymorphic && derived->attr.is_class)
2434 derived = gfc_get_derived_super_type (derived);
2436 if (!derived)
2437 return NULL;
2439 if (!derived->name)
2440 return NULL;
2442 /* Find the gsymbol for the module of use associated derived types. */
2443 if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
2444 && !derived->attr.vtype && !derived->attr.is_class)
2445 gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module);
2446 else
2447 gsym = NULL;
2449 /* Work in the gsymbol namespace if the top-level namespace is a module.
2450 This ensures that the vtable is unique, which is required since we use
2451 its address in SELECT TYPE. */
2452 if (gsym && gsym->ns && ns && ns->proc_name
2453 && ns->proc_name->attr.flavor == FL_MODULE)
2454 ns = gsym->ns;
2456 if (ns)
2458 char tname[GFC_MAX_SYMBOL_LEN+1];
2459 char *name;
2461 get_unique_hashed_string (tname, derived);
2462 name = xasprintf ("__vtab_%s", tname);
2464 /* Look for the vtab symbol in various namespaces. */
2465 if (gsym && gsym->ns)
2467 gfc_find_symbol (name, gsym->ns, 0, &vtab);
2468 if (vtab)
2469 ns = gsym->ns;
2471 if (vtab == NULL)
2472 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
2473 if (vtab == NULL)
2474 gfc_find_symbol (name, ns, 0, &vtab);
2475 if (vtab == NULL)
2476 gfc_find_symbol (name, derived->ns, 0, &vtab);
2478 if (vtab == NULL)
2480 gfc_get_symbol (name, ns, &vtab);
2481 vtab->ts.type = BT_DERIVED;
2482 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2483 &gfc_current_locus))
2484 goto cleanup;
2485 vtab->attr.target = 1;
2486 vtab->attr.save = SAVE_IMPLICIT;
2487 vtab->attr.vtab = 1;
2488 vtab->attr.access = ACCESS_PUBLIC;
2489 gfc_set_sym_referenced (vtab);
2490 free (name);
2491 name = xasprintf ("__vtype_%s", tname);
2493 gfc_find_symbol (name, ns, 0, &vtype);
2494 if (vtype == NULL)
2496 gfc_component *c;
2497 gfc_symbol *parent = NULL, *parent_vtab = NULL;
2498 bool rdt = false;
2500 /* Is this a derived type with recursive allocatable
2501 components? */
2502 c = (derived->attr.unlimited_polymorphic
2503 || derived->attr.abstract) ?
2504 NULL : derived->components;
2505 for (; c; c= c->next)
2506 if (c->ts.type == BT_DERIVED
2507 && c->ts.u.derived == derived)
2509 rdt = true;
2510 break;
2513 gfc_get_symbol (name, ns, &vtype);
2514 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2515 &gfc_current_locus))
2516 goto cleanup;
2517 vtype->attr.access = ACCESS_PUBLIC;
2518 vtype->attr.vtype = 1;
2519 gfc_set_sym_referenced (vtype);
2521 /* Add component '_hash'. */
2522 if (!gfc_add_component (vtype, "_hash", &c))
2523 goto cleanup;
2524 c->ts.type = BT_INTEGER;
2525 c->ts.kind = 4;
2526 c->attr.access = ACCESS_PRIVATE;
2527 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2528 NULL, derived->hash_value);
2530 /* Add component '_size'. */
2531 if (!gfc_add_component (vtype, "_size", &c))
2532 goto cleanup;
2533 c->ts.type = BT_INTEGER;
2534 c->ts.kind = gfc_size_kind;
2535 c->attr.access = ACCESS_PRIVATE;
2536 /* Remember the derived type in ts.u.derived,
2537 so that the correct initializer can be set later on
2538 (in gfc_conv_structure). */
2539 c->ts.u.derived = derived;
2540 c->initializer = gfc_get_int_expr (gfc_size_kind,
2541 NULL, 0);
2543 /* Add component _extends. */
2544 if (!gfc_add_component (vtype, "_extends", &c))
2545 goto cleanup;
2546 c->attr.pointer = 1;
2547 c->attr.access = ACCESS_PRIVATE;
2548 if (!derived->attr.unlimited_polymorphic)
2549 parent = gfc_get_derived_super_type (derived);
2550 else
2551 parent = NULL;
2553 if (parent)
2555 parent_vtab = gfc_find_derived_vtab (parent);
2556 c->ts.type = BT_DERIVED;
2557 c->ts.u.derived = parent_vtab->ts.u.derived;
2558 c->initializer = gfc_get_expr ();
2559 c->initializer->expr_type = EXPR_VARIABLE;
2560 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2561 0, &c->initializer->symtree);
2563 else
2565 c->ts.type = BT_DERIVED;
2566 c->ts.u.derived = vtype;
2567 c->initializer = gfc_get_null_expr (NULL);
2570 if (!derived->attr.unlimited_polymorphic
2571 && derived->components == NULL
2572 && !derived->attr.zero_comp)
2574 /* At this point an error must have occurred.
2575 Prevent further errors on the vtype components. */
2576 found_sym = vtab;
2577 goto have_vtype;
2580 /* Add component _def_init. */
2581 if (!gfc_add_component (vtype, "_def_init", &c))
2582 goto cleanup;
2583 c->attr.pointer = 1;
2584 c->attr.artificial = 1;
2585 c->attr.access = ACCESS_PRIVATE;
2586 c->ts.type = BT_DERIVED;
2587 c->ts.u.derived = derived;
2588 if (derived->attr.unlimited_polymorphic
2589 || derived->attr.abstract)
2590 c->initializer = gfc_get_null_expr (NULL);
2591 else
2593 /* Construct default initialization variable. */
2594 free (name);
2595 name = xasprintf ("__def_init_%s", tname);
2596 gfc_get_symbol (name, ns, &def_init);
2597 def_init->attr.target = 1;
2598 def_init->attr.artificial = 1;
2599 def_init->attr.save = SAVE_IMPLICIT;
2600 def_init->attr.access = ACCESS_PUBLIC;
2601 def_init->attr.flavor = FL_VARIABLE;
2602 gfc_set_sym_referenced (def_init);
2603 def_init->ts.type = BT_DERIVED;
2604 def_init->ts.u.derived = derived;
2605 def_init->value = gfc_default_initializer (&def_init->ts);
2607 c->initializer = gfc_lval_expr_from_sym (def_init);
2610 /* Add component _copy. */
2611 if (!gfc_add_component (vtype, "_copy", &c))
2612 goto cleanup;
2613 c->attr.proc_pointer = 1;
2614 c->attr.access = ACCESS_PRIVATE;
2615 c->tb = XCNEW (gfc_typebound_proc);
2616 c->tb->ppc = 1;
2617 if (derived->attr.unlimited_polymorphic
2618 || derived->attr.abstract)
2619 c->initializer = gfc_get_null_expr (NULL);
2620 else
2622 /* Set up namespace. */
2623 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2624 sub_ns->sibling = ns->contained;
2625 ns->contained = sub_ns;
2626 sub_ns->resolved = 1;
2627 /* Set up procedure symbol. */
2628 free (name);
2629 name = xasprintf ("__copy_%s", tname);
2630 gfc_get_symbol (name, sub_ns, &copy);
2631 sub_ns->proc_name = copy;
2632 copy->attr.flavor = FL_PROCEDURE;
2633 copy->attr.subroutine = 1;
2634 copy->attr.pure = 1;
2635 copy->attr.artificial = 1;
2636 copy->attr.if_source = IFSRC_DECL;
2637 /* This is elemental so that arrays are automatically
2638 treated correctly by the scalarizer. */
2639 copy->attr.elemental = 1;
2640 if (ns->proc_name->attr.flavor == FL_MODULE)
2641 copy->module = ns->proc_name->name;
2642 gfc_set_sym_referenced (copy);
2643 /* Set up formal arguments. */
2644 gfc_get_symbol ("src", sub_ns, &src);
2645 src->ts.type = BT_DERIVED;
2646 src->ts.u.derived = derived;
2647 src->attr.flavor = FL_VARIABLE;
2648 src->attr.dummy = 1;
2649 src->attr.artificial = 1;
2650 src->attr.intent = INTENT_IN;
2651 gfc_set_sym_referenced (src);
2652 copy->formal = gfc_get_formal_arglist ();
2653 copy->formal->sym = src;
2654 gfc_get_symbol ("dst", sub_ns, &dst);
2655 dst->ts.type = BT_DERIVED;
2656 dst->ts.u.derived = derived;
2657 dst->attr.flavor = FL_VARIABLE;
2658 dst->attr.dummy = 1;
2659 dst->attr.artificial = 1;
2660 dst->attr.intent = INTENT_INOUT;
2661 gfc_set_sym_referenced (dst);
2662 copy->formal->next = gfc_get_formal_arglist ();
2663 copy->formal->next->sym = dst;
2664 /* Set up code. */
2665 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
2666 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2667 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2668 /* Set initializer. */
2669 c->initializer = gfc_lval_expr_from_sym (copy);
2670 c->ts.interface = copy;
2673 /* Add component _final, which contains a procedure pointer to
2674 a wrapper which handles both the freeing of allocatable
2675 components and the calls to finalization subroutines.
2676 Note: The actual wrapper function can only be generated
2677 at resolution time. */
2678 if (!gfc_add_component (vtype, "_final", &c))
2679 goto cleanup;
2680 c->attr.proc_pointer = 1;
2681 c->attr.access = ACCESS_PRIVATE;
2682 c->attr.artificial = 1;
2683 c->tb = XCNEW (gfc_typebound_proc);
2684 c->tb->ppc = 1;
2685 generate_finalization_wrapper (derived, ns, tname, c);
2687 /* Add component _deallocate. */
2688 if (!gfc_add_component (vtype, "_deallocate", &c))
2689 goto cleanup;
2690 c->attr.proc_pointer = 1;
2691 c->attr.access = ACCESS_PRIVATE;
2692 c->tb = XCNEW (gfc_typebound_proc);
2693 c->tb->ppc = 1;
2694 if (derived->attr.unlimited_polymorphic
2695 || derived->attr.abstract
2696 || !rdt)
2697 c->initializer = gfc_get_null_expr (NULL);
2698 else
2700 /* Set up namespace. */
2701 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2703 sub_ns->sibling = ns->contained;
2704 ns->contained = sub_ns;
2705 sub_ns->resolved = 1;
2706 /* Set up procedure symbol. */
2707 free (name);
2708 name = xasprintf ("__deallocate_%s", tname);
2709 gfc_get_symbol (name, sub_ns, &dealloc);
2710 sub_ns->proc_name = dealloc;
2711 dealloc->attr.flavor = FL_PROCEDURE;
2712 dealloc->attr.subroutine = 1;
2713 dealloc->attr.pure = 1;
2714 dealloc->attr.artificial = 1;
2715 dealloc->attr.if_source = IFSRC_DECL;
2717 if (ns->proc_name->attr.flavor == FL_MODULE)
2718 dealloc->module = ns->proc_name->name;
2719 gfc_set_sym_referenced (dealloc);
2720 /* Set up formal argument. */
2721 gfc_get_symbol ("arg", sub_ns, &arg);
2722 arg->ts.type = BT_DERIVED;
2723 arg->ts.u.derived = derived;
2724 arg->attr.flavor = FL_VARIABLE;
2725 arg->attr.dummy = 1;
2726 arg->attr.artificial = 1;
2727 arg->attr.intent = INTENT_INOUT;
2728 arg->attr.dimension = 1;
2729 arg->attr.allocatable = 1;
2730 arg->as = gfc_get_array_spec();
2731 arg->as->type = AS_ASSUMED_SHAPE;
2732 arg->as->rank = 1;
2733 arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
2734 NULL, 1);
2735 gfc_set_sym_referenced (arg);
2736 dealloc->formal = gfc_get_formal_arglist ();
2737 dealloc->formal->sym = arg;
2738 /* Set up code. */
2739 sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
2740 sub_ns->code->ext.alloc.list = gfc_get_alloc ();
2741 sub_ns->code->ext.alloc.list->expr
2742 = gfc_lval_expr_from_sym (arg);
2743 /* Set initializer. */
2744 c->initializer = gfc_lval_expr_from_sym (dealloc);
2745 c->ts.interface = dealloc;
2748 /* Add procedure pointers for type-bound procedures. */
2749 if (!derived->attr.unlimited_polymorphic)
2750 add_procs_to_declared_vtab (derived, vtype);
2753 have_vtype:
2754 vtab->ts.u.derived = vtype;
2755 vtab->value = gfc_default_initializer (&vtab->ts);
2757 free (name);
2760 found_sym = vtab;
2762 cleanup:
2763 /* It is unexpected to have some symbols added at resolution or code
2764 generation time. We commit the changes in order to keep a clean state. */
2765 if (found_sym)
2767 gfc_commit_symbol (vtab);
2768 if (vtype)
2769 gfc_commit_symbol (vtype);
2770 if (def_init)
2771 gfc_commit_symbol (def_init);
2772 if (copy)
2773 gfc_commit_symbol (copy);
2774 if (src)
2775 gfc_commit_symbol (src);
2776 if (dst)
2777 gfc_commit_symbol (dst);
2778 if (dealloc)
2779 gfc_commit_symbol (dealloc);
2780 if (arg)
2781 gfc_commit_symbol (arg);
2783 else
2784 gfc_undo_symbols ();
2786 return found_sym;
2790 /* Check if a derived type is finalizable. That is the case if it
2791 (1) has a FINAL subroutine or
2792 (2) has a nonpointer nonallocatable component of finalizable type.
2793 If it is finalizable, return an expression containing the
2794 finalization wrapper. */
2796 bool
2797 gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2799 gfc_symbol *vtab;
2800 gfc_component *c;
2802 /* (1) Check for FINAL subroutines. */
2803 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2804 goto yes;
2806 /* (2) Check for components of finalizable type. */
2807 for (c = derived->components; c; c = c->next)
2808 if (c->ts.type == BT_DERIVED
2809 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2810 && gfc_is_finalizable (c->ts.u.derived, NULL))
2811 goto yes;
2813 return false;
2815 yes:
2816 /* Make sure vtab is generated. */
2817 vtab = gfc_find_derived_vtab (derived);
2818 if (final_expr)
2820 /* Return finalizer expression. */
2821 gfc_component *final;
2822 final = vtab->ts.u.derived->components->next->next->next->next->next;
2823 gcc_assert (strcmp (final->name, "_final") == 0);
2824 gcc_assert (final->initializer
2825 && final->initializer->expr_type != EXPR_NULL);
2826 *final_expr = final->initializer;
2828 return true;
2832 bool
2833 gfc_may_be_finalized (gfc_typespec ts)
2835 return (ts.type == BT_CLASS || (ts.type == BT_DERIVED
2836 && ts.u.derived && gfc_is_finalizable (ts.u.derived, NULL)));
2840 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2841 needed to support unlimited polymorphism. */
2843 static gfc_symbol *
2844 find_intrinsic_vtab (gfc_typespec *ts)
2846 gfc_namespace *ns;
2847 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
2848 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
2850 /* Find the top-level namespace. */
2851 for (ns = gfc_current_ns; ns; ns = ns->parent)
2852 if (!ns->parent)
2853 break;
2855 if (ns)
2857 char tname[GFC_MAX_SYMBOL_LEN+1];
2858 char *name;
2860 /* Encode all types as TYPENAME_KIND_ including especially character
2861 arrays, whose length is now consistently stored in the _len component
2862 of the class-variable. */
2863 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2864 name = xasprintf ("__vtab_%s", tname);
2866 /* Look for the vtab symbol in the top-level namespace only. */
2867 gfc_find_symbol (name, ns, 0, &vtab);
2869 if (vtab == NULL)
2871 gfc_get_symbol (name, ns, &vtab);
2872 vtab->ts.type = BT_DERIVED;
2873 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
2874 &gfc_current_locus))
2875 goto cleanup;
2876 vtab->attr.target = 1;
2877 vtab->attr.save = SAVE_IMPLICIT;
2878 vtab->attr.vtab = 1;
2879 vtab->attr.access = ACCESS_PUBLIC;
2880 gfc_set_sym_referenced (vtab);
2881 free (name);
2882 name = xasprintf ("__vtype_%s", tname);
2884 gfc_find_symbol (name, ns, 0, &vtype);
2885 if (vtype == NULL)
2887 gfc_component *c;
2888 int hash;
2889 gfc_namespace *sub_ns;
2890 gfc_namespace *contained;
2891 gfc_expr *e;
2892 size_t e_size;
2894 gfc_get_symbol (name, ns, &vtype);
2895 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
2896 &gfc_current_locus))
2897 goto cleanup;
2898 vtype->attr.access = ACCESS_PUBLIC;
2899 vtype->attr.vtype = 1;
2900 gfc_set_sym_referenced (vtype);
2902 /* Add component '_hash'. */
2903 if (!gfc_add_component (vtype, "_hash", &c))
2904 goto cleanup;
2905 c->ts.type = BT_INTEGER;
2906 c->ts.kind = 4;
2907 c->attr.access = ACCESS_PRIVATE;
2908 hash = gfc_intrinsic_hash_value (ts);
2909 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2910 NULL, hash);
2912 /* Add component '_size'. */
2913 if (!gfc_add_component (vtype, "_size", &c))
2914 goto cleanup;
2915 c->ts.type = BT_INTEGER;
2916 c->ts.kind = gfc_size_kind;
2917 c->attr.access = ACCESS_PRIVATE;
2919 /* Build a minimal expression to make use of
2920 target-memory.cc/gfc_element_size for 'size'. Special handling
2921 for character arrays, that are not constant sized: to support
2922 len (str) * kind, only the kind information is stored in the
2923 vtab. */
2924 e = gfc_get_expr ();
2925 e->ts = *ts;
2926 e->expr_type = EXPR_VARIABLE;
2927 if (ts->type == BT_CHARACTER)
2928 e_size = ts->kind;
2929 else
2930 gfc_element_size (e, &e_size);
2931 c->initializer = gfc_get_int_expr (gfc_size_kind,
2932 NULL,
2933 e_size);
2934 gfc_free_expr (e);
2936 /* Add component _extends. */
2937 if (!gfc_add_component (vtype, "_extends", &c))
2938 goto cleanup;
2939 c->attr.pointer = 1;
2940 c->attr.access = ACCESS_PRIVATE;
2941 c->ts.type = BT_VOID;
2942 c->initializer = gfc_get_null_expr (NULL);
2944 /* Add component _def_init. */
2945 if (!gfc_add_component (vtype, "_def_init", &c))
2946 goto cleanup;
2947 c->attr.pointer = 1;
2948 c->attr.access = ACCESS_PRIVATE;
2949 c->ts.type = BT_VOID;
2950 c->initializer = gfc_get_null_expr (NULL);
2952 /* Add component _copy. */
2953 if (!gfc_add_component (vtype, "_copy", &c))
2954 goto cleanup;
2955 c->attr.proc_pointer = 1;
2956 c->attr.access = ACCESS_PRIVATE;
2957 c->tb = XCNEW (gfc_typebound_proc);
2958 c->tb->ppc = 1;
2960 free (name);
2961 if (ts->type != BT_CHARACTER)
2962 name = xasprintf ("__copy_%s", tname);
2963 else
2965 /* __copy is always the same for characters.
2966 Check to see if copy function already exists. */
2967 name = xasprintf ("__copy_character_%d", ts->kind);
2968 contained = ns->contained;
2969 for (; contained; contained = contained->sibling)
2970 if (contained->proc_name
2971 && strcmp (name, contained->proc_name->name) == 0)
2973 copy = contained->proc_name;
2974 goto got_char_copy;
2978 /* Set up namespace. */
2979 sub_ns = gfc_get_namespace (ns, 0);
2980 sub_ns->sibling = ns->contained;
2981 ns->contained = sub_ns;
2982 sub_ns->resolved = 1;
2983 /* Set up procedure symbol. */
2984 gfc_get_symbol (name, sub_ns, &copy);
2985 sub_ns->proc_name = copy;
2986 copy->attr.flavor = FL_PROCEDURE;
2987 copy->attr.subroutine = 1;
2988 copy->attr.pure = 1;
2989 copy->attr.if_source = IFSRC_DECL;
2990 /* This is elemental so that arrays are automatically
2991 treated correctly by the scalarizer. */
2992 copy->attr.elemental = 1;
2993 if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
2994 copy->module = ns->proc_name->name;
2995 gfc_set_sym_referenced (copy);
2996 /* Set up formal arguments. */
2997 gfc_get_symbol ("src", sub_ns, &src);
2998 src->ts.type = ts->type;
2999 src->ts.kind = ts->kind;
3000 src->attr.flavor = FL_VARIABLE;
3001 src->attr.dummy = 1;
3002 src->attr.intent = INTENT_IN;
3003 gfc_set_sym_referenced (src);
3004 copy->formal = gfc_get_formal_arglist ();
3005 copy->formal->sym = src;
3006 gfc_get_symbol ("dst", sub_ns, &dst);
3007 dst->ts.type = ts->type;
3008 dst->ts.kind = ts->kind;
3009 dst->attr.flavor = FL_VARIABLE;
3010 dst->attr.dummy = 1;
3011 dst->attr.intent = INTENT_INOUT;
3012 gfc_set_sym_referenced (dst);
3013 copy->formal->next = gfc_get_formal_arglist ();
3014 copy->formal->next->sym = dst;
3015 /* Set up code. */
3016 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
3017 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
3018 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
3019 got_char_copy:
3020 /* Set initializer. */
3021 c->initializer = gfc_lval_expr_from_sym (copy);
3022 c->ts.interface = copy;
3024 /* Add component _final. */
3025 if (!gfc_add_component (vtype, "_final", &c))
3026 goto cleanup;
3027 c->attr.proc_pointer = 1;
3028 c->attr.access = ACCESS_PRIVATE;
3029 c->attr.artificial = 1;
3030 c->tb = XCNEW (gfc_typebound_proc);
3031 c->tb->ppc = 1;
3032 c->initializer = gfc_get_null_expr (NULL);
3034 vtab->ts.u.derived = vtype;
3035 vtab->value = gfc_default_initializer (&vtab->ts);
3037 free (name);
3040 found_sym = vtab;
3042 cleanup:
3043 /* It is unexpected to have some symbols added at resolution or code
3044 generation time. We commit the changes in order to keep a clean state. */
3045 if (found_sym)
3047 gfc_commit_symbol (vtab);
3048 if (vtype)
3049 gfc_commit_symbol (vtype);
3050 if (copy)
3051 gfc_commit_symbol (copy);
3052 if (src)
3053 gfc_commit_symbol (src);
3054 if (dst)
3055 gfc_commit_symbol (dst);
3057 else
3058 gfc_undo_symbols ();
3060 return found_sym;
3064 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
3066 gfc_symbol *
3067 gfc_find_vtab (gfc_typespec *ts)
3069 switch (ts->type)
3071 case BT_UNKNOWN:
3072 return NULL;
3073 case BT_DERIVED:
3074 return gfc_find_derived_vtab (ts->u.derived);
3075 case BT_CLASS:
3076 if (ts->u.derived->attr.is_class
3077 && ts->u.derived->components
3078 && ts->u.derived->components->ts.u.derived)
3079 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
3080 else
3081 return NULL;
3082 default:
3083 return find_intrinsic_vtab (ts);
3088 /* General worker function to find either a type-bound procedure or a
3089 type-bound user operator. */
3091 static gfc_symtree*
3092 find_typebound_proc_uop (gfc_symbol* derived, bool* t,
3093 const char* name, bool noaccess, bool uop,
3094 locus* where)
3096 gfc_symtree* res;
3097 gfc_symtree* root;
3099 /* Set default to failure. */
3100 if (t)
3101 *t = false;
3103 if (derived->f2k_derived)
3104 /* Set correct symbol-root. */
3105 root = (uop ? derived->f2k_derived->tb_uop_root
3106 : derived->f2k_derived->tb_sym_root);
3107 else
3108 return NULL;
3110 /* Try to find it in the current type's namespace. */
3111 res = gfc_find_symtree (root, name);
3112 if (res && res->n.tb && !res->n.tb->error)
3114 /* We found one. */
3115 if (t)
3116 *t = true;
3118 if (!noaccess && derived->attr.use_assoc
3119 && res->n.tb->access == ACCESS_PRIVATE)
3121 if (where)
3122 gfc_error ("%qs of %qs is PRIVATE at %L",
3123 name, derived->name, where);
3124 if (t)
3125 *t = false;
3128 return res;
3131 /* Otherwise, recurse on parent type if derived is an extension. */
3132 if (derived->attr.extension)
3134 gfc_symbol* super_type;
3135 super_type = gfc_get_derived_super_type (derived);
3136 gcc_assert (super_type);
3138 return find_typebound_proc_uop (super_type, t, name,
3139 noaccess, uop, where);
3142 /* Nothing found. */
3143 return NULL;
3147 /* Find a type-bound procedure or user operator by name for a derived-type
3148 (looking recursively through the super-types). */
3150 gfc_symtree*
3151 gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
3152 const char* name, bool noaccess, locus* where)
3154 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
3157 gfc_symtree*
3158 gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
3159 const char* name, bool noaccess, locus* where)
3161 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
3165 /* Find a type-bound intrinsic operator looking recursively through the
3166 super-type hierarchy. */
3168 gfc_typebound_proc*
3169 gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
3170 gfc_intrinsic_op op, bool noaccess,
3171 locus* where)
3173 gfc_typebound_proc* res;
3175 /* Set default to failure. */
3176 if (t)
3177 *t = false;
3179 /* Try to find it in the current type's namespace. */
3180 if (derived->f2k_derived)
3181 res = derived->f2k_derived->tb_op[op];
3182 else
3183 res = NULL;
3185 /* Check access. */
3186 if (res && !res->error)
3188 /* We found one. */
3189 if (t)
3190 *t = true;
3192 if (!noaccess && derived->attr.use_assoc
3193 && res->access == ACCESS_PRIVATE)
3195 if (where)
3196 gfc_error ("%qs of %qs is PRIVATE at %L",
3197 gfc_op2string (op), derived->name, where);
3198 if (t)
3199 *t = false;
3202 return res;
3205 /* Otherwise, recurse on parent type if derived is an extension. */
3206 if (derived->attr.extension)
3208 gfc_symbol* super_type;
3209 super_type = gfc_get_derived_super_type (derived);
3210 gcc_assert (super_type);
3212 return gfc_find_typebound_intrinsic_op (super_type, t, op,
3213 noaccess, where);
3216 /* Nothing found. */
3217 return NULL;
3221 /* Get a typebound-procedure symtree or create and insert it if not yet
3222 present. This is like a very simplified version of gfc_get_sym_tree for
3223 tbp-symtrees rather than regular ones. */
3225 gfc_symtree*
3226 gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
3228 gfc_symtree *result = gfc_find_symtree (*root, name);
3229 return result ? result : gfc_new_symtree (root, name);