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