]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/class.c
PR libstdc++/92143 adjust for OS X aligned_alloc behaviour
[thirdparty/gcc.git] / gcc / fortran / class.c
CommitLineData
d15bac21 1/* Implementation of Fortran 2003 Polymorphism.
a5544970 2 Copyright (C) 2009-2019 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
dfd6231e
PT
2244 /* Find the gsymbol for the module of use associated derived types. */
2245 if ((derived->attr.use_assoc || derived->attr.used_in_submodule)
2246 && !derived->attr.vtype && !derived->attr.is_class)
2247 gsym = gfc_find_gsymbol (gfc_gsym_root, derived->module);
2248 else
2249 gsym = NULL;
2250
2251 /* Work in the gsymbol namespace if the top-level namespace is a module.
2252 This ensures that the vtable is unique, which is required since we use
2253 its address in SELECT TYPE. */
2254 if (gsym && gsym->ns && ns && ns->proc_name
2255 && ns->proc_name->attr.flavor == FL_MODULE)
2256 ns = gsym->ns;
2257
d15bac21
JW
2258 if (ns)
2259 {
2004617a
QZ
2260 char tname[GFC_MAX_SYMBOL_LEN+1];
2261 char *name;
29a7d776 2262
4fa02692 2263 get_unique_hashed_string (tname, derived);
2004617a 2264 name = xasprintf ("__vtab_%s", tname);
611c64f0
JW
2265
2266 /* Look for the vtab symbol in various namespaces. */
dfd6231e
PT
2267 if (gsym && gsym->ns)
2268 {
2269 gfc_find_symbol (name, gsym->ns, 0, &vtab);
2270 if (vtab)
2271 ns = gsym->ns;
2272 }
2273 if (vtab == NULL)
2274 gfc_find_symbol (name, gfc_current_ns, 0, &vtab);
611c64f0
JW
2275 if (vtab == NULL)
2276 gfc_find_symbol (name, ns, 0, &vtab);
2277 if (vtab == NULL)
2278 gfc_find_symbol (name, derived->ns, 0, &vtab);
d15bac21
JW
2279
2280 if (vtab == NULL)
2281 {
2282 gfc_get_symbol (name, ns, &vtab);
2283 vtab->ts.type = BT_DERIVED;
cddf0123 2284 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
524af0d6 2285 &gfc_current_locus))
e10f52d0 2286 goto cleanup;
d15bac21 2287 vtab->attr.target = 1;
95f5c775 2288 vtab->attr.save = SAVE_IMPLICIT;
d15bac21 2289 vtab->attr.vtab = 1;
f3f98a1e 2290 vtab->attr.access = ACCESS_PUBLIC;
d15bac21 2291 gfc_set_sym_referenced (vtab);
2004617a 2292 name = xasprintf ("__vtype_%s", tname);
29a7d776 2293
d15bac21
JW
2294 gfc_find_symbol (name, ns, 0, &vtype);
2295 if (vtype == NULL)
2296 {
2297 gfc_component *c;
2298 gfc_symbol *parent = NULL, *parent_vtab = NULL;
bf9f15ee
PT
2299 bool rdt = false;
2300
2301 /* Is this a derived type with recursive allocatable
2302 components? */
2303 c = (derived->attr.unlimited_polymorphic
2304 || derived->attr.abstract) ?
2305 NULL : derived->components;
2306 for (; c; c= c->next)
2307 if (c->ts.type == BT_DERIVED
2308 && c->ts.u.derived == derived)
2309 {
2310 rdt = true;
2311 break;
2312 }
d15bac21
JW
2313
2314 gfc_get_symbol (name, ns, &vtype);
cddf0123 2315 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
524af0d6 2316 &gfc_current_locus))
81fb8a48 2317 goto cleanup;
f3f98a1e 2318 vtype->attr.access = ACCESS_PUBLIC;
611c64f0 2319 vtype->attr.vtype = 1;
d15bac21
JW
2320 gfc_set_sym_referenced (vtype);
2321
b04533af 2322 /* Add component '_hash'. */
524af0d6 2323 if (!gfc_add_component (vtype, "_hash", &c))
81fb8a48 2324 goto cleanup;
d15bac21
JW
2325 c->ts.type = BT_INTEGER;
2326 c->ts.kind = 4;
2327 c->attr.access = ACCESS_PRIVATE;
2328 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2329 NULL, derived->hash_value);
2330
b04533af 2331 /* Add component '_size'. */
524af0d6 2332 if (!gfc_add_component (vtype, "_size", &c))
81fb8a48 2333 goto cleanup;
d15bac21 2334 c->ts.type = BT_INTEGER;
f622221a 2335 c->ts.kind = gfc_size_kind;
d15bac21
JW
2336 c->attr.access = ACCESS_PRIVATE;
2337 /* Remember the derived type in ts.u.derived,
2338 so that the correct initializer can be set later on
2339 (in gfc_conv_structure). */
2340 c->ts.u.derived = derived;
f622221a 2341 c->initializer = gfc_get_int_expr (gfc_size_kind,
d15bac21
JW
2342 NULL, 0);
2343
b04533af 2344 /* Add component _extends. */
524af0d6 2345 if (!gfc_add_component (vtype, "_extends", &c))
81fb8a48 2346 goto cleanup;
d15bac21
JW
2347 c->attr.pointer = 1;
2348 c->attr.access = ACCESS_PRIVATE;
8b704316
PT
2349 if (!derived->attr.unlimited_polymorphic)
2350 parent = gfc_get_derived_super_type (derived);
2351 else
2352 parent = NULL;
2353
d15bac21
JW
2354 if (parent)
2355 {
88ce8031 2356 parent_vtab = gfc_find_derived_vtab (parent);
d15bac21
JW
2357 c->ts.type = BT_DERIVED;
2358 c->ts.u.derived = parent_vtab->ts.u.derived;
2359 c->initializer = gfc_get_expr ();
2360 c->initializer->expr_type = EXPR_VARIABLE;
2361 gfc_find_sym_tree (parent_vtab->name, parent_vtab->ns,
2362 0, &c->initializer->symtree);
2363 }
2364 else
2365 {
2366 c->ts.type = BT_DERIVED;
2367 c->ts.u.derived = vtype;
2368 c->initializer = gfc_get_null_expr (NULL);
2369 }
2370
8b704316
PT
2371 if (!derived->attr.unlimited_polymorphic
2372 && derived->components == NULL
2373 && !derived->attr.zero_comp)
611c64f0
JW
2374 {
2375 /* At this point an error must have occurred.
2376 Prevent further errors on the vtype components. */
2377 found_sym = vtab;
2378 goto have_vtype;
2379 }
2380
b04533af 2381 /* Add component _def_init. */
524af0d6 2382 if (!gfc_add_component (vtype, "_def_init", &c))
50f30801
JW
2383 goto cleanup;
2384 c->attr.pointer = 1;
8e54f139 2385 c->attr.artificial = 1;
50f30801
JW
2386 c->attr.access = ACCESS_PRIVATE;
2387 c->ts.type = BT_DERIVED;
2388 c->ts.u.derived = derived;
8b704316
PT
2389 if (derived->attr.unlimited_polymorphic
2390 || derived->attr.abstract)
611c64f0 2391 c->initializer = gfc_get_null_expr (NULL);
50f30801
JW
2392 else
2393 {
2394 /* Construct default initialization variable. */
2004617a 2395 name = xasprintf ("__def_init_%s", tname);
50f30801
JW
2396 gfc_get_symbol (name, ns, &def_init);
2397 def_init->attr.target = 1;
8e54f139 2398 def_init->attr.artificial = 1;
95f5c775 2399 def_init->attr.save = SAVE_IMPLICIT;
50f30801 2400 def_init->attr.access = ACCESS_PUBLIC;
22c30bc0 2401 def_init->attr.flavor = FL_VARIABLE;
50f30801
JW
2402 gfc_set_sym_referenced (def_init);
2403 def_init->ts.type = BT_DERIVED;
2404 def_init->ts.u.derived = derived;
2405 def_init->value = gfc_default_initializer (&def_init->ts);
2406
2407 c->initializer = gfc_lval_expr_from_sym (def_init);
2408 }
2409
b04533af 2410 /* Add component _copy. */
524af0d6 2411 if (!gfc_add_component (vtype, "_copy", &c))
611c64f0
JW
2412 goto cleanup;
2413 c->attr.proc_pointer = 1;
2414 c->attr.access = ACCESS_PRIVATE;
2415 c->tb = XCNEW (gfc_typebound_proc);
2416 c->tb->ppc = 1;
8b704316
PT
2417 if (derived->attr.unlimited_polymorphic
2418 || derived->attr.abstract)
611c64f0
JW
2419 c->initializer = gfc_get_null_expr (NULL);
2420 else
2421 {
2422 /* Set up namespace. */
2423 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2424 sub_ns->sibling = ns->contained;
2425 ns->contained = sub_ns;
2426 sub_ns->resolved = 1;
2427 /* Set up procedure symbol. */
2004617a 2428 name = xasprintf ("__copy_%s", tname);
611c64f0
JW
2429 gfc_get_symbol (name, sub_ns, &copy);
2430 sub_ns->proc_name = copy;
2431 copy->attr.flavor = FL_PROCEDURE;
cf651ca2 2432 copy->attr.subroutine = 1;
0b73eb81 2433 copy->attr.pure = 1;
8e54f139 2434 copy->attr.artificial = 1;
611c64f0 2435 copy->attr.if_source = IFSRC_DECL;
c49ea23d
PT
2436 /* This is elemental so that arrays are automatically
2437 treated correctly by the scalarizer. */
2438 copy->attr.elemental = 1;
844ba455
JW
2439 if (ns->proc_name->attr.flavor == FL_MODULE)
2440 copy->module = ns->proc_name->name;
611c64f0
JW
2441 gfc_set_sym_referenced (copy);
2442 /* Set up formal arguments. */
2443 gfc_get_symbol ("src", sub_ns, &src);
2444 src->ts.type = BT_DERIVED;
2445 src->ts.u.derived = derived;
2446 src->attr.flavor = FL_VARIABLE;
2447 src->attr.dummy = 1;
8e54f139
TB
2448 src->attr.artificial = 1;
2449 src->attr.intent = INTENT_IN;
611c64f0
JW
2450 gfc_set_sym_referenced (src);
2451 copy->formal = gfc_get_formal_arglist ();
2452 copy->formal->sym = src;
2453 gfc_get_symbol ("dst", sub_ns, &dst);
2454 dst->ts.type = BT_DERIVED;
2455 dst->ts.u.derived = derived;
2456 dst->attr.flavor = FL_VARIABLE;
2457 dst->attr.dummy = 1;
8e54f139 2458 dst->attr.artificial = 1;
16023efc 2459 dst->attr.intent = INTENT_INOUT;
611c64f0
JW
2460 gfc_set_sym_referenced (dst);
2461 copy->formal->next = gfc_get_formal_arglist ();
2462 copy->formal->next->sym = dst;
2463 /* Set up code. */
11e5274a 2464 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
611c64f0
JW
2465 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2466 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2467 /* Set initializer. */
2468 c->initializer = gfc_lval_expr_from_sym (copy);
2469 c->ts.interface = copy;
2470 }
2471
8e54f139
TB
2472 /* Add component _final, which contains a procedure pointer to
2473 a wrapper which handles both the freeing of allocatable
2474 components and the calls to finalization subroutines.
2475 Note: The actual wrapper function can only be generated
2476 at resolution time. */
524af0d6 2477 if (!gfc_add_component (vtype, "_final", &c))
8e54f139
TB
2478 goto cleanup;
2479 c->attr.proc_pointer = 1;
2480 c->attr.access = ACCESS_PRIVATE;
f8add009 2481 c->attr.artificial = 1;
8e54f139
TB
2482 c->tb = XCNEW (gfc_typebound_proc);
2483 c->tb->ppc = 1;
2484 generate_finalization_wrapper (derived, ns, tname, c);
2485
bf9f15ee
PT
2486 /* Add component _deallocate. */
2487 if (!gfc_add_component (vtype, "_deallocate", &c))
2488 goto cleanup;
2489 c->attr.proc_pointer = 1;
2490 c->attr.access = ACCESS_PRIVATE;
2491 c->tb = XCNEW (gfc_typebound_proc);
2492 c->tb->ppc = 1;
2493 if (derived->attr.unlimited_polymorphic
2494 || derived->attr.abstract
2495 || !rdt)
2496 c->initializer = gfc_get_null_expr (NULL);
2497 else
2498 {
2499 /* Set up namespace. */
2500 gfc_namespace *sub_ns = gfc_get_namespace (ns, 0);
2501
2502 sub_ns->sibling = ns->contained;
2503 ns->contained = sub_ns;
2504 sub_ns->resolved = 1;
2505 /* Set up procedure symbol. */
2004617a 2506 name = xasprintf ("__deallocate_%s", tname);
bf9f15ee
PT
2507 gfc_get_symbol (name, sub_ns, &dealloc);
2508 sub_ns->proc_name = dealloc;
2509 dealloc->attr.flavor = FL_PROCEDURE;
2510 dealloc->attr.subroutine = 1;
2511 dealloc->attr.pure = 1;
2512 dealloc->attr.artificial = 1;
2513 dealloc->attr.if_source = IFSRC_DECL;
2514
2515 if (ns->proc_name->attr.flavor == FL_MODULE)
2516 dealloc->module = ns->proc_name->name;
2517 gfc_set_sym_referenced (dealloc);
2518 /* Set up formal argument. */
2519 gfc_get_symbol ("arg", sub_ns, &arg);
2520 arg->ts.type = BT_DERIVED;
2521 arg->ts.u.derived = derived;
2522 arg->attr.flavor = FL_VARIABLE;
2523 arg->attr.dummy = 1;
2524 arg->attr.artificial = 1;
2525 arg->attr.intent = INTENT_INOUT;
2526 arg->attr.dimension = 1;
2527 arg->attr.allocatable = 1;
2528 arg->as = gfc_get_array_spec();
2529 arg->as->type = AS_ASSUMED_SHAPE;
2530 arg->as->rank = 1;
2531 arg->as->lower[0] = gfc_get_int_expr (gfc_default_integer_kind,
2532 NULL, 1);
2533 gfc_set_sym_referenced (arg);
2534 dealloc->formal = gfc_get_formal_arglist ();
2535 dealloc->formal->sym = arg;
2536 /* Set up code. */
2537 sub_ns->code = gfc_get_code (EXEC_DEALLOCATE);
2538 sub_ns->code->ext.alloc.list = gfc_get_alloc ();
2539 sub_ns->code->ext.alloc.list->expr
2540 = gfc_lval_expr_from_sym (arg);
2541 /* Set initializer. */
2542 c->initializer = gfc_lval_expr_from_sym (dealloc);
2543 c->ts.interface = dealloc;
2544 }
2545
50f30801 2546 /* Add procedure pointers for type-bound procedures. */
8b704316
PT
2547 if (!derived->attr.unlimited_polymorphic)
2548 add_procs_to_declared_vtab (derived, vtype);
d6cd8711 2549 }
d15bac21 2550
611c64f0 2551have_vtype:
d15bac21
JW
2552 vtab->ts.u.derived = vtype;
2553 vtab->value = gfc_default_initializer (&vtab->ts);
2554 }
2004617a 2555 free (name);
d15bac21
JW
2556 }
2557
81fb8a48
MM
2558 found_sym = vtab;
2559
2560cleanup:
2561 /* It is unexpected to have some symbols added at resolution or code
2562 generation time. We commit the changes in order to keep a clean state. */
2563 if (found_sym)
e10f52d0
JW
2564 {
2565 gfc_commit_symbol (vtab);
2566 if (vtype)
2567 gfc_commit_symbol (vtype);
50f30801
JW
2568 if (def_init)
2569 gfc_commit_symbol (def_init);
611c64f0
JW
2570 if (copy)
2571 gfc_commit_symbol (copy);
2572 if (src)
2573 gfc_commit_symbol (src);
2574 if (dst)
2575 gfc_commit_symbol (dst);
bf9f15ee
PT
2576 if (dealloc)
2577 gfc_commit_symbol (dealloc);
2578 if (arg)
2579 gfc_commit_symbol (arg);
e10f52d0 2580 }
81fb8a48
MM
2581 else
2582 gfc_undo_symbols ();
2583
2584 return found_sym;
d15bac21
JW
2585}
2586
2587
86035eec
TB
2588/* Check if a derived type is finalizable. That is the case if it
2589 (1) has a FINAL subroutine or
2590 (2) has a nonpointer nonallocatable component of finalizable type.
2591 If it is finalizable, return an expression containing the
2592 finalization wrapper. */
2593
2594bool
2595gfc_is_finalizable (gfc_symbol *derived, gfc_expr **final_expr)
2596{
2597 gfc_symbol *vtab;
2598 gfc_component *c;
2599
2600 /* (1) Check for FINAL subroutines. */
2601 if (derived->f2k_derived && derived->f2k_derived->finalizers)
2602 goto yes;
2603
2604 /* (2) Check for components of finalizable type. */
2605 for (c = derived->components; c; c = c->next)
2606 if (c->ts.type == BT_DERIVED
2607 && !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable
2608 && gfc_is_finalizable (c->ts.u.derived, NULL))
2609 goto yes;
2610
2611 return false;
2612
2613yes:
2614 /* Make sure vtab is generated. */
2615 vtab = gfc_find_derived_vtab (derived);
2616 if (final_expr)
2617 {
2618 /* Return finalizer expression. */
2619 gfc_component *final;
2620 final = vtab->ts.u.derived->components->next->next->next->next->next;
2621 gcc_assert (strcmp (final->name, "_final") == 0);
2622 gcc_assert (final->initializer
2623 && final->initializer->expr_type != EXPR_NULL);
2624 *final_expr = final->initializer;
2625 }
2626 return true;
2627}
2628
2629
8b704316 2630/* Find (or generate) the symbol for an intrinsic type's vtab. This is
7289d1c9 2631 needed to support unlimited polymorphism. */
8b704316 2632
7289d1c9
JW
2633static gfc_symbol *
2634find_intrinsic_vtab (gfc_typespec *ts)
8b704316
PT
2635{
2636 gfc_namespace *ns;
adede54c 2637 gfc_symbol *vtab = NULL, *vtype = NULL, *found_sym = NULL;
8b704316 2638 gfc_symbol *copy = NULL, *src = NULL, *dst = NULL;
8b704316 2639
8b704316
PT
2640 /* Find the top-level namespace. */
2641 for (ns = gfc_current_ns; ns; ns = ns->parent)
2642 if (!ns->parent)
2643 break;
2644
8b704316
PT
2645 if (ns)
2646 {
2004617a
QZ
2647 char tname[GFC_MAX_SYMBOL_LEN+1];
2648 char *name;
b120c8b2 2649
cef026ec
AV
2650 /* Encode all types as TYPENAME_KIND_ including especially character
2651 arrays, whose length is now consistently stored in the _len component
2652 of the class-variable. */
2653 sprintf (tname, "%s_%d_", gfc_basic_typename (ts->type), ts->kind);
2004617a 2654 name = xasprintf ("__vtab_%s", tname);
8b704316 2655
63631f7d
AV
2656 /* Look for the vtab symbol in the top-level namespace only. */
2657 gfc_find_symbol (name, ns, 0, &vtab);
8b704316
PT
2658
2659 if (vtab == NULL)
2660 {
2661 gfc_get_symbol (name, ns, &vtab);
2662 vtab->ts.type = BT_DERIVED;
cddf0123 2663 if (!gfc_add_flavor (&vtab->attr, FL_VARIABLE, NULL,
524af0d6 2664 &gfc_current_locus))
8b704316
PT
2665 goto cleanup;
2666 vtab->attr.target = 1;
2667 vtab->attr.save = SAVE_IMPLICIT;
2668 vtab->attr.vtab = 1;
2669 vtab->attr.access = ACCESS_PUBLIC;
2670 gfc_set_sym_referenced (vtab);
2004617a 2671 name = xasprintf ("__vtype_%s", tname);
8b704316
PT
2672
2673 gfc_find_symbol (name, ns, 0, &vtype);
2674 if (vtype == NULL)
2675 {
2676 gfc_component *c;
2677 int hash;
2678 gfc_namespace *sub_ns;
2679 gfc_namespace *contained;
cddf0123 2680 gfc_expr *e;
cdd17931 2681 size_t e_size;
8b704316
PT
2682
2683 gfc_get_symbol (name, ns, &vtype);
cddf0123 2684 if (!gfc_add_flavor (&vtype->attr, FL_DERIVED, NULL,
524af0d6 2685 &gfc_current_locus))
8b704316
PT
2686 goto cleanup;
2687 vtype->attr.access = ACCESS_PUBLIC;
2688 vtype->attr.vtype = 1;
2689 gfc_set_sym_referenced (vtype);
2690
2691 /* Add component '_hash'. */
524af0d6 2692 if (!gfc_add_component (vtype, "_hash", &c))
8b704316
PT
2693 goto cleanup;
2694 c->ts.type = BT_INTEGER;
2695 c->ts.kind = 4;
2696 c->attr.access = ACCESS_PRIVATE;
2697 hash = gfc_intrinsic_hash_value (ts);
2698 c->initializer = gfc_get_int_expr (gfc_default_integer_kind,
2699 NULL, hash);
2700
2701 /* Add component '_size'. */
524af0d6 2702 if (!gfc_add_component (vtype, "_size", &c))
8b704316
PT
2703 goto cleanup;
2704 c->ts.type = BT_INTEGER;
f622221a 2705 c->ts.kind = gfc_size_kind;
8b704316 2706 c->attr.access = ACCESS_PRIVATE;
cddf0123
PT
2707
2708 /* Build a minimal expression to make use of
34d9d749
AV
2709 target-memory.c/gfc_element_size for 'size'. Special handling
2710 for character arrays, that are not constant sized: to support
2711 len (str) * kind, only the kind information is stored in the
2712 vtab. */
cddf0123
PT
2713 e = gfc_get_expr ();
2714 e->ts = *ts;
2715 e->expr_type = EXPR_VARIABLE;
cdd17931
HA
2716 if (ts->type == BT_CHARACTER)
2717 e_size = ts->kind;
2718 else
2719 gfc_element_size (e, &e_size);
f622221a 2720 c->initializer = gfc_get_int_expr (gfc_size_kind,
cddf0123 2721 NULL,
cdd17931 2722 e_size);
cddf0123 2723 gfc_free_expr (e);
8b704316
PT
2724
2725 /* Add component _extends. */
524af0d6 2726 if (!gfc_add_component (vtype, "_extends", &c))
8b704316
PT
2727 goto cleanup;
2728 c->attr.pointer = 1;
2729 c->attr.access = ACCESS_PRIVATE;
15115f7a 2730 c->ts.type = BT_VOID;
8b704316
PT
2731 c->initializer = gfc_get_null_expr (NULL);
2732
2733 /* Add component _def_init. */
524af0d6 2734 if (!gfc_add_component (vtype, "_def_init", &c))
8b704316
PT
2735 goto cleanup;
2736 c->attr.pointer = 1;
2737 c->attr.access = ACCESS_PRIVATE;
15115f7a 2738 c->ts.type = BT_VOID;
8b704316
PT
2739 c->initializer = gfc_get_null_expr (NULL);
2740
2741 /* Add component _copy. */
524af0d6 2742 if (!gfc_add_component (vtype, "_copy", &c))
8b704316
PT
2743 goto cleanup;
2744 c->attr.proc_pointer = 1;
2745 c->attr.access = ACCESS_PRIVATE;
2746 c->tb = XCNEW (gfc_typebound_proc);
2747 c->tb->ppc = 1;
2748
3c3f892b 2749 if (ts->type != BT_CHARACTER)
2004617a 2750 name = xasprintf ("__copy_%s", tname);
3c3f892b
JW
2751 else
2752 {
2753 /* __copy is always the same for characters.
2754 Check to see if copy function already exists. */
2004617a 2755 name = xasprintf ("__copy_character_%d", ts->kind);
3c3f892b
JW
2756 contained = ns->contained;
2757 for (; contained; contained = contained->sibling)
2758 if (contained->proc_name
2759 && strcmp (name, contained->proc_name->name) == 0)
2760 {
2761 copy = contained->proc_name;
2762 goto got_char_copy;
2763 }
2764 }
8b704316
PT
2765
2766 /* Set up namespace. */
2767 sub_ns = gfc_get_namespace (ns, 0);
2768 sub_ns->sibling = ns->contained;
2769 ns->contained = sub_ns;
2770 sub_ns->resolved = 1;
2771 /* Set up procedure symbol. */
8b704316
PT
2772 gfc_get_symbol (name, sub_ns, &copy);
2773 sub_ns->proc_name = copy;
2774 copy->attr.flavor = FL_PROCEDURE;
2775 copy->attr.subroutine = 1;
2776 copy->attr.pure = 1;
2777 copy->attr.if_source = IFSRC_DECL;
2778 /* This is elemental so that arrays are automatically
2779 treated correctly by the scalarizer. */
2780 copy->attr.elemental = 1;
f8add009 2781 if (ns->proc_name && ns->proc_name->attr.flavor == FL_MODULE)
8b704316 2782 copy->module = ns->proc_name->name;
f8add009 2783 gfc_set_sym_referenced (copy);
8b704316
PT
2784 /* Set up formal arguments. */
2785 gfc_get_symbol ("src", sub_ns, &src);
2786 src->ts.type = ts->type;
2787 src->ts.kind = ts->kind;
2788 src->attr.flavor = FL_VARIABLE;
2789 src->attr.dummy = 1;
2790 src->attr.intent = INTENT_IN;
2791 gfc_set_sym_referenced (src);
2792 copy->formal = gfc_get_formal_arglist ();
2793 copy->formal->sym = src;
2794 gfc_get_symbol ("dst", sub_ns, &dst);
2795 dst->ts.type = ts->type;
2796 dst->ts.kind = ts->kind;
2797 dst->attr.flavor = FL_VARIABLE;
2798 dst->attr.dummy = 1;
16023efc 2799 dst->attr.intent = INTENT_INOUT;
8b704316
PT
2800 gfc_set_sym_referenced (dst);
2801 copy->formal->next = gfc_get_formal_arglist ();
2802 copy->formal->next->sym = dst;
2803 /* Set up code. */
11e5274a 2804 sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
8b704316
PT
2805 sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
2806 sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
2807 got_char_copy:
2808 /* Set initializer. */
2809 c->initializer = gfc_lval_expr_from_sym (copy);
2810 c->ts.interface = copy;
94241120
TB
2811
2812 /* Add component _final. */
524af0d6 2813 if (!gfc_add_component (vtype, "_final", &c))
94241120
TB
2814 goto cleanup;
2815 c->attr.proc_pointer = 1;
2816 c->attr.access = ACCESS_PRIVATE;
f8add009 2817 c->attr.artificial = 1;
94241120
TB
2818 c->tb = XCNEW (gfc_typebound_proc);
2819 c->tb->ppc = 1;
2820 c->initializer = gfc_get_null_expr (NULL);
8b704316
PT
2821 }
2822 vtab->ts.u.derived = vtype;
2823 vtab->value = gfc_default_initializer (&vtab->ts);
2824 }
2004617a 2825 free (name);
8b704316
PT
2826 }
2827
2828 found_sym = vtab;
2829
2830cleanup:
2831 /* It is unexpected to have some symbols added at resolution or code
2832 generation time. We commit the changes in order to keep a clean state. */
2833 if (found_sym)
2834 {
2835 gfc_commit_symbol (vtab);
2836 if (vtype)
2837 gfc_commit_symbol (vtype);
8b704316
PT
2838 if (copy)
2839 gfc_commit_symbol (copy);
2840 if (src)
2841 gfc_commit_symbol (src);
2842 if (dst)
2843 gfc_commit_symbol (dst);
2844 }
2845 else
2846 gfc_undo_symbols ();
2847
2848 return found_sym;
2849}
2850
2851
7289d1c9
JW
2852/* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
2853
2854gfc_symbol *
2855gfc_find_vtab (gfc_typespec *ts)
2856{
2857 switch (ts->type)
2858 {
2859 case BT_UNKNOWN:
2860 return NULL;
2861 case BT_DERIVED:
2862 return gfc_find_derived_vtab (ts->u.derived);
2863 case BT_CLASS:
903ecc6c
JW
2864 if (ts->u.derived->components && ts->u.derived->components->ts.u.derived)
2865 return gfc_find_derived_vtab (ts->u.derived->components->ts.u.derived);
2866 else
2867 return NULL;
7289d1c9
JW
2868 default:
2869 return find_intrinsic_vtab (ts);
2870 }
2871}
2872
2873
d15bac21
JW
2874/* General worker function to find either a type-bound procedure or a
2875 type-bound user operator. */
2876
2877static gfc_symtree*
524af0d6 2878find_typebound_proc_uop (gfc_symbol* derived, bool* t,
d15bac21
JW
2879 const char* name, bool noaccess, bool uop,
2880 locus* where)
2881{
2882 gfc_symtree* res;
2883 gfc_symtree* root;
2884
d15bac21
JW
2885 /* Set default to failure. */
2886 if (t)
524af0d6 2887 *t = false;
d15bac21 2888
9b940c6d
JW
2889 if (derived->f2k_derived)
2890 /* Set correct symbol-root. */
2891 root = (uop ? derived->f2k_derived->tb_uop_root
2892 : derived->f2k_derived->tb_sym_root);
2893 else
2894 return NULL;
2895
d15bac21
JW
2896 /* Try to find it in the current type's namespace. */
2897 res = gfc_find_symtree (root, name);
2898 if (res && res->n.tb && !res->n.tb->error)
2899 {
2900 /* We found one. */
2901 if (t)
524af0d6 2902 *t = true;
d15bac21
JW
2903
2904 if (!noaccess && derived->attr.use_assoc
2905 && res->n.tb->access == ACCESS_PRIVATE)
2906 {
2907 if (where)
c4100eae 2908 gfc_error ("%qs of %qs is PRIVATE at %L",
d15bac21
JW
2909 name, derived->name, where);
2910 if (t)
524af0d6 2911 *t = false;
d15bac21
JW
2912 }
2913
2914 return res;
2915 }
2916
2917 /* Otherwise, recurse on parent type if derived is an extension. */
2918 if (derived->attr.extension)
2919 {
2920 gfc_symbol* super_type;
2921 super_type = gfc_get_derived_super_type (derived);
2922 gcc_assert (super_type);
2923
2924 return find_typebound_proc_uop (super_type, t, name,
2925 noaccess, uop, where);
2926 }
2927
2928 /* Nothing found. */
2929 return NULL;
2930}
2931
2932
2933/* Find a type-bound procedure or user operator by name for a derived-type
2934 (looking recursively through the super-types). */
2935
2936gfc_symtree*
524af0d6 2937gfc_find_typebound_proc (gfc_symbol* derived, bool* t,
d15bac21
JW
2938 const char* name, bool noaccess, locus* where)
2939{
2940 return find_typebound_proc_uop (derived, t, name, noaccess, false, where);
2941}
2942
2943gfc_symtree*
524af0d6 2944gfc_find_typebound_user_op (gfc_symbol* derived, bool* t,
d15bac21
JW
2945 const char* name, bool noaccess, locus* where)
2946{
2947 return find_typebound_proc_uop (derived, t, name, noaccess, true, where);
2948}
2949
2950
2951/* Find a type-bound intrinsic operator looking recursively through the
2952 super-type hierarchy. */
2953
2954gfc_typebound_proc*
524af0d6 2955gfc_find_typebound_intrinsic_op (gfc_symbol* derived, bool* t,
d15bac21
JW
2956 gfc_intrinsic_op op, bool noaccess,
2957 locus* where)
2958{
2959 gfc_typebound_proc* res;
2960
2961 /* Set default to failure. */
2962 if (t)
524af0d6 2963 *t = false;
d15bac21
JW
2964
2965 /* Try to find it in the current type's namespace. */
2966 if (derived->f2k_derived)
2967 res = derived->f2k_derived->tb_op[op];
8b704316 2968 else
d15bac21
JW
2969 res = NULL;
2970
2971 /* Check access. */
2972 if (res && !res->error)
2973 {
2974 /* We found one. */
2975 if (t)
524af0d6 2976 *t = true;
d15bac21
JW
2977
2978 if (!noaccess && derived->attr.use_assoc
2979 && res->access == ACCESS_PRIVATE)
2980 {
2981 if (where)
c4100eae 2982 gfc_error ("%qs of %qs is PRIVATE at %L",
d15bac21
JW
2983 gfc_op2string (op), derived->name, where);
2984 if (t)
524af0d6 2985 *t = false;
d15bac21
JW
2986 }
2987
2988 return res;
2989 }
2990
2991 /* Otherwise, recurse on parent type if derived is an extension. */
2992 if (derived->attr.extension)
2993 {
2994 gfc_symbol* super_type;
2995 super_type = gfc_get_derived_super_type (derived);
2996 gcc_assert (super_type);
2997
2998 return gfc_find_typebound_intrinsic_op (super_type, t, op,
2999 noaccess, where);
3000 }
3001
3002 /* Nothing found. */
3003 return NULL;
3004}
3005
3006
3007/* Get a typebound-procedure symtree or create and insert it if not yet
3008 present. This is like a very simplified version of gfc_get_sym_tree for
3009 tbp-symtrees rather than regular ones. */
3010
3011gfc_symtree*
3012gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
3013{
b93d8a3f
JW
3014 gfc_symtree *result = gfc_find_symtree (*root, name);
3015 return result ? result : gfc_new_symtree (root, name);
d15bac21 3016}