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