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