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