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