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