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