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