1 /* Implementation of Fortran 2003 Polymorphism.
2 Copyright (C) 2009-2024 Free Software Foundation, Inc.
3 Contributed by Paul Richard Thomas <pault@gcc.gnu.org>
4 and Janus Weil <janus@gcc.gnu.org>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* class.cc -- This file contains the front end functions needed to service
24 the implementation of Fortran 2003 polymorphism and other
25 object-oriented features. */
28 /* Outline of the internal representation:
30 Each CLASS variable is encapsulated by a class container, which is a
31 structure with two fields:
32 * _data: A pointer to the actual data of the variable. This field has the
33 declared type of the class variable and its attributes
34 (pointer/allocatable/dimension/...).
35 * _vptr: A pointer to the vtable entry (see below) of the dynamic type.
37 Only for unlimited polymorphic classes:
38 * _len: An integer(C_SIZE_T) to store the string length when the unlimited
39 polymorphic pointer is used to point to a char array. The '_len'
40 component will be zero when no character array is stored in
43 For each derived type we set up a "vtable" entry, i.e. a structure with the
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.
50 * _final: A procedure pointer to a wrapper function, which frees
51 allocatable components and calls FINAL subroutines.
52 * _deallocate: A procedure pointer to a deallocation procedure; nonnull
53 only for a recursive derived type.
55 After these follow procedure pointer components for the specific
56 type-bound procedures. */
61 #include "coretypes.h"
63 #include "constructor.h"
64 #include "target-memory.h"
66 /* Inserts a derived type component reference in a data reference chain.
67 TS: base type of the ref chain so far, in which we will pick the component
68 REF: the address of the GFC_REF pointer to update
69 NAME: name of the component to insert
70 Note that component insertion makes sense only if we are at the end of
71 the chain (*REF == NULL) or if we are adding a missing "_data" component
72 to access the actual contents of a class object. */
75 insert_component_ref (gfc_typespec
*ts
, gfc_ref
**ref
, const char * const name
)
80 gcc_assert (ts
->type
== BT_DERIVED
|| ts
->type
== BT_CLASS
);
82 gfc_find_component (ts
->u
.derived
, name
, true, true, &new_ref
);
84 gfc_get_errors (&wcnt
, &ecnt
);
85 if (ecnt
> 0 && !new_ref
)
87 gcc_assert (new_ref
->u
.c
.component
);
90 new_ref
= new_ref
->next
;
97 /* We need to update the base type in the trailing reference chain to
98 that of the new component. */
100 gcc_assert (strcmp (name
, "_data") == 0);
102 if (new_ref
->next
->type
== REF_COMPONENT
)
103 next
= new_ref
->next
;
104 else if (new_ref
->next
->type
== REF_ARRAY
105 && new_ref
->next
->next
106 && new_ref
->next
->next
->type
== REF_COMPONENT
)
107 next
= new_ref
->next
->next
;
111 gcc_assert (new_ref
->u
.c
.component
->ts
.type
== BT_CLASS
112 || new_ref
->u
.c
.component
->ts
.type
== BT_DERIVED
);
113 next
->u
.c
.sym
= new_ref
->u
.c
.component
->ts
.u
.derived
;
121 /* Tells whether we need to add a "_data" reference to access REF subobject
122 from an object of type TS. If FIRST_REF_IN_CHAIN is set, then the base
123 object accessed by REF is a variable; in other words it is a full object,
127 class_data_ref_missing (gfc_typespec
*ts
, gfc_ref
*ref
, bool first_ref_in_chain
)
129 /* Only class containers may need the "_data" reference. */
130 if (ts
->type
!= BT_CLASS
)
133 /* Accessing a class container with an array reference is certainly wrong. */
134 if (ref
->type
!= REF_COMPONENT
)
137 /* Accessing the class container's fields is fine. */
138 if (ref
->u
.c
.component
->name
[0] == '_')
141 /* At this point we have a class container with a non class container's field
142 component reference. We don't want to add the "_data" component if we are
143 at the first reference and the symbol's type is an extended derived type.
144 In that case, conv_parent_component_references will do the right thing so
145 it is not absolutely necessary. Omitting it prevents a regression (see
146 class_41.f03) in the interface mapping mechanism. When evaluating string
147 lengths depending on dummy arguments, we create a fake symbol with a type
148 equal to that of the dummy type. However, because of type extension,
149 the backend type (corresponding to the actual argument) can have a
150 different (extended) type. Adding the "_data" component explicitly, using
151 the base type, confuses the gfc_conv_component_ref code which deals with
152 the extended type. */
153 if (first_ref_in_chain
&& ts
->u
.derived
->attr
.extension
)
156 /* We have a class container with a non class container's field component
157 reference that doesn't fall into the above. */
162 /* Browse through a data reference chain and add the missing "_data" references
163 when a subobject of a class object is accessed without it.
164 Note that it doesn't add the "_data" reference when the class container
165 is the last element in the reference chain. */
168 gfc_fix_class_refs (gfc_expr
*e
)
173 if ((e
->expr_type
!= EXPR_VARIABLE
174 && e
->expr_type
!= EXPR_FUNCTION
)
175 || (e
->expr_type
== EXPR_FUNCTION
176 && e
->value
.function
.isym
!= NULL
))
179 if (e
->expr_type
== EXPR_VARIABLE
)
180 ts
= &e
->symtree
->n
.sym
->ts
;
185 gcc_assert (e
->expr_type
== EXPR_FUNCTION
);
186 if (e
->value
.function
.esym
!= NULL
)
187 func
= e
->value
.function
.esym
;
189 func
= e
->symtree
->n
.sym
;
191 if (func
->result
!= NULL
)
192 ts
= &func
->result
->ts
;
197 for (ref
= &e
->ref
; *ref
!= NULL
; ref
= &(*ref
)->next
)
199 if (class_data_ref_missing (ts
, *ref
, ref
== &e
->ref
))
200 insert_component_ref (ts
, ref
, "_data");
202 if ((*ref
)->type
== REF_COMPONENT
)
203 ts
= &(*ref
)->u
.c
.component
->ts
;
208 /* Insert a reference to the component of the given name.
209 Only to be used with CLASS containers and vtables. */
212 gfc_add_component_ref (gfc_expr
*e
, const char *name
)
215 gfc_ref
**tail
= &(e
->ref
);
216 gfc_ref
*ref
, *next
= NULL
;
217 gfc_symbol
*derived
= e
->symtree
->n
.sym
->ts
.u
.derived
;
218 while (*tail
!= NULL
)
220 if ((*tail
)->type
== REF_COMPONENT
)
222 if (strcmp ((*tail
)->u
.c
.component
->name
, "_data") == 0
224 && (*tail
)->next
->type
== REF_ARRAY
225 && (*tail
)->next
->next
== NULL
)
227 derived
= (*tail
)->u
.c
.component
->ts
.u
.derived
;
229 if ((*tail
)->type
== REF_ARRAY
&& (*tail
)->next
== NULL
)
231 tail
= &((*tail
)->next
);
233 if (derived
&& derived
->components
&& derived
->components
->next
&&
234 derived
->components
->next
->ts
.type
== BT_DERIVED
&&
235 derived
->components
->next
->ts
.u
.derived
== NULL
)
237 /* Fix up missing vtype. */
238 gfc_symbol
*vtab
= gfc_find_derived_vtab (derived
->components
->ts
.u
.derived
);
240 derived
->components
->next
->ts
.u
.derived
= vtab
->ts
.u
.derived
;
242 if (*tail
!= NULL
&& strcmp (name
, "_data") == 0)
245 /* Avoid losing memory. */
246 gfc_free_ref_list (*tail
);
247 c
= gfc_find_component (derived
, name
, true, true, tail
);
250 for (ref
= *tail
; ref
->next
; ref
= ref
->next
)
259 /* This is used to add both the _data component reference and an array
260 reference to class expressions. Used in translation of intrinsic
261 array inquiry functions. */
264 gfc_add_class_array_ref (gfc_expr
*e
)
266 int rank
= CLASS_DATA (e
)->as
->rank
;
267 int corank
= CLASS_DATA (e
)->as
->corank
;
268 gfc_array_spec
*as
= CLASS_DATA (e
)->as
;
270 gfc_add_data_component (e
);
273 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
276 if (ref
->type
!= REF_ARRAY
)
278 ref
->next
= gfc_get_ref ();
280 ref
->type
= REF_ARRAY
;
281 ref
->u
.ar
.type
= AR_FULL
;
287 /* Unfortunately, class array expressions can appear in various conditions;
288 with and without both _data component and an arrayspec. This function
289 deals with that variability. The previous reference to 'ref' is to a
293 class_array_ref_detected (gfc_ref
*ref
, bool *full_array
)
295 bool no_data
= false;
296 bool with_data
= false;
298 /* An array reference with no _data component. */
299 if (ref
&& ref
->type
== REF_ARRAY
301 && ref
->u
.ar
.type
!= AR_ELEMENT
)
304 *full_array
= ref
->u
.ar
.type
== AR_FULL
;
308 /* Cover cases where _data appears, with or without an array ref. */
309 if (ref
&& ref
->type
== REF_COMPONENT
310 && strcmp (ref
->u
.c
.component
->name
, "_data") == 0)
318 else if (ref
->next
&& ref
->next
->type
== REF_ARRAY
319 && ref
->type
== REF_COMPONENT
320 && ref
->next
->u
.ar
.type
!= AR_ELEMENT
)
324 *full_array
= ref
->next
->u
.ar
.type
== AR_FULL
;
328 return no_data
|| with_data
;
332 /* Returns true if the expression contains a reference to a class
333 array. Notice that class array elements return false. */
336 gfc_is_class_array_ref (gfc_expr
*e
, bool *full_array
)
346 /* Is this a class array object? ie. Is the symbol of type class? */
348 && e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
349 && CLASS_DATA (e
->symtree
->n
.sym
)
350 && CLASS_DATA (e
->symtree
->n
.sym
)->attr
.dimension
351 && class_array_ref_detected (e
->ref
, full_array
))
354 /* Or is this a class array component reference? */
355 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
357 if (ref
->type
== REF_COMPONENT
358 && ref
->u
.c
.component
->ts
.type
== BT_CLASS
359 && CLASS_DATA (ref
->u
.c
.component
)->attr
.dimension
360 && class_array_ref_detected (ref
->next
, full_array
))
368 /* Returns true if the expression is a reference to a class
369 scalar. This function is necessary because such expressions
370 can be dressed with a reference to the _data component and so
371 have a type other than BT_CLASS. */
374 gfc_is_class_scalar_expr (gfc_expr
*e
)
381 /* Is this a class object? */
382 if (e
->symtree
&& e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
383 && CLASS_DATA (e
->symtree
->n
.sym
)
384 && !CLASS_DATA (e
->symtree
->n
.sym
)->attr
.dimension
386 || (e
->ref
->type
== REF_COMPONENT
387 && strcmp (e
->ref
->u
.c
.component
->name
, "_data") == 0
388 && (e
->ref
->next
== NULL
389 || (e
->ref
->next
->type
== REF_ARRAY
390 && e
->ref
->next
->u
.ar
.codimen
> 0
391 && e
->ref
->next
->u
.ar
.dimen
== 0
392 && e
->ref
->next
->next
== NULL
)))))
395 /* Or is the final reference BT_CLASS or _data? */
396 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
398 if (ref
->type
== REF_COMPONENT
&& ref
->u
.c
.component
->ts
.type
== BT_CLASS
399 && CLASS_DATA (ref
->u
.c
.component
)
400 && !CLASS_DATA (ref
->u
.c
.component
)->attr
.dimension
401 && (ref
->next
== NULL
402 || (ref
->next
->type
== REF_COMPONENT
403 && strcmp (ref
->next
->u
.c
.component
->name
, "_data") == 0
404 && (ref
->next
->next
== NULL
405 || (ref
->next
->next
->type
== REF_ARRAY
406 && ref
->next
->next
->u
.ar
.codimen
> 0
407 && ref
->next
->next
->u
.ar
.dimen
== 0
408 && ref
->next
->next
->next
== NULL
)))))
416 /* Tells whether the expression E is a reference to a (scalar) class container.
417 Scalar because array class containers usually have an array reference after
418 them, and gfc_fix_class_refs will add the missing "_data" component reference
422 gfc_is_class_container_ref (gfc_expr
*e
)
427 if (e
->expr_type
!= EXPR_VARIABLE
)
428 return e
->ts
.type
== BT_CLASS
;
430 if (e
->symtree
->n
.sym
->ts
.type
== BT_CLASS
)
435 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
437 if (ref
->type
!= REF_COMPONENT
)
439 else if (ref
->u
.c
.component
->ts
.type
== BT_CLASS
)
449 /* Build an initializer for CLASS pointers,
450 initializing the _data component to the init_expr (or NULL) and the _vptr
451 component to the corresponding type (or the declared type, given by ts). */
454 gfc_class_initializer (gfc_typespec
*ts
, gfc_expr
*init_expr
)
458 gfc_symbol
*vtab
= NULL
;
460 if (init_expr
&& init_expr
->expr_type
!= EXPR_NULL
)
461 vtab
= gfc_find_vtab (&init_expr
->ts
);
463 vtab
= gfc_find_vtab (ts
);
465 init
= gfc_get_structure_constructor_expr (ts
->type
, ts
->kind
,
466 &ts
->u
.derived
->declared_at
);
469 for (comp
= ts
->u
.derived
->components
; comp
; comp
= comp
->next
)
471 gfc_constructor
*ctor
= gfc_constructor_get();
472 if (strcmp (comp
->name
, "_vptr") == 0 && vtab
)
473 ctor
->expr
= gfc_lval_expr_from_sym (vtab
);
474 else if (init_expr
&& init_expr
->expr_type
!= EXPR_NULL
)
475 ctor
->expr
= gfc_copy_expr (init_expr
);
477 ctor
->expr
= gfc_get_null_expr (NULL
);
478 gfc_constructor_append (&init
->value
.constructor
, ctor
);
485 /* Create a unique string identifier for a derived type, composed of its name
486 and module name. This is used to construct unique names for the class
487 containers and vtab symbols. */
490 get_unique_type_string (gfc_symbol
*derived
)
495 if (derived
->attr
.unlimited_polymorphic
)
498 dt_name
= gfc_dt_upper_string (derived
->name
);
499 len
= strlen (dt_name
) + 2;
500 if (derived
->attr
.unlimited_polymorphic
)
502 string
= XNEWVEC (char, len
);
503 sprintf (string
, "_%s", dt_name
);
505 else if (derived
->module
)
507 string
= XNEWVEC (char, strlen (derived
->module
) + len
);
508 sprintf (string
, "%s_%s", derived
->module
, dt_name
);
510 else if (derived
->ns
->proc_name
)
512 string
= XNEWVEC (char, strlen (derived
->ns
->proc_name
->name
) + len
);
513 sprintf (string
, "%s_%s", derived
->ns
->proc_name
->name
, dt_name
);
517 string
= XNEWVEC (char, len
);
518 sprintf (string
, "_%s", dt_name
);
524 /* A relative of 'get_unique_type_string' which makes sure the generated
525 string will not be too long (replacing it by a hash string if needed). */
528 get_unique_hashed_string (char *string
, gfc_symbol
*derived
)
530 /* Provide sufficient space to hold "symbol.symbol_symbol". */
532 tmp
= get_unique_type_string (derived
);
533 /* If string is too long, use hash value in hex representation (allow for
534 extra decoration, cf. gfc_build_class_symbol & gfc_find_derived_vtab).
535 We need space to for 15 characters "__class_" + symbol name + "_%d_%da",
536 where %d is the (co)rank which can be up to n = 15. */
537 if (strlen (tmp
) > GFC_MAX_SYMBOL_LEN
- 15)
539 int h
= gfc_hash_value (derived
);
540 sprintf (string
, "%X", h
);
543 strcpy (string
, tmp
);
548 /* Assign a hash value for a derived type. The algorithm is that of SDBM. */
551 gfc_hash_value (gfc_symbol
*sym
)
553 unsigned int hash
= 0;
554 /* Provide sufficient space to hold "symbol.symbol_symbol". */
558 c
= get_unique_type_string (sym
);
561 for (i
= 0; i
< len
; i
++)
562 hash
= (hash
<< 6) + (hash
<< 16) - hash
+ c
[i
];
565 /* Return the hash but take the modulus for the sake of module read,
566 even though this slightly increases the chance of collision. */
567 return (hash
% 100000000);
571 /* Assign a hash value for an intrinsic type. The algorithm is that of SDBM. */
574 gfc_intrinsic_hash_value (gfc_typespec
*ts
)
576 unsigned int hash
= 0;
577 const char *c
= gfc_typename (ts
, true);
582 for (i
= 0; i
< len
; i
++)
583 hash
= (hash
<< 6) + (hash
<< 16) - hash
+ c
[i
];
585 /* Return the hash but take the modulus for the sake of module read,
586 even though this slightly increases the chance of collision. */
587 return (hash
% 100000000);
591 /* Get the _len component from a class/derived object storing a string.
592 For unlimited polymorphic entities a ref to the _data component is available
593 while a ref to the _len component is needed. This routine traverese the
594 ref-chain and strips the last ref to a _data from it replacing it with a
595 ref to the _len component. */
598 gfc_get_len_component (gfc_expr
*e
, int k
)
601 gfc_ref
*ref
, **last
;
603 ptr
= gfc_copy_expr (e
);
605 /* We need to remove the last _data component ref from ptr. */
611 && ref
->type
== REF_COMPONENT
612 && strcmp ("_data", ref
->u
.c
.component
->name
)== 0)
614 gfc_free_ref_list (ref
);
621 /* And replace if with a ref to the _len component. */
622 gfc_add_len_component (ptr
);
623 if (k
!= ptr
->ts
.kind
)
627 ts
.type
= BT_INTEGER
;
629 gfc_convert_type_warn (ptr
, &ts
, 2, 0);
635 /* Build a polymorphic CLASS entity, using the symbol that comes from
636 build_sym. A CLASS entity is represented by an encapsulating type,
637 which contains the declared type as '_data' component, plus a pointer
638 component '_vptr' which determines the dynamic type. When this CLASS
639 entity is unlimited polymorphic, then also add a component '_len' to
640 store the length of string when that is stored in it. */
644 gfc_build_class_symbol (gfc_typespec
*ts
, symbol_attribute
*attr
,
647 char tname
[GFC_MAX_SYMBOL_LEN
+1];
649 gfc_typespec
*orig_ts
= ts
;
658 /* We cannot build the class container now. */
659 if (attr
->class_ok
&& (!ts
->u
.derived
|| !ts
->u
.derived
->components
))
662 /* Class container has already been built with same name. */
664 && ts
->u
.derived
->components
->attr
.dimension
>= attr
->dimension
665 && ts
->u
.derived
->components
->attr
.codimension
>= attr
->codimension
666 && ts
->u
.derived
->components
->attr
.class_pointer
>= attr
->pointer
667 && ts
->u
.derived
->components
->attr
.allocatable
>= attr
->allocatable
)
671 attr
->dimension
|= ts
->u
.derived
->components
->attr
.dimension
;
672 attr
->codimension
|= ts
->u
.derived
->components
->attr
.codimension
;
673 attr
->pointer
|= ts
->u
.derived
->components
->attr
.class_pointer
;
674 attr
->allocatable
|= ts
->u
.derived
->components
->attr
.allocatable
;
675 ts
= &ts
->u
.derived
->components
->ts
;
678 attr
->class_ok
= attr
->dummy
|| attr
->pointer
|| attr
->allocatable
679 || attr
->select_type_temporary
|| attr
->associate_var
;
682 /* We cannot build the class container yet. */
685 /* Determine the name of the encapsulating type. */
686 rank
= !(*as
) || (*as
)->rank
== -1 ? GFC_MAX_DIMENSIONS
: (*as
)->rank
;
691 get_unique_hashed_string (tname
, ts
->u
.derived
);
692 if ((*as
) && attr
->allocatable
)
693 name
= xasprintf ("__class_%s_%d_%da", tname
, rank
, (*as
)->corank
);
694 else if ((*as
) && attr
->pointer
)
695 name
= xasprintf ("__class_%s_%d_%dp", tname
, rank
, (*as
)->corank
);
697 name
= xasprintf ("__class_%s_%d_%dt", tname
, rank
, (*as
)->corank
);
698 else if (attr
->pointer
)
699 name
= xasprintf ("__class_%s_p", tname
);
700 else if (attr
->allocatable
)
701 name
= xasprintf ("__class_%s_a", tname
);
703 name
= xasprintf ("__class_%s_t", tname
);
705 if (ts
->u
.derived
->attr
.unlimited_polymorphic
)
707 /* Find the top-level namespace. */
708 for (ns
= gfc_current_ns
; ns
; ns
= ns
->parent
)
713 ns
= ts
->u
.derived
->ns
;
715 /* Although this might seem to be counterintuitive, we can build separate
716 class types with different array specs because the TKR interface checks
717 work on the declared type. All array type other than deferred shape or
718 assumed rank are added to the function namespace to ensure that they
719 are properly distinguished. */
720 if (attr
->dummy
&& (*as
)
721 && ((!attr
->codimension
722 && !((*as
)->type
== AS_DEFERRED
|| (*as
)->type
== AS_ASSUMED_RANK
))
723 || (attr
->codimension
724 && !((*as
)->cotype
== AS_DEFERRED
725 || (*as
)->cotype
== AS_ASSUMED_RANK
))))
729 gfc_find_symbol (name
, ns
, 0, &fclass
);
730 /* If a local class type with this name already exists, update the
731 name with an index. */
735 sname
= xasprintf ("%s_%d", name
, ++ctr
);
741 gfc_find_symbol (name
, ns
, 0, &fclass
);
746 /* If not there, create a new symbol. */
747 fclass
= gfc_new_symbol (name
, ns
);
748 st
= gfc_new_symtree (&ns
->sym_root
, name
);
750 gfc_set_sym_referenced (fclass
);
752 fclass
->ts
.type
= BT_UNKNOWN
;
753 if (!ts
->u
.derived
->attr
.unlimited_polymorphic
)
754 fclass
->attr
.abstract
= ts
->u
.derived
->attr
.abstract
;
755 fclass
->f2k_derived
= gfc_get_namespace (NULL
, 0);
756 if (!gfc_add_flavor (&fclass
->attr
, FL_DERIVED
, NULL
,
760 /* Add component '_data'. */
761 if (!gfc_add_component (fclass
, "_data", &c
))
764 c
->ts
.type
= BT_DERIVED
;
765 c
->attr
.access
= ACCESS_PRIVATE
;
766 c
->ts
.u
.derived
= ts
->u
.derived
;
767 c
->attr
.class_pointer
= attr
->pointer
;
768 c
->attr
.pointer
= attr
->pointer
|| (attr
->dummy
&& !attr
->allocatable
)
769 || attr
->select_type_temporary
;
770 c
->attr
.allocatable
= attr
->allocatable
;
771 c
->attr
.dimension
= attr
->dimension
;
772 c
->attr
.codimension
= attr
->codimension
;
773 c
->attr
.abstract
= fclass
->attr
.abstract
;
775 c
->initializer
= NULL
;
777 /* Add component '_vptr'. */
778 if (!gfc_add_component (fclass
, "_vptr", &c
))
780 c
->ts
.type
= BT_DERIVED
;
781 c
->attr
.access
= ACCESS_PRIVATE
;
784 if (ts
->u
.derived
->attr
.unlimited_polymorphic
)
786 vtab
= gfc_find_derived_vtab (ts
->u
.derived
);
788 c
->ts
.u
.derived
= vtab
->ts
.u
.derived
;
790 /* Add component '_len'. Only unlimited polymorphic pointers may
791 have a string assigned to them, i.e., only those need the _len
793 if (!gfc_add_component (fclass
, "_len", &c
))
795 c
->ts
.type
= BT_INTEGER
;
796 c
->ts
.kind
= gfc_charlen_int_kind
;
797 c
->attr
.access
= ACCESS_PRIVATE
;
798 c
->attr
.artificial
= 1;
801 /* Build vtab later. */
802 c
->ts
.u
.derived
= NULL
;
805 if (!ts
->u
.derived
->attr
.unlimited_polymorphic
)
807 /* Since the extension field is 8 bit wide, we can only have
808 up to 255 extension levels. */
809 if (ts
->u
.derived
->attr
.extension
== 255)
811 gfc_error ("Maximum extension level reached with type %qs at %L",
812 ts
->u
.derived
->name
, &ts
->u
.derived
->declared_at
);
816 fclass
->attr
.extension
= ts
->u
.derived
->attr
.extension
+ 1;
817 fclass
->attr
.alloc_comp
= ts
->u
.derived
->attr
.alloc_comp
;
818 fclass
->attr
.coarray_comp
= ts
->u
.derived
->attr
.coarray_comp
;
821 fclass
->attr
.is_class
= 1;
822 orig_ts
->u
.derived
= fclass
;
823 attr
->allocatable
= attr
->pointer
= attr
->dimension
= attr
->codimension
= 0;
830 /* Change class, using gfc_build_class_symbol. This is needed for associate
831 names, when rank changes or a derived type is produced by resolution. */
834 gfc_change_class (gfc_typespec
*ts
, symbol_attribute
*sym_attr
,
835 gfc_array_spec
*sym_as
, int rank
, int corank
)
837 symbol_attribute attr
;
839 gfc_array_spec
*as
= NULL
;
840 gfc_symbol
*der
= ts
->u
.derived
;
845 attr
.associate_var
= 1;
846 attr
.class_pointer
= 1;
847 attr
.allocatable
= 0;
849 attr
.dimension
= rank
? 1 : 0;
853 as
= gfc_copy_array_spec (sym_as
);
856 as
= gfc_get_array_spec ();
858 as
->type
= AS_DEFERRED
;
862 if (as
&& as
->corank
!= 0)
863 attr
.codimension
= 1;
865 if (!gfc_build_class_symbol (ts
, &attr
, &as
))
868 gfc_set_sym_referenced (ts
->u
.derived
);
870 /* Make sure the _vptr is set. */
871 c
= gfc_find_component (ts
->u
.derived
, "_vptr", true, true, NULL
);
872 if (c
->ts
.u
.derived
== NULL
)
873 c
->ts
.u
.derived
= gfc_find_derived_vtab (der
);
874 /* _vptr now has the _vtab in it, change it to the _vtype. */
875 if (c
->ts
.u
.derived
->attr
.vtab
)
876 c
->ts
.u
.derived
= c
->ts
.u
.derived
->ts
.u
.derived
;
880 /* Add a procedure pointer component to the vtype
881 to represent a specific type-bound procedure. */
884 add_proc_comp (gfc_symbol
*vtype
, const char *name
, gfc_typebound_proc
*tb
)
888 if (tb
->non_overridable
&& !tb
->overridden
)
891 c
= gfc_find_component (vtype
, name
, true, true, NULL
);
895 /* Add procedure component. */
896 if (!gfc_add_component (vtype
, name
, &c
))
900 c
->tb
= XCNEW (gfc_typebound_proc
);
903 c
->attr
.procedure
= 1;
904 c
->attr
.proc_pointer
= 1;
905 c
->attr
.flavor
= FL_PROCEDURE
;
906 c
->attr
.access
= ACCESS_PRIVATE
;
907 c
->attr
.external
= 1;
909 c
->attr
.if_source
= IFSRC_IFBODY
;
911 else if (c
->attr
.proc_pointer
&& c
->tb
)
919 gfc_symbol
*ifc
= tb
->u
.specific
->n
.sym
;
920 c
->ts
.interface
= ifc
;
922 c
->initializer
= gfc_get_variable_expr (tb
->u
.specific
);
923 c
->attr
.pure
= ifc
->attr
.pure
;
928 /* Add all specific type-bound procedures in the symtree 'st' to a vtype. */
931 add_procs_to_declared_vtab1 (gfc_symtree
*st
, gfc_symbol
*vtype
)
937 add_procs_to_declared_vtab1 (st
->left
, vtype
);
940 add_procs_to_declared_vtab1 (st
->right
, vtype
);
942 if (st
->n
.tb
&& !st
->n
.tb
->error
943 && !st
->n
.tb
->is_generic
&& st
->n
.tb
->u
.specific
)
944 add_proc_comp (vtype
, st
->name
, st
->n
.tb
);
948 /* Copy procedure pointers components from the parent type. */
951 copy_vtab_proc_comps (gfc_symbol
*declared
, gfc_symbol
*vtype
)
956 vtab
= gfc_find_derived_vtab (declared
);
958 for (cmp
= vtab
->ts
.u
.derived
->components
; cmp
; cmp
= cmp
->next
)
960 if (gfc_find_component (vtype
, cmp
->name
, true, true, NULL
))
963 add_proc_comp (vtype
, cmp
->name
, cmp
->tb
);
968 /* Returns true if any of its nonpointer nonallocatable components or
969 their nonpointer nonallocatable subcomponents has a finalization
973 has_finalizer_component (gfc_symbol
*derived
)
977 for (c
= derived
->components
; c
; c
= c
->next
)
978 if (c
->ts
.type
== BT_DERIVED
&& !c
->attr
.pointer
&& !c
->attr
.allocatable
979 && c
->attr
.flavor
!= FL_PROCEDURE
)
981 if (c
->ts
.u
.derived
->f2k_derived
982 && c
->ts
.u
.derived
->f2k_derived
->finalizers
)
985 /* Stop infinite recursion through this function by inhibiting
986 calls when the derived type and that of the component are
988 if (!gfc_compare_derived_types (derived
, c
->ts
.u
.derived
)
989 && has_finalizer_component (c
->ts
.u
.derived
))
997 comp_is_finalizable (gfc_component
*comp
)
999 if (comp
->attr
.proc_pointer
)
1001 else if (comp
->attr
.allocatable
&& comp
->ts
.type
!= BT_CLASS
)
1003 else if (comp
->ts
.type
== BT_DERIVED
&& !comp
->attr
.pointer
1004 && (comp
->ts
.u
.derived
->attr
.alloc_comp
1005 || has_finalizer_component (comp
->ts
.u
.derived
)
1006 || (comp
->ts
.u
.derived
->f2k_derived
1007 && comp
->ts
.u
.derived
->f2k_derived
->finalizers
)))
1009 else if (comp
->ts
.type
== BT_CLASS
&& CLASS_DATA (comp
)
1010 && CLASS_DATA (comp
)->attr
.allocatable
)
1017 /* Call DEALLOCATE for the passed component if it is allocatable, if it is
1018 neither allocatable nor a pointer but has a finalizer, call it. If it
1019 is a nonpointer component with allocatable components or has finalizers, walk
1020 them. Either of them is required; other nonallocatables and pointers aren't
1022 Note: If the component is allocatable, the DEALLOCATE handling takes care
1023 of calling the appropriate finalizers, coarray deregistering, and
1024 deallocation of allocatable subcomponents. */
1027 finalize_component (gfc_expr
*expr
, gfc_symbol
*derived
, gfc_component
*comp
,
1028 gfc_symbol
*stat
, gfc_symbol
*fini_coarray
, gfc_code
**code
,
1029 gfc_namespace
*sub_ns
)
1033 gfc_was_finalized
*f
;
1035 if (!comp_is_finalizable (comp
))
1038 /* If this expression with this component has been finalized
1039 already in this namespace, there is nothing to do. */
1040 for (f
= sub_ns
->was_finalized
; f
; f
= f
->next
)
1042 if (f
->e
== expr
&& f
->c
== comp
)
1046 e
= gfc_copy_expr (expr
);
1048 e
->ref
= ref
= gfc_get_ref ();
1051 for (ref
= e
->ref
; ref
->next
; ref
= ref
->next
)
1053 ref
->next
= gfc_get_ref ();
1056 ref
->type
= REF_COMPONENT
;
1057 ref
->u
.c
.sym
= derived
;
1058 ref
->u
.c
.component
= comp
;
1061 if (comp
->attr
.dimension
|| comp
->attr
.codimension
1062 || (comp
->ts
.type
== BT_CLASS
&& CLASS_DATA (comp
)
1063 && (CLASS_DATA (comp
)->attr
.dimension
1064 || CLASS_DATA (comp
)->attr
.codimension
)))
1066 ref
->next
= gfc_get_ref ();
1067 ref
->next
->type
= REF_ARRAY
;
1068 ref
->next
->u
.ar
.dimen
= 0;
1069 ref
->next
->u
.ar
.as
= comp
->ts
.type
== BT_CLASS
? CLASS_DATA (comp
)->as
1071 e
->rank
= ref
->next
->u
.ar
.as
->rank
;
1072 e
->corank
= ref
->next
->u
.ar
.as
->corank
;
1073 ref
->next
->u
.ar
.type
= e
->rank
? AR_FULL
: AR_ELEMENT
;
1076 /* Call DEALLOCATE (comp, stat=ignore). */
1077 if (comp
->attr
.allocatable
1078 || (comp
->ts
.type
== BT_CLASS
&& CLASS_DATA (comp
)
1079 && CLASS_DATA (comp
)->attr
.allocatable
))
1081 gfc_code
*dealloc
, *block
= NULL
;
1083 /* Add IF (fini_coarray). */
1084 if (comp
->attr
.codimension
1085 || (comp
->ts
.type
== BT_CLASS
&& CLASS_DATA (comp
)
1086 && CLASS_DATA (comp
)->attr
.codimension
))
1088 block
= gfc_get_code (EXEC_IF
);
1091 (*code
)->next
= block
;
1092 (*code
) = (*code
)->next
;
1097 block
->block
= gfc_get_code (EXEC_IF
);
1098 block
= block
->block
;
1099 block
->expr1
= gfc_lval_expr_from_sym (fini_coarray
);
1102 dealloc
= gfc_get_code (EXEC_DEALLOCATE
);
1104 dealloc
->ext
.alloc
.list
= gfc_get_alloc ();
1105 dealloc
->ext
.alloc
.list
->expr
= e
;
1106 dealloc
->expr1
= gfc_lval_expr_from_sym (stat
);
1108 gfc_code
*cond
= gfc_get_code (EXEC_IF
);
1109 cond
->block
= gfc_get_code (EXEC_IF
);
1110 cond
->block
->expr1
= gfc_get_expr ();
1111 cond
->block
->expr1
->expr_type
= EXPR_FUNCTION
;
1112 cond
->block
->expr1
->where
= gfc_current_locus
;
1113 gfc_get_sym_tree ("associated", sub_ns
, &cond
->block
->expr1
->symtree
, false);
1114 cond
->block
->expr1
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
1115 cond
->block
->expr1
->symtree
->n
.sym
->attr
.intrinsic
= 1;
1116 cond
->block
->expr1
->symtree
->n
.sym
->result
= cond
->block
->expr1
->symtree
->n
.sym
;
1117 gfc_commit_symbol (cond
->block
->expr1
->symtree
->n
.sym
);
1118 cond
->block
->expr1
->ts
.type
= BT_LOGICAL
;
1119 cond
->block
->expr1
->ts
.kind
= gfc_default_logical_kind
;
1120 cond
->block
->expr1
->value
.function
.isym
= gfc_intrinsic_function_by_id (GFC_ISYM_ASSOCIATED
);
1121 cond
->block
->expr1
->value
.function
.actual
= gfc_get_actual_arglist ();
1122 cond
->block
->expr1
->value
.function
.actual
->expr
= gfc_copy_expr (expr
);
1123 cond
->block
->expr1
->value
.function
.actual
->next
= gfc_get_actual_arglist ();
1124 cond
->block
->next
= dealloc
;
1130 (*code
)->next
= cond
;
1131 (*code
) = (*code
)->next
;
1137 else if (comp
->ts
.type
== BT_DERIVED
1138 && comp
->ts
.u
.derived
->f2k_derived
1139 && comp
->ts
.u
.derived
->f2k_derived
->finalizers
)
1141 /* Call FINAL_WRAPPER (comp); */
1142 gfc_code
*final_wrap
;
1143 gfc_symbol
*vtab
, *byte_stride
;
1144 gfc_expr
*scalar
, *size_expr
, *fini_coarray_expr
;
1147 vtab
= gfc_find_derived_vtab (comp
->ts
.u
.derived
);
1148 for (c
= vtab
->ts
.u
.derived
->components
; c
; c
= c
->next
)
1149 if (strcmp (c
->name
, "_final") == 0)
1154 /* Set scalar argument for storage_size. */
1155 gfc_get_symbol ("comp_byte_stride", sub_ns
, &byte_stride
);
1156 byte_stride
->ts
= e
->ts
;
1157 byte_stride
->attr
.flavor
= FL_VARIABLE
;
1158 byte_stride
->attr
.value
= 1;
1159 byte_stride
->attr
.artificial
= 1;
1160 gfc_set_sym_referenced (byte_stride
);
1161 gfc_commit_symbol (byte_stride
);
1162 scalar
= gfc_lval_expr_from_sym (byte_stride
);
1164 final_wrap
= gfc_get_code (EXEC_CALL
);
1165 final_wrap
->symtree
= c
->initializer
->symtree
;
1166 final_wrap
->resolved_sym
= c
->initializer
->symtree
->n
.sym
;
1167 final_wrap
->ext
.actual
= gfc_get_actual_arglist ();
1168 final_wrap
->ext
.actual
->expr
= e
;
1170 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1171 size_expr
= gfc_get_expr ();
1172 size_expr
->where
= gfc_current_locus
;
1173 size_expr
->expr_type
= EXPR_OP
;
1174 size_expr
->value
.op
.op
= INTRINSIC_DIVIDE
;
1176 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1177 size_expr
->value
.op
.op1
1178 = gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_STORAGE_SIZE
,
1179 "storage_size", gfc_current_locus
, 2,
1181 gfc_get_int_expr (gfc_index_integer_kind
,
1184 /* NUMERIC_STORAGE_SIZE. */
1185 size_expr
->value
.op
.op2
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
,
1186 gfc_character_storage_size
);
1187 size_expr
->value
.op
.op1
->ts
= size_expr
->value
.op
.op2
->ts
;
1188 size_expr
->ts
= size_expr
->value
.op
.op1
->ts
;
1190 /* Which provides the argument 'byte_stride'..... */
1191 final_wrap
->ext
.actual
->next
= gfc_get_actual_arglist ();
1192 final_wrap
->ext
.actual
->next
->expr
= size_expr
;
1194 /* ...and last of all the 'fini_coarray' argument. */
1195 fini_coarray_expr
= gfc_lval_expr_from_sym (fini_coarray
);
1196 final_wrap
->ext
.actual
->next
->next
= gfc_get_actual_arglist ();
1197 final_wrap
->ext
.actual
->next
->next
->expr
= fini_coarray_expr
;
1203 (*code
)->next
= final_wrap
;
1204 (*code
) = (*code
)->next
;
1207 (*code
) = final_wrap
;
1213 for (c
= comp
->ts
.u
.derived
->components
; c
; c
= c
->next
)
1214 finalize_component (e
, comp
->ts
.u
.derived
, c
, stat
, fini_coarray
, code
,
1219 /* Record that this was finalized already in this namespace. */
1220 f
= sub_ns
->was_finalized
;
1221 sub_ns
->was_finalized
= XCNEW (gfc_was_finalized
);
1222 sub_ns
->was_finalized
->e
= expr
;
1223 sub_ns
->was_finalized
->c
= comp
;
1224 sub_ns
->was_finalized
->next
= f
;
1228 /* Generate code equivalent to
1229 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1230 + offset, c_ptr), ptr). */
1233 finalization_scalarizer (gfc_symbol
*array
, gfc_symbol
*ptr
,
1234 gfc_expr
*offset
, gfc_namespace
*sub_ns
)
1237 gfc_expr
*expr
, *expr2
;
1239 /* C_F_POINTER(). */
1240 block
= gfc_get_code (EXEC_CALL
);
1241 gfc_get_sym_tree ("c_f_pointer", sub_ns
, &block
->symtree
, true);
1242 block
->resolved_sym
= block
->symtree
->n
.sym
;
1243 block
->resolved_sym
->attr
.flavor
= FL_PROCEDURE
;
1244 block
->resolved_sym
->attr
.intrinsic
= 1;
1245 block
->resolved_sym
->attr
.subroutine
= 1;
1246 block
->resolved_sym
->from_intmod
= INTMOD_ISO_C_BINDING
;
1247 block
->resolved_sym
->intmod_sym_id
= ISOCBINDING_F_POINTER
;
1248 block
->resolved_isym
= gfc_intrinsic_subroutine_by_id (GFC_ISYM_C_F_POINTER
);
1249 gfc_commit_symbol (block
->resolved_sym
);
1251 /* C_F_POINTER's first argument: TRANSFER ( <addr>, c_intptr_t). */
1252 block
->ext
.actual
= gfc_get_actual_arglist ();
1253 block
->ext
.actual
->next
= gfc_get_actual_arglist ();
1254 block
->ext
.actual
->next
->expr
= gfc_get_int_expr (gfc_index_integer_kind
,
1256 block
->ext
.actual
->next
->next
= gfc_get_actual_arglist (); /* SIZE. */
1258 /* The <addr> part: TRANSFER (C_LOC (array), c_intptr_t). */
1260 /* TRANSFER's first argument: C_LOC (array). */
1261 expr
= gfc_get_expr ();
1262 expr
->expr_type
= EXPR_FUNCTION
;
1263 gfc_get_sym_tree ("c_loc", sub_ns
, &expr
->symtree
, false);
1264 expr
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
1265 expr
->symtree
->n
.sym
->intmod_sym_id
= ISOCBINDING_LOC
;
1266 expr
->symtree
->n
.sym
->attr
.intrinsic
= 1;
1267 expr
->symtree
->n
.sym
->from_intmod
= INTMOD_ISO_C_BINDING
;
1268 expr
->value
.function
.isym
= gfc_intrinsic_function_by_id (GFC_ISYM_C_LOC
);
1269 expr
->value
.function
.actual
= gfc_get_actual_arglist ();
1270 expr
->value
.function
.actual
->expr
1271 = gfc_lval_expr_from_sym (array
);
1272 expr
->symtree
->n
.sym
->result
= expr
->symtree
->n
.sym
;
1273 gfc_commit_symbol (expr
->symtree
->n
.sym
);
1274 expr
->ts
.type
= BT_INTEGER
;
1275 expr
->ts
.kind
= gfc_index_integer_kind
;
1276 expr
->where
= gfc_current_locus
;
1279 expr2
= gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_TRANSFER
, "transfer",
1280 gfc_current_locus
, 3, expr
,
1281 gfc_get_int_expr (gfc_index_integer_kind
,
1283 expr2
->ts
.type
= BT_INTEGER
;
1284 expr2
->ts
.kind
= gfc_index_integer_kind
;
1286 /* <array addr> + <offset>. */
1287 block
->ext
.actual
->expr
= gfc_get_expr ();
1288 block
->ext
.actual
->expr
->expr_type
= EXPR_OP
;
1289 block
->ext
.actual
->expr
->value
.op
.op
= INTRINSIC_PLUS
;
1290 block
->ext
.actual
->expr
->value
.op
.op1
= expr2
;
1291 block
->ext
.actual
->expr
->value
.op
.op2
= offset
;
1292 block
->ext
.actual
->expr
->ts
= expr
->ts
;
1293 block
->ext
.actual
->expr
->where
= gfc_current_locus
;
1295 /* C_F_POINTER's 2nd arg: ptr -- and its absent shape=. */
1296 block
->ext
.actual
->next
= gfc_get_actual_arglist ();
1297 block
->ext
.actual
->next
->expr
= gfc_lval_expr_from_sym (ptr
);
1298 block
->ext
.actual
->next
->next
= gfc_get_actual_arglist ();
1304 /* Calculates the offset to the (idx+1)th element of an array, taking the
1305 stride into account. It generates the code:
1308 offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1) * strides(idx2)
1310 offset = offset * byte_stride. */
1313 finalization_get_offset (gfc_symbol
*idx
, gfc_symbol
*idx2
, gfc_symbol
*offset
,
1314 gfc_symbol
*strides
, gfc_symbol
*sizes
,
1315 gfc_symbol
*byte_stride
, gfc_expr
*rank
,
1316 gfc_code
*block
, gfc_namespace
*sub_ns
)
1319 gfc_expr
*expr
, *expr2
;
1322 block
->next
= gfc_get_code (EXEC_ASSIGN
);
1323 block
= block
->next
;
1324 block
->expr1
= gfc_lval_expr_from_sym (offset
);
1325 block
->expr2
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
1328 iter
= gfc_get_iterator ();
1329 iter
->var
= gfc_lval_expr_from_sym (idx2
);
1330 iter
->start
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1331 iter
->end
= gfc_copy_expr (rank
);
1332 iter
->step
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1333 block
->next
= gfc_get_code (EXEC_DO
);
1334 block
= block
->next
;
1335 block
->ext
.iterator
= iter
;
1336 block
->block
= gfc_get_code (EXEC_DO
);
1338 /* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
1341 /* mod (idx, sizes(idx2)). */
1342 expr
= gfc_lval_expr_from_sym (sizes
);
1343 expr
->ref
= gfc_get_ref ();
1344 expr
->ref
->type
= REF_ARRAY
;
1345 expr
->ref
->u
.ar
.as
= sizes
->as
;
1346 expr
->ref
->u
.ar
.type
= AR_ELEMENT
;
1347 expr
->ref
->u
.ar
.dimen
= 1;
1348 expr
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
1349 expr
->ref
->u
.ar
.start
[0] = gfc_lval_expr_from_sym (idx2
);
1350 expr
->where
= sizes
->declared_at
;
1352 expr
= gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_MOD
, "mod",
1353 gfc_current_locus
, 2,
1354 gfc_lval_expr_from_sym (idx
), expr
);
1357 /* (...) / sizes(idx2-1). */
1358 expr2
= gfc_get_expr ();
1359 expr2
->expr_type
= EXPR_OP
;
1360 expr2
->value
.op
.op
= INTRINSIC_DIVIDE
;
1361 expr2
->value
.op
.op1
= expr
;
1362 expr2
->value
.op
.op2
= gfc_lval_expr_from_sym (sizes
);
1363 expr2
->value
.op
.op2
->ref
= gfc_get_ref ();
1364 expr2
->value
.op
.op2
->ref
->type
= REF_ARRAY
;
1365 expr2
->value
.op
.op2
->ref
->u
.ar
.as
= sizes
->as
;
1366 expr2
->value
.op
.op2
->ref
->u
.ar
.type
= AR_ELEMENT
;
1367 expr2
->value
.op
.op2
->ref
->u
.ar
.dimen
= 1;
1368 expr2
->value
.op
.op2
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
1369 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0] = gfc_get_expr ();
1370 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->expr_type
= EXPR_OP
;
1371 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->where
= gfc_current_locus
;
1372 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op
= INTRINSIC_MINUS
;
1373 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op1
1374 = gfc_lval_expr_from_sym (idx2
);
1375 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op2
1376 = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1377 expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->ts
1378 = expr2
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op1
->ts
;
1379 expr2
->ts
= idx
->ts
;
1380 expr2
->where
= gfc_current_locus
;
1382 /* ... * strides(idx2). */
1383 expr
= gfc_get_expr ();
1384 expr
->expr_type
= EXPR_OP
;
1385 expr
->value
.op
.op
= INTRINSIC_TIMES
;
1386 expr
->value
.op
.op1
= expr2
;
1387 expr
->value
.op
.op2
= gfc_lval_expr_from_sym (strides
);
1388 expr
->value
.op
.op2
->ref
= gfc_get_ref ();
1389 expr
->value
.op
.op2
->ref
->type
= REF_ARRAY
;
1390 expr
->value
.op
.op2
->ref
->u
.ar
.type
= AR_ELEMENT
;
1391 expr
->value
.op
.op2
->ref
->u
.ar
.dimen
= 1;
1392 expr
->value
.op
.op2
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
1393 expr
->value
.op
.op2
->ref
->u
.ar
.start
[0] = gfc_lval_expr_from_sym (idx2
);
1394 expr
->value
.op
.op2
->ref
->u
.ar
.as
= strides
->as
;
1396 expr
->where
= gfc_current_locus
;
1398 /* offset = offset + ... */
1399 block
->block
->next
= gfc_get_code (EXEC_ASSIGN
);
1400 block
->block
->next
->expr1
= gfc_lval_expr_from_sym (offset
);
1401 block
->block
->next
->expr2
= gfc_get_expr ();
1402 block
->block
->next
->expr2
->expr_type
= EXPR_OP
;
1403 block
->block
->next
->expr2
->value
.op
.op
= INTRINSIC_PLUS
;
1404 block
->block
->next
->expr2
->value
.op
.op1
= gfc_lval_expr_from_sym (offset
);
1405 block
->block
->next
->expr2
->value
.op
.op2
= expr
;
1406 block
->block
->next
->expr2
->ts
= idx
->ts
;
1407 block
->block
->next
->expr2
->where
= gfc_current_locus
;
1409 /* After the loop: offset = offset * byte_stride. */
1410 block
->next
= gfc_get_code (EXEC_ASSIGN
);
1411 block
= block
->next
;
1412 block
->expr1
= gfc_lval_expr_from_sym (offset
);
1413 block
->expr2
= gfc_get_expr ();
1414 block
->expr2
->expr_type
= EXPR_OP
;
1415 block
->expr2
->value
.op
.op
= INTRINSIC_TIMES
;
1416 block
->expr2
->value
.op
.op1
= gfc_lval_expr_from_sym (offset
);
1417 block
->expr2
->value
.op
.op2
= gfc_lval_expr_from_sym (byte_stride
);
1418 block
->expr2
->ts
= block
->expr2
->value
.op
.op1
->ts
;
1419 block
->expr2
->where
= gfc_current_locus
;
1424 /* Insert code of the following form:
1427 integer(c_intptr_t) :: i
1429 if ((byte_stride == STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1430 && (is_contiguous || !final_rank3->attr.contiguous
1431 || final_rank3->as->type != AS_ASSUMED_SHAPE))
1432 || 0 == STORAGE_SIZE (array)) then
1433 call final_rank3 (array)
1436 integer(c_intptr_t) :: offset, j
1437 type(t) :: tmp(shape (array))
1439 do i = 0, size (array)-1
1440 offset = obtain_offset(i, strides, sizes, byte_stride)
1441 addr = transfer (c_loc (array), addr) + offset
1442 call c_f_pointer (transfer (addr, cptr), ptr)
1444 addr = transfer (c_loc (tmp), addr)
1445 + i * STORAGE_SIZE (array)/NUMERIC_STORAGE_SIZE
1446 call c_f_pointer (transfer (addr, cptr), ptr2)
1449 call final_rank3 (tmp)
1455 finalizer_insert_packed_call (gfc_code
*block
, gfc_finalizer
*fini
,
1456 gfc_symbol
*array
, gfc_symbol
*byte_stride
,
1457 gfc_symbol
*idx
, gfc_symbol
*ptr
,
1459 gfc_symbol
*strides
, gfc_symbol
*sizes
,
1460 gfc_symbol
*idx2
, gfc_symbol
*offset
,
1461 gfc_symbol
*is_contiguous
, gfc_expr
*rank
,
1462 gfc_namespace
*sub_ns
)
1464 gfc_symbol
*tmp_array
, *ptr2
;
1465 gfc_expr
*size_expr
, *offset2
, *expr
;
1471 block
->next
= gfc_get_code (EXEC_IF
);
1472 block
= block
->next
;
1474 block
->block
= gfc_get_code (EXEC_IF
);
1475 block
= block
->block
;
1477 /* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
1478 size_expr
= gfc_get_expr ();
1479 size_expr
->where
= gfc_current_locus
;
1480 size_expr
->expr_type
= EXPR_OP
;
1481 size_expr
->value
.op
.op
= INTRINSIC_DIVIDE
;
1483 /* STORAGE_SIZE (array,kind=c_intptr_t). */
1484 size_expr
->value
.op
.op1
1485 = gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_STORAGE_SIZE
,
1486 "storage_size", gfc_current_locus
, 2,
1487 gfc_lval_expr_from_sym (array
),
1488 gfc_get_int_expr (gfc_index_integer_kind
,
1491 /* NUMERIC_STORAGE_SIZE. */
1492 size_expr
->value
.op
.op2
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
,
1493 gfc_character_storage_size
);
1494 size_expr
->value
.op
.op1
->ts
= size_expr
->value
.op
.op2
->ts
;
1495 size_expr
->ts
= size_expr
->value
.op
.op1
->ts
;
1497 /* IF condition: (stride == size_expr
1498 && ((fini's as->ASSUMED_SIZE && !fini's attr.contiguous)
1500 || 0 == size_expr. */
1501 block
->expr1
= gfc_get_expr ();
1502 block
->expr1
->ts
.type
= BT_LOGICAL
;
1503 block
->expr1
->ts
.kind
= gfc_default_logical_kind
;
1504 block
->expr1
->expr_type
= EXPR_OP
;
1505 block
->expr1
->where
= gfc_current_locus
;
1507 block
->expr1
->value
.op
.op
= INTRINSIC_OR
;
1509 /* byte_stride == size_expr */
1510 expr
= gfc_get_expr ();
1511 expr
->ts
.type
= BT_LOGICAL
;
1512 expr
->ts
.kind
= gfc_default_logical_kind
;
1513 expr
->expr_type
= EXPR_OP
;
1514 expr
->where
= gfc_current_locus
;
1515 expr
->value
.op
.op
= INTRINSIC_EQ
;
1517 = gfc_lval_expr_from_sym (byte_stride
);
1518 expr
->value
.op
.op2
= size_expr
;
1520 /* If strides aren't allowed (not assumed shape or CONTIGUOUS),
1521 add is_contiguous check. */
1523 if (fini
->proc_tree
->n
.sym
->formal
->sym
->as
->type
!= AS_ASSUMED_SHAPE
1524 || fini
->proc_tree
->n
.sym
->formal
->sym
->attr
.contiguous
)
1527 expr2
= gfc_get_expr ();
1528 expr2
->ts
.type
= BT_LOGICAL
;
1529 expr2
->ts
.kind
= gfc_default_logical_kind
;
1530 expr2
->expr_type
= EXPR_OP
;
1531 expr2
->where
= gfc_current_locus
;
1532 expr2
->value
.op
.op
= INTRINSIC_AND
;
1533 expr2
->value
.op
.op1
= expr
;
1534 expr2
->value
.op
.op2
= gfc_lval_expr_from_sym (is_contiguous
);
1538 block
->expr1
->value
.op
.op1
= expr
;
1540 /* 0 == size_expr */
1541 block
->expr1
->value
.op
.op2
= gfc_get_expr ();
1542 block
->expr1
->value
.op
.op2
->ts
.type
= BT_LOGICAL
;
1543 block
->expr1
->value
.op
.op2
->ts
.kind
= gfc_default_logical_kind
;
1544 block
->expr1
->value
.op
.op2
->expr_type
= EXPR_OP
;
1545 block
->expr1
->value
.op
.op2
->where
= gfc_current_locus
;
1546 block
->expr1
->value
.op
.op2
->value
.op
.op
= INTRINSIC_EQ
;
1547 block
->expr1
->value
.op
.op2
->value
.op
.op1
=
1548 gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
1549 block
->expr1
->value
.op
.op2
->value
.op
.op2
= gfc_copy_expr (size_expr
);
1551 /* IF body: call final subroutine. */
1552 block
->next
= gfc_get_code (EXEC_CALL
);
1553 block
->next
->symtree
= fini
->proc_tree
;
1554 block
->next
->resolved_sym
= fini
->proc_tree
->n
.sym
;
1555 block
->next
->ext
.actual
= gfc_get_actual_arglist ();
1556 block
->next
->ext
.actual
->expr
= gfc_lval_expr_from_sym (array
);
1560 block
->block
= gfc_get_code (EXEC_IF
);
1561 block
= block
->block
;
1563 /* BLOCK ... END BLOCK. */
1564 block
->next
= gfc_get_code (EXEC_BLOCK
);
1565 block
= block
->next
;
1567 ns
= gfc_build_block_ns (sub_ns
);
1568 block
->ext
.block
.ns
= ns
;
1569 block
->ext
.block
.assoc
= NULL
;
1571 gfc_get_symbol ("ptr2", ns
, &ptr2
);
1572 ptr2
->ts
.type
= BT_DERIVED
;
1573 ptr2
->ts
.u
.derived
= array
->ts
.u
.derived
;
1574 ptr2
->attr
.flavor
= FL_VARIABLE
;
1575 ptr2
->attr
.pointer
= 1;
1576 ptr2
->attr
.artificial
= 1;
1577 gfc_set_sym_referenced (ptr2
);
1578 gfc_commit_symbol (ptr2
);
1580 gfc_get_symbol ("tmp_array", ns
, &tmp_array
);
1581 tmp_array
->ts
.type
= BT_DERIVED
;
1582 tmp_array
->ts
.u
.derived
= array
->ts
.u
.derived
;
1583 tmp_array
->attr
.flavor
= FL_VARIABLE
;
1584 tmp_array
->attr
.dimension
= 1;
1585 tmp_array
->attr
.artificial
= 1;
1586 tmp_array
->as
= gfc_get_array_spec();
1587 tmp_array
->attr
.intent
= INTENT_INOUT
;
1588 tmp_array
->as
->type
= AS_EXPLICIT
;
1589 tmp_array
->as
->rank
= fini
->proc_tree
->n
.sym
->formal
->sym
->as
->rank
;
1591 for (i
= 0; i
< tmp_array
->as
->rank
; i
++)
1593 gfc_expr
*shape_expr
;
1594 tmp_array
->as
->lower
[i
] = gfc_get_int_expr (gfc_default_integer_kind
,
1596 /* SIZE (array, dim=i+1, kind=gfc_index_integer_kind). */
1598 = gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_SIZE
, "size",
1599 gfc_current_locus
, 3,
1600 gfc_lval_expr_from_sym (array
),
1601 gfc_get_int_expr (gfc_default_integer_kind
,
1603 gfc_get_int_expr (gfc_default_integer_kind
,
1605 gfc_index_integer_kind
));
1606 shape_expr
->ts
.kind
= gfc_index_integer_kind
;
1607 tmp_array
->as
->upper
[i
] = shape_expr
;
1609 gfc_set_sym_referenced (tmp_array
);
1610 gfc_commit_symbol (tmp_array
);
1613 iter
= gfc_get_iterator ();
1614 iter
->var
= gfc_lval_expr_from_sym (idx
);
1615 iter
->start
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
1616 iter
->end
= gfc_lval_expr_from_sym (nelem
);
1617 iter
->step
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1619 block
= gfc_get_code (EXEC_DO
);
1621 block
->ext
.iterator
= iter
;
1622 block
->block
= gfc_get_code (EXEC_DO
);
1624 /* Offset calculation for the new array: idx * size of type (in bytes). */
1625 offset2
= gfc_get_expr ();
1626 offset2
->expr_type
= EXPR_OP
;
1627 offset2
->where
= gfc_current_locus
;
1628 offset2
->value
.op
.op
= INTRINSIC_TIMES
;
1629 offset2
->value
.op
.op1
= gfc_lval_expr_from_sym (idx
);
1630 offset2
->value
.op
.op2
= gfc_copy_expr (size_expr
);
1631 offset2
->ts
= byte_stride
->ts
;
1633 /* Offset calculation of "array". */
1634 block2
= finalization_get_offset (idx
, idx2
, offset
, strides
, sizes
,
1635 byte_stride
, rank
, block
->block
, sub_ns
);
1638 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1639 + idx * stride, c_ptr), ptr). */
1640 block2
->next
= finalization_scalarizer (array
, ptr
,
1641 gfc_lval_expr_from_sym (offset
),
1643 block2
= block2
->next
;
1644 block2
->next
= finalization_scalarizer (tmp_array
, ptr2
, offset2
, sub_ns
);
1645 block2
= block2
->next
;
1648 block2
->next
= gfc_get_code (EXEC_ASSIGN
);
1649 block2
= block2
->next
;
1650 block2
->expr1
= gfc_lval_expr_from_sym (ptr2
);
1651 block2
->expr2
= gfc_lval_expr_from_sym (ptr
);
1653 /* Call now the user's final subroutine. */
1654 block
->next
= gfc_get_code (EXEC_CALL
);
1655 block
= block
->next
;
1656 block
->symtree
= fini
->proc_tree
;
1657 block
->resolved_sym
= fini
->proc_tree
->n
.sym
;
1658 block
->ext
.actual
= gfc_get_actual_arglist ();
1659 block
->ext
.actual
->expr
= gfc_lval_expr_from_sym (tmp_array
);
1661 if (fini
->proc_tree
->n
.sym
->formal
->sym
->attr
.intent
== INTENT_IN
)
1667 iter
= gfc_get_iterator ();
1668 iter
->var
= gfc_lval_expr_from_sym (idx
);
1669 iter
->start
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
1670 iter
->end
= gfc_lval_expr_from_sym (nelem
);
1671 iter
->step
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1673 block
->next
= gfc_get_code (EXEC_DO
);
1674 block
= block
->next
;
1675 block
->ext
.iterator
= iter
;
1676 block
->block
= gfc_get_code (EXEC_DO
);
1678 /* Offset calculation of "array". */
1679 block2
= finalization_get_offset (idx
, idx2
, offset
, strides
, sizes
,
1680 byte_stride
, rank
, block
->block
, sub_ns
);
1683 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
1684 + offset, c_ptr), ptr). */
1685 block2
->next
= finalization_scalarizer (array
, ptr
,
1686 gfc_lval_expr_from_sym (offset
),
1688 block2
= block2
->next
;
1689 block2
->next
= finalization_scalarizer (tmp_array
, ptr2
,
1690 gfc_copy_expr (offset2
), sub_ns
);
1691 block2
= block2
->next
;
1694 block2
->next
= gfc_get_code (EXEC_ASSIGN
);
1695 block2
->next
->expr1
= gfc_lval_expr_from_sym (ptr
);
1696 block2
->next
->expr2
= gfc_lval_expr_from_sym (ptr2
);
1700 /* Generate the finalization/polymorphic freeing wrapper subroutine for the
1701 derived type "derived". The function first calls the appropriate FINAL
1702 subroutine, then it DEALLOCATEs (finalizes/frees) the allocatable
1703 components (but not the inherited ones). Last, it calls the wrapper
1704 subroutine of the parent. The generated wrapper procedure takes as argument
1705 an assumed-rank array.
1706 If neither allocatable components nor FINAL subroutines exists, the vtab
1707 will contain a NULL pointer.
1708 The generated function has the form
1709 _final(assumed-rank array, stride, skip_corarray)
1710 where the array has to be contiguous (except of the lowest dimension). The
1711 stride (in bytes) is used to allow different sizes for ancestor types by
1712 skipping over the additionally added components in the scalarizer. If
1713 "fini_coarray" is false, coarray components are not finalized to allow for
1714 the correct semantic with intrinsic assignment. */
1717 generate_finalization_wrapper (gfc_symbol
*derived
, gfc_namespace
*ns
,
1718 const char *tname
, gfc_component
*vtab_final
)
1720 gfc_symbol
*final
, *array
, *fini_coarray
, *byte_stride
, *sizes
, *strides
;
1721 gfc_symbol
*ptr
= NULL
, *idx
, *idx2
, *is_contiguous
, *offset
, *nelem
;
1722 gfc_component
*comp
;
1723 gfc_namespace
*sub_ns
;
1724 gfc_code
*last_code
, *block
;
1726 bool finalizable_comp
= false;
1727 gfc_expr
*ancestor_wrapper
= NULL
, *rank
;
1730 if (derived
->attr
.unlimited_polymorphic
)
1732 vtab_final
->initializer
= gfc_get_null_expr (NULL
);
1736 /* Search for the ancestor's finalizers. */
1737 if (derived
->attr
.extension
&& derived
->components
1738 && (!derived
->components
->ts
.u
.derived
->attr
.abstract
1739 || has_finalizer_component (derived
)))
1742 gfc_component
*comp
;
1744 vtab
= gfc_find_derived_vtab (derived
->components
->ts
.u
.derived
);
1745 for (comp
= vtab
->ts
.u
.derived
->components
; comp
; comp
= comp
->next
)
1746 if (comp
->name
[0] == '_' && comp
->name
[1] == 'f')
1748 ancestor_wrapper
= comp
->initializer
;
1753 /* No wrapper of the ancestor and no own FINAL subroutines and allocatable
1754 components: Return a NULL() expression; we defer this a bit to have
1755 an interface declaration. */
1756 if ((!ancestor_wrapper
|| ancestor_wrapper
->expr_type
== EXPR_NULL
)
1757 && !derived
->attr
.alloc_comp
1758 && (!derived
->f2k_derived
|| !derived
->f2k_derived
->finalizers
)
1759 && !has_finalizer_component (derived
))
1761 vtab_final
->initializer
= gfc_get_null_expr (NULL
);
1762 gcc_assert (vtab_final
->ts
.interface
== NULL
);
1766 /* Check whether there are new allocatable components. */
1767 for (comp
= derived
->components
; comp
; comp
= comp
->next
)
1769 if (comp
== derived
->components
&& derived
->attr
.extension
1770 && ancestor_wrapper
&& ancestor_wrapper
->expr_type
!= EXPR_NULL
)
1773 finalizable_comp
|= comp_is_finalizable (comp
);
1776 /* If there is no new finalizer and no new allocatable, return with
1777 an expr to the ancestor's one. */
1778 if (!finalizable_comp
1779 && (!derived
->f2k_derived
|| !derived
->f2k_derived
->finalizers
))
1781 gcc_assert (ancestor_wrapper
&& ancestor_wrapper
->ref
== NULL
1782 && ancestor_wrapper
->expr_type
== EXPR_VARIABLE
);
1783 vtab_final
->initializer
= gfc_copy_expr (ancestor_wrapper
);
1784 vtab_final
->ts
.interface
= vtab_final
->initializer
->symtree
->n
.sym
;
1788 /* We now create a wrapper, which does the following:
1789 1. Call the suitable finalization subroutine for this type
1790 2. Loop over all noninherited allocatable components and noninherited
1791 components with allocatable components and DEALLOCATE those; this will
1792 take care of finalizers, coarray deregistering and allocatable
1794 3. Call the ancestor's finalizer. */
1796 /* Declare the wrapper function; it takes an assumed-rank array
1797 and a VALUE logical as arguments. */
1799 /* Set up the namespace. */
1800 sub_ns
= gfc_get_namespace (ns
, 0);
1801 sub_ns
->sibling
= ns
->contained
;
1802 ns
->contained
= sub_ns
;
1803 sub_ns
->resolved
= 1;
1805 /* Set up the procedure symbol. */
1806 name
= xasprintf ("__final_%s", tname
);
1807 gfc_get_symbol (name
, sub_ns
, &final
);
1808 sub_ns
->proc_name
= final
;
1809 final
->attr
.flavor
= FL_PROCEDURE
;
1810 final
->attr
.function
= 1;
1811 final
->attr
.pure
= 0;
1812 final
->attr
.recursive
= 1;
1813 final
->result
= final
;
1814 final
->ts
.type
= BT_INTEGER
;
1816 final
->attr
.artificial
= 1;
1817 final
->attr
.always_explicit
= 1;
1818 final
->attr
.if_source
= IFSRC_DECL
;
1819 if (ns
->proc_name
->attr
.flavor
== FL_MODULE
)
1820 final
->module
= ns
->proc_name
->name
;
1821 gfc_set_sym_referenced (final
);
1822 gfc_commit_symbol (final
);
1824 /* Set up formal argument. */
1825 gfc_get_symbol ("array", sub_ns
, &array
);
1826 array
->ts
.type
= BT_DERIVED
;
1827 array
->ts
.u
.derived
= derived
;
1828 array
->attr
.flavor
= FL_VARIABLE
;
1829 array
->attr
.dummy
= 1;
1830 array
->attr
.contiguous
= 1;
1831 array
->attr
.dimension
= 1;
1832 array
->attr
.artificial
= 1;
1833 array
->as
= gfc_get_array_spec();
1834 array
->as
->type
= AS_ASSUMED_RANK
;
1835 array
->as
->rank
= -1;
1836 array
->attr
.intent
= INTENT_INOUT
;
1837 gfc_set_sym_referenced (array
);
1838 final
->formal
= gfc_get_formal_arglist ();
1839 final
->formal
->sym
= array
;
1840 gfc_commit_symbol (array
);
1842 /* Set up formal argument. */
1843 gfc_get_symbol ("byte_stride", sub_ns
, &byte_stride
);
1844 byte_stride
->ts
.type
= BT_INTEGER
;
1845 byte_stride
->ts
.kind
= gfc_index_integer_kind
;
1846 byte_stride
->attr
.flavor
= FL_VARIABLE
;
1847 byte_stride
->attr
.dummy
= 1;
1848 byte_stride
->attr
.value
= 1;
1849 byte_stride
->attr
.artificial
= 1;
1850 gfc_set_sym_referenced (byte_stride
);
1851 final
->formal
->next
= gfc_get_formal_arglist ();
1852 final
->formal
->next
->sym
= byte_stride
;
1853 gfc_commit_symbol (byte_stride
);
1855 /* Set up formal argument. */
1856 gfc_get_symbol ("fini_coarray", sub_ns
, &fini_coarray
);
1857 fini_coarray
->ts
.type
= BT_LOGICAL
;
1858 fini_coarray
->ts
.kind
= 1;
1859 fini_coarray
->attr
.flavor
= FL_VARIABLE
;
1860 fini_coarray
->attr
.dummy
= 1;
1861 fini_coarray
->attr
.value
= 1;
1862 fini_coarray
->attr
.artificial
= 1;
1863 gfc_set_sym_referenced (fini_coarray
);
1864 final
->formal
->next
->next
= gfc_get_formal_arglist ();
1865 final
->formal
->next
->next
->sym
= fini_coarray
;
1866 gfc_commit_symbol (fini_coarray
);
1868 /* Local variables. */
1870 gfc_get_symbol ("idx", sub_ns
, &idx
);
1871 idx
->ts
.type
= BT_INTEGER
;
1872 idx
->ts
.kind
= gfc_index_integer_kind
;
1873 idx
->attr
.flavor
= FL_VARIABLE
;
1874 idx
->attr
.artificial
= 1;
1875 gfc_set_sym_referenced (idx
);
1876 gfc_commit_symbol (idx
);
1878 gfc_get_symbol ("idx2", sub_ns
, &idx2
);
1879 idx2
->ts
.type
= BT_INTEGER
;
1880 idx2
->ts
.kind
= gfc_index_integer_kind
;
1881 idx2
->attr
.flavor
= FL_VARIABLE
;
1882 idx2
->attr
.artificial
= 1;
1883 gfc_set_sym_referenced (idx2
);
1884 gfc_commit_symbol (idx2
);
1886 gfc_get_symbol ("offset", sub_ns
, &offset
);
1887 offset
->ts
.type
= BT_INTEGER
;
1888 offset
->ts
.kind
= gfc_index_integer_kind
;
1889 offset
->attr
.flavor
= FL_VARIABLE
;
1890 offset
->attr
.artificial
= 1;
1891 gfc_set_sym_referenced (offset
);
1892 gfc_commit_symbol (offset
);
1894 /* Create RANK expression. */
1895 rank
= gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_RANK
, "rank",
1896 gfc_current_locus
, 1,
1897 gfc_lval_expr_from_sym (array
));
1898 if (rank
->ts
.kind
!= idx
->ts
.kind
)
1899 gfc_convert_type_warn (rank
, &idx
->ts
, 2, 0);
1901 /* Create is_contiguous variable. */
1902 gfc_get_symbol ("is_contiguous", sub_ns
, &is_contiguous
);
1903 is_contiguous
->ts
.type
= BT_LOGICAL
;
1904 is_contiguous
->ts
.kind
= gfc_default_logical_kind
;
1905 is_contiguous
->attr
.flavor
= FL_VARIABLE
;
1906 is_contiguous
->attr
.artificial
= 1;
1907 gfc_set_sym_referenced (is_contiguous
);
1908 gfc_commit_symbol (is_contiguous
);
1910 /* Create "sizes(0..rank)" variable, which contains the multiplied
1911 up extent of the dimensions, i.e. sizes(0) = 1, sizes(1) = extent(dim=1),
1912 sizes(2) = sizes(1) * extent(dim=2) etc. */
1913 gfc_get_symbol ("sizes", sub_ns
, &sizes
);
1914 sizes
->ts
.type
= BT_INTEGER
;
1915 sizes
->ts
.kind
= gfc_index_integer_kind
;
1916 sizes
->attr
.flavor
= FL_VARIABLE
;
1917 sizes
->attr
.dimension
= 1;
1918 sizes
->attr
.artificial
= 1;
1919 sizes
->as
= gfc_get_array_spec();
1920 sizes
->attr
.intent
= INTENT_INOUT
;
1921 sizes
->as
->type
= AS_EXPLICIT
;
1922 sizes
->as
->rank
= 1;
1923 sizes
->as
->lower
[0] = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
1924 sizes
->as
->upper
[0] = gfc_copy_expr (rank
);
1925 gfc_set_sym_referenced (sizes
);
1926 gfc_commit_symbol (sizes
);
1928 /* Create "strides(1..rank)" variable, which contains the strides per
1930 gfc_get_symbol ("strides", sub_ns
, &strides
);
1931 strides
->ts
.type
= BT_INTEGER
;
1932 strides
->ts
.kind
= gfc_index_integer_kind
;
1933 strides
->attr
.flavor
= FL_VARIABLE
;
1934 strides
->attr
.dimension
= 1;
1935 strides
->attr
.artificial
= 1;
1936 strides
->as
= gfc_get_array_spec();
1937 strides
->attr
.intent
= INTENT_INOUT
;
1938 strides
->as
->type
= AS_EXPLICIT
;
1939 strides
->as
->rank
= 1;
1940 strides
->as
->lower
[0] = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1941 strides
->as
->upper
[0] = gfc_copy_expr (rank
);
1942 gfc_set_sym_referenced (strides
);
1943 gfc_commit_symbol (strides
);
1946 /* Set return value to 0. */
1947 last_code
= gfc_get_code (EXEC_ASSIGN
);
1948 last_code
->expr1
= gfc_lval_expr_from_sym (final
);
1949 last_code
->expr2
= gfc_get_int_expr (4, NULL
, 0);
1950 sub_ns
->code
= last_code
;
1952 /* Set: is_contiguous = .true. */
1953 last_code
->next
= gfc_get_code (EXEC_ASSIGN
);
1954 last_code
= last_code
->next
;
1955 last_code
->expr1
= gfc_lval_expr_from_sym (is_contiguous
);
1956 last_code
->expr2
= gfc_get_logical_expr (gfc_default_logical_kind
,
1957 &gfc_current_locus
, true);
1959 /* Set: sizes(0) = 1. */
1960 last_code
->next
= gfc_get_code (EXEC_ASSIGN
);
1961 last_code
= last_code
->next
;
1962 last_code
->expr1
= gfc_lval_expr_from_sym (sizes
);
1963 last_code
->expr1
->ref
= gfc_get_ref ();
1964 last_code
->expr1
->ref
->type
= REF_ARRAY
;
1965 last_code
->expr1
->ref
->u
.ar
.type
= AR_ELEMENT
;
1966 last_code
->expr1
->ref
->u
.ar
.dimen
= 1;
1967 last_code
->expr1
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
1968 last_code
->expr1
->ref
->u
.ar
.start
[0]
1969 = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
1970 last_code
->expr1
->ref
->u
.ar
.as
= sizes
->as
;
1971 last_code
->expr2
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 1);
1975 strides(idx) = _F._stride (array, dim=idx)
1976 sizes(idx) = sizes(i-1) * size(array, dim=idx, kind=index_kind)
1977 if (strides (idx) /= sizes(i-1)) is_contiguous = .false.
1981 iter
= gfc_get_iterator ();
1982 iter
->var
= gfc_lval_expr_from_sym (idx
);
1983 iter
->start
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1984 iter
->end
= gfc_copy_expr (rank
);
1985 iter
->step
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
1986 last_code
->next
= gfc_get_code (EXEC_DO
);
1987 last_code
= last_code
->next
;
1988 last_code
->ext
.iterator
= iter
;
1989 last_code
->block
= gfc_get_code (EXEC_DO
);
1991 /* strides(idx) = _F._stride(array,dim=idx). */
1992 last_code
->block
->next
= gfc_get_code (EXEC_ASSIGN
);
1993 block
= last_code
->block
->next
;
1995 block
->expr1
= gfc_lval_expr_from_sym (strides
);
1996 block
->expr1
->ref
= gfc_get_ref ();
1997 block
->expr1
->ref
->type
= REF_ARRAY
;
1998 block
->expr1
->ref
->u
.ar
.type
= AR_ELEMENT
;
1999 block
->expr1
->ref
->u
.ar
.dimen
= 1;
2000 block
->expr1
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
2001 block
->expr1
->ref
->u
.ar
.start
[0] = gfc_lval_expr_from_sym (idx
);
2002 block
->expr1
->ref
->u
.ar
.as
= strides
->as
;
2004 block
->expr2
= gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_STRIDE
, "stride",
2005 gfc_current_locus
, 2,
2006 gfc_lval_expr_from_sym (array
),
2007 gfc_lval_expr_from_sym (idx
));
2009 /* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
2010 block
->next
= gfc_get_code (EXEC_ASSIGN
);
2011 block
= block
->next
;
2013 /* sizes(idx) = ... */
2014 block
->expr1
= gfc_lval_expr_from_sym (sizes
);
2015 block
->expr1
->ref
= gfc_get_ref ();
2016 block
->expr1
->ref
->type
= REF_ARRAY
;
2017 block
->expr1
->ref
->u
.ar
.type
= AR_ELEMENT
;
2018 block
->expr1
->ref
->u
.ar
.dimen
= 1;
2019 block
->expr1
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
2020 block
->expr1
->ref
->u
.ar
.start
[0] = gfc_lval_expr_from_sym (idx
);
2021 block
->expr1
->ref
->u
.ar
.as
= sizes
->as
;
2023 block
->expr2
= gfc_get_expr ();
2024 block
->expr2
->expr_type
= EXPR_OP
;
2025 block
->expr2
->value
.op
.op
= INTRINSIC_TIMES
;
2026 block
->expr2
->where
= gfc_current_locus
;
2029 block
->expr2
->value
.op
.op1
= gfc_lval_expr_from_sym (sizes
);
2030 block
->expr2
->value
.op
.op1
->ref
= gfc_get_ref ();
2031 block
->expr2
->value
.op
.op1
->ref
->type
= REF_ARRAY
;
2032 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.as
= sizes
->as
;
2033 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.type
= AR_ELEMENT
;
2034 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.dimen
= 1;
2035 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
2036 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0] = gfc_get_expr ();
2037 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->expr_type
= EXPR_OP
;
2038 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->where
= gfc_current_locus
;
2039 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->value
.op
.op
= INTRINSIC_MINUS
;
2040 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->value
.op
.op1
2041 = gfc_lval_expr_from_sym (idx
);
2042 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->value
.op
.op2
2043 = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
2044 block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->ts
2045 = block
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0]->value
.op
.op1
->ts
;
2047 /* size(array, dim=idx, kind=index_kind). */
2048 block
->expr2
->value
.op
.op2
2049 = gfc_build_intrinsic_call (sub_ns
, GFC_ISYM_SIZE
, "size",
2050 gfc_current_locus
, 3,
2051 gfc_lval_expr_from_sym (array
),
2052 gfc_lval_expr_from_sym (idx
),
2053 gfc_get_int_expr (gfc_index_integer_kind
,
2055 gfc_index_integer_kind
));
2056 block
->expr2
->value
.op
.op2
->ts
.kind
= gfc_index_integer_kind
;
2057 block
->expr2
->ts
= idx
->ts
;
2059 /* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
2060 block
->next
= gfc_get_code (EXEC_IF
);
2061 block
= block
->next
;
2063 block
->block
= gfc_get_code (EXEC_IF
);
2064 block
= block
->block
;
2066 /* if condition: strides(idx) /= sizes(idx-1). */
2067 block
->expr1
= gfc_get_expr ();
2068 block
->expr1
->ts
.type
= BT_LOGICAL
;
2069 block
->expr1
->ts
.kind
= gfc_default_logical_kind
;
2070 block
->expr1
->expr_type
= EXPR_OP
;
2071 block
->expr1
->where
= gfc_current_locus
;
2072 block
->expr1
->value
.op
.op
= INTRINSIC_NE
;
2074 block
->expr1
->value
.op
.op1
= gfc_lval_expr_from_sym (strides
);
2075 block
->expr1
->value
.op
.op1
->ref
= gfc_get_ref ();
2076 block
->expr1
->value
.op
.op1
->ref
->type
= REF_ARRAY
;
2077 block
->expr1
->value
.op
.op1
->ref
->u
.ar
.type
= AR_ELEMENT
;
2078 block
->expr1
->value
.op
.op1
->ref
->u
.ar
.dimen
= 1;
2079 block
->expr1
->value
.op
.op1
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
2080 block
->expr1
->value
.op
.op1
->ref
->u
.ar
.start
[0] = gfc_lval_expr_from_sym (idx
);
2081 block
->expr1
->value
.op
.op1
->ref
->u
.ar
.as
= strides
->as
;
2083 block
->expr1
->value
.op
.op2
= gfc_lval_expr_from_sym (sizes
);
2084 block
->expr1
->value
.op
.op2
->ref
= gfc_get_ref ();
2085 block
->expr1
->value
.op
.op2
->ref
->type
= REF_ARRAY
;
2086 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.as
= sizes
->as
;
2087 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.type
= AR_ELEMENT
;
2088 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.dimen
= 1;
2089 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
2090 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0] = gfc_get_expr ();
2091 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->expr_type
= EXPR_OP
;
2092 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->where
= gfc_current_locus
;
2093 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op
= INTRINSIC_MINUS
;
2094 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op1
2095 = gfc_lval_expr_from_sym (idx
);
2096 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op2
2097 = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
2098 block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->ts
2099 = block
->expr1
->value
.op
.op2
->ref
->u
.ar
.start
[0]->value
.op
.op1
->ts
;
2101 /* if body: is_contiguous = .false. */
2102 block
->next
= gfc_get_code (EXEC_ASSIGN
);
2103 block
= block
->next
;
2104 block
->expr1
= gfc_lval_expr_from_sym (is_contiguous
);
2105 block
->expr2
= gfc_get_logical_expr (gfc_default_logical_kind
,
2106 &gfc_current_locus
, false);
2108 /* Obtain the size (number of elements) of "array" MINUS ONE,
2109 which is used in the scalarization. */
2110 gfc_get_symbol ("nelem", sub_ns
, &nelem
);
2111 nelem
->ts
.type
= BT_INTEGER
;
2112 nelem
->ts
.kind
= gfc_index_integer_kind
;
2113 nelem
->attr
.flavor
= FL_VARIABLE
;
2114 nelem
->attr
.artificial
= 1;
2115 gfc_set_sym_referenced (nelem
);
2116 gfc_commit_symbol (nelem
);
2118 /* nelem = sizes (rank) - 1. */
2119 last_code
->next
= gfc_get_code (EXEC_ASSIGN
);
2120 last_code
= last_code
->next
;
2122 last_code
->expr1
= gfc_lval_expr_from_sym (nelem
);
2124 last_code
->expr2
= gfc_get_expr ();
2125 last_code
->expr2
->expr_type
= EXPR_OP
;
2126 last_code
->expr2
->value
.op
.op
= INTRINSIC_MINUS
;
2127 last_code
->expr2
->value
.op
.op2
2128 = gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
2129 last_code
->expr2
->ts
= last_code
->expr2
->value
.op
.op2
->ts
;
2130 last_code
->expr2
->where
= gfc_current_locus
;
2132 last_code
->expr2
->value
.op
.op1
= gfc_lval_expr_from_sym (sizes
);
2133 last_code
->expr2
->value
.op
.op1
->ref
= gfc_get_ref ();
2134 last_code
->expr2
->value
.op
.op1
->ref
->type
= REF_ARRAY
;
2135 last_code
->expr2
->value
.op
.op1
->ref
->u
.ar
.type
= AR_ELEMENT
;
2136 last_code
->expr2
->value
.op
.op1
->ref
->u
.ar
.dimen
= 1;
2137 last_code
->expr2
->value
.op
.op1
->ref
->u
.ar
.dimen_type
[0] = DIMEN_ELEMENT
;
2138 last_code
->expr2
->value
.op
.op1
->ref
->u
.ar
.start
[0] = gfc_copy_expr (rank
);
2139 last_code
->expr2
->value
.op
.op1
->ref
->u
.ar
.as
= sizes
->as
;
2141 /* Call final subroutines. We now generate code like:
2143 integer, pointer :: ptr
2145 integer(c_intptr_t) :: i, addr
2147 select case (rank (array))
2149 ! If needed, the array is packed
2150 call final_rank3 (array)
2152 do i = 0, size (array)-1
2153 addr = transfer (c_loc (array), addr) + i * stride
2154 call c_f_pointer (transfer (addr, cptr), ptr)
2155 call elemental_final (ptr)
2159 if (derived
->f2k_derived
&& derived
->f2k_derived
->finalizers
)
2161 gfc_finalizer
*fini
, *fini_elem
= NULL
;
2163 gfc_get_symbol ("ptr1", sub_ns
, &ptr
);
2164 ptr
->ts
.type
= BT_DERIVED
;
2165 ptr
->ts
.u
.derived
= derived
;
2166 ptr
->attr
.flavor
= FL_VARIABLE
;
2167 ptr
->attr
.pointer
= 1;
2168 ptr
->attr
.artificial
= 1;
2169 gfc_set_sym_referenced (ptr
);
2170 gfc_commit_symbol (ptr
);
2172 fini
= derived
->f2k_derived
->finalizers
;
2174 /* Assumed rank finalizers can be called directly. The call takes care
2175 of setting up the descriptor. resolve_finalizers has already checked
2176 that this is the only finalizer for this kind/type (F2018: C790). */
2177 if (fini
->proc_tree
&& fini
->proc_tree
->n
.sym
->formal
->sym
->as
2178 && fini
->proc_tree
->n
.sym
->formal
->sym
->as
->type
== AS_ASSUMED_RANK
)
2180 last_code
->next
= gfc_get_code (EXEC_CALL
);
2181 last_code
->next
->symtree
= fini
->proc_tree
;
2182 last_code
->next
->resolved_sym
= fini
->proc_tree
->n
.sym
;
2183 last_code
->next
->ext
.actual
= gfc_get_actual_arglist ();
2184 last_code
->next
->ext
.actual
->expr
= gfc_lval_expr_from_sym (array
);
2186 last_code
= last_code
->next
;
2187 goto finish_assumed_rank
;
2190 /* SELECT CASE (RANK (array)). */
2191 last_code
->next
= gfc_get_code (EXEC_SELECT
);
2192 last_code
= last_code
->next
;
2193 last_code
->expr1
= gfc_copy_expr (rank
);
2197 for (; fini
; fini
= fini
->next
)
2199 gcc_assert (fini
->proc_tree
); /* Should have been set in gfc_resolve_finalizers. */
2200 if (fini
->proc_tree
->n
.sym
->attr
.elemental
)
2206 /* CASE (fini_rank). */
2209 block
->block
= gfc_get_code (EXEC_SELECT
);
2210 block
= block
->block
;
2214 block
= gfc_get_code (EXEC_SELECT
);
2215 last_code
->block
= block
;
2217 block
->ext
.block
.case_list
= gfc_get_case ();
2218 block
->ext
.block
.case_list
->where
= gfc_current_locus
;
2219 if (fini
->proc_tree
->n
.sym
->formal
->sym
->attr
.dimension
)
2220 block
->ext
.block
.case_list
->low
2221 = gfc_get_int_expr (gfc_default_integer_kind
, NULL
,
2222 fini
->proc_tree
->n
.sym
->formal
->sym
->as
->rank
);
2224 block
->ext
.block
.case_list
->low
2225 = gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 0);
2226 block
->ext
.block
.case_list
->high
2227 = gfc_copy_expr (block
->ext
.block
.case_list
->low
);
2229 /* CALL fini_rank (array) - possibly with packing. */
2230 if (fini
->proc_tree
->n
.sym
->formal
->sym
->attr
.dimension
)
2231 finalizer_insert_packed_call (block
, fini
, array
, byte_stride
,
2232 idx
, ptr
, nelem
, strides
,
2233 sizes
, idx2
, offset
, is_contiguous
,
2237 block
->next
= gfc_get_code (EXEC_CALL
);
2238 block
->next
->symtree
= fini
->proc_tree
;
2239 block
->next
->resolved_sym
= fini
->proc_tree
->n
.sym
;
2240 block
->next
->ext
.actual
= gfc_get_actual_arglist ();
2241 block
->next
->ext
.actual
->expr
= gfc_lval_expr_from_sym (array
);
2245 /* Elemental call - scalarized. */
2251 block
->block
= gfc_get_code (EXEC_SELECT
);
2252 block
= block
->block
;
2256 block
= gfc_get_code (EXEC_SELECT
);
2257 last_code
->block
= block
;
2259 block
->ext
.block
.case_list
= gfc_get_case ();
2262 iter
= gfc_get_iterator ();
2263 iter
->var
= gfc_lval_expr_from_sym (idx
);
2264 iter
->start
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
2265 iter
->end
= gfc_lval_expr_from_sym (nelem
);
2266 iter
->step
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
2267 block
->next
= gfc_get_code (EXEC_DO
);
2268 block
= block
->next
;
2269 block
->ext
.iterator
= iter
;
2270 block
->block
= gfc_get_code (EXEC_DO
);
2272 /* Offset calculation. */
2273 block
= finalization_get_offset (idx
, idx2
, offset
, strides
, sizes
,
2274 byte_stride
, rank
, block
->block
,
2278 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2279 + offset, c_ptr), ptr). */
2281 = finalization_scalarizer (array
, ptr
,
2282 gfc_lval_expr_from_sym (offset
),
2284 block
= block
->next
;
2286 /* CALL final_elemental (array). */
2287 block
->next
= gfc_get_code (EXEC_CALL
);
2288 block
= block
->next
;
2289 block
->symtree
= fini_elem
->proc_tree
;
2290 block
->resolved_sym
= fini_elem
->proc_sym
;
2291 block
->ext
.actual
= gfc_get_actual_arglist ();
2292 block
->ext
.actual
->expr
= gfc_lval_expr_from_sym (ptr
);
2296 finish_assumed_rank
:
2298 /* Finalize and deallocate allocatable components. The same manual
2299 scalarization is used as above. */
2301 if (finalizable_comp
)
2304 gfc_code
*block
= NULL
;
2308 gfc_get_symbol ("ptr2", sub_ns
, &ptr
);
2309 ptr
->ts
.type
= BT_DERIVED
;
2310 ptr
->ts
.u
.derived
= derived
;
2311 ptr
->attr
.flavor
= FL_VARIABLE
;
2312 ptr
->attr
.pointer
= 1;
2313 ptr
->attr
.artificial
= 1;
2314 gfc_set_sym_referenced (ptr
);
2315 gfc_commit_symbol (ptr
);
2318 gfc_get_symbol ("ignore", sub_ns
, &stat
);
2319 stat
->attr
.flavor
= FL_VARIABLE
;
2320 stat
->attr
.artificial
= 1;
2321 stat
->ts
.type
= BT_INTEGER
;
2322 stat
->ts
.kind
= gfc_default_integer_kind
;
2323 gfc_set_sym_referenced (stat
);
2324 gfc_commit_symbol (stat
);
2327 iter
= gfc_get_iterator ();
2328 iter
->var
= gfc_lval_expr_from_sym (idx
);
2329 iter
->start
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 0);
2330 iter
->end
= gfc_lval_expr_from_sym (nelem
);
2331 iter
->step
= gfc_get_int_expr (gfc_index_integer_kind
, NULL
, 1);
2332 last_code
->next
= gfc_get_code (EXEC_DO
);
2333 last_code
= last_code
->next
;
2334 last_code
->ext
.iterator
= iter
;
2335 last_code
->block
= gfc_get_code (EXEC_DO
);
2337 /* Offset calculation. */
2338 block
= finalization_get_offset (idx
, idx2
, offset
, strides
, sizes
,
2339 byte_stride
, rank
, last_code
->block
,
2343 CALL C_F_POINTER (TRANSFER (TRANSFER (C_LOC (array, cptr), c_intptr)
2344 + idx * stride, c_ptr), ptr). */
2345 block
->next
= finalization_scalarizer (array
, ptr
,
2346 gfc_lval_expr_from_sym(offset
),
2348 block
= block
->next
;
2350 for (comp
= derived
->components
; comp
; comp
= comp
->next
)
2352 if (comp
== derived
->components
&& derived
->attr
.extension
2353 && ancestor_wrapper
&& ancestor_wrapper
->expr_type
!= EXPR_NULL
)
2356 finalize_component (gfc_lval_expr_from_sym (ptr
), derived
, comp
,
2357 stat
, fini_coarray
, &block
, sub_ns
);
2358 if (!last_code
->block
->next
)
2359 last_code
->block
->next
= block
;
2364 /* Call the finalizer of the ancestor. */
2365 if (ancestor_wrapper
&& ancestor_wrapper
->expr_type
!= EXPR_NULL
)
2367 last_code
->next
= gfc_get_code (EXEC_CALL
);
2368 last_code
= last_code
->next
;
2369 last_code
->symtree
= ancestor_wrapper
->symtree
;
2370 last_code
->resolved_sym
= ancestor_wrapper
->symtree
->n
.sym
;
2372 last_code
->ext
.actual
= gfc_get_actual_arglist ();
2373 last_code
->ext
.actual
->expr
= gfc_lval_expr_from_sym (array
);
2374 last_code
->ext
.actual
->next
= gfc_get_actual_arglist ();
2375 last_code
->ext
.actual
->next
->expr
= gfc_lval_expr_from_sym (byte_stride
);
2376 last_code
->ext
.actual
->next
->next
= gfc_get_actual_arglist ();
2377 last_code
->ext
.actual
->next
->next
->expr
2378 = gfc_lval_expr_from_sym (fini_coarray
);
2381 gfc_free_expr (rank
);
2382 vtab_final
->initializer
= gfc_lval_expr_from_sym (final
);
2383 vtab_final
->ts
.interface
= final
;
2388 /* Add procedure pointers for all type-bound procedures to a vtab. */
2391 add_procs_to_declared_vtab (gfc_symbol
*derived
, gfc_symbol
*vtype
)
2393 gfc_symbol
* super_type
;
2395 super_type
= gfc_get_derived_super_type (derived
);
2397 if (super_type
&& (super_type
!= derived
))
2399 /* Make sure that the PPCs appear in the same order as in the parent. */
2400 copy_vtab_proc_comps (super_type
, vtype
);
2401 /* Only needed to get the PPC initializers right. */
2402 add_procs_to_declared_vtab (super_type
, vtype
);
2405 if (derived
->f2k_derived
&& derived
->f2k_derived
->tb_sym_root
)
2406 add_procs_to_declared_vtab1 (derived
->f2k_derived
->tb_sym_root
, vtype
);
2408 if (derived
->f2k_derived
&& derived
->f2k_derived
->tb_uop_root
)
2409 add_procs_to_declared_vtab1 (derived
->f2k_derived
->tb_uop_root
, vtype
);
2413 /* Find or generate the symbol for a derived type's vtab. */
2416 gfc_find_derived_vtab (gfc_symbol
*derived
)
2419 gfc_symbol
*vtab
= NULL
, *vtype
= NULL
, *found_sym
= NULL
, *def_init
= NULL
;
2420 gfc_symbol
*copy
= NULL
, *src
= NULL
, *dst
= NULL
;
2421 gfc_gsymbol
*gsym
= NULL
;
2422 gfc_symbol
*dealloc
= NULL
, *arg
= NULL
;
2424 if (derived
->attr
.pdt_template
)
2427 /* Find the top-level namespace. */
2428 for (ns
= gfc_current_ns
; ns
; ns
= ns
->parent
)
2432 /* If the type is a class container, use the underlying derived type. */
2433 if (!derived
->attr
.unlimited_polymorphic
&& derived
->attr
.is_class
)
2434 derived
= gfc_get_derived_super_type (derived
);
2442 /* Find the gsymbol for the module of use associated derived types. */
2443 if ((derived
->attr
.use_assoc
|| derived
->attr
.used_in_submodule
)
2444 && !derived
->attr
.vtype
&& !derived
->attr
.is_class
)
2445 gsym
= gfc_find_gsymbol (gfc_gsym_root
, derived
->module
);
2449 /* Work in the gsymbol namespace if the top-level namespace is a module.
2450 This ensures that the vtable is unique, which is required since we use
2451 its address in SELECT TYPE. */
2452 if (gsym
&& gsym
->ns
&& ns
&& ns
->proc_name
2453 && ns
->proc_name
->attr
.flavor
== FL_MODULE
)
2458 char tname
[GFC_MAX_SYMBOL_LEN
+1];
2461 get_unique_hashed_string (tname
, derived
);
2462 name
= xasprintf ("__vtab_%s", tname
);
2464 /* Look for the vtab symbol in various namespaces. */
2465 if (gsym
&& gsym
->ns
)
2467 gfc_find_symbol (name
, gsym
->ns
, 0, &vtab
);
2472 gfc_find_symbol (name
, gfc_current_ns
, 0, &vtab
);
2474 gfc_find_symbol (name
, ns
, 0, &vtab
);
2476 gfc_find_symbol (name
, derived
->ns
, 0, &vtab
);
2480 gfc_get_symbol (name
, ns
, &vtab
);
2481 vtab
->ts
.type
= BT_DERIVED
;
2482 if (!gfc_add_flavor (&vtab
->attr
, FL_VARIABLE
, NULL
,
2483 &gfc_current_locus
))
2485 vtab
->attr
.target
= 1;
2486 vtab
->attr
.save
= SAVE_IMPLICIT
;
2487 vtab
->attr
.vtab
= 1;
2488 vtab
->attr
.access
= ACCESS_PUBLIC
;
2489 gfc_set_sym_referenced (vtab
);
2491 name
= xasprintf ("__vtype_%s", tname
);
2493 gfc_find_symbol (name
, ns
, 0, &vtype
);
2497 gfc_symbol
*parent
= NULL
, *parent_vtab
= NULL
;
2500 /* Is this a derived type with recursive allocatable
2502 c
= (derived
->attr
.unlimited_polymorphic
2503 || derived
->attr
.abstract
) ?
2504 NULL
: derived
->components
;
2505 for (; c
; c
= c
->next
)
2506 if (c
->ts
.type
== BT_DERIVED
2507 && c
->ts
.u
.derived
== derived
)
2513 gfc_get_symbol (name
, ns
, &vtype
);
2514 if (!gfc_add_flavor (&vtype
->attr
, FL_DERIVED
, NULL
,
2515 &gfc_current_locus
))
2517 vtype
->attr
.access
= ACCESS_PUBLIC
;
2518 vtype
->attr
.vtype
= 1;
2519 gfc_set_sym_referenced (vtype
);
2521 /* Add component '_hash'. */
2522 if (!gfc_add_component (vtype
, "_hash", &c
))
2524 c
->ts
.type
= BT_INTEGER
;
2526 c
->attr
.access
= ACCESS_PRIVATE
;
2527 c
->initializer
= gfc_get_int_expr (gfc_default_integer_kind
,
2528 NULL
, derived
->hash_value
);
2530 /* Add component '_size'. */
2531 if (!gfc_add_component (vtype
, "_size", &c
))
2533 c
->ts
.type
= BT_INTEGER
;
2534 c
->ts
.kind
= gfc_size_kind
;
2535 c
->attr
.access
= ACCESS_PRIVATE
;
2536 /* Remember the derived type in ts.u.derived,
2537 so that the correct initializer can be set later on
2538 (in gfc_conv_structure). */
2539 c
->ts
.u
.derived
= derived
;
2540 c
->initializer
= gfc_get_int_expr (gfc_size_kind
,
2543 /* Add component _extends. */
2544 if (!gfc_add_component (vtype
, "_extends", &c
))
2546 c
->attr
.pointer
= 1;
2547 c
->attr
.access
= ACCESS_PRIVATE
;
2548 if (!derived
->attr
.unlimited_polymorphic
)
2549 parent
= gfc_get_derived_super_type (derived
);
2555 parent_vtab
= gfc_find_derived_vtab (parent
);
2556 c
->ts
.type
= BT_DERIVED
;
2557 c
->ts
.u
.derived
= parent_vtab
->ts
.u
.derived
;
2558 c
->initializer
= gfc_get_expr ();
2559 c
->initializer
->expr_type
= EXPR_VARIABLE
;
2560 gfc_find_sym_tree (parent_vtab
->name
, parent_vtab
->ns
,
2561 0, &c
->initializer
->symtree
);
2565 c
->ts
.type
= BT_DERIVED
;
2566 c
->ts
.u
.derived
= vtype
;
2567 c
->initializer
= gfc_get_null_expr (NULL
);
2570 if (!derived
->attr
.unlimited_polymorphic
2571 && derived
->components
== NULL
2572 && !derived
->attr
.zero_comp
)
2574 /* At this point an error must have occurred.
2575 Prevent further errors on the vtype components. */
2580 /* Add component _def_init. */
2581 if (!gfc_add_component (vtype
, "_def_init", &c
))
2583 c
->attr
.pointer
= 1;
2584 c
->attr
.artificial
= 1;
2585 c
->attr
.access
= ACCESS_PRIVATE
;
2586 c
->ts
.type
= BT_DERIVED
;
2587 c
->ts
.u
.derived
= derived
;
2588 if (derived
->attr
.unlimited_polymorphic
2589 || derived
->attr
.abstract
)
2590 c
->initializer
= gfc_get_null_expr (NULL
);
2593 /* Construct default initialization variable. */
2595 name
= xasprintf ("__def_init_%s", tname
);
2596 gfc_get_symbol (name
, ns
, &def_init
);
2597 def_init
->attr
.target
= 1;
2598 def_init
->attr
.artificial
= 1;
2599 def_init
->attr
.save
= SAVE_IMPLICIT
;
2600 def_init
->attr
.access
= ACCESS_PUBLIC
;
2601 def_init
->attr
.flavor
= FL_VARIABLE
;
2602 gfc_set_sym_referenced (def_init
);
2603 def_init
->ts
.type
= BT_DERIVED
;
2604 def_init
->ts
.u
.derived
= derived
;
2605 def_init
->value
= gfc_default_initializer (&def_init
->ts
);
2607 c
->initializer
= gfc_lval_expr_from_sym (def_init
);
2610 /* Add component _copy. */
2611 if (!gfc_add_component (vtype
, "_copy", &c
))
2613 c
->attr
.proc_pointer
= 1;
2614 c
->attr
.access
= ACCESS_PRIVATE
;
2615 c
->tb
= XCNEW (gfc_typebound_proc
);
2617 if (derived
->attr
.unlimited_polymorphic
2618 || derived
->attr
.abstract
)
2619 c
->initializer
= gfc_get_null_expr (NULL
);
2622 /* Set up namespace. */
2623 gfc_namespace
*sub_ns
= gfc_get_namespace (ns
, 0);
2624 sub_ns
->sibling
= ns
->contained
;
2625 ns
->contained
= sub_ns
;
2626 sub_ns
->resolved
= 1;
2627 /* Set up procedure symbol. */
2629 name
= xasprintf ("__copy_%s", tname
);
2630 gfc_get_symbol (name
, sub_ns
, ©
);
2631 sub_ns
->proc_name
= copy
;
2632 copy
->attr
.flavor
= FL_PROCEDURE
;
2633 copy
->attr
.subroutine
= 1;
2634 copy
->attr
.pure
= 1;
2635 copy
->attr
.artificial
= 1;
2636 copy
->attr
.if_source
= IFSRC_DECL
;
2637 /* This is elemental so that arrays are automatically
2638 treated correctly by the scalarizer. */
2639 copy
->attr
.elemental
= 1;
2640 if (ns
->proc_name
->attr
.flavor
== FL_MODULE
)
2641 copy
->module
= ns
->proc_name
->name
;
2642 gfc_set_sym_referenced (copy
);
2643 /* Set up formal arguments. */
2644 gfc_get_symbol ("src", sub_ns
, &src
);
2645 src
->ts
.type
= BT_DERIVED
;
2646 src
->ts
.u
.derived
= derived
;
2647 src
->attr
.flavor
= FL_VARIABLE
;
2648 src
->attr
.dummy
= 1;
2649 src
->attr
.artificial
= 1;
2650 src
->attr
.intent
= INTENT_IN
;
2651 gfc_set_sym_referenced (src
);
2652 copy
->formal
= gfc_get_formal_arglist ();
2653 copy
->formal
->sym
= src
;
2654 gfc_get_symbol ("dst", sub_ns
, &dst
);
2655 dst
->ts
.type
= BT_DERIVED
;
2656 dst
->ts
.u
.derived
= derived
;
2657 dst
->attr
.flavor
= FL_VARIABLE
;
2658 dst
->attr
.dummy
= 1;
2659 dst
->attr
.artificial
= 1;
2660 dst
->attr
.intent
= INTENT_INOUT
;
2661 gfc_set_sym_referenced (dst
);
2662 copy
->formal
->next
= gfc_get_formal_arglist ();
2663 copy
->formal
->next
->sym
= dst
;
2665 sub_ns
->code
= gfc_get_code (EXEC_INIT_ASSIGN
);
2666 sub_ns
->code
->expr1
= gfc_lval_expr_from_sym (dst
);
2667 sub_ns
->code
->expr2
= gfc_lval_expr_from_sym (src
);
2668 /* Set initializer. */
2669 c
->initializer
= gfc_lval_expr_from_sym (copy
);
2670 c
->ts
.interface
= copy
;
2673 /* Add component _final, which contains a procedure pointer to
2674 a wrapper which handles both the freeing of allocatable
2675 components and the calls to finalization subroutines.
2676 Note: The actual wrapper function can only be generated
2677 at resolution time. */
2678 if (!gfc_add_component (vtype
, "_final", &c
))
2680 c
->attr
.proc_pointer
= 1;
2681 c
->attr
.access
= ACCESS_PRIVATE
;
2682 c
->attr
.artificial
= 1;
2683 c
->tb
= XCNEW (gfc_typebound_proc
);
2685 generate_finalization_wrapper (derived
, ns
, tname
, c
);
2687 /* Add component _deallocate. */
2688 if (!gfc_add_component (vtype
, "_deallocate", &c
))
2690 c
->attr
.proc_pointer
= 1;
2691 c
->attr
.access
= ACCESS_PRIVATE
;
2692 c
->tb
= XCNEW (gfc_typebound_proc
);
2694 if (derived
->attr
.unlimited_polymorphic
2695 || derived
->attr
.abstract
2697 c
->initializer
= gfc_get_null_expr (NULL
);
2700 /* Set up namespace. */
2701 gfc_namespace
*sub_ns
= gfc_get_namespace (ns
, 0);
2703 sub_ns
->sibling
= ns
->contained
;
2704 ns
->contained
= sub_ns
;
2705 sub_ns
->resolved
= 1;
2706 /* Set up procedure symbol. */
2708 name
= xasprintf ("__deallocate_%s", tname
);
2709 gfc_get_symbol (name
, sub_ns
, &dealloc
);
2710 sub_ns
->proc_name
= dealloc
;
2711 dealloc
->attr
.flavor
= FL_PROCEDURE
;
2712 dealloc
->attr
.subroutine
= 1;
2713 dealloc
->attr
.pure
= 1;
2714 dealloc
->attr
.artificial
= 1;
2715 dealloc
->attr
.if_source
= IFSRC_DECL
;
2717 if (ns
->proc_name
->attr
.flavor
== FL_MODULE
)
2718 dealloc
->module
= ns
->proc_name
->name
;
2719 gfc_set_sym_referenced (dealloc
);
2720 /* Set up formal argument. */
2721 gfc_get_symbol ("arg", sub_ns
, &arg
);
2722 arg
->ts
.type
= BT_DERIVED
;
2723 arg
->ts
.u
.derived
= derived
;
2724 arg
->attr
.flavor
= FL_VARIABLE
;
2725 arg
->attr
.dummy
= 1;
2726 arg
->attr
.artificial
= 1;
2727 arg
->attr
.intent
= INTENT_INOUT
;
2728 arg
->attr
.dimension
= 1;
2729 arg
->attr
.allocatable
= 1;
2730 arg
->as
= gfc_get_array_spec();
2731 arg
->as
->type
= AS_ASSUMED_SHAPE
;
2733 arg
->as
->lower
[0] = gfc_get_int_expr (gfc_default_integer_kind
,
2735 gfc_set_sym_referenced (arg
);
2736 dealloc
->formal
= gfc_get_formal_arglist ();
2737 dealloc
->formal
->sym
= arg
;
2739 sub_ns
->code
= gfc_get_code (EXEC_DEALLOCATE
);
2740 sub_ns
->code
->ext
.alloc
.list
= gfc_get_alloc ();
2741 sub_ns
->code
->ext
.alloc
.list
->expr
2742 = gfc_lval_expr_from_sym (arg
);
2743 /* Set initializer. */
2744 c
->initializer
= gfc_lval_expr_from_sym (dealloc
);
2745 c
->ts
.interface
= dealloc
;
2748 /* Add procedure pointers for type-bound procedures. */
2749 if (!derived
->attr
.unlimited_polymorphic
)
2750 add_procs_to_declared_vtab (derived
, vtype
);
2754 vtab
->ts
.u
.derived
= vtype
;
2755 vtab
->value
= gfc_default_initializer (&vtab
->ts
);
2763 /* It is unexpected to have some symbols added at resolution or code
2764 generation time. We commit the changes in order to keep a clean state. */
2767 gfc_commit_symbol (vtab
);
2769 gfc_commit_symbol (vtype
);
2771 gfc_commit_symbol (def_init
);
2773 gfc_commit_symbol (copy
);
2775 gfc_commit_symbol (src
);
2777 gfc_commit_symbol (dst
);
2779 gfc_commit_symbol (dealloc
);
2781 gfc_commit_symbol (arg
);
2784 gfc_undo_symbols ();
2790 /* Check if a derived type is finalizable. That is the case if it
2791 (1) has a FINAL subroutine or
2792 (2) has a nonpointer nonallocatable component of finalizable type.
2793 If it is finalizable, return an expression containing the
2794 finalization wrapper. */
2797 gfc_is_finalizable (gfc_symbol
*derived
, gfc_expr
**final_expr
)
2802 /* (1) Check for FINAL subroutines. */
2803 if (derived
->f2k_derived
&& derived
->f2k_derived
->finalizers
)
2806 /* (2) Check for components of finalizable type. */
2807 for (c
= derived
->components
; c
; c
= c
->next
)
2808 if (c
->ts
.type
== BT_DERIVED
2809 && !c
->attr
.pointer
&& !c
->attr
.proc_pointer
&& !c
->attr
.allocatable
2810 && gfc_is_finalizable (c
->ts
.u
.derived
, NULL
))
2816 /* Make sure vtab is generated. */
2817 vtab
= gfc_find_derived_vtab (derived
);
2820 /* Return finalizer expression. */
2821 gfc_component
*final
;
2822 final
= vtab
->ts
.u
.derived
->components
->next
->next
->next
->next
->next
;
2823 gcc_assert (strcmp (final
->name
, "_final") == 0);
2824 gcc_assert (final
->initializer
2825 && final
->initializer
->expr_type
!= EXPR_NULL
);
2826 *final_expr
= final
->initializer
;
2833 gfc_may_be_finalized (gfc_typespec ts
)
2835 return (ts
.type
== BT_CLASS
|| (ts
.type
== BT_DERIVED
2836 && ts
.u
.derived
&& gfc_is_finalizable (ts
.u
.derived
, NULL
)));
2840 /* Find (or generate) the symbol for an intrinsic type's vtab. This is
2841 needed to support unlimited polymorphism. */
2844 find_intrinsic_vtab (gfc_typespec
*ts
)
2847 gfc_symbol
*vtab
= NULL
, *vtype
= NULL
, *found_sym
= NULL
;
2848 gfc_symbol
*copy
= NULL
, *src
= NULL
, *dst
= NULL
;
2850 /* Find the top-level namespace. */
2851 for (ns
= gfc_current_ns
; ns
; ns
= ns
->parent
)
2857 char tname
[GFC_MAX_SYMBOL_LEN
+1];
2860 /* Encode all types as TYPENAME_KIND_ including especially character
2861 arrays, whose length is now consistently stored in the _len component
2862 of the class-variable. */
2863 sprintf (tname
, "%s_%d_", gfc_basic_typename (ts
->type
), ts
->kind
);
2864 name
= xasprintf ("__vtab_%s", tname
);
2866 /* Look for the vtab symbol in the top-level namespace only. */
2867 gfc_find_symbol (name
, ns
, 0, &vtab
);
2871 gfc_get_symbol (name
, ns
, &vtab
);
2872 vtab
->ts
.type
= BT_DERIVED
;
2873 if (!gfc_add_flavor (&vtab
->attr
, FL_VARIABLE
, NULL
,
2874 &gfc_current_locus
))
2876 vtab
->attr
.target
= 1;
2877 vtab
->attr
.save
= SAVE_IMPLICIT
;
2878 vtab
->attr
.vtab
= 1;
2879 vtab
->attr
.access
= ACCESS_PUBLIC
;
2880 gfc_set_sym_referenced (vtab
);
2882 name
= xasprintf ("__vtype_%s", tname
);
2884 gfc_find_symbol (name
, ns
, 0, &vtype
);
2889 gfc_namespace
*sub_ns
;
2890 gfc_namespace
*contained
;
2894 gfc_get_symbol (name
, ns
, &vtype
);
2895 if (!gfc_add_flavor (&vtype
->attr
, FL_DERIVED
, NULL
,
2896 &gfc_current_locus
))
2898 vtype
->attr
.access
= ACCESS_PUBLIC
;
2899 vtype
->attr
.vtype
= 1;
2900 gfc_set_sym_referenced (vtype
);
2902 /* Add component '_hash'. */
2903 if (!gfc_add_component (vtype
, "_hash", &c
))
2905 c
->ts
.type
= BT_INTEGER
;
2907 c
->attr
.access
= ACCESS_PRIVATE
;
2908 hash
= gfc_intrinsic_hash_value (ts
);
2909 c
->initializer
= gfc_get_int_expr (gfc_default_integer_kind
,
2912 /* Add component '_size'. */
2913 if (!gfc_add_component (vtype
, "_size", &c
))
2915 c
->ts
.type
= BT_INTEGER
;
2916 c
->ts
.kind
= gfc_size_kind
;
2917 c
->attr
.access
= ACCESS_PRIVATE
;
2919 /* Build a minimal expression to make use of
2920 target-memory.cc/gfc_element_size for 'size'. Special handling
2921 for character arrays, that are not constant sized: to support
2922 len (str) * kind, only the kind information is stored in the
2924 e
= gfc_get_expr ();
2926 e
->expr_type
= EXPR_VARIABLE
;
2927 if (ts
->type
== BT_CHARACTER
)
2930 gfc_element_size (e
, &e_size
);
2931 c
->initializer
= gfc_get_int_expr (gfc_size_kind
,
2936 /* Add component _extends. */
2937 if (!gfc_add_component (vtype
, "_extends", &c
))
2939 c
->attr
.pointer
= 1;
2940 c
->attr
.access
= ACCESS_PRIVATE
;
2941 c
->ts
.type
= BT_VOID
;
2942 c
->initializer
= gfc_get_null_expr (NULL
);
2944 /* Add component _def_init. */
2945 if (!gfc_add_component (vtype
, "_def_init", &c
))
2947 c
->attr
.pointer
= 1;
2948 c
->attr
.access
= ACCESS_PRIVATE
;
2949 c
->ts
.type
= BT_VOID
;
2950 c
->initializer
= gfc_get_null_expr (NULL
);
2952 /* Add component _copy. */
2953 if (!gfc_add_component (vtype
, "_copy", &c
))
2955 c
->attr
.proc_pointer
= 1;
2956 c
->attr
.access
= ACCESS_PRIVATE
;
2957 c
->tb
= XCNEW (gfc_typebound_proc
);
2961 if (ts
->type
!= BT_CHARACTER
)
2962 name
= xasprintf ("__copy_%s", tname
);
2965 /* __copy is always the same for characters.
2966 Check to see if copy function already exists. */
2967 name
= xasprintf ("__copy_character_%d", ts
->kind
);
2968 contained
= ns
->contained
;
2969 for (; contained
; contained
= contained
->sibling
)
2970 if (contained
->proc_name
2971 && strcmp (name
, contained
->proc_name
->name
) == 0)
2973 copy
= contained
->proc_name
;
2978 /* Set up namespace. */
2979 sub_ns
= gfc_get_namespace (ns
, 0);
2980 sub_ns
->sibling
= ns
->contained
;
2981 ns
->contained
= sub_ns
;
2982 sub_ns
->resolved
= 1;
2983 /* Set up procedure symbol. */
2984 gfc_get_symbol (name
, sub_ns
, ©
);
2985 sub_ns
->proc_name
= copy
;
2986 copy
->attr
.flavor
= FL_PROCEDURE
;
2987 copy
->attr
.subroutine
= 1;
2988 copy
->attr
.pure
= 1;
2989 copy
->attr
.if_source
= IFSRC_DECL
;
2990 /* This is elemental so that arrays are automatically
2991 treated correctly by the scalarizer. */
2992 copy
->attr
.elemental
= 1;
2993 if (ns
->proc_name
&& ns
->proc_name
->attr
.flavor
== FL_MODULE
)
2994 copy
->module
= ns
->proc_name
->name
;
2995 gfc_set_sym_referenced (copy
);
2996 /* Set up formal arguments. */
2997 gfc_get_symbol ("src", sub_ns
, &src
);
2998 src
->ts
.type
= ts
->type
;
2999 src
->ts
.kind
= ts
->kind
;
3000 src
->attr
.flavor
= FL_VARIABLE
;
3001 src
->attr
.dummy
= 1;
3002 src
->attr
.intent
= INTENT_IN
;
3003 gfc_set_sym_referenced (src
);
3004 copy
->formal
= gfc_get_formal_arglist ();
3005 copy
->formal
->sym
= src
;
3006 gfc_get_symbol ("dst", sub_ns
, &dst
);
3007 dst
->ts
.type
= ts
->type
;
3008 dst
->ts
.kind
= ts
->kind
;
3009 dst
->attr
.flavor
= FL_VARIABLE
;
3010 dst
->attr
.dummy
= 1;
3011 dst
->attr
.intent
= INTENT_INOUT
;
3012 gfc_set_sym_referenced (dst
);
3013 copy
->formal
->next
= gfc_get_formal_arglist ();
3014 copy
->formal
->next
->sym
= dst
;
3016 sub_ns
->code
= gfc_get_code (EXEC_INIT_ASSIGN
);
3017 sub_ns
->code
->expr1
= gfc_lval_expr_from_sym (dst
);
3018 sub_ns
->code
->expr2
= gfc_lval_expr_from_sym (src
);
3020 /* Set initializer. */
3021 c
->initializer
= gfc_lval_expr_from_sym (copy
);
3022 c
->ts
.interface
= copy
;
3024 /* Add component _final. */
3025 if (!gfc_add_component (vtype
, "_final", &c
))
3027 c
->attr
.proc_pointer
= 1;
3028 c
->attr
.access
= ACCESS_PRIVATE
;
3029 c
->attr
.artificial
= 1;
3030 c
->tb
= XCNEW (gfc_typebound_proc
);
3032 c
->initializer
= gfc_get_null_expr (NULL
);
3034 vtab
->ts
.u
.derived
= vtype
;
3035 vtab
->value
= gfc_default_initializer (&vtab
->ts
);
3043 /* It is unexpected to have some symbols added at resolution or code
3044 generation time. We commit the changes in order to keep a clean state. */
3047 gfc_commit_symbol (vtab
);
3049 gfc_commit_symbol (vtype
);
3051 gfc_commit_symbol (copy
);
3053 gfc_commit_symbol (src
);
3055 gfc_commit_symbol (dst
);
3058 gfc_undo_symbols ();
3064 /* Find (or generate) a vtab for an arbitrary type (derived or intrinsic). */
3067 gfc_find_vtab (gfc_typespec
*ts
)
3074 return gfc_find_derived_vtab (ts
->u
.derived
);
3076 if (ts
->u
.derived
->attr
.is_class
3077 && ts
->u
.derived
->components
3078 && ts
->u
.derived
->components
->ts
.u
.derived
)
3079 return gfc_find_derived_vtab (ts
->u
.derived
->components
->ts
.u
.derived
);
3083 return find_intrinsic_vtab (ts
);
3088 /* General worker function to find either a type-bound procedure or a
3089 type-bound user operator. */
3092 find_typebound_proc_uop (gfc_symbol
* derived
, bool* t
,
3093 const char* name
, bool noaccess
, bool uop
,
3099 /* Set default to failure. */
3103 if (derived
->f2k_derived
)
3104 /* Set correct symbol-root. */
3105 root
= (uop
? derived
->f2k_derived
->tb_uop_root
3106 : derived
->f2k_derived
->tb_sym_root
);
3110 /* Try to find it in the current type's namespace. */
3111 res
= gfc_find_symtree (root
, name
);
3112 if (res
&& res
->n
.tb
&& !res
->n
.tb
->error
)
3118 if (!noaccess
&& derived
->attr
.use_assoc
3119 && res
->n
.tb
->access
== ACCESS_PRIVATE
)
3122 gfc_error ("%qs of %qs is PRIVATE at %L",
3123 name
, derived
->name
, where
);
3131 /* Otherwise, recurse on parent type if derived is an extension. */
3132 if (derived
->attr
.extension
)
3134 gfc_symbol
* super_type
;
3135 super_type
= gfc_get_derived_super_type (derived
);
3136 gcc_assert (super_type
);
3138 return find_typebound_proc_uop (super_type
, t
, name
,
3139 noaccess
, uop
, where
);
3142 /* Nothing found. */
3147 /* Find a type-bound procedure or user operator by name for a derived-type
3148 (looking recursively through the super-types). */
3151 gfc_find_typebound_proc (gfc_symbol
* derived
, bool* t
,
3152 const char* name
, bool noaccess
, locus
* where
)
3154 return find_typebound_proc_uop (derived
, t
, name
, noaccess
, false, where
);
3158 gfc_find_typebound_user_op (gfc_symbol
* derived
, bool* t
,
3159 const char* name
, bool noaccess
, locus
* where
)
3161 return find_typebound_proc_uop (derived
, t
, name
, noaccess
, true, where
);
3165 /* Find a type-bound intrinsic operator looking recursively through the
3166 super-type hierarchy. */
3169 gfc_find_typebound_intrinsic_op (gfc_symbol
* derived
, bool* t
,
3170 gfc_intrinsic_op op
, bool noaccess
,
3173 gfc_typebound_proc
* res
;
3175 /* Set default to failure. */
3179 /* Try to find it in the current type's namespace. */
3180 if (derived
->f2k_derived
)
3181 res
= derived
->f2k_derived
->tb_op
[op
];
3186 if (res
&& !res
->error
)
3192 if (!noaccess
&& derived
->attr
.use_assoc
3193 && res
->access
== ACCESS_PRIVATE
)
3196 gfc_error ("%qs of %qs is PRIVATE at %L",
3197 gfc_op2string (op
), derived
->name
, where
);
3205 /* Otherwise, recurse on parent type if derived is an extension. */
3206 if (derived
->attr
.extension
)
3208 gfc_symbol
* super_type
;
3209 super_type
= gfc_get_derived_super_type (derived
);
3210 gcc_assert (super_type
);
3212 return gfc_find_typebound_intrinsic_op (super_type
, t
, op
,
3216 /* Nothing found. */
3221 /* Get a typebound-procedure symtree or create and insert it if not yet
3222 present. This is like a very simplified version of gfc_get_sym_tree for
3223 tbp-symtrees rather than regular ones. */
3226 gfc_get_tbp_symtree (gfc_symtree
**root
, const char *name
)
3228 gfc_symtree
*result
= gfc_find_symtree (*root
, name
);
3229 return result
? result
: gfc_new_symtree (root
, name
);