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