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