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