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