annotate gcc/fortran/trans-types.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Backend support for Fortran 95 basic types and derived types.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Paul Brook <paul@nowt.org>
kono
parents:
diff changeset
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 /* trans-types.c -- gfortran backend types */
kono
parents:
diff changeset
23
kono
parents:
diff changeset
24 #include "config.h"
kono
parents:
diff changeset
25 #include "system.h"
kono
parents:
diff changeset
26 #include "coretypes.h"
kono
parents:
diff changeset
27 #include "target.h"
kono
parents:
diff changeset
28 #include "tree.h"
kono
parents:
diff changeset
29 #include "gfortran.h"
kono
parents:
diff changeset
30 #include "trans.h"
kono
parents:
diff changeset
31 #include "stringpool.h"
kono
parents:
diff changeset
32 #include "fold-const.h"
kono
parents:
diff changeset
33 #include "stor-layout.h"
kono
parents:
diff changeset
34 #include "langhooks.h" /* For iso-c-bindings.def. */
kono
parents:
diff changeset
35 #include "toplev.h" /* For rest_of_decl_compilation. */
kono
parents:
diff changeset
36 #include "trans-types.h"
kono
parents:
diff changeset
37 #include "trans-const.h"
kono
parents:
diff changeset
38 #include "trans-array.h"
kono
parents:
diff changeset
39 #include "dwarf2out.h" /* For struct array_descr_info. */
kono
parents:
diff changeset
40 #include "attribs.h"
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 #if (GFC_MAX_DIMENSIONS < 10)
kono
parents:
diff changeset
44 #define GFC_RANK_DIGITS 1
kono
parents:
diff changeset
45 #define GFC_RANK_PRINTF_FORMAT "%01d"
kono
parents:
diff changeset
46 #elif (GFC_MAX_DIMENSIONS < 100)
kono
parents:
diff changeset
47 #define GFC_RANK_DIGITS 2
kono
parents:
diff changeset
48 #define GFC_RANK_PRINTF_FORMAT "%02d"
kono
parents:
diff changeset
49 #else
kono
parents:
diff changeset
50 #error If you really need >99 dimensions, continue the sequence above...
kono
parents:
diff changeset
51 #endif
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 /* array of structs so we don't have to worry about xmalloc or free */
kono
parents:
diff changeset
54 CInteropKind_t c_interop_kinds_table[ISOCBINDING_NUMBER];
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 tree gfc_array_index_type;
kono
parents:
diff changeset
57 tree gfc_array_range_type;
kono
parents:
diff changeset
58 tree gfc_character1_type_node;
kono
parents:
diff changeset
59 tree pvoid_type_node;
kono
parents:
diff changeset
60 tree prvoid_type_node;
kono
parents:
diff changeset
61 tree ppvoid_type_node;
kono
parents:
diff changeset
62 tree pchar_type_node;
kono
parents:
diff changeset
63 tree pfunc_type_node;
kono
parents:
diff changeset
64
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
65 tree logical_type_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
66 tree logical_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
67 tree logical_false_node;
111
kono
parents:
diff changeset
68 tree gfc_charlen_type_node;
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 tree gfc_float128_type_node = NULL_TREE;
kono
parents:
diff changeset
71 tree gfc_complex_float128_type_node = NULL_TREE;
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 bool gfc_real16_is_float128 = false;
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 static GTY(()) tree gfc_desc_dim_type;
kono
parents:
diff changeset
76 static GTY(()) tree gfc_max_array_element_size;
kono
parents:
diff changeset
77 static GTY(()) tree gfc_array_descriptor_base[2 * (GFC_MAX_DIMENSIONS+1)];
kono
parents:
diff changeset
78 static GTY(()) tree gfc_array_descriptor_base_caf[2 * (GFC_MAX_DIMENSIONS+1)];
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 /* Arrays for all integral and real kinds. We'll fill this in at runtime
kono
parents:
diff changeset
81 after the target has a chance to process command-line options. */
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 #define MAX_INT_KINDS 5
kono
parents:
diff changeset
84 gfc_integer_info gfc_integer_kinds[MAX_INT_KINDS + 1];
kono
parents:
diff changeset
85 gfc_logical_info gfc_logical_kinds[MAX_INT_KINDS + 1];
kono
parents:
diff changeset
86 static GTY(()) tree gfc_integer_types[MAX_INT_KINDS + 1];
kono
parents:
diff changeset
87 static GTY(()) tree gfc_logical_types[MAX_INT_KINDS + 1];
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 #define MAX_REAL_KINDS 5
kono
parents:
diff changeset
90 gfc_real_info gfc_real_kinds[MAX_REAL_KINDS + 1];
kono
parents:
diff changeset
91 static GTY(()) tree gfc_real_types[MAX_REAL_KINDS + 1];
kono
parents:
diff changeset
92 static GTY(()) tree gfc_complex_types[MAX_REAL_KINDS + 1];
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 #define MAX_CHARACTER_KINDS 2
kono
parents:
diff changeset
95 gfc_character_info gfc_character_kinds[MAX_CHARACTER_KINDS + 1];
kono
parents:
diff changeset
96 static GTY(()) tree gfc_character_types[MAX_CHARACTER_KINDS + 1];
kono
parents:
diff changeset
97 static GTY(()) tree gfc_pcharacter_types[MAX_CHARACTER_KINDS + 1];
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 static tree gfc_add_field_to_struct_1 (tree, tree, tree, tree **);
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 /* The integer kind to use for array indices. This will be set to the
kono
parents:
diff changeset
102 proper value based on target information from the backend. */
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 int gfc_index_integer_kind;
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 /* The default kinds of the various types. */
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 int gfc_default_integer_kind;
kono
parents:
diff changeset
109 int gfc_max_integer_kind;
kono
parents:
diff changeset
110 int gfc_default_real_kind;
kono
parents:
diff changeset
111 int gfc_default_double_kind;
kono
parents:
diff changeset
112 int gfc_default_character_kind;
kono
parents:
diff changeset
113 int gfc_default_logical_kind;
kono
parents:
diff changeset
114 int gfc_default_complex_kind;
kono
parents:
diff changeset
115 int gfc_c_int_kind;
kono
parents:
diff changeset
116 int gfc_atomic_int_kind;
kono
parents:
diff changeset
117 int gfc_atomic_logical_kind;
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 /* The kind size used for record offsets. If the target system supports
kono
parents:
diff changeset
120 kind=8, this will be set to 8, otherwise it is set to 4. */
kono
parents:
diff changeset
121 int gfc_intio_kind;
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 /* The integer kind used to store character lengths. */
kono
parents:
diff changeset
124 int gfc_charlen_int_kind;
kono
parents:
diff changeset
125
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 /* Kind of internal integer for storing object sizes. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
127 int gfc_size_kind;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128
111
kono
parents:
diff changeset
129 /* The size of the numeric storage unit and character storage unit. */
kono
parents:
diff changeset
130 int gfc_numeric_storage_size;
kono
parents:
diff changeset
131 int gfc_character_storage_size;
kono
parents:
diff changeset
132
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 tree dtype_type_node = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 /* Build the dtype_type_node if necessary. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 tree get_dtype_type_node (void)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 tree field;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
140 tree dtype_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 tree *dtype_chain = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
142
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
143 if (dtype_type_node == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
144 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
145 dtype_node = make_node (RECORD_TYPE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 TYPE_NAME (dtype_node) = get_identifier ("dtype_type");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 TYPE_NAMELESS (dtype_node) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148 field = gfc_add_field_to_struct_1 (dtype_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 get_identifier ("elem_len"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 size_type_node, &dtype_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
151 TREE_NO_WARNING (field) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
152 field = gfc_add_field_to_struct_1 (dtype_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
153 get_identifier ("version"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
154 integer_type_node, &dtype_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 TREE_NO_WARNING (field) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156 field = gfc_add_field_to_struct_1 (dtype_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 get_identifier ("rank"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158 signed_char_type_node, &dtype_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159 TREE_NO_WARNING (field) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 field = gfc_add_field_to_struct_1 (dtype_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 get_identifier ("type"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 signed_char_type_node, &dtype_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 TREE_NO_WARNING (field) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 field = gfc_add_field_to_struct_1 (dtype_node,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 get_identifier ("attribute"),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 short_integer_type_node, &dtype_chain);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
167 TREE_NO_WARNING (field) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
168 gfc_finish_type (dtype_node);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
169 TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (dtype_node)) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 dtype_type_node = dtype_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 return dtype_type_node;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 }
111
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 bool
kono
parents:
diff changeset
176 gfc_check_any_c_kind (gfc_typespec *ts)
kono
parents:
diff changeset
177 {
kono
parents:
diff changeset
178 int i;
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 for (i = 0; i < ISOCBINDING_NUMBER; i++)
kono
parents:
diff changeset
181 {
kono
parents:
diff changeset
182 /* Check for any C interoperable kind for the given type/kind in ts.
kono
parents:
diff changeset
183 This can be used after verify_c_interop to make sure that the
kono
parents:
diff changeset
184 Fortran kind being used exists in at least some form for C. */
kono
parents:
diff changeset
185 if (c_interop_kinds_table[i].f90_type == ts->type &&
kono
parents:
diff changeset
186 c_interop_kinds_table[i].value == ts->kind)
kono
parents:
diff changeset
187 return true;
kono
parents:
diff changeset
188 }
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 return false;
kono
parents:
diff changeset
191 }
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 static int
kono
parents:
diff changeset
195 get_real_kind_from_node (tree type)
kono
parents:
diff changeset
196 {
kono
parents:
diff changeset
197 int i;
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 for (i = 0; gfc_real_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
200 if (gfc_real_kinds[i].mode_precision == TYPE_PRECISION (type))
kono
parents:
diff changeset
201 return gfc_real_kinds[i].kind;
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 return -4;
kono
parents:
diff changeset
204 }
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 static int
kono
parents:
diff changeset
207 get_int_kind_from_node (tree type)
kono
parents:
diff changeset
208 {
kono
parents:
diff changeset
209 int i;
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 if (!type)
kono
parents:
diff changeset
212 return -2;
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
215 if (gfc_integer_kinds[i].bit_size == TYPE_PRECISION (type))
kono
parents:
diff changeset
216 return gfc_integer_kinds[i].kind;
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 return -1;
kono
parents:
diff changeset
219 }
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 static int
kono
parents:
diff changeset
222 get_int_kind_from_name (const char *name)
kono
parents:
diff changeset
223 {
kono
parents:
diff changeset
224 return get_int_kind_from_node (get_typenode_from_name (name));
kono
parents:
diff changeset
225 }
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 /* Get the kind number corresponding to an integer of given size,
kono
parents:
diff changeset
229 following the required return values for ISO_FORTRAN_ENV INT* constants:
kono
parents:
diff changeset
230 -2 is returned if we support a kind of larger size, -1 otherwise. */
kono
parents:
diff changeset
231 int
kono
parents:
diff changeset
232 gfc_get_int_kind_from_width_isofortranenv (int size)
kono
parents:
diff changeset
233 {
kono
parents:
diff changeset
234 int i;
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 /* Look for a kind with matching storage size. */
kono
parents:
diff changeset
237 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
238 if (gfc_integer_kinds[i].bit_size == size)
kono
parents:
diff changeset
239 return gfc_integer_kinds[i].kind;
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 /* Look for a kind with larger storage size. */
kono
parents:
diff changeset
242 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
243 if (gfc_integer_kinds[i].bit_size > size)
kono
parents:
diff changeset
244 return -2;
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 return -1;
kono
parents:
diff changeset
247 }
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249
kono
parents:
diff changeset
250 /* Get the kind number corresponding to a real of a given storage size.
kono
parents:
diff changeset
251 If two real's have the same storage size, then choose the real with
kono
parents:
diff changeset
252 the largest precision. If a kind type is unavailable and a real
kono
parents:
diff changeset
253 exists with wider storage, then return -2; otherwise, return -1. */
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 int
kono
parents:
diff changeset
256 gfc_get_real_kind_from_width_isofortranenv (int size)
kono
parents:
diff changeset
257 {
kono
parents:
diff changeset
258 int digits, i, kind;
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 size /= 8;
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 kind = -1;
kono
parents:
diff changeset
263 digits = 0;
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 /* Look for a kind with matching storage size. */
kono
parents:
diff changeset
266 for (i = 0; gfc_real_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
267 if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) == size)
kono
parents:
diff changeset
268 {
kono
parents:
diff changeset
269 if (gfc_real_kinds[i].digits > digits)
kono
parents:
diff changeset
270 {
kono
parents:
diff changeset
271 digits = gfc_real_kinds[i].digits;
kono
parents:
diff changeset
272 kind = gfc_real_kinds[i].kind;
kono
parents:
diff changeset
273 }
kono
parents:
diff changeset
274 }
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 if (kind != -1)
kono
parents:
diff changeset
277 return kind;
kono
parents:
diff changeset
278
kono
parents:
diff changeset
279 /* Look for a kind with larger storage size. */
kono
parents:
diff changeset
280 for (i = 0; gfc_real_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
281 if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) > size)
kono
parents:
diff changeset
282 kind = -2;
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 return kind;
kono
parents:
diff changeset
285 }
kono
parents:
diff changeset
286
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 static int
kono
parents:
diff changeset
290 get_int_kind_from_width (int size)
kono
parents:
diff changeset
291 {
kono
parents:
diff changeset
292 int i;
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
295 if (gfc_integer_kinds[i].bit_size == size)
kono
parents:
diff changeset
296 return gfc_integer_kinds[i].kind;
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 return -2;
kono
parents:
diff changeset
299 }
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 static int
kono
parents:
diff changeset
302 get_int_kind_from_minimal_width (int size)
kono
parents:
diff changeset
303 {
kono
parents:
diff changeset
304 int i;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
307 if (gfc_integer_kinds[i].bit_size >= size)
kono
parents:
diff changeset
308 return gfc_integer_kinds[i].kind;
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 return -2;
kono
parents:
diff changeset
311 }
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 /* Generate the CInteropKind_t objects for the C interoperable
kono
parents:
diff changeset
315 kinds. */
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 void
kono
parents:
diff changeset
318 gfc_init_c_interop_kinds (void)
kono
parents:
diff changeset
319 {
kono
parents:
diff changeset
320 int i;
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 /* init all pointers in the list to NULL */
kono
parents:
diff changeset
323 for (i = 0; i < ISOCBINDING_NUMBER; i++)
kono
parents:
diff changeset
324 {
kono
parents:
diff changeset
325 /* Initialize the name and value fields. */
kono
parents:
diff changeset
326 c_interop_kinds_table[i].name[0] = '\0';
kono
parents:
diff changeset
327 c_interop_kinds_table[i].value = -100;
kono
parents:
diff changeset
328 c_interop_kinds_table[i].f90_type = BT_UNKNOWN;
kono
parents:
diff changeset
329 }
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 #define NAMED_INTCST(a,b,c,d) \
kono
parents:
diff changeset
332 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
333 c_interop_kinds_table[a].f90_type = BT_INTEGER; \
kono
parents:
diff changeset
334 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
335 #define NAMED_REALCST(a,b,c,d) \
kono
parents:
diff changeset
336 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
337 c_interop_kinds_table[a].f90_type = BT_REAL; \
kono
parents:
diff changeset
338 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
339 #define NAMED_CMPXCST(a,b,c,d) \
kono
parents:
diff changeset
340 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
341 c_interop_kinds_table[a].f90_type = BT_COMPLEX; \
kono
parents:
diff changeset
342 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
343 #define NAMED_LOGCST(a,b,c) \
kono
parents:
diff changeset
344 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
345 c_interop_kinds_table[a].f90_type = BT_LOGICAL; \
kono
parents:
diff changeset
346 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
347 #define NAMED_CHARKNDCST(a,b,c) \
kono
parents:
diff changeset
348 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
349 c_interop_kinds_table[a].f90_type = BT_CHARACTER; \
kono
parents:
diff changeset
350 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
351 #define NAMED_CHARCST(a,b,c) \
kono
parents:
diff changeset
352 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
353 c_interop_kinds_table[a].f90_type = BT_CHARACTER; \
kono
parents:
diff changeset
354 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
355 #define DERIVED_TYPE(a,b,c) \
kono
parents:
diff changeset
356 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
357 c_interop_kinds_table[a].f90_type = BT_DERIVED; \
kono
parents:
diff changeset
358 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
359 #define NAMED_FUNCTION(a,b,c,d) \
kono
parents:
diff changeset
360 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
361 c_interop_kinds_table[a].f90_type = BT_PROCEDURE; \
kono
parents:
diff changeset
362 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
363 #define NAMED_SUBROUTINE(a,b,c,d) \
kono
parents:
diff changeset
364 strncpy (c_interop_kinds_table[a].name, b, strlen(b) + 1); \
kono
parents:
diff changeset
365 c_interop_kinds_table[a].f90_type = BT_PROCEDURE; \
kono
parents:
diff changeset
366 c_interop_kinds_table[a].value = c;
kono
parents:
diff changeset
367 #include "iso-c-binding.def"
kono
parents:
diff changeset
368 }
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 /* Query the target to determine which machine modes are available for
kono
parents:
diff changeset
372 computation. Choose KIND numbers for them. */
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 void
kono
parents:
diff changeset
375 gfc_init_kinds (void)
kono
parents:
diff changeset
376 {
kono
parents:
diff changeset
377 opt_scalar_int_mode int_mode_iter;
kono
parents:
diff changeset
378 opt_scalar_float_mode float_mode_iter;
kono
parents:
diff changeset
379 int i_index, r_index, kind;
kono
parents:
diff changeset
380 bool saw_i4 = false, saw_i8 = false;
kono
parents:
diff changeset
381 bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;
kono
parents:
diff changeset
382
kono
parents:
diff changeset
383 i_index = 0;
kono
parents:
diff changeset
384 FOR_EACH_MODE_IN_CLASS (int_mode_iter, MODE_INT)
kono
parents:
diff changeset
385 {
kono
parents:
diff changeset
386 scalar_int_mode mode = int_mode_iter.require ();
kono
parents:
diff changeset
387 int kind, bitsize;
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 if (!targetm.scalar_mode_supported_p (mode))
kono
parents:
diff changeset
390 continue;
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 /* The middle end doesn't support constants larger than 2*HWI.
kono
parents:
diff changeset
393 Perhaps the target hook shouldn't have accepted these either,
kono
parents:
diff changeset
394 but just to be safe... */
kono
parents:
diff changeset
395 bitsize = GET_MODE_BITSIZE (mode);
kono
parents:
diff changeset
396 if (bitsize > 2*HOST_BITS_PER_WIDE_INT)
kono
parents:
diff changeset
397 continue;
kono
parents:
diff changeset
398
kono
parents:
diff changeset
399 gcc_assert (i_index != MAX_INT_KINDS);
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 /* Let the kind equal the bit size divided by 8. This insulates the
kono
parents:
diff changeset
402 programmer from the underlying byte size. */
kono
parents:
diff changeset
403 kind = bitsize / 8;
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 if (kind == 4)
kono
parents:
diff changeset
406 saw_i4 = true;
kono
parents:
diff changeset
407 if (kind == 8)
kono
parents:
diff changeset
408 saw_i8 = true;
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 gfc_integer_kinds[i_index].kind = kind;
kono
parents:
diff changeset
411 gfc_integer_kinds[i_index].radix = 2;
kono
parents:
diff changeset
412 gfc_integer_kinds[i_index].digits = bitsize - 1;
kono
parents:
diff changeset
413 gfc_integer_kinds[i_index].bit_size = bitsize;
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 gfc_logical_kinds[i_index].kind = kind;
kono
parents:
diff changeset
416 gfc_logical_kinds[i_index].bit_size = bitsize;
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 i_index += 1;
kono
parents:
diff changeset
419 }
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 /* Set the kind used to match GFC_INT_IO in libgfortran. This is
kono
parents:
diff changeset
422 used for large file access. */
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 if (saw_i8)
kono
parents:
diff changeset
425 gfc_intio_kind = 8;
kono
parents:
diff changeset
426 else
kono
parents:
diff changeset
427 gfc_intio_kind = 4;
kono
parents:
diff changeset
428
kono
parents:
diff changeset
429 /* If we do not at least have kind = 4, everything is pointless. */
kono
parents:
diff changeset
430 gcc_assert(saw_i4);
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 /* Set the maximum integer kind. Used with at least BOZ constants. */
kono
parents:
diff changeset
433 gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 r_index = 0;
kono
parents:
diff changeset
436 FOR_EACH_MODE_IN_CLASS (float_mode_iter, MODE_FLOAT)
kono
parents:
diff changeset
437 {
kono
parents:
diff changeset
438 scalar_float_mode mode = float_mode_iter.require ();
kono
parents:
diff changeset
439 const struct real_format *fmt = REAL_MODE_FORMAT (mode);
kono
parents:
diff changeset
440 int kind;
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 if (fmt == NULL)
kono
parents:
diff changeset
443 continue;
kono
parents:
diff changeset
444 if (!targetm.scalar_mode_supported_p (mode))
kono
parents:
diff changeset
445 continue;
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 /* Only let float, double, long double and __float128 go through.
kono
parents:
diff changeset
448 Runtime support for others is not provided, so they would be
kono
parents:
diff changeset
449 useless. */
kono
parents:
diff changeset
450 if (!targetm.libgcc_floating_mode_supported_p (mode))
kono
parents:
diff changeset
451 continue;
kono
parents:
diff changeset
452 if (mode != TYPE_MODE (float_type_node)
kono
parents:
diff changeset
453 && (mode != TYPE_MODE (double_type_node))
kono
parents:
diff changeset
454 && (mode != TYPE_MODE (long_double_type_node))
kono
parents:
diff changeset
455 #if defined(HAVE_TFmode) && defined(ENABLE_LIBQUADMATH_SUPPORT)
kono
parents:
diff changeset
456 && (mode != TFmode)
kono
parents:
diff changeset
457 #endif
kono
parents:
diff changeset
458 )
kono
parents:
diff changeset
459 continue;
kono
parents:
diff changeset
460
kono
parents:
diff changeset
461 /* Let the kind equal the precision divided by 8, rounding up. Again,
kono
parents:
diff changeset
462 this insulates the programmer from the underlying byte size.
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 Also, it effectively deals with IEEE extended formats. There, the
kono
parents:
diff changeset
465 total size of the type may equal 16, but it's got 6 bytes of padding
kono
parents:
diff changeset
466 and the increased size can get in the way of a real IEEE quad format
kono
parents:
diff changeset
467 which may also be supported by the target.
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 We round up so as to handle IA-64 __floatreg (RFmode), which is an
kono
parents:
diff changeset
470 82 bit type. Not to be confused with __float80 (XFmode), which is
kono
parents:
diff changeset
471 an 80 bit type also supported by IA-64. So XFmode should come out
kono
parents:
diff changeset
472 to be kind=10, and RFmode should come out to be kind=11. Egads. */
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 kind = (GET_MODE_PRECISION (mode) + 7) / 8;
kono
parents:
diff changeset
475
kono
parents:
diff changeset
476 if (kind == 4)
kono
parents:
diff changeset
477 saw_r4 = true;
kono
parents:
diff changeset
478 if (kind == 8)
kono
parents:
diff changeset
479 saw_r8 = true;
kono
parents:
diff changeset
480 if (kind == 10)
kono
parents:
diff changeset
481 saw_r10 = true;
kono
parents:
diff changeset
482 if (kind == 16)
kono
parents:
diff changeset
483 saw_r16 = true;
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 /* Careful we don't stumble a weird internal mode. */
kono
parents:
diff changeset
486 gcc_assert (r_index <= 0 || gfc_real_kinds[r_index-1].kind != kind);
kono
parents:
diff changeset
487 /* Or have too many modes for the allocated space. */
kono
parents:
diff changeset
488 gcc_assert (r_index != MAX_REAL_KINDS);
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 gfc_real_kinds[r_index].kind = kind;
kono
parents:
diff changeset
491 gfc_real_kinds[r_index].radix = fmt->b;
kono
parents:
diff changeset
492 gfc_real_kinds[r_index].digits = fmt->p;
kono
parents:
diff changeset
493 gfc_real_kinds[r_index].min_exponent = fmt->emin;
kono
parents:
diff changeset
494 gfc_real_kinds[r_index].max_exponent = fmt->emax;
kono
parents:
diff changeset
495 if (fmt->pnan < fmt->p)
kono
parents:
diff changeset
496 /* This is an IBM extended double format (or the MIPS variant)
kono
parents:
diff changeset
497 made up of two IEEE doubles. The value of the long double is
kono
parents:
diff changeset
498 the sum of the values of the two parts. The most significant
kono
parents:
diff changeset
499 part is required to be the value of the long double rounded
kono
parents:
diff changeset
500 to the nearest double. If we use emax of 1024 then we can't
kono
parents:
diff changeset
501 represent huge(x) = (1 - b**(-p)) * b**(emax-1) * b, because
kono
parents:
diff changeset
502 rounding will make the most significant part overflow. */
kono
parents:
diff changeset
503 gfc_real_kinds[r_index].max_exponent = fmt->emax - 1;
kono
parents:
diff changeset
504 gfc_real_kinds[r_index].mode_precision = GET_MODE_PRECISION (mode);
kono
parents:
diff changeset
505 r_index += 1;
kono
parents:
diff changeset
506 }
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 /* Choose the default integer kind. We choose 4 unless the user directs us
kono
parents:
diff changeset
509 otherwise. Even if the user specified that the default integer kind is 8,
kono
parents:
diff changeset
510 the numeric storage size is not 64 bits. In this case, a warning will be
kono
parents:
diff changeset
511 issued when NUMERIC_STORAGE_SIZE is used. Set NUMERIC_STORAGE_SIZE to 32. */
kono
parents:
diff changeset
512
kono
parents:
diff changeset
513 gfc_numeric_storage_size = 4 * 8;
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 if (flag_default_integer)
kono
parents:
diff changeset
516 {
kono
parents:
diff changeset
517 if (!saw_i8)
kono
parents:
diff changeset
518 gfc_fatal_error ("INTEGER(KIND=8) is not available for "
kono
parents:
diff changeset
519 "%<-fdefault-integer-8%> option");
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 gfc_default_integer_kind = 8;
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 }
kono
parents:
diff changeset
524 else if (flag_integer4_kind == 8)
kono
parents:
diff changeset
525 {
kono
parents:
diff changeset
526 if (!saw_i8)
kono
parents:
diff changeset
527 gfc_fatal_error ("INTEGER(KIND=8) is not available for "
kono
parents:
diff changeset
528 "%<-finteger-4-integer-8%> option");
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 gfc_default_integer_kind = 8;
kono
parents:
diff changeset
531 }
kono
parents:
diff changeset
532 else if (saw_i4)
kono
parents:
diff changeset
533 {
kono
parents:
diff changeset
534 gfc_default_integer_kind = 4;
kono
parents:
diff changeset
535 }
kono
parents:
diff changeset
536 else
kono
parents:
diff changeset
537 {
kono
parents:
diff changeset
538 gfc_default_integer_kind = gfc_integer_kinds[i_index - 1].kind;
kono
parents:
diff changeset
539 gfc_numeric_storage_size = gfc_integer_kinds[i_index - 1].bit_size;
kono
parents:
diff changeset
540 }
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 /* Choose the default real kind. Again, we choose 4 when possible. */
kono
parents:
diff changeset
543 if (flag_default_real_8)
kono
parents:
diff changeset
544 {
kono
parents:
diff changeset
545 if (!saw_r8)
kono
parents:
diff changeset
546 gfc_fatal_error ("REAL(KIND=8) is not available for "
kono
parents:
diff changeset
547 "%<-fdefault-real-8%> option");
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 gfc_default_real_kind = 8;
kono
parents:
diff changeset
550 }
kono
parents:
diff changeset
551 else if (flag_default_real_10)
kono
parents:
diff changeset
552 {
kono
parents:
diff changeset
553 if (!saw_r10)
kono
parents:
diff changeset
554 gfc_fatal_error ("REAL(KIND=10) is not available for "
kono
parents:
diff changeset
555 "%<-fdefault-real-10%> option");
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 gfc_default_real_kind = 10;
kono
parents:
diff changeset
558 }
kono
parents:
diff changeset
559 else if (flag_default_real_16)
kono
parents:
diff changeset
560 {
kono
parents:
diff changeset
561 if (!saw_r16)
kono
parents:
diff changeset
562 gfc_fatal_error ("REAL(KIND=16) is not available for "
kono
parents:
diff changeset
563 "%<-fdefault-real-16%> option");
kono
parents:
diff changeset
564
kono
parents:
diff changeset
565 gfc_default_real_kind = 16;
kono
parents:
diff changeset
566 }
kono
parents:
diff changeset
567 else if (flag_real4_kind == 8)
kono
parents:
diff changeset
568 {
kono
parents:
diff changeset
569 if (!saw_r8)
kono
parents:
diff changeset
570 gfc_fatal_error ("REAL(KIND=8) is not available for %<-freal-4-real-8%> "
kono
parents:
diff changeset
571 "option");
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 gfc_default_real_kind = 8;
kono
parents:
diff changeset
574 }
kono
parents:
diff changeset
575 else if (flag_real4_kind == 10)
kono
parents:
diff changeset
576 {
kono
parents:
diff changeset
577 if (!saw_r10)
kono
parents:
diff changeset
578 gfc_fatal_error ("REAL(KIND=10) is not available for "
kono
parents:
diff changeset
579 "%<-freal-4-real-10%> option");
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 gfc_default_real_kind = 10;
kono
parents:
diff changeset
582 }
kono
parents:
diff changeset
583 else if (flag_real4_kind == 16)
kono
parents:
diff changeset
584 {
kono
parents:
diff changeset
585 if (!saw_r16)
kono
parents:
diff changeset
586 gfc_fatal_error ("REAL(KIND=16) is not available for "
kono
parents:
diff changeset
587 "%<-freal-4-real-16%> option");
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 gfc_default_real_kind = 16;
kono
parents:
diff changeset
590 }
kono
parents:
diff changeset
591 else if (saw_r4)
kono
parents:
diff changeset
592 gfc_default_real_kind = 4;
kono
parents:
diff changeset
593 else
kono
parents:
diff changeset
594 gfc_default_real_kind = gfc_real_kinds[0].kind;
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 /* Choose the default double kind. If -fdefault-real and -fdefault-double
kono
parents:
diff changeset
597 are specified, we use kind=8, if it's available. If -fdefault-real is
kono
parents:
diff changeset
598 specified without -fdefault-double, we use kind=16, if it's available.
kono
parents:
diff changeset
599 Otherwise we do not change anything. */
kono
parents:
diff changeset
600 if (flag_default_double && saw_r8)
kono
parents:
diff changeset
601 gfc_default_double_kind = 8;
kono
parents:
diff changeset
602 else if (flag_default_real_8 || flag_default_real_10 || flag_default_real_16)
kono
parents:
diff changeset
603 {
kono
parents:
diff changeset
604 /* Use largest available kind. */
kono
parents:
diff changeset
605 if (saw_r16)
kono
parents:
diff changeset
606 gfc_default_double_kind = 16;
kono
parents:
diff changeset
607 else if (saw_r10)
kono
parents:
diff changeset
608 gfc_default_double_kind = 10;
kono
parents:
diff changeset
609 else if (saw_r8)
kono
parents:
diff changeset
610 gfc_default_double_kind = 8;
kono
parents:
diff changeset
611 else
kono
parents:
diff changeset
612 gfc_default_double_kind = gfc_default_real_kind;
kono
parents:
diff changeset
613 }
kono
parents:
diff changeset
614 else if (flag_real8_kind == 4)
kono
parents:
diff changeset
615 {
kono
parents:
diff changeset
616 if (!saw_r4)
kono
parents:
diff changeset
617 gfc_fatal_error ("REAL(KIND=4) is not available for "
kono
parents:
diff changeset
618 "%<-freal-8-real-4%> option");
kono
parents:
diff changeset
619
kono
parents:
diff changeset
620 gfc_default_double_kind = 4;
kono
parents:
diff changeset
621 }
kono
parents:
diff changeset
622 else if (flag_real8_kind == 10 )
kono
parents:
diff changeset
623 {
kono
parents:
diff changeset
624 if (!saw_r10)
kono
parents:
diff changeset
625 gfc_fatal_error ("REAL(KIND=10) is not available for "
kono
parents:
diff changeset
626 "%<-freal-8-real-10%> option");
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 gfc_default_double_kind = 10;
kono
parents:
diff changeset
629 }
kono
parents:
diff changeset
630 else if (flag_real8_kind == 16 )
kono
parents:
diff changeset
631 {
kono
parents:
diff changeset
632 if (!saw_r16)
kono
parents:
diff changeset
633 gfc_fatal_error ("REAL(KIND=10) is not available for "
kono
parents:
diff changeset
634 "%<-freal-8-real-16%> option");
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 gfc_default_double_kind = 16;
kono
parents:
diff changeset
637 }
kono
parents:
diff changeset
638 else if (saw_r4 && saw_r8)
kono
parents:
diff changeset
639 gfc_default_double_kind = 8;
kono
parents:
diff changeset
640 else
kono
parents:
diff changeset
641 {
kono
parents:
diff changeset
642 /* F95 14.6.3.1: A nonpointer scalar object of type double precision
kono
parents:
diff changeset
643 real ... occupies two contiguous numeric storage units.
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 Therefore we must be supplied a kind twice as large as we chose
kono
parents:
diff changeset
646 for single precision. There are loopholes, in that double
kono
parents:
diff changeset
647 precision must *occupy* two storage units, though it doesn't have
kono
parents:
diff changeset
648 to *use* two storage units. Which means that you can make this
kono
parents:
diff changeset
649 kind artificially wide by padding it. But at present there are
kono
parents:
diff changeset
650 no GCC targets for which a two-word type does not exist, so we
kono
parents:
diff changeset
651 just let gfc_validate_kind abort and tell us if something breaks. */
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 gfc_default_double_kind
kono
parents:
diff changeset
654 = gfc_validate_kind (BT_REAL, gfc_default_real_kind * 2, false);
kono
parents:
diff changeset
655 }
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 /* The default logical kind is constrained to be the same as the
kono
parents:
diff changeset
658 default integer kind. Similarly with complex and real. */
kono
parents:
diff changeset
659 gfc_default_logical_kind = gfc_default_integer_kind;
kono
parents:
diff changeset
660 gfc_default_complex_kind = gfc_default_real_kind;
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 /* We only have two character kinds: ASCII and UCS-4.
kono
parents:
diff changeset
663 ASCII corresponds to a 8-bit integer type, if one is available.
kono
parents:
diff changeset
664 UCS-4 corresponds to a 32-bit integer type, if one is available. */
kono
parents:
diff changeset
665 i_index = 0;
kono
parents:
diff changeset
666 if ((kind = get_int_kind_from_width (8)) > 0)
kono
parents:
diff changeset
667 {
kono
parents:
diff changeset
668 gfc_character_kinds[i_index].kind = kind;
kono
parents:
diff changeset
669 gfc_character_kinds[i_index].bit_size = 8;
kono
parents:
diff changeset
670 gfc_character_kinds[i_index].name = "ascii";
kono
parents:
diff changeset
671 i_index++;
kono
parents:
diff changeset
672 }
kono
parents:
diff changeset
673 if ((kind = get_int_kind_from_width (32)) > 0)
kono
parents:
diff changeset
674 {
kono
parents:
diff changeset
675 gfc_character_kinds[i_index].kind = kind;
kono
parents:
diff changeset
676 gfc_character_kinds[i_index].bit_size = 32;
kono
parents:
diff changeset
677 gfc_character_kinds[i_index].name = "iso_10646";
kono
parents:
diff changeset
678 i_index++;
kono
parents:
diff changeset
679 }
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 /* Choose the smallest integer kind for our default character. */
kono
parents:
diff changeset
682 gfc_default_character_kind = gfc_character_kinds[0].kind;
kono
parents:
diff changeset
683 gfc_character_storage_size = gfc_default_character_kind * 8;
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 gfc_index_integer_kind = get_int_kind_from_name (PTRDIFF_TYPE);
kono
parents:
diff changeset
686
kono
parents:
diff changeset
687 /* Pick a kind the same size as the C "int" type. */
kono
parents:
diff changeset
688 gfc_c_int_kind = INT_TYPE_SIZE / 8;
kono
parents:
diff changeset
689
kono
parents:
diff changeset
690 /* Choose atomic kinds to match C's int. */
kono
parents:
diff changeset
691 gfc_atomic_int_kind = gfc_c_int_kind;
kono
parents:
diff changeset
692 gfc_atomic_logical_kind = gfc_c_int_kind;
kono
parents:
diff changeset
693 }
kono
parents:
diff changeset
694
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 /* Make sure that a valid kind is present. Returns an index into the
kono
parents:
diff changeset
697 associated kinds array, -1 if the kind is not present. */
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 static int
kono
parents:
diff changeset
700 validate_integer (int kind)
kono
parents:
diff changeset
701 {
kono
parents:
diff changeset
702 int i;
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
705 if (gfc_integer_kinds[i].kind == kind)
kono
parents:
diff changeset
706 return i;
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 return -1;
kono
parents:
diff changeset
709 }
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 static int
kono
parents:
diff changeset
712 validate_real (int kind)
kono
parents:
diff changeset
713 {
kono
parents:
diff changeset
714 int i;
kono
parents:
diff changeset
715
kono
parents:
diff changeset
716 for (i = 0; gfc_real_kinds[i].kind != 0; i++)
kono
parents:
diff changeset
717 if (gfc_real_kinds[i].kind == kind)
kono
parents:
diff changeset
718 return i;
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 return -1;
kono
parents:
diff changeset
721 }
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 static int
kono
parents:
diff changeset
724 validate_logical (int kind)
kono
parents:
diff changeset
725 {
kono
parents:
diff changeset
726 int i;
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 for (i = 0; gfc_logical_kinds[i].kind; i++)
kono
parents:
diff changeset
729 if (gfc_logical_kinds[i].kind == kind)
kono
parents:
diff changeset
730 return i;
kono
parents:
diff changeset
731
kono
parents:
diff changeset
732 return -1;
kono
parents:
diff changeset
733 }
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 static int
kono
parents:
diff changeset
736 validate_character (int kind)
kono
parents:
diff changeset
737 {
kono
parents:
diff changeset
738 int i;
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 for (i = 0; gfc_character_kinds[i].kind; i++)
kono
parents:
diff changeset
741 if (gfc_character_kinds[i].kind == kind)
kono
parents:
diff changeset
742 return i;
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 return -1;
kono
parents:
diff changeset
745 }
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 /* Validate a kind given a basic type. The return value is the same
kono
parents:
diff changeset
748 for the child functions, with -1 indicating nonexistence of the
kono
parents:
diff changeset
749 type. If MAY_FAIL is false, then -1 is never returned, and we ICE. */
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 int
kono
parents:
diff changeset
752 gfc_validate_kind (bt type, int kind, bool may_fail)
kono
parents:
diff changeset
753 {
kono
parents:
diff changeset
754 int rc;
kono
parents:
diff changeset
755
kono
parents:
diff changeset
756 switch (type)
kono
parents:
diff changeset
757 {
kono
parents:
diff changeset
758 case BT_REAL: /* Fall through */
kono
parents:
diff changeset
759 case BT_COMPLEX:
kono
parents:
diff changeset
760 rc = validate_real (kind);
kono
parents:
diff changeset
761 break;
kono
parents:
diff changeset
762 case BT_INTEGER:
kono
parents:
diff changeset
763 rc = validate_integer (kind);
kono
parents:
diff changeset
764 break;
kono
parents:
diff changeset
765 case BT_LOGICAL:
kono
parents:
diff changeset
766 rc = validate_logical (kind);
kono
parents:
diff changeset
767 break;
kono
parents:
diff changeset
768 case BT_CHARACTER:
kono
parents:
diff changeset
769 rc = validate_character (kind);
kono
parents:
diff changeset
770 break;
kono
parents:
diff changeset
771
kono
parents:
diff changeset
772 default:
kono
parents:
diff changeset
773 gfc_internal_error ("gfc_validate_kind(): Got bad type");
kono
parents:
diff changeset
774 }
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 if (rc < 0 && !may_fail)
kono
parents:
diff changeset
777 gfc_internal_error ("gfc_validate_kind(): Got bad kind");
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 return rc;
kono
parents:
diff changeset
780 }
kono
parents:
diff changeset
781
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 /* Four subroutines of gfc_init_types. Create type nodes for the given kind.
kono
parents:
diff changeset
784 Reuse common type nodes where possible. Recognize if the kind matches up
kono
parents:
diff changeset
785 with a C type. This will be used later in determining which routines may
kono
parents:
diff changeset
786 be scarfed from libm. */
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 static tree
kono
parents:
diff changeset
789 gfc_build_int_type (gfc_integer_info *info)
kono
parents:
diff changeset
790 {
kono
parents:
diff changeset
791 int mode_precision = info->bit_size;
kono
parents:
diff changeset
792
kono
parents:
diff changeset
793 if (mode_precision == CHAR_TYPE_SIZE)
kono
parents:
diff changeset
794 info->c_char = 1;
kono
parents:
diff changeset
795 if (mode_precision == SHORT_TYPE_SIZE)
kono
parents:
diff changeset
796 info->c_short = 1;
kono
parents:
diff changeset
797 if (mode_precision == INT_TYPE_SIZE)
kono
parents:
diff changeset
798 info->c_int = 1;
kono
parents:
diff changeset
799 if (mode_precision == LONG_TYPE_SIZE)
kono
parents:
diff changeset
800 info->c_long = 1;
kono
parents:
diff changeset
801 if (mode_precision == LONG_LONG_TYPE_SIZE)
kono
parents:
diff changeset
802 info->c_long_long = 1;
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 if (TYPE_PRECISION (intQI_type_node) == mode_precision)
kono
parents:
diff changeset
805 return intQI_type_node;
kono
parents:
diff changeset
806 if (TYPE_PRECISION (intHI_type_node) == mode_precision)
kono
parents:
diff changeset
807 return intHI_type_node;
kono
parents:
diff changeset
808 if (TYPE_PRECISION (intSI_type_node) == mode_precision)
kono
parents:
diff changeset
809 return intSI_type_node;
kono
parents:
diff changeset
810 if (TYPE_PRECISION (intDI_type_node) == mode_precision)
kono
parents:
diff changeset
811 return intDI_type_node;
kono
parents:
diff changeset
812 if (TYPE_PRECISION (intTI_type_node) == mode_precision)
kono
parents:
diff changeset
813 return intTI_type_node;
kono
parents:
diff changeset
814
kono
parents:
diff changeset
815 return make_signed_type (mode_precision);
kono
parents:
diff changeset
816 }
kono
parents:
diff changeset
817
kono
parents:
diff changeset
818 tree
kono
parents:
diff changeset
819 gfc_build_uint_type (int size)
kono
parents:
diff changeset
820 {
kono
parents:
diff changeset
821 if (size == CHAR_TYPE_SIZE)
kono
parents:
diff changeset
822 return unsigned_char_type_node;
kono
parents:
diff changeset
823 if (size == SHORT_TYPE_SIZE)
kono
parents:
diff changeset
824 return short_unsigned_type_node;
kono
parents:
diff changeset
825 if (size == INT_TYPE_SIZE)
kono
parents:
diff changeset
826 return unsigned_type_node;
kono
parents:
diff changeset
827 if (size == LONG_TYPE_SIZE)
kono
parents:
diff changeset
828 return long_unsigned_type_node;
kono
parents:
diff changeset
829 if (size == LONG_LONG_TYPE_SIZE)
kono
parents:
diff changeset
830 return long_long_unsigned_type_node;
kono
parents:
diff changeset
831
kono
parents:
diff changeset
832 return make_unsigned_type (size);
kono
parents:
diff changeset
833 }
kono
parents:
diff changeset
834
kono
parents:
diff changeset
835
kono
parents:
diff changeset
836 static tree
kono
parents:
diff changeset
837 gfc_build_real_type (gfc_real_info *info)
kono
parents:
diff changeset
838 {
kono
parents:
diff changeset
839 int mode_precision = info->mode_precision;
kono
parents:
diff changeset
840 tree new_type;
kono
parents:
diff changeset
841
kono
parents:
diff changeset
842 if (mode_precision == FLOAT_TYPE_SIZE)
kono
parents:
diff changeset
843 info->c_float = 1;
kono
parents:
diff changeset
844 if (mode_precision == DOUBLE_TYPE_SIZE)
kono
parents:
diff changeset
845 info->c_double = 1;
kono
parents:
diff changeset
846 if (mode_precision == LONG_DOUBLE_TYPE_SIZE)
kono
parents:
diff changeset
847 info->c_long_double = 1;
kono
parents:
diff changeset
848 if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
kono
parents:
diff changeset
849 {
kono
parents:
diff changeset
850 info->c_float128 = 1;
kono
parents:
diff changeset
851 gfc_real16_is_float128 = true;
kono
parents:
diff changeset
852 }
kono
parents:
diff changeset
853
kono
parents:
diff changeset
854 if (TYPE_PRECISION (float_type_node) == mode_precision)
kono
parents:
diff changeset
855 return float_type_node;
kono
parents:
diff changeset
856 if (TYPE_PRECISION (double_type_node) == mode_precision)
kono
parents:
diff changeset
857 return double_type_node;
kono
parents:
diff changeset
858 if (TYPE_PRECISION (long_double_type_node) == mode_precision)
kono
parents:
diff changeset
859 return long_double_type_node;
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 new_type = make_node (REAL_TYPE);
kono
parents:
diff changeset
862 TYPE_PRECISION (new_type) = mode_precision;
kono
parents:
diff changeset
863 layout_type (new_type);
kono
parents:
diff changeset
864 return new_type;
kono
parents:
diff changeset
865 }
kono
parents:
diff changeset
866
kono
parents:
diff changeset
867 static tree
kono
parents:
diff changeset
868 gfc_build_complex_type (tree scalar_type)
kono
parents:
diff changeset
869 {
kono
parents:
diff changeset
870 tree new_type;
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 if (scalar_type == NULL)
kono
parents:
diff changeset
873 return NULL;
kono
parents:
diff changeset
874 if (scalar_type == float_type_node)
kono
parents:
diff changeset
875 return complex_float_type_node;
kono
parents:
diff changeset
876 if (scalar_type == double_type_node)
kono
parents:
diff changeset
877 return complex_double_type_node;
kono
parents:
diff changeset
878 if (scalar_type == long_double_type_node)
kono
parents:
diff changeset
879 return complex_long_double_type_node;
kono
parents:
diff changeset
880
kono
parents:
diff changeset
881 new_type = make_node (COMPLEX_TYPE);
kono
parents:
diff changeset
882 TREE_TYPE (new_type) = scalar_type;
kono
parents:
diff changeset
883 layout_type (new_type);
kono
parents:
diff changeset
884 return new_type;
kono
parents:
diff changeset
885 }
kono
parents:
diff changeset
886
kono
parents:
diff changeset
887 static tree
kono
parents:
diff changeset
888 gfc_build_logical_type (gfc_logical_info *info)
kono
parents:
diff changeset
889 {
kono
parents:
diff changeset
890 int bit_size = info->bit_size;
kono
parents:
diff changeset
891 tree new_type;
kono
parents:
diff changeset
892
kono
parents:
diff changeset
893 if (bit_size == BOOL_TYPE_SIZE)
kono
parents:
diff changeset
894 {
kono
parents:
diff changeset
895 info->c_bool = 1;
kono
parents:
diff changeset
896 return boolean_type_node;
kono
parents:
diff changeset
897 }
kono
parents:
diff changeset
898
kono
parents:
diff changeset
899 new_type = make_unsigned_type (bit_size);
kono
parents:
diff changeset
900 TREE_SET_CODE (new_type, BOOLEAN_TYPE);
kono
parents:
diff changeset
901 TYPE_MAX_VALUE (new_type) = build_int_cst (new_type, 1);
kono
parents:
diff changeset
902 TYPE_PRECISION (new_type) = 1;
kono
parents:
diff changeset
903
kono
parents:
diff changeset
904 return new_type;
kono
parents:
diff changeset
905 }
kono
parents:
diff changeset
906
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 /* Create the backend type nodes. We map them to their
kono
parents:
diff changeset
909 equivalent C type, at least for now. We also give
kono
parents:
diff changeset
910 names to the types here, and we push them in the
kono
parents:
diff changeset
911 global binding level context.*/
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 void
kono
parents:
diff changeset
914 gfc_init_types (void)
kono
parents:
diff changeset
915 {
kono
parents:
diff changeset
916 char name_buf[26];
kono
parents:
diff changeset
917 int index;
kono
parents:
diff changeset
918 tree type;
kono
parents:
diff changeset
919 unsigned n;
kono
parents:
diff changeset
920
kono
parents:
diff changeset
921 /* Create and name the types. */
kono
parents:
diff changeset
922 #define PUSH_TYPE(name, node) \
kono
parents:
diff changeset
923 pushdecl (build_decl (input_location, \
kono
parents:
diff changeset
924 TYPE_DECL, get_identifier (name), node))
kono
parents:
diff changeset
925
kono
parents:
diff changeset
926 for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
kono
parents:
diff changeset
927 {
kono
parents:
diff changeset
928 type = gfc_build_int_type (&gfc_integer_kinds[index]);
kono
parents:
diff changeset
929 /* Ensure integer(kind=1) doesn't have TYPE_STRING_FLAG set. */
kono
parents:
diff changeset
930 if (TYPE_STRING_FLAG (type))
kono
parents:
diff changeset
931 type = make_signed_type (gfc_integer_kinds[index].bit_size);
kono
parents:
diff changeset
932 gfc_integer_types[index] = type;
kono
parents:
diff changeset
933 snprintf (name_buf, sizeof(name_buf), "integer(kind=%d)",
kono
parents:
diff changeset
934 gfc_integer_kinds[index].kind);
kono
parents:
diff changeset
935 PUSH_TYPE (name_buf, type);
kono
parents:
diff changeset
936 }
kono
parents:
diff changeset
937
kono
parents:
diff changeset
938 for (index = 0; gfc_logical_kinds[index].kind != 0; ++index)
kono
parents:
diff changeset
939 {
kono
parents:
diff changeset
940 type = gfc_build_logical_type (&gfc_logical_kinds[index]);
kono
parents:
diff changeset
941 gfc_logical_types[index] = type;
kono
parents:
diff changeset
942 snprintf (name_buf, sizeof(name_buf), "logical(kind=%d)",
kono
parents:
diff changeset
943 gfc_logical_kinds[index].kind);
kono
parents:
diff changeset
944 PUSH_TYPE (name_buf, type);
kono
parents:
diff changeset
945 }
kono
parents:
diff changeset
946
kono
parents:
diff changeset
947 for (index = 0; gfc_real_kinds[index].kind != 0; index++)
kono
parents:
diff changeset
948 {
kono
parents:
diff changeset
949 type = gfc_build_real_type (&gfc_real_kinds[index]);
kono
parents:
diff changeset
950 gfc_real_types[index] = type;
kono
parents:
diff changeset
951 snprintf (name_buf, sizeof(name_buf), "real(kind=%d)",
kono
parents:
diff changeset
952 gfc_real_kinds[index].kind);
kono
parents:
diff changeset
953 PUSH_TYPE (name_buf, type);
kono
parents:
diff changeset
954
kono
parents:
diff changeset
955 if (gfc_real_kinds[index].c_float128)
kono
parents:
diff changeset
956 gfc_float128_type_node = type;
kono
parents:
diff changeset
957
kono
parents:
diff changeset
958 type = gfc_build_complex_type (type);
kono
parents:
diff changeset
959 gfc_complex_types[index] = type;
kono
parents:
diff changeset
960 snprintf (name_buf, sizeof(name_buf), "complex(kind=%d)",
kono
parents:
diff changeset
961 gfc_real_kinds[index].kind);
kono
parents:
diff changeset
962 PUSH_TYPE (name_buf, type);
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 if (gfc_real_kinds[index].c_float128)
kono
parents:
diff changeset
965 gfc_complex_float128_type_node = type;
kono
parents:
diff changeset
966 }
kono
parents:
diff changeset
967
kono
parents:
diff changeset
968 for (index = 0; gfc_character_kinds[index].kind != 0; ++index)
kono
parents:
diff changeset
969 {
kono
parents:
diff changeset
970 type = gfc_build_uint_type (gfc_character_kinds[index].bit_size);
kono
parents:
diff changeset
971 type = build_qualified_type (type, TYPE_UNQUALIFIED);
kono
parents:
diff changeset
972 snprintf (name_buf, sizeof(name_buf), "character(kind=%d)",
kono
parents:
diff changeset
973 gfc_character_kinds[index].kind);
kono
parents:
diff changeset
974 PUSH_TYPE (name_buf, type);
kono
parents:
diff changeset
975 gfc_character_types[index] = type;
kono
parents:
diff changeset
976 gfc_pcharacter_types[index] = build_pointer_type (type);
kono
parents:
diff changeset
977 }
kono
parents:
diff changeset
978 gfc_character1_type_node = gfc_character_types[0];
kono
parents:
diff changeset
979
kono
parents:
diff changeset
980 PUSH_TYPE ("byte", unsigned_char_type_node);
kono
parents:
diff changeset
981 PUSH_TYPE ("void", void_type_node);
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 /* DBX debugging output gets upset if these aren't set. */
kono
parents:
diff changeset
984 if (!TYPE_NAME (integer_type_node))
kono
parents:
diff changeset
985 PUSH_TYPE ("c_integer", integer_type_node);
kono
parents:
diff changeset
986 if (!TYPE_NAME (char_type_node))
kono
parents:
diff changeset
987 PUSH_TYPE ("c_char", char_type_node);
kono
parents:
diff changeset
988
kono
parents:
diff changeset
989 #undef PUSH_TYPE
kono
parents:
diff changeset
990
kono
parents:
diff changeset
991 pvoid_type_node = build_pointer_type (void_type_node);
kono
parents:
diff changeset
992 prvoid_type_node = build_qualified_type (pvoid_type_node, TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
993 ppvoid_type_node = build_pointer_type (pvoid_type_node);
kono
parents:
diff changeset
994 pchar_type_node = build_pointer_type (gfc_character1_type_node);
kono
parents:
diff changeset
995 pfunc_type_node
kono
parents:
diff changeset
996 = build_pointer_type (build_function_type_list (void_type_node, NULL_TREE));
kono
parents:
diff changeset
997
kono
parents:
diff changeset
998 gfc_array_index_type = gfc_get_int_type (gfc_index_integer_kind);
kono
parents:
diff changeset
999 /* We cannot use gfc_index_zero_node in definition of gfc_array_range_type,
kono
parents:
diff changeset
1000 since this function is called before gfc_init_constants. */
kono
parents:
diff changeset
1001 gfc_array_range_type
kono
parents:
diff changeset
1002 = build_range_type (gfc_array_index_type,
kono
parents:
diff changeset
1003 build_int_cst (gfc_array_index_type, 0),
kono
parents:
diff changeset
1004 NULL_TREE);
kono
parents:
diff changeset
1005
kono
parents:
diff changeset
1006 /* The maximum array element size that can be handled is determined
kono
parents:
diff changeset
1007 by the number of bits available to store this field in the array
kono
parents:
diff changeset
1008 descriptor. */
kono
parents:
diff changeset
1009
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1010 n = TYPE_PRECISION (size_type_node);
111
kono
parents:
diff changeset
1011 gfc_max_array_element_size
kono
parents:
diff changeset
1012 = wide_int_to_tree (size_type_node,
kono
parents:
diff changeset
1013 wi::mask (n, UNSIGNED,
kono
parents:
diff changeset
1014 TYPE_PRECISION (size_type_node)));
kono
parents:
diff changeset
1015
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1016 logical_type_node = gfc_get_logical_type (gfc_default_logical_kind);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1017 logical_true_node = build_int_cst (logical_type_node, 1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1018 logical_false_node = build_int_cst (logical_type_node, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1019
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1020 /* Character lengths are of type size_t, except signed. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1021 gfc_charlen_int_kind = get_int_kind_from_node (size_type_node);
111
kono
parents:
diff changeset
1022 gfc_charlen_type_node = gfc_get_int_type (gfc_charlen_int_kind);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1023
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1024 /* Fortran kind number of size_type_node (size_t). This is used for
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1025 the _size member in vtables. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1026 gfc_size_kind = get_int_kind_from_node (size_type_node);
111
kono
parents:
diff changeset
1027 }
kono
parents:
diff changeset
1028
kono
parents:
diff changeset
1029 /* Get the type node for the given type and kind. */
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 tree
kono
parents:
diff changeset
1032 gfc_get_int_type (int kind)
kono
parents:
diff changeset
1033 {
kono
parents:
diff changeset
1034 int index = gfc_validate_kind (BT_INTEGER, kind, true);
kono
parents:
diff changeset
1035 return index < 0 ? 0 : gfc_integer_types[index];
kono
parents:
diff changeset
1036 }
kono
parents:
diff changeset
1037
kono
parents:
diff changeset
1038 tree
kono
parents:
diff changeset
1039 gfc_get_real_type (int kind)
kono
parents:
diff changeset
1040 {
kono
parents:
diff changeset
1041 int index = gfc_validate_kind (BT_REAL, kind, true);
kono
parents:
diff changeset
1042 return index < 0 ? 0 : gfc_real_types[index];
kono
parents:
diff changeset
1043 }
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045 tree
kono
parents:
diff changeset
1046 gfc_get_complex_type (int kind)
kono
parents:
diff changeset
1047 {
kono
parents:
diff changeset
1048 int index = gfc_validate_kind (BT_COMPLEX, kind, true);
kono
parents:
diff changeset
1049 return index < 0 ? 0 : gfc_complex_types[index];
kono
parents:
diff changeset
1050 }
kono
parents:
diff changeset
1051
kono
parents:
diff changeset
1052 tree
kono
parents:
diff changeset
1053 gfc_get_logical_type (int kind)
kono
parents:
diff changeset
1054 {
kono
parents:
diff changeset
1055 int index = gfc_validate_kind (BT_LOGICAL, kind, true);
kono
parents:
diff changeset
1056 return index < 0 ? 0 : gfc_logical_types[index];
kono
parents:
diff changeset
1057 }
kono
parents:
diff changeset
1058
kono
parents:
diff changeset
1059 tree
kono
parents:
diff changeset
1060 gfc_get_char_type (int kind)
kono
parents:
diff changeset
1061 {
kono
parents:
diff changeset
1062 int index = gfc_validate_kind (BT_CHARACTER, kind, true);
kono
parents:
diff changeset
1063 return index < 0 ? 0 : gfc_character_types[index];
kono
parents:
diff changeset
1064 }
kono
parents:
diff changeset
1065
kono
parents:
diff changeset
1066 tree
kono
parents:
diff changeset
1067 gfc_get_pchar_type (int kind)
kono
parents:
diff changeset
1068 {
kono
parents:
diff changeset
1069 int index = gfc_validate_kind (BT_CHARACTER, kind, true);
kono
parents:
diff changeset
1070 return index < 0 ? 0 : gfc_pcharacter_types[index];
kono
parents:
diff changeset
1071 }
kono
parents:
diff changeset
1072
kono
parents:
diff changeset
1073
kono
parents:
diff changeset
1074 /* Create a character type with the given kind and length. */
kono
parents:
diff changeset
1075
kono
parents:
diff changeset
1076 tree
kono
parents:
diff changeset
1077 gfc_get_character_type_len_for_eltype (tree eltype, tree len)
kono
parents:
diff changeset
1078 {
kono
parents:
diff changeset
1079 tree bounds, type;
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 bounds = build_range_type (gfc_charlen_type_node, gfc_index_one_node, len);
kono
parents:
diff changeset
1082 type = build_array_type (eltype, bounds);
kono
parents:
diff changeset
1083 TYPE_STRING_FLAG (type) = 1;
kono
parents:
diff changeset
1084
kono
parents:
diff changeset
1085 return type;
kono
parents:
diff changeset
1086 }
kono
parents:
diff changeset
1087
kono
parents:
diff changeset
1088 tree
kono
parents:
diff changeset
1089 gfc_get_character_type_len (int kind, tree len)
kono
parents:
diff changeset
1090 {
kono
parents:
diff changeset
1091 gfc_validate_kind (BT_CHARACTER, kind, false);
kono
parents:
diff changeset
1092 return gfc_get_character_type_len_for_eltype (gfc_get_char_type (kind), len);
kono
parents:
diff changeset
1093 }
kono
parents:
diff changeset
1094
kono
parents:
diff changeset
1095
kono
parents:
diff changeset
1096 /* Get a type node for a character kind. */
kono
parents:
diff changeset
1097
kono
parents:
diff changeset
1098 tree
kono
parents:
diff changeset
1099 gfc_get_character_type (int kind, gfc_charlen * cl)
kono
parents:
diff changeset
1100 {
kono
parents:
diff changeset
1101 tree len;
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 len = (cl == NULL) ? NULL_TREE : cl->backend_decl;
kono
parents:
diff changeset
1104 if (len && POINTER_TYPE_P (TREE_TYPE (len)))
kono
parents:
diff changeset
1105 len = build_fold_indirect_ref (len);
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 return gfc_get_character_type_len (kind, len);
kono
parents:
diff changeset
1108 }
kono
parents:
diff changeset
1109
kono
parents:
diff changeset
1110 /* Convert a basic type. This will be an array for character types. */
kono
parents:
diff changeset
1111
kono
parents:
diff changeset
1112 tree
kono
parents:
diff changeset
1113 gfc_typenode_for_spec (gfc_typespec * spec, int codim)
kono
parents:
diff changeset
1114 {
kono
parents:
diff changeset
1115 tree basetype;
kono
parents:
diff changeset
1116
kono
parents:
diff changeset
1117 switch (spec->type)
kono
parents:
diff changeset
1118 {
kono
parents:
diff changeset
1119 case BT_UNKNOWN:
kono
parents:
diff changeset
1120 gcc_unreachable ();
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 case BT_INTEGER:
kono
parents:
diff changeset
1123 /* We use INTEGER(c_intptr_t) for C_PTR and C_FUNPTR once the symbol
kono
parents:
diff changeset
1124 has been resolved. This is done so we can convert C_PTR and
kono
parents:
diff changeset
1125 C_FUNPTR to simple variables that get translated to (void *). */
kono
parents:
diff changeset
1126 if (spec->f90_type == BT_VOID)
kono
parents:
diff changeset
1127 {
kono
parents:
diff changeset
1128 if (spec->u.derived
kono
parents:
diff changeset
1129 && spec->u.derived->intmod_sym_id == ISOCBINDING_PTR)
kono
parents:
diff changeset
1130 basetype = ptr_type_node;
kono
parents:
diff changeset
1131 else
kono
parents:
diff changeset
1132 basetype = pfunc_type_node;
kono
parents:
diff changeset
1133 }
kono
parents:
diff changeset
1134 else
kono
parents:
diff changeset
1135 basetype = gfc_get_int_type (spec->kind);
kono
parents:
diff changeset
1136 break;
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 case BT_REAL:
kono
parents:
diff changeset
1139 basetype = gfc_get_real_type (spec->kind);
kono
parents:
diff changeset
1140 break;
kono
parents:
diff changeset
1141
kono
parents:
diff changeset
1142 case BT_COMPLEX:
kono
parents:
diff changeset
1143 basetype = gfc_get_complex_type (spec->kind);
kono
parents:
diff changeset
1144 break;
kono
parents:
diff changeset
1145
kono
parents:
diff changeset
1146 case BT_LOGICAL:
kono
parents:
diff changeset
1147 basetype = gfc_get_logical_type (spec->kind);
kono
parents:
diff changeset
1148 break;
kono
parents:
diff changeset
1149
kono
parents:
diff changeset
1150 case BT_CHARACTER:
kono
parents:
diff changeset
1151 basetype = gfc_get_character_type (spec->kind, spec->u.cl);
kono
parents:
diff changeset
1152 break;
kono
parents:
diff changeset
1153
kono
parents:
diff changeset
1154 case BT_HOLLERITH:
kono
parents:
diff changeset
1155 /* Since this cannot be used, return a length one character. */
kono
parents:
diff changeset
1156 basetype = gfc_get_character_type_len (gfc_default_character_kind,
kono
parents:
diff changeset
1157 gfc_index_one_node);
kono
parents:
diff changeset
1158 break;
kono
parents:
diff changeset
1159
kono
parents:
diff changeset
1160 case BT_UNION:
kono
parents:
diff changeset
1161 basetype = gfc_get_union_type (spec->u.derived);
kono
parents:
diff changeset
1162 break;
kono
parents:
diff changeset
1163
kono
parents:
diff changeset
1164 case BT_DERIVED:
kono
parents:
diff changeset
1165 case BT_CLASS:
kono
parents:
diff changeset
1166 basetype = gfc_get_derived_type (spec->u.derived, codim);
kono
parents:
diff changeset
1167
kono
parents:
diff changeset
1168 if (spec->type == BT_CLASS)
kono
parents:
diff changeset
1169 GFC_CLASS_TYPE_P (basetype) = 1;
kono
parents:
diff changeset
1170
kono
parents:
diff changeset
1171 /* If we're dealing with either C_PTR or C_FUNPTR, we modified the
kono
parents:
diff changeset
1172 type and kind to fit a (void *) and the basetype returned was a
kono
parents:
diff changeset
1173 ptr_type_node. We need to pass up this new information to the
kono
parents:
diff changeset
1174 symbol that was declared of type C_PTR or C_FUNPTR. */
kono
parents:
diff changeset
1175 if (spec->u.derived->ts.f90_type == BT_VOID)
kono
parents:
diff changeset
1176 {
kono
parents:
diff changeset
1177 spec->type = BT_INTEGER;
kono
parents:
diff changeset
1178 spec->kind = gfc_index_integer_kind;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 spec->f90_type = BT_VOID;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 spec->is_c_interop = 1; /* Mark as escaping later. */
111
kono
parents:
diff changeset
1181 }
kono
parents:
diff changeset
1182 break;
kono
parents:
diff changeset
1183 case BT_VOID:
kono
parents:
diff changeset
1184 case BT_ASSUMED:
kono
parents:
diff changeset
1185 /* This is for the second arg to c_f_pointer and c_f_procpointer
kono
parents:
diff changeset
1186 of the iso_c_binding module, to accept any ptr type. */
kono
parents:
diff changeset
1187 basetype = ptr_type_node;
kono
parents:
diff changeset
1188 if (spec->f90_type == BT_VOID)
kono
parents:
diff changeset
1189 {
kono
parents:
diff changeset
1190 if (spec->u.derived
kono
parents:
diff changeset
1191 && spec->u.derived->intmod_sym_id == ISOCBINDING_PTR)
kono
parents:
diff changeset
1192 basetype = ptr_type_node;
kono
parents:
diff changeset
1193 else
kono
parents:
diff changeset
1194 basetype = pfunc_type_node;
kono
parents:
diff changeset
1195 }
kono
parents:
diff changeset
1196 break;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1197 case BT_PROCEDURE:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1198 basetype = pfunc_type_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1199 break;
111
kono
parents:
diff changeset
1200 default:
kono
parents:
diff changeset
1201 gcc_unreachable ();
kono
parents:
diff changeset
1202 }
kono
parents:
diff changeset
1203 return basetype;
kono
parents:
diff changeset
1204 }
kono
parents:
diff changeset
1205
kono
parents:
diff changeset
1206 /* Build an INT_CST for constant expressions, otherwise return NULL_TREE. */
kono
parents:
diff changeset
1207
kono
parents:
diff changeset
1208 static tree
kono
parents:
diff changeset
1209 gfc_conv_array_bound (gfc_expr * expr)
kono
parents:
diff changeset
1210 {
kono
parents:
diff changeset
1211 /* If expr is an integer constant, return that. */
kono
parents:
diff changeset
1212 if (expr != NULL && expr->expr_type == EXPR_CONSTANT)
kono
parents:
diff changeset
1213 return gfc_conv_mpz_to_tree (expr->value.integer, gfc_index_integer_kind);
kono
parents:
diff changeset
1214
kono
parents:
diff changeset
1215 /* Otherwise return NULL. */
kono
parents:
diff changeset
1216 return NULL_TREE;
kono
parents:
diff changeset
1217 }
kono
parents:
diff changeset
1218
kono
parents:
diff changeset
1219 /* Return the type of an element of the array. Note that scalar coarrays
kono
parents:
diff changeset
1220 are special. In particular, for GFC_ARRAY_TYPE_P, the original argument
kono
parents:
diff changeset
1221 (with POINTER_TYPE stripped) is returned. */
kono
parents:
diff changeset
1222
kono
parents:
diff changeset
1223 tree
kono
parents:
diff changeset
1224 gfc_get_element_type (tree type)
kono
parents:
diff changeset
1225 {
kono
parents:
diff changeset
1226 tree element;
kono
parents:
diff changeset
1227
kono
parents:
diff changeset
1228 if (GFC_ARRAY_TYPE_P (type))
kono
parents:
diff changeset
1229 {
kono
parents:
diff changeset
1230 if (TREE_CODE (type) == POINTER_TYPE)
kono
parents:
diff changeset
1231 type = TREE_TYPE (type);
kono
parents:
diff changeset
1232 if (GFC_TYPE_ARRAY_RANK (type) == 0)
kono
parents:
diff changeset
1233 {
kono
parents:
diff changeset
1234 gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0);
kono
parents:
diff changeset
1235 element = type;
kono
parents:
diff changeset
1236 }
kono
parents:
diff changeset
1237 else
kono
parents:
diff changeset
1238 {
kono
parents:
diff changeset
1239 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
kono
parents:
diff changeset
1240 element = TREE_TYPE (type);
kono
parents:
diff changeset
1241 }
kono
parents:
diff changeset
1242 }
kono
parents:
diff changeset
1243 else
kono
parents:
diff changeset
1244 {
kono
parents:
diff changeset
1245 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
kono
parents:
diff changeset
1246 element = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
kono
parents:
diff changeset
1247
kono
parents:
diff changeset
1248 gcc_assert (TREE_CODE (element) == POINTER_TYPE);
kono
parents:
diff changeset
1249 element = TREE_TYPE (element);
kono
parents:
diff changeset
1250
kono
parents:
diff changeset
1251 /* For arrays, which are not scalar coarrays. */
kono
parents:
diff changeset
1252 if (TREE_CODE (element) == ARRAY_TYPE && !TYPE_STRING_FLAG (element))
kono
parents:
diff changeset
1253 element = TREE_TYPE (element);
kono
parents:
diff changeset
1254 }
kono
parents:
diff changeset
1255
kono
parents:
diff changeset
1256 return element;
kono
parents:
diff changeset
1257 }
kono
parents:
diff changeset
1258
kono
parents:
diff changeset
1259 /* Build an array. This function is called from gfc_sym_type().
kono
parents:
diff changeset
1260 Actually returns array descriptor type.
kono
parents:
diff changeset
1261
kono
parents:
diff changeset
1262 Format of array descriptors is as follows:
kono
parents:
diff changeset
1263
kono
parents:
diff changeset
1264 struct gfc_array_descriptor
kono
parents:
diff changeset
1265 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1266 array *data;
111
kono
parents:
diff changeset
1267 index offset;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1268 struct dtype_type dtype;
111
kono
parents:
diff changeset
1269 struct descriptor_dimension dimension[N_DIM];
kono
parents:
diff changeset
1270 }
kono
parents:
diff changeset
1271
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1272 struct dtype_type
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1273 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1274 size_t elem_len;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1275 int version;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1276 signed char rank;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1277 signed char type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1278 signed short attribute;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1279 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1280
111
kono
parents:
diff changeset
1281 struct descriptor_dimension
kono
parents:
diff changeset
1282 {
kono
parents:
diff changeset
1283 index stride;
kono
parents:
diff changeset
1284 index lbound;
kono
parents:
diff changeset
1285 index ubound;
kono
parents:
diff changeset
1286 }
kono
parents:
diff changeset
1287
kono
parents:
diff changeset
1288 Translation code should use gfc_conv_descriptor_* rather than
kono
parents:
diff changeset
1289 accessing the descriptor directly. Any changes to the array
kono
parents:
diff changeset
1290 descriptor type will require changes in gfc_conv_descriptor_* and
kono
parents:
diff changeset
1291 gfc_build_array_initializer.
kono
parents:
diff changeset
1292
kono
parents:
diff changeset
1293 This is represented internally as a RECORD_TYPE. The index nodes
kono
parents:
diff changeset
1294 are gfc_array_index_type and the data node is a pointer to the
kono
parents:
diff changeset
1295 data. See below for the handling of character types.
kono
parents:
diff changeset
1296
kono
parents:
diff changeset
1297 I originally used nested ARRAY_TYPE nodes to represent arrays, but
kono
parents:
diff changeset
1298 this generated poor code for assumed/deferred size arrays. These
kono
parents:
diff changeset
1299 require use of PLACEHOLDER_EXPR/WITH_RECORD_EXPR, which isn't part
kono
parents:
diff changeset
1300 of the GENERIC grammar. Also, there is no way to explicitly set
kono
parents:
diff changeset
1301 the array stride, so all data must be packed(1). I've tried to
kono
parents:
diff changeset
1302 mark all the functions which would require modification with a GCC
kono
parents:
diff changeset
1303 ARRAYS comment.
kono
parents:
diff changeset
1304
kono
parents:
diff changeset
1305 The data component points to the first element in the array. The
kono
parents:
diff changeset
1306 offset field is the position of the origin of the array (i.e. element
kono
parents:
diff changeset
1307 (0, 0 ...)). This may be outside the bounds of the array.
kono
parents:
diff changeset
1308
kono
parents:
diff changeset
1309 An element is accessed by
kono
parents:
diff changeset
1310 data[offset + index0*stride0 + index1*stride1 + index2*stride2]
kono
parents:
diff changeset
1311 This gives good performance as the computation does not involve the
kono
parents:
diff changeset
1312 bounds of the array. For packed arrays, this is optimized further
kono
parents:
diff changeset
1313 by substituting the known strides.
kono
parents:
diff changeset
1314
kono
parents:
diff changeset
1315 This system has one problem: all array bounds must be within 2^31
kono
parents:
diff changeset
1316 elements of the origin (2^63 on 64-bit machines). For example
kono
parents:
diff changeset
1317 integer, dimension (80000:90000, 80000:90000, 2) :: array
kono
parents:
diff changeset
1318 may not work properly on 32-bit machines because 80000*80000 >
kono
parents:
diff changeset
1319 2^31, so the calculation for stride2 would overflow. This may
kono
parents:
diff changeset
1320 still work, but I haven't checked, and it relies on the overflow
kono
parents:
diff changeset
1321 doing the right thing.
kono
parents:
diff changeset
1322
kono
parents:
diff changeset
1323 The way to fix this problem is to access elements as follows:
kono
parents:
diff changeset
1324 data[(index0-lbound0)*stride0 + (index1-lbound1)*stride1]
kono
parents:
diff changeset
1325 Obviously this is much slower. I will make this a compile time
kono
parents:
diff changeset
1326 option, something like -fsmall-array-offsets. Mixing code compiled
kono
parents:
diff changeset
1327 with and without this switch will work.
kono
parents:
diff changeset
1328
kono
parents:
diff changeset
1329 (1) This can be worked around by modifying the upper bound of the
kono
parents:
diff changeset
1330 previous dimension. This requires extra fields in the descriptor
kono
parents:
diff changeset
1331 (both real_ubound and fake_ubound). */
kono
parents:
diff changeset
1332
kono
parents:
diff changeset
1333
kono
parents:
diff changeset
1334 /* Returns true if the array sym does not require a descriptor. */
kono
parents:
diff changeset
1335
kono
parents:
diff changeset
1336 int
kono
parents:
diff changeset
1337 gfc_is_nodesc_array (gfc_symbol * sym)
kono
parents:
diff changeset
1338 {
kono
parents:
diff changeset
1339 symbol_attribute *array_attr;
kono
parents:
diff changeset
1340 gfc_array_spec *as;
kono
parents:
diff changeset
1341 bool is_classarray = IS_CLASS_ARRAY (sym);
kono
parents:
diff changeset
1342
kono
parents:
diff changeset
1343 array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
kono
parents:
diff changeset
1344 as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 gcc_assert (array_attr->dimension || array_attr->codimension);
kono
parents:
diff changeset
1347
kono
parents:
diff changeset
1348 /* We only want local arrays. */
kono
parents:
diff changeset
1349 if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
kono
parents:
diff changeset
1350 || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
kono
parents:
diff changeset
1351 || array_attr->allocatable)
kono
parents:
diff changeset
1352 return 0;
kono
parents:
diff changeset
1353
kono
parents:
diff changeset
1354 /* We want a descriptor for associate-name arrays that do not have an
kono
parents:
diff changeset
1355 explicitly known shape already. */
kono
parents:
diff changeset
1356 if (sym->assoc && as->type != AS_EXPLICIT)
kono
parents:
diff changeset
1357 return 0;
kono
parents:
diff changeset
1358
kono
parents:
diff changeset
1359 /* The dummy is stored in sym and not in the component. */
kono
parents:
diff changeset
1360 if (sym->attr.dummy)
kono
parents:
diff changeset
1361 return as->type != AS_ASSUMED_SHAPE
kono
parents:
diff changeset
1362 && as->type != AS_ASSUMED_RANK;
kono
parents:
diff changeset
1363
kono
parents:
diff changeset
1364 if (sym->attr.result || sym->attr.function)
kono
parents:
diff changeset
1365 return 0;
kono
parents:
diff changeset
1366
kono
parents:
diff changeset
1367 gcc_assert (as->type == AS_EXPLICIT || as->cp_was_assumed);
kono
parents:
diff changeset
1368
kono
parents:
diff changeset
1369 return 1;
kono
parents:
diff changeset
1370 }
kono
parents:
diff changeset
1371
kono
parents:
diff changeset
1372
kono
parents:
diff changeset
1373 /* Create an array descriptor type. */
kono
parents:
diff changeset
1374
kono
parents:
diff changeset
1375 static tree
kono
parents:
diff changeset
1376 gfc_build_array_type (tree type, gfc_array_spec * as,
kono
parents:
diff changeset
1377 enum gfc_array_kind akind, bool restricted,
kono
parents:
diff changeset
1378 bool contiguous, int codim)
kono
parents:
diff changeset
1379 {
kono
parents:
diff changeset
1380 tree lbound[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
1381 tree ubound[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
1382 int n, corank;
kono
parents:
diff changeset
1383
kono
parents:
diff changeset
1384 /* Assumed-shape arrays do not have codimension information stored in the
kono
parents:
diff changeset
1385 descriptor. */
kono
parents:
diff changeset
1386 corank = MAX (as->corank, codim);
kono
parents:
diff changeset
1387 if (as->type == AS_ASSUMED_SHAPE ||
kono
parents:
diff changeset
1388 (as->type == AS_ASSUMED_RANK && akind == GFC_ARRAY_ALLOCATABLE))
kono
parents:
diff changeset
1389 corank = codim;
kono
parents:
diff changeset
1390
kono
parents:
diff changeset
1391 if (as->type == AS_ASSUMED_RANK)
kono
parents:
diff changeset
1392 for (n = 0; n < GFC_MAX_DIMENSIONS; n++)
kono
parents:
diff changeset
1393 {
kono
parents:
diff changeset
1394 lbound[n] = NULL_TREE;
kono
parents:
diff changeset
1395 ubound[n] = NULL_TREE;
kono
parents:
diff changeset
1396 }
kono
parents:
diff changeset
1397
kono
parents:
diff changeset
1398 for (n = 0; n < as->rank; n++)
kono
parents:
diff changeset
1399 {
kono
parents:
diff changeset
1400 /* Create expressions for the known bounds of the array. */
kono
parents:
diff changeset
1401 if (as->type == AS_ASSUMED_SHAPE && as->lower[n] == NULL)
kono
parents:
diff changeset
1402 lbound[n] = gfc_index_one_node;
kono
parents:
diff changeset
1403 else
kono
parents:
diff changeset
1404 lbound[n] = gfc_conv_array_bound (as->lower[n]);
kono
parents:
diff changeset
1405 ubound[n] = gfc_conv_array_bound (as->upper[n]);
kono
parents:
diff changeset
1406 }
kono
parents:
diff changeset
1407
kono
parents:
diff changeset
1408 for (n = as->rank; n < as->rank + corank; n++)
kono
parents:
diff changeset
1409 {
kono
parents:
diff changeset
1410 if (as->type != AS_DEFERRED && as->lower[n] == NULL)
kono
parents:
diff changeset
1411 lbound[n] = gfc_index_one_node;
kono
parents:
diff changeset
1412 else
kono
parents:
diff changeset
1413 lbound[n] = gfc_conv_array_bound (as->lower[n]);
kono
parents:
diff changeset
1414
kono
parents:
diff changeset
1415 if (n < as->rank + corank - 1)
kono
parents:
diff changeset
1416 ubound[n] = gfc_conv_array_bound (as->upper[n]);
kono
parents:
diff changeset
1417 }
kono
parents:
diff changeset
1418
kono
parents:
diff changeset
1419 if (as->type == AS_ASSUMED_SHAPE)
kono
parents:
diff changeset
1420 akind = contiguous ? GFC_ARRAY_ASSUMED_SHAPE_CONT
kono
parents:
diff changeset
1421 : GFC_ARRAY_ASSUMED_SHAPE;
kono
parents:
diff changeset
1422 else if (as->type == AS_ASSUMED_RANK)
kono
parents:
diff changeset
1423 akind = contiguous ? GFC_ARRAY_ASSUMED_RANK_CONT
kono
parents:
diff changeset
1424 : GFC_ARRAY_ASSUMED_RANK;
kono
parents:
diff changeset
1425 return gfc_get_array_type_bounds (type, as->rank == -1
kono
parents:
diff changeset
1426 ? GFC_MAX_DIMENSIONS : as->rank,
kono
parents:
diff changeset
1427 corank, lbound, ubound, 0, akind,
kono
parents:
diff changeset
1428 restricted);
kono
parents:
diff changeset
1429 }
kono
parents:
diff changeset
1430
kono
parents:
diff changeset
1431 /* Returns the struct descriptor_dimension type. */
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 static tree
kono
parents:
diff changeset
1434 gfc_get_desc_dim_type (void)
kono
parents:
diff changeset
1435 {
kono
parents:
diff changeset
1436 tree type;
kono
parents:
diff changeset
1437 tree decl, *chain = NULL;
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 if (gfc_desc_dim_type)
kono
parents:
diff changeset
1440 return gfc_desc_dim_type;
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 /* Build the type node. */
kono
parents:
diff changeset
1443 type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
1444
kono
parents:
diff changeset
1445 TYPE_NAME (type) = get_identifier ("descriptor_dimension");
kono
parents:
diff changeset
1446 TYPE_PACKED (type) = 1;
kono
parents:
diff changeset
1447
kono
parents:
diff changeset
1448 /* Consists of the stride, lbound and ubound members. */
kono
parents:
diff changeset
1449 decl = gfc_add_field_to_struct_1 (type,
kono
parents:
diff changeset
1450 get_identifier ("stride"),
kono
parents:
diff changeset
1451 gfc_array_index_type, &chain);
kono
parents:
diff changeset
1452 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1453
kono
parents:
diff changeset
1454 decl = gfc_add_field_to_struct_1 (type,
kono
parents:
diff changeset
1455 get_identifier ("lbound"),
kono
parents:
diff changeset
1456 gfc_array_index_type, &chain);
kono
parents:
diff changeset
1457 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1458
kono
parents:
diff changeset
1459 decl = gfc_add_field_to_struct_1 (type,
kono
parents:
diff changeset
1460 get_identifier ("ubound"),
kono
parents:
diff changeset
1461 gfc_array_index_type, &chain);
kono
parents:
diff changeset
1462 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1463
kono
parents:
diff changeset
1464 /* Finish off the type. */
kono
parents:
diff changeset
1465 gfc_finish_type (type);
kono
parents:
diff changeset
1466 TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) = 1;
kono
parents:
diff changeset
1467
kono
parents:
diff changeset
1468 gfc_desc_dim_type = type;
kono
parents:
diff changeset
1469 return type;
kono
parents:
diff changeset
1470 }
kono
parents:
diff changeset
1471
kono
parents:
diff changeset
1472
kono
parents:
diff changeset
1473 /* Return the DTYPE for an array. This describes the type and type parameters
kono
parents:
diff changeset
1474 of the array. */
kono
parents:
diff changeset
1475 /* TODO: Only call this when the value is actually used, and make all the
kono
parents:
diff changeset
1476 unknown cases abort. */
kono
parents:
diff changeset
1477
kono
parents:
diff changeset
1478 tree
kono
parents:
diff changeset
1479 gfc_get_dtype_rank_type (int rank, tree etype)
kono
parents:
diff changeset
1480 {
kono
parents:
diff changeset
1481 tree size;
kono
parents:
diff changeset
1482 int n;
kono
parents:
diff changeset
1483 tree tmp;
kono
parents:
diff changeset
1484 tree dtype;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1485 tree field;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1486 vec<constructor_elt, va_gc> *v = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1487
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1488 size = TYPE_SIZE_UNIT (etype);
111
kono
parents:
diff changeset
1489
kono
parents:
diff changeset
1490 switch (TREE_CODE (etype))
kono
parents:
diff changeset
1491 {
kono
parents:
diff changeset
1492 case INTEGER_TYPE:
kono
parents:
diff changeset
1493 n = BT_INTEGER;
kono
parents:
diff changeset
1494 break;
kono
parents:
diff changeset
1495
kono
parents:
diff changeset
1496 case BOOLEAN_TYPE:
kono
parents:
diff changeset
1497 n = BT_LOGICAL;
kono
parents:
diff changeset
1498 break;
kono
parents:
diff changeset
1499
kono
parents:
diff changeset
1500 case REAL_TYPE:
kono
parents:
diff changeset
1501 n = BT_REAL;
kono
parents:
diff changeset
1502 break;
kono
parents:
diff changeset
1503
kono
parents:
diff changeset
1504 case COMPLEX_TYPE:
kono
parents:
diff changeset
1505 n = BT_COMPLEX;
kono
parents:
diff changeset
1506 break;
kono
parents:
diff changeset
1507
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1508 case RECORD_TYPE:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1509 if (GFC_CLASS_TYPE_P (etype))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1510 n = BT_CLASS;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1511 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1512 n = BT_DERIVED;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1513 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1514
111
kono
parents:
diff changeset
1515 /* We will never have arrays of arrays. */
kono
parents:
diff changeset
1516 case ARRAY_TYPE:
kono
parents:
diff changeset
1517 n = BT_CHARACTER;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1518 if (size == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1519 size = TYPE_SIZE_UNIT (TREE_TYPE (etype));
111
kono
parents:
diff changeset
1520 break;
kono
parents:
diff changeset
1521
kono
parents:
diff changeset
1522 case POINTER_TYPE:
kono
parents:
diff changeset
1523 n = BT_ASSUMED;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1524 if (TREE_CODE (TREE_TYPE (etype)) != VOID_TYPE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1525 size = TYPE_SIZE_UNIT (TREE_TYPE (etype));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1526 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1527 size = build_int_cst (size_type_node, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1528 break;
111
kono
parents:
diff changeset
1529
kono
parents:
diff changeset
1530 default:
kono
parents:
diff changeset
1531 /* TODO: Don't do dtype for temporary descriptorless arrays. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1532 /* We can encounter strange array types for temporary arrays. */
111
kono
parents:
diff changeset
1533 return gfc_index_zero_node;
kono
parents:
diff changeset
1534 }
kono
parents:
diff changeset
1535
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1536 tmp = get_dtype_type_node ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1537 field = gfc_advance_chain (TYPE_FIELDS (tmp),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1538 GFC_DTYPE_ELEM_LEN);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1539 CONSTRUCTOR_APPEND_ELT (v, field,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1540 fold_convert (TREE_TYPE (field), size));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1541
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1542 field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1543 GFC_DTYPE_RANK);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1544 CONSTRUCTOR_APPEND_ELT (v, field,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1545 build_int_cst (TREE_TYPE (field), rank));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1546
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1547 field = gfc_advance_chain (TYPE_FIELDS (dtype_type_node),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1548 GFC_DTYPE_TYPE);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1549 CONSTRUCTOR_APPEND_ELT (v, field,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1550 build_int_cst (TREE_TYPE (field), n));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1551
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1552 dtype = build_constructor (tmp, v);
111
kono
parents:
diff changeset
1553
kono
parents:
diff changeset
1554 return dtype;
kono
parents:
diff changeset
1555 }
kono
parents:
diff changeset
1556
kono
parents:
diff changeset
1557
kono
parents:
diff changeset
1558 tree
kono
parents:
diff changeset
1559 gfc_get_dtype (tree type)
kono
parents:
diff changeset
1560 {
kono
parents:
diff changeset
1561 tree dtype;
kono
parents:
diff changeset
1562 tree etype;
kono
parents:
diff changeset
1563 int rank;
kono
parents:
diff changeset
1564
kono
parents:
diff changeset
1565 gcc_assert (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type));
kono
parents:
diff changeset
1566
kono
parents:
diff changeset
1567 rank = GFC_TYPE_ARRAY_RANK (type);
kono
parents:
diff changeset
1568 etype = gfc_get_element_type (type);
kono
parents:
diff changeset
1569 dtype = gfc_get_dtype_rank_type (rank, etype);
kono
parents:
diff changeset
1570
kono
parents:
diff changeset
1571 GFC_TYPE_ARRAY_DTYPE (type) = dtype;
kono
parents:
diff changeset
1572 return dtype;
kono
parents:
diff changeset
1573 }
kono
parents:
diff changeset
1574
kono
parents:
diff changeset
1575
kono
parents:
diff changeset
1576 /* Build an array type for use without a descriptor, packed according
kono
parents:
diff changeset
1577 to the value of PACKED. */
kono
parents:
diff changeset
1578
kono
parents:
diff changeset
1579 tree
kono
parents:
diff changeset
1580 gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
kono
parents:
diff changeset
1581 bool restricted)
kono
parents:
diff changeset
1582 {
kono
parents:
diff changeset
1583 tree range;
kono
parents:
diff changeset
1584 tree type;
kono
parents:
diff changeset
1585 tree tmp;
kono
parents:
diff changeset
1586 int n;
kono
parents:
diff changeset
1587 int known_stride;
kono
parents:
diff changeset
1588 int known_offset;
kono
parents:
diff changeset
1589 mpz_t offset;
kono
parents:
diff changeset
1590 mpz_t stride;
kono
parents:
diff changeset
1591 mpz_t delta;
kono
parents:
diff changeset
1592 gfc_expr *expr;
kono
parents:
diff changeset
1593
kono
parents:
diff changeset
1594 mpz_init_set_ui (offset, 0);
kono
parents:
diff changeset
1595 mpz_init_set_ui (stride, 1);
kono
parents:
diff changeset
1596 mpz_init (delta);
kono
parents:
diff changeset
1597
kono
parents:
diff changeset
1598 /* We don't use build_array_type because this does not include include
kono
parents:
diff changeset
1599 lang-specific information (i.e. the bounds of the array) when checking
kono
parents:
diff changeset
1600 for duplicates. */
kono
parents:
diff changeset
1601 if (as->rank)
kono
parents:
diff changeset
1602 type = make_node (ARRAY_TYPE);
kono
parents:
diff changeset
1603 else
kono
parents:
diff changeset
1604 type = build_variant_type_copy (etype);
kono
parents:
diff changeset
1605
kono
parents:
diff changeset
1606 GFC_ARRAY_TYPE_P (type) = 1;
kono
parents:
diff changeset
1607 TYPE_LANG_SPECIFIC (type) = ggc_cleared_alloc<struct lang_type> ();
kono
parents:
diff changeset
1608
kono
parents:
diff changeset
1609 known_stride = (packed != PACKED_NO);
kono
parents:
diff changeset
1610 known_offset = 1;
kono
parents:
diff changeset
1611 for (n = 0; n < as->rank; n++)
kono
parents:
diff changeset
1612 {
kono
parents:
diff changeset
1613 /* Fill in the stride and bound components of the type. */
kono
parents:
diff changeset
1614 if (known_stride)
kono
parents:
diff changeset
1615 tmp = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
kono
parents:
diff changeset
1616 else
kono
parents:
diff changeset
1617 tmp = NULL_TREE;
kono
parents:
diff changeset
1618 GFC_TYPE_ARRAY_STRIDE (type, n) = tmp;
kono
parents:
diff changeset
1619
kono
parents:
diff changeset
1620 expr = as->lower[n];
kono
parents:
diff changeset
1621 if (expr->expr_type == EXPR_CONSTANT)
kono
parents:
diff changeset
1622 {
kono
parents:
diff changeset
1623 tmp = gfc_conv_mpz_to_tree (expr->value.integer,
kono
parents:
diff changeset
1624 gfc_index_integer_kind);
kono
parents:
diff changeset
1625 }
kono
parents:
diff changeset
1626 else
kono
parents:
diff changeset
1627 {
kono
parents:
diff changeset
1628 known_stride = 0;
kono
parents:
diff changeset
1629 tmp = NULL_TREE;
kono
parents:
diff changeset
1630 }
kono
parents:
diff changeset
1631 GFC_TYPE_ARRAY_LBOUND (type, n) = tmp;
kono
parents:
diff changeset
1632
kono
parents:
diff changeset
1633 if (known_stride)
kono
parents:
diff changeset
1634 {
kono
parents:
diff changeset
1635 /* Calculate the offset. */
kono
parents:
diff changeset
1636 mpz_mul (delta, stride, as->lower[n]->value.integer);
kono
parents:
diff changeset
1637 mpz_sub (offset, offset, delta);
kono
parents:
diff changeset
1638 }
kono
parents:
diff changeset
1639 else
kono
parents:
diff changeset
1640 known_offset = 0;
kono
parents:
diff changeset
1641
kono
parents:
diff changeset
1642 expr = as->upper[n];
kono
parents:
diff changeset
1643 if (expr && expr->expr_type == EXPR_CONSTANT)
kono
parents:
diff changeset
1644 {
kono
parents:
diff changeset
1645 tmp = gfc_conv_mpz_to_tree (expr->value.integer,
kono
parents:
diff changeset
1646 gfc_index_integer_kind);
kono
parents:
diff changeset
1647 }
kono
parents:
diff changeset
1648 else
kono
parents:
diff changeset
1649 {
kono
parents:
diff changeset
1650 tmp = NULL_TREE;
kono
parents:
diff changeset
1651 known_stride = 0;
kono
parents:
diff changeset
1652 }
kono
parents:
diff changeset
1653 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
kono
parents:
diff changeset
1654
kono
parents:
diff changeset
1655 if (known_stride)
kono
parents:
diff changeset
1656 {
kono
parents:
diff changeset
1657 /* Calculate the stride. */
kono
parents:
diff changeset
1658 mpz_sub (delta, as->upper[n]->value.integer,
kono
parents:
diff changeset
1659 as->lower[n]->value.integer);
kono
parents:
diff changeset
1660 mpz_add_ui (delta, delta, 1);
kono
parents:
diff changeset
1661 mpz_mul (stride, stride, delta);
kono
parents:
diff changeset
1662 }
kono
parents:
diff changeset
1663
kono
parents:
diff changeset
1664 /* Only the first stride is known for partial packed arrays. */
kono
parents:
diff changeset
1665 if (packed == PACKED_NO || packed == PACKED_PARTIAL)
kono
parents:
diff changeset
1666 known_stride = 0;
kono
parents:
diff changeset
1667 }
kono
parents:
diff changeset
1668 for (n = as->rank; n < as->rank + as->corank; n++)
kono
parents:
diff changeset
1669 {
kono
parents:
diff changeset
1670 expr = as->lower[n];
kono
parents:
diff changeset
1671 if (expr->expr_type == EXPR_CONSTANT)
kono
parents:
diff changeset
1672 tmp = gfc_conv_mpz_to_tree (expr->value.integer,
kono
parents:
diff changeset
1673 gfc_index_integer_kind);
kono
parents:
diff changeset
1674 else
kono
parents:
diff changeset
1675 tmp = NULL_TREE;
kono
parents:
diff changeset
1676 GFC_TYPE_ARRAY_LBOUND (type, n) = tmp;
kono
parents:
diff changeset
1677
kono
parents:
diff changeset
1678 expr = as->upper[n];
kono
parents:
diff changeset
1679 if (expr && expr->expr_type == EXPR_CONSTANT)
kono
parents:
diff changeset
1680 tmp = gfc_conv_mpz_to_tree (expr->value.integer,
kono
parents:
diff changeset
1681 gfc_index_integer_kind);
kono
parents:
diff changeset
1682 else
kono
parents:
diff changeset
1683 tmp = NULL_TREE;
kono
parents:
diff changeset
1684 if (n < as->rank + as->corank - 1)
kono
parents:
diff changeset
1685 GFC_TYPE_ARRAY_UBOUND (type, n) = tmp;
kono
parents:
diff changeset
1686 }
kono
parents:
diff changeset
1687
kono
parents:
diff changeset
1688 if (known_offset)
kono
parents:
diff changeset
1689 {
kono
parents:
diff changeset
1690 GFC_TYPE_ARRAY_OFFSET (type) =
kono
parents:
diff changeset
1691 gfc_conv_mpz_to_tree (offset, gfc_index_integer_kind);
kono
parents:
diff changeset
1692 }
kono
parents:
diff changeset
1693 else
kono
parents:
diff changeset
1694 GFC_TYPE_ARRAY_OFFSET (type) = NULL_TREE;
kono
parents:
diff changeset
1695
kono
parents:
diff changeset
1696 if (known_stride)
kono
parents:
diff changeset
1697 {
kono
parents:
diff changeset
1698 GFC_TYPE_ARRAY_SIZE (type) =
kono
parents:
diff changeset
1699 gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
kono
parents:
diff changeset
1700 }
kono
parents:
diff changeset
1701 else
kono
parents:
diff changeset
1702 GFC_TYPE_ARRAY_SIZE (type) = NULL_TREE;
kono
parents:
diff changeset
1703
kono
parents:
diff changeset
1704 GFC_TYPE_ARRAY_RANK (type) = as->rank;
kono
parents:
diff changeset
1705 GFC_TYPE_ARRAY_CORANK (type) = as->corank;
kono
parents:
diff changeset
1706 GFC_TYPE_ARRAY_DTYPE (type) = NULL_TREE;
kono
parents:
diff changeset
1707 range = build_range_type (gfc_array_index_type, gfc_index_zero_node,
kono
parents:
diff changeset
1708 NULL_TREE);
kono
parents:
diff changeset
1709 /* TODO: use main type if it is unbounded. */
kono
parents:
diff changeset
1710 GFC_TYPE_ARRAY_DATAPTR_TYPE (type) =
kono
parents:
diff changeset
1711 build_pointer_type (build_array_type (etype, range));
kono
parents:
diff changeset
1712 if (restricted)
kono
parents:
diff changeset
1713 GFC_TYPE_ARRAY_DATAPTR_TYPE (type) =
kono
parents:
diff changeset
1714 build_qualified_type (GFC_TYPE_ARRAY_DATAPTR_TYPE (type),
kono
parents:
diff changeset
1715 TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
1716
kono
parents:
diff changeset
1717 if (as->rank == 0)
kono
parents:
diff changeset
1718 {
kono
parents:
diff changeset
1719 if (packed != PACKED_STATIC || flag_coarray == GFC_FCOARRAY_LIB)
kono
parents:
diff changeset
1720 {
kono
parents:
diff changeset
1721 type = build_pointer_type (type);
kono
parents:
diff changeset
1722
kono
parents:
diff changeset
1723 if (restricted)
kono
parents:
diff changeset
1724 type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
1725
kono
parents:
diff changeset
1726 GFC_ARRAY_TYPE_P (type) = 1;
kono
parents:
diff changeset
1727 TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type));
kono
parents:
diff changeset
1728 }
kono
parents:
diff changeset
1729
kono
parents:
diff changeset
1730 return type;
kono
parents:
diff changeset
1731 }
kono
parents:
diff changeset
1732
kono
parents:
diff changeset
1733 if (known_stride)
kono
parents:
diff changeset
1734 {
kono
parents:
diff changeset
1735 mpz_sub_ui (stride, stride, 1);
kono
parents:
diff changeset
1736 range = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind);
kono
parents:
diff changeset
1737 }
kono
parents:
diff changeset
1738 else
kono
parents:
diff changeset
1739 range = NULL_TREE;
kono
parents:
diff changeset
1740
kono
parents:
diff changeset
1741 range = build_range_type (gfc_array_index_type, gfc_index_zero_node, range);
kono
parents:
diff changeset
1742 TYPE_DOMAIN (type) = range;
kono
parents:
diff changeset
1743
kono
parents:
diff changeset
1744 build_pointer_type (etype);
kono
parents:
diff changeset
1745 TREE_TYPE (type) = etype;
kono
parents:
diff changeset
1746
kono
parents:
diff changeset
1747 layout_type (type);
kono
parents:
diff changeset
1748
kono
parents:
diff changeset
1749 mpz_clear (offset);
kono
parents:
diff changeset
1750 mpz_clear (stride);
kono
parents:
diff changeset
1751 mpz_clear (delta);
kono
parents:
diff changeset
1752
kono
parents:
diff changeset
1753 /* Represent packed arrays as multi-dimensional if they have rank >
kono
parents:
diff changeset
1754 1 and with proper bounds, instead of flat arrays. This makes for
kono
parents:
diff changeset
1755 better debug info. */
kono
parents:
diff changeset
1756 if (known_offset)
kono
parents:
diff changeset
1757 {
kono
parents:
diff changeset
1758 tree gtype = etype, rtype, type_decl;
kono
parents:
diff changeset
1759
kono
parents:
diff changeset
1760 for (n = as->rank - 1; n >= 0; n--)
kono
parents:
diff changeset
1761 {
kono
parents:
diff changeset
1762 rtype = build_range_type (gfc_array_index_type,
kono
parents:
diff changeset
1763 GFC_TYPE_ARRAY_LBOUND (type, n),
kono
parents:
diff changeset
1764 GFC_TYPE_ARRAY_UBOUND (type, n));
kono
parents:
diff changeset
1765 gtype = build_array_type (gtype, rtype);
kono
parents:
diff changeset
1766 }
kono
parents:
diff changeset
1767 TYPE_NAME (type) = type_decl = build_decl (input_location,
kono
parents:
diff changeset
1768 TYPE_DECL, NULL, gtype);
kono
parents:
diff changeset
1769 DECL_ORIGINAL_TYPE (type_decl) = gtype;
kono
parents:
diff changeset
1770 }
kono
parents:
diff changeset
1771
kono
parents:
diff changeset
1772 if (packed != PACKED_STATIC || !known_stride
kono
parents:
diff changeset
1773 || (as->corank && flag_coarray == GFC_FCOARRAY_LIB))
kono
parents:
diff changeset
1774 {
kono
parents:
diff changeset
1775 /* For dummy arrays and automatic (heap allocated) arrays we
kono
parents:
diff changeset
1776 want a pointer to the array. */
kono
parents:
diff changeset
1777 type = build_pointer_type (type);
kono
parents:
diff changeset
1778 if (restricted)
kono
parents:
diff changeset
1779 type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
1780 GFC_ARRAY_TYPE_P (type) = 1;
kono
parents:
diff changeset
1781 TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type));
kono
parents:
diff changeset
1782 }
kono
parents:
diff changeset
1783 return type;
kono
parents:
diff changeset
1784 }
kono
parents:
diff changeset
1785
kono
parents:
diff changeset
1786
kono
parents:
diff changeset
1787 /* Return or create the base type for an array descriptor. */
kono
parents:
diff changeset
1788
kono
parents:
diff changeset
1789 static tree
kono
parents:
diff changeset
1790 gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted)
kono
parents:
diff changeset
1791 {
kono
parents:
diff changeset
1792 tree fat_type, decl, arraytype, *chain = NULL;
kono
parents:
diff changeset
1793 char name[16 + 2*GFC_RANK_DIGITS + 1 + 1];
kono
parents:
diff changeset
1794 int idx;
kono
parents:
diff changeset
1795
kono
parents:
diff changeset
1796 /* Assumed-rank array. */
kono
parents:
diff changeset
1797 if (dimen == -1)
kono
parents:
diff changeset
1798 dimen = GFC_MAX_DIMENSIONS;
kono
parents:
diff changeset
1799
kono
parents:
diff changeset
1800 idx = 2 * (codimen + dimen) + restricted;
kono
parents:
diff changeset
1801
kono
parents:
diff changeset
1802 gcc_assert (codimen + dimen >= 0 && codimen + dimen <= GFC_MAX_DIMENSIONS);
kono
parents:
diff changeset
1803
kono
parents:
diff changeset
1804 if (flag_coarray == GFC_FCOARRAY_LIB && codimen)
kono
parents:
diff changeset
1805 {
kono
parents:
diff changeset
1806 if (gfc_array_descriptor_base_caf[idx])
kono
parents:
diff changeset
1807 return gfc_array_descriptor_base_caf[idx];
kono
parents:
diff changeset
1808 }
kono
parents:
diff changeset
1809 else if (gfc_array_descriptor_base[idx])
kono
parents:
diff changeset
1810 return gfc_array_descriptor_base[idx];
kono
parents:
diff changeset
1811
kono
parents:
diff changeset
1812 /* Build the type node. */
kono
parents:
diff changeset
1813 fat_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
1814
kono
parents:
diff changeset
1815 sprintf (name, "array_descriptor" GFC_RANK_PRINTF_FORMAT, dimen + codimen);
kono
parents:
diff changeset
1816 TYPE_NAME (fat_type) = get_identifier (name);
kono
parents:
diff changeset
1817 TYPE_NAMELESS (fat_type) = 1;
kono
parents:
diff changeset
1818
kono
parents:
diff changeset
1819 /* Add the data member as the first element of the descriptor. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1820 gfc_add_field_to_struct_1 (fat_type,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1821 get_identifier ("data"),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1822 (restricted
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1823 ? prvoid_type_node
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1824 : ptr_type_node), &chain);
111
kono
parents:
diff changeset
1825
kono
parents:
diff changeset
1826 /* Add the base component. */
kono
parents:
diff changeset
1827 decl = gfc_add_field_to_struct_1 (fat_type,
kono
parents:
diff changeset
1828 get_identifier ("offset"),
kono
parents:
diff changeset
1829 gfc_array_index_type, &chain);
kono
parents:
diff changeset
1830 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 /* Add the dtype component. */
kono
parents:
diff changeset
1833 decl = gfc_add_field_to_struct_1 (fat_type,
kono
parents:
diff changeset
1834 get_identifier ("dtype"),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1835 get_dtype_type_node (), &chain);
111
kono
parents:
diff changeset
1836 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1837
kono
parents:
diff changeset
1838 /* Add the span component. */
kono
parents:
diff changeset
1839 decl = gfc_add_field_to_struct_1 (fat_type,
kono
parents:
diff changeset
1840 get_identifier ("span"),
kono
parents:
diff changeset
1841 gfc_array_index_type, &chain);
kono
parents:
diff changeset
1842 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1843
kono
parents:
diff changeset
1844 /* Build the array type for the stride and bound components. */
kono
parents:
diff changeset
1845 if (dimen + codimen > 0)
kono
parents:
diff changeset
1846 {
kono
parents:
diff changeset
1847 arraytype =
kono
parents:
diff changeset
1848 build_array_type (gfc_get_desc_dim_type (),
kono
parents:
diff changeset
1849 build_range_type (gfc_array_index_type,
kono
parents:
diff changeset
1850 gfc_index_zero_node,
kono
parents:
diff changeset
1851 gfc_rank_cst[codimen + dimen - 1]));
kono
parents:
diff changeset
1852
kono
parents:
diff changeset
1853 decl = gfc_add_field_to_struct_1 (fat_type, get_identifier ("dim"),
kono
parents:
diff changeset
1854 arraytype, &chain);
kono
parents:
diff changeset
1855 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1856 }
kono
parents:
diff changeset
1857
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1858 if (flag_coarray == GFC_FCOARRAY_LIB)
111
kono
parents:
diff changeset
1859 {
kono
parents:
diff changeset
1860 decl = gfc_add_field_to_struct_1 (fat_type,
kono
parents:
diff changeset
1861 get_identifier ("token"),
kono
parents:
diff changeset
1862 prvoid_type_node, &chain);
kono
parents:
diff changeset
1863 TREE_NO_WARNING (decl) = 1;
kono
parents:
diff changeset
1864 }
kono
parents:
diff changeset
1865
kono
parents:
diff changeset
1866 /* Finish off the type. */
kono
parents:
diff changeset
1867 gfc_finish_type (fat_type);
kono
parents:
diff changeset
1868 TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (fat_type)) = 1;
kono
parents:
diff changeset
1869
kono
parents:
diff changeset
1870 if (flag_coarray == GFC_FCOARRAY_LIB && codimen)
kono
parents:
diff changeset
1871 gfc_array_descriptor_base_caf[idx] = fat_type;
kono
parents:
diff changeset
1872 else
kono
parents:
diff changeset
1873 gfc_array_descriptor_base[idx] = fat_type;
kono
parents:
diff changeset
1874
kono
parents:
diff changeset
1875 return fat_type;
kono
parents:
diff changeset
1876 }
kono
parents:
diff changeset
1877
kono
parents:
diff changeset
1878
kono
parents:
diff changeset
1879 /* Build an array (descriptor) type with given bounds. */
kono
parents:
diff changeset
1880
kono
parents:
diff changeset
1881 tree
kono
parents:
diff changeset
1882 gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound,
kono
parents:
diff changeset
1883 tree * ubound, int packed,
kono
parents:
diff changeset
1884 enum gfc_array_kind akind, bool restricted)
kono
parents:
diff changeset
1885 {
kono
parents:
diff changeset
1886 char name[8 + 2*GFC_RANK_DIGITS + 1 + GFC_MAX_SYMBOL_LEN];
kono
parents:
diff changeset
1887 tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype;
kono
parents:
diff changeset
1888 const char *type_name;
kono
parents:
diff changeset
1889 int n;
kono
parents:
diff changeset
1890
kono
parents:
diff changeset
1891 base_type = gfc_get_array_descriptor_base (dimen, codimen, restricted);
kono
parents:
diff changeset
1892 fat_type = build_distinct_type_copy (base_type);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1893 /* Unshare TYPE_FIELDs. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1894 for (tree *tp = &TYPE_FIELDS (fat_type); *tp; tp = &DECL_CHAIN (*tp))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1895 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1896 tree next = DECL_CHAIN (*tp);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1897 *tp = copy_node (*tp);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1898 DECL_CONTEXT (*tp) = fat_type;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1899 DECL_CHAIN (*tp) = next;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1900 }
111
kono
parents:
diff changeset
1901 /* Make sure that nontarget and target array type have the same canonical
kono
parents:
diff changeset
1902 type (and same stub decl for debug info). */
kono
parents:
diff changeset
1903 base_type = gfc_get_array_descriptor_base (dimen, codimen, false);
kono
parents:
diff changeset
1904 TYPE_CANONICAL (fat_type) = base_type;
kono
parents:
diff changeset
1905 TYPE_STUB_DECL (fat_type) = TYPE_STUB_DECL (base_type);
kono
parents:
diff changeset
1906
kono
parents:
diff changeset
1907 tmp = TYPE_NAME (etype);
kono
parents:
diff changeset
1908 if (tmp && TREE_CODE (tmp) == TYPE_DECL)
kono
parents:
diff changeset
1909 tmp = DECL_NAME (tmp);
kono
parents:
diff changeset
1910 if (tmp)
kono
parents:
diff changeset
1911 type_name = IDENTIFIER_POINTER (tmp);
kono
parents:
diff changeset
1912 else
kono
parents:
diff changeset
1913 type_name = "unknown";
kono
parents:
diff changeset
1914 sprintf (name, "array" GFC_RANK_PRINTF_FORMAT "_%.*s", dimen + codimen,
kono
parents:
diff changeset
1915 GFC_MAX_SYMBOL_LEN, type_name);
kono
parents:
diff changeset
1916 TYPE_NAME (fat_type) = get_identifier (name);
kono
parents:
diff changeset
1917 TYPE_NAMELESS (fat_type) = 1;
kono
parents:
diff changeset
1918
kono
parents:
diff changeset
1919 GFC_DESCRIPTOR_TYPE_P (fat_type) = 1;
kono
parents:
diff changeset
1920 TYPE_LANG_SPECIFIC (fat_type) = ggc_cleared_alloc<struct lang_type> ();
kono
parents:
diff changeset
1921
kono
parents:
diff changeset
1922 GFC_TYPE_ARRAY_RANK (fat_type) = dimen;
kono
parents:
diff changeset
1923 GFC_TYPE_ARRAY_CORANK (fat_type) = codimen;
kono
parents:
diff changeset
1924 GFC_TYPE_ARRAY_DTYPE (fat_type) = NULL_TREE;
kono
parents:
diff changeset
1925 GFC_TYPE_ARRAY_AKIND (fat_type) = akind;
kono
parents:
diff changeset
1926
kono
parents:
diff changeset
1927 /* Build an array descriptor record type. */
kono
parents:
diff changeset
1928 if (packed != 0)
kono
parents:
diff changeset
1929 stride = gfc_index_one_node;
kono
parents:
diff changeset
1930 else
kono
parents:
diff changeset
1931 stride = NULL_TREE;
kono
parents:
diff changeset
1932 for (n = 0; n < dimen + codimen; n++)
kono
parents:
diff changeset
1933 {
kono
parents:
diff changeset
1934 if (n < dimen)
kono
parents:
diff changeset
1935 GFC_TYPE_ARRAY_STRIDE (fat_type, n) = stride;
kono
parents:
diff changeset
1936
kono
parents:
diff changeset
1937 if (lbound)
kono
parents:
diff changeset
1938 lower = lbound[n];
kono
parents:
diff changeset
1939 else
kono
parents:
diff changeset
1940 lower = NULL_TREE;
kono
parents:
diff changeset
1941
kono
parents:
diff changeset
1942 if (lower != NULL_TREE)
kono
parents:
diff changeset
1943 {
kono
parents:
diff changeset
1944 if (INTEGER_CST_P (lower))
kono
parents:
diff changeset
1945 GFC_TYPE_ARRAY_LBOUND (fat_type, n) = lower;
kono
parents:
diff changeset
1946 else
kono
parents:
diff changeset
1947 lower = NULL_TREE;
kono
parents:
diff changeset
1948 }
kono
parents:
diff changeset
1949
kono
parents:
diff changeset
1950 if (codimen && n == dimen + codimen - 1)
kono
parents:
diff changeset
1951 break;
kono
parents:
diff changeset
1952
kono
parents:
diff changeset
1953 upper = ubound[n];
kono
parents:
diff changeset
1954 if (upper != NULL_TREE)
kono
parents:
diff changeset
1955 {
kono
parents:
diff changeset
1956 if (INTEGER_CST_P (upper))
kono
parents:
diff changeset
1957 GFC_TYPE_ARRAY_UBOUND (fat_type, n) = upper;
kono
parents:
diff changeset
1958 else
kono
parents:
diff changeset
1959 upper = NULL_TREE;
kono
parents:
diff changeset
1960 }
kono
parents:
diff changeset
1961
kono
parents:
diff changeset
1962 if (n >= dimen)
kono
parents:
diff changeset
1963 continue;
kono
parents:
diff changeset
1964
kono
parents:
diff changeset
1965 if (upper != NULL_TREE && lower != NULL_TREE && stride != NULL_TREE)
kono
parents:
diff changeset
1966 {
kono
parents:
diff changeset
1967 tmp = fold_build2_loc (input_location, MINUS_EXPR,
kono
parents:
diff changeset
1968 gfc_array_index_type, upper, lower);
kono
parents:
diff changeset
1969 tmp = fold_build2_loc (input_location, PLUS_EXPR,
kono
parents:
diff changeset
1970 gfc_array_index_type, tmp,
kono
parents:
diff changeset
1971 gfc_index_one_node);
kono
parents:
diff changeset
1972 stride = fold_build2_loc (input_location, MULT_EXPR,
kono
parents:
diff changeset
1973 gfc_array_index_type, tmp, stride);
kono
parents:
diff changeset
1974 /* Check the folding worked. */
kono
parents:
diff changeset
1975 gcc_assert (INTEGER_CST_P (stride));
kono
parents:
diff changeset
1976 }
kono
parents:
diff changeset
1977 else
kono
parents:
diff changeset
1978 stride = NULL_TREE;
kono
parents:
diff changeset
1979 }
kono
parents:
diff changeset
1980 GFC_TYPE_ARRAY_SIZE (fat_type) = stride;
kono
parents:
diff changeset
1981
kono
parents:
diff changeset
1982 /* TODO: known offsets for descriptors. */
kono
parents:
diff changeset
1983 GFC_TYPE_ARRAY_OFFSET (fat_type) = NULL_TREE;
kono
parents:
diff changeset
1984
kono
parents:
diff changeset
1985 if (dimen == 0)
kono
parents:
diff changeset
1986 {
kono
parents:
diff changeset
1987 arraytype = build_pointer_type (etype);
kono
parents:
diff changeset
1988 if (restricted)
kono
parents:
diff changeset
1989 arraytype = build_qualified_type (arraytype, TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
1990
kono
parents:
diff changeset
1991 GFC_TYPE_ARRAY_DATAPTR_TYPE (fat_type) = arraytype;
kono
parents:
diff changeset
1992 return fat_type;
kono
parents:
diff changeset
1993 }
kono
parents:
diff changeset
1994
kono
parents:
diff changeset
1995 /* We define data as an array with the correct size if possible.
kono
parents:
diff changeset
1996 Much better than doing pointer arithmetic. */
kono
parents:
diff changeset
1997 if (stride)
kono
parents:
diff changeset
1998 rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node,
kono
parents:
diff changeset
1999 int_const_binop (MINUS_EXPR, stride,
kono
parents:
diff changeset
2000 build_int_cst (TREE_TYPE (stride), 1)));
kono
parents:
diff changeset
2001 else
kono
parents:
diff changeset
2002 rtype = gfc_array_range_type;
kono
parents:
diff changeset
2003 arraytype = build_array_type (etype, rtype);
kono
parents:
diff changeset
2004 arraytype = build_pointer_type (arraytype);
kono
parents:
diff changeset
2005 if (restricted)
kono
parents:
diff changeset
2006 arraytype = build_qualified_type (arraytype, TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
2007 GFC_TYPE_ARRAY_DATAPTR_TYPE (fat_type) = arraytype;
kono
parents:
diff changeset
2008
kono
parents:
diff changeset
2009 /* This will generate the base declarations we need to emit debug
kono
parents:
diff changeset
2010 information for this type. FIXME: there must be a better way to
kono
parents:
diff changeset
2011 avoid divergence between compilations with and without debug
kono
parents:
diff changeset
2012 information. */
kono
parents:
diff changeset
2013 {
kono
parents:
diff changeset
2014 struct array_descr_info info;
kono
parents:
diff changeset
2015 gfc_get_array_descr_info (fat_type, &info);
kono
parents:
diff changeset
2016 gfc_get_array_descr_info (build_pointer_type (fat_type), &info);
kono
parents:
diff changeset
2017 }
kono
parents:
diff changeset
2018
kono
parents:
diff changeset
2019 return fat_type;
kono
parents:
diff changeset
2020 }
kono
parents:
diff changeset
2021
kono
parents:
diff changeset
2022 /* Build a pointer type. This function is called from gfc_sym_type(). */
kono
parents:
diff changeset
2023
kono
parents:
diff changeset
2024 static tree
kono
parents:
diff changeset
2025 gfc_build_pointer_type (gfc_symbol * sym, tree type)
kono
parents:
diff changeset
2026 {
kono
parents:
diff changeset
2027 /* Array pointer types aren't actually pointers. */
kono
parents:
diff changeset
2028 if (sym->attr.dimension)
kono
parents:
diff changeset
2029 return type;
kono
parents:
diff changeset
2030 else
kono
parents:
diff changeset
2031 return build_pointer_type (type);
kono
parents:
diff changeset
2032 }
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 static tree gfc_nonrestricted_type (tree t);
kono
parents:
diff changeset
2035 /* Given two record or union type nodes TO and FROM, ensure
kono
parents:
diff changeset
2036 that all fields in FROM have a corresponding field in TO,
kono
parents:
diff changeset
2037 their type being nonrestrict variants. This accepts a TO
kono
parents:
diff changeset
2038 node that already has a prefix of the fields in FROM. */
kono
parents:
diff changeset
2039 static void
kono
parents:
diff changeset
2040 mirror_fields (tree to, tree from)
kono
parents:
diff changeset
2041 {
kono
parents:
diff changeset
2042 tree fto, ffrom;
kono
parents:
diff changeset
2043 tree *chain;
kono
parents:
diff changeset
2044
kono
parents:
diff changeset
2045 /* Forward to the end of TOs fields. */
kono
parents:
diff changeset
2046 fto = TYPE_FIELDS (to);
kono
parents:
diff changeset
2047 ffrom = TYPE_FIELDS (from);
kono
parents:
diff changeset
2048 chain = &TYPE_FIELDS (to);
kono
parents:
diff changeset
2049 while (fto)
kono
parents:
diff changeset
2050 {
kono
parents:
diff changeset
2051 gcc_assert (ffrom && DECL_NAME (fto) == DECL_NAME (ffrom));
kono
parents:
diff changeset
2052 chain = &DECL_CHAIN (fto);
kono
parents:
diff changeset
2053 fto = DECL_CHAIN (fto);
kono
parents:
diff changeset
2054 ffrom = DECL_CHAIN (ffrom);
kono
parents:
diff changeset
2055 }
kono
parents:
diff changeset
2056
kono
parents:
diff changeset
2057 /* Now add all fields remaining in FROM (starting with ffrom). */
kono
parents:
diff changeset
2058 for (; ffrom; ffrom = DECL_CHAIN (ffrom))
kono
parents:
diff changeset
2059 {
kono
parents:
diff changeset
2060 tree newfield = copy_node (ffrom);
kono
parents:
diff changeset
2061 DECL_CONTEXT (newfield) = to;
kono
parents:
diff changeset
2062 /* The store to DECL_CHAIN might seem redundant with the
kono
parents:
diff changeset
2063 stores to *chain, but not clearing it here would mean
kono
parents:
diff changeset
2064 leaving a chain into the old fields. If ever
kono
parents:
diff changeset
2065 our called functions would look at them confusion
kono
parents:
diff changeset
2066 will arise. */
kono
parents:
diff changeset
2067 DECL_CHAIN (newfield) = NULL_TREE;
kono
parents:
diff changeset
2068 *chain = newfield;
kono
parents:
diff changeset
2069 chain = &DECL_CHAIN (newfield);
kono
parents:
diff changeset
2070
kono
parents:
diff changeset
2071 if (TREE_CODE (ffrom) == FIELD_DECL)
kono
parents:
diff changeset
2072 {
kono
parents:
diff changeset
2073 tree elemtype = gfc_nonrestricted_type (TREE_TYPE (ffrom));
kono
parents:
diff changeset
2074 TREE_TYPE (newfield) = elemtype;
kono
parents:
diff changeset
2075 }
kono
parents:
diff changeset
2076 }
kono
parents:
diff changeset
2077 *chain = NULL_TREE;
kono
parents:
diff changeset
2078 }
kono
parents:
diff changeset
2079
kono
parents:
diff changeset
2080 /* Given a type T, returns a different type of the same structure,
kono
parents:
diff changeset
2081 except that all types it refers to (recursively) are always
kono
parents:
diff changeset
2082 non-restrict qualified types. */
kono
parents:
diff changeset
2083 static tree
kono
parents:
diff changeset
2084 gfc_nonrestricted_type (tree t)
kono
parents:
diff changeset
2085 {
kono
parents:
diff changeset
2086 tree ret = t;
kono
parents:
diff changeset
2087
kono
parents:
diff changeset
2088 /* If the type isn't laid out yet, don't copy it. If something
kono
parents:
diff changeset
2089 needs it for real it should wait until the type got finished. */
kono
parents:
diff changeset
2090 if (!TYPE_SIZE (t))
kono
parents:
diff changeset
2091 return t;
kono
parents:
diff changeset
2092
kono
parents:
diff changeset
2093 if (!TYPE_LANG_SPECIFIC (t))
kono
parents:
diff changeset
2094 TYPE_LANG_SPECIFIC (t) = ggc_cleared_alloc<struct lang_type> ();
kono
parents:
diff changeset
2095 /* If we're dealing with this very node already further up
kono
parents:
diff changeset
2096 the call chain (recursion via pointers and struct members)
kono
parents:
diff changeset
2097 we haven't yet determined if we really need a new type node.
kono
parents:
diff changeset
2098 Assume we don't, return T itself. */
kono
parents:
diff changeset
2099 if (TYPE_LANG_SPECIFIC (t)->nonrestricted_type == error_mark_node)
kono
parents:
diff changeset
2100 return t;
kono
parents:
diff changeset
2101
kono
parents:
diff changeset
2102 /* If we have calculated this all already, just return it. */
kono
parents:
diff changeset
2103 if (TYPE_LANG_SPECIFIC (t)->nonrestricted_type)
kono
parents:
diff changeset
2104 return TYPE_LANG_SPECIFIC (t)->nonrestricted_type;
kono
parents:
diff changeset
2105
kono
parents:
diff changeset
2106 /* Mark this type. */
kono
parents:
diff changeset
2107 TYPE_LANG_SPECIFIC (t)->nonrestricted_type = error_mark_node;
kono
parents:
diff changeset
2108
kono
parents:
diff changeset
2109 switch (TREE_CODE (t))
kono
parents:
diff changeset
2110 {
kono
parents:
diff changeset
2111 default:
kono
parents:
diff changeset
2112 break;
kono
parents:
diff changeset
2113
kono
parents:
diff changeset
2114 case POINTER_TYPE:
kono
parents:
diff changeset
2115 case REFERENCE_TYPE:
kono
parents:
diff changeset
2116 {
kono
parents:
diff changeset
2117 tree totype = gfc_nonrestricted_type (TREE_TYPE (t));
kono
parents:
diff changeset
2118 if (totype == TREE_TYPE (t))
kono
parents:
diff changeset
2119 ret = t;
kono
parents:
diff changeset
2120 else if (TREE_CODE (t) == POINTER_TYPE)
kono
parents:
diff changeset
2121 ret = build_pointer_type (totype);
kono
parents:
diff changeset
2122 else
kono
parents:
diff changeset
2123 ret = build_reference_type (totype);
kono
parents:
diff changeset
2124 ret = build_qualified_type (ret,
kono
parents:
diff changeset
2125 TYPE_QUALS (t) & ~TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
2126 }
kono
parents:
diff changeset
2127 break;
kono
parents:
diff changeset
2128
kono
parents:
diff changeset
2129 case ARRAY_TYPE:
kono
parents:
diff changeset
2130 {
kono
parents:
diff changeset
2131 tree elemtype = gfc_nonrestricted_type (TREE_TYPE (t));
kono
parents:
diff changeset
2132 if (elemtype == TREE_TYPE (t))
kono
parents:
diff changeset
2133 ret = t;
kono
parents:
diff changeset
2134 else
kono
parents:
diff changeset
2135 {
kono
parents:
diff changeset
2136 ret = build_variant_type_copy (t);
kono
parents:
diff changeset
2137 TREE_TYPE (ret) = elemtype;
kono
parents:
diff changeset
2138 if (TYPE_LANG_SPECIFIC (t)
kono
parents:
diff changeset
2139 && GFC_TYPE_ARRAY_DATAPTR_TYPE (t))
kono
parents:
diff changeset
2140 {
kono
parents:
diff changeset
2141 tree dataptr_type = GFC_TYPE_ARRAY_DATAPTR_TYPE (t);
kono
parents:
diff changeset
2142 dataptr_type = gfc_nonrestricted_type (dataptr_type);
kono
parents:
diff changeset
2143 if (dataptr_type != GFC_TYPE_ARRAY_DATAPTR_TYPE (t))
kono
parents:
diff changeset
2144 {
kono
parents:
diff changeset
2145 TYPE_LANG_SPECIFIC (ret)
kono
parents:
diff changeset
2146 = ggc_cleared_alloc<struct lang_type> ();
kono
parents:
diff changeset
2147 *TYPE_LANG_SPECIFIC (ret) = *TYPE_LANG_SPECIFIC (t);
kono
parents:
diff changeset
2148 GFC_TYPE_ARRAY_DATAPTR_TYPE (ret) = dataptr_type;
kono
parents:
diff changeset
2149 }
kono
parents:
diff changeset
2150 }
kono
parents:
diff changeset
2151 }
kono
parents:
diff changeset
2152 }
kono
parents:
diff changeset
2153 break;
kono
parents:
diff changeset
2154
kono
parents:
diff changeset
2155 case RECORD_TYPE:
kono
parents:
diff changeset
2156 case UNION_TYPE:
kono
parents:
diff changeset
2157 case QUAL_UNION_TYPE:
kono
parents:
diff changeset
2158 {
kono
parents:
diff changeset
2159 tree field;
kono
parents:
diff changeset
2160 /* First determine if we need a new type at all.
kono
parents:
diff changeset
2161 Careful, the two calls to gfc_nonrestricted_type per field
kono
parents:
diff changeset
2162 might return different values. That happens exactly when
kono
parents:
diff changeset
2163 one of the fields reaches back to this very record type
kono
parents:
diff changeset
2164 (via pointers). The first calls will assume that we don't
kono
parents:
diff changeset
2165 need to copy T (see the error_mark_node marking). If there
kono
parents:
diff changeset
2166 are any reasons for copying T apart from having to copy T,
kono
parents:
diff changeset
2167 we'll indeed copy it, and the second calls to
kono
parents:
diff changeset
2168 gfc_nonrestricted_type will use that new node if they
kono
parents:
diff changeset
2169 reach back to T. */
kono
parents:
diff changeset
2170 for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
kono
parents:
diff changeset
2171 if (TREE_CODE (field) == FIELD_DECL)
kono
parents:
diff changeset
2172 {
kono
parents:
diff changeset
2173 tree elemtype = gfc_nonrestricted_type (TREE_TYPE (field));
kono
parents:
diff changeset
2174 if (elemtype != TREE_TYPE (field))
kono
parents:
diff changeset
2175 break;
kono
parents:
diff changeset
2176 }
kono
parents:
diff changeset
2177 if (!field)
kono
parents:
diff changeset
2178 break;
kono
parents:
diff changeset
2179 ret = build_variant_type_copy (t);
kono
parents:
diff changeset
2180 TYPE_FIELDS (ret) = NULL_TREE;
kono
parents:
diff changeset
2181
kono
parents:
diff changeset
2182 /* Here we make sure that as soon as we know we have to copy
kono
parents:
diff changeset
2183 T, that also fields reaching back to us will use the new
kono
parents:
diff changeset
2184 copy. It's okay if that copy still contains the old fields,
kono
parents:
diff changeset
2185 we won't look at them. */
kono
parents:
diff changeset
2186 TYPE_LANG_SPECIFIC (t)->nonrestricted_type = ret;
kono
parents:
diff changeset
2187 mirror_fields (ret, t);
kono
parents:
diff changeset
2188 }
kono
parents:
diff changeset
2189 break;
kono
parents:
diff changeset
2190 }
kono
parents:
diff changeset
2191
kono
parents:
diff changeset
2192 TYPE_LANG_SPECIFIC (t)->nonrestricted_type = ret;
kono
parents:
diff changeset
2193 return ret;
kono
parents:
diff changeset
2194 }
kono
parents:
diff changeset
2195
kono
parents:
diff changeset
2196
kono
parents:
diff changeset
2197 /* Return the type for a symbol. Special handling is required for character
kono
parents:
diff changeset
2198 types to get the correct level of indirection.
kono
parents:
diff changeset
2199 For functions return the return type.
kono
parents:
diff changeset
2200 For subroutines return void_type_node.
kono
parents:
diff changeset
2201 Calling this multiple times for the same symbol should be avoided,
kono
parents:
diff changeset
2202 especially for character and array types. */
kono
parents:
diff changeset
2203
kono
parents:
diff changeset
2204 tree
kono
parents:
diff changeset
2205 gfc_sym_type (gfc_symbol * sym)
kono
parents:
diff changeset
2206 {
kono
parents:
diff changeset
2207 tree type;
kono
parents:
diff changeset
2208 int byref;
kono
parents:
diff changeset
2209 bool restricted;
kono
parents:
diff changeset
2210
kono
parents:
diff changeset
2211 /* Procedure Pointers inside COMMON blocks. */
kono
parents:
diff changeset
2212 if (sym->attr.proc_pointer && sym->attr.in_common)
kono
parents:
diff changeset
2213 {
kono
parents:
diff changeset
2214 /* Unset proc_pointer as gfc_get_function_type calls gfc_sym_type. */
kono
parents:
diff changeset
2215 sym->attr.proc_pointer = 0;
kono
parents:
diff changeset
2216 type = build_pointer_type (gfc_get_function_type (sym));
kono
parents:
diff changeset
2217 sym->attr.proc_pointer = 1;
kono
parents:
diff changeset
2218 return type;
kono
parents:
diff changeset
2219 }
kono
parents:
diff changeset
2220
kono
parents:
diff changeset
2221 if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function)
kono
parents:
diff changeset
2222 return void_type_node;
kono
parents:
diff changeset
2223
kono
parents:
diff changeset
2224 /* In the case of a function the fake result variable may have a
kono
parents:
diff changeset
2225 type different from the function type, so don't return early in
kono
parents:
diff changeset
2226 that case. */
kono
parents:
diff changeset
2227 if (sym->backend_decl && !sym->attr.function)
kono
parents:
diff changeset
2228 return TREE_TYPE (sym->backend_decl);
kono
parents:
diff changeset
2229
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2230 if (sym->attr.result
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2231 && sym->ts.type == BT_CHARACTER
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2232 && sym->ts.u.cl->backend_decl == NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2233 && sym->ns->proc_name
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2234 && sym->ns->proc_name->ts.u.cl
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2235 && sym->ns->proc_name->ts.u.cl->backend_decl != NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2236 sym->ts.u.cl->backend_decl = sym->ns->proc_name->ts.u.cl->backend_decl;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2237
111
kono
parents:
diff changeset
2238 if (sym->ts.type == BT_CHARACTER
kono
parents:
diff changeset
2239 && ((sym->attr.function && sym->attr.is_bind_c)
kono
parents:
diff changeset
2240 || (sym->attr.result
kono
parents:
diff changeset
2241 && sym->ns->proc_name
kono
parents:
diff changeset
2242 && sym->ns->proc_name->attr.is_bind_c)
kono
parents:
diff changeset
2243 || (sym->ts.deferred && (!sym->ts.u.cl
kono
parents:
diff changeset
2244 || !sym->ts.u.cl->backend_decl))))
kono
parents:
diff changeset
2245 type = gfc_character1_type_node;
kono
parents:
diff changeset
2246 else
kono
parents:
diff changeset
2247 type = gfc_typenode_for_spec (&sym->ts, sym->attr.codimension);
kono
parents:
diff changeset
2248
kono
parents:
diff changeset
2249 if (sym->attr.dummy && !sym->attr.function && !sym->attr.value)
kono
parents:
diff changeset
2250 byref = 1;
kono
parents:
diff changeset
2251 else
kono
parents:
diff changeset
2252 byref = 0;
kono
parents:
diff changeset
2253
kono
parents:
diff changeset
2254 restricted = !sym->attr.target && !sym->attr.pointer
kono
parents:
diff changeset
2255 && !sym->attr.proc_pointer && !sym->attr.cray_pointee;
kono
parents:
diff changeset
2256 if (!restricted)
kono
parents:
diff changeset
2257 type = gfc_nonrestricted_type (type);
kono
parents:
diff changeset
2258
kono
parents:
diff changeset
2259 if (sym->attr.dimension || sym->attr.codimension)
kono
parents:
diff changeset
2260 {
kono
parents:
diff changeset
2261 if (gfc_is_nodesc_array (sym))
kono
parents:
diff changeset
2262 {
kono
parents:
diff changeset
2263 /* If this is a character argument of unknown length, just use the
kono
parents:
diff changeset
2264 base type. */
kono
parents:
diff changeset
2265 if (sym->ts.type != BT_CHARACTER
kono
parents:
diff changeset
2266 || !(sym->attr.dummy || sym->attr.function)
kono
parents:
diff changeset
2267 || sym->ts.u.cl->backend_decl)
kono
parents:
diff changeset
2268 {
kono
parents:
diff changeset
2269 type = gfc_get_nodesc_array_type (type, sym->as,
kono
parents:
diff changeset
2270 byref ? PACKED_FULL
kono
parents:
diff changeset
2271 : PACKED_STATIC,
kono
parents:
diff changeset
2272 restricted);
kono
parents:
diff changeset
2273 byref = 0;
kono
parents:
diff changeset
2274 }
kono
parents:
diff changeset
2275 }
kono
parents:
diff changeset
2276 else
kono
parents:
diff changeset
2277 {
kono
parents:
diff changeset
2278 enum gfc_array_kind akind = GFC_ARRAY_UNKNOWN;
kono
parents:
diff changeset
2279 if (sym->attr.pointer)
kono
parents:
diff changeset
2280 akind = sym->attr.contiguous ? GFC_ARRAY_POINTER_CONT
kono
parents:
diff changeset
2281 : GFC_ARRAY_POINTER;
kono
parents:
diff changeset
2282 else if (sym->attr.allocatable)
kono
parents:
diff changeset
2283 akind = GFC_ARRAY_ALLOCATABLE;
kono
parents:
diff changeset
2284 type = gfc_build_array_type (type, sym->as, akind, restricted,
kono
parents:
diff changeset
2285 sym->attr.contiguous, false);
kono
parents:
diff changeset
2286 }
kono
parents:
diff changeset
2287 }
kono
parents:
diff changeset
2288 else
kono
parents:
diff changeset
2289 {
kono
parents:
diff changeset
2290 if (sym->attr.allocatable || sym->attr.pointer
kono
parents:
diff changeset
2291 || gfc_is_associate_pointer (sym))
kono
parents:
diff changeset
2292 type = gfc_build_pointer_type (sym, type);
kono
parents:
diff changeset
2293 }
kono
parents:
diff changeset
2294
kono
parents:
diff changeset
2295 /* We currently pass all parameters by reference.
kono
parents:
diff changeset
2296 See f95_get_function_decl. For dummy function parameters return the
kono
parents:
diff changeset
2297 function type. */
kono
parents:
diff changeset
2298 if (byref)
kono
parents:
diff changeset
2299 {
kono
parents:
diff changeset
2300 /* We must use pointer types for potentially absent variables. The
kono
parents:
diff changeset
2301 optimizers assume a reference type argument is never NULL. */
kono
parents:
diff changeset
2302 if (sym->attr.optional
kono
parents:
diff changeset
2303 || (sym->ns->proc_name && sym->ns->proc_name->attr.entry_master))
kono
parents:
diff changeset
2304 type = build_pointer_type (type);
kono
parents:
diff changeset
2305 else
kono
parents:
diff changeset
2306 {
kono
parents:
diff changeset
2307 type = build_reference_type (type);
kono
parents:
diff changeset
2308 if (restricted)
kono
parents:
diff changeset
2309 type = build_qualified_type (type, TYPE_QUAL_RESTRICT);
kono
parents:
diff changeset
2310 }
kono
parents:
diff changeset
2311 }
kono
parents:
diff changeset
2312
kono
parents:
diff changeset
2313 return (type);
kono
parents:
diff changeset
2314 }
kono
parents:
diff changeset
2315
kono
parents:
diff changeset
2316 /* Layout and output debug info for a record type. */
kono
parents:
diff changeset
2317
kono
parents:
diff changeset
2318 void
kono
parents:
diff changeset
2319 gfc_finish_type (tree type)
kono
parents:
diff changeset
2320 {
kono
parents:
diff changeset
2321 tree decl;
kono
parents:
diff changeset
2322
kono
parents:
diff changeset
2323 decl = build_decl (input_location,
kono
parents:
diff changeset
2324 TYPE_DECL, NULL_TREE, type);
kono
parents:
diff changeset
2325 TYPE_STUB_DECL (type) = decl;
kono
parents:
diff changeset
2326 layout_type (type);
kono
parents:
diff changeset
2327 rest_of_type_compilation (type, 1);
kono
parents:
diff changeset
2328 rest_of_decl_compilation (decl, 1, 0);
kono
parents:
diff changeset
2329 }
kono
parents:
diff changeset
2330
kono
parents:
diff changeset
2331 /* Add a field of given NAME and TYPE to the context of a UNION_TYPE
kono
parents:
diff changeset
2332 or RECORD_TYPE pointed to by CONTEXT. The new field is chained
kono
parents:
diff changeset
2333 to the end of the field list pointed to by *CHAIN.
kono
parents:
diff changeset
2334
kono
parents:
diff changeset
2335 Returns a pointer to the new field. */
kono
parents:
diff changeset
2336
kono
parents:
diff changeset
2337 static tree
kono
parents:
diff changeset
2338 gfc_add_field_to_struct_1 (tree context, tree name, tree type, tree **chain)
kono
parents:
diff changeset
2339 {
kono
parents:
diff changeset
2340 tree decl = build_decl (input_location, FIELD_DECL, name, type);
kono
parents:
diff changeset
2341
kono
parents:
diff changeset
2342 DECL_CONTEXT (decl) = context;
kono
parents:
diff changeset
2343 DECL_CHAIN (decl) = NULL_TREE;
kono
parents:
diff changeset
2344 if (TYPE_FIELDS (context) == NULL_TREE)
kono
parents:
diff changeset
2345 TYPE_FIELDS (context) = decl;
kono
parents:
diff changeset
2346 if (chain != NULL)
kono
parents:
diff changeset
2347 {
kono
parents:
diff changeset
2348 if (*chain != NULL)
kono
parents:
diff changeset
2349 **chain = decl;
kono
parents:
diff changeset
2350 *chain = &DECL_CHAIN (decl);
kono
parents:
diff changeset
2351 }
kono
parents:
diff changeset
2352
kono
parents:
diff changeset
2353 return decl;
kono
parents:
diff changeset
2354 }
kono
parents:
diff changeset
2355
kono
parents:
diff changeset
2356 /* Like `gfc_add_field_to_struct_1', but adds alignment
kono
parents:
diff changeset
2357 information. */
kono
parents:
diff changeset
2358
kono
parents:
diff changeset
2359 tree
kono
parents:
diff changeset
2360 gfc_add_field_to_struct (tree context, tree name, tree type, tree **chain)
kono
parents:
diff changeset
2361 {
kono
parents:
diff changeset
2362 tree decl = gfc_add_field_to_struct_1 (context, name, type, chain);
kono
parents:
diff changeset
2363
kono
parents:
diff changeset
2364 DECL_INITIAL (decl) = 0;
kono
parents:
diff changeset
2365 SET_DECL_ALIGN (decl, 0);
kono
parents:
diff changeset
2366 DECL_USER_ALIGN (decl) = 0;
kono
parents:
diff changeset
2367
kono
parents:
diff changeset
2368 return decl;
kono
parents:
diff changeset
2369 }
kono
parents:
diff changeset
2370
kono
parents:
diff changeset
2371
kono
parents:
diff changeset
2372 /* Copy the backend_decl and component backend_decls if
kono
parents:
diff changeset
2373 the two derived type symbols are "equal", as described
kono
parents:
diff changeset
2374 in 4.4.2 and resolved by gfc_compare_derived_types. */
kono
parents:
diff changeset
2375
kono
parents:
diff changeset
2376 int
kono
parents:
diff changeset
2377 gfc_copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to,
kono
parents:
diff changeset
2378 bool from_gsym)
kono
parents:
diff changeset
2379 {
kono
parents:
diff changeset
2380 gfc_component *to_cm;
kono
parents:
diff changeset
2381 gfc_component *from_cm;
kono
parents:
diff changeset
2382
kono
parents:
diff changeset
2383 if (from == to)
kono
parents:
diff changeset
2384 return 1;
kono
parents:
diff changeset
2385
kono
parents:
diff changeset
2386 if (from->backend_decl == NULL
kono
parents:
diff changeset
2387 || !gfc_compare_derived_types (from, to))
kono
parents:
diff changeset
2388 return 0;
kono
parents:
diff changeset
2389
kono
parents:
diff changeset
2390 to->backend_decl = from->backend_decl;
kono
parents:
diff changeset
2391
kono
parents:
diff changeset
2392 to_cm = to->components;
kono
parents:
diff changeset
2393 from_cm = from->components;
kono
parents:
diff changeset
2394
kono
parents:
diff changeset
2395 /* Copy the component declarations. If a component is itself
kono
parents:
diff changeset
2396 a derived type, we need a copy of its component declarations.
kono
parents:
diff changeset
2397 This is done by recursing into gfc_get_derived_type and
kono
parents:
diff changeset
2398 ensures that the component's component declarations have
kono
parents:
diff changeset
2399 been built. If it is a character, we need the character
kono
parents:
diff changeset
2400 length, as well. */
kono
parents:
diff changeset
2401 for (; to_cm; to_cm = to_cm->next, from_cm = from_cm->next)
kono
parents:
diff changeset
2402 {
kono
parents:
diff changeset
2403 to_cm->backend_decl = from_cm->backend_decl;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2404 to_cm->caf_token = from_cm->caf_token;
111
kono
parents:
diff changeset
2405 if (from_cm->ts.type == BT_UNION)
kono
parents:
diff changeset
2406 gfc_get_union_type (to_cm->ts.u.derived);
kono
parents:
diff changeset
2407 else if (from_cm->ts.type == BT_DERIVED
kono
parents:
diff changeset
2408 && (!from_cm->attr.pointer || from_gsym))
kono
parents:
diff changeset
2409 gfc_get_derived_type (to_cm->ts.u.derived);
kono
parents:
diff changeset
2410 else if (from_cm->ts.type == BT_CLASS
kono
parents:
diff changeset
2411 && (!CLASS_DATA (from_cm)->attr.class_pointer || from_gsym))
kono
parents:
diff changeset
2412 gfc_get_derived_type (to_cm->ts.u.derived);
kono
parents:
diff changeset
2413 else if (from_cm->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
2414 to_cm->ts.u.cl->backend_decl = from_cm->ts.u.cl->backend_decl;
kono
parents:
diff changeset
2415 }
kono
parents:
diff changeset
2416
kono
parents:
diff changeset
2417 return 1;
kono
parents:
diff changeset
2418 }
kono
parents:
diff changeset
2419
kono
parents:
diff changeset
2420
kono
parents:
diff changeset
2421 /* Build a tree node for a procedure pointer component. */
kono
parents:
diff changeset
2422
kono
parents:
diff changeset
2423 tree
kono
parents:
diff changeset
2424 gfc_get_ppc_type (gfc_component* c)
kono
parents:
diff changeset
2425 {
kono
parents:
diff changeset
2426 tree t;
kono
parents:
diff changeset
2427
kono
parents:
diff changeset
2428 /* Explicit interface. */
kono
parents:
diff changeset
2429 if (c->attr.if_source != IFSRC_UNKNOWN && c->ts.interface)
kono
parents:
diff changeset
2430 return build_pointer_type (gfc_get_function_type (c->ts.interface));
kono
parents:
diff changeset
2431
kono
parents:
diff changeset
2432 /* Implicit interface (only return value may be known). */
kono
parents:
diff changeset
2433 if (c->attr.function && !c->attr.dimension && c->ts.type != BT_CHARACTER)
kono
parents:
diff changeset
2434 t = gfc_typenode_for_spec (&c->ts);
kono
parents:
diff changeset
2435 else
kono
parents:
diff changeset
2436 t = void_type_node;
kono
parents:
diff changeset
2437
kono
parents:
diff changeset
2438 return build_pointer_type (build_function_type_list (t, NULL_TREE));
kono
parents:
diff changeset
2439 }
kono
parents:
diff changeset
2440
kono
parents:
diff changeset
2441
kono
parents:
diff changeset
2442 /* Build a tree node for a union type. Requires building each map
kono
parents:
diff changeset
2443 structure which is an element of the union. */
kono
parents:
diff changeset
2444
kono
parents:
diff changeset
2445 tree
kono
parents:
diff changeset
2446 gfc_get_union_type (gfc_symbol *un)
kono
parents:
diff changeset
2447 {
kono
parents:
diff changeset
2448 gfc_component *map = NULL;
kono
parents:
diff changeset
2449 tree typenode = NULL, map_type = NULL, map_field = NULL;
kono
parents:
diff changeset
2450 tree *chain = NULL;
kono
parents:
diff changeset
2451
kono
parents:
diff changeset
2452 if (un->backend_decl)
kono
parents:
diff changeset
2453 {
kono
parents:
diff changeset
2454 if (TYPE_FIELDS (un->backend_decl) || un->attr.proc_pointer_comp)
kono
parents:
diff changeset
2455 return un->backend_decl;
kono
parents:
diff changeset
2456 else
kono
parents:
diff changeset
2457 typenode = un->backend_decl;
kono
parents:
diff changeset
2458 }
kono
parents:
diff changeset
2459 else
kono
parents:
diff changeset
2460 {
kono
parents:
diff changeset
2461 typenode = make_node (UNION_TYPE);
kono
parents:
diff changeset
2462 TYPE_NAME (typenode) = get_identifier (un->name);
kono
parents:
diff changeset
2463 }
kono
parents:
diff changeset
2464
kono
parents:
diff changeset
2465 /* Add each contained MAP as a field. */
kono
parents:
diff changeset
2466 for (map = un->components; map; map = map->next)
kono
parents:
diff changeset
2467 {
kono
parents:
diff changeset
2468 gcc_assert (map->ts.type == BT_DERIVED);
kono
parents:
diff changeset
2469
kono
parents:
diff changeset
2470 /* The map's type node, which is defined within this union's context. */
kono
parents:
diff changeset
2471 map_type = gfc_get_derived_type (map->ts.u.derived);
kono
parents:
diff changeset
2472 TYPE_CONTEXT (map_type) = typenode;
kono
parents:
diff changeset
2473
kono
parents:
diff changeset
2474 /* The map field's declaration. */
kono
parents:
diff changeset
2475 map_field = gfc_add_field_to_struct(typenode, get_identifier(map->name),
kono
parents:
diff changeset
2476 map_type, &chain);
kono
parents:
diff changeset
2477 if (map->loc.lb)
kono
parents:
diff changeset
2478 gfc_set_decl_location (map_field, &map->loc);
kono
parents:
diff changeset
2479 else if (un->declared_at.lb)
kono
parents:
diff changeset
2480 gfc_set_decl_location (map_field, &un->declared_at);
kono
parents:
diff changeset
2481
kono
parents:
diff changeset
2482 DECL_PACKED (map_field) |= TYPE_PACKED (typenode);
kono
parents:
diff changeset
2483 DECL_NAMELESS(map_field) = true;
kono
parents:
diff changeset
2484
kono
parents:
diff changeset
2485 /* We should never clobber another backend declaration for this map,
kono
parents:
diff changeset
2486 because each map component is unique. */
kono
parents:
diff changeset
2487 if (!map->backend_decl)
kono
parents:
diff changeset
2488 map->backend_decl = map_field;
kono
parents:
diff changeset
2489 }
kono
parents:
diff changeset
2490
kono
parents:
diff changeset
2491 un->backend_decl = typenode;
kono
parents:
diff changeset
2492 gfc_finish_type (typenode);
kono
parents:
diff changeset
2493
kono
parents:
diff changeset
2494 return typenode;
kono
parents:
diff changeset
2495 }
kono
parents:
diff changeset
2496
kono
parents:
diff changeset
2497
kono
parents:
diff changeset
2498 /* Build a tree node for a derived type. If there are equal
kono
parents:
diff changeset
2499 derived types, with different local names, these are built
kono
parents:
diff changeset
2500 at the same time. If an equal derived type has been built
kono
parents:
diff changeset
2501 in a parent namespace, this is used. */
kono
parents:
diff changeset
2502
kono
parents:
diff changeset
2503 tree
kono
parents:
diff changeset
2504 gfc_get_derived_type (gfc_symbol * derived, int codimen)
kono
parents:
diff changeset
2505 {
kono
parents:
diff changeset
2506 tree typenode = NULL, field = NULL, field_type = NULL;
kono
parents:
diff changeset
2507 tree canonical = NULL_TREE;
kono
parents:
diff changeset
2508 tree *chain = NULL;
kono
parents:
diff changeset
2509 bool got_canonical = false;
kono
parents:
diff changeset
2510 bool unlimited_entity = false;
kono
parents:
diff changeset
2511 gfc_component *c;
kono
parents:
diff changeset
2512 gfc_namespace *ns;
kono
parents:
diff changeset
2513 tree tmp;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2514 bool coarray_flag;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2515
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2516 coarray_flag = flag_coarray == GFC_FCOARRAY_LIB
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2517 && derived->module && !derived->attr.vtype;
111
kono
parents:
diff changeset
2518
kono
parents:
diff changeset
2519 gcc_assert (!derived->attr.pdt_template);
kono
parents:
diff changeset
2520
kono
parents:
diff changeset
2521 if (derived->attr.unlimited_polymorphic
kono
parents:
diff changeset
2522 || (flag_coarray == GFC_FCOARRAY_LIB
kono
parents:
diff changeset
2523 && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
kono
parents:
diff changeset
2524 && (derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2525 || derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2526 || derived->intmod_sym_id == ISOFORTRAN_TEAM_TYPE)))
111
kono
parents:
diff changeset
2527 return ptr_type_node;
kono
parents:
diff changeset
2528
kono
parents:
diff changeset
2529 if (flag_coarray != GFC_FCOARRAY_LIB
kono
parents:
diff changeset
2530 && derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2531 && (derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2532 || derived->intmod_sym_id == ISOFORTRAN_TEAM_TYPE))
111
kono
parents:
diff changeset
2533 return gfc_get_int_type (gfc_default_integer_kind);
kono
parents:
diff changeset
2534
kono
parents:
diff changeset
2535 if (derived && derived->attr.flavor == FL_PROCEDURE
kono
parents:
diff changeset
2536 && derived->attr.generic)
kono
parents:
diff changeset
2537 derived = gfc_find_dt_in_generic (derived);
kono
parents:
diff changeset
2538
kono
parents:
diff changeset
2539 /* See if it's one of the iso_c_binding derived types. */
kono
parents:
diff changeset
2540 if (derived->attr.is_iso_c == 1 || derived->ts.f90_type == BT_VOID)
kono
parents:
diff changeset
2541 {
kono
parents:
diff changeset
2542 if (derived->backend_decl)
kono
parents:
diff changeset
2543 return derived->backend_decl;
kono
parents:
diff changeset
2544
kono
parents:
diff changeset
2545 if (derived->intmod_sym_id == ISOCBINDING_PTR)
kono
parents:
diff changeset
2546 derived->backend_decl = ptr_type_node;
kono
parents:
diff changeset
2547 else
kono
parents:
diff changeset
2548 derived->backend_decl = pfunc_type_node;
kono
parents:
diff changeset
2549
kono
parents:
diff changeset
2550 derived->ts.kind = gfc_index_integer_kind;
kono
parents:
diff changeset
2551 derived->ts.type = BT_INTEGER;
kono
parents:
diff changeset
2552 /* Set the f90_type to BT_VOID as a way to recognize something of type
kono
parents:
diff changeset
2553 BT_INTEGER that needs to fit a void * for the purpose of the
kono
parents:
diff changeset
2554 iso_c_binding derived types. */
kono
parents:
diff changeset
2555 derived->ts.f90_type = BT_VOID;
kono
parents:
diff changeset
2556
kono
parents:
diff changeset
2557 return derived->backend_decl;
kono
parents:
diff changeset
2558 }
kono
parents:
diff changeset
2559
kono
parents:
diff changeset
2560 /* If use associated, use the module type for this one. */
kono
parents:
diff changeset
2561 if (derived->backend_decl == NULL
kono
parents:
diff changeset
2562 && derived->attr.use_assoc
kono
parents:
diff changeset
2563 && derived->module
kono
parents:
diff changeset
2564 && gfc_get_module_backend_decl (derived))
kono
parents:
diff changeset
2565 goto copy_derived_types;
kono
parents:
diff changeset
2566
kono
parents:
diff changeset
2567 /* The derived types from an earlier namespace can be used as the
kono
parents:
diff changeset
2568 canonical type. */
kono
parents:
diff changeset
2569 if (derived->backend_decl == NULL && !derived->attr.use_assoc
kono
parents:
diff changeset
2570 && gfc_global_ns_list)
kono
parents:
diff changeset
2571 {
kono
parents:
diff changeset
2572 for (ns = gfc_global_ns_list;
kono
parents:
diff changeset
2573 ns->translated && !got_canonical;
kono
parents:
diff changeset
2574 ns = ns->sibling)
kono
parents:
diff changeset
2575 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2576 if (ns->derived_types)
111
kono
parents:
diff changeset
2577 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2578 for (gfc_symbol *dt = ns->derived_types; dt && !got_canonical;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2579 dt = dt->dt_next)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2580 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2581 gfc_copy_dt_decls_ifequal (dt, derived, true);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2582 if (derived->backend_decl)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2583 got_canonical = true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2584 if (dt->dt_next == ns->derived_types)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2585 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2586 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2587 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2588 }
111
kono
parents:
diff changeset
2589 }
kono
parents:
diff changeset
2590
kono
parents:
diff changeset
2591 /* Store up the canonical type to be added to this one. */
kono
parents:
diff changeset
2592 if (got_canonical)
kono
parents:
diff changeset
2593 {
kono
parents:
diff changeset
2594 if (TYPE_CANONICAL (derived->backend_decl))
kono
parents:
diff changeset
2595 canonical = TYPE_CANONICAL (derived->backend_decl);
kono
parents:
diff changeset
2596 else
kono
parents:
diff changeset
2597 canonical = derived->backend_decl;
kono
parents:
diff changeset
2598
kono
parents:
diff changeset
2599 derived->backend_decl = NULL_TREE;
kono
parents:
diff changeset
2600 }
kono
parents:
diff changeset
2601
kono
parents:
diff changeset
2602 /* derived->backend_decl != 0 means we saw it before, but its
kono
parents:
diff changeset
2603 components' backend_decl may have not been built. */
kono
parents:
diff changeset
2604 if (derived->backend_decl)
kono
parents:
diff changeset
2605 {
kono
parents:
diff changeset
2606 /* Its components' backend_decl have been built or we are
kono
parents:
diff changeset
2607 seeing recursion through the formal arglist of a procedure
kono
parents:
diff changeset
2608 pointer component. */
kono
parents:
diff changeset
2609 if (TYPE_FIELDS (derived->backend_decl))
kono
parents:
diff changeset
2610 return derived->backend_decl;
kono
parents:
diff changeset
2611 else if (derived->attr.abstract
kono
parents:
diff changeset
2612 && derived->attr.proc_pointer_comp)
kono
parents:
diff changeset
2613 {
kono
parents:
diff changeset
2614 /* If an abstract derived type with procedure pointer
kono
parents:
diff changeset
2615 components has no other type of component, return the
kono
parents:
diff changeset
2616 backend_decl. Otherwise build the components if any of the
kono
parents:
diff changeset
2617 non-procedure pointer components have no backend_decl. */
kono
parents:
diff changeset
2618 for (c = derived->components; c; c = c->next)
kono
parents:
diff changeset
2619 {
kono
parents:
diff changeset
2620 bool same_alloc_type = c->attr.allocatable
kono
parents:
diff changeset
2621 && derived == c->ts.u.derived;
kono
parents:
diff changeset
2622 if (!c->attr.proc_pointer
kono
parents:
diff changeset
2623 && !same_alloc_type
kono
parents:
diff changeset
2624 && c->backend_decl == NULL)
kono
parents:
diff changeset
2625 break;
kono
parents:
diff changeset
2626 else if (c->next == NULL)
kono
parents:
diff changeset
2627 return derived->backend_decl;
kono
parents:
diff changeset
2628 }
kono
parents:
diff changeset
2629 typenode = derived->backend_decl;
kono
parents:
diff changeset
2630 }
kono
parents:
diff changeset
2631 else
kono
parents:
diff changeset
2632 typenode = derived->backend_decl;
kono
parents:
diff changeset
2633 }
kono
parents:
diff changeset
2634 else
kono
parents:
diff changeset
2635 {
kono
parents:
diff changeset
2636 /* We see this derived type first time, so build the type node. */
kono
parents:
diff changeset
2637 typenode = make_node (RECORD_TYPE);
kono
parents:
diff changeset
2638 TYPE_NAME (typenode) = get_identifier (derived->name);
kono
parents:
diff changeset
2639 TYPE_PACKED (typenode) = flag_pack_derived;
kono
parents:
diff changeset
2640 derived->backend_decl = typenode;
kono
parents:
diff changeset
2641 }
kono
parents:
diff changeset
2642
kono
parents:
diff changeset
2643 if (derived->components
kono
parents:
diff changeset
2644 && derived->components->ts.type == BT_DERIVED
kono
parents:
diff changeset
2645 && strcmp (derived->components->name, "_data") == 0
kono
parents:
diff changeset
2646 && derived->components->ts.u.derived->attr.unlimited_polymorphic)
kono
parents:
diff changeset
2647 unlimited_entity = true;
kono
parents:
diff changeset
2648
kono
parents:
diff changeset
2649 /* Go through the derived type components, building them as
kono
parents:
diff changeset
2650 necessary. The reason for doing this now is that it is
kono
parents:
diff changeset
2651 possible to recurse back to this derived type through a
kono
parents:
diff changeset
2652 pointer component (PR24092). If this happens, the fields
kono
parents:
diff changeset
2653 will be built and so we can return the type. */
kono
parents:
diff changeset
2654 for (c = derived->components; c; c = c->next)
kono
parents:
diff changeset
2655 {
kono
parents:
diff changeset
2656 bool same_alloc_type = c->attr.allocatable
kono
parents:
diff changeset
2657 && derived == c->ts.u.derived;
kono
parents:
diff changeset
2658
kono
parents:
diff changeset
2659 if (c->ts.type == BT_UNION && c->ts.u.derived->backend_decl == NULL)
kono
parents:
diff changeset
2660 c->ts.u.derived->backend_decl = gfc_get_union_type (c->ts.u.derived);
kono
parents:
diff changeset
2661
kono
parents:
diff changeset
2662 if (c->ts.type != BT_DERIVED && c->ts.type != BT_CLASS)
kono
parents:
diff changeset
2663 continue;
kono
parents:
diff changeset
2664
kono
parents:
diff changeset
2665 if ((!c->attr.pointer && !c->attr.proc_pointer
kono
parents:
diff changeset
2666 && !same_alloc_type)
kono
parents:
diff changeset
2667 || c->ts.u.derived->backend_decl == NULL)
kono
parents:
diff changeset
2668 {
kono
parents:
diff changeset
2669 int local_codim = c->attr.codimension ? c->as->corank: codimen;
kono
parents:
diff changeset
2670 c->ts.u.derived->backend_decl = gfc_get_derived_type (c->ts.u.derived,
kono
parents:
diff changeset
2671 local_codim);
kono
parents:
diff changeset
2672 }
kono
parents:
diff changeset
2673
kono
parents:
diff changeset
2674 if (c->ts.u.derived->attr.is_iso_c)
kono
parents:
diff changeset
2675 {
kono
parents:
diff changeset
2676 /* Need to copy the modified ts from the derived type. The
kono
parents:
diff changeset
2677 typespec was modified because C_PTR/C_FUNPTR are translated
kono
parents:
diff changeset
2678 into (void *) from derived types. */
kono
parents:
diff changeset
2679 c->ts.type = c->ts.u.derived->ts.type;
kono
parents:
diff changeset
2680 c->ts.kind = c->ts.u.derived->ts.kind;
kono
parents:
diff changeset
2681 c->ts.f90_type = c->ts.u.derived->ts.f90_type;
kono
parents:
diff changeset
2682 if (c->initializer)
kono
parents:
diff changeset
2683 {
kono
parents:
diff changeset
2684 c->initializer->ts.type = c->ts.type;
kono
parents:
diff changeset
2685 c->initializer->ts.kind = c->ts.kind;
kono
parents:
diff changeset
2686 c->initializer->ts.f90_type = c->ts.f90_type;
kono
parents:
diff changeset
2687 c->initializer->expr_type = EXPR_NULL;
kono
parents:
diff changeset
2688 }
kono
parents:
diff changeset
2689 }
kono
parents:
diff changeset
2690 }
kono
parents:
diff changeset
2691
kono
parents:
diff changeset
2692 if (TYPE_FIELDS (derived->backend_decl))
kono
parents:
diff changeset
2693 return derived->backend_decl;
kono
parents:
diff changeset
2694
kono
parents:
diff changeset
2695 /* Build the type member list. Install the newly created RECORD_TYPE
kono
parents:
diff changeset
2696 node as DECL_CONTEXT of each FIELD_DECL. In this case we must go
kono
parents:
diff changeset
2697 through only the top-level linked list of components so we correctly
kono
parents:
diff changeset
2698 build UNION_TYPE nodes for BT_UNION components. MAPs and other nested
kono
parents:
diff changeset
2699 types are built as part of gfc_get_union_type. */
kono
parents:
diff changeset
2700 for (c = derived->components; c; c = c->next)
kono
parents:
diff changeset
2701 {
kono
parents:
diff changeset
2702 bool same_alloc_type = c->attr.allocatable
kono
parents:
diff changeset
2703 && derived == c->ts.u.derived;
kono
parents:
diff changeset
2704 /* Prevent infinite recursion, when the procedure pointer type is
kono
parents:
diff changeset
2705 the same as derived, by forcing the procedure pointer component to
kono
parents:
diff changeset
2706 be built as if the explicit interface does not exist. */
kono
parents:
diff changeset
2707 if (c->attr.proc_pointer
kono
parents:
diff changeset
2708 && (c->ts.type != BT_DERIVED || (c->ts.u.derived
kono
parents:
diff changeset
2709 && !gfc_compare_derived_types (derived, c->ts.u.derived)))
kono
parents:
diff changeset
2710 && (c->ts.type != BT_CLASS || (CLASS_DATA (c)->ts.u.derived
kono
parents:
diff changeset
2711 && !gfc_compare_derived_types (derived, CLASS_DATA (c)->ts.u.derived))))
kono
parents:
diff changeset
2712 field_type = gfc_get_ppc_type (c);
kono
parents:
diff changeset
2713 else if (c->attr.proc_pointer && derived->backend_decl)
kono
parents:
diff changeset
2714 {
kono
parents:
diff changeset
2715 tmp = build_function_type_list (derived->backend_decl, NULL_TREE);
kono
parents:
diff changeset
2716 field_type = build_pointer_type (tmp);
kono
parents:
diff changeset
2717 }
kono
parents:
diff changeset
2718 else if (c->ts.type == BT_DERIVED || c->ts.type == BT_CLASS)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2719 field_type = c->ts.u.derived->backend_decl;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2720 else if (c->attr.caf_token)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2721 field_type = pvoid_type_node;
111
kono
parents:
diff changeset
2722 else
kono
parents:
diff changeset
2723 {
kono
parents:
diff changeset
2724 if (c->ts.type == BT_CHARACTER
kono
parents:
diff changeset
2725 && !c->ts.deferred && !c->attr.pdt_string)
kono
parents:
diff changeset
2726 {
kono
parents:
diff changeset
2727 /* Evaluate the string length. */
kono
parents:
diff changeset
2728 gfc_conv_const_charlen (c->ts.u.cl);
kono
parents:
diff changeset
2729 gcc_assert (c->ts.u.cl->backend_decl);
kono
parents:
diff changeset
2730 }
kono
parents:
diff changeset
2731 else if (c->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
2732 c->ts.u.cl->backend_decl
kono
parents:
diff changeset
2733 = build_int_cst (gfc_charlen_type_node, 0);
kono
parents:
diff changeset
2734
kono
parents:
diff changeset
2735 field_type = gfc_typenode_for_spec (&c->ts, codimen);
kono
parents:
diff changeset
2736 }
kono
parents:
diff changeset
2737
kono
parents:
diff changeset
2738 /* This returns an array descriptor type. Initialization may be
kono
parents:
diff changeset
2739 required. */
kono
parents:
diff changeset
2740 if ((c->attr.dimension || c->attr.codimension) && !c->attr.proc_pointer )
kono
parents:
diff changeset
2741 {
kono
parents:
diff changeset
2742 if (c->attr.pointer || c->attr.allocatable || c->attr.pdt_array)
kono
parents:
diff changeset
2743 {
kono
parents:
diff changeset
2744 enum gfc_array_kind akind;
kono
parents:
diff changeset
2745 if (c->attr.pointer)
kono
parents:
diff changeset
2746 akind = c->attr.contiguous ? GFC_ARRAY_POINTER_CONT
kono
parents:
diff changeset
2747 : GFC_ARRAY_POINTER;
kono
parents:
diff changeset
2748 else
kono
parents:
diff changeset
2749 akind = GFC_ARRAY_ALLOCATABLE;
kono
parents:
diff changeset
2750 /* Pointers to arrays aren't actually pointer types. The
kono
parents:
diff changeset
2751 descriptors are separate, but the data is common. */
kono
parents:
diff changeset
2752 field_type = gfc_build_array_type (field_type, c->as, akind,
kono
parents:
diff changeset
2753 !c->attr.target
kono
parents:
diff changeset
2754 && !c->attr.pointer,
kono
parents:
diff changeset
2755 c->attr.contiguous,
kono
parents:
diff changeset
2756 codimen);
kono
parents:
diff changeset
2757 }
kono
parents:
diff changeset
2758 else
kono
parents:
diff changeset
2759 field_type = gfc_get_nodesc_array_type (field_type, c->as,
kono
parents:
diff changeset
2760 PACKED_STATIC,
kono
parents:
diff changeset
2761 !c->attr.target);
kono
parents:
diff changeset
2762 }
kono
parents:
diff changeset
2763 else if ((c->attr.pointer || c->attr.allocatable || c->attr.pdt_string)
kono
parents:
diff changeset
2764 && !c->attr.proc_pointer
kono
parents:
diff changeset
2765 && !(unlimited_entity && c == derived->components))
kono
parents:
diff changeset
2766 field_type = build_pointer_type (field_type);
kono
parents:
diff changeset
2767
kono
parents:
diff changeset
2768 if (c->attr.pointer || same_alloc_type)
kono
parents:
diff changeset
2769 field_type = gfc_nonrestricted_type (field_type);
kono
parents:
diff changeset
2770
kono
parents:
diff changeset
2771 /* vtype fields can point to different types to the base type. */
kono
parents:
diff changeset
2772 if (c->ts.type == BT_DERIVED
kono
parents:
diff changeset
2773 && c->ts.u.derived && c->ts.u.derived->attr.vtype)
kono
parents:
diff changeset
2774 field_type = build_pointer_type_for_mode (TREE_TYPE (field_type),
kono
parents:
diff changeset
2775 ptr_mode, true);
kono
parents:
diff changeset
2776
kono
parents:
diff changeset
2777 /* Ensure that the CLASS language specific flag is set. */
kono
parents:
diff changeset
2778 if (c->ts.type == BT_CLASS)
kono
parents:
diff changeset
2779 {
kono
parents:
diff changeset
2780 if (POINTER_TYPE_P (field_type))
kono
parents:
diff changeset
2781 GFC_CLASS_TYPE_P (TREE_TYPE (field_type)) = 1;
kono
parents:
diff changeset
2782 else
kono
parents:
diff changeset
2783 GFC_CLASS_TYPE_P (field_type) = 1;
kono
parents:
diff changeset
2784 }
kono
parents:
diff changeset
2785
kono
parents:
diff changeset
2786 field = gfc_add_field_to_struct (typenode,
kono
parents:
diff changeset
2787 get_identifier (c->name),
kono
parents:
diff changeset
2788 field_type, &chain);
kono
parents:
diff changeset
2789 if (c->loc.lb)
kono
parents:
diff changeset
2790 gfc_set_decl_location (field, &c->loc);
kono
parents:
diff changeset
2791 else if (derived->declared_at.lb)
kono
parents:
diff changeset
2792 gfc_set_decl_location (field, &derived->declared_at);
kono
parents:
diff changeset
2793
kono
parents:
diff changeset
2794 gfc_finish_decl_attrs (field, &c->attr);
kono
parents:
diff changeset
2795
kono
parents:
diff changeset
2796 DECL_PACKED (field) |= TYPE_PACKED (typenode);
kono
parents:
diff changeset
2797
kono
parents:
diff changeset
2798 gcc_assert (field);
kono
parents:
diff changeset
2799 if (!c->backend_decl)
kono
parents:
diff changeset
2800 c->backend_decl = field;
kono
parents:
diff changeset
2801
kono
parents:
diff changeset
2802 if (c->attr.pointer && c->attr.dimension
kono
parents:
diff changeset
2803 && !(c->ts.type == BT_DERIVED
kono
parents:
diff changeset
2804 && strcmp (c->name, "_data") == 0))
kono
parents:
diff changeset
2805 GFC_DECL_PTR_ARRAY_P (c->backend_decl) = 1;
kono
parents:
diff changeset
2806 }
kono
parents:
diff changeset
2807
kono
parents:
diff changeset
2808 /* Now lay out the derived type, including the fields. */
kono
parents:
diff changeset
2809 if (canonical)
kono
parents:
diff changeset
2810 TYPE_CANONICAL (typenode) = canonical;
kono
parents:
diff changeset
2811
kono
parents:
diff changeset
2812 gfc_finish_type (typenode);
kono
parents:
diff changeset
2813 gfc_set_decl_location (TYPE_STUB_DECL (typenode), &derived->declared_at);
kono
parents:
diff changeset
2814 if (derived->module && derived->ns->proc_name
kono
parents:
diff changeset
2815 && derived->ns->proc_name->attr.flavor == FL_MODULE)
kono
parents:
diff changeset
2816 {
kono
parents:
diff changeset
2817 if (derived->ns->proc_name->backend_decl
kono
parents:
diff changeset
2818 && TREE_CODE (derived->ns->proc_name->backend_decl)
kono
parents:
diff changeset
2819 == NAMESPACE_DECL)
kono
parents:
diff changeset
2820 {
kono
parents:
diff changeset
2821 TYPE_CONTEXT (typenode) = derived->ns->proc_name->backend_decl;
kono
parents:
diff changeset
2822 DECL_CONTEXT (TYPE_STUB_DECL (typenode))
kono
parents:
diff changeset
2823 = derived->ns->proc_name->backend_decl;
kono
parents:
diff changeset
2824 }
kono
parents:
diff changeset
2825 }
kono
parents:
diff changeset
2826
kono
parents:
diff changeset
2827 derived->backend_decl = typenode;
kono
parents:
diff changeset
2828
kono
parents:
diff changeset
2829 copy_derived_types:
kono
parents:
diff changeset
2830
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2831 for (c = derived->components; c; c = c->next)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2832 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2833 /* Do not add a caf_token field for class container components. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2834 if ((codimen || coarray_flag)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2835 && !c->attr.dimension && !c->attr.codimension
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2836 && (c->attr.allocatable || c->attr.pointer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2837 && !derived->attr.is_class)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2838 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2839 char caf_name[GFC_MAX_SYMBOL_LEN];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2840 gfc_component *token;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2841 snprintf (caf_name, GFC_MAX_SYMBOL_LEN, "_caf_%s", c->name);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2842 token = gfc_find_component (derived, caf_name, true, true, NULL);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2843 gcc_assert (token);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2844 c->caf_token = token->backend_decl;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2845 TREE_NO_WARNING (c->caf_token) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2846 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2847 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2848
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2849 for (gfc_symbol *dt = gfc_derived_types; dt; dt = dt->dt_next)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2850 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2851 gfc_copy_dt_decls_ifequal (derived, dt, false);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2852 if (dt->dt_next == gfc_derived_types)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2853 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2854 }
111
kono
parents:
diff changeset
2855
kono
parents:
diff changeset
2856 return derived->backend_decl;
kono
parents:
diff changeset
2857 }
kono
parents:
diff changeset
2858
kono
parents:
diff changeset
2859
kono
parents:
diff changeset
2860 int
kono
parents:
diff changeset
2861 gfc_return_by_reference (gfc_symbol * sym)
kono
parents:
diff changeset
2862 {
kono
parents:
diff changeset
2863 if (!sym->attr.function)
kono
parents:
diff changeset
2864 return 0;
kono
parents:
diff changeset
2865
kono
parents:
diff changeset
2866 if (sym->attr.dimension)
kono
parents:
diff changeset
2867 return 1;
kono
parents:
diff changeset
2868
kono
parents:
diff changeset
2869 if (sym->ts.type == BT_CHARACTER
kono
parents:
diff changeset
2870 && !sym->attr.is_bind_c
kono
parents:
diff changeset
2871 && (!sym->attr.result
kono
parents:
diff changeset
2872 || !sym->ns->proc_name
kono
parents:
diff changeset
2873 || !sym->ns->proc_name->attr.is_bind_c))
kono
parents:
diff changeset
2874 return 1;
kono
parents:
diff changeset
2875
kono
parents:
diff changeset
2876 /* Possibly return complex numbers by reference for g77 compatibility.
kono
parents:
diff changeset
2877 We don't do this for calls to intrinsics (as the library uses the
kono
parents:
diff changeset
2878 -fno-f2c calling convention), nor for calls to functions which always
kono
parents:
diff changeset
2879 require an explicit interface, as no compatibility problems can
kono
parents:
diff changeset
2880 arise there. */
kono
parents:
diff changeset
2881 if (flag_f2c && sym->ts.type == BT_COMPLEX
kono
parents:
diff changeset
2882 && !sym->attr.intrinsic && !sym->attr.always_explicit)
kono
parents:
diff changeset
2883 return 1;
kono
parents:
diff changeset
2884
kono
parents:
diff changeset
2885 return 0;
kono
parents:
diff changeset
2886 }
kono
parents:
diff changeset
2887
kono
parents:
diff changeset
2888 static tree
kono
parents:
diff changeset
2889 gfc_get_mixed_entry_union (gfc_namespace *ns)
kono
parents:
diff changeset
2890 {
kono
parents:
diff changeset
2891 tree type;
kono
parents:
diff changeset
2892 tree *chain = NULL;
kono
parents:
diff changeset
2893 char name[GFC_MAX_SYMBOL_LEN + 1];
kono
parents:
diff changeset
2894 gfc_entry_list *el, *el2;
kono
parents:
diff changeset
2895
kono
parents:
diff changeset
2896 gcc_assert (ns->proc_name->attr.mixed_entry_master);
kono
parents:
diff changeset
2897 gcc_assert (memcmp (ns->proc_name->name, "master.", 7) == 0);
kono
parents:
diff changeset
2898
kono
parents:
diff changeset
2899 snprintf (name, GFC_MAX_SYMBOL_LEN, "munion.%s", ns->proc_name->name + 7);
kono
parents:
diff changeset
2900
kono
parents:
diff changeset
2901 /* Build the type node. */
kono
parents:
diff changeset
2902 type = make_node (UNION_TYPE);
kono
parents:
diff changeset
2903
kono
parents:
diff changeset
2904 TYPE_NAME (type) = get_identifier (name);
kono
parents:
diff changeset
2905
kono
parents:
diff changeset
2906 for (el = ns->entries; el; el = el->next)
kono
parents:
diff changeset
2907 {
kono
parents:
diff changeset
2908 /* Search for duplicates. */
kono
parents:
diff changeset
2909 for (el2 = ns->entries; el2 != el; el2 = el2->next)
kono
parents:
diff changeset
2910 if (el2->sym->result == el->sym->result)
kono
parents:
diff changeset
2911 break;
kono
parents:
diff changeset
2912
kono
parents:
diff changeset
2913 if (el == el2)
kono
parents:
diff changeset
2914 gfc_add_field_to_struct_1 (type,
kono
parents:
diff changeset
2915 get_identifier (el->sym->result->name),
kono
parents:
diff changeset
2916 gfc_sym_type (el->sym->result), &chain);
kono
parents:
diff changeset
2917 }
kono
parents:
diff changeset
2918
kono
parents:
diff changeset
2919 /* Finish off the type. */
kono
parents:
diff changeset
2920 gfc_finish_type (type);
kono
parents:
diff changeset
2921 TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type)) = 1;
kono
parents:
diff changeset
2922 return type;
kono
parents:
diff changeset
2923 }
kono
parents:
diff changeset
2924
kono
parents:
diff changeset
2925 /* Create a "fn spec" based on the formal arguments;
kono
parents:
diff changeset
2926 cf. create_function_arglist. */
kono
parents:
diff changeset
2927
kono
parents:
diff changeset
2928 static tree
kono
parents:
diff changeset
2929 create_fn_spec (gfc_symbol *sym, tree fntype)
kono
parents:
diff changeset
2930 {
kono
parents:
diff changeset
2931 char spec[150];
kono
parents:
diff changeset
2932 size_t spec_len;
kono
parents:
diff changeset
2933 gfc_formal_arglist *f;
kono
parents:
diff changeset
2934 tree tmp;
kono
parents:
diff changeset
2935
kono
parents:
diff changeset
2936 memset (&spec, 0, sizeof (spec));
kono
parents:
diff changeset
2937 spec[0] = '.';
kono
parents:
diff changeset
2938 spec_len = 1;
kono
parents:
diff changeset
2939
kono
parents:
diff changeset
2940 if (sym->attr.entry_master)
kono
parents:
diff changeset
2941 spec[spec_len++] = 'R';
kono
parents:
diff changeset
2942 if (gfc_return_by_reference (sym))
kono
parents:
diff changeset
2943 {
kono
parents:
diff changeset
2944 gfc_symbol *result = sym->result ? sym->result : sym;
kono
parents:
diff changeset
2945
kono
parents:
diff changeset
2946 if (result->attr.pointer || sym->attr.proc_pointer)
kono
parents:
diff changeset
2947 spec[spec_len++] = '.';
kono
parents:
diff changeset
2948 else
kono
parents:
diff changeset
2949 spec[spec_len++] = 'w';
kono
parents:
diff changeset
2950 if (sym->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
2951 spec[spec_len++] = 'R';
kono
parents:
diff changeset
2952 }
kono
parents:
diff changeset
2953
kono
parents:
diff changeset
2954 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
kono
parents:
diff changeset
2955 if (spec_len < sizeof (spec))
kono
parents:
diff changeset
2956 {
kono
parents:
diff changeset
2957 if (!f->sym || f->sym->attr.pointer || f->sym->attr.target
kono
parents:
diff changeset
2958 || f->sym->attr.external || f->sym->attr.cray_pointer
kono
parents:
diff changeset
2959 || (f->sym->ts.type == BT_DERIVED
kono
parents:
diff changeset
2960 && (f->sym->ts.u.derived->attr.proc_pointer_comp
kono
parents:
diff changeset
2961 || f->sym->ts.u.derived->attr.pointer_comp))
kono
parents:
diff changeset
2962 || (f->sym->ts.type == BT_CLASS
kono
parents:
diff changeset
2963 && (CLASS_DATA (f->sym)->ts.u.derived->attr.proc_pointer_comp
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2964 || CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2965 || (f->sym->ts.type == BT_INTEGER && f->sym->ts.is_c_interop))
111
kono
parents:
diff changeset
2966 spec[spec_len++] = '.';
kono
parents:
diff changeset
2967 else if (f->sym->attr.intent == INTENT_IN)
kono
parents:
diff changeset
2968 spec[spec_len++] = 'r';
kono
parents:
diff changeset
2969 else if (f->sym)
kono
parents:
diff changeset
2970 spec[spec_len++] = 'w';
kono
parents:
diff changeset
2971 }
kono
parents:
diff changeset
2972
kono
parents:
diff changeset
2973 tmp = build_tree_list (NULL_TREE, build_string (spec_len, spec));
kono
parents:
diff changeset
2974 tmp = tree_cons (get_identifier ("fn spec"), tmp, TYPE_ATTRIBUTES (fntype));
kono
parents:
diff changeset
2975 return build_type_attribute_variant (fntype, tmp);
kono
parents:
diff changeset
2976 }
kono
parents:
diff changeset
2977
kono
parents:
diff changeset
2978 tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2979 gfc_get_function_type (gfc_symbol * sym, gfc_actual_arglist *actual_args)
111
kono
parents:
diff changeset
2980 {
kono
parents:
diff changeset
2981 tree type;
kono
parents:
diff changeset
2982 vec<tree, va_gc> *typelist = NULL;
kono
parents:
diff changeset
2983 gfc_formal_arglist *f;
kono
parents:
diff changeset
2984 gfc_symbol *arg;
kono
parents:
diff changeset
2985 int alternate_return = 0;
kono
parents:
diff changeset
2986 bool is_varargs = true;
kono
parents:
diff changeset
2987
kono
parents:
diff changeset
2988 /* Make sure this symbol is a function, a subroutine or the main
kono
parents:
diff changeset
2989 program. */
kono
parents:
diff changeset
2990 gcc_assert (sym->attr.flavor == FL_PROCEDURE
kono
parents:
diff changeset
2991 || sym->attr.flavor == FL_PROGRAM);
kono
parents:
diff changeset
2992
kono
parents:
diff changeset
2993 /* To avoid recursing infinitely on recursive types, we use error_mark_node
kono
parents:
diff changeset
2994 so that they can be detected here and handled further down. */
kono
parents:
diff changeset
2995 if (sym->backend_decl == NULL)
kono
parents:
diff changeset
2996 sym->backend_decl = error_mark_node;
kono
parents:
diff changeset
2997 else if (sym->backend_decl == error_mark_node)
kono
parents:
diff changeset
2998 goto arg_type_list_done;
kono
parents:
diff changeset
2999 else if (sym->attr.proc_pointer)
kono
parents:
diff changeset
3000 return TREE_TYPE (TREE_TYPE (sym->backend_decl));
kono
parents:
diff changeset
3001 else
kono
parents:
diff changeset
3002 return TREE_TYPE (sym->backend_decl);
kono
parents:
diff changeset
3003
kono
parents:
diff changeset
3004 if (sym->attr.entry_master)
kono
parents:
diff changeset
3005 /* Additional parameter for selecting an entry point. */
kono
parents:
diff changeset
3006 vec_safe_push (typelist, gfc_array_index_type);
kono
parents:
diff changeset
3007
kono
parents:
diff changeset
3008 if (sym->result)
kono
parents:
diff changeset
3009 arg = sym->result;
kono
parents:
diff changeset
3010 else
kono
parents:
diff changeset
3011 arg = sym;
kono
parents:
diff changeset
3012
kono
parents:
diff changeset
3013 if (arg->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
3014 gfc_conv_const_charlen (arg->ts.u.cl);
kono
parents:
diff changeset
3015
kono
parents:
diff changeset
3016 /* Some functions we use an extra parameter for the return value. */
kono
parents:
diff changeset
3017 if (gfc_return_by_reference (sym))
kono
parents:
diff changeset
3018 {
kono
parents:
diff changeset
3019 type = gfc_sym_type (arg);
kono
parents:
diff changeset
3020 if (arg->ts.type == BT_COMPLEX
kono
parents:
diff changeset
3021 || arg->attr.dimension
kono
parents:
diff changeset
3022 || arg->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
3023 type = build_reference_type (type);
kono
parents:
diff changeset
3024
kono
parents:
diff changeset
3025 vec_safe_push (typelist, type);
kono
parents:
diff changeset
3026 if (arg->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
3027 {
kono
parents:
diff changeset
3028 if (!arg->ts.deferred)
kono
parents:
diff changeset
3029 /* Transfer by value. */
kono
parents:
diff changeset
3030 vec_safe_push (typelist, gfc_charlen_type_node);
kono
parents:
diff changeset
3031 else
kono
parents:
diff changeset
3032 /* Deferred character lengths are transferred by reference
kono
parents:
diff changeset
3033 so that the value can be returned. */
kono
parents:
diff changeset
3034 vec_safe_push (typelist, build_pointer_type(gfc_charlen_type_node));
kono
parents:
diff changeset
3035 }
kono
parents:
diff changeset
3036 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3037 if (sym->backend_decl == error_mark_node && actual_args != NULL
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3038 && sym->formal == NULL && (sym->attr.proc == PROC_EXTERNAL
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3039 || sym->attr.proc == PROC_UNKNOWN))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3040 gfc_get_formal_from_actual_arglist (sym, actual_args);
111
kono
parents:
diff changeset
3041
kono
parents:
diff changeset
3042 /* Build the argument types for the function. */
kono
parents:
diff changeset
3043 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
kono
parents:
diff changeset
3044 {
kono
parents:
diff changeset
3045 arg = f->sym;
kono
parents:
diff changeset
3046 if (arg)
kono
parents:
diff changeset
3047 {
kono
parents:
diff changeset
3048 /* Evaluate constant character lengths here so that they can be
kono
parents:
diff changeset
3049 included in the type. */
kono
parents:
diff changeset
3050 if (arg->ts.type == BT_CHARACTER)
kono
parents:
diff changeset
3051 gfc_conv_const_charlen (arg->ts.u.cl);
kono
parents:
diff changeset
3052
kono
parents:
diff changeset
3053 if (arg->attr.flavor == FL_PROCEDURE)
kono
parents:
diff changeset
3054 {
kono
parents:
diff changeset
3055 type = gfc_get_function_type (arg);
kono
parents:
diff changeset
3056 type = build_pointer_type (type);
kono
parents:
diff changeset
3057 }
kono
parents:
diff changeset
3058 else
kono
parents:
diff changeset
3059 type = gfc_sym_type (arg);
kono
parents:
diff changeset
3060
kono
parents:
diff changeset
3061 /* Parameter Passing Convention
kono
parents:
diff changeset
3062
kono
parents:
diff changeset
3063 We currently pass all parameters by reference.
kono
parents:
diff changeset
3064 Parameters with INTENT(IN) could be passed by value.
kono
parents:
diff changeset
3065 The problem arises if a function is called via an implicit
kono
parents:
diff changeset
3066 prototype. In this situation the INTENT is not known.
kono
parents:
diff changeset
3067 For this reason all parameters to global functions must be
kono
parents:
diff changeset
3068 passed by reference. Passing by value would potentially
kono
parents:
diff changeset
3069 generate bad code. Worse there would be no way of telling that
kono
parents:
diff changeset
3070 this code was bad, except that it would give incorrect results.
kono
parents:
diff changeset
3071
kono
parents:
diff changeset
3072 Contained procedures could pass by value as these are never
kono
parents:
diff changeset
3073 used without an explicit interface, and cannot be passed as
kono
parents:
diff changeset
3074 actual parameters for a dummy procedure. */
kono
parents:
diff changeset
3075
kono
parents:
diff changeset
3076 vec_safe_push (typelist, type);
kono
parents:
diff changeset
3077 }
kono
parents:
diff changeset
3078 else
kono
parents:
diff changeset
3079 {
kono
parents:
diff changeset
3080 if (sym->attr.subroutine)
kono
parents:
diff changeset
3081 alternate_return = 1;
kono
parents:
diff changeset
3082 }
kono
parents:
diff changeset
3083 }
kono
parents:
diff changeset
3084
kono
parents:
diff changeset
3085 /* Add hidden string length parameters. */
kono
parents:
diff changeset
3086 for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
kono
parents:
diff changeset
3087 {
kono
parents:
diff changeset
3088 arg = f->sym;
kono
parents:
diff changeset
3089 if (arg && arg->ts.type == BT_CHARACTER && !sym->attr.is_bind_c)
kono
parents:
diff changeset
3090 {
kono
parents:
diff changeset
3091 if (!arg->ts.deferred)
kono
parents:
diff changeset
3092 /* Transfer by value. */
kono
parents:
diff changeset
3093 type = gfc_charlen_type_node;
kono
parents:
diff changeset
3094 else
kono
parents:
diff changeset
3095 /* Deferred character lengths are transferred by reference
kono
parents:
diff changeset
3096 so that the value can be returned. */
kono
parents:
diff changeset
3097 type = build_pointer_type (gfc_charlen_type_node);
kono
parents:
diff changeset
3098
kono
parents:
diff changeset
3099 vec_safe_push (typelist, type);
kono
parents:
diff changeset
3100 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3101 /* For noncharacter scalar intrinsic types, VALUE passes the value,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3102 hence, the optional status cannot be transferred via a NULL pointer.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3103 Thus, we will use a hidden argument in that case. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3104 else if (arg
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3105 && arg->attr.optional
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3106 && arg->attr.value
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3107 && !arg->attr.dimension
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3108 && arg->ts.type != BT_CLASS
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3109 && !gfc_bt_struct (arg->ts.type))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3110 vec_safe_push (typelist, boolean_type_node);
111
kono
parents:
diff changeset
3111 }
kono
parents:
diff changeset
3112
kono
parents:
diff changeset
3113 if (!vec_safe_is_empty (typelist)
kono
parents:
diff changeset
3114 || sym->attr.is_main_program
kono
parents:
diff changeset
3115 || sym->attr.if_source != IFSRC_UNKNOWN)
kono
parents:
diff changeset
3116 is_varargs = false;
kono
parents:
diff changeset
3117
kono
parents:
diff changeset
3118 if (sym->backend_decl == error_mark_node)
kono
parents:
diff changeset
3119 sym->backend_decl = NULL_TREE;
kono
parents:
diff changeset
3120
kono
parents:
diff changeset
3121 arg_type_list_done:
kono
parents:
diff changeset
3122
kono
parents:
diff changeset
3123 if (alternate_return)
kono
parents:
diff changeset
3124 type = integer_type_node;
kono
parents:
diff changeset
3125 else if (!sym->attr.function || gfc_return_by_reference (sym))
kono
parents:
diff changeset
3126 type = void_type_node;
kono
parents:
diff changeset
3127 else if (sym->attr.mixed_entry_master)
kono
parents:
diff changeset
3128 type = gfc_get_mixed_entry_union (sym->ns);
kono
parents:
diff changeset
3129 else if (flag_f2c && sym->ts.type == BT_REAL
kono
parents:
diff changeset
3130 && sym->ts.kind == gfc_default_real_kind
kono
parents:
diff changeset
3131 && !sym->attr.always_explicit)
kono
parents:
diff changeset
3132 {
kono
parents:
diff changeset
3133 /* Special case: f2c calling conventions require that (scalar)
kono
parents:
diff changeset
3134 default REAL functions return the C type double instead. f2c
kono
parents:
diff changeset
3135 compatibility is only an issue with functions that don't
kono
parents:
diff changeset
3136 require an explicit interface, as only these could be
kono
parents:
diff changeset
3137 implemented in Fortran 77. */
kono
parents:
diff changeset
3138 sym->ts.kind = gfc_default_double_kind;
kono
parents:
diff changeset
3139 type = gfc_typenode_for_spec (&sym->ts);
kono
parents:
diff changeset
3140 sym->ts.kind = gfc_default_real_kind;
kono
parents:
diff changeset
3141 }
kono
parents:
diff changeset
3142 else if (sym->result && sym->result->attr.proc_pointer)
kono
parents:
diff changeset
3143 /* Procedure pointer return values. */
kono
parents:
diff changeset
3144 {
kono
parents:
diff changeset
3145 if (sym->result->attr.result && strcmp (sym->name,"ppr@") != 0)
kono
parents:
diff changeset
3146 {
kono
parents:
diff changeset
3147 /* Unset proc_pointer as gfc_get_function_type
kono
parents:
diff changeset
3148 is called recursively. */
kono
parents:
diff changeset
3149 sym->result->attr.proc_pointer = 0;
kono
parents:
diff changeset
3150 type = build_pointer_type (gfc_get_function_type (sym->result));
kono
parents:
diff changeset
3151 sym->result->attr.proc_pointer = 1;
kono
parents:
diff changeset
3152 }
kono
parents:
diff changeset
3153 else
kono
parents:
diff changeset
3154 type = gfc_sym_type (sym->result);
kono
parents:
diff changeset
3155 }
kono
parents:
diff changeset
3156 else
kono
parents:
diff changeset
3157 type = gfc_sym_type (sym);
kono
parents:
diff changeset
3158
kono
parents:
diff changeset
3159 if (is_varargs)
kono
parents:
diff changeset
3160 type = build_varargs_function_type_vec (type, typelist);
kono
parents:
diff changeset
3161 else
kono
parents:
diff changeset
3162 type = build_function_type_vec (type, typelist);
kono
parents:
diff changeset
3163 type = create_fn_spec (sym, type);
kono
parents:
diff changeset
3164
kono
parents:
diff changeset
3165 return type;
kono
parents:
diff changeset
3166 }
kono
parents:
diff changeset
3167
kono
parents:
diff changeset
3168 /* Language hooks for middle-end access to type nodes. */
kono
parents:
diff changeset
3169
kono
parents:
diff changeset
3170 /* Return an integer type with BITS bits of precision,
kono
parents:
diff changeset
3171 that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
kono
parents:
diff changeset
3172
kono
parents:
diff changeset
3173 tree
kono
parents:
diff changeset
3174 gfc_type_for_size (unsigned bits, int unsignedp)
kono
parents:
diff changeset
3175 {
kono
parents:
diff changeset
3176 if (!unsignedp)
kono
parents:
diff changeset
3177 {
kono
parents:
diff changeset
3178 int i;
kono
parents:
diff changeset
3179 for (i = 0; i <= MAX_INT_KINDS; ++i)
kono
parents:
diff changeset
3180 {
kono
parents:
diff changeset
3181 tree type = gfc_integer_types[i];
kono
parents:
diff changeset
3182 if (type && bits == TYPE_PRECISION (type))
kono
parents:
diff changeset
3183 return type;
kono
parents:
diff changeset
3184 }
kono
parents:
diff changeset
3185
kono
parents:
diff changeset
3186 /* Handle TImode as a special case because it is used by some backends
kono
parents:
diff changeset
3187 (e.g. ARM) even though it is not available for normal use. */
kono
parents:
diff changeset
3188 #if HOST_BITS_PER_WIDE_INT >= 64
kono
parents:
diff changeset
3189 if (bits == TYPE_PRECISION (intTI_type_node))
kono
parents:
diff changeset
3190 return intTI_type_node;
kono
parents:
diff changeset
3191 #endif
kono
parents:
diff changeset
3192
kono
parents:
diff changeset
3193 if (bits <= TYPE_PRECISION (intQI_type_node))
kono
parents:
diff changeset
3194 return intQI_type_node;
kono
parents:
diff changeset
3195 if (bits <= TYPE_PRECISION (intHI_type_node))
kono
parents:
diff changeset
3196 return intHI_type_node;
kono
parents:
diff changeset
3197 if (bits <= TYPE_PRECISION (intSI_type_node))
kono
parents:
diff changeset
3198 return intSI_type_node;
kono
parents:
diff changeset
3199 if (bits <= TYPE_PRECISION (intDI_type_node))
kono
parents:
diff changeset
3200 return intDI_type_node;
kono
parents:
diff changeset
3201 if (bits <= TYPE_PRECISION (intTI_type_node))
kono
parents:
diff changeset
3202 return intTI_type_node;
kono
parents:
diff changeset
3203 }
kono
parents:
diff changeset
3204 else
kono
parents:
diff changeset
3205 {
kono
parents:
diff changeset
3206 if (bits <= TYPE_PRECISION (unsigned_intQI_type_node))
kono
parents:
diff changeset
3207 return unsigned_intQI_type_node;
kono
parents:
diff changeset
3208 if (bits <= TYPE_PRECISION (unsigned_intHI_type_node))
kono
parents:
diff changeset
3209 return unsigned_intHI_type_node;
kono
parents:
diff changeset
3210 if (bits <= TYPE_PRECISION (unsigned_intSI_type_node))
kono
parents:
diff changeset
3211 return unsigned_intSI_type_node;
kono
parents:
diff changeset
3212 if (bits <= TYPE_PRECISION (unsigned_intDI_type_node))
kono
parents:
diff changeset
3213 return unsigned_intDI_type_node;
kono
parents:
diff changeset
3214 if (bits <= TYPE_PRECISION (unsigned_intTI_type_node))
kono
parents:
diff changeset
3215 return unsigned_intTI_type_node;
kono
parents:
diff changeset
3216 }
kono
parents:
diff changeset
3217
kono
parents:
diff changeset
3218 return NULL_TREE;
kono
parents:
diff changeset
3219 }
kono
parents:
diff changeset
3220
kono
parents:
diff changeset
3221 /* Return a data type that has machine mode MODE. If the mode is an
kono
parents:
diff changeset
3222 integer, then UNSIGNEDP selects between signed and unsigned types. */
kono
parents:
diff changeset
3223
kono
parents:
diff changeset
3224 tree
kono
parents:
diff changeset
3225 gfc_type_for_mode (machine_mode mode, int unsignedp)
kono
parents:
diff changeset
3226 {
kono
parents:
diff changeset
3227 int i;
kono
parents:
diff changeset
3228 tree *base;
kono
parents:
diff changeset
3229 scalar_int_mode int_mode;
kono
parents:
diff changeset
3230
kono
parents:
diff changeset
3231 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
kono
parents:
diff changeset
3232 base = gfc_real_types;
kono
parents:
diff changeset
3233 else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
kono
parents:
diff changeset
3234 base = gfc_complex_types;
kono
parents:
diff changeset
3235 else if (is_a <scalar_int_mode> (mode, &int_mode))
kono
parents:
diff changeset
3236 {
kono
parents:
diff changeset
3237 tree type = gfc_type_for_size (GET_MODE_PRECISION (int_mode), unsignedp);
kono
parents:
diff changeset
3238 return type != NULL_TREE && mode == TYPE_MODE (type) ? type : NULL_TREE;
kono
parents:
diff changeset
3239 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3240 else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3241 && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3242 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3243 unsigned int elem_bits = vector_element_size (GET_MODE_BITSIZE (mode),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3244 GET_MODE_NUNITS (mode));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3245 tree bool_type = build_nonstandard_boolean_type (elem_bits);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3246 return build_vector_type_for_mode (bool_type, mode);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3247 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3248 else if (VECTOR_MODE_P (mode)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3249 && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
111
kono
parents:
diff changeset
3250 {
kono
parents:
diff changeset
3251 machine_mode inner_mode = GET_MODE_INNER (mode);
kono
parents:
diff changeset
3252 tree inner_type = gfc_type_for_mode (inner_mode, unsignedp);
kono
parents:
diff changeset
3253 if (inner_type != NULL_TREE)
kono
parents:
diff changeset
3254 return build_vector_type_for_mode (inner_type, mode);
kono
parents:
diff changeset
3255 return NULL_TREE;
kono
parents:
diff changeset
3256 }
kono
parents:
diff changeset
3257 else
kono
parents:
diff changeset
3258 return NULL_TREE;
kono
parents:
diff changeset
3259
kono
parents:
diff changeset
3260 for (i = 0; i <= MAX_REAL_KINDS; ++i)
kono
parents:
diff changeset
3261 {
kono
parents:
diff changeset
3262 tree type = base[i];
kono
parents:
diff changeset
3263 if (type && mode == TYPE_MODE (type))
kono
parents:
diff changeset
3264 return type;
kono
parents:
diff changeset
3265 }
kono
parents:
diff changeset
3266
kono
parents:
diff changeset
3267 return NULL_TREE;
kono
parents:
diff changeset
3268 }
kono
parents:
diff changeset
3269
kono
parents:
diff changeset
3270 /* Return TRUE if TYPE is a type with a hidden descriptor, fill in INFO
kono
parents:
diff changeset
3271 in that case. */
kono
parents:
diff changeset
3272
kono
parents:
diff changeset
3273 bool
kono
parents:
diff changeset
3274 gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
kono
parents:
diff changeset
3275 {
kono
parents:
diff changeset
3276 int rank, dim;
kono
parents:
diff changeset
3277 bool indirect = false;
kono
parents:
diff changeset
3278 tree etype, ptype, t, base_decl;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3279 tree data_off, span_off, dim_off, dtype_off, dim_size, elem_size;
111
kono
parents:
diff changeset
3280 tree lower_suboff, upper_suboff, stride_suboff;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3281 tree dtype, field, rank_off;
111
kono
parents:
diff changeset
3282
kono
parents:
diff changeset
3283 if (! GFC_DESCRIPTOR_TYPE_P (type))
kono
parents:
diff changeset
3284 {
kono
parents:
diff changeset
3285 if (! POINTER_TYPE_P (type))
kono
parents:
diff changeset
3286 return false;
kono
parents:
diff changeset
3287 type = TREE_TYPE (type);
kono
parents:
diff changeset
3288 if (! GFC_DESCRIPTOR_TYPE_P (type))
kono
parents:
diff changeset
3289 return false;
kono
parents:
diff changeset
3290 indirect = true;
kono
parents:
diff changeset
3291 }
kono
parents:
diff changeset
3292
kono
parents:
diff changeset
3293 rank = GFC_TYPE_ARRAY_RANK (type);
kono
parents:
diff changeset
3294 if (rank >= (int) (sizeof (info->dimen) / sizeof (info->dimen[0])))
kono
parents:
diff changeset
3295 return false;
kono
parents:
diff changeset
3296
kono
parents:
diff changeset
3297 etype = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
kono
parents:
diff changeset
3298 gcc_assert (POINTER_TYPE_P (etype));
kono
parents:
diff changeset
3299 etype = TREE_TYPE (etype);
kono
parents:
diff changeset
3300
kono
parents:
diff changeset
3301 /* If the type is not a scalar coarray. */
kono
parents:
diff changeset
3302 if (TREE_CODE (etype) == ARRAY_TYPE)
kono
parents:
diff changeset
3303 etype = TREE_TYPE (etype);
kono
parents:
diff changeset
3304
kono
parents:
diff changeset
3305 /* Can't handle variable sized elements yet. */
kono
parents:
diff changeset
3306 if (int_size_in_bytes (etype) <= 0)
kono
parents:
diff changeset
3307 return false;
kono
parents:
diff changeset
3308 /* Nor non-constant lower bounds in assumed shape arrays. */
kono
parents:
diff changeset
3309 if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE
kono
parents:
diff changeset
3310 || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT)
kono
parents:
diff changeset
3311 {
kono
parents:
diff changeset
3312 for (dim = 0; dim < rank; dim++)
kono
parents:
diff changeset
3313 if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE
kono
parents:
diff changeset
3314 || TREE_CODE (GFC_TYPE_ARRAY_LBOUND (type, dim)) != INTEGER_CST)
kono
parents:
diff changeset
3315 return false;
kono
parents:
diff changeset
3316 }
kono
parents:
diff changeset
3317
kono
parents:
diff changeset
3318 memset (info, '\0', sizeof (*info));
kono
parents:
diff changeset
3319 info->ndimensions = rank;
kono
parents:
diff changeset
3320 info->ordering = array_descr_ordering_column_major;
kono
parents:
diff changeset
3321 info->element_type = etype;
kono
parents:
diff changeset
3322 ptype = build_pointer_type (gfc_array_index_type);
kono
parents:
diff changeset
3323 base_decl = GFC_TYPE_ARRAY_BASE_DECL (type, indirect);
kono
parents:
diff changeset
3324 if (!base_decl)
kono
parents:
diff changeset
3325 {
kono
parents:
diff changeset
3326 base_decl = make_node (DEBUG_EXPR_DECL);
kono
parents:
diff changeset
3327 DECL_ARTIFICIAL (base_decl) = 1;
kono
parents:
diff changeset
3328 TREE_TYPE (base_decl) = indirect ? build_pointer_type (ptype) : ptype;
kono
parents:
diff changeset
3329 SET_DECL_MODE (base_decl, TYPE_MODE (TREE_TYPE (base_decl)));
kono
parents:
diff changeset
3330 GFC_TYPE_ARRAY_BASE_DECL (type, indirect) = base_decl;
kono
parents:
diff changeset
3331 }
kono
parents:
diff changeset
3332 info->base_decl = base_decl;
kono
parents:
diff changeset
3333 if (indirect)
kono
parents:
diff changeset
3334 base_decl = build1 (INDIRECT_REF, ptype, base_decl);
kono
parents:
diff changeset
3335
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3336 gfc_get_descriptor_offsets_for_info (type, &data_off, &dtype_off, &span_off,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3337 &dim_off, &dim_size, &stride_suboff,
111
kono
parents:
diff changeset
3338 &lower_suboff, &upper_suboff);
kono
parents:
diff changeset
3339
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3340 t = fold_build_pointer_plus (base_decl, span_off);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3341 elem_size = build1 (INDIRECT_REF, gfc_array_index_type, t);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3342
111
kono
parents:
diff changeset
3343 t = base_decl;
kono
parents:
diff changeset
3344 if (!integer_zerop (data_off))
kono
parents:
diff changeset
3345 t = fold_build_pointer_plus (t, data_off);
kono
parents:
diff changeset
3346 t = build1 (NOP_EXPR, build_pointer_type (ptr_type_node), t);
kono
parents:
diff changeset
3347 info->data_location = build1 (INDIRECT_REF, ptr_type_node, t);
kono
parents:
diff changeset
3348 if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ALLOCATABLE)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3349 info->allocated = build2 (NE_EXPR, logical_type_node,
111
kono
parents:
diff changeset
3350 info->data_location, null_pointer_node);
kono
parents:
diff changeset
3351 else if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER
kono
parents:
diff changeset
3352 || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3353 info->associated = build2 (NE_EXPR, logical_type_node,
111
kono
parents:
diff changeset
3354 info->data_location, null_pointer_node);
kono
parents:
diff changeset
3355 if ((GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK
kono
parents:
diff changeset
3356 || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_CONT)
kono
parents:
diff changeset
3357 && dwarf_version >= 5)
kono
parents:
diff changeset
3358 {
kono
parents:
diff changeset
3359 rank = 1;
kono
parents:
diff changeset
3360 info->ndimensions = 1;
kono
parents:
diff changeset
3361 t = base_decl;
kono
parents:
diff changeset
3362 if (!integer_zerop (dtype_off))
kono
parents:
diff changeset
3363 t = fold_build_pointer_plus (t, dtype_off);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3364 dtype = TYPE_MAIN_VARIANT (get_dtype_type_node ());
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3365 field = gfc_advance_chain (TYPE_FIELDS (dtype), GFC_DTYPE_RANK);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3366 rank_off = byte_position (field);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3367 if (!integer_zerop (dtype_off))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3368 t = fold_build_pointer_plus (t, rank_off);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3369
111
kono
parents:
diff changeset
3370 t = build1 (NOP_EXPR, build_pointer_type (gfc_array_index_type), t);
kono
parents:
diff changeset
3371 t = build1 (INDIRECT_REF, gfc_array_index_type, t);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3372 info->rank = t;
111
kono
parents:
diff changeset
3373 t = build0 (PLACEHOLDER_EXPR, TREE_TYPE (dim_off));
kono
parents:
diff changeset
3374 t = size_binop (MULT_EXPR, t, dim_size);
kono
parents:
diff changeset
3375 dim_off = build2 (PLUS_EXPR, TREE_TYPE (dim_off), t, dim_off);
kono
parents:
diff changeset
3376 }
kono
parents:
diff changeset
3377
kono
parents:
diff changeset
3378 for (dim = 0; dim < rank; dim++)
kono
parents:
diff changeset
3379 {
kono
parents:
diff changeset
3380 t = fold_build_pointer_plus (base_decl,
kono
parents:
diff changeset
3381 size_binop (PLUS_EXPR,
kono
parents:
diff changeset
3382 dim_off, lower_suboff));
kono
parents:
diff changeset
3383 t = build1 (INDIRECT_REF, gfc_array_index_type, t);
kono
parents:
diff changeset
3384 info->dimen[dim].lower_bound = t;
kono
parents:
diff changeset
3385 t = fold_build_pointer_plus (base_decl,
kono
parents:
diff changeset
3386 size_binop (PLUS_EXPR,
kono
parents:
diff changeset
3387 dim_off, upper_suboff));
kono
parents:
diff changeset
3388 t = build1 (INDIRECT_REF, gfc_array_index_type, t);
kono
parents:
diff changeset
3389 info->dimen[dim].upper_bound = t;
kono
parents:
diff changeset
3390 if (GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE
kono
parents:
diff changeset
3391 || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_SHAPE_CONT)
kono
parents:
diff changeset
3392 {
kono
parents:
diff changeset
3393 /* Assumed shape arrays have known lower bounds. */
kono
parents:
diff changeset
3394 info->dimen[dim].upper_bound
kono
parents:
diff changeset
3395 = build2 (MINUS_EXPR, gfc_array_index_type,
kono
parents:
diff changeset
3396 info->dimen[dim].upper_bound,
kono
parents:
diff changeset
3397 info->dimen[dim].lower_bound);
kono
parents:
diff changeset
3398 info->dimen[dim].lower_bound
kono
parents:
diff changeset
3399 = fold_convert (gfc_array_index_type,
kono
parents:
diff changeset
3400 GFC_TYPE_ARRAY_LBOUND (type, dim));
kono
parents:
diff changeset
3401 info->dimen[dim].upper_bound
kono
parents:
diff changeset
3402 = build2 (PLUS_EXPR, gfc_array_index_type,
kono
parents:
diff changeset
3403 info->dimen[dim].lower_bound,
kono
parents:
diff changeset
3404 info->dimen[dim].upper_bound);
kono
parents:
diff changeset
3405 }
kono
parents:
diff changeset
3406 t = fold_build_pointer_plus (base_decl,
kono
parents:
diff changeset
3407 size_binop (PLUS_EXPR,
kono
parents:
diff changeset
3408 dim_off, stride_suboff));
kono
parents:
diff changeset
3409 t = build1 (INDIRECT_REF, gfc_array_index_type, t);
kono
parents:
diff changeset
3410 t = build2 (MULT_EXPR, gfc_array_index_type, t, elem_size);
kono
parents:
diff changeset
3411 info->dimen[dim].stride = t;
kono
parents:
diff changeset
3412 if (dim + 1 < rank)
kono
parents:
diff changeset
3413 dim_off = size_binop (PLUS_EXPR, dim_off, dim_size);
kono
parents:
diff changeset
3414 }
kono
parents:
diff changeset
3415
kono
parents:
diff changeset
3416 return true;
kono
parents:
diff changeset
3417 }
kono
parents:
diff changeset
3418
kono
parents:
diff changeset
3419
kono
parents:
diff changeset
3420 /* Create a type to handle vector subscripts for coarray library calls. It
kono
parents:
diff changeset
3421 has the form:
kono
parents:
diff changeset
3422 struct caf_vector_t {
kono
parents:
diff changeset
3423 size_t nvec; // size of the vector
kono
parents:
diff changeset
3424 union {
kono
parents:
diff changeset
3425 struct {
kono
parents:
diff changeset
3426 void *vector;
kono
parents:
diff changeset
3427 int kind;
kono
parents:
diff changeset
3428 } v;
kono
parents:
diff changeset
3429 struct {
kono
parents:
diff changeset
3430 ptrdiff_t lower_bound;
kono
parents:
diff changeset
3431 ptrdiff_t upper_bound;
kono
parents:
diff changeset
3432 ptrdiff_t stride;
kono
parents:
diff changeset
3433 } triplet;
kono
parents:
diff changeset
3434 } u;
kono
parents:
diff changeset
3435 }
kono
parents:
diff changeset
3436 where nvec == 0 for DIMEN_ELEMENT or DIMEN_RANGE and nvec being the vector
kono
parents:
diff changeset
3437 size in case of DIMEN_VECTOR, where kind is the integer type of the vector. */
kono
parents:
diff changeset
3438
kono
parents:
diff changeset
3439 tree
kono
parents:
diff changeset
3440 gfc_get_caf_vector_type (int dim)
kono
parents:
diff changeset
3441 {
kono
parents:
diff changeset
3442 static tree vector_types[GFC_MAX_DIMENSIONS];
kono
parents:
diff changeset
3443 static tree vec_type = NULL_TREE;
kono
parents:
diff changeset
3444 tree triplet_struct_type, vect_struct_type, union_type, tmp, *chain;
kono
parents:
diff changeset
3445
kono
parents:
diff changeset
3446 if (vector_types[dim-1] != NULL_TREE)
kono
parents:
diff changeset
3447 return vector_types[dim-1];
kono
parents:
diff changeset
3448
kono
parents:
diff changeset
3449 if (vec_type == NULL_TREE)
kono
parents:
diff changeset
3450 {
kono
parents:
diff changeset
3451 chain = 0;
kono
parents:
diff changeset
3452 vect_struct_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3453 tmp = gfc_add_field_to_struct_1 (vect_struct_type,
kono
parents:
diff changeset
3454 get_identifier ("vector"),
kono
parents:
diff changeset
3455 pvoid_type_node, &chain);
kono
parents:
diff changeset
3456 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3457 tmp = gfc_add_field_to_struct_1 (vect_struct_type,
kono
parents:
diff changeset
3458 get_identifier ("kind"),
kono
parents:
diff changeset
3459 integer_type_node, &chain);
kono
parents:
diff changeset
3460 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3461 gfc_finish_type (vect_struct_type);
kono
parents:
diff changeset
3462
kono
parents:
diff changeset
3463 chain = 0;
kono
parents:
diff changeset
3464 triplet_struct_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3465 tmp = gfc_add_field_to_struct_1 (triplet_struct_type,
kono
parents:
diff changeset
3466 get_identifier ("lower_bound"),
kono
parents:
diff changeset
3467 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3468 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3469 tmp = gfc_add_field_to_struct_1 (triplet_struct_type,
kono
parents:
diff changeset
3470 get_identifier ("upper_bound"),
kono
parents:
diff changeset
3471 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3472 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3473 tmp = gfc_add_field_to_struct_1 (triplet_struct_type, get_identifier ("stride"),
kono
parents:
diff changeset
3474 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3475 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3476 gfc_finish_type (triplet_struct_type);
kono
parents:
diff changeset
3477
kono
parents:
diff changeset
3478 chain = 0;
kono
parents:
diff changeset
3479 union_type = make_node (UNION_TYPE);
kono
parents:
diff changeset
3480 tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("v"),
kono
parents:
diff changeset
3481 vect_struct_type, &chain);
kono
parents:
diff changeset
3482 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3483 tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("triplet"),
kono
parents:
diff changeset
3484 triplet_struct_type, &chain);
kono
parents:
diff changeset
3485 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3486 gfc_finish_type (union_type);
kono
parents:
diff changeset
3487
kono
parents:
diff changeset
3488 chain = 0;
kono
parents:
diff changeset
3489 vec_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3490 tmp = gfc_add_field_to_struct_1 (vec_type, get_identifier ("nvec"),
kono
parents:
diff changeset
3491 size_type_node, &chain);
kono
parents:
diff changeset
3492 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3493 tmp = gfc_add_field_to_struct_1 (vec_type, get_identifier ("u"),
kono
parents:
diff changeset
3494 union_type, &chain);
kono
parents:
diff changeset
3495 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3496 gfc_finish_type (vec_type);
kono
parents:
diff changeset
3497 TYPE_NAME (vec_type) = get_identifier ("caf_vector_t");
kono
parents:
diff changeset
3498 }
kono
parents:
diff changeset
3499
kono
parents:
diff changeset
3500 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
kono
parents:
diff changeset
3501 gfc_rank_cst[dim-1]);
kono
parents:
diff changeset
3502 vector_types[dim-1] = build_array_type (vec_type, tmp);
kono
parents:
diff changeset
3503 return vector_types[dim-1];
kono
parents:
diff changeset
3504 }
kono
parents:
diff changeset
3505
kono
parents:
diff changeset
3506
kono
parents:
diff changeset
3507 tree
kono
parents:
diff changeset
3508 gfc_get_caf_reference_type ()
kono
parents:
diff changeset
3509 {
kono
parents:
diff changeset
3510 static tree reference_type = NULL_TREE;
kono
parents:
diff changeset
3511 tree c_struct_type, s_struct_type, v_struct_type, union_type, dim_union_type,
kono
parents:
diff changeset
3512 a_struct_type, u_union_type, tmp, *chain;
kono
parents:
diff changeset
3513
kono
parents:
diff changeset
3514 if (reference_type != NULL_TREE)
kono
parents:
diff changeset
3515 return reference_type;
kono
parents:
diff changeset
3516
kono
parents:
diff changeset
3517 chain = 0;
kono
parents:
diff changeset
3518 c_struct_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3519 tmp = gfc_add_field_to_struct_1 (c_struct_type,
kono
parents:
diff changeset
3520 get_identifier ("offset"),
kono
parents:
diff changeset
3521 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3522 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3523 tmp = gfc_add_field_to_struct_1 (c_struct_type,
kono
parents:
diff changeset
3524 get_identifier ("caf_token_offset"),
kono
parents:
diff changeset
3525 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3526 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3527 gfc_finish_type (c_struct_type);
kono
parents:
diff changeset
3528
kono
parents:
diff changeset
3529 chain = 0;
kono
parents:
diff changeset
3530 s_struct_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3531 tmp = gfc_add_field_to_struct_1 (s_struct_type,
kono
parents:
diff changeset
3532 get_identifier ("start"),
kono
parents:
diff changeset
3533 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3534 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3535 tmp = gfc_add_field_to_struct_1 (s_struct_type,
kono
parents:
diff changeset
3536 get_identifier ("end"),
kono
parents:
diff changeset
3537 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3538 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3539 tmp = gfc_add_field_to_struct_1 (s_struct_type,
kono
parents:
diff changeset
3540 get_identifier ("stride"),
kono
parents:
diff changeset
3541 gfc_array_index_type, &chain);
kono
parents:
diff changeset
3542 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3543 gfc_finish_type (s_struct_type);
kono
parents:
diff changeset
3544
kono
parents:
diff changeset
3545 chain = 0;
kono
parents:
diff changeset
3546 v_struct_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3547 tmp = gfc_add_field_to_struct_1 (v_struct_type,
kono
parents:
diff changeset
3548 get_identifier ("vector"),
kono
parents:
diff changeset
3549 pvoid_type_node, &chain);
kono
parents:
diff changeset
3550 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3551 tmp = gfc_add_field_to_struct_1 (v_struct_type,
kono
parents:
diff changeset
3552 get_identifier ("nvec"),
kono
parents:
diff changeset
3553 size_type_node, &chain);
kono
parents:
diff changeset
3554 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3555 tmp = gfc_add_field_to_struct_1 (v_struct_type,
kono
parents:
diff changeset
3556 get_identifier ("kind"),
kono
parents:
diff changeset
3557 integer_type_node, &chain);
kono
parents:
diff changeset
3558 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3559 gfc_finish_type (v_struct_type);
kono
parents:
diff changeset
3560
kono
parents:
diff changeset
3561 chain = 0;
kono
parents:
diff changeset
3562 union_type = make_node (UNION_TYPE);
kono
parents:
diff changeset
3563 tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("s"),
kono
parents:
diff changeset
3564 s_struct_type, &chain);
kono
parents:
diff changeset
3565 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3566 tmp = gfc_add_field_to_struct_1 (union_type, get_identifier ("v"),
kono
parents:
diff changeset
3567 v_struct_type, &chain);
kono
parents:
diff changeset
3568 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3569 gfc_finish_type (union_type);
kono
parents:
diff changeset
3570
kono
parents:
diff changeset
3571 tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node,
kono
parents:
diff changeset
3572 gfc_rank_cst[GFC_MAX_DIMENSIONS - 1]);
kono
parents:
diff changeset
3573 dim_union_type = build_array_type (union_type, tmp);
kono
parents:
diff changeset
3574
kono
parents:
diff changeset
3575 chain = 0;
kono
parents:
diff changeset
3576 a_struct_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3577 tmp = gfc_add_field_to_struct_1 (a_struct_type, get_identifier ("mode"),
kono
parents:
diff changeset
3578 build_array_type (unsigned_char_type_node,
kono
parents:
diff changeset
3579 build_range_type (gfc_array_index_type,
kono
parents:
diff changeset
3580 gfc_index_zero_node,
kono
parents:
diff changeset
3581 gfc_rank_cst[GFC_MAX_DIMENSIONS - 1])),
kono
parents:
diff changeset
3582 &chain);
kono
parents:
diff changeset
3583 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3584 tmp = gfc_add_field_to_struct_1 (a_struct_type,
kono
parents:
diff changeset
3585 get_identifier ("static_array_type"),
kono
parents:
diff changeset
3586 integer_type_node, &chain);
kono
parents:
diff changeset
3587 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3588 tmp = gfc_add_field_to_struct_1 (a_struct_type, get_identifier ("dim"),
kono
parents:
diff changeset
3589 dim_union_type, &chain);
kono
parents:
diff changeset
3590 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3591 gfc_finish_type (a_struct_type);
kono
parents:
diff changeset
3592
kono
parents:
diff changeset
3593 chain = 0;
kono
parents:
diff changeset
3594 u_union_type = make_node (UNION_TYPE);
kono
parents:
diff changeset
3595 tmp = gfc_add_field_to_struct_1 (u_union_type, get_identifier ("c"),
kono
parents:
diff changeset
3596 c_struct_type, &chain);
kono
parents:
diff changeset
3597 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3598 tmp = gfc_add_field_to_struct_1 (u_union_type, get_identifier ("a"),
kono
parents:
diff changeset
3599 a_struct_type, &chain);
kono
parents:
diff changeset
3600 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3601 gfc_finish_type (u_union_type);
kono
parents:
diff changeset
3602
kono
parents:
diff changeset
3603 chain = 0;
kono
parents:
diff changeset
3604 reference_type = make_node (RECORD_TYPE);
kono
parents:
diff changeset
3605 tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("next"),
kono
parents:
diff changeset
3606 build_pointer_type (reference_type), &chain);
kono
parents:
diff changeset
3607 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3608 tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("type"),
kono
parents:
diff changeset
3609 integer_type_node, &chain);
kono
parents:
diff changeset
3610 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3611 tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("item_size"),
kono
parents:
diff changeset
3612 size_type_node, &chain);
kono
parents:
diff changeset
3613 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3614 tmp = gfc_add_field_to_struct_1 (reference_type, get_identifier ("u"),
kono
parents:
diff changeset
3615 u_union_type, &chain);
kono
parents:
diff changeset
3616 TREE_NO_WARNING (tmp) = 1;
kono
parents:
diff changeset
3617 gfc_finish_type (reference_type);
kono
parents:
diff changeset
3618 TYPE_NAME (reference_type) = get_identifier ("caf_reference_t");
kono
parents:
diff changeset
3619
kono
parents:
diff changeset
3620 return reference_type;
kono
parents:
diff changeset
3621 }
kono
parents:
diff changeset
3622
kono
parents:
diff changeset
3623 #include "gt-fortran-trans-types.h"