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