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