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