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