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