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