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