trans-decl.cc revision 1.1 1 1.1 mrg /* Backend function setup
2 1.1 mrg Copyright (C) 2002-2022 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Paul Brook
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU General Public License as published by the Free
9 1.1 mrg Software Foundation; either version 3, or (at your option) any later
10 1.1 mrg version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 1.1 mrg for more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU General Public License
18 1.1 mrg along with GCC; see the file COPYING3. If not see
19 1.1 mrg <http://www.gnu.org/licenses/>. */
20 1.1 mrg
21 1.1 mrg /* trans-decl.cc -- Handling of backend function and variable decls, etc */
22 1.1 mrg
23 1.1 mrg #include "config.h"
24 1.1 mrg #include "system.h"
25 1.1 mrg #include "coretypes.h"
26 1.1 mrg #include "target.h"
27 1.1 mrg #include "function.h"
28 1.1 mrg #include "tree.h"
29 1.1 mrg #include "gfortran.h"
30 1.1 mrg #include "gimple-expr.h" /* For create_tmp_var_raw. */
31 1.1 mrg #include "trans.h"
32 1.1 mrg #include "stringpool.h"
33 1.1 mrg #include "cgraph.h"
34 1.1 mrg #include "fold-const.h"
35 1.1 mrg #include "stor-layout.h"
36 1.1 mrg #include "varasm.h"
37 1.1 mrg #include "attribs.h"
38 1.1 mrg #include "dumpfile.h"
39 1.1 mrg #include "toplev.h" /* For announce_function. */
40 1.1 mrg #include "debug.h"
41 1.1 mrg #include "constructor.h"
42 1.1 mrg #include "trans-types.h"
43 1.1 mrg #include "trans-array.h"
44 1.1 mrg #include "trans-const.h"
45 1.1 mrg /* Only for gfc_trans_code. Shouldn't need to include this. */
46 1.1 mrg #include "trans-stmt.h"
47 1.1 mrg #include "gomp-constants.h"
48 1.1 mrg #include "gimplify.h"
49 1.1 mrg #include "omp-general.h"
50 1.1 mrg #include "attr-fnspec.h"
51 1.1 mrg
52 1.1 mrg #define MAX_LABEL_VALUE 99999
53 1.1 mrg
54 1.1 mrg
55 1.1 mrg /* Holds the result of the function if no result variable specified. */
56 1.1 mrg
57 1.1 mrg static GTY(()) tree current_fake_result_decl;
58 1.1 mrg static GTY(()) tree parent_fake_result_decl;
59 1.1 mrg
60 1.1 mrg
61 1.1 mrg /* Holds the variable DECLs for the current function. */
62 1.1 mrg
63 1.1 mrg static GTY(()) tree saved_function_decls;
64 1.1 mrg static GTY(()) tree saved_parent_function_decls;
65 1.1 mrg
66 1.1 mrg /* Holds the variable DECLs that are locals. */
67 1.1 mrg
68 1.1 mrg static GTY(()) tree saved_local_decls;
69 1.1 mrg
70 1.1 mrg /* The namespace of the module we're currently generating. Only used while
71 1.1 mrg outputting decls for module variables. Do not rely on this being set. */
72 1.1 mrg
73 1.1 mrg static gfc_namespace *module_namespace;
74 1.1 mrg
75 1.1 mrg /* The currently processed procedure symbol. */
76 1.1 mrg static gfc_symbol* current_procedure_symbol = NULL;
77 1.1 mrg
78 1.1 mrg /* The currently processed module. */
79 1.1 mrg static struct module_htab_entry *cur_module;
80 1.1 mrg
81 1.1 mrg /* With -fcoarray=lib: For generating the registering call
82 1.1 mrg of static coarrays. */
83 1.1 mrg static bool has_coarray_vars;
84 1.1 mrg static stmtblock_t caf_init_block;
85 1.1 mrg
86 1.1 mrg
87 1.1 mrg /* List of static constructor functions. */
88 1.1 mrg
89 1.1 mrg tree gfc_static_ctors;
90 1.1 mrg
91 1.1 mrg
92 1.1 mrg /* Whether we've seen a symbol from an IEEE module in the namespace. */
93 1.1 mrg static int seen_ieee_symbol;
94 1.1 mrg
95 1.1 mrg /* Function declarations for builtin library functions. */
96 1.1 mrg
97 1.1 mrg tree gfor_fndecl_pause_numeric;
98 1.1 mrg tree gfor_fndecl_pause_string;
99 1.1 mrg tree gfor_fndecl_stop_numeric;
100 1.1 mrg tree gfor_fndecl_stop_string;
101 1.1 mrg tree gfor_fndecl_error_stop_numeric;
102 1.1 mrg tree gfor_fndecl_error_stop_string;
103 1.1 mrg tree gfor_fndecl_runtime_error;
104 1.1 mrg tree gfor_fndecl_runtime_error_at;
105 1.1 mrg tree gfor_fndecl_runtime_warning_at;
106 1.1 mrg tree gfor_fndecl_os_error_at;
107 1.1 mrg tree gfor_fndecl_generate_error;
108 1.1 mrg tree gfor_fndecl_set_args;
109 1.1 mrg tree gfor_fndecl_set_fpe;
110 1.1 mrg tree gfor_fndecl_set_options;
111 1.1 mrg tree gfor_fndecl_set_convert;
112 1.1 mrg tree gfor_fndecl_set_record_marker;
113 1.1 mrg tree gfor_fndecl_set_max_subrecord_length;
114 1.1 mrg tree gfor_fndecl_ctime;
115 1.1 mrg tree gfor_fndecl_fdate;
116 1.1 mrg tree gfor_fndecl_ttynam;
117 1.1 mrg tree gfor_fndecl_in_pack;
118 1.1 mrg tree gfor_fndecl_in_unpack;
119 1.1 mrg tree gfor_fndecl_associated;
120 1.1 mrg tree gfor_fndecl_system_clock4;
121 1.1 mrg tree gfor_fndecl_system_clock8;
122 1.1 mrg tree gfor_fndecl_ieee_procedure_entry;
123 1.1 mrg tree gfor_fndecl_ieee_procedure_exit;
124 1.1 mrg
125 1.1 mrg /* Coarray run-time library function decls. */
126 1.1 mrg tree gfor_fndecl_caf_init;
127 1.1 mrg tree gfor_fndecl_caf_finalize;
128 1.1 mrg tree gfor_fndecl_caf_this_image;
129 1.1 mrg tree gfor_fndecl_caf_num_images;
130 1.1 mrg tree gfor_fndecl_caf_register;
131 1.1 mrg tree gfor_fndecl_caf_deregister;
132 1.1 mrg tree gfor_fndecl_caf_get;
133 1.1 mrg tree gfor_fndecl_caf_send;
134 1.1 mrg tree gfor_fndecl_caf_sendget;
135 1.1 mrg tree gfor_fndecl_caf_get_by_ref;
136 1.1 mrg tree gfor_fndecl_caf_send_by_ref;
137 1.1 mrg tree gfor_fndecl_caf_sendget_by_ref;
138 1.1 mrg tree gfor_fndecl_caf_sync_all;
139 1.1 mrg tree gfor_fndecl_caf_sync_memory;
140 1.1 mrg tree gfor_fndecl_caf_sync_images;
141 1.1 mrg tree gfor_fndecl_caf_stop_str;
142 1.1 mrg tree gfor_fndecl_caf_stop_numeric;
143 1.1 mrg tree gfor_fndecl_caf_error_stop;
144 1.1 mrg tree gfor_fndecl_caf_error_stop_str;
145 1.1 mrg tree gfor_fndecl_caf_atomic_def;
146 1.1 mrg tree gfor_fndecl_caf_atomic_ref;
147 1.1 mrg tree gfor_fndecl_caf_atomic_cas;
148 1.1 mrg tree gfor_fndecl_caf_atomic_op;
149 1.1 mrg tree gfor_fndecl_caf_lock;
150 1.1 mrg tree gfor_fndecl_caf_unlock;
151 1.1 mrg tree gfor_fndecl_caf_event_post;
152 1.1 mrg tree gfor_fndecl_caf_event_wait;
153 1.1 mrg tree gfor_fndecl_caf_event_query;
154 1.1 mrg tree gfor_fndecl_caf_fail_image;
155 1.1 mrg tree gfor_fndecl_caf_failed_images;
156 1.1 mrg tree gfor_fndecl_caf_image_status;
157 1.1 mrg tree gfor_fndecl_caf_stopped_images;
158 1.1 mrg tree gfor_fndecl_caf_form_team;
159 1.1 mrg tree gfor_fndecl_caf_change_team;
160 1.1 mrg tree gfor_fndecl_caf_end_team;
161 1.1 mrg tree gfor_fndecl_caf_sync_team;
162 1.1 mrg tree gfor_fndecl_caf_get_team;
163 1.1 mrg tree gfor_fndecl_caf_team_number;
164 1.1 mrg tree gfor_fndecl_co_broadcast;
165 1.1 mrg tree gfor_fndecl_co_max;
166 1.1 mrg tree gfor_fndecl_co_min;
167 1.1 mrg tree gfor_fndecl_co_reduce;
168 1.1 mrg tree gfor_fndecl_co_sum;
169 1.1 mrg tree gfor_fndecl_caf_is_present;
170 1.1 mrg tree gfor_fndecl_caf_random_init;
171 1.1 mrg
172 1.1 mrg
173 1.1 mrg /* Math functions. Many other math functions are handled in
174 1.1 mrg trans-intrinsic.cc. */
175 1.1 mrg
176 1.1 mrg gfc_powdecl_list gfor_fndecl_math_powi[4][3];
177 1.1 mrg tree gfor_fndecl_math_ishftc4;
178 1.1 mrg tree gfor_fndecl_math_ishftc8;
179 1.1 mrg tree gfor_fndecl_math_ishftc16;
180 1.1 mrg
181 1.1 mrg
182 1.1 mrg /* String functions. */
183 1.1 mrg
184 1.1 mrg tree gfor_fndecl_compare_string;
185 1.1 mrg tree gfor_fndecl_concat_string;
186 1.1 mrg tree gfor_fndecl_string_len_trim;
187 1.1 mrg tree gfor_fndecl_string_index;
188 1.1 mrg tree gfor_fndecl_string_scan;
189 1.1 mrg tree gfor_fndecl_string_verify;
190 1.1 mrg tree gfor_fndecl_string_trim;
191 1.1 mrg tree gfor_fndecl_string_minmax;
192 1.1 mrg tree gfor_fndecl_adjustl;
193 1.1 mrg tree gfor_fndecl_adjustr;
194 1.1 mrg tree gfor_fndecl_select_string;
195 1.1 mrg tree gfor_fndecl_compare_string_char4;
196 1.1 mrg tree gfor_fndecl_concat_string_char4;
197 1.1 mrg tree gfor_fndecl_string_len_trim_char4;
198 1.1 mrg tree gfor_fndecl_string_index_char4;
199 1.1 mrg tree gfor_fndecl_string_scan_char4;
200 1.1 mrg tree gfor_fndecl_string_verify_char4;
201 1.1 mrg tree gfor_fndecl_string_trim_char4;
202 1.1 mrg tree gfor_fndecl_string_minmax_char4;
203 1.1 mrg tree gfor_fndecl_adjustl_char4;
204 1.1 mrg tree gfor_fndecl_adjustr_char4;
205 1.1 mrg tree gfor_fndecl_select_string_char4;
206 1.1 mrg
207 1.1 mrg
208 1.1 mrg /* Conversion between character kinds. */
209 1.1 mrg tree gfor_fndecl_convert_char1_to_char4;
210 1.1 mrg tree gfor_fndecl_convert_char4_to_char1;
211 1.1 mrg
212 1.1 mrg
213 1.1 mrg /* Other misc. runtime library functions. */
214 1.1 mrg tree gfor_fndecl_iargc;
215 1.1 mrg tree gfor_fndecl_kill;
216 1.1 mrg tree gfor_fndecl_kill_sub;
217 1.1 mrg tree gfor_fndecl_is_contiguous0;
218 1.1 mrg
219 1.1 mrg
220 1.1 mrg /* Intrinsic functions implemented in Fortran. */
221 1.1 mrg tree gfor_fndecl_sc_kind;
222 1.1 mrg tree gfor_fndecl_si_kind;
223 1.1 mrg tree gfor_fndecl_sr_kind;
224 1.1 mrg
225 1.1 mrg /* BLAS gemm functions. */
226 1.1 mrg tree gfor_fndecl_sgemm;
227 1.1 mrg tree gfor_fndecl_dgemm;
228 1.1 mrg tree gfor_fndecl_cgemm;
229 1.1 mrg tree gfor_fndecl_zgemm;
230 1.1 mrg
231 1.1 mrg /* RANDOM_INIT function. */
232 1.1 mrg tree gfor_fndecl_random_init; /* libgfortran, 1 image only. */
233 1.1 mrg
234 1.1 mrg static void
235 1.1 mrg gfc_add_decl_to_parent_function (tree decl)
236 1.1 mrg {
237 1.1 mrg gcc_assert (decl);
238 1.1 mrg DECL_CONTEXT (decl) = DECL_CONTEXT (current_function_decl);
239 1.1 mrg DECL_NONLOCAL (decl) = 1;
240 1.1 mrg DECL_CHAIN (decl) = saved_parent_function_decls;
241 1.1 mrg saved_parent_function_decls = decl;
242 1.1 mrg }
243 1.1 mrg
244 1.1 mrg void
245 1.1 mrg gfc_add_decl_to_function (tree decl)
246 1.1 mrg {
247 1.1 mrg gcc_assert (decl);
248 1.1 mrg TREE_USED (decl) = 1;
249 1.1 mrg DECL_CONTEXT (decl) = current_function_decl;
250 1.1 mrg DECL_CHAIN (decl) = saved_function_decls;
251 1.1 mrg saved_function_decls = decl;
252 1.1 mrg }
253 1.1 mrg
254 1.1 mrg static void
255 1.1 mrg add_decl_as_local (tree decl)
256 1.1 mrg {
257 1.1 mrg gcc_assert (decl);
258 1.1 mrg TREE_USED (decl) = 1;
259 1.1 mrg DECL_CONTEXT (decl) = current_function_decl;
260 1.1 mrg DECL_CHAIN (decl) = saved_local_decls;
261 1.1 mrg saved_local_decls = decl;
262 1.1 mrg }
263 1.1 mrg
264 1.1 mrg
265 1.1 mrg /* Build a backend label declaration. Set TREE_USED for named labels.
266 1.1 mrg The context of the label is always the current_function_decl. All
267 1.1 mrg labels are marked artificial. */
268 1.1 mrg
269 1.1 mrg tree
270 1.1 mrg gfc_build_label_decl (tree label_id)
271 1.1 mrg {
272 1.1 mrg /* 2^32 temporaries should be enough. */
273 1.1 mrg static unsigned int tmp_num = 1;
274 1.1 mrg tree label_decl;
275 1.1 mrg char *label_name;
276 1.1 mrg
277 1.1 mrg if (label_id == NULL_TREE)
278 1.1 mrg {
279 1.1 mrg /* Build an internal label name. */
280 1.1 mrg ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++);
281 1.1 mrg label_id = get_identifier (label_name);
282 1.1 mrg }
283 1.1 mrg else
284 1.1 mrg label_name = NULL;
285 1.1 mrg
286 1.1 mrg /* Build the LABEL_DECL node. Labels have no type. */
287 1.1 mrg label_decl = build_decl (input_location,
288 1.1 mrg LABEL_DECL, label_id, void_type_node);
289 1.1 mrg DECL_CONTEXT (label_decl) = current_function_decl;
290 1.1 mrg SET_DECL_MODE (label_decl, VOIDmode);
291 1.1 mrg
292 1.1 mrg /* We always define the label as used, even if the original source
293 1.1 mrg file never references the label. We don't want all kinds of
294 1.1 mrg spurious warnings for old-style Fortran code with too many
295 1.1 mrg labels. */
296 1.1 mrg TREE_USED (label_decl) = 1;
297 1.1 mrg
298 1.1 mrg DECL_ARTIFICIAL (label_decl) = 1;
299 1.1 mrg return label_decl;
300 1.1 mrg }
301 1.1 mrg
302 1.1 mrg
303 1.1 mrg /* Set the backend source location of a decl. */
304 1.1 mrg
305 1.1 mrg void
306 1.1 mrg gfc_set_decl_location (tree decl, locus * loc)
307 1.1 mrg {
308 1.1 mrg DECL_SOURCE_LOCATION (decl) = gfc_get_location (loc);
309 1.1 mrg }
310 1.1 mrg
311 1.1 mrg
312 1.1 mrg /* Return the backend label declaration for a given label structure,
313 1.1 mrg or create it if it doesn't exist yet. */
314 1.1 mrg
315 1.1 mrg tree
316 1.1 mrg gfc_get_label_decl (gfc_st_label * lp)
317 1.1 mrg {
318 1.1 mrg if (lp->backend_decl)
319 1.1 mrg return lp->backend_decl;
320 1.1 mrg else
321 1.1 mrg {
322 1.1 mrg char label_name[GFC_MAX_SYMBOL_LEN + 1];
323 1.1 mrg tree label_decl;
324 1.1 mrg
325 1.1 mrg /* Validate the label declaration from the front end. */
326 1.1 mrg gcc_assert (lp != NULL && lp->value <= MAX_LABEL_VALUE);
327 1.1 mrg
328 1.1 mrg /* Build a mangled name for the label. */
329 1.1 mrg sprintf (label_name, "__label_%.6d", lp->value);
330 1.1 mrg
331 1.1 mrg /* Build the LABEL_DECL node. */
332 1.1 mrg label_decl = gfc_build_label_decl (get_identifier (label_name));
333 1.1 mrg
334 1.1 mrg /* Tell the debugger where the label came from. */
335 1.1 mrg if (lp->value <= MAX_LABEL_VALUE) /* An internal label. */
336 1.1 mrg gfc_set_decl_location (label_decl, &lp->where);
337 1.1 mrg else
338 1.1 mrg DECL_ARTIFICIAL (label_decl) = 1;
339 1.1 mrg
340 1.1 mrg /* Store the label in the label list and return the LABEL_DECL. */
341 1.1 mrg lp->backend_decl = label_decl;
342 1.1 mrg return label_decl;
343 1.1 mrg }
344 1.1 mrg }
345 1.1 mrg
346 1.1 mrg /* Return the name of an identifier. */
347 1.1 mrg
348 1.1 mrg static const char *
349 1.1 mrg sym_identifier (gfc_symbol *sym)
350 1.1 mrg {
351 1.1 mrg if (sym->attr.is_main_program && strcmp (sym->name, "main") == 0)
352 1.1 mrg return "MAIN__";
353 1.1 mrg else
354 1.1 mrg return sym->name;
355 1.1 mrg }
356 1.1 mrg
357 1.1 mrg /* Convert a gfc_symbol to an identifier of the same name. */
358 1.1 mrg
359 1.1 mrg static tree
360 1.1 mrg gfc_sym_identifier (gfc_symbol * sym)
361 1.1 mrg {
362 1.1 mrg return get_identifier (sym_identifier (sym));
363 1.1 mrg }
364 1.1 mrg
365 1.1 mrg /* Construct mangled name from symbol name. */
366 1.1 mrg
367 1.1 mrg static const char *
368 1.1 mrg mangled_identifier (gfc_symbol *sym)
369 1.1 mrg {
370 1.1 mrg gfc_symbol *proc = sym->ns->proc_name;
371 1.1 mrg static char name[3*GFC_MAX_MANGLED_SYMBOL_LEN + 14];
372 1.1 mrg /* Prevent the mangling of identifiers that have an assigned
373 1.1 mrg binding label (mainly those that are bind(c)). */
374 1.1 mrg
375 1.1 mrg if (sym->attr.is_bind_c == 1 && sym->binding_label)
376 1.1 mrg return sym->binding_label;
377 1.1 mrg
378 1.1 mrg if (!sym->fn_result_spec
379 1.1 mrg || (sym->module && !(proc && proc->attr.flavor == FL_PROCEDURE)))
380 1.1 mrg {
381 1.1 mrg if (sym->module == NULL)
382 1.1 mrg return sym_identifier (sym);
383 1.1 mrg else
384 1.1 mrg snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name);
385 1.1 mrg }
386 1.1 mrg else
387 1.1 mrg {
388 1.1 mrg /* This is an entity that is actually local to a module procedure
389 1.1 mrg that appears in the result specification expression. Since
390 1.1 mrg sym->module will be a zero length string, we use ns->proc_name
391 1.1 mrg to provide the module name instead. */
392 1.1 mrg if (proc && proc->module)
393 1.1 mrg snprintf (name, sizeof name, "__%s_MOD__%s_PROC_%s",
394 1.1 mrg proc->module, proc->name, sym->name);
395 1.1 mrg else
396 1.1 mrg snprintf (name, sizeof name, "__%s_PROC_%s",
397 1.1 mrg proc->name, sym->name);
398 1.1 mrg }
399 1.1 mrg
400 1.1 mrg return name;
401 1.1 mrg }
402 1.1 mrg
403 1.1 mrg /* Get mangled identifier, adding the symbol to the global table if
404 1.1 mrg it is not yet already there. */
405 1.1 mrg
406 1.1 mrg static tree
407 1.1 mrg gfc_sym_mangled_identifier (gfc_symbol * sym)
408 1.1 mrg {
409 1.1 mrg tree result;
410 1.1 mrg gfc_gsymbol *gsym;
411 1.1 mrg const char *name;
412 1.1 mrg
413 1.1 mrg name = mangled_identifier (sym);
414 1.1 mrg result = get_identifier (name);
415 1.1 mrg
416 1.1 mrg gsym = gfc_find_gsymbol (gfc_gsym_root, name);
417 1.1 mrg if (gsym == NULL)
418 1.1 mrg {
419 1.1 mrg gsym = gfc_get_gsymbol (name, false);
420 1.1 mrg gsym->ns = sym->ns;
421 1.1 mrg gsym->sym_name = sym->name;
422 1.1 mrg }
423 1.1 mrg
424 1.1 mrg return result;
425 1.1 mrg }
426 1.1 mrg
427 1.1 mrg /* Construct mangled function name from symbol name. */
428 1.1 mrg
429 1.1 mrg static tree
430 1.1 mrg gfc_sym_mangled_function_id (gfc_symbol * sym)
431 1.1 mrg {
432 1.1 mrg int has_underscore;
433 1.1 mrg char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
434 1.1 mrg
435 1.1 mrg /* It may be possible to simply use the binding label if it's
436 1.1 mrg provided, and remove the other checks. Then we could use it
437 1.1 mrg for other things if we wished. */
438 1.1 mrg if ((sym->attr.is_bind_c == 1 || sym->attr.is_iso_c == 1) &&
439 1.1 mrg sym->binding_label)
440 1.1 mrg /* use the binding label rather than the mangled name */
441 1.1 mrg return get_identifier (sym->binding_label);
442 1.1 mrg
443 1.1 mrg if ((sym->module == NULL || sym->attr.proc == PROC_EXTERNAL
444 1.1 mrg || (sym->module != NULL && (sym->attr.external
445 1.1 mrg || sym->attr.if_source == IFSRC_IFBODY)))
446 1.1 mrg && !sym->attr.module_procedure)
447 1.1 mrg {
448 1.1 mrg /* Main program is mangled into MAIN__. */
449 1.1 mrg if (sym->attr.is_main_program)
450 1.1 mrg return get_identifier ("MAIN__");
451 1.1 mrg
452 1.1 mrg /* Intrinsic procedures are never mangled. */
453 1.1 mrg if (sym->attr.proc == PROC_INTRINSIC)
454 1.1 mrg return get_identifier (sym->name);
455 1.1 mrg
456 1.1 mrg if (flag_underscoring)
457 1.1 mrg {
458 1.1 mrg has_underscore = strchr (sym->name, '_') != 0;
459 1.1 mrg if (flag_second_underscore && has_underscore)
460 1.1 mrg snprintf (name, sizeof name, "%s__", sym->name);
461 1.1 mrg else
462 1.1 mrg snprintf (name, sizeof name, "%s_", sym->name);
463 1.1 mrg return get_identifier (name);
464 1.1 mrg }
465 1.1 mrg else
466 1.1 mrg return get_identifier (sym->name);
467 1.1 mrg }
468 1.1 mrg else
469 1.1 mrg {
470 1.1 mrg snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name);
471 1.1 mrg return get_identifier (name);
472 1.1 mrg }
473 1.1 mrg }
474 1.1 mrg
475 1.1 mrg
476 1.1 mrg void
477 1.1 mrg gfc_set_decl_assembler_name (tree decl, tree name)
478 1.1 mrg {
479 1.1 mrg tree target_mangled = targetm.mangle_decl_assembler_name (decl, name);
480 1.1 mrg SET_DECL_ASSEMBLER_NAME (decl, target_mangled);
481 1.1 mrg }
482 1.1 mrg
483 1.1 mrg
484 1.1 mrg /* Returns true if a variable of specified size should go on the stack. */
485 1.1 mrg
486 1.1 mrg int
487 1.1 mrg gfc_can_put_var_on_stack (tree size)
488 1.1 mrg {
489 1.1 mrg unsigned HOST_WIDE_INT low;
490 1.1 mrg
491 1.1 mrg if (!INTEGER_CST_P (size))
492 1.1 mrg return 0;
493 1.1 mrg
494 1.1 mrg if (flag_max_stack_var_size < 0)
495 1.1 mrg return 1;
496 1.1 mrg
497 1.1 mrg if (!tree_fits_uhwi_p (size))
498 1.1 mrg return 0;
499 1.1 mrg
500 1.1 mrg low = TREE_INT_CST_LOW (size);
501 1.1 mrg if (low > (unsigned HOST_WIDE_INT) flag_max_stack_var_size)
502 1.1 mrg return 0;
503 1.1 mrg
504 1.1 mrg /* TODO: Set a per-function stack size limit. */
505 1.1 mrg
506 1.1 mrg return 1;
507 1.1 mrg }
508 1.1 mrg
509 1.1 mrg
510 1.1 mrg /* gfc_finish_cray_pointee sets DECL_VALUE_EXPR for a Cray pointee to
511 1.1 mrg an expression involving its corresponding pointer. There are
512 1.1 mrg 2 cases; one for variable size arrays, and one for everything else,
513 1.1 mrg because variable-sized arrays require one fewer level of
514 1.1 mrg indirection. */
515 1.1 mrg
516 1.1 mrg static void
517 1.1 mrg gfc_finish_cray_pointee (tree decl, gfc_symbol *sym)
518 1.1 mrg {
519 1.1 mrg tree ptr_decl = gfc_get_symbol_decl (sym->cp_pointer);
520 1.1 mrg tree value;
521 1.1 mrg
522 1.1 mrg /* Parameters need to be dereferenced. */
523 1.1 mrg if (sym->cp_pointer->attr.dummy)
524 1.1 mrg ptr_decl = build_fold_indirect_ref_loc (input_location,
525 1.1 mrg ptr_decl);
526 1.1 mrg
527 1.1 mrg /* Check to see if we're dealing with a variable-sized array. */
528 1.1 mrg if (sym->attr.dimension
529 1.1 mrg && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE)
530 1.1 mrg {
531 1.1 mrg /* These decls will be dereferenced later, so we don't dereference
532 1.1 mrg them here. */
533 1.1 mrg value = convert (TREE_TYPE (decl), ptr_decl);
534 1.1 mrg }
535 1.1 mrg else
536 1.1 mrg {
537 1.1 mrg ptr_decl = convert (build_pointer_type (TREE_TYPE (decl)),
538 1.1 mrg ptr_decl);
539 1.1 mrg value = build_fold_indirect_ref_loc (input_location,
540 1.1 mrg ptr_decl);
541 1.1 mrg }
542 1.1 mrg
543 1.1 mrg SET_DECL_VALUE_EXPR (decl, value);
544 1.1 mrg DECL_HAS_VALUE_EXPR_P (decl) = 1;
545 1.1 mrg GFC_DECL_CRAY_POINTEE (decl) = 1;
546 1.1 mrg }
547 1.1 mrg
548 1.1 mrg
549 1.1 mrg /* Finish processing of a declaration without an initial value. */
550 1.1 mrg
551 1.1 mrg static void
552 1.1 mrg gfc_finish_decl (tree decl)
553 1.1 mrg {
554 1.1 mrg gcc_assert (TREE_CODE (decl) == PARM_DECL
555 1.1 mrg || DECL_INITIAL (decl) == NULL_TREE);
556 1.1 mrg
557 1.1 mrg if (!VAR_P (decl))
558 1.1 mrg return;
559 1.1 mrg
560 1.1 mrg if (DECL_SIZE (decl) == NULL_TREE
561 1.1 mrg && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
562 1.1 mrg layout_decl (decl, 0);
563 1.1 mrg
564 1.1 mrg /* A few consistency checks. */
565 1.1 mrg /* A static variable with an incomplete type is an error if it is
566 1.1 mrg initialized. Also if it is not file scope. Otherwise, let it
567 1.1 mrg through, but if it is not `extern' then it may cause an error
568 1.1 mrg message later. */
569 1.1 mrg /* An automatic variable with an incomplete type is an error. */
570 1.1 mrg
571 1.1 mrg /* We should know the storage size. */
572 1.1 mrg gcc_assert (DECL_SIZE (decl) != NULL_TREE
573 1.1 mrg || (TREE_STATIC (decl)
574 1.1 mrg ? (!DECL_INITIAL (decl) || !DECL_CONTEXT (decl))
575 1.1 mrg : DECL_EXTERNAL (decl)));
576 1.1 mrg
577 1.1 mrg /* The storage size should be constant. */
578 1.1 mrg gcc_assert ((!DECL_EXTERNAL (decl) && !TREE_STATIC (decl))
579 1.1 mrg || !DECL_SIZE (decl)
580 1.1 mrg || TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST);
581 1.1 mrg }
582 1.1 mrg
583 1.1 mrg
584 1.1 mrg /* Handle setting of GFC_DECL_SCALAR* on DECL. */
585 1.1 mrg
586 1.1 mrg void
587 1.1 mrg gfc_finish_decl_attrs (tree decl, symbol_attribute *attr)
588 1.1 mrg {
589 1.1 mrg if (!attr->dimension && !attr->codimension)
590 1.1 mrg {
591 1.1 mrg /* Handle scalar allocatable variables. */
592 1.1 mrg if (attr->allocatable)
593 1.1 mrg {
594 1.1 mrg gfc_allocate_lang_decl (decl);
595 1.1 mrg GFC_DECL_SCALAR_ALLOCATABLE (decl) = 1;
596 1.1 mrg }
597 1.1 mrg /* Handle scalar pointer variables. */
598 1.1 mrg if (attr->pointer)
599 1.1 mrg {
600 1.1 mrg gfc_allocate_lang_decl (decl);
601 1.1 mrg GFC_DECL_SCALAR_POINTER (decl) = 1;
602 1.1 mrg }
603 1.1 mrg if (attr->target)
604 1.1 mrg {
605 1.1 mrg gfc_allocate_lang_decl (decl);
606 1.1 mrg GFC_DECL_SCALAR_TARGET (decl) = 1;
607 1.1 mrg }
608 1.1 mrg }
609 1.1 mrg }
610 1.1 mrg
611 1.1 mrg
612 1.1 mrg /* Apply symbol attributes to a variable, and add it to the function scope. */
613 1.1 mrg
614 1.1 mrg static void
615 1.1 mrg gfc_finish_var_decl (tree decl, gfc_symbol * sym)
616 1.1 mrg {
617 1.1 mrg tree new_type;
618 1.1 mrg
619 1.1 mrg /* Set DECL_VALUE_EXPR for Cray Pointees. */
620 1.1 mrg if (sym->attr.cray_pointee)
621 1.1 mrg gfc_finish_cray_pointee (decl, sym);
622 1.1 mrg
623 1.1 mrg /* TREE_ADDRESSABLE means the address of this variable is actually needed.
624 1.1 mrg This is the equivalent of the TARGET variables.
625 1.1 mrg We also need to set this if the variable is passed by reference in a
626 1.1 mrg CALL statement. */
627 1.1 mrg if (sym->attr.target)
628 1.1 mrg TREE_ADDRESSABLE (decl) = 1;
629 1.1 mrg
630 1.1 mrg /* If it wasn't used we wouldn't be getting it. */
631 1.1 mrg TREE_USED (decl) = 1;
632 1.1 mrg
633 1.1 mrg if (sym->attr.flavor == FL_PARAMETER
634 1.1 mrg && (sym->attr.dimension || sym->ts.type == BT_DERIVED))
635 1.1 mrg TREE_READONLY (decl) = 1;
636 1.1 mrg
637 1.1 mrg /* Chain this decl to the pending declarations. Don't do pushdecl()
638 1.1 mrg because this would add them to the current scope rather than the
639 1.1 mrg function scope. */
640 1.1 mrg if (current_function_decl != NULL_TREE)
641 1.1 mrg {
642 1.1 mrg if (sym->ns->proc_name
643 1.1 mrg && (sym->ns->proc_name->backend_decl == current_function_decl
644 1.1 mrg || sym->result == sym))
645 1.1 mrg gfc_add_decl_to_function (decl);
646 1.1 mrg else if (sym->ns->proc_name
647 1.1 mrg && sym->ns->proc_name->attr.flavor == FL_LABEL)
648 1.1 mrg /* This is a BLOCK construct. */
649 1.1 mrg add_decl_as_local (decl);
650 1.1 mrg else if (sym->ns->omp_affinity_iterators)
651 1.1 mrg /* This is a block-local iterator. */
652 1.1 mrg add_decl_as_local (decl);
653 1.1 mrg else
654 1.1 mrg gfc_add_decl_to_parent_function (decl);
655 1.1 mrg }
656 1.1 mrg
657 1.1 mrg if (sym->attr.cray_pointee)
658 1.1 mrg return;
659 1.1 mrg
660 1.1 mrg if(sym->attr.is_bind_c == 1 && sym->binding_label)
661 1.1 mrg {
662 1.1 mrg /* We need to put variables that are bind(c) into the common
663 1.1 mrg segment of the object file, because this is what C would do.
664 1.1 mrg gfortran would typically put them in either the BSS or
665 1.1 mrg initialized data segments, and only mark them as common if
666 1.1 mrg they were part of common blocks. However, if they are not put
667 1.1 mrg into common space, then C cannot initialize global Fortran
668 1.1 mrg variables that it interoperates with and the draft says that
669 1.1 mrg either Fortran or C should be able to initialize it (but not
670 1.1 mrg both, of course.) (J3/04-007, section 15.3). */
671 1.1 mrg TREE_PUBLIC(decl) = 1;
672 1.1 mrg DECL_COMMON(decl) = 1;
673 1.1 mrg if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
674 1.1 mrg {
675 1.1 mrg DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
676 1.1 mrg DECL_VISIBILITY_SPECIFIED (decl) = true;
677 1.1 mrg }
678 1.1 mrg }
679 1.1 mrg
680 1.1 mrg /* If a variable is USE associated, it's always external. */
681 1.1 mrg if (sym->attr.use_assoc || sym->attr.used_in_submodule)
682 1.1 mrg {
683 1.1 mrg DECL_EXTERNAL (decl) = 1;
684 1.1 mrg TREE_PUBLIC (decl) = 1;
685 1.1 mrg }
686 1.1 mrg else if (sym->fn_result_spec && !sym->ns->proc_name->module)
687 1.1 mrg {
688 1.1 mrg
689 1.1 mrg if (sym->ns->proc_name->attr.if_source != IFSRC_DECL)
690 1.1 mrg DECL_EXTERNAL (decl) = 1;
691 1.1 mrg else
692 1.1 mrg TREE_STATIC (decl) = 1;
693 1.1 mrg
694 1.1 mrg TREE_PUBLIC (decl) = 1;
695 1.1 mrg }
696 1.1 mrg else if (sym->module && !sym->attr.result && !sym->attr.dummy)
697 1.1 mrg {
698 1.1 mrg /* TODO: Don't set sym->module for result or dummy variables. */
699 1.1 mrg gcc_assert (current_function_decl == NULL_TREE || sym->result == sym);
700 1.1 mrg
701 1.1 mrg TREE_PUBLIC (decl) = 1;
702 1.1 mrg TREE_STATIC (decl) = 1;
703 1.1 mrg if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
704 1.1 mrg {
705 1.1 mrg DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
706 1.1 mrg DECL_VISIBILITY_SPECIFIED (decl) = true;
707 1.1 mrg }
708 1.1 mrg }
709 1.1 mrg
710 1.1 mrg /* Derived types are a bit peculiar because of the possibility of
711 1.1 mrg a default initializer; this must be applied each time the variable
712 1.1 mrg comes into scope it therefore need not be static. These variables
713 1.1 mrg are SAVE_NONE but have an initializer. Otherwise explicitly
714 1.1 mrg initialized variables are SAVE_IMPLICIT and explicitly saved are
715 1.1 mrg SAVE_EXPLICIT. */
716 1.1 mrg if (!sym->attr.use_assoc
717 1.1 mrg && (sym->attr.save != SAVE_NONE || sym->attr.data
718 1.1 mrg || (sym->value && sym->ns->proc_name->attr.is_main_program)
719 1.1 mrg || (flag_coarray == GFC_FCOARRAY_LIB
720 1.1 mrg && sym->attr.codimension && !sym->attr.allocatable)))
721 1.1 mrg TREE_STATIC (decl) = 1;
722 1.1 mrg
723 1.1 mrg /* If derived-type variables with DTIO procedures are not made static
724 1.1 mrg some bits of code referencing them get optimized away.
725 1.1 mrg TODO Understand why this is so and fix it. */
726 1.1 mrg if (!sym->attr.use_assoc
727 1.1 mrg && ((sym->ts.type == BT_DERIVED
728 1.1 mrg && sym->ts.u.derived->attr.has_dtio_procs)
729 1.1 mrg || (sym->ts.type == BT_CLASS
730 1.1 mrg && CLASS_DATA (sym)->ts.u.derived->attr.has_dtio_procs)))
731 1.1 mrg TREE_STATIC (decl) = 1;
732 1.1 mrg
733 1.1 mrg /* Treat asynchronous variables the same as volatile, for now. */
734 1.1 mrg if (sym->attr.volatile_ || sym->attr.asynchronous)
735 1.1 mrg {
736 1.1 mrg TREE_THIS_VOLATILE (decl) = 1;
737 1.1 mrg TREE_SIDE_EFFECTS (decl) = 1;
738 1.1 mrg new_type = build_qualified_type (TREE_TYPE (decl), TYPE_QUAL_VOLATILE);
739 1.1 mrg TREE_TYPE (decl) = new_type;
740 1.1 mrg }
741 1.1 mrg
742 1.1 mrg /* Keep variables larger than max-stack-var-size off stack. */
743 1.1 mrg if (!(sym->ns->proc_name && sym->ns->proc_name->attr.recursive)
744 1.1 mrg && !sym->attr.automatic
745 1.1 mrg && !sym->attr.associate_var
746 1.1 mrg && sym->attr.save != SAVE_EXPLICIT
747 1.1 mrg && sym->attr.save != SAVE_IMPLICIT
748 1.1 mrg && INTEGER_CST_P (DECL_SIZE_UNIT (decl))
749 1.1 mrg && !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
750 1.1 mrg /* Put variable length auto array pointers always into stack. */
751 1.1 mrg && (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
752 1.1 mrg || sym->attr.dimension == 0
753 1.1 mrg || sym->as->type != AS_EXPLICIT
754 1.1 mrg || sym->attr.pointer
755 1.1 mrg || sym->attr.allocatable)
756 1.1 mrg && !DECL_ARTIFICIAL (decl))
757 1.1 mrg {
758 1.1 mrg if (flag_max_stack_var_size > 0
759 1.1 mrg && !(sym->ns->proc_name
760 1.1 mrg && sym->ns->proc_name->attr.is_main_program))
761 1.1 mrg gfc_warning (OPT_Wsurprising,
762 1.1 mrg "Array %qs at %L is larger than limit set by "
763 1.1 mrg "%<-fmax-stack-var-size=%>, moved from stack to static "
764 1.1 mrg "storage. This makes the procedure unsafe when called "
765 1.1 mrg "recursively, or concurrently from multiple threads. "
766 1.1 mrg "Consider increasing the %<-fmax-stack-var-size=%> "
767 1.1 mrg "limit (or use %<-frecursive%>, which implies "
768 1.1 mrg "unlimited %<-fmax-stack-var-size%>) - or change the "
769 1.1 mrg "code to use an ALLOCATABLE array. If the variable is "
770 1.1 mrg "never accessed concurrently, this warning can be "
771 1.1 mrg "ignored, and the variable could also be declared with "
772 1.1 mrg "the SAVE attribute.",
773 1.1 mrg sym->name, &sym->declared_at);
774 1.1 mrg
775 1.1 mrg TREE_STATIC (decl) = 1;
776 1.1 mrg
777 1.1 mrg /* Because the size of this variable isn't known until now, we may have
778 1.1 mrg greedily added an initializer to this variable (in build_init_assign)
779 1.1 mrg even though the max-stack-var-size indicates the variable should be
780 1.1 mrg static. Therefore we rip out the automatic initializer here and
781 1.1 mrg replace it with a static one. */
782 1.1 mrg gfc_symtree *st = gfc_find_symtree (sym->ns->sym_root, sym->name);
783 1.1 mrg gfc_code *prev = NULL;
784 1.1 mrg gfc_code *code = sym->ns->code;
785 1.1 mrg while (code && code->op == EXEC_INIT_ASSIGN)
786 1.1 mrg {
787 1.1 mrg /* Look for an initializer meant for this symbol. */
788 1.1 mrg if (code->expr1->symtree == st)
789 1.1 mrg {
790 1.1 mrg if (prev)
791 1.1 mrg prev->next = code->next;
792 1.1 mrg else
793 1.1 mrg sym->ns->code = code->next;
794 1.1 mrg
795 1.1 mrg break;
796 1.1 mrg }
797 1.1 mrg
798 1.1 mrg prev = code;
799 1.1 mrg code = code->next;
800 1.1 mrg }
801 1.1 mrg if (code && code->op == EXEC_INIT_ASSIGN)
802 1.1 mrg {
803 1.1 mrg /* Keep the init expression for a static initializer. */
804 1.1 mrg sym->value = code->expr2;
805 1.1 mrg /* Cleanup the defunct code object, without freeing the init expr. */
806 1.1 mrg code->expr2 = NULL;
807 1.1 mrg gfc_free_statement (code);
808 1.1 mrg free (code);
809 1.1 mrg }
810 1.1 mrg }
811 1.1 mrg
812 1.1 mrg /* Handle threadprivate variables. */
813 1.1 mrg if (sym->attr.threadprivate
814 1.1 mrg && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
815 1.1 mrg set_decl_tls_model (decl, decl_default_tls_model (decl));
816 1.1 mrg
817 1.1 mrg gfc_finish_decl_attrs (decl, &sym->attr);
818 1.1 mrg }
819 1.1 mrg
820 1.1 mrg
821 1.1 mrg /* Allocate the lang-specific part of a decl. */
822 1.1 mrg
823 1.1 mrg void
824 1.1 mrg gfc_allocate_lang_decl (tree decl)
825 1.1 mrg {
826 1.1 mrg if (DECL_LANG_SPECIFIC (decl) == NULL)
827 1.1 mrg DECL_LANG_SPECIFIC (decl) = ggc_cleared_alloc<struct lang_decl> ();
828 1.1 mrg }
829 1.1 mrg
830 1.1 mrg /* Remember a symbol to generate initialization/cleanup code at function
831 1.1 mrg entry/exit. */
832 1.1 mrg
833 1.1 mrg static void
834 1.1 mrg gfc_defer_symbol_init (gfc_symbol * sym)
835 1.1 mrg {
836 1.1 mrg gfc_symbol *p;
837 1.1 mrg gfc_symbol *last;
838 1.1 mrg gfc_symbol *head;
839 1.1 mrg
840 1.1 mrg /* Don't add a symbol twice. */
841 1.1 mrg if (sym->tlink)
842 1.1 mrg return;
843 1.1 mrg
844 1.1 mrg last = head = sym->ns->proc_name;
845 1.1 mrg p = last->tlink;
846 1.1 mrg
847 1.1 mrg /* Make sure that setup code for dummy variables which are used in the
848 1.1 mrg setup of other variables is generated first. */
849 1.1 mrg if (sym->attr.dummy)
850 1.1 mrg {
851 1.1 mrg /* Find the first dummy arg seen after us, or the first non-dummy arg.
852 1.1 mrg This is a circular list, so don't go past the head. */
853 1.1 mrg while (p != head
854 1.1 mrg && (!p->attr.dummy || p->dummy_order > sym->dummy_order))
855 1.1 mrg {
856 1.1 mrg last = p;
857 1.1 mrg p = p->tlink;
858 1.1 mrg }
859 1.1 mrg }
860 1.1 mrg /* Insert in between last and p. */
861 1.1 mrg last->tlink = sym;
862 1.1 mrg sym->tlink = p;
863 1.1 mrg }
864 1.1 mrg
865 1.1 mrg
866 1.1 mrg /* Used in gfc_get_symbol_decl and gfc_get_derived_type to obtain the
867 1.1 mrg backend_decl for a module symbol, if it all ready exists. If the
868 1.1 mrg module gsymbol does not exist, it is created. If the symbol does
869 1.1 mrg not exist, it is added to the gsymbol namespace. Returns true if
870 1.1 mrg an existing backend_decl is found. */
871 1.1 mrg
872 1.1 mrg bool
873 1.1 mrg gfc_get_module_backend_decl (gfc_symbol *sym)
874 1.1 mrg {
875 1.1 mrg gfc_gsymbol *gsym;
876 1.1 mrg gfc_symbol *s;
877 1.1 mrg gfc_symtree *st;
878 1.1 mrg
879 1.1 mrg gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module);
880 1.1 mrg
881 1.1 mrg if (!gsym || (gsym->ns && gsym->type == GSYM_MODULE))
882 1.1 mrg {
883 1.1 mrg st = NULL;
884 1.1 mrg s = NULL;
885 1.1 mrg
886 1.1 mrg /* Check for a symbol with the same name. */
887 1.1 mrg if (gsym)
888 1.1 mrg gfc_find_symbol (sym->name, gsym->ns, 0, &s);
889 1.1 mrg
890 1.1 mrg if (!s)
891 1.1 mrg {
892 1.1 mrg if (!gsym)
893 1.1 mrg {
894 1.1 mrg gsym = gfc_get_gsymbol (sym->module, false);
895 1.1 mrg gsym->type = GSYM_MODULE;
896 1.1 mrg gsym->ns = gfc_get_namespace (NULL, 0);
897 1.1 mrg }
898 1.1 mrg
899 1.1 mrg st = gfc_new_symtree (&gsym->ns->sym_root, sym->name);
900 1.1 mrg st->n.sym = sym;
901 1.1 mrg sym->refs++;
902 1.1 mrg }
903 1.1 mrg else if (gfc_fl_struct (sym->attr.flavor))
904 1.1 mrg {
905 1.1 mrg if (s && s->attr.flavor == FL_PROCEDURE)
906 1.1 mrg {
907 1.1 mrg gfc_interface *intr;
908 1.1 mrg gcc_assert (s->attr.generic);
909 1.1 mrg for (intr = s->generic; intr; intr = intr->next)
910 1.1 mrg if (gfc_fl_struct (intr->sym->attr.flavor))
911 1.1 mrg {
912 1.1 mrg s = intr->sym;
913 1.1 mrg break;
914 1.1 mrg }
915 1.1 mrg }
916 1.1 mrg
917 1.1 mrg /* Normally we can assume that s is a derived-type symbol since it
918 1.1 mrg shares a name with the derived-type sym. However if sym is a
919 1.1 mrg STRUCTURE, it may in fact share a name with any other basic type
920 1.1 mrg variable. If s is in fact of derived type then we can continue
921 1.1 mrg looking for a duplicate type declaration. */
922 1.1 mrg if (sym->attr.flavor == FL_STRUCT && s->ts.type == BT_DERIVED)
923 1.1 mrg {
924 1.1 mrg s = s->ts.u.derived;
925 1.1 mrg }
926 1.1 mrg
927 1.1 mrg if (gfc_fl_struct (s->attr.flavor) && !s->backend_decl)
928 1.1 mrg {
929 1.1 mrg if (s->attr.flavor == FL_UNION)
930 1.1 mrg s->backend_decl = gfc_get_union_type (s);
931 1.1 mrg else
932 1.1 mrg s->backend_decl = gfc_get_derived_type (s);
933 1.1 mrg }
934 1.1 mrg gfc_copy_dt_decls_ifequal (s, sym, true);
935 1.1 mrg return true;
936 1.1 mrg }
937 1.1 mrg else if (s->backend_decl)
938 1.1 mrg {
939 1.1 mrg if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
940 1.1 mrg gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived,
941 1.1 mrg true);
942 1.1 mrg else if (sym->ts.type == BT_CHARACTER)
943 1.1 mrg sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl;
944 1.1 mrg sym->backend_decl = s->backend_decl;
945 1.1 mrg return true;
946 1.1 mrg }
947 1.1 mrg }
948 1.1 mrg return false;
949 1.1 mrg }
950 1.1 mrg
951 1.1 mrg
952 1.1 mrg /* Create an array index type variable with function scope. */
953 1.1 mrg
954 1.1 mrg static tree
955 1.1 mrg create_index_var (const char * pfx, int nest)
956 1.1 mrg {
957 1.1 mrg tree decl;
958 1.1 mrg
959 1.1 mrg decl = gfc_create_var_np (gfc_array_index_type, pfx);
960 1.1 mrg if (nest)
961 1.1 mrg gfc_add_decl_to_parent_function (decl);
962 1.1 mrg else
963 1.1 mrg gfc_add_decl_to_function (decl);
964 1.1 mrg return decl;
965 1.1 mrg }
966 1.1 mrg
967 1.1 mrg
968 1.1 mrg /* Create variables to hold all the non-constant bits of info for a
969 1.1 mrg descriptorless array. Remember these in the lang-specific part of the
970 1.1 mrg type. */
971 1.1 mrg
972 1.1 mrg static void
973 1.1 mrg gfc_build_qualified_array (tree decl, gfc_symbol * sym)
974 1.1 mrg {
975 1.1 mrg tree type;
976 1.1 mrg int dim;
977 1.1 mrg int nest;
978 1.1 mrg gfc_namespace* procns;
979 1.1 mrg symbol_attribute *array_attr;
980 1.1 mrg gfc_array_spec *as;
981 1.1 mrg bool is_classarray = IS_CLASS_ARRAY (sym);
982 1.1 mrg
983 1.1 mrg type = TREE_TYPE (decl);
984 1.1 mrg array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
985 1.1 mrg as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
986 1.1 mrg
987 1.1 mrg /* We just use the descriptor, if there is one. */
988 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type))
989 1.1 mrg return;
990 1.1 mrg
991 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (type));
992 1.1 mrg procns = gfc_find_proc_namespace (sym->ns);
993 1.1 mrg nest = (procns->proc_name->backend_decl != current_function_decl)
994 1.1 mrg && !sym->attr.contained;
995 1.1 mrg
996 1.1 mrg if (array_attr->codimension && flag_coarray == GFC_FCOARRAY_LIB
997 1.1 mrg && as->type != AS_ASSUMED_SHAPE
998 1.1 mrg && GFC_TYPE_ARRAY_CAF_TOKEN (type) == NULL_TREE)
999 1.1 mrg {
1000 1.1 mrg tree token;
1001 1.1 mrg tree token_type = build_qualified_type (pvoid_type_node,
1002 1.1 mrg TYPE_QUAL_RESTRICT);
1003 1.1 mrg
1004 1.1 mrg if (sym->module && (sym->attr.use_assoc
1005 1.1 mrg || sym->ns->proc_name->attr.flavor == FL_MODULE))
1006 1.1 mrg {
1007 1.1 mrg tree token_name
1008 1.1 mrg = get_identifier (gfc_get_string (GFC_PREFIX ("caf_token%s"),
1009 1.1 mrg IDENTIFIER_POINTER (gfc_sym_mangled_identifier (sym))));
1010 1.1 mrg token = build_decl (DECL_SOURCE_LOCATION (decl), VAR_DECL, token_name,
1011 1.1 mrg token_type);
1012 1.1 mrg if (sym->attr.use_assoc)
1013 1.1 mrg DECL_EXTERNAL (token) = 1;
1014 1.1 mrg else
1015 1.1 mrg TREE_STATIC (token) = 1;
1016 1.1 mrg
1017 1.1 mrg TREE_PUBLIC (token) = 1;
1018 1.1 mrg
1019 1.1 mrg if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
1020 1.1 mrg {
1021 1.1 mrg DECL_VISIBILITY (token) = VISIBILITY_HIDDEN;
1022 1.1 mrg DECL_VISIBILITY_SPECIFIED (token) = true;
1023 1.1 mrg }
1024 1.1 mrg }
1025 1.1 mrg else
1026 1.1 mrg {
1027 1.1 mrg token = gfc_create_var_np (token_type, "caf_token");
1028 1.1 mrg TREE_STATIC (token) = 1;
1029 1.1 mrg }
1030 1.1 mrg
1031 1.1 mrg GFC_TYPE_ARRAY_CAF_TOKEN (type) = token;
1032 1.1 mrg DECL_ARTIFICIAL (token) = 1;
1033 1.1 mrg DECL_NONALIASED (token) = 1;
1034 1.1 mrg
1035 1.1 mrg if (sym->module && !sym->attr.use_assoc)
1036 1.1 mrg {
1037 1.1 mrg pushdecl (token);
1038 1.1 mrg DECL_CONTEXT (token) = sym->ns->proc_name->backend_decl;
1039 1.1 mrg gfc_module_add_decl (cur_module, token);
1040 1.1 mrg }
1041 1.1 mrg else if (sym->attr.host_assoc
1042 1.1 mrg && TREE_CODE (DECL_CONTEXT (current_function_decl))
1043 1.1 mrg != TRANSLATION_UNIT_DECL)
1044 1.1 mrg gfc_add_decl_to_parent_function (token);
1045 1.1 mrg else
1046 1.1 mrg gfc_add_decl_to_function (token);
1047 1.1 mrg }
1048 1.1 mrg
1049 1.1 mrg for (dim = 0; dim < GFC_TYPE_ARRAY_RANK (type); dim++)
1050 1.1 mrg {
1051 1.1 mrg if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE)
1052 1.1 mrg {
1053 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var ("lbound", nest);
1054 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_LBOUND (type, dim));
1055 1.1 mrg }
1056 1.1 mrg /* Don't try to use the unknown bound for assumed shape arrays. */
1057 1.1 mrg if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
1058 1.1 mrg && (as->type != AS_ASSUMED_SIZE
1059 1.1 mrg || dim < GFC_TYPE_ARRAY_RANK (type) - 1))
1060 1.1 mrg {
1061 1.1 mrg GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var ("ubound", nest);
1062 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim));
1063 1.1 mrg }
1064 1.1 mrg
1065 1.1 mrg if (GFC_TYPE_ARRAY_STRIDE (type, dim) == NULL_TREE)
1066 1.1 mrg {
1067 1.1 mrg GFC_TYPE_ARRAY_STRIDE (type, dim) = create_index_var ("stride", nest);
1068 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_STRIDE (type, dim));
1069 1.1 mrg }
1070 1.1 mrg }
1071 1.1 mrg for (dim = GFC_TYPE_ARRAY_RANK (type);
1072 1.1 mrg dim < GFC_TYPE_ARRAY_RANK (type) + GFC_TYPE_ARRAY_CORANK (type); dim++)
1073 1.1 mrg {
1074 1.1 mrg if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE)
1075 1.1 mrg {
1076 1.1 mrg GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var ("lbound", nest);
1077 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_LBOUND (type, dim));
1078 1.1 mrg }
1079 1.1 mrg /* Don't try to use the unknown ubound for the last coarray dimension. */
1080 1.1 mrg if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
1081 1.1 mrg && dim < GFC_TYPE_ARRAY_RANK (type) + GFC_TYPE_ARRAY_CORANK (type) - 1)
1082 1.1 mrg {
1083 1.1 mrg GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var ("ubound", nest);
1084 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim));
1085 1.1 mrg }
1086 1.1 mrg }
1087 1.1 mrg if (GFC_TYPE_ARRAY_OFFSET (type) == NULL_TREE)
1088 1.1 mrg {
1089 1.1 mrg GFC_TYPE_ARRAY_OFFSET (type) = gfc_create_var_np (gfc_array_index_type,
1090 1.1 mrg "offset");
1091 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_OFFSET (type));
1092 1.1 mrg
1093 1.1 mrg if (nest)
1094 1.1 mrg gfc_add_decl_to_parent_function (GFC_TYPE_ARRAY_OFFSET (type));
1095 1.1 mrg else
1096 1.1 mrg gfc_add_decl_to_function (GFC_TYPE_ARRAY_OFFSET (type));
1097 1.1 mrg }
1098 1.1 mrg
1099 1.1 mrg if (GFC_TYPE_ARRAY_SIZE (type) == NULL_TREE
1100 1.1 mrg && as->type != AS_ASSUMED_SIZE)
1101 1.1 mrg {
1102 1.1 mrg GFC_TYPE_ARRAY_SIZE (type) = create_index_var ("size", nest);
1103 1.1 mrg suppress_warning (GFC_TYPE_ARRAY_SIZE (type));
1104 1.1 mrg }
1105 1.1 mrg
1106 1.1 mrg if (POINTER_TYPE_P (type))
1107 1.1 mrg {
1108 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (type)));
1109 1.1 mrg gcc_assert (TYPE_LANG_SPECIFIC (type)
1110 1.1 mrg == TYPE_LANG_SPECIFIC (TREE_TYPE (type)));
1111 1.1 mrg type = TREE_TYPE (type);
1112 1.1 mrg }
1113 1.1 mrg
1114 1.1 mrg if (! COMPLETE_TYPE_P (type) && GFC_TYPE_ARRAY_SIZE (type))
1115 1.1 mrg {
1116 1.1 mrg tree size, range;
1117 1.1 mrg
1118 1.1 mrg size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
1119 1.1 mrg GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node);
1120 1.1 mrg range = build_range_type (gfc_array_index_type, gfc_index_zero_node,
1121 1.1 mrg size);
1122 1.1 mrg TYPE_DOMAIN (type) = range;
1123 1.1 mrg layout_type (type);
1124 1.1 mrg }
1125 1.1 mrg
1126 1.1 mrg if (TYPE_NAME (type) != NULL_TREE && as->rank > 0
1127 1.1 mrg && GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1) != NULL_TREE
1128 1.1 mrg && VAR_P (GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1)))
1129 1.1 mrg {
1130 1.1 mrg tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
1131 1.1 mrg
1132 1.1 mrg for (dim = 0; dim < as->rank - 1; dim++)
1133 1.1 mrg {
1134 1.1 mrg gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
1135 1.1 mrg gtype = TREE_TYPE (gtype);
1136 1.1 mrg }
1137 1.1 mrg gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
1138 1.1 mrg if (TYPE_MAX_VALUE (TYPE_DOMAIN (gtype)) == NULL)
1139 1.1 mrg TYPE_NAME (type) = NULL_TREE;
1140 1.1 mrg }
1141 1.1 mrg
1142 1.1 mrg if (TYPE_NAME (type) == NULL_TREE)
1143 1.1 mrg {
1144 1.1 mrg tree gtype = TREE_TYPE (type), rtype, type_decl;
1145 1.1 mrg
1146 1.1 mrg for (dim = as->rank - 1; dim >= 0; dim--)
1147 1.1 mrg {
1148 1.1 mrg tree lbound, ubound;
1149 1.1 mrg lbound = GFC_TYPE_ARRAY_LBOUND (type, dim);
1150 1.1 mrg ubound = GFC_TYPE_ARRAY_UBOUND (type, dim);
1151 1.1 mrg rtype = build_range_type (gfc_array_index_type, lbound, ubound);
1152 1.1 mrg gtype = build_array_type (gtype, rtype);
1153 1.1 mrg /* Ensure the bound variables aren't optimized out at -O0.
1154 1.1 mrg For -O1 and above they often will be optimized out, but
1155 1.1 mrg can be tracked by VTA. Also set DECL_NAMELESS, so that
1156 1.1 mrg the artificial lbound.N or ubound.N DECL_NAME doesn't
1157 1.1 mrg end up in debug info. */
1158 1.1 mrg if (lbound
1159 1.1 mrg && VAR_P (lbound)
1160 1.1 mrg && DECL_ARTIFICIAL (lbound)
1161 1.1 mrg && DECL_IGNORED_P (lbound))
1162 1.1 mrg {
1163 1.1 mrg if (DECL_NAME (lbound)
1164 1.1 mrg && strstr (IDENTIFIER_POINTER (DECL_NAME (lbound)),
1165 1.1 mrg "lbound") != 0)
1166 1.1 mrg DECL_NAMELESS (lbound) = 1;
1167 1.1 mrg DECL_IGNORED_P (lbound) = 0;
1168 1.1 mrg }
1169 1.1 mrg if (ubound
1170 1.1 mrg && VAR_P (ubound)
1171 1.1 mrg && DECL_ARTIFICIAL (ubound)
1172 1.1 mrg && DECL_IGNORED_P (ubound))
1173 1.1 mrg {
1174 1.1 mrg if (DECL_NAME (ubound)
1175 1.1 mrg && strstr (IDENTIFIER_POINTER (DECL_NAME (ubound)),
1176 1.1 mrg "ubound") != 0)
1177 1.1 mrg DECL_NAMELESS (ubound) = 1;
1178 1.1 mrg DECL_IGNORED_P (ubound) = 0;
1179 1.1 mrg }
1180 1.1 mrg }
1181 1.1 mrg TYPE_NAME (type) = type_decl = build_decl (input_location,
1182 1.1 mrg TYPE_DECL, NULL, gtype);
1183 1.1 mrg DECL_ORIGINAL_TYPE (type_decl) = gtype;
1184 1.1 mrg }
1185 1.1 mrg }
1186 1.1 mrg
1187 1.1 mrg
1188 1.1 mrg /* For some dummy arguments we don't use the actual argument directly.
1189 1.1 mrg Instead we create a local decl and use that. This allows us to perform
1190 1.1 mrg initialization, and construct full type information. */
1191 1.1 mrg
1192 1.1 mrg static tree
1193 1.1 mrg gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
1194 1.1 mrg {
1195 1.1 mrg tree decl;
1196 1.1 mrg tree type;
1197 1.1 mrg gfc_array_spec *as;
1198 1.1 mrg symbol_attribute *array_attr;
1199 1.1 mrg char *name;
1200 1.1 mrg gfc_packed packed;
1201 1.1 mrg int n;
1202 1.1 mrg bool known_size;
1203 1.1 mrg bool is_classarray = IS_CLASS_ARRAY (sym);
1204 1.1 mrg
1205 1.1 mrg /* Use the array as and attr. */
1206 1.1 mrg as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
1207 1.1 mrg array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
1208 1.1 mrg
1209 1.1 mrg /* The dummy is returned for pointer, allocatable or assumed rank arrays.
1210 1.1 mrg For class arrays the information if sym is an allocatable or pointer
1211 1.1 mrg object needs to be checked explicitly (IS_CLASS_ARRAY can be false for
1212 1.1 mrg too many reasons to be of use here). */
1213 1.1 mrg if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
1214 1.1 mrg || (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.class_pointer)
1215 1.1 mrg || array_attr->allocatable
1216 1.1 mrg || (as && as->type == AS_ASSUMED_RANK))
1217 1.1 mrg return dummy;
1218 1.1 mrg
1219 1.1 mrg /* Add to list of variables if not a fake result variable.
1220 1.1 mrg These symbols are set on the symbol only, not on the class component. */
1221 1.1 mrg if (sym->attr.result || sym->attr.dummy)
1222 1.1 mrg gfc_defer_symbol_init (sym);
1223 1.1 mrg
1224 1.1 mrg /* For a class array the array descriptor is in the _data component, while
1225 1.1 mrg for a regular array the TREE_TYPE of the dummy is a pointer to the
1226 1.1 mrg descriptor. */
1227 1.1 mrg type = TREE_TYPE (is_classarray ? gfc_class_data_get (dummy)
1228 1.1 mrg : TREE_TYPE (dummy));
1229 1.1 mrg /* type now is the array descriptor w/o any indirection. */
1230 1.1 mrg gcc_assert (TREE_CODE (dummy) == PARM_DECL
1231 1.1 mrg && POINTER_TYPE_P (TREE_TYPE (dummy)));
1232 1.1 mrg
1233 1.1 mrg /* Do we know the element size? */
1234 1.1 mrg known_size = sym->ts.type != BT_CHARACTER
1235 1.1 mrg || INTEGER_CST_P (sym->ts.u.cl->backend_decl);
1236 1.1 mrg
1237 1.1 mrg if (known_size && !GFC_DESCRIPTOR_TYPE_P (type))
1238 1.1 mrg {
1239 1.1 mrg /* For descriptorless arrays with known element size the actual
1240 1.1 mrg argument is sufficient. */
1241 1.1 mrg gfc_build_qualified_array (dummy, sym);
1242 1.1 mrg return dummy;
1243 1.1 mrg }
1244 1.1 mrg
1245 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type))
1246 1.1 mrg {
1247 1.1 mrg /* Create a descriptorless array pointer. */
1248 1.1 mrg packed = PACKED_NO;
1249 1.1 mrg
1250 1.1 mrg /* Even when -frepack-arrays is used, symbols with TARGET attribute
1251 1.1 mrg are not repacked. */
1252 1.1 mrg if (!flag_repack_arrays || sym->attr.target)
1253 1.1 mrg {
1254 1.1 mrg if (as->type == AS_ASSUMED_SIZE)
1255 1.1 mrg packed = PACKED_FULL;
1256 1.1 mrg }
1257 1.1 mrg else
1258 1.1 mrg {
1259 1.1 mrg if (as->type == AS_EXPLICIT)
1260 1.1 mrg {
1261 1.1 mrg packed = PACKED_FULL;
1262 1.1 mrg for (n = 0; n < as->rank; n++)
1263 1.1 mrg {
1264 1.1 mrg if (!(as->upper[n]
1265 1.1 mrg && as->lower[n]
1266 1.1 mrg && as->upper[n]->expr_type == EXPR_CONSTANT
1267 1.1 mrg && as->lower[n]->expr_type == EXPR_CONSTANT))
1268 1.1 mrg {
1269 1.1 mrg packed = PACKED_PARTIAL;
1270 1.1 mrg break;
1271 1.1 mrg }
1272 1.1 mrg }
1273 1.1 mrg }
1274 1.1 mrg else
1275 1.1 mrg packed = PACKED_PARTIAL;
1276 1.1 mrg }
1277 1.1 mrg
1278 1.1 mrg /* For classarrays the element type is required, but
1279 1.1 mrg gfc_typenode_for_spec () returns the array descriptor. */
1280 1.1 mrg type = is_classarray ? gfc_get_element_type (type)
1281 1.1 mrg : gfc_typenode_for_spec (&sym->ts);
1282 1.1 mrg type = gfc_get_nodesc_array_type (type, as, packed,
1283 1.1 mrg !sym->attr.target);
1284 1.1 mrg }
1285 1.1 mrg else
1286 1.1 mrg {
1287 1.1 mrg /* We now have an expression for the element size, so create a fully
1288 1.1 mrg qualified type. Reset sym->backend decl or this will just return the
1289 1.1 mrg old type. */
1290 1.1 mrg DECL_ARTIFICIAL (sym->backend_decl) = 1;
1291 1.1 mrg sym->backend_decl = NULL_TREE;
1292 1.1 mrg type = gfc_sym_type (sym);
1293 1.1 mrg packed = PACKED_FULL;
1294 1.1 mrg }
1295 1.1 mrg
1296 1.1 mrg ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0);
1297 1.1 mrg decl = build_decl (input_location,
1298 1.1 mrg VAR_DECL, get_identifier (name), type);
1299 1.1 mrg
1300 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
1301 1.1 mrg DECL_NAMELESS (decl) = 1;
1302 1.1 mrg TREE_PUBLIC (decl) = 0;
1303 1.1 mrg TREE_STATIC (decl) = 0;
1304 1.1 mrg DECL_EXTERNAL (decl) = 0;
1305 1.1 mrg
1306 1.1 mrg /* Avoid uninitialized warnings for optional dummy arguments. */
1307 1.1 mrg if ((sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.optional)
1308 1.1 mrg || sym->attr.optional)
1309 1.1 mrg suppress_warning (decl);
1310 1.1 mrg
1311 1.1 mrg /* We should never get deferred shape arrays here. We used to because of
1312 1.1 mrg frontend bugs. */
1313 1.1 mrg gcc_assert (as->type != AS_DEFERRED);
1314 1.1 mrg
1315 1.1 mrg if (packed == PACKED_PARTIAL)
1316 1.1 mrg GFC_DECL_PARTIAL_PACKED_ARRAY (decl) = 1;
1317 1.1 mrg else if (packed == PACKED_FULL)
1318 1.1 mrg GFC_DECL_PACKED_ARRAY (decl) = 1;
1319 1.1 mrg
1320 1.1 mrg gfc_build_qualified_array (decl, sym);
1321 1.1 mrg
1322 1.1 mrg if (DECL_LANG_SPECIFIC (dummy))
1323 1.1 mrg DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (dummy);
1324 1.1 mrg else
1325 1.1 mrg gfc_allocate_lang_decl (decl);
1326 1.1 mrg
1327 1.1 mrg GFC_DECL_SAVED_DESCRIPTOR (decl) = dummy;
1328 1.1 mrg
1329 1.1 mrg if (sym->ns->proc_name->backend_decl == current_function_decl
1330 1.1 mrg || sym->attr.contained)
1331 1.1 mrg gfc_add_decl_to_function (decl);
1332 1.1 mrg else
1333 1.1 mrg gfc_add_decl_to_parent_function (decl);
1334 1.1 mrg
1335 1.1 mrg return decl;
1336 1.1 mrg }
1337 1.1 mrg
1338 1.1 mrg /* Return a constant or a variable to use as a string length. Does not
1339 1.1 mrg add the decl to the current scope. */
1340 1.1 mrg
1341 1.1 mrg static tree
1342 1.1 mrg gfc_create_string_length (gfc_symbol * sym)
1343 1.1 mrg {
1344 1.1 mrg gcc_assert (sym->ts.u.cl);
1345 1.1 mrg gfc_conv_const_charlen (sym->ts.u.cl);
1346 1.1 mrg
1347 1.1 mrg if (sym->ts.u.cl->backend_decl == NULL_TREE)
1348 1.1 mrg {
1349 1.1 mrg tree length;
1350 1.1 mrg const char *name;
1351 1.1 mrg
1352 1.1 mrg /* The string length variable shall be in static memory if it is either
1353 1.1 mrg explicitly SAVED, a module variable or with -fno-automatic. Only
1354 1.1 mrg relevant is "len=:" - otherwise, it is either a constant length or
1355 1.1 mrg it is an automatic variable. */
1356 1.1 mrg bool static_length = sym->attr.save
1357 1.1 mrg || sym->ns->proc_name->attr.flavor == FL_MODULE
1358 1.1 mrg || (flag_max_stack_var_size == 0
1359 1.1 mrg && sym->ts.deferred && !sym->attr.dummy
1360 1.1 mrg && !sym->attr.result && !sym->attr.function);
1361 1.1 mrg
1362 1.1 mrg /* Also prefix the mangled name. We need to call GFC_PREFIX for static
1363 1.1 mrg variables as some systems do not support the "." in the assembler name.
1364 1.1 mrg For nonstatic variables, the "." does not appear in assembler. */
1365 1.1 mrg if (static_length)
1366 1.1 mrg {
1367 1.1 mrg if (sym->module)
1368 1.1 mrg name = gfc_get_string (GFC_PREFIX ("%s_MOD_%s"), sym->module,
1369 1.1 mrg sym->name);
1370 1.1 mrg else
1371 1.1 mrg name = gfc_get_string (GFC_PREFIX ("%s"), sym->name);
1372 1.1 mrg }
1373 1.1 mrg else if (sym->module)
1374 1.1 mrg name = gfc_get_string (".__%s_MOD_%s", sym->module, sym->name);
1375 1.1 mrg else
1376 1.1 mrg name = gfc_get_string (".%s", sym->name);
1377 1.1 mrg
1378 1.1 mrg length = build_decl (input_location,
1379 1.1 mrg VAR_DECL, get_identifier (name),
1380 1.1 mrg gfc_charlen_type_node);
1381 1.1 mrg DECL_ARTIFICIAL (length) = 1;
1382 1.1 mrg TREE_USED (length) = 1;
1383 1.1 mrg if (sym->ns->proc_name->tlink != NULL)
1384 1.1 mrg gfc_defer_symbol_init (sym);
1385 1.1 mrg
1386 1.1 mrg sym->ts.u.cl->backend_decl = length;
1387 1.1 mrg
1388 1.1 mrg if (static_length)
1389 1.1 mrg TREE_STATIC (length) = 1;
1390 1.1 mrg
1391 1.1 mrg if (sym->ns->proc_name->attr.flavor == FL_MODULE
1392 1.1 mrg && (sym->attr.access != ACCESS_PRIVATE || sym->attr.public_used))
1393 1.1 mrg TREE_PUBLIC (length) = 1;
1394 1.1 mrg }
1395 1.1 mrg
1396 1.1 mrg gcc_assert (sym->ts.u.cl->backend_decl != NULL_TREE);
1397 1.1 mrg return sym->ts.u.cl->backend_decl;
1398 1.1 mrg }
1399 1.1 mrg
1400 1.1 mrg /* If a variable is assigned a label, we add another two auxiliary
1401 1.1 mrg variables. */
1402 1.1 mrg
1403 1.1 mrg static void
1404 1.1 mrg gfc_add_assign_aux_vars (gfc_symbol * sym)
1405 1.1 mrg {
1406 1.1 mrg tree addr;
1407 1.1 mrg tree length;
1408 1.1 mrg tree decl;
1409 1.1 mrg
1410 1.1 mrg gcc_assert (sym->backend_decl);
1411 1.1 mrg
1412 1.1 mrg decl = sym->backend_decl;
1413 1.1 mrg gfc_allocate_lang_decl (decl);
1414 1.1 mrg GFC_DECL_ASSIGN (decl) = 1;
1415 1.1 mrg length = build_decl (input_location,
1416 1.1 mrg VAR_DECL, create_tmp_var_name (sym->name),
1417 1.1 mrg gfc_charlen_type_node);
1418 1.1 mrg addr = build_decl (input_location,
1419 1.1 mrg VAR_DECL, create_tmp_var_name (sym->name),
1420 1.1 mrg pvoid_type_node);
1421 1.1 mrg gfc_finish_var_decl (length, sym);
1422 1.1 mrg gfc_finish_var_decl (addr, sym);
1423 1.1 mrg /* STRING_LENGTH is also used as flag. Less than -1 means that
1424 1.1 mrg ASSIGN_ADDR cannot be used. Equal -1 means that ASSIGN_ADDR is the
1425 1.1 mrg target label's address. Otherwise, value is the length of a format string
1426 1.1 mrg and ASSIGN_ADDR is its address. */
1427 1.1 mrg if (TREE_STATIC (length))
1428 1.1 mrg DECL_INITIAL (length) = build_int_cst (gfc_charlen_type_node, -2);
1429 1.1 mrg else
1430 1.1 mrg gfc_defer_symbol_init (sym);
1431 1.1 mrg
1432 1.1 mrg GFC_DECL_STRING_LEN (decl) = length;
1433 1.1 mrg GFC_DECL_ASSIGN_ADDR (decl) = addr;
1434 1.1 mrg }
1435 1.1 mrg
1436 1.1 mrg
1437 1.1 mrg static tree
1438 1.1 mrg add_attributes_to_decl (symbol_attribute sym_attr, tree list)
1439 1.1 mrg {
1440 1.1 mrg unsigned id;
1441 1.1 mrg tree attr;
1442 1.1 mrg
1443 1.1 mrg for (id = 0; id < EXT_ATTR_NUM; id++)
1444 1.1 mrg if (sym_attr.ext_attr & (1 << id) && ext_attr_list[id].middle_end_name)
1445 1.1 mrg {
1446 1.1 mrg attr = build_tree_list (
1447 1.1 mrg get_identifier (ext_attr_list[id].middle_end_name),
1448 1.1 mrg NULL_TREE);
1449 1.1 mrg list = chainon (list, attr);
1450 1.1 mrg }
1451 1.1 mrg
1452 1.1 mrg tree clauses = NULL_TREE;
1453 1.1 mrg
1454 1.1 mrg if (sym_attr.oacc_routine_lop != OACC_ROUTINE_LOP_NONE)
1455 1.1 mrg {
1456 1.1 mrg omp_clause_code code;
1457 1.1 mrg switch (sym_attr.oacc_routine_lop)
1458 1.1 mrg {
1459 1.1 mrg case OACC_ROUTINE_LOP_GANG:
1460 1.1 mrg code = OMP_CLAUSE_GANG;
1461 1.1 mrg break;
1462 1.1 mrg case OACC_ROUTINE_LOP_WORKER:
1463 1.1 mrg code = OMP_CLAUSE_WORKER;
1464 1.1 mrg break;
1465 1.1 mrg case OACC_ROUTINE_LOP_VECTOR:
1466 1.1 mrg code = OMP_CLAUSE_VECTOR;
1467 1.1 mrg break;
1468 1.1 mrg case OACC_ROUTINE_LOP_SEQ:
1469 1.1 mrg code = OMP_CLAUSE_SEQ;
1470 1.1 mrg break;
1471 1.1 mrg case OACC_ROUTINE_LOP_NONE:
1472 1.1 mrg case OACC_ROUTINE_LOP_ERROR:
1473 1.1 mrg default:
1474 1.1 mrg gcc_unreachable ();
1475 1.1 mrg }
1476 1.1 mrg tree c = build_omp_clause (UNKNOWN_LOCATION, code);
1477 1.1 mrg OMP_CLAUSE_CHAIN (c) = clauses;
1478 1.1 mrg clauses = c;
1479 1.1 mrg
1480 1.1 mrg tree dims = oacc_build_routine_dims (clauses);
1481 1.1 mrg list = oacc_replace_fn_attrib_attr (list, dims);
1482 1.1 mrg }
1483 1.1 mrg
1484 1.1 mrg if (sym_attr.oacc_routine_nohost)
1485 1.1 mrg {
1486 1.1 mrg tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_NOHOST);
1487 1.1 mrg OMP_CLAUSE_CHAIN (c) = clauses;
1488 1.1 mrg clauses = c;
1489 1.1 mrg }
1490 1.1 mrg
1491 1.1 mrg if (sym_attr.omp_device_type != OMP_DEVICE_TYPE_UNSET)
1492 1.1 mrg {
1493 1.1 mrg tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_DEVICE_TYPE);
1494 1.1 mrg switch (sym_attr.omp_device_type)
1495 1.1 mrg {
1496 1.1 mrg case OMP_DEVICE_TYPE_HOST:
1497 1.1 mrg OMP_CLAUSE_DEVICE_TYPE_KIND (c) = OMP_CLAUSE_DEVICE_TYPE_HOST;
1498 1.1 mrg break;
1499 1.1 mrg case OMP_DEVICE_TYPE_NOHOST:
1500 1.1 mrg OMP_CLAUSE_DEVICE_TYPE_KIND (c) = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
1501 1.1 mrg break;
1502 1.1 mrg case OMP_DEVICE_TYPE_ANY:
1503 1.1 mrg OMP_CLAUSE_DEVICE_TYPE_KIND (c) = OMP_CLAUSE_DEVICE_TYPE_ANY;
1504 1.1 mrg break;
1505 1.1 mrg default:
1506 1.1 mrg gcc_unreachable ();
1507 1.1 mrg }
1508 1.1 mrg OMP_CLAUSE_CHAIN (c) = clauses;
1509 1.1 mrg clauses = c;
1510 1.1 mrg }
1511 1.1 mrg
1512 1.1 mrg if (sym_attr.omp_declare_target_link
1513 1.1 mrg || sym_attr.oacc_declare_link)
1514 1.1 mrg list = tree_cons (get_identifier ("omp declare target link"),
1515 1.1 mrg clauses, list);
1516 1.1 mrg else if (sym_attr.omp_declare_target
1517 1.1 mrg || sym_attr.oacc_declare_create
1518 1.1 mrg || sym_attr.oacc_declare_copyin
1519 1.1 mrg || sym_attr.oacc_declare_deviceptr
1520 1.1 mrg || sym_attr.oacc_declare_device_resident)
1521 1.1 mrg list = tree_cons (get_identifier ("omp declare target"),
1522 1.1 mrg clauses, list);
1523 1.1 mrg
1524 1.1 mrg return list;
1525 1.1 mrg }
1526 1.1 mrg
1527 1.1 mrg
1528 1.1 mrg static void build_function_decl (gfc_symbol * sym, bool global);
1529 1.1 mrg
1530 1.1 mrg
1531 1.1 mrg /* Return the decl for a gfc_symbol, create it if it doesn't already
1532 1.1 mrg exist. */
1533 1.1 mrg
1534 1.1 mrg tree
1535 1.1 mrg gfc_get_symbol_decl (gfc_symbol * sym)
1536 1.1 mrg {
1537 1.1 mrg tree decl;
1538 1.1 mrg tree length = NULL_TREE;
1539 1.1 mrg tree attributes;
1540 1.1 mrg int byref;
1541 1.1 mrg bool intrinsic_array_parameter = false;
1542 1.1 mrg bool fun_or_res;
1543 1.1 mrg
1544 1.1 mrg gcc_assert (sym->attr.referenced
1545 1.1 mrg || sym->attr.flavor == FL_PROCEDURE
1546 1.1 mrg || sym->attr.use_assoc
1547 1.1 mrg || sym->attr.used_in_submodule
1548 1.1 mrg || sym->ns->proc_name->attr.if_source == IFSRC_IFBODY
1549 1.1 mrg || (sym->module && sym->attr.if_source != IFSRC_DECL
1550 1.1 mrg && sym->backend_decl));
1551 1.1 mrg
1552 1.1 mrg if (sym->attr.dummy && sym->ns->proc_name->attr.is_bind_c
1553 1.1 mrg && is_CFI_desc (sym, NULL))
1554 1.1 mrg {
1555 1.1 mrg gcc_assert (sym->backend_decl && (sym->ts.type != BT_CHARACTER
1556 1.1 mrg || sym->ts.u.cl->backend_decl));
1557 1.1 mrg return sym->backend_decl;
1558 1.1 mrg }
1559 1.1 mrg
1560 1.1 mrg if (sym->ns && sym->ns->proc_name && sym->ns->proc_name->attr.function)
1561 1.1 mrg byref = gfc_return_by_reference (sym->ns->proc_name);
1562 1.1 mrg else
1563 1.1 mrg byref = 0;
1564 1.1 mrg
1565 1.1 mrg /* Make sure that the vtab for the declared type is completed. */
1566 1.1 mrg if (sym->ts.type == BT_CLASS)
1567 1.1 mrg {
1568 1.1 mrg gfc_component *c = CLASS_DATA (sym);
1569 1.1 mrg if (!c->ts.u.derived->backend_decl)
1570 1.1 mrg {
1571 1.1 mrg gfc_find_derived_vtab (c->ts.u.derived);
1572 1.1 mrg gfc_get_derived_type (sym->ts.u.derived);
1573 1.1 mrg }
1574 1.1 mrg }
1575 1.1 mrg
1576 1.1 mrg /* PDT parameterized array components and string_lengths must have the
1577 1.1 mrg 'len' parameters substituted for the expressions appearing in the
1578 1.1 mrg declaration of the entity and memory allocated/deallocated. */
1579 1.1 mrg if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
1580 1.1 mrg && sym->param_list != NULL
1581 1.1 mrg && gfc_current_ns == sym->ns
1582 1.1 mrg && !(sym->attr.use_assoc || sym->attr.dummy))
1583 1.1 mrg gfc_defer_symbol_init (sym);
1584 1.1 mrg
1585 1.1 mrg /* Dummy PDT 'len' parameters should be checked when they are explicit. */
1586 1.1 mrg if ((sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
1587 1.1 mrg && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1588 1.1 mrg && sym->param_list != NULL
1589 1.1 mrg && sym->attr.dummy)
1590 1.1 mrg gfc_defer_symbol_init (sym);
1591 1.1 mrg
1592 1.1 mrg /* All deferred character length procedures need to retain the backend
1593 1.1 mrg decl, which is a pointer to the character length in the caller's
1594 1.1 mrg namespace and to declare a local character length. */
1595 1.1 mrg if (!byref && sym->attr.function
1596 1.1 mrg && sym->ts.type == BT_CHARACTER
1597 1.1 mrg && sym->ts.deferred
1598 1.1 mrg && sym->ts.u.cl->passed_length == NULL
1599 1.1 mrg && sym->ts.u.cl->backend_decl
1600 1.1 mrg && TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)
1601 1.1 mrg {
1602 1.1 mrg sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
1603 1.1 mrg gcc_assert (POINTER_TYPE_P (TREE_TYPE (sym->ts.u.cl->passed_length)));
1604 1.1 mrg sym->ts.u.cl->backend_decl = build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
1605 1.1 mrg }
1606 1.1 mrg
1607 1.1 mrg fun_or_res = byref && (sym->attr.result
1608 1.1 mrg || (sym->attr.function && sym->ts.deferred));
1609 1.1 mrg if ((sym->attr.dummy && ! sym->attr.function) || fun_or_res)
1610 1.1 mrg {
1611 1.1 mrg /* Return via extra parameter. */
1612 1.1 mrg if (sym->attr.result && byref
1613 1.1 mrg && !sym->backend_decl)
1614 1.1 mrg {
1615 1.1 mrg sym->backend_decl =
1616 1.1 mrg DECL_ARGUMENTS (sym->ns->proc_name->backend_decl);
1617 1.1 mrg /* For entry master function skip over the __entry
1618 1.1 mrg argument. */
1619 1.1 mrg if (sym->ns->proc_name->attr.entry_master)
1620 1.1 mrg sym->backend_decl = DECL_CHAIN (sym->backend_decl);
1621 1.1 mrg }
1622 1.1 mrg
1623 1.1 mrg /* Dummy variables should already have been created. */
1624 1.1 mrg gcc_assert (sym->backend_decl);
1625 1.1 mrg
1626 1.1 mrg /* However, the string length of deferred arrays must be set. */
1627 1.1 mrg if (sym->ts.type == BT_CHARACTER
1628 1.1 mrg && sym->ts.deferred
1629 1.1 mrg && sym->attr.dimension
1630 1.1 mrg && sym->attr.allocatable)
1631 1.1 mrg gfc_defer_symbol_init (sym);
1632 1.1 mrg
1633 1.1 mrg if (sym->attr.pointer && sym->attr.dimension && sym->ts.type != BT_CLASS)
1634 1.1 mrg GFC_DECL_PTR_ARRAY_P (sym->backend_decl) = 1;
1635 1.1 mrg
1636 1.1 mrg /* Create a character length variable. */
1637 1.1 mrg if (sym->ts.type == BT_CHARACTER)
1638 1.1 mrg {
1639 1.1 mrg /* For a deferred dummy, make a new string length variable. */
1640 1.1 mrg if (sym->ts.deferred
1641 1.1 mrg &&
1642 1.1 mrg (sym->ts.u.cl->passed_length == sym->ts.u.cl->backend_decl))
1643 1.1 mrg sym->ts.u.cl->backend_decl = NULL_TREE;
1644 1.1 mrg
1645 1.1 mrg if (sym->ts.deferred && byref)
1646 1.1 mrg {
1647 1.1 mrg /* The string length of a deferred char array is stored in the
1648 1.1 mrg parameter at sym->ts.u.cl->backend_decl as a reference and
1649 1.1 mrg marked as a result. Exempt this variable from generating a
1650 1.1 mrg temporary for it. */
1651 1.1 mrg if (sym->attr.result)
1652 1.1 mrg {
1653 1.1 mrg /* We need to insert a indirect ref for param decls. */
1654 1.1 mrg if (sym->ts.u.cl->backend_decl
1655 1.1 mrg && TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL)
1656 1.1 mrg {
1657 1.1 mrg sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
1658 1.1 mrg sym->ts.u.cl->backend_decl =
1659 1.1 mrg build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
1660 1.1 mrg }
1661 1.1 mrg }
1662 1.1 mrg /* For all other parameters make sure, that they are copied so
1663 1.1 mrg that the value and any modifications are local to the routine
1664 1.1 mrg by generating a temporary variable. */
1665 1.1 mrg else if (sym->attr.function
1666 1.1 mrg && sym->ts.u.cl->passed_length == NULL
1667 1.1 mrg && sym->ts.u.cl->backend_decl)
1668 1.1 mrg {
1669 1.1 mrg sym->ts.u.cl->passed_length = sym->ts.u.cl->backend_decl;
1670 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (sym->ts.u.cl->passed_length)))
1671 1.1 mrg sym->ts.u.cl->backend_decl
1672 1.1 mrg = build_fold_indirect_ref (sym->ts.u.cl->backend_decl);
1673 1.1 mrg else
1674 1.1 mrg sym->ts.u.cl->backend_decl = NULL_TREE;
1675 1.1 mrg }
1676 1.1 mrg }
1677 1.1 mrg
1678 1.1 mrg if (sym->ts.u.cl->backend_decl == NULL_TREE)
1679 1.1 mrg length = gfc_create_string_length (sym);
1680 1.1 mrg else
1681 1.1 mrg length = sym->ts.u.cl->backend_decl;
1682 1.1 mrg if (VAR_P (length) && DECL_FILE_SCOPE_P (length))
1683 1.1 mrg {
1684 1.1 mrg /* Add the string length to the same context as the symbol. */
1685 1.1 mrg if (DECL_CONTEXT (length) == NULL_TREE)
1686 1.1 mrg {
1687 1.1 mrg if (sym->backend_decl == current_function_decl
1688 1.1 mrg || (DECL_CONTEXT (sym->backend_decl)
1689 1.1 mrg == current_function_decl))
1690 1.1 mrg gfc_add_decl_to_function (length);
1691 1.1 mrg else
1692 1.1 mrg gfc_add_decl_to_parent_function (length);
1693 1.1 mrg }
1694 1.1 mrg
1695 1.1 mrg gcc_assert (sym->backend_decl == current_function_decl
1696 1.1 mrg ? DECL_CONTEXT (length) == current_function_decl
1697 1.1 mrg : (DECL_CONTEXT (sym->backend_decl)
1698 1.1 mrg == DECL_CONTEXT (length)));
1699 1.1 mrg
1700 1.1 mrg gfc_defer_symbol_init (sym);
1701 1.1 mrg }
1702 1.1 mrg }
1703 1.1 mrg
1704 1.1 mrg /* Use a copy of the descriptor for dummy arrays. */
1705 1.1 mrg if ((sym->attr.dimension || sym->attr.codimension)
1706 1.1 mrg && !TREE_USED (sym->backend_decl))
1707 1.1 mrg {
1708 1.1 mrg decl = gfc_build_dummy_array_decl (sym, sym->backend_decl);
1709 1.1 mrg /* Prevent the dummy from being detected as unused if it is copied. */
1710 1.1 mrg if (sym->backend_decl != NULL && decl != sym->backend_decl)
1711 1.1 mrg DECL_ARTIFICIAL (sym->backend_decl) = 1;
1712 1.1 mrg sym->backend_decl = decl;
1713 1.1 mrg }
1714 1.1 mrg
1715 1.1 mrg /* Returning the descriptor for dummy class arrays is hazardous, because
1716 1.1 mrg some caller is expecting an expression to apply the component refs to.
1717 1.1 mrg Therefore the descriptor is only created and stored in
1718 1.1 mrg sym->backend_decl's GFC_DECL_SAVED_DESCRIPTOR. The caller is then
1719 1.1 mrg responsible to extract it from there, when the descriptor is
1720 1.1 mrg desired. */
1721 1.1 mrg if (IS_CLASS_ARRAY (sym)
1722 1.1 mrg && (!DECL_LANG_SPECIFIC (sym->backend_decl)
1723 1.1 mrg || !GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl)))
1724 1.1 mrg {
1725 1.1 mrg decl = gfc_build_dummy_array_decl (sym, sym->backend_decl);
1726 1.1 mrg /* Prevent the dummy from being detected as unused if it is copied. */
1727 1.1 mrg if (sym->backend_decl != NULL && decl != sym->backend_decl)
1728 1.1 mrg DECL_ARTIFICIAL (sym->backend_decl) = 1;
1729 1.1 mrg sym->backend_decl = decl;
1730 1.1 mrg }
1731 1.1 mrg
1732 1.1 mrg TREE_USED (sym->backend_decl) = 1;
1733 1.1 mrg if (sym->attr.assign && GFC_DECL_ASSIGN (sym->backend_decl) == 0)
1734 1.1 mrg gfc_add_assign_aux_vars (sym);
1735 1.1 mrg
1736 1.1 mrg if (sym->ts.type == BT_CLASS && sym->backend_decl)
1737 1.1 mrg GFC_DECL_CLASS(sym->backend_decl) = 1;
1738 1.1 mrg
1739 1.1 mrg return sym->backend_decl;
1740 1.1 mrg }
1741 1.1 mrg
1742 1.1 mrg if (sym->result == sym && sym->attr.assign
1743 1.1 mrg && GFC_DECL_ASSIGN (sym->backend_decl) == 0)
1744 1.1 mrg gfc_add_assign_aux_vars (sym);
1745 1.1 mrg
1746 1.1 mrg if (sym->backend_decl)
1747 1.1 mrg return sym->backend_decl;
1748 1.1 mrg
1749 1.1 mrg /* Special case for array-valued named constants from intrinsic
1750 1.1 mrg procedures; those are inlined. */
1751 1.1 mrg if (sym->attr.use_assoc && sym->attr.flavor == FL_PARAMETER
1752 1.1 mrg && (sym->from_intmod == INTMOD_ISO_FORTRAN_ENV
1753 1.1 mrg || sym->from_intmod == INTMOD_ISO_C_BINDING))
1754 1.1 mrg intrinsic_array_parameter = true;
1755 1.1 mrg
1756 1.1 mrg /* If use associated compilation, use the module
1757 1.1 mrg declaration. */
1758 1.1 mrg if ((sym->attr.flavor == FL_VARIABLE
1759 1.1 mrg || sym->attr.flavor == FL_PARAMETER)
1760 1.1 mrg && (sym->attr.use_assoc || sym->attr.used_in_submodule)
1761 1.1 mrg && !intrinsic_array_parameter
1762 1.1 mrg && sym->module
1763 1.1 mrg && gfc_get_module_backend_decl (sym))
1764 1.1 mrg {
1765 1.1 mrg if (sym->ts.type == BT_CLASS && sym->backend_decl)
1766 1.1 mrg GFC_DECL_CLASS(sym->backend_decl) = 1;
1767 1.1 mrg return sym->backend_decl;
1768 1.1 mrg }
1769 1.1 mrg
1770 1.1 mrg if (sym->attr.flavor == FL_PROCEDURE)
1771 1.1 mrg {
1772 1.1 mrg /* Catch functions. Only used for actual parameters,
1773 1.1 mrg procedure pointers and procptr initialization targets. */
1774 1.1 mrg if (sym->attr.use_assoc
1775 1.1 mrg || sym->attr.used_in_submodule
1776 1.1 mrg || sym->attr.intrinsic
1777 1.1 mrg || sym->attr.if_source != IFSRC_DECL)
1778 1.1 mrg {
1779 1.1 mrg decl = gfc_get_extern_function_decl (sym);
1780 1.1 mrg }
1781 1.1 mrg else
1782 1.1 mrg {
1783 1.1 mrg if (!sym->backend_decl)
1784 1.1 mrg build_function_decl (sym, false);
1785 1.1 mrg decl = sym->backend_decl;
1786 1.1 mrg }
1787 1.1 mrg return decl;
1788 1.1 mrg }
1789 1.1 mrg
1790 1.1 mrg if (sym->attr.intrinsic)
1791 1.1 mrg gfc_internal_error ("intrinsic variable which isn't a procedure");
1792 1.1 mrg
1793 1.1 mrg /* Create string length decl first so that they can be used in the
1794 1.1 mrg type declaration. For associate names, the target character
1795 1.1 mrg length is used. Set 'length' to a constant so that if the
1796 1.1 mrg string length is a variable, it is not finished a second time. */
1797 1.1 mrg if (sym->ts.type == BT_CHARACTER)
1798 1.1 mrg {
1799 1.1 mrg if (sym->attr.associate_var
1800 1.1 mrg && sym->ts.deferred
1801 1.1 mrg && sym->assoc && sym->assoc->target
1802 1.1 mrg && ((sym->assoc->target->expr_type == EXPR_VARIABLE
1803 1.1 mrg && sym->assoc->target->symtree->n.sym->ts.type != BT_CHARACTER)
1804 1.1 mrg || sym->assoc->target->expr_type != EXPR_VARIABLE))
1805 1.1 mrg sym->ts.u.cl->backend_decl = NULL_TREE;
1806 1.1 mrg
1807 1.1 mrg if (sym->attr.associate_var
1808 1.1 mrg && sym->ts.u.cl->backend_decl
1809 1.1 mrg && (VAR_P (sym->ts.u.cl->backend_decl)
1810 1.1 mrg || TREE_CODE (sym->ts.u.cl->backend_decl) == PARM_DECL))
1811 1.1 mrg length = gfc_index_zero_node;
1812 1.1 mrg else
1813 1.1 mrg length = gfc_create_string_length (sym);
1814 1.1 mrg }
1815 1.1 mrg
1816 1.1 mrg /* Create the decl for the variable. */
1817 1.1 mrg decl = build_decl (gfc_get_location (&sym->declared_at),
1818 1.1 mrg VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym));
1819 1.1 mrg
1820 1.1 mrg /* Add attributes to variables. Functions are handled elsewhere. */
1821 1.1 mrg attributes = add_attributes_to_decl (sym->attr, NULL_TREE);
1822 1.1 mrg decl_attributes (&decl, attributes, 0);
1823 1.1 mrg
1824 1.1 mrg /* Symbols from modules should have their assembler names mangled.
1825 1.1 mrg This is done here rather than in gfc_finish_var_decl because it
1826 1.1 mrg is different for string length variables. */
1827 1.1 mrg if (sym->module || sym->fn_result_spec)
1828 1.1 mrg {
1829 1.1 mrg gfc_set_decl_assembler_name (decl, gfc_sym_mangled_identifier (sym));
1830 1.1 mrg if (sym->attr.use_assoc && !intrinsic_array_parameter)
1831 1.1 mrg DECL_IGNORED_P (decl) = 1;
1832 1.1 mrg }
1833 1.1 mrg
1834 1.1 mrg if (sym->attr.select_type_temporary)
1835 1.1 mrg {
1836 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
1837 1.1 mrg DECL_IGNORED_P (decl) = 1;
1838 1.1 mrg }
1839 1.1 mrg
1840 1.1 mrg if (sym->attr.dimension || sym->attr.codimension)
1841 1.1 mrg {
1842 1.1 mrg /* Create variables to hold the non-constant bits of array info. */
1843 1.1 mrg gfc_build_qualified_array (decl, sym);
1844 1.1 mrg
1845 1.1 mrg if (sym->attr.contiguous
1846 1.1 mrg || ((sym->attr.allocatable || !sym->attr.dummy) && !sym->attr.pointer))
1847 1.1 mrg GFC_DECL_PACKED_ARRAY (decl) = 1;
1848 1.1 mrg }
1849 1.1 mrg
1850 1.1 mrg /* Remember this variable for allocation/cleanup. */
1851 1.1 mrg if (sym->attr.dimension || sym->attr.allocatable || sym->attr.codimension
1852 1.1 mrg || (sym->ts.type == BT_CLASS &&
1853 1.1 mrg (CLASS_DATA (sym)->attr.dimension
1854 1.1 mrg || CLASS_DATA (sym)->attr.allocatable))
1855 1.1 mrg || (sym->ts.type == BT_DERIVED
1856 1.1 mrg && (sym->ts.u.derived->attr.alloc_comp
1857 1.1 mrg || (!sym->attr.pointer && !sym->attr.artificial && !sym->attr.save
1858 1.1 mrg && !sym->ns->proc_name->attr.is_main_program
1859 1.1 mrg && gfc_is_finalizable (sym->ts.u.derived, NULL))))
1860 1.1 mrg /* This applies a derived type default initializer. */
1861 1.1 mrg || (sym->ts.type == BT_DERIVED
1862 1.1 mrg && sym->attr.save == SAVE_NONE
1863 1.1 mrg && !sym->attr.data
1864 1.1 mrg && !sym->attr.allocatable
1865 1.1 mrg && (sym->value && !sym->ns->proc_name->attr.is_main_program)
1866 1.1 mrg && !(sym->attr.use_assoc && !intrinsic_array_parameter)))
1867 1.1 mrg gfc_defer_symbol_init (sym);
1868 1.1 mrg
1869 1.1 mrg if (sym->ts.type == BT_CHARACTER
1870 1.1 mrg && sym->attr.allocatable
1871 1.1 mrg && !sym->attr.dimension
1872 1.1 mrg && sym->ts.u.cl && sym->ts.u.cl->length
1873 1.1 mrg && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE)
1874 1.1 mrg gfc_defer_symbol_init (sym);
1875 1.1 mrg
1876 1.1 mrg /* Associate names can use the hidden string length variable
1877 1.1 mrg of their associated target. */
1878 1.1 mrg if (sym->ts.type == BT_CHARACTER
1879 1.1 mrg && TREE_CODE (length) != INTEGER_CST
1880 1.1 mrg && TREE_CODE (sym->ts.u.cl->backend_decl) != INDIRECT_REF)
1881 1.1 mrg {
1882 1.1 mrg length = fold_convert (gfc_charlen_type_node, length);
1883 1.1 mrg gfc_finish_var_decl (length, sym);
1884 1.1 mrg if (!sym->attr.associate_var
1885 1.1 mrg && TREE_CODE (length) == VAR_DECL
1886 1.1 mrg && sym->value && sym->value->expr_type != EXPR_NULL
1887 1.1 mrg && sym->value->ts.u.cl->length)
1888 1.1 mrg {
1889 1.1 mrg gfc_expr *len = sym->value->ts.u.cl->length;
1890 1.1 mrg DECL_INITIAL (length) = gfc_conv_initializer (len, &len->ts,
1891 1.1 mrg TREE_TYPE (length),
1892 1.1 mrg false, false, false);
1893 1.1 mrg DECL_INITIAL (length) = fold_convert (gfc_charlen_type_node,
1894 1.1 mrg DECL_INITIAL (length));
1895 1.1 mrg }
1896 1.1 mrg else
1897 1.1 mrg gcc_assert (!sym->value || sym->value->expr_type == EXPR_NULL);
1898 1.1 mrg }
1899 1.1 mrg
1900 1.1 mrg gfc_finish_var_decl (decl, sym);
1901 1.1 mrg
1902 1.1 mrg if (sym->ts.type == BT_CHARACTER)
1903 1.1 mrg /* Character variables need special handling. */
1904 1.1 mrg gfc_allocate_lang_decl (decl);
1905 1.1 mrg
1906 1.1 mrg if (sym->assoc && sym->attr.subref_array_pointer)
1907 1.1 mrg sym->attr.pointer = 1;
1908 1.1 mrg
1909 1.1 mrg if (sym->attr.pointer && sym->attr.dimension
1910 1.1 mrg && !sym->ts.deferred
1911 1.1 mrg && !(sym->attr.select_type_temporary
1912 1.1 mrg && !sym->attr.subref_array_pointer))
1913 1.1 mrg GFC_DECL_PTR_ARRAY_P (decl) = 1;
1914 1.1 mrg
1915 1.1 mrg if (sym->ts.type == BT_CLASS)
1916 1.1 mrg GFC_DECL_CLASS(decl) = 1;
1917 1.1 mrg
1918 1.1 mrg sym->backend_decl = decl;
1919 1.1 mrg
1920 1.1 mrg if (sym->attr.assign)
1921 1.1 mrg gfc_add_assign_aux_vars (sym);
1922 1.1 mrg
1923 1.1 mrg if (intrinsic_array_parameter)
1924 1.1 mrg {
1925 1.1 mrg TREE_STATIC (decl) = 1;
1926 1.1 mrg DECL_EXTERNAL (decl) = 0;
1927 1.1 mrg }
1928 1.1 mrg
1929 1.1 mrg if (TREE_STATIC (decl)
1930 1.1 mrg && !(sym->attr.use_assoc && !intrinsic_array_parameter)
1931 1.1 mrg && (sym->attr.save || sym->ns->proc_name->attr.is_main_program
1932 1.1 mrg || !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
1933 1.1 mrg || sym->attr.data || sym->ns->proc_name->attr.flavor == FL_MODULE)
1934 1.1 mrg && (flag_coarray != GFC_FCOARRAY_LIB
1935 1.1 mrg || !sym->attr.codimension || sym->attr.allocatable)
1936 1.1 mrg && !(sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
1937 1.1 mrg && !(sym->ts.type == BT_CLASS
1938 1.1 mrg && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type))
1939 1.1 mrg {
1940 1.1 mrg /* Add static initializer. For procedures, it is only needed if
1941 1.1 mrg SAVE is specified otherwise they need to be reinitialized
1942 1.1 mrg every time the procedure is entered. The TREE_STATIC is
1943 1.1 mrg in this case due to -fmax-stack-var-size=. */
1944 1.1 mrg
1945 1.1 mrg DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
1946 1.1 mrg TREE_TYPE (decl), sym->attr.dimension
1947 1.1 mrg || (sym->attr.codimension
1948 1.1 mrg && sym->attr.allocatable),
1949 1.1 mrg sym->attr.pointer || sym->attr.allocatable
1950 1.1 mrg || sym->ts.type == BT_CLASS,
1951 1.1 mrg sym->attr.proc_pointer);
1952 1.1 mrg }
1953 1.1 mrg
1954 1.1 mrg if (!TREE_STATIC (decl)
1955 1.1 mrg && POINTER_TYPE_P (TREE_TYPE (decl))
1956 1.1 mrg && !sym->attr.pointer
1957 1.1 mrg && !sym->attr.allocatable
1958 1.1 mrg && !sym->attr.proc_pointer
1959 1.1 mrg && !sym->attr.select_type_temporary)
1960 1.1 mrg DECL_BY_REFERENCE (decl) = 1;
1961 1.1 mrg
1962 1.1 mrg if (sym->attr.associate_var)
1963 1.1 mrg GFC_DECL_ASSOCIATE_VAR_P (decl) = 1;
1964 1.1 mrg
1965 1.1 mrg /* We only longer mark __def_init as read-only if it actually has an
1966 1.1 mrg initializer, it does not needlessly take up space in the
1967 1.1 mrg read-only section and can go into the BSS instead, see PR 84487.
1968 1.1 mrg Marking this as artificial means that OpenMP will treat this as
1969 1.1 mrg predetermined shared. */
1970 1.1 mrg
1971 1.1 mrg bool def_init = startswith (sym->name, "__def_init");
1972 1.1 mrg
1973 1.1 mrg if (sym->attr.vtab || def_init)
1974 1.1 mrg {
1975 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
1976 1.1 mrg if (def_init && sym->value)
1977 1.1 mrg TREE_READONLY (decl) = 1;
1978 1.1 mrg }
1979 1.1 mrg
1980 1.1 mrg return decl;
1981 1.1 mrg }
1982 1.1 mrg
1983 1.1 mrg
1984 1.1 mrg /* Substitute a temporary variable in place of the real one. */
1985 1.1 mrg
1986 1.1 mrg void
1987 1.1 mrg gfc_shadow_sym (gfc_symbol * sym, tree decl, gfc_saved_var * save)
1988 1.1 mrg {
1989 1.1 mrg save->attr = sym->attr;
1990 1.1 mrg save->decl = sym->backend_decl;
1991 1.1 mrg
1992 1.1 mrg gfc_clear_attr (&sym->attr);
1993 1.1 mrg sym->attr.referenced = 1;
1994 1.1 mrg sym->attr.flavor = FL_VARIABLE;
1995 1.1 mrg
1996 1.1 mrg sym->backend_decl = decl;
1997 1.1 mrg }
1998 1.1 mrg
1999 1.1 mrg
2000 1.1 mrg /* Restore the original variable. */
2001 1.1 mrg
2002 1.1 mrg void
2003 1.1 mrg gfc_restore_sym (gfc_symbol * sym, gfc_saved_var * save)
2004 1.1 mrg {
2005 1.1 mrg sym->attr = save->attr;
2006 1.1 mrg sym->backend_decl = save->decl;
2007 1.1 mrg }
2008 1.1 mrg
2009 1.1 mrg
2010 1.1 mrg /* Declare a procedure pointer. */
2011 1.1 mrg
2012 1.1 mrg static tree
2013 1.1 mrg get_proc_pointer_decl (gfc_symbol *sym)
2014 1.1 mrg {
2015 1.1 mrg tree decl;
2016 1.1 mrg tree attributes;
2017 1.1 mrg
2018 1.1 mrg if (sym->module || sym->fn_result_spec)
2019 1.1 mrg {
2020 1.1 mrg const char *name;
2021 1.1 mrg gfc_gsymbol *gsym;
2022 1.1 mrg
2023 1.1 mrg name = mangled_identifier (sym);
2024 1.1 mrg gsym = gfc_find_gsymbol (gfc_gsym_root, name);
2025 1.1 mrg if (gsym != NULL)
2026 1.1 mrg {
2027 1.1 mrg gfc_symbol *s;
2028 1.1 mrg gfc_find_symbol (sym->name, gsym->ns, 0, &s);
2029 1.1 mrg if (s && s->backend_decl)
2030 1.1 mrg return s->backend_decl;
2031 1.1 mrg }
2032 1.1 mrg }
2033 1.1 mrg
2034 1.1 mrg decl = sym->backend_decl;
2035 1.1 mrg if (decl)
2036 1.1 mrg return decl;
2037 1.1 mrg
2038 1.1 mrg decl = build_decl (input_location,
2039 1.1 mrg VAR_DECL, get_identifier (sym->name),
2040 1.1 mrg build_pointer_type (gfc_get_function_type (sym)));
2041 1.1 mrg
2042 1.1 mrg if (sym->module)
2043 1.1 mrg {
2044 1.1 mrg /* Apply name mangling. */
2045 1.1 mrg gfc_set_decl_assembler_name (decl, gfc_sym_mangled_identifier (sym));
2046 1.1 mrg if (sym->attr.use_assoc)
2047 1.1 mrg DECL_IGNORED_P (decl) = 1;
2048 1.1 mrg }
2049 1.1 mrg
2050 1.1 mrg if ((sym->ns->proc_name
2051 1.1 mrg && sym->ns->proc_name->backend_decl == current_function_decl)
2052 1.1 mrg || sym->attr.contained)
2053 1.1 mrg gfc_add_decl_to_function (decl);
2054 1.1 mrg else if (sym->ns->proc_name->attr.flavor != FL_MODULE)
2055 1.1 mrg gfc_add_decl_to_parent_function (decl);
2056 1.1 mrg
2057 1.1 mrg sym->backend_decl = decl;
2058 1.1 mrg
2059 1.1 mrg /* If a variable is USE associated, it's always external. */
2060 1.1 mrg if (sym->attr.use_assoc)
2061 1.1 mrg {
2062 1.1 mrg DECL_EXTERNAL (decl) = 1;
2063 1.1 mrg TREE_PUBLIC (decl) = 1;
2064 1.1 mrg }
2065 1.1 mrg else if (sym->module && sym->ns->proc_name->attr.flavor == FL_MODULE)
2066 1.1 mrg {
2067 1.1 mrg /* This is the declaration of a module variable. */
2068 1.1 mrg TREE_PUBLIC (decl) = 1;
2069 1.1 mrg if (sym->attr.access == ACCESS_PRIVATE && !sym->attr.public_used)
2070 1.1 mrg {
2071 1.1 mrg DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
2072 1.1 mrg DECL_VISIBILITY_SPECIFIED (decl) = true;
2073 1.1 mrg }
2074 1.1 mrg TREE_STATIC (decl) = 1;
2075 1.1 mrg }
2076 1.1 mrg
2077 1.1 mrg if (!sym->attr.use_assoc
2078 1.1 mrg && (sym->attr.save != SAVE_NONE || sym->attr.data
2079 1.1 mrg || (sym->value && sym->ns->proc_name->attr.is_main_program)))
2080 1.1 mrg TREE_STATIC (decl) = 1;
2081 1.1 mrg
2082 1.1 mrg if (TREE_STATIC (decl) && sym->value)
2083 1.1 mrg {
2084 1.1 mrg /* Add static initializer. */
2085 1.1 mrg DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
2086 1.1 mrg TREE_TYPE (decl),
2087 1.1 mrg sym->attr.dimension,
2088 1.1 mrg false, true);
2089 1.1 mrg }
2090 1.1 mrg
2091 1.1 mrg /* Handle threadprivate procedure pointers. */
2092 1.1 mrg if (sym->attr.threadprivate
2093 1.1 mrg && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
2094 1.1 mrg set_decl_tls_model (decl, decl_default_tls_model (decl));
2095 1.1 mrg
2096 1.1 mrg attributes = add_attributes_to_decl (sym->attr, NULL_TREE);
2097 1.1 mrg decl_attributes (&decl, attributes, 0);
2098 1.1 mrg
2099 1.1 mrg return decl;
2100 1.1 mrg }
2101 1.1 mrg
2102 1.1 mrg
2103 1.1 mrg /* Get a basic decl for an external function. */
2104 1.1 mrg
2105 1.1 mrg tree
2106 1.1 mrg gfc_get_extern_function_decl (gfc_symbol * sym, gfc_actual_arglist *actual_args,
2107 1.1 mrg const char *fnspec)
2108 1.1 mrg {
2109 1.1 mrg tree type;
2110 1.1 mrg tree fndecl;
2111 1.1 mrg tree attributes;
2112 1.1 mrg gfc_expr e;
2113 1.1 mrg gfc_intrinsic_sym *isym;
2114 1.1 mrg gfc_expr argexpr;
2115 1.1 mrg char s[GFC_MAX_SYMBOL_LEN + 23]; /* "_gfortran_f2c_specific" and '\0'. */
2116 1.1 mrg tree name;
2117 1.1 mrg tree mangled_name;
2118 1.1 mrg gfc_gsymbol *gsym;
2119 1.1 mrg
2120 1.1 mrg if (sym->backend_decl)
2121 1.1 mrg return sym->backend_decl;
2122 1.1 mrg
2123 1.1 mrg /* We should never be creating external decls for alternate entry points.
2124 1.1 mrg The procedure may be an alternate entry point, but we don't want/need
2125 1.1 mrg to know that. */
2126 1.1 mrg gcc_assert (!(sym->attr.entry || sym->attr.entry_master));
2127 1.1 mrg
2128 1.1 mrg if (sym->attr.proc_pointer)
2129 1.1 mrg return get_proc_pointer_decl (sym);
2130 1.1 mrg
2131 1.1 mrg /* See if this is an external procedure from the same file. If so,
2132 1.1 mrg return the backend_decl. If we are looking at a BIND(C)
2133 1.1 mrg procedure and the symbol is not BIND(C), or vice versa, we
2134 1.1 mrg haven't found the right procedure. */
2135 1.1 mrg
2136 1.1 mrg if (sym->binding_label)
2137 1.1 mrg {
2138 1.1 mrg gsym = gfc_find_gsymbol (gfc_gsym_root, sym->binding_label);
2139 1.1 mrg if (gsym && !gsym->bind_c)
2140 1.1 mrg gsym = NULL;
2141 1.1 mrg }
2142 1.1 mrg else if (sym->module == NULL)
2143 1.1 mrg {
2144 1.1 mrg gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
2145 1.1 mrg if (gsym && gsym->bind_c)
2146 1.1 mrg gsym = NULL;
2147 1.1 mrg }
2148 1.1 mrg else
2149 1.1 mrg {
2150 1.1 mrg /* Procedure from a different module. */
2151 1.1 mrg gsym = NULL;
2152 1.1 mrg }
2153 1.1 mrg
2154 1.1 mrg if (gsym && !gsym->defined)
2155 1.1 mrg gsym = NULL;
2156 1.1 mrg
2157 1.1 mrg /* This can happen because of C binding. */
2158 1.1 mrg if (gsym && gsym->ns && gsym->ns->proc_name
2159 1.1 mrg && gsym->ns->proc_name->attr.flavor == FL_MODULE)
2160 1.1 mrg goto module_sym;
2161 1.1 mrg
2162 1.1 mrg if ((!sym->attr.use_assoc || sym->attr.if_source != IFSRC_DECL)
2163 1.1 mrg && !sym->backend_decl
2164 1.1 mrg && gsym && gsym->ns
2165 1.1 mrg && ((gsym->type == GSYM_SUBROUTINE) || (gsym->type == GSYM_FUNCTION))
2166 1.1 mrg && (gsym->ns->proc_name->backend_decl || !sym->attr.intrinsic))
2167 1.1 mrg {
2168 1.1 mrg if (!gsym->ns->proc_name->backend_decl)
2169 1.1 mrg {
2170 1.1 mrg /* By construction, the external function cannot be
2171 1.1 mrg a contained procedure. */
2172 1.1 mrg locus old_loc;
2173 1.1 mrg
2174 1.1 mrg gfc_save_backend_locus (&old_loc);
2175 1.1 mrg push_cfun (NULL);
2176 1.1 mrg
2177 1.1 mrg gfc_create_function_decl (gsym->ns, true);
2178 1.1 mrg
2179 1.1 mrg pop_cfun ();
2180 1.1 mrg gfc_restore_backend_locus (&old_loc);
2181 1.1 mrg }
2182 1.1 mrg
2183 1.1 mrg /* If the namespace has entries, the proc_name is the
2184 1.1 mrg entry master. Find the entry and use its backend_decl.
2185 1.1 mrg otherwise, use the proc_name backend_decl. */
2186 1.1 mrg if (gsym->ns->entries)
2187 1.1 mrg {
2188 1.1 mrg gfc_entry_list *entry = gsym->ns->entries;
2189 1.1 mrg
2190 1.1 mrg for (; entry; entry = entry->next)
2191 1.1 mrg {
2192 1.1 mrg if (strcmp (gsym->name, entry->sym->name) == 0)
2193 1.1 mrg {
2194 1.1 mrg sym->backend_decl = entry->sym->backend_decl;
2195 1.1 mrg break;
2196 1.1 mrg }
2197 1.1 mrg }
2198 1.1 mrg }
2199 1.1 mrg else
2200 1.1 mrg sym->backend_decl = gsym->ns->proc_name->backend_decl;
2201 1.1 mrg
2202 1.1 mrg if (sym->backend_decl)
2203 1.1 mrg {
2204 1.1 mrg /* Avoid problems of double deallocation of the backend declaration
2205 1.1 mrg later in gfc_trans_use_stmts; cf. PR 45087. */
2206 1.1 mrg if (sym->attr.if_source != IFSRC_DECL && sym->attr.use_assoc)
2207 1.1 mrg sym->attr.use_assoc = 0;
2208 1.1 mrg
2209 1.1 mrg return sym->backend_decl;
2210 1.1 mrg }
2211 1.1 mrg }
2212 1.1 mrg
2213 1.1 mrg /* See if this is a module procedure from the same file. If so,
2214 1.1 mrg return the backend_decl. */
2215 1.1 mrg if (sym->module)
2216 1.1 mrg gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module);
2217 1.1 mrg
2218 1.1 mrg module_sym:
2219 1.1 mrg if (gsym && gsym->ns
2220 1.1 mrg && (gsym->type == GSYM_MODULE
2221 1.1 mrg || (gsym->ns->proc_name && gsym->ns->proc_name->attr.flavor == FL_MODULE)))
2222 1.1 mrg {
2223 1.1 mrg gfc_symbol *s;
2224 1.1 mrg
2225 1.1 mrg s = NULL;
2226 1.1 mrg if (gsym->type == GSYM_MODULE)
2227 1.1 mrg gfc_find_symbol (sym->name, gsym->ns, 0, &s);
2228 1.1 mrg else
2229 1.1 mrg gfc_find_symbol (gsym->sym_name, gsym->ns, 0, &s);
2230 1.1 mrg
2231 1.1 mrg if (s && s->backend_decl)
2232 1.1 mrg {
2233 1.1 mrg if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
2234 1.1 mrg gfc_copy_dt_decls_ifequal (s->ts.u.derived, sym->ts.u.derived,
2235 1.1 mrg true);
2236 1.1 mrg else if (sym->ts.type == BT_CHARACTER)
2237 1.1 mrg sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl;
2238 1.1 mrg sym->backend_decl = s->backend_decl;
2239 1.1 mrg return sym->backend_decl;
2240 1.1 mrg }
2241 1.1 mrg }
2242 1.1 mrg
2243 1.1 mrg if (sym->attr.intrinsic)
2244 1.1 mrg {
2245 1.1 mrg /* Call the resolution function to get the actual name. This is
2246 1.1 mrg a nasty hack which relies on the resolution functions only looking
2247 1.1 mrg at the first argument. We pass NULL for the second argument
2248 1.1 mrg otherwise things like AINT get confused. */
2249 1.1 mrg isym = gfc_find_function (sym->name);
2250 1.1 mrg gcc_assert (isym->resolve.f0 != NULL);
2251 1.1 mrg
2252 1.1 mrg memset (&e, 0, sizeof (e));
2253 1.1 mrg e.expr_type = EXPR_FUNCTION;
2254 1.1 mrg
2255 1.1 mrg memset (&argexpr, 0, sizeof (argexpr));
2256 1.1 mrg gcc_assert (isym->formal);
2257 1.1 mrg argexpr.ts = isym->formal->ts;
2258 1.1 mrg
2259 1.1 mrg if (isym->formal->next == NULL)
2260 1.1 mrg isym->resolve.f1 (&e, &argexpr);
2261 1.1 mrg else
2262 1.1 mrg {
2263 1.1 mrg if (isym->formal->next->next == NULL)
2264 1.1 mrg isym->resolve.f2 (&e, &argexpr, NULL);
2265 1.1 mrg else
2266 1.1 mrg {
2267 1.1 mrg if (isym->formal->next->next->next == NULL)
2268 1.1 mrg isym->resolve.f3 (&e, &argexpr, NULL, NULL);
2269 1.1 mrg else
2270 1.1 mrg {
2271 1.1 mrg /* All specific intrinsics take less than 5 arguments. */
2272 1.1 mrg gcc_assert (isym->formal->next->next->next->next == NULL);
2273 1.1 mrg isym->resolve.f4 (&e, &argexpr, NULL, NULL, NULL);
2274 1.1 mrg }
2275 1.1 mrg }
2276 1.1 mrg }
2277 1.1 mrg
2278 1.1 mrg if (flag_f2c
2279 1.1 mrg && ((e.ts.type == BT_REAL && e.ts.kind == gfc_default_real_kind)
2280 1.1 mrg || e.ts.type == BT_COMPLEX))
2281 1.1 mrg {
2282 1.1 mrg /* Specific which needs a different implementation if f2c
2283 1.1 mrg calling conventions are used. */
2284 1.1 mrg sprintf (s, "_gfortran_f2c_specific%s", e.value.function.name);
2285 1.1 mrg }
2286 1.1 mrg else
2287 1.1 mrg sprintf (s, "_gfortran_specific%s", e.value.function.name);
2288 1.1 mrg
2289 1.1 mrg name = get_identifier (s);
2290 1.1 mrg mangled_name = name;
2291 1.1 mrg }
2292 1.1 mrg else
2293 1.1 mrg {
2294 1.1 mrg name = gfc_sym_identifier (sym);
2295 1.1 mrg mangled_name = gfc_sym_mangled_function_id (sym);
2296 1.1 mrg }
2297 1.1 mrg
2298 1.1 mrg type = gfc_get_function_type (sym, actual_args, fnspec);
2299 1.1 mrg
2300 1.1 mrg fndecl = build_decl (input_location,
2301 1.1 mrg FUNCTION_DECL, name, type);
2302 1.1 mrg
2303 1.1 mrg /* Initialize DECL_EXTERNAL and TREE_PUBLIC before calling decl_attributes;
2304 1.1 mrg TREE_PUBLIC specifies whether a function is globally addressable (i.e.
2305 1.1 mrg the opposite of declaring a function as static in C). */
2306 1.1 mrg DECL_EXTERNAL (fndecl) = 1;
2307 1.1 mrg TREE_PUBLIC (fndecl) = 1;
2308 1.1 mrg
2309 1.1 mrg attributes = add_attributes_to_decl (sym->attr, NULL_TREE);
2310 1.1 mrg decl_attributes (&fndecl, attributes, 0);
2311 1.1 mrg
2312 1.1 mrg gfc_set_decl_assembler_name (fndecl, mangled_name);
2313 1.1 mrg
2314 1.1 mrg /* Set the context of this decl. */
2315 1.1 mrg if (0 && sym->ns && sym->ns->proc_name)
2316 1.1 mrg {
2317 1.1 mrg /* TODO: Add external decls to the appropriate scope. */
2318 1.1 mrg DECL_CONTEXT (fndecl) = sym->ns->proc_name->backend_decl;
2319 1.1 mrg }
2320 1.1 mrg else
2321 1.1 mrg {
2322 1.1 mrg /* Global declaration, e.g. intrinsic subroutine. */
2323 1.1 mrg DECL_CONTEXT (fndecl) = NULL_TREE;
2324 1.1 mrg }
2325 1.1 mrg
2326 1.1 mrg /* Set attributes for PURE functions. A call to PURE function in the
2327 1.1 mrg Fortran 95 sense is both pure and without side effects in the C
2328 1.1 mrg sense. */
2329 1.1 mrg if (sym->attr.pure || sym->attr.implicit_pure)
2330 1.1 mrg {
2331 1.1 mrg if (sym->attr.function && !gfc_return_by_reference (sym))
2332 1.1 mrg DECL_PURE_P (fndecl) = 1;
2333 1.1 mrg /* TODO: check if pure SUBROUTINEs don't have INTENT(OUT)
2334 1.1 mrg parameters and don't use alternate returns (is this
2335 1.1 mrg allowed?). In that case, calls to them are meaningless, and
2336 1.1 mrg can be optimized away. See also in build_function_decl(). */
2337 1.1 mrg TREE_SIDE_EFFECTS (fndecl) = 0;
2338 1.1 mrg }
2339 1.1 mrg
2340 1.1 mrg /* Mark non-returning functions. */
2341 1.1 mrg if (sym->attr.noreturn)
2342 1.1 mrg TREE_THIS_VOLATILE(fndecl) = 1;
2343 1.1 mrg
2344 1.1 mrg sym->backend_decl = fndecl;
2345 1.1 mrg
2346 1.1 mrg if (DECL_CONTEXT (fndecl) == NULL_TREE)
2347 1.1 mrg pushdecl_top_level (fndecl);
2348 1.1 mrg
2349 1.1 mrg if (sym->formal_ns
2350 1.1 mrg && sym->formal_ns->proc_name == sym)
2351 1.1 mrg {
2352 1.1 mrg if (sym->formal_ns->omp_declare_simd)
2353 1.1 mrg gfc_trans_omp_declare_simd (sym->formal_ns);
2354 1.1 mrg if (flag_openmp)
2355 1.1 mrg gfc_trans_omp_declare_variant (sym->formal_ns);
2356 1.1 mrg }
2357 1.1 mrg
2358 1.1 mrg return fndecl;
2359 1.1 mrg }
2360 1.1 mrg
2361 1.1 mrg
2362 1.1 mrg /* Create a declaration for a procedure. For external functions (in the C
2363 1.1 mrg sense) use gfc_get_extern_function_decl. HAS_ENTRIES is true if this is
2364 1.1 mrg a master function with alternate entry points. */
2365 1.1 mrg
2366 1.1 mrg static void
2367 1.1 mrg build_function_decl (gfc_symbol * sym, bool global)
2368 1.1 mrg {
2369 1.1 mrg tree fndecl, type, attributes;
2370 1.1 mrg symbol_attribute attr;
2371 1.1 mrg tree result_decl;
2372 1.1 mrg gfc_formal_arglist *f;
2373 1.1 mrg
2374 1.1 mrg bool module_procedure = sym->attr.module_procedure
2375 1.1 mrg && sym->ns
2376 1.1 mrg && sym->ns->proc_name
2377 1.1 mrg && sym->ns->proc_name->attr.flavor == FL_MODULE;
2378 1.1 mrg
2379 1.1 mrg gcc_assert (!sym->attr.external || module_procedure);
2380 1.1 mrg
2381 1.1 mrg if (sym->backend_decl)
2382 1.1 mrg return;
2383 1.1 mrg
2384 1.1 mrg /* Set the line and filename. sym->declared_at seems to point to the
2385 1.1 mrg last statement for subroutines, but it'll do for now. */
2386 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
2387 1.1 mrg
2388 1.1 mrg /* Allow only one nesting level. Allow public declarations. */
2389 1.1 mrg gcc_assert (current_function_decl == NULL_TREE
2390 1.1 mrg || DECL_FILE_SCOPE_P (current_function_decl)
2391 1.1 mrg || (TREE_CODE (DECL_CONTEXT (current_function_decl))
2392 1.1 mrg == NAMESPACE_DECL));
2393 1.1 mrg
2394 1.1 mrg type = gfc_get_function_type (sym);
2395 1.1 mrg fndecl = build_decl (input_location,
2396 1.1 mrg FUNCTION_DECL, gfc_sym_identifier (sym), type);
2397 1.1 mrg
2398 1.1 mrg attr = sym->attr;
2399 1.1 mrg
2400 1.1 mrg /* Initialize DECL_EXTERNAL and TREE_PUBLIC before calling decl_attributes;
2401 1.1 mrg TREE_PUBLIC specifies whether a function is globally addressable (i.e.
2402 1.1 mrg the opposite of declaring a function as static in C). */
2403 1.1 mrg DECL_EXTERNAL (fndecl) = 0;
2404 1.1 mrg
2405 1.1 mrg if (sym->attr.access == ACCESS_UNKNOWN && sym->module
2406 1.1 mrg && (sym->ns->default_access == ACCESS_PRIVATE
2407 1.1 mrg || (sym->ns->default_access == ACCESS_UNKNOWN
2408 1.1 mrg && flag_module_private)))
2409 1.1 mrg sym->attr.access = ACCESS_PRIVATE;
2410 1.1 mrg
2411 1.1 mrg if (!current_function_decl
2412 1.1 mrg && !sym->attr.entry_master && !sym->attr.is_main_program
2413 1.1 mrg && (sym->attr.access != ACCESS_PRIVATE || sym->binding_label
2414 1.1 mrg || sym->attr.public_used))
2415 1.1 mrg TREE_PUBLIC (fndecl) = 1;
2416 1.1 mrg
2417 1.1 mrg if (sym->attr.referenced || sym->attr.entry_master)
2418 1.1 mrg TREE_USED (fndecl) = 1;
2419 1.1 mrg
2420 1.1 mrg attributes = add_attributes_to_decl (attr, NULL_TREE);
2421 1.1 mrg decl_attributes (&fndecl, attributes, 0);
2422 1.1 mrg
2423 1.1 mrg /* Figure out the return type of the declared function, and build a
2424 1.1 mrg RESULT_DECL for it. If this is a subroutine with alternate
2425 1.1 mrg returns, build a RESULT_DECL for it. */
2426 1.1 mrg result_decl = NULL_TREE;
2427 1.1 mrg /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)). */
2428 1.1 mrg if (attr.function)
2429 1.1 mrg {
2430 1.1 mrg if (gfc_return_by_reference (sym))
2431 1.1 mrg type = void_type_node;
2432 1.1 mrg else
2433 1.1 mrg {
2434 1.1 mrg if (sym->result != sym)
2435 1.1 mrg result_decl = gfc_sym_identifier (sym->result);
2436 1.1 mrg
2437 1.1 mrg type = TREE_TYPE (TREE_TYPE (fndecl));
2438 1.1 mrg }
2439 1.1 mrg }
2440 1.1 mrg else
2441 1.1 mrg {
2442 1.1 mrg /* Look for alternate return placeholders. */
2443 1.1 mrg int has_alternate_returns = 0;
2444 1.1 mrg for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2445 1.1 mrg {
2446 1.1 mrg if (f->sym == NULL)
2447 1.1 mrg {
2448 1.1 mrg has_alternate_returns = 1;
2449 1.1 mrg break;
2450 1.1 mrg }
2451 1.1 mrg }
2452 1.1 mrg
2453 1.1 mrg if (has_alternate_returns)
2454 1.1 mrg type = integer_type_node;
2455 1.1 mrg else
2456 1.1 mrg type = void_type_node;
2457 1.1 mrg }
2458 1.1 mrg
2459 1.1 mrg result_decl = build_decl (input_location,
2460 1.1 mrg RESULT_DECL, result_decl, type);
2461 1.1 mrg DECL_ARTIFICIAL (result_decl) = 1;
2462 1.1 mrg DECL_IGNORED_P (result_decl) = 1;
2463 1.1 mrg DECL_CONTEXT (result_decl) = fndecl;
2464 1.1 mrg DECL_RESULT (fndecl) = result_decl;
2465 1.1 mrg
2466 1.1 mrg /* Don't call layout_decl for a RESULT_DECL.
2467 1.1 mrg layout_decl (result_decl, 0); */
2468 1.1 mrg
2469 1.1 mrg /* TREE_STATIC means the function body is defined here. */
2470 1.1 mrg TREE_STATIC (fndecl) = 1;
2471 1.1 mrg
2472 1.1 mrg /* Set attributes for PURE functions. A call to a PURE function in the
2473 1.1 mrg Fortran 95 sense is both pure and without side effects in the C
2474 1.1 mrg sense. */
2475 1.1 mrg if (attr.pure || attr.implicit_pure)
2476 1.1 mrg {
2477 1.1 mrg /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments
2478 1.1 mrg including an alternate return. In that case it can also be
2479 1.1 mrg marked as PURE. See also in gfc_get_extern_function_decl(). */
2480 1.1 mrg if (attr.function && !gfc_return_by_reference (sym))
2481 1.1 mrg DECL_PURE_P (fndecl) = 1;
2482 1.1 mrg TREE_SIDE_EFFECTS (fndecl) = 0;
2483 1.1 mrg }
2484 1.1 mrg
2485 1.1 mrg
2486 1.1 mrg /* Layout the function declaration and put it in the binding level
2487 1.1 mrg of the current function. */
2488 1.1 mrg
2489 1.1 mrg if (global)
2490 1.1 mrg pushdecl_top_level (fndecl);
2491 1.1 mrg else
2492 1.1 mrg pushdecl (fndecl);
2493 1.1 mrg
2494 1.1 mrg /* Perform name mangling if this is a top level or module procedure. */
2495 1.1 mrg if (current_function_decl == NULL_TREE)
2496 1.1 mrg gfc_set_decl_assembler_name (fndecl, gfc_sym_mangled_function_id (sym));
2497 1.1 mrg
2498 1.1 mrg sym->backend_decl = fndecl;
2499 1.1 mrg }
2500 1.1 mrg
2501 1.1 mrg
2502 1.1 mrg /* Create the DECL_ARGUMENTS for a procedure.
2503 1.1 mrg NOTE: The arguments added here must match the argument type created by
2504 1.1 mrg gfc_get_function_type (). */
2505 1.1 mrg
2506 1.1 mrg static void
2507 1.1 mrg create_function_arglist (gfc_symbol * sym)
2508 1.1 mrg {
2509 1.1 mrg tree fndecl;
2510 1.1 mrg gfc_formal_arglist *f;
2511 1.1 mrg tree typelist, hidden_typelist;
2512 1.1 mrg tree arglist, hidden_arglist;
2513 1.1 mrg tree type;
2514 1.1 mrg tree parm;
2515 1.1 mrg
2516 1.1 mrg fndecl = sym->backend_decl;
2517 1.1 mrg
2518 1.1 mrg /* Build formal argument list. Make sure that their TREE_CONTEXT is
2519 1.1 mrg the new FUNCTION_DECL node. */
2520 1.1 mrg arglist = NULL_TREE;
2521 1.1 mrg hidden_arglist = NULL_TREE;
2522 1.1 mrg typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
2523 1.1 mrg
2524 1.1 mrg if (sym->attr.entry_master)
2525 1.1 mrg {
2526 1.1 mrg type = TREE_VALUE (typelist);
2527 1.1 mrg parm = build_decl (input_location,
2528 1.1 mrg PARM_DECL, get_identifier ("__entry"), type);
2529 1.1 mrg
2530 1.1 mrg DECL_CONTEXT (parm) = fndecl;
2531 1.1 mrg DECL_ARG_TYPE (parm) = type;
2532 1.1 mrg TREE_READONLY (parm) = 1;
2533 1.1 mrg gfc_finish_decl (parm);
2534 1.1 mrg DECL_ARTIFICIAL (parm) = 1;
2535 1.1 mrg
2536 1.1 mrg arglist = chainon (arglist, parm);
2537 1.1 mrg typelist = TREE_CHAIN (typelist);
2538 1.1 mrg }
2539 1.1 mrg
2540 1.1 mrg if (gfc_return_by_reference (sym))
2541 1.1 mrg {
2542 1.1 mrg tree type = TREE_VALUE (typelist), length = NULL;
2543 1.1 mrg
2544 1.1 mrg if (sym->ts.type == BT_CHARACTER)
2545 1.1 mrg {
2546 1.1 mrg /* Length of character result. */
2547 1.1 mrg tree len_type = TREE_VALUE (TREE_CHAIN (typelist));
2548 1.1 mrg
2549 1.1 mrg length = build_decl (input_location,
2550 1.1 mrg PARM_DECL,
2551 1.1 mrg get_identifier (".__result"),
2552 1.1 mrg len_type);
2553 1.1 mrg if (POINTER_TYPE_P (len_type))
2554 1.1 mrg {
2555 1.1 mrg sym->ts.u.cl->passed_length = length;
2556 1.1 mrg TREE_USED (length) = 1;
2557 1.1 mrg }
2558 1.1 mrg else if (!sym->ts.u.cl->length)
2559 1.1 mrg {
2560 1.1 mrg sym->ts.u.cl->backend_decl = length;
2561 1.1 mrg TREE_USED (length) = 1;
2562 1.1 mrg }
2563 1.1 mrg gcc_assert (TREE_CODE (length) == PARM_DECL);
2564 1.1 mrg DECL_CONTEXT (length) = fndecl;
2565 1.1 mrg DECL_ARG_TYPE (length) = len_type;
2566 1.1 mrg TREE_READONLY (length) = 1;
2567 1.1 mrg DECL_ARTIFICIAL (length) = 1;
2568 1.1 mrg gfc_finish_decl (length);
2569 1.1 mrg if (sym->ts.u.cl->backend_decl == NULL
2570 1.1 mrg || sym->ts.u.cl->backend_decl == length)
2571 1.1 mrg {
2572 1.1 mrg gfc_symbol *arg;
2573 1.1 mrg tree backend_decl;
2574 1.1 mrg
2575 1.1 mrg if (sym->ts.u.cl->backend_decl == NULL)
2576 1.1 mrg {
2577 1.1 mrg tree len = build_decl (input_location,
2578 1.1 mrg VAR_DECL,
2579 1.1 mrg get_identifier ("..__result"),
2580 1.1 mrg gfc_charlen_type_node);
2581 1.1 mrg DECL_ARTIFICIAL (len) = 1;
2582 1.1 mrg TREE_USED (len) = 1;
2583 1.1 mrg sym->ts.u.cl->backend_decl = len;
2584 1.1 mrg }
2585 1.1 mrg
2586 1.1 mrg /* Make sure PARM_DECL type doesn't point to incomplete type. */
2587 1.1 mrg arg = sym->result ? sym->result : sym;
2588 1.1 mrg backend_decl = arg->backend_decl;
2589 1.1 mrg /* Temporary clear it, so that gfc_sym_type creates complete
2590 1.1 mrg type. */
2591 1.1 mrg arg->backend_decl = NULL;
2592 1.1 mrg type = gfc_sym_type (arg);
2593 1.1 mrg arg->backend_decl = backend_decl;
2594 1.1 mrg type = build_reference_type (type);
2595 1.1 mrg }
2596 1.1 mrg }
2597 1.1 mrg
2598 1.1 mrg parm = build_decl (input_location,
2599 1.1 mrg PARM_DECL, get_identifier ("__result"), type);
2600 1.1 mrg
2601 1.1 mrg DECL_CONTEXT (parm) = fndecl;
2602 1.1 mrg DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
2603 1.1 mrg TREE_READONLY (parm) = 1;
2604 1.1 mrg DECL_ARTIFICIAL (parm) = 1;
2605 1.1 mrg gfc_finish_decl (parm);
2606 1.1 mrg
2607 1.1 mrg arglist = chainon (arglist, parm);
2608 1.1 mrg typelist = TREE_CHAIN (typelist);
2609 1.1 mrg
2610 1.1 mrg if (sym->ts.type == BT_CHARACTER)
2611 1.1 mrg {
2612 1.1 mrg gfc_allocate_lang_decl (parm);
2613 1.1 mrg arglist = chainon (arglist, length);
2614 1.1 mrg typelist = TREE_CHAIN (typelist);
2615 1.1 mrg }
2616 1.1 mrg }
2617 1.1 mrg
2618 1.1 mrg hidden_typelist = typelist;
2619 1.1 mrg for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2620 1.1 mrg if (f->sym != NULL) /* Ignore alternate returns. */
2621 1.1 mrg hidden_typelist = TREE_CHAIN (hidden_typelist);
2622 1.1 mrg
2623 1.1 mrg for (f = gfc_sym_get_dummy_args (sym); f; f = f->next)
2624 1.1 mrg {
2625 1.1 mrg char name[GFC_MAX_SYMBOL_LEN + 2];
2626 1.1 mrg
2627 1.1 mrg /* Ignore alternate returns. */
2628 1.1 mrg if (f->sym == NULL)
2629 1.1 mrg continue;
2630 1.1 mrg
2631 1.1 mrg type = TREE_VALUE (typelist);
2632 1.1 mrg
2633 1.1 mrg if (f->sym->ts.type == BT_CHARACTER
2634 1.1 mrg && (!sym->attr.is_bind_c || sym->attr.entry_master))
2635 1.1 mrg {
2636 1.1 mrg tree len_type = TREE_VALUE (hidden_typelist);
2637 1.1 mrg tree length = NULL_TREE;
2638 1.1 mrg if (!f->sym->ts.deferred)
2639 1.1 mrg gcc_assert (len_type == gfc_charlen_type_node);
2640 1.1 mrg else
2641 1.1 mrg gcc_assert (POINTER_TYPE_P (len_type));
2642 1.1 mrg
2643 1.1 mrg strcpy (&name[1], f->sym->name);
2644 1.1 mrg name[0] = '_';
2645 1.1 mrg length = build_decl (input_location,
2646 1.1 mrg PARM_DECL, get_identifier (name), len_type);
2647 1.1 mrg
2648 1.1 mrg hidden_arglist = chainon (hidden_arglist, length);
2649 1.1 mrg DECL_CONTEXT (length) = fndecl;
2650 1.1 mrg DECL_ARTIFICIAL (length) = 1;
2651 1.1 mrg DECL_ARG_TYPE (length) = len_type;
2652 1.1 mrg TREE_READONLY (length) = 1;
2653 1.1 mrg gfc_finish_decl (length);
2654 1.1 mrg
2655 1.1 mrg /* Marking the length DECL_HIDDEN_STRING_LENGTH will lead
2656 1.1 mrg to tail calls being disabled. Only do that if we
2657 1.1 mrg potentially have broken callers. */
2658 1.1 mrg if (flag_tail_call_workaround
2659 1.1 mrg && f->sym->ts.u.cl
2660 1.1 mrg && f->sym->ts.u.cl->length
2661 1.1 mrg && f->sym->ts.u.cl->length->expr_type == EXPR_CONSTANT
2662 1.1 mrg && (flag_tail_call_workaround == 2
2663 1.1 mrg || f->sym->ns->implicit_interface_calls))
2664 1.1 mrg DECL_HIDDEN_STRING_LENGTH (length) = 1;
2665 1.1 mrg
2666 1.1 mrg /* Remember the passed value. */
2667 1.1 mrg if (!f->sym->ts.u.cl || f->sym->ts.u.cl->passed_length)
2668 1.1 mrg {
2669 1.1 mrg /* This can happen if the same type is used for multiple
2670 1.1 mrg arguments. We need to copy cl as otherwise
2671 1.1 mrg cl->passed_length gets overwritten. */
2672 1.1 mrg f->sym->ts.u.cl = gfc_new_charlen (f->sym->ns, f->sym->ts.u.cl);
2673 1.1 mrg }
2674 1.1 mrg f->sym->ts.u.cl->passed_length = length;
2675 1.1 mrg
2676 1.1 mrg /* Use the passed value for assumed length variables. */
2677 1.1 mrg if (!f->sym->ts.u.cl->length)
2678 1.1 mrg {
2679 1.1 mrg TREE_USED (length) = 1;
2680 1.1 mrg gcc_assert (!f->sym->ts.u.cl->backend_decl);
2681 1.1 mrg f->sym->ts.u.cl->backend_decl = length;
2682 1.1 mrg }
2683 1.1 mrg
2684 1.1 mrg hidden_typelist = TREE_CHAIN (hidden_typelist);
2685 1.1 mrg
2686 1.1 mrg if (f->sym->ts.u.cl->backend_decl == NULL
2687 1.1 mrg || f->sym->ts.u.cl->backend_decl == length)
2688 1.1 mrg {
2689 1.1 mrg if (POINTER_TYPE_P (len_type))
2690 1.1 mrg f->sym->ts.u.cl->backend_decl
2691 1.1 mrg = build_fold_indirect_ref_loc (input_location, length);
2692 1.1 mrg else if (f->sym->ts.u.cl->backend_decl == NULL)
2693 1.1 mrg gfc_create_string_length (f->sym);
2694 1.1 mrg
2695 1.1 mrg /* Make sure PARM_DECL type doesn't point to incomplete type. */
2696 1.1 mrg if (f->sym->attr.flavor == FL_PROCEDURE)
2697 1.1 mrg type = build_pointer_type (gfc_get_function_type (f->sym));
2698 1.1 mrg else
2699 1.1 mrg type = gfc_sym_type (f->sym);
2700 1.1 mrg }
2701 1.1 mrg }
2702 1.1 mrg /* For noncharacter scalar intrinsic types, VALUE passes the value,
2703 1.1 mrg hence, the optional status cannot be transferred via a NULL pointer.
2704 1.1 mrg Thus, we will use a hidden argument in that case. */
2705 1.1 mrg else if (f->sym->attr.optional && f->sym->attr.value
2706 1.1 mrg && !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
2707 1.1 mrg && !gfc_bt_struct (f->sym->ts.type))
2708 1.1 mrg {
2709 1.1 mrg tree tmp;
2710 1.1 mrg strcpy (&name[1], f->sym->name);
2711 1.1 mrg name[0] = '_';
2712 1.1 mrg tmp = build_decl (input_location,
2713 1.1 mrg PARM_DECL, get_identifier (name),
2714 1.1 mrg boolean_type_node);
2715 1.1 mrg
2716 1.1 mrg hidden_arglist = chainon (hidden_arglist, tmp);
2717 1.1 mrg DECL_CONTEXT (tmp) = fndecl;
2718 1.1 mrg DECL_ARTIFICIAL (tmp) = 1;
2719 1.1 mrg DECL_ARG_TYPE (tmp) = boolean_type_node;
2720 1.1 mrg TREE_READONLY (tmp) = 1;
2721 1.1 mrg gfc_finish_decl (tmp);
2722 1.1 mrg
2723 1.1 mrg hidden_typelist = TREE_CHAIN (hidden_typelist);
2724 1.1 mrg }
2725 1.1 mrg
2726 1.1 mrg /* For non-constant length array arguments, make sure they use
2727 1.1 mrg a different type node from TYPE_ARG_TYPES type. */
2728 1.1 mrg if (f->sym->attr.dimension
2729 1.1 mrg && type == TREE_VALUE (typelist)
2730 1.1 mrg && TREE_CODE (type) == POINTER_TYPE
2731 1.1 mrg && GFC_ARRAY_TYPE_P (type)
2732 1.1 mrg && f->sym->as->type != AS_ASSUMED_SIZE
2733 1.1 mrg && ! COMPLETE_TYPE_P (TREE_TYPE (type)))
2734 1.1 mrg {
2735 1.1 mrg if (f->sym->attr.flavor == FL_PROCEDURE)
2736 1.1 mrg type = build_pointer_type (gfc_get_function_type (f->sym));
2737 1.1 mrg else
2738 1.1 mrg type = gfc_sym_type (f->sym);
2739 1.1 mrg }
2740 1.1 mrg
2741 1.1 mrg if (f->sym->attr.proc_pointer)
2742 1.1 mrg type = build_pointer_type (type);
2743 1.1 mrg
2744 1.1 mrg if (f->sym->attr.volatile_)
2745 1.1 mrg type = build_qualified_type (type, TYPE_QUAL_VOLATILE);
2746 1.1 mrg
2747 1.1 mrg /* Build the argument declaration. For C descriptors, we use a
2748 1.1 mrg '_'-prefixed name for the parm_decl and inside the proc the
2749 1.1 mrg sym->name. */
2750 1.1 mrg tree parm_name;
2751 1.1 mrg if (sym->attr.is_bind_c && is_CFI_desc (f->sym, NULL))
2752 1.1 mrg {
2753 1.1 mrg strcpy (&name[1], f->sym->name);
2754 1.1 mrg name[0] = '_';
2755 1.1 mrg parm_name = get_identifier (name);
2756 1.1 mrg }
2757 1.1 mrg else
2758 1.1 mrg parm_name = gfc_sym_identifier (f->sym);
2759 1.1 mrg parm = build_decl (input_location, PARM_DECL, parm_name, type);
2760 1.1 mrg
2761 1.1 mrg if (f->sym->attr.volatile_)
2762 1.1 mrg {
2763 1.1 mrg TREE_THIS_VOLATILE (parm) = 1;
2764 1.1 mrg TREE_SIDE_EFFECTS (parm) = 1;
2765 1.1 mrg }
2766 1.1 mrg
2767 1.1 mrg /* Fill in arg stuff. */
2768 1.1 mrg DECL_CONTEXT (parm) = fndecl;
2769 1.1 mrg DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
2770 1.1 mrg /* All implementation args except for VALUE are read-only. */
2771 1.1 mrg if (!f->sym->attr.value)
2772 1.1 mrg TREE_READONLY (parm) = 1;
2773 1.1 mrg if (POINTER_TYPE_P (type)
2774 1.1 mrg && (!f->sym->attr.proc_pointer
2775 1.1 mrg && f->sym->attr.flavor != FL_PROCEDURE))
2776 1.1 mrg DECL_BY_REFERENCE (parm) = 1;
2777 1.1 mrg if (f->sym->attr.optional)
2778 1.1 mrg {
2779 1.1 mrg gfc_allocate_lang_decl (parm);
2780 1.1 mrg GFC_DECL_OPTIONAL_ARGUMENT (parm) = 1;
2781 1.1 mrg }
2782 1.1 mrg
2783 1.1 mrg gfc_finish_decl (parm);
2784 1.1 mrg gfc_finish_decl_attrs (parm, &f->sym->attr);
2785 1.1 mrg
2786 1.1 mrg f->sym->backend_decl = parm;
2787 1.1 mrg
2788 1.1 mrg /* Coarrays which are descriptorless or assumed-shape pass with
2789 1.1 mrg -fcoarray=lib the token and the offset as hidden arguments. */
2790 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB
2791 1.1 mrg && ((f->sym->ts.type != BT_CLASS && f->sym->attr.codimension
2792 1.1 mrg && !f->sym->attr.allocatable)
2793 1.1 mrg || (f->sym->ts.type == BT_CLASS
2794 1.1 mrg && CLASS_DATA (f->sym)->attr.codimension
2795 1.1 mrg && !CLASS_DATA (f->sym)->attr.allocatable)))
2796 1.1 mrg {
2797 1.1 mrg tree caf_type;
2798 1.1 mrg tree token;
2799 1.1 mrg tree offset;
2800 1.1 mrg
2801 1.1 mrg gcc_assert (f->sym->backend_decl != NULL_TREE
2802 1.1 mrg && !sym->attr.is_bind_c);
2803 1.1 mrg caf_type = f->sym->ts.type == BT_CLASS
2804 1.1 mrg ? TREE_TYPE (CLASS_DATA (f->sym)->backend_decl)
2805 1.1 mrg : TREE_TYPE (f->sym->backend_decl);
2806 1.1 mrg
2807 1.1 mrg token = build_decl (input_location, PARM_DECL,
2808 1.1 mrg create_tmp_var_name ("caf_token"),
2809 1.1 mrg build_qualified_type (pvoid_type_node,
2810 1.1 mrg TYPE_QUAL_RESTRICT));
2811 1.1 mrg if ((f->sym->ts.type != BT_CLASS
2812 1.1 mrg && f->sym->as->type != AS_DEFERRED)
2813 1.1 mrg || (f->sym->ts.type == BT_CLASS
2814 1.1 mrg && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
2815 1.1 mrg {
2816 1.1 mrg gcc_assert (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL
2817 1.1 mrg || GFC_DECL_TOKEN (f->sym->backend_decl) == NULL_TREE);
2818 1.1 mrg if (DECL_LANG_SPECIFIC (f->sym->backend_decl) == NULL)
2819 1.1 mrg gfc_allocate_lang_decl (f->sym->backend_decl);
2820 1.1 mrg GFC_DECL_TOKEN (f->sym->backend_decl) = token;
2821 1.1 mrg }
2822 1.1 mrg else
2823 1.1 mrg {
2824 1.1 mrg gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) == NULL_TREE);
2825 1.1 mrg GFC_TYPE_ARRAY_CAF_TOKEN (caf_type) = token;
2826 1.1 mrg }
2827 1.1 mrg
2828 1.1 mrg DECL_CONTEXT (token) = fndecl;
2829 1.1 mrg DECL_ARTIFICIAL (token) = 1;
2830 1.1 mrg DECL_ARG_TYPE (token) = TREE_VALUE (typelist);
2831 1.1 mrg TREE_READONLY (token) = 1;
2832 1.1 mrg hidden_arglist = chainon (hidden_arglist, token);
2833 1.1 mrg hidden_typelist = TREE_CHAIN (hidden_typelist);
2834 1.1 mrg gfc_finish_decl (token);
2835 1.1 mrg
2836 1.1 mrg offset = build_decl (input_location, PARM_DECL,
2837 1.1 mrg create_tmp_var_name ("caf_offset"),
2838 1.1 mrg gfc_array_index_type);
2839 1.1 mrg
2840 1.1 mrg if ((f->sym->ts.type != BT_CLASS
2841 1.1 mrg && f->sym->as->type != AS_DEFERRED)
2842 1.1 mrg || (f->sym->ts.type == BT_CLASS
2843 1.1 mrg && CLASS_DATA (f->sym)->as->type != AS_DEFERRED))
2844 1.1 mrg {
2845 1.1 mrg gcc_assert (GFC_DECL_CAF_OFFSET (f->sym->backend_decl)
2846 1.1 mrg == NULL_TREE);
2847 1.1 mrg GFC_DECL_CAF_OFFSET (f->sym->backend_decl) = offset;
2848 1.1 mrg }
2849 1.1 mrg else
2850 1.1 mrg {
2851 1.1 mrg gcc_assert (GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) == NULL_TREE);
2852 1.1 mrg GFC_TYPE_ARRAY_CAF_OFFSET (caf_type) = offset;
2853 1.1 mrg }
2854 1.1 mrg DECL_CONTEXT (offset) = fndecl;
2855 1.1 mrg DECL_ARTIFICIAL (offset) = 1;
2856 1.1 mrg DECL_ARG_TYPE (offset) = TREE_VALUE (typelist);
2857 1.1 mrg TREE_READONLY (offset) = 1;
2858 1.1 mrg hidden_arglist = chainon (hidden_arglist, offset);
2859 1.1 mrg hidden_typelist = TREE_CHAIN (hidden_typelist);
2860 1.1 mrg gfc_finish_decl (offset);
2861 1.1 mrg }
2862 1.1 mrg
2863 1.1 mrg arglist = chainon (arglist, parm);
2864 1.1 mrg typelist = TREE_CHAIN (typelist);
2865 1.1 mrg }
2866 1.1 mrg
2867 1.1 mrg /* Add the hidden string length parameters, unless the procedure
2868 1.1 mrg is bind(C). */
2869 1.1 mrg if (!sym->attr.is_bind_c)
2870 1.1 mrg arglist = chainon (arglist, hidden_arglist);
2871 1.1 mrg
2872 1.1 mrg gcc_assert (hidden_typelist == NULL_TREE
2873 1.1 mrg || TREE_VALUE (hidden_typelist) == void_type_node);
2874 1.1 mrg DECL_ARGUMENTS (fndecl) = arglist;
2875 1.1 mrg }
2876 1.1 mrg
2877 1.1 mrg /* Do the setup necessary before generating the body of a function. */
2878 1.1 mrg
2879 1.1 mrg static void
2880 1.1 mrg trans_function_start (gfc_symbol * sym)
2881 1.1 mrg {
2882 1.1 mrg tree fndecl;
2883 1.1 mrg
2884 1.1 mrg fndecl = sym->backend_decl;
2885 1.1 mrg
2886 1.1 mrg /* Let GCC know the current scope is this function. */
2887 1.1 mrg current_function_decl = fndecl;
2888 1.1 mrg
2889 1.1 mrg /* Let the world know what we're about to do. */
2890 1.1 mrg announce_function (fndecl);
2891 1.1 mrg
2892 1.1 mrg if (DECL_FILE_SCOPE_P (fndecl))
2893 1.1 mrg {
2894 1.1 mrg /* Create RTL for function declaration. */
2895 1.1 mrg rest_of_decl_compilation (fndecl, 1, 0);
2896 1.1 mrg }
2897 1.1 mrg
2898 1.1 mrg /* Create RTL for function definition. */
2899 1.1 mrg make_decl_rtl (fndecl);
2900 1.1 mrg
2901 1.1 mrg allocate_struct_function (fndecl, false);
2902 1.1 mrg
2903 1.1 mrg /* function.cc requires a push at the start of the function. */
2904 1.1 mrg pushlevel ();
2905 1.1 mrg }
2906 1.1 mrg
2907 1.1 mrg /* Create thunks for alternate entry points. */
2908 1.1 mrg
2909 1.1 mrg static void
2910 1.1 mrg build_entry_thunks (gfc_namespace * ns, bool global)
2911 1.1 mrg {
2912 1.1 mrg gfc_formal_arglist *formal;
2913 1.1 mrg gfc_formal_arglist *thunk_formal;
2914 1.1 mrg gfc_entry_list *el;
2915 1.1 mrg gfc_symbol *thunk_sym;
2916 1.1 mrg stmtblock_t body;
2917 1.1 mrg tree thunk_fndecl;
2918 1.1 mrg tree tmp;
2919 1.1 mrg locus old_loc;
2920 1.1 mrg
2921 1.1 mrg /* This should always be a toplevel function. */
2922 1.1 mrg gcc_assert (current_function_decl == NULL_TREE);
2923 1.1 mrg
2924 1.1 mrg gfc_save_backend_locus (&old_loc);
2925 1.1 mrg for (el = ns->entries; el; el = el->next)
2926 1.1 mrg {
2927 1.1 mrg vec<tree, va_gc> *args = NULL;
2928 1.1 mrg vec<tree, va_gc> *string_args = NULL;
2929 1.1 mrg
2930 1.1 mrg thunk_sym = el->sym;
2931 1.1 mrg
2932 1.1 mrg build_function_decl (thunk_sym, global);
2933 1.1 mrg create_function_arglist (thunk_sym);
2934 1.1 mrg
2935 1.1 mrg trans_function_start (thunk_sym);
2936 1.1 mrg
2937 1.1 mrg thunk_fndecl = thunk_sym->backend_decl;
2938 1.1 mrg
2939 1.1 mrg gfc_init_block (&body);
2940 1.1 mrg
2941 1.1 mrg /* Pass extra parameter identifying this entry point. */
2942 1.1 mrg tmp = build_int_cst (gfc_array_index_type, el->id);
2943 1.1 mrg vec_safe_push (args, tmp);
2944 1.1 mrg
2945 1.1 mrg if (thunk_sym->attr.function)
2946 1.1 mrg {
2947 1.1 mrg if (gfc_return_by_reference (ns->proc_name))
2948 1.1 mrg {
2949 1.1 mrg tree ref = DECL_ARGUMENTS (current_function_decl);
2950 1.1 mrg vec_safe_push (args, ref);
2951 1.1 mrg if (ns->proc_name->ts.type == BT_CHARACTER)
2952 1.1 mrg vec_safe_push (args, DECL_CHAIN (ref));
2953 1.1 mrg }
2954 1.1 mrg }
2955 1.1 mrg
2956 1.1 mrg for (formal = gfc_sym_get_dummy_args (ns->proc_name); formal;
2957 1.1 mrg formal = formal->next)
2958 1.1 mrg {
2959 1.1 mrg /* Ignore alternate returns. */
2960 1.1 mrg if (formal->sym == NULL)
2961 1.1 mrg continue;
2962 1.1 mrg
2963 1.1 mrg /* We don't have a clever way of identifying arguments, so resort to
2964 1.1 mrg a brute-force search. */
2965 1.1 mrg for (thunk_formal = gfc_sym_get_dummy_args (thunk_sym);
2966 1.1 mrg thunk_formal;
2967 1.1 mrg thunk_formal = thunk_formal->next)
2968 1.1 mrg {
2969 1.1 mrg if (thunk_formal->sym == formal->sym)
2970 1.1 mrg break;
2971 1.1 mrg }
2972 1.1 mrg
2973 1.1 mrg if (thunk_formal)
2974 1.1 mrg {
2975 1.1 mrg /* Pass the argument. */
2976 1.1 mrg DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1;
2977 1.1 mrg vec_safe_push (args, thunk_formal->sym->backend_decl);
2978 1.1 mrg if (formal->sym->ts.type == BT_CHARACTER)
2979 1.1 mrg {
2980 1.1 mrg tmp = thunk_formal->sym->ts.u.cl->backend_decl;
2981 1.1 mrg vec_safe_push (string_args, tmp);
2982 1.1 mrg }
2983 1.1 mrg }
2984 1.1 mrg else
2985 1.1 mrg {
2986 1.1 mrg /* Pass NULL for a missing argument. */
2987 1.1 mrg vec_safe_push (args, null_pointer_node);
2988 1.1 mrg if (formal->sym->ts.type == BT_CHARACTER)
2989 1.1 mrg {
2990 1.1 mrg tmp = build_int_cst (gfc_charlen_type_node, 0);
2991 1.1 mrg vec_safe_push (string_args, tmp);
2992 1.1 mrg }
2993 1.1 mrg }
2994 1.1 mrg }
2995 1.1 mrg
2996 1.1 mrg /* Call the master function. */
2997 1.1 mrg vec_safe_splice (args, string_args);
2998 1.1 mrg tmp = ns->proc_name->backend_decl;
2999 1.1 mrg tmp = build_call_expr_loc_vec (input_location, tmp, args);
3000 1.1 mrg if (ns->proc_name->attr.mixed_entry_master)
3001 1.1 mrg {
3002 1.1 mrg tree union_decl, field;
3003 1.1 mrg tree master_type = TREE_TYPE (ns->proc_name->backend_decl);
3004 1.1 mrg
3005 1.1 mrg union_decl = build_decl (input_location,
3006 1.1 mrg VAR_DECL, get_identifier ("__result"),
3007 1.1 mrg TREE_TYPE (master_type));
3008 1.1 mrg DECL_ARTIFICIAL (union_decl) = 1;
3009 1.1 mrg DECL_EXTERNAL (union_decl) = 0;
3010 1.1 mrg TREE_PUBLIC (union_decl) = 0;
3011 1.1 mrg TREE_USED (union_decl) = 1;
3012 1.1 mrg layout_decl (union_decl, 0);
3013 1.1 mrg pushdecl (union_decl);
3014 1.1 mrg
3015 1.1 mrg DECL_CONTEXT (union_decl) = current_function_decl;
3016 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3017 1.1 mrg TREE_TYPE (union_decl), union_decl, tmp);
3018 1.1 mrg gfc_add_expr_to_block (&body, tmp);
3019 1.1 mrg
3020 1.1 mrg for (field = TYPE_FIELDS (TREE_TYPE (union_decl));
3021 1.1 mrg field; field = DECL_CHAIN (field))
3022 1.1 mrg if (strcmp (IDENTIFIER_POINTER (DECL_NAME (field)),
3023 1.1 mrg thunk_sym->result->name) == 0)
3024 1.1 mrg break;
3025 1.1 mrg gcc_assert (field != NULL_TREE);
3026 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF,
3027 1.1 mrg TREE_TYPE (field), union_decl, field,
3028 1.1 mrg NULL_TREE);
3029 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3030 1.1 mrg TREE_TYPE (DECL_RESULT (current_function_decl)),
3031 1.1 mrg DECL_RESULT (current_function_decl), tmp);
3032 1.1 mrg tmp = build1_v (RETURN_EXPR, tmp);
3033 1.1 mrg }
3034 1.1 mrg else if (TREE_TYPE (DECL_RESULT (current_function_decl))
3035 1.1 mrg != void_type_node)
3036 1.1 mrg {
3037 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
3038 1.1 mrg TREE_TYPE (DECL_RESULT (current_function_decl)),
3039 1.1 mrg DECL_RESULT (current_function_decl), tmp);
3040 1.1 mrg tmp = build1_v (RETURN_EXPR, tmp);
3041 1.1 mrg }
3042 1.1 mrg gfc_add_expr_to_block (&body, tmp);
3043 1.1 mrg
3044 1.1 mrg /* Finish off this function and send it for code generation. */
3045 1.1 mrg DECL_SAVED_TREE (thunk_fndecl) = gfc_finish_block (&body);
3046 1.1 mrg tmp = getdecls ();
3047 1.1 mrg poplevel (1, 1);
3048 1.1 mrg BLOCK_SUPERCONTEXT (DECL_INITIAL (thunk_fndecl)) = thunk_fndecl;
3049 1.1 mrg DECL_SAVED_TREE (thunk_fndecl)
3050 1.1 mrg = fold_build3_loc (DECL_SOURCE_LOCATION (thunk_fndecl), BIND_EXPR,
3051 1.1 mrg void_type_node, tmp, DECL_SAVED_TREE (thunk_fndecl),
3052 1.1 mrg DECL_INITIAL (thunk_fndecl));
3053 1.1 mrg
3054 1.1 mrg /* Output the GENERIC tree. */
3055 1.1 mrg dump_function (TDI_original, thunk_fndecl);
3056 1.1 mrg
3057 1.1 mrg /* Store the end of the function, so that we get good line number
3058 1.1 mrg info for the epilogue. */
3059 1.1 mrg cfun->function_end_locus = input_location;
3060 1.1 mrg
3061 1.1 mrg /* We're leaving the context of this function, so zap cfun.
3062 1.1 mrg It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
3063 1.1 mrg tree_rest_of_compilation. */
3064 1.1 mrg set_cfun (NULL);
3065 1.1 mrg
3066 1.1 mrg current_function_decl = NULL_TREE;
3067 1.1 mrg
3068 1.1 mrg cgraph_node::finalize_function (thunk_fndecl, true);
3069 1.1 mrg
3070 1.1 mrg /* We share the symbols in the formal argument list with other entry
3071 1.1 mrg points and the master function. Clear them so that they are
3072 1.1 mrg recreated for each function. */
3073 1.1 mrg for (formal = gfc_sym_get_dummy_args (thunk_sym); formal;
3074 1.1 mrg formal = formal->next)
3075 1.1 mrg if (formal->sym != NULL) /* Ignore alternate returns. */
3076 1.1 mrg {
3077 1.1 mrg formal->sym->backend_decl = NULL_TREE;
3078 1.1 mrg if (formal->sym->ts.type == BT_CHARACTER)
3079 1.1 mrg formal->sym->ts.u.cl->backend_decl = NULL_TREE;
3080 1.1 mrg }
3081 1.1 mrg
3082 1.1 mrg if (thunk_sym->attr.function)
3083 1.1 mrg {
3084 1.1 mrg if (thunk_sym->ts.type == BT_CHARACTER)
3085 1.1 mrg thunk_sym->ts.u.cl->backend_decl = NULL_TREE;
3086 1.1 mrg if (thunk_sym->result->ts.type == BT_CHARACTER)
3087 1.1 mrg thunk_sym->result->ts.u.cl->backend_decl = NULL_TREE;
3088 1.1 mrg }
3089 1.1 mrg }
3090 1.1 mrg
3091 1.1 mrg gfc_restore_backend_locus (&old_loc);
3092 1.1 mrg }
3093 1.1 mrg
3094 1.1 mrg
3095 1.1 mrg /* Create a decl for a function, and create any thunks for alternate entry
3096 1.1 mrg points. If global is true, generate the function in the global binding
3097 1.1 mrg level, otherwise in the current binding level (which can be global). */
3098 1.1 mrg
3099 1.1 mrg void
3100 1.1 mrg gfc_create_function_decl (gfc_namespace * ns, bool global)
3101 1.1 mrg {
3102 1.1 mrg /* Create a declaration for the master function. */
3103 1.1 mrg build_function_decl (ns->proc_name, global);
3104 1.1 mrg
3105 1.1 mrg /* Compile the entry thunks. */
3106 1.1 mrg if (ns->entries)
3107 1.1 mrg build_entry_thunks (ns, global);
3108 1.1 mrg
3109 1.1 mrg /* Now create the read argument list. */
3110 1.1 mrg create_function_arglist (ns->proc_name);
3111 1.1 mrg
3112 1.1 mrg if (ns->omp_declare_simd)
3113 1.1 mrg gfc_trans_omp_declare_simd (ns);
3114 1.1 mrg
3115 1.1 mrg /* Handle 'declare variant' directives. The applicable directives might
3116 1.1 mrg be declared in a parent namespace, so this needs to be called even if
3117 1.1 mrg there are no local directives. */
3118 1.1 mrg if (flag_openmp)
3119 1.1 mrg gfc_trans_omp_declare_variant (ns);
3120 1.1 mrg }
3121 1.1 mrg
3122 1.1 mrg /* Return the decl used to hold the function return value. If
3123 1.1 mrg parent_flag is set, the context is the parent_scope. */
3124 1.1 mrg
3125 1.1 mrg tree
3126 1.1 mrg gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
3127 1.1 mrg {
3128 1.1 mrg tree decl;
3129 1.1 mrg tree length;
3130 1.1 mrg tree this_fake_result_decl;
3131 1.1 mrg tree this_function_decl;
3132 1.1 mrg
3133 1.1 mrg char name[GFC_MAX_SYMBOL_LEN + 10];
3134 1.1 mrg
3135 1.1 mrg if (parent_flag)
3136 1.1 mrg {
3137 1.1 mrg this_fake_result_decl = parent_fake_result_decl;
3138 1.1 mrg this_function_decl = DECL_CONTEXT (current_function_decl);
3139 1.1 mrg }
3140 1.1 mrg else
3141 1.1 mrg {
3142 1.1 mrg this_fake_result_decl = current_fake_result_decl;
3143 1.1 mrg this_function_decl = current_function_decl;
3144 1.1 mrg }
3145 1.1 mrg
3146 1.1 mrg if (sym
3147 1.1 mrg && sym->ns->proc_name->backend_decl == this_function_decl
3148 1.1 mrg && sym->ns->proc_name->attr.entry_master
3149 1.1 mrg && sym != sym->ns->proc_name)
3150 1.1 mrg {
3151 1.1 mrg tree t = NULL, var;
3152 1.1 mrg if (this_fake_result_decl != NULL)
3153 1.1 mrg for (t = TREE_CHAIN (this_fake_result_decl); t; t = TREE_CHAIN (t))
3154 1.1 mrg if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t)), sym->name) == 0)
3155 1.1 mrg break;
3156 1.1 mrg if (t)
3157 1.1 mrg return TREE_VALUE (t);
3158 1.1 mrg decl = gfc_get_fake_result_decl (sym->ns->proc_name, parent_flag);
3159 1.1 mrg
3160 1.1 mrg if (parent_flag)
3161 1.1 mrg this_fake_result_decl = parent_fake_result_decl;
3162 1.1 mrg else
3163 1.1 mrg this_fake_result_decl = current_fake_result_decl;
3164 1.1 mrg
3165 1.1 mrg if (decl && sym->ns->proc_name->attr.mixed_entry_master)
3166 1.1 mrg {
3167 1.1 mrg tree field;
3168 1.1 mrg
3169 1.1 mrg for (field = TYPE_FIELDS (TREE_TYPE (decl));
3170 1.1 mrg field; field = DECL_CHAIN (field))
3171 1.1 mrg if (strcmp (IDENTIFIER_POINTER (DECL_NAME (field)),
3172 1.1 mrg sym->name) == 0)
3173 1.1 mrg break;
3174 1.1 mrg
3175 1.1 mrg gcc_assert (field != NULL_TREE);
3176 1.1 mrg decl = fold_build3_loc (input_location, COMPONENT_REF,
3177 1.1 mrg TREE_TYPE (field), decl, field, NULL_TREE);
3178 1.1 mrg }
3179 1.1 mrg
3180 1.1 mrg var = create_tmp_var_raw (TREE_TYPE (decl), sym->name);
3181 1.1 mrg if (parent_flag)
3182 1.1 mrg gfc_add_decl_to_parent_function (var);
3183 1.1 mrg else
3184 1.1 mrg gfc_add_decl_to_function (var);
3185 1.1 mrg
3186 1.1 mrg SET_DECL_VALUE_EXPR (var, decl);
3187 1.1 mrg DECL_HAS_VALUE_EXPR_P (var) = 1;
3188 1.1 mrg GFC_DECL_RESULT (var) = 1;
3189 1.1 mrg
3190 1.1 mrg TREE_CHAIN (this_fake_result_decl)
3191 1.1 mrg = tree_cons (get_identifier (sym->name), var,
3192 1.1 mrg TREE_CHAIN (this_fake_result_decl));
3193 1.1 mrg return var;
3194 1.1 mrg }
3195 1.1 mrg
3196 1.1 mrg if (this_fake_result_decl != NULL_TREE)
3197 1.1 mrg return TREE_VALUE (this_fake_result_decl);
3198 1.1 mrg
3199 1.1 mrg /* Only when gfc_get_fake_result_decl is called by gfc_trans_return,
3200 1.1 mrg sym is NULL. */
3201 1.1 mrg if (!sym)
3202 1.1 mrg return NULL_TREE;
3203 1.1 mrg
3204 1.1 mrg if (sym->ts.type == BT_CHARACTER)
3205 1.1 mrg {
3206 1.1 mrg if (sym->ts.u.cl->backend_decl == NULL_TREE)
3207 1.1 mrg length = gfc_create_string_length (sym);
3208 1.1 mrg else
3209 1.1 mrg length = sym->ts.u.cl->backend_decl;
3210 1.1 mrg if (VAR_P (length) && DECL_CONTEXT (length) == NULL_TREE)
3211 1.1 mrg gfc_add_decl_to_function (length);
3212 1.1 mrg }
3213 1.1 mrg
3214 1.1 mrg if (gfc_return_by_reference (sym))
3215 1.1 mrg {
3216 1.1 mrg decl = DECL_ARGUMENTS (this_function_decl);
3217 1.1 mrg
3218 1.1 mrg if (sym->ns->proc_name->backend_decl == this_function_decl
3219 1.1 mrg && sym->ns->proc_name->attr.entry_master)
3220 1.1 mrg decl = DECL_CHAIN (decl);
3221 1.1 mrg
3222 1.1 mrg TREE_USED (decl) = 1;
3223 1.1 mrg if (sym->as)
3224 1.1 mrg decl = gfc_build_dummy_array_decl (sym, decl);
3225 1.1 mrg }
3226 1.1 mrg else
3227 1.1 mrg {
3228 1.1 mrg sprintf (name, "__result_%.20s",
3229 1.1 mrg IDENTIFIER_POINTER (DECL_NAME (this_function_decl)));
3230 1.1 mrg
3231 1.1 mrg if (!sym->attr.mixed_entry_master && sym->attr.function)
3232 1.1 mrg decl = build_decl (DECL_SOURCE_LOCATION (this_function_decl),
3233 1.1 mrg VAR_DECL, get_identifier (name),
3234 1.1 mrg gfc_sym_type (sym));
3235 1.1 mrg else
3236 1.1 mrg decl = build_decl (DECL_SOURCE_LOCATION (this_function_decl),
3237 1.1 mrg VAR_DECL, get_identifier (name),
3238 1.1 mrg TREE_TYPE (TREE_TYPE (this_function_decl)));
3239 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
3240 1.1 mrg DECL_EXTERNAL (decl) = 0;
3241 1.1 mrg TREE_PUBLIC (decl) = 0;
3242 1.1 mrg TREE_USED (decl) = 1;
3243 1.1 mrg GFC_DECL_RESULT (decl) = 1;
3244 1.1 mrg TREE_ADDRESSABLE (decl) = 1;
3245 1.1 mrg
3246 1.1 mrg layout_decl (decl, 0);
3247 1.1 mrg gfc_finish_decl_attrs (decl, &sym->attr);
3248 1.1 mrg
3249 1.1 mrg if (parent_flag)
3250 1.1 mrg gfc_add_decl_to_parent_function (decl);
3251 1.1 mrg else
3252 1.1 mrg gfc_add_decl_to_function (decl);
3253 1.1 mrg }
3254 1.1 mrg
3255 1.1 mrg if (parent_flag)
3256 1.1 mrg parent_fake_result_decl = build_tree_list (NULL, decl);
3257 1.1 mrg else
3258 1.1 mrg current_fake_result_decl = build_tree_list (NULL, decl);
3259 1.1 mrg
3260 1.1 mrg if (sym->attr.assign)
3261 1.1 mrg DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl);
3262 1.1 mrg
3263 1.1 mrg return decl;
3264 1.1 mrg }
3265 1.1 mrg
3266 1.1 mrg
3267 1.1 mrg /* Builds a function decl. The remaining parameters are the types of the
3268 1.1 mrg function arguments. Negative nargs indicates a varargs function. */
3269 1.1 mrg
3270 1.1 mrg static tree
3271 1.1 mrg build_library_function_decl_1 (tree name, const char *spec,
3272 1.1 mrg tree rettype, int nargs, va_list p)
3273 1.1 mrg {
3274 1.1 mrg vec<tree, va_gc> *arglist;
3275 1.1 mrg tree fntype;
3276 1.1 mrg tree fndecl;
3277 1.1 mrg int n;
3278 1.1 mrg
3279 1.1 mrg /* Library functions must be declared with global scope. */
3280 1.1 mrg gcc_assert (current_function_decl == NULL_TREE);
3281 1.1 mrg
3282 1.1 mrg /* Create a list of the argument types. */
3283 1.1 mrg vec_alloc (arglist, abs (nargs));
3284 1.1 mrg for (n = abs (nargs); n > 0; n--)
3285 1.1 mrg {
3286 1.1 mrg tree argtype = va_arg (p, tree);
3287 1.1 mrg arglist->quick_push (argtype);
3288 1.1 mrg }
3289 1.1 mrg
3290 1.1 mrg /* Build the function type and decl. */
3291 1.1 mrg if (nargs >= 0)
3292 1.1 mrg fntype = build_function_type_vec (rettype, arglist);
3293 1.1 mrg else
3294 1.1 mrg fntype = build_varargs_function_type_vec (rettype, arglist);
3295 1.1 mrg if (spec)
3296 1.1 mrg {
3297 1.1 mrg tree attr_args = build_tree_list (NULL_TREE,
3298 1.1 mrg build_string (strlen (spec), spec));
3299 1.1 mrg tree attrs = tree_cons (get_identifier ("fn spec"),
3300 1.1 mrg attr_args, TYPE_ATTRIBUTES (fntype));
3301 1.1 mrg fntype = build_type_attribute_variant (fntype, attrs);
3302 1.1 mrg }
3303 1.1 mrg fndecl = build_decl (input_location,
3304 1.1 mrg FUNCTION_DECL, name, fntype);
3305 1.1 mrg
3306 1.1 mrg /* Mark this decl as external. */
3307 1.1 mrg DECL_EXTERNAL (fndecl) = 1;
3308 1.1 mrg TREE_PUBLIC (fndecl) = 1;
3309 1.1 mrg
3310 1.1 mrg pushdecl (fndecl);
3311 1.1 mrg
3312 1.1 mrg rest_of_decl_compilation (fndecl, 1, 0);
3313 1.1 mrg
3314 1.1 mrg return fndecl;
3315 1.1 mrg }
3316 1.1 mrg
3317 1.1 mrg /* Builds a function decl. The remaining parameters are the types of the
3318 1.1 mrg function arguments. Negative nargs indicates a varargs function. */
3319 1.1 mrg
3320 1.1 mrg tree
3321 1.1 mrg gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
3322 1.1 mrg {
3323 1.1 mrg tree ret;
3324 1.1 mrg va_list args;
3325 1.1 mrg va_start (args, nargs);
3326 1.1 mrg ret = build_library_function_decl_1 (name, NULL, rettype, nargs, args);
3327 1.1 mrg va_end (args);
3328 1.1 mrg return ret;
3329 1.1 mrg }
3330 1.1 mrg
3331 1.1 mrg /* Builds a function decl. The remaining parameters are the types of the
3332 1.1 mrg function arguments. Negative nargs indicates a varargs function.
3333 1.1 mrg The SPEC parameter specifies the function argument and return type
3334 1.1 mrg specification according to the fnspec function type attribute. */
3335 1.1 mrg
3336 1.1 mrg tree
3337 1.1 mrg gfc_build_library_function_decl_with_spec (tree name, const char *spec,
3338 1.1 mrg tree rettype, int nargs, ...)
3339 1.1 mrg {
3340 1.1 mrg tree ret;
3341 1.1 mrg va_list args;
3342 1.1 mrg va_start (args, nargs);
3343 1.1 mrg if (flag_checking)
3344 1.1 mrg {
3345 1.1 mrg attr_fnspec fnspec (spec, strlen (spec));
3346 1.1 mrg fnspec.verify ();
3347 1.1 mrg }
3348 1.1 mrg ret = build_library_function_decl_1 (name, spec, rettype, nargs, args);
3349 1.1 mrg va_end (args);
3350 1.1 mrg return ret;
3351 1.1 mrg }
3352 1.1 mrg
3353 1.1 mrg static void
3354 1.1 mrg gfc_build_intrinsic_function_decls (void)
3355 1.1 mrg {
3356 1.1 mrg tree gfc_int4_type_node = gfc_get_int_type (4);
3357 1.1 mrg tree gfc_pint4_type_node = build_pointer_type (gfc_int4_type_node);
3358 1.1 mrg tree gfc_int8_type_node = gfc_get_int_type (8);
3359 1.1 mrg tree gfc_pint8_type_node = build_pointer_type (gfc_int8_type_node);
3360 1.1 mrg tree gfc_int16_type_node = gfc_get_int_type (16);
3361 1.1 mrg tree gfc_logical4_type_node = gfc_get_logical_type (4);
3362 1.1 mrg tree pchar1_type_node = gfc_get_pchar_type (1);
3363 1.1 mrg tree pchar4_type_node = gfc_get_pchar_type (4);
3364 1.1 mrg
3365 1.1 mrg /* String functions. */
3366 1.1 mrg gfor_fndecl_compare_string = gfc_build_library_function_decl_with_spec (
3367 1.1 mrg get_identifier (PREFIX("compare_string")), ". . R . R ",
3368 1.1 mrg integer_type_node, 4, gfc_charlen_type_node, pchar1_type_node,
3369 1.1 mrg gfc_charlen_type_node, pchar1_type_node);
3370 1.1 mrg DECL_PURE_P (gfor_fndecl_compare_string) = 1;
3371 1.1 mrg TREE_NOTHROW (gfor_fndecl_compare_string) = 1;
3372 1.1 mrg
3373 1.1 mrg gfor_fndecl_concat_string = gfc_build_library_function_decl_with_spec (
3374 1.1 mrg get_identifier (PREFIX("concat_string")), ". . W . R . R ",
3375 1.1 mrg void_type_node, 6, gfc_charlen_type_node, pchar1_type_node,
3376 1.1 mrg gfc_charlen_type_node, pchar1_type_node,
3377 1.1 mrg gfc_charlen_type_node, pchar1_type_node);
3378 1.1 mrg TREE_NOTHROW (gfor_fndecl_concat_string) = 1;
3379 1.1 mrg
3380 1.1 mrg gfor_fndecl_string_len_trim = gfc_build_library_function_decl_with_spec (
3381 1.1 mrg get_identifier (PREFIX("string_len_trim")), ". . R ",
3382 1.1 mrg gfc_charlen_type_node, 2, gfc_charlen_type_node, pchar1_type_node);
3383 1.1 mrg DECL_PURE_P (gfor_fndecl_string_len_trim) = 1;
3384 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_len_trim) = 1;
3385 1.1 mrg
3386 1.1 mrg gfor_fndecl_string_index = gfc_build_library_function_decl_with_spec (
3387 1.1 mrg get_identifier (PREFIX("string_index")), ". . R . R . ",
3388 1.1 mrg gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar1_type_node,
3389 1.1 mrg gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
3390 1.1 mrg DECL_PURE_P (gfor_fndecl_string_index) = 1;
3391 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_index) = 1;
3392 1.1 mrg
3393 1.1 mrg gfor_fndecl_string_scan = gfc_build_library_function_decl_with_spec (
3394 1.1 mrg get_identifier (PREFIX("string_scan")), ". . R . R . ",
3395 1.1 mrg gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar1_type_node,
3396 1.1 mrg gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
3397 1.1 mrg DECL_PURE_P (gfor_fndecl_string_scan) = 1;
3398 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_scan) = 1;
3399 1.1 mrg
3400 1.1 mrg gfor_fndecl_string_verify = gfc_build_library_function_decl_with_spec (
3401 1.1 mrg get_identifier (PREFIX("string_verify")), ". . R . R . ",
3402 1.1 mrg gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar1_type_node,
3403 1.1 mrg gfc_charlen_type_node, pchar1_type_node, gfc_logical4_type_node);
3404 1.1 mrg DECL_PURE_P (gfor_fndecl_string_verify) = 1;
3405 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_verify) = 1;
3406 1.1 mrg
3407 1.1 mrg gfor_fndecl_string_trim = gfc_build_library_function_decl_with_spec (
3408 1.1 mrg get_identifier (PREFIX("string_trim")), ". W w . R ",
3409 1.1 mrg void_type_node, 4, build_pointer_type (gfc_charlen_type_node),
3410 1.1 mrg build_pointer_type (pchar1_type_node), gfc_charlen_type_node,
3411 1.1 mrg pchar1_type_node);
3412 1.1 mrg
3413 1.1 mrg gfor_fndecl_string_minmax = gfc_build_library_function_decl_with_spec (
3414 1.1 mrg get_identifier (PREFIX("string_minmax")), ". W w . R ",
3415 1.1 mrg void_type_node, -4, build_pointer_type (gfc_charlen_type_node),
3416 1.1 mrg build_pointer_type (pchar1_type_node), integer_type_node,
3417 1.1 mrg integer_type_node);
3418 1.1 mrg
3419 1.1 mrg gfor_fndecl_adjustl = gfc_build_library_function_decl_with_spec (
3420 1.1 mrg get_identifier (PREFIX("adjustl")), ". W . R ",
3421 1.1 mrg void_type_node, 3, pchar1_type_node, gfc_charlen_type_node,
3422 1.1 mrg pchar1_type_node);
3423 1.1 mrg TREE_NOTHROW (gfor_fndecl_adjustl) = 1;
3424 1.1 mrg
3425 1.1 mrg gfor_fndecl_adjustr = gfc_build_library_function_decl_with_spec (
3426 1.1 mrg get_identifier (PREFIX("adjustr")), ". W . R ",
3427 1.1 mrg void_type_node, 3, pchar1_type_node, gfc_charlen_type_node,
3428 1.1 mrg pchar1_type_node);
3429 1.1 mrg TREE_NOTHROW (gfor_fndecl_adjustr) = 1;
3430 1.1 mrg
3431 1.1 mrg gfor_fndecl_select_string = gfc_build_library_function_decl_with_spec (
3432 1.1 mrg get_identifier (PREFIX("select_string")), ". R . R . ",
3433 1.1 mrg integer_type_node, 4, pvoid_type_node, integer_type_node,
3434 1.1 mrg pchar1_type_node, gfc_charlen_type_node);
3435 1.1 mrg DECL_PURE_P (gfor_fndecl_select_string) = 1;
3436 1.1 mrg TREE_NOTHROW (gfor_fndecl_select_string) = 1;
3437 1.1 mrg
3438 1.1 mrg gfor_fndecl_compare_string_char4 = gfc_build_library_function_decl_with_spec (
3439 1.1 mrg get_identifier (PREFIX("compare_string_char4")), ". . R . R ",
3440 1.1 mrg integer_type_node, 4, gfc_charlen_type_node, pchar4_type_node,
3441 1.1 mrg gfc_charlen_type_node, pchar4_type_node);
3442 1.1 mrg DECL_PURE_P (gfor_fndecl_compare_string_char4) = 1;
3443 1.1 mrg TREE_NOTHROW (gfor_fndecl_compare_string_char4) = 1;
3444 1.1 mrg
3445 1.1 mrg gfor_fndecl_concat_string_char4 = gfc_build_library_function_decl_with_spec (
3446 1.1 mrg get_identifier (PREFIX("concat_string_char4")), ". . W . R . R ",
3447 1.1 mrg void_type_node, 6, gfc_charlen_type_node, pchar4_type_node,
3448 1.1 mrg gfc_charlen_type_node, pchar4_type_node, gfc_charlen_type_node,
3449 1.1 mrg pchar4_type_node);
3450 1.1 mrg TREE_NOTHROW (gfor_fndecl_concat_string_char4) = 1;
3451 1.1 mrg
3452 1.1 mrg gfor_fndecl_string_len_trim_char4 = gfc_build_library_function_decl_with_spec (
3453 1.1 mrg get_identifier (PREFIX("string_len_trim_char4")), ". . R ",
3454 1.1 mrg gfc_charlen_type_node, 2, gfc_charlen_type_node, pchar4_type_node);
3455 1.1 mrg DECL_PURE_P (gfor_fndecl_string_len_trim_char4) = 1;
3456 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_len_trim_char4) = 1;
3457 1.1 mrg
3458 1.1 mrg gfor_fndecl_string_index_char4 = gfc_build_library_function_decl_with_spec (
3459 1.1 mrg get_identifier (PREFIX("string_index_char4")), ". . R . R . ",
3460 1.1 mrg gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar4_type_node,
3461 1.1 mrg gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
3462 1.1 mrg DECL_PURE_P (gfor_fndecl_string_index_char4) = 1;
3463 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_index_char4) = 1;
3464 1.1 mrg
3465 1.1 mrg gfor_fndecl_string_scan_char4 = gfc_build_library_function_decl_with_spec (
3466 1.1 mrg get_identifier (PREFIX("string_scan_char4")), ". . R . R . ",
3467 1.1 mrg gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar4_type_node,
3468 1.1 mrg gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
3469 1.1 mrg DECL_PURE_P (gfor_fndecl_string_scan_char4) = 1;
3470 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_scan_char4) = 1;
3471 1.1 mrg
3472 1.1 mrg gfor_fndecl_string_verify_char4 = gfc_build_library_function_decl_with_spec (
3473 1.1 mrg get_identifier (PREFIX("string_verify_char4")), ". . R . R . ",
3474 1.1 mrg gfc_charlen_type_node, 5, gfc_charlen_type_node, pchar4_type_node,
3475 1.1 mrg gfc_charlen_type_node, pchar4_type_node, gfc_logical4_type_node);
3476 1.1 mrg DECL_PURE_P (gfor_fndecl_string_verify_char4) = 1;
3477 1.1 mrg TREE_NOTHROW (gfor_fndecl_string_verify_char4) = 1;
3478 1.1 mrg
3479 1.1 mrg gfor_fndecl_string_trim_char4 = gfc_build_library_function_decl_with_spec (
3480 1.1 mrg get_identifier (PREFIX("string_trim_char4")), ". W w . R ",
3481 1.1 mrg void_type_node, 4, build_pointer_type (gfc_charlen_type_node),
3482 1.1 mrg build_pointer_type (pchar4_type_node), gfc_charlen_type_node,
3483 1.1 mrg pchar4_type_node);
3484 1.1 mrg
3485 1.1 mrg gfor_fndecl_string_minmax_char4 = gfc_build_library_function_decl_with_spec (
3486 1.1 mrg get_identifier (PREFIX("string_minmax_char4")), ". W w . R ",
3487 1.1 mrg void_type_node, -4, build_pointer_type (gfc_charlen_type_node),
3488 1.1 mrg build_pointer_type (pchar4_type_node), integer_type_node,
3489 1.1 mrg integer_type_node);
3490 1.1 mrg
3491 1.1 mrg gfor_fndecl_adjustl_char4 = gfc_build_library_function_decl_with_spec (
3492 1.1 mrg get_identifier (PREFIX("adjustl_char4")), ". W . R ",
3493 1.1 mrg void_type_node, 3, pchar4_type_node, gfc_charlen_type_node,
3494 1.1 mrg pchar4_type_node);
3495 1.1 mrg TREE_NOTHROW (gfor_fndecl_adjustl_char4) = 1;
3496 1.1 mrg
3497 1.1 mrg gfor_fndecl_adjustr_char4 = gfc_build_library_function_decl_with_spec (
3498 1.1 mrg get_identifier (PREFIX("adjustr_char4")), ". W . R ",
3499 1.1 mrg void_type_node, 3, pchar4_type_node, gfc_charlen_type_node,
3500 1.1 mrg pchar4_type_node);
3501 1.1 mrg TREE_NOTHROW (gfor_fndecl_adjustr_char4) = 1;
3502 1.1 mrg
3503 1.1 mrg gfor_fndecl_select_string_char4 = gfc_build_library_function_decl_with_spec (
3504 1.1 mrg get_identifier (PREFIX("select_string_char4")), ". R . R . ",
3505 1.1 mrg integer_type_node, 4, pvoid_type_node, integer_type_node,
3506 1.1 mrg pvoid_type_node, gfc_charlen_type_node);
3507 1.1 mrg DECL_PURE_P (gfor_fndecl_select_string_char4) = 1;
3508 1.1 mrg TREE_NOTHROW (gfor_fndecl_select_string_char4) = 1;
3509 1.1 mrg
3510 1.1 mrg
3511 1.1 mrg /* Conversion between character kinds. */
3512 1.1 mrg
3513 1.1 mrg gfor_fndecl_convert_char1_to_char4 = gfc_build_library_function_decl_with_spec (
3514 1.1 mrg get_identifier (PREFIX("convert_char1_to_char4")), ". w . R ",
3515 1.1 mrg void_type_node, 3, build_pointer_type (pchar4_type_node),
3516 1.1 mrg gfc_charlen_type_node, pchar1_type_node);
3517 1.1 mrg
3518 1.1 mrg gfor_fndecl_convert_char4_to_char1 = gfc_build_library_function_decl_with_spec (
3519 1.1 mrg get_identifier (PREFIX("convert_char4_to_char1")), ". w . R ",
3520 1.1 mrg void_type_node, 3, build_pointer_type (pchar1_type_node),
3521 1.1 mrg gfc_charlen_type_node, pchar4_type_node);
3522 1.1 mrg
3523 1.1 mrg /* Misc. functions. */
3524 1.1 mrg
3525 1.1 mrg gfor_fndecl_ttynam = gfc_build_library_function_decl_with_spec (
3526 1.1 mrg get_identifier (PREFIX("ttynam")), ". W . . ",
3527 1.1 mrg void_type_node, 3, pchar_type_node, gfc_charlen_type_node,
3528 1.1 mrg integer_type_node);
3529 1.1 mrg
3530 1.1 mrg gfor_fndecl_fdate = gfc_build_library_function_decl_with_spec (
3531 1.1 mrg get_identifier (PREFIX("fdate")), ". W . ",
3532 1.1 mrg void_type_node, 2, pchar_type_node, gfc_charlen_type_node);
3533 1.1 mrg
3534 1.1 mrg gfor_fndecl_ctime = gfc_build_library_function_decl_with_spec (
3535 1.1 mrg get_identifier (PREFIX("ctime")), ". W . . ",
3536 1.1 mrg void_type_node, 3, pchar_type_node, gfc_charlen_type_node,
3537 1.1 mrg gfc_int8_type_node);
3538 1.1 mrg
3539 1.1 mrg gfor_fndecl_random_init = gfc_build_library_function_decl (
3540 1.1 mrg get_identifier (PREFIX("random_init")),
3541 1.1 mrg void_type_node, 3, gfc_logical4_type_node, gfc_logical4_type_node,
3542 1.1 mrg gfc_int4_type_node);
3543 1.1 mrg
3544 1.1 mrg // gfor_fndecl_caf_rand_init is defined in the lib-coarray section below.
3545 1.1 mrg
3546 1.1 mrg gfor_fndecl_sc_kind = gfc_build_library_function_decl_with_spec (
3547 1.1 mrg get_identifier (PREFIX("selected_char_kind")), ". . R ",
3548 1.1 mrg gfc_int4_type_node, 2, gfc_charlen_type_node, pchar_type_node);
3549 1.1 mrg DECL_PURE_P (gfor_fndecl_sc_kind) = 1;
3550 1.1 mrg TREE_NOTHROW (gfor_fndecl_sc_kind) = 1;
3551 1.1 mrg
3552 1.1 mrg gfor_fndecl_si_kind = gfc_build_library_function_decl_with_spec (
3553 1.1 mrg get_identifier (PREFIX("selected_int_kind")), ". R ",
3554 1.1 mrg gfc_int4_type_node, 1, pvoid_type_node);
3555 1.1 mrg DECL_PURE_P (gfor_fndecl_si_kind) = 1;
3556 1.1 mrg TREE_NOTHROW (gfor_fndecl_si_kind) = 1;
3557 1.1 mrg
3558 1.1 mrg gfor_fndecl_sr_kind = gfc_build_library_function_decl_with_spec (
3559 1.1 mrg get_identifier (PREFIX("selected_real_kind2008")), ". R R ",
3560 1.1 mrg gfc_int4_type_node, 3, pvoid_type_node, pvoid_type_node,
3561 1.1 mrg pvoid_type_node);
3562 1.1 mrg DECL_PURE_P (gfor_fndecl_sr_kind) = 1;
3563 1.1 mrg TREE_NOTHROW (gfor_fndecl_sr_kind) = 1;
3564 1.1 mrg
3565 1.1 mrg gfor_fndecl_system_clock4 = gfc_build_library_function_decl (
3566 1.1 mrg get_identifier (PREFIX("system_clock_4")),
3567 1.1 mrg void_type_node, 3, gfc_pint4_type_node, gfc_pint4_type_node,
3568 1.1 mrg gfc_pint4_type_node);
3569 1.1 mrg
3570 1.1 mrg gfor_fndecl_system_clock8 = gfc_build_library_function_decl (
3571 1.1 mrg get_identifier (PREFIX("system_clock_8")),
3572 1.1 mrg void_type_node, 3, gfc_pint8_type_node, gfc_pint8_type_node,
3573 1.1 mrg gfc_pint8_type_node);
3574 1.1 mrg
3575 1.1 mrg /* Power functions. */
3576 1.1 mrg {
3577 1.1 mrg tree ctype, rtype, itype, jtype;
3578 1.1 mrg int rkind, ikind, jkind;
3579 1.1 mrg #define NIKINDS 3
3580 1.1 mrg #define NRKINDS 4
3581 1.1 mrg static int ikinds[NIKINDS] = {4, 8, 16};
3582 1.1 mrg static int rkinds[NRKINDS] = {4, 8, 10, 16};
3583 1.1 mrg char name[PREFIX_LEN + 12]; /* _gfortran_pow_?n_?n */
3584 1.1 mrg
3585 1.1 mrg for (ikind=0; ikind < NIKINDS; ikind++)
3586 1.1 mrg {
3587 1.1 mrg itype = gfc_get_int_type (ikinds[ikind]);
3588 1.1 mrg
3589 1.1 mrg for (jkind=0; jkind < NIKINDS; jkind++)
3590 1.1 mrg {
3591 1.1 mrg jtype = gfc_get_int_type (ikinds[jkind]);
3592 1.1 mrg if (itype && jtype)
3593 1.1 mrg {
3594 1.1 mrg sprintf (name, PREFIX("pow_i%d_i%d"), ikinds[ikind],
3595 1.1 mrg ikinds[jkind]);
3596 1.1 mrg gfor_fndecl_math_powi[jkind][ikind].integer =
3597 1.1 mrg gfc_build_library_function_decl (get_identifier (name),
3598 1.1 mrg jtype, 2, jtype, itype);
3599 1.1 mrg TREE_READONLY (gfor_fndecl_math_powi[jkind][ikind].integer) = 1;
3600 1.1 mrg TREE_NOTHROW (gfor_fndecl_math_powi[jkind][ikind].integer) = 1;
3601 1.1 mrg }
3602 1.1 mrg }
3603 1.1 mrg
3604 1.1 mrg for (rkind = 0; rkind < NRKINDS; rkind ++)
3605 1.1 mrg {
3606 1.1 mrg rtype = gfc_get_real_type (rkinds[rkind]);
3607 1.1 mrg if (rtype && itype)
3608 1.1 mrg {
3609 1.1 mrg sprintf (name, PREFIX("pow_r%d_i%d"),
3610 1.1 mrg gfc_type_abi_kind (BT_REAL, rkinds[rkind]),
3611 1.1 mrg ikinds[ikind]);
3612 1.1 mrg gfor_fndecl_math_powi[rkind][ikind].real =
3613 1.1 mrg gfc_build_library_function_decl (get_identifier (name),
3614 1.1 mrg rtype, 2, rtype, itype);
3615 1.1 mrg TREE_READONLY (gfor_fndecl_math_powi[rkind][ikind].real) = 1;
3616 1.1 mrg TREE_NOTHROW (gfor_fndecl_math_powi[rkind][ikind].real) = 1;
3617 1.1 mrg }
3618 1.1 mrg
3619 1.1 mrg ctype = gfc_get_complex_type (rkinds[rkind]);
3620 1.1 mrg if (ctype && itype)
3621 1.1 mrg {
3622 1.1 mrg sprintf (name, PREFIX("pow_c%d_i%d"),
3623 1.1 mrg gfc_type_abi_kind (BT_REAL, rkinds[rkind]),
3624 1.1 mrg ikinds[ikind]);
3625 1.1 mrg gfor_fndecl_math_powi[rkind][ikind].cmplx =
3626 1.1 mrg gfc_build_library_function_decl (get_identifier (name),
3627 1.1 mrg ctype, 2,ctype, itype);
3628 1.1 mrg TREE_READONLY (gfor_fndecl_math_powi[rkind][ikind].cmplx) = 1;
3629 1.1 mrg TREE_NOTHROW (gfor_fndecl_math_powi[rkind][ikind].cmplx) = 1;
3630 1.1 mrg }
3631 1.1 mrg }
3632 1.1 mrg }
3633 1.1 mrg #undef NIKINDS
3634 1.1 mrg #undef NRKINDS
3635 1.1 mrg }
3636 1.1 mrg
3637 1.1 mrg gfor_fndecl_math_ishftc4 = gfc_build_library_function_decl (
3638 1.1 mrg get_identifier (PREFIX("ishftc4")),
3639 1.1 mrg gfc_int4_type_node, 3, gfc_int4_type_node, gfc_int4_type_node,
3640 1.1 mrg gfc_int4_type_node);
3641 1.1 mrg TREE_READONLY (gfor_fndecl_math_ishftc4) = 1;
3642 1.1 mrg TREE_NOTHROW (gfor_fndecl_math_ishftc4) = 1;
3643 1.1 mrg
3644 1.1 mrg gfor_fndecl_math_ishftc8 = gfc_build_library_function_decl (
3645 1.1 mrg get_identifier (PREFIX("ishftc8")),
3646 1.1 mrg gfc_int8_type_node, 3, gfc_int8_type_node, gfc_int4_type_node,
3647 1.1 mrg gfc_int4_type_node);
3648 1.1 mrg TREE_READONLY (gfor_fndecl_math_ishftc8) = 1;
3649 1.1 mrg TREE_NOTHROW (gfor_fndecl_math_ishftc8) = 1;
3650 1.1 mrg
3651 1.1 mrg if (gfc_int16_type_node)
3652 1.1 mrg {
3653 1.1 mrg gfor_fndecl_math_ishftc16 = gfc_build_library_function_decl (
3654 1.1 mrg get_identifier (PREFIX("ishftc16")),
3655 1.1 mrg gfc_int16_type_node, 3, gfc_int16_type_node, gfc_int4_type_node,
3656 1.1 mrg gfc_int4_type_node);
3657 1.1 mrg TREE_READONLY (gfor_fndecl_math_ishftc16) = 1;
3658 1.1 mrg TREE_NOTHROW (gfor_fndecl_math_ishftc16) = 1;
3659 1.1 mrg }
3660 1.1 mrg
3661 1.1 mrg /* BLAS functions. */
3662 1.1 mrg {
3663 1.1 mrg tree pint = build_pointer_type (integer_type_node);
3664 1.1 mrg tree ps = build_pointer_type (gfc_get_real_type (gfc_default_real_kind));
3665 1.1 mrg tree pd = build_pointer_type (gfc_get_real_type (gfc_default_double_kind));
3666 1.1 mrg tree pc = build_pointer_type (gfc_get_complex_type (gfc_default_real_kind));
3667 1.1 mrg tree pz = build_pointer_type
3668 1.1 mrg (gfc_get_complex_type (gfc_default_double_kind));
3669 1.1 mrg
3670 1.1 mrg gfor_fndecl_sgemm = gfc_build_library_function_decl
3671 1.1 mrg (get_identifier
3672 1.1 mrg (flag_underscoring ? "sgemm_" : "sgemm"),
3673 1.1 mrg void_type_node, 15, pchar_type_node,
3674 1.1 mrg pchar_type_node, pint, pint, pint, ps, ps, pint,
3675 1.1 mrg ps, pint, ps, ps, pint, integer_type_node,
3676 1.1 mrg integer_type_node);
3677 1.1 mrg gfor_fndecl_dgemm = gfc_build_library_function_decl
3678 1.1 mrg (get_identifier
3679 1.1 mrg (flag_underscoring ? "dgemm_" : "dgemm"),
3680 1.1 mrg void_type_node, 15, pchar_type_node,
3681 1.1 mrg pchar_type_node, pint, pint, pint, pd, pd, pint,
3682 1.1 mrg pd, pint, pd, pd, pint, integer_type_node,
3683 1.1 mrg integer_type_node);
3684 1.1 mrg gfor_fndecl_cgemm = gfc_build_library_function_decl
3685 1.1 mrg (get_identifier
3686 1.1 mrg (flag_underscoring ? "cgemm_" : "cgemm"),
3687 1.1 mrg void_type_node, 15, pchar_type_node,
3688 1.1 mrg pchar_type_node, pint, pint, pint, pc, pc, pint,
3689 1.1 mrg pc, pint, pc, pc, pint, integer_type_node,
3690 1.1 mrg integer_type_node);
3691 1.1 mrg gfor_fndecl_zgemm = gfc_build_library_function_decl
3692 1.1 mrg (get_identifier
3693 1.1 mrg (flag_underscoring ? "zgemm_" : "zgemm"),
3694 1.1 mrg void_type_node, 15, pchar_type_node,
3695 1.1 mrg pchar_type_node, pint, pint, pint, pz, pz, pint,
3696 1.1 mrg pz, pint, pz, pz, pint, integer_type_node,
3697 1.1 mrg integer_type_node);
3698 1.1 mrg }
3699 1.1 mrg
3700 1.1 mrg /* Other functions. */
3701 1.1 mrg gfor_fndecl_iargc = gfc_build_library_function_decl (
3702 1.1 mrg get_identifier (PREFIX ("iargc")), gfc_int4_type_node, 0);
3703 1.1 mrg TREE_NOTHROW (gfor_fndecl_iargc) = 1;
3704 1.1 mrg
3705 1.1 mrg gfor_fndecl_kill_sub = gfc_build_library_function_decl (
3706 1.1 mrg get_identifier (PREFIX ("kill_sub")), void_type_node,
3707 1.1 mrg 3, gfc_int4_type_node, gfc_int4_type_node, gfc_pint4_type_node);
3708 1.1 mrg
3709 1.1 mrg gfor_fndecl_kill = gfc_build_library_function_decl (
3710 1.1 mrg get_identifier (PREFIX ("kill")), gfc_int4_type_node,
3711 1.1 mrg 2, gfc_int4_type_node, gfc_int4_type_node);
3712 1.1 mrg
3713 1.1 mrg gfor_fndecl_is_contiguous0 = gfc_build_library_function_decl_with_spec (
3714 1.1 mrg get_identifier (PREFIX("is_contiguous0")), ". R ",
3715 1.1 mrg gfc_int4_type_node, 1, pvoid_type_node);
3716 1.1 mrg DECL_PURE_P (gfor_fndecl_is_contiguous0) = 1;
3717 1.1 mrg TREE_NOTHROW (gfor_fndecl_is_contiguous0) = 1;
3718 1.1 mrg }
3719 1.1 mrg
3720 1.1 mrg
3721 1.1 mrg /* Make prototypes for runtime library functions. */
3722 1.1 mrg
3723 1.1 mrg void
3724 1.1 mrg gfc_build_builtin_function_decls (void)
3725 1.1 mrg {
3726 1.1 mrg tree gfc_int8_type_node = gfc_get_int_type (8);
3727 1.1 mrg
3728 1.1 mrg gfor_fndecl_stop_numeric = gfc_build_library_function_decl (
3729 1.1 mrg get_identifier (PREFIX("stop_numeric")),
3730 1.1 mrg void_type_node, 2, integer_type_node, boolean_type_node);
3731 1.1 mrg /* STOP doesn't return. */
3732 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_stop_numeric) = 1;
3733 1.1 mrg
3734 1.1 mrg gfor_fndecl_stop_string = gfc_build_library_function_decl_with_spec (
3735 1.1 mrg get_identifier (PREFIX("stop_string")), ". R . . ",
3736 1.1 mrg void_type_node, 3, pchar_type_node, size_type_node,
3737 1.1 mrg boolean_type_node);
3738 1.1 mrg /* STOP doesn't return. */
3739 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_stop_string) = 1;
3740 1.1 mrg
3741 1.1 mrg gfor_fndecl_error_stop_numeric = gfc_build_library_function_decl (
3742 1.1 mrg get_identifier (PREFIX("error_stop_numeric")),
3743 1.1 mrg void_type_node, 2, integer_type_node, boolean_type_node);
3744 1.1 mrg /* ERROR STOP doesn't return. */
3745 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_error_stop_numeric) = 1;
3746 1.1 mrg
3747 1.1 mrg gfor_fndecl_error_stop_string = gfc_build_library_function_decl_with_spec (
3748 1.1 mrg get_identifier (PREFIX("error_stop_string")), ". R . . ",
3749 1.1 mrg void_type_node, 3, pchar_type_node, size_type_node,
3750 1.1 mrg boolean_type_node);
3751 1.1 mrg /* ERROR STOP doesn't return. */
3752 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1;
3753 1.1 mrg
3754 1.1 mrg gfor_fndecl_pause_numeric = gfc_build_library_function_decl (
3755 1.1 mrg get_identifier (PREFIX("pause_numeric")),
3756 1.1 mrg void_type_node, 1, gfc_int8_type_node);
3757 1.1 mrg
3758 1.1 mrg gfor_fndecl_pause_string = gfc_build_library_function_decl_with_spec (
3759 1.1 mrg get_identifier (PREFIX("pause_string")), ". R . ",
3760 1.1 mrg void_type_node, 2, pchar_type_node, size_type_node);
3761 1.1 mrg
3762 1.1 mrg gfor_fndecl_runtime_error = gfc_build_library_function_decl_with_spec (
3763 1.1 mrg get_identifier (PREFIX("runtime_error")), ". R ",
3764 1.1 mrg void_type_node, -1, pchar_type_node);
3765 1.1 mrg /* The runtime_error function does not return. */
3766 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_runtime_error) = 1;
3767 1.1 mrg
3768 1.1 mrg gfor_fndecl_runtime_error_at = gfc_build_library_function_decl_with_spec (
3769 1.1 mrg get_identifier (PREFIX("runtime_error_at")), ". R R ",
3770 1.1 mrg void_type_node, -2, pchar_type_node, pchar_type_node);
3771 1.1 mrg /* The runtime_error_at function does not return. */
3772 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_runtime_error_at) = 1;
3773 1.1 mrg
3774 1.1 mrg gfor_fndecl_runtime_warning_at = gfc_build_library_function_decl_with_spec (
3775 1.1 mrg get_identifier (PREFIX("runtime_warning_at")), ". R R ",
3776 1.1 mrg void_type_node, -2, pchar_type_node, pchar_type_node);
3777 1.1 mrg
3778 1.1 mrg gfor_fndecl_generate_error = gfc_build_library_function_decl_with_spec (
3779 1.1 mrg get_identifier (PREFIX("generate_error")), ". R . R ",
3780 1.1 mrg void_type_node, 3, pvoid_type_node, integer_type_node,
3781 1.1 mrg pchar_type_node);
3782 1.1 mrg
3783 1.1 mrg gfor_fndecl_os_error_at = gfc_build_library_function_decl_with_spec (
3784 1.1 mrg get_identifier (PREFIX("os_error_at")), ". R R ",
3785 1.1 mrg void_type_node, -2, pchar_type_node, pchar_type_node);
3786 1.1 mrg /* The os_error_at function does not return. */
3787 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_os_error_at) = 1;
3788 1.1 mrg
3789 1.1 mrg gfor_fndecl_set_args = gfc_build_library_function_decl (
3790 1.1 mrg get_identifier (PREFIX("set_args")),
3791 1.1 mrg void_type_node, 2, integer_type_node,
3792 1.1 mrg build_pointer_type (pchar_type_node));
3793 1.1 mrg
3794 1.1 mrg gfor_fndecl_set_fpe = gfc_build_library_function_decl (
3795 1.1 mrg get_identifier (PREFIX("set_fpe")),
3796 1.1 mrg void_type_node, 1, integer_type_node);
3797 1.1 mrg
3798 1.1 mrg gfor_fndecl_ieee_procedure_entry = gfc_build_library_function_decl (
3799 1.1 mrg get_identifier (PREFIX("ieee_procedure_entry")),
3800 1.1 mrg void_type_node, 1, pvoid_type_node);
3801 1.1 mrg
3802 1.1 mrg gfor_fndecl_ieee_procedure_exit = gfc_build_library_function_decl (
3803 1.1 mrg get_identifier (PREFIX("ieee_procedure_exit")),
3804 1.1 mrg void_type_node, 1, pvoid_type_node);
3805 1.1 mrg
3806 1.1 mrg /* Keep the array dimension in sync with the call, later in this file. */
3807 1.1 mrg gfor_fndecl_set_options = gfc_build_library_function_decl_with_spec (
3808 1.1 mrg get_identifier (PREFIX("set_options")), ". . R ",
3809 1.1 mrg void_type_node, 2, integer_type_node,
3810 1.1 mrg build_pointer_type (integer_type_node));
3811 1.1 mrg
3812 1.1 mrg gfor_fndecl_set_convert = gfc_build_library_function_decl (
3813 1.1 mrg get_identifier (PREFIX("set_convert")),
3814 1.1 mrg void_type_node, 1, integer_type_node);
3815 1.1 mrg
3816 1.1 mrg gfor_fndecl_set_record_marker = gfc_build_library_function_decl (
3817 1.1 mrg get_identifier (PREFIX("set_record_marker")),
3818 1.1 mrg void_type_node, 1, integer_type_node);
3819 1.1 mrg
3820 1.1 mrg gfor_fndecl_set_max_subrecord_length = gfc_build_library_function_decl (
3821 1.1 mrg get_identifier (PREFIX("set_max_subrecord_length")),
3822 1.1 mrg void_type_node, 1, integer_type_node);
3823 1.1 mrg
3824 1.1 mrg gfor_fndecl_in_pack = gfc_build_library_function_decl_with_spec (
3825 1.1 mrg get_identifier (PREFIX("internal_pack")), ". r ",
3826 1.1 mrg pvoid_type_node, 1, pvoid_type_node);
3827 1.1 mrg
3828 1.1 mrg gfor_fndecl_in_unpack = gfc_build_library_function_decl_with_spec (
3829 1.1 mrg get_identifier (PREFIX("internal_unpack")), ". w R ",
3830 1.1 mrg void_type_node, 2, pvoid_type_node, pvoid_type_node);
3831 1.1 mrg
3832 1.1 mrg gfor_fndecl_associated = gfc_build_library_function_decl_with_spec (
3833 1.1 mrg get_identifier (PREFIX("associated")), ". R R ",
3834 1.1 mrg integer_type_node, 2, ppvoid_type_node, ppvoid_type_node);
3835 1.1 mrg DECL_PURE_P (gfor_fndecl_associated) = 1;
3836 1.1 mrg TREE_NOTHROW (gfor_fndecl_associated) = 1;
3837 1.1 mrg
3838 1.1 mrg /* Coarray library calls. */
3839 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
3840 1.1 mrg {
3841 1.1 mrg tree pint_type, pppchar_type;
3842 1.1 mrg
3843 1.1 mrg pint_type = build_pointer_type (integer_type_node);
3844 1.1 mrg pppchar_type
3845 1.1 mrg = build_pointer_type (build_pointer_type (pchar_type_node));
3846 1.1 mrg
3847 1.1 mrg gfor_fndecl_caf_init = gfc_build_library_function_decl_with_spec (
3848 1.1 mrg get_identifier (PREFIX("caf_init")), ". W W ",
3849 1.1 mrg void_type_node, 2, pint_type, pppchar_type);
3850 1.1 mrg
3851 1.1 mrg gfor_fndecl_caf_finalize = gfc_build_library_function_decl (
3852 1.1 mrg get_identifier (PREFIX("caf_finalize")), void_type_node, 0);
3853 1.1 mrg
3854 1.1 mrg gfor_fndecl_caf_this_image = gfc_build_library_function_decl (
3855 1.1 mrg get_identifier (PREFIX("caf_this_image")), integer_type_node,
3856 1.1 mrg 1, integer_type_node);
3857 1.1 mrg
3858 1.1 mrg gfor_fndecl_caf_num_images = gfc_build_library_function_decl (
3859 1.1 mrg get_identifier (PREFIX("caf_num_images")), integer_type_node,
3860 1.1 mrg 2, integer_type_node, integer_type_node);
3861 1.1 mrg
3862 1.1 mrg gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec (
3863 1.1 mrg get_identifier (PREFIX("caf_register")), ". . . W w w w . ",
3864 1.1 mrg void_type_node, 7,
3865 1.1 mrg size_type_node, integer_type_node, ppvoid_type_node, pvoid_type_node,
3866 1.1 mrg pint_type, pchar_type_node, size_type_node);
3867 1.1 mrg
3868 1.1 mrg gfor_fndecl_caf_deregister = gfc_build_library_function_decl_with_spec (
3869 1.1 mrg get_identifier (PREFIX("caf_deregister")), ". W . w w . ",
3870 1.1 mrg void_type_node, 5,
3871 1.1 mrg ppvoid_type_node, integer_type_node, pint_type, pchar_type_node,
3872 1.1 mrg size_type_node);
3873 1.1 mrg
3874 1.1 mrg gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec (
3875 1.1 mrg get_identifier (PREFIX("caf_get")), ". r . . r r w . . . w ",
3876 1.1 mrg void_type_node, 10,
3877 1.1 mrg pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
3878 1.1 mrg pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
3879 1.1 mrg boolean_type_node, pint_type);
3880 1.1 mrg
3881 1.1 mrg gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec (
3882 1.1 mrg get_identifier (PREFIX("caf_send")), ". r . . w r r . . . w ",
3883 1.1 mrg void_type_node, 11,
3884 1.1 mrg pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
3885 1.1 mrg pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
3886 1.1 mrg boolean_type_node, pint_type, pvoid_type_node);
3887 1.1 mrg
3888 1.1 mrg gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec (
3889 1.1 mrg get_identifier (PREFIX("caf_sendget")), ". r . . w r r . . r r . . . w ",
3890 1.1 mrg void_type_node, 14, pvoid_type_node, size_type_node, integer_type_node,
3891 1.1 mrg pvoid_type_node, pvoid_type_node, pvoid_type_node, size_type_node,
3892 1.1 mrg integer_type_node, pvoid_type_node, pvoid_type_node, integer_type_node,
3893 1.1 mrg integer_type_node, boolean_type_node, integer_type_node);
3894 1.1 mrg
3895 1.1 mrg gfor_fndecl_caf_get_by_ref = gfc_build_library_function_decl_with_spec (
3896 1.1 mrg get_identifier (PREFIX("caf_get_by_ref")), ". r . w r . . . . w . ",
3897 1.1 mrg void_type_node,
3898 1.1 mrg 10, pvoid_type_node, integer_type_node, pvoid_type_node,
3899 1.1 mrg pvoid_type_node, integer_type_node, integer_type_node,
3900 1.1 mrg boolean_type_node, boolean_type_node, pint_type, integer_type_node);
3901 1.1 mrg
3902 1.1 mrg gfor_fndecl_caf_send_by_ref = gfc_build_library_function_decl_with_spec (
3903 1.1 mrg get_identifier (PREFIX("caf_send_by_ref")), ". r . r r . . . . w . ",
3904 1.1 mrg void_type_node, 10, pvoid_type_node, integer_type_node, pvoid_type_node,
3905 1.1 mrg pvoid_type_node, integer_type_node, integer_type_node,
3906 1.1 mrg boolean_type_node, boolean_type_node, pint_type, integer_type_node);
3907 1.1 mrg
3908 1.1 mrg gfor_fndecl_caf_sendget_by_ref
3909 1.1 mrg = gfc_build_library_function_decl_with_spec (
3910 1.1 mrg get_identifier (PREFIX("caf_sendget_by_ref")),
3911 1.1 mrg ". r . r r . r . . . w w . . ",
3912 1.1 mrg void_type_node, 13, pvoid_type_node, integer_type_node,
3913 1.1 mrg pvoid_type_node, pvoid_type_node, integer_type_node,
3914 1.1 mrg pvoid_type_node, integer_type_node, integer_type_node,
3915 1.1 mrg boolean_type_node, pint_type, pint_type, integer_type_node,
3916 1.1 mrg integer_type_node);
3917 1.1 mrg
3918 1.1 mrg gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
3919 1.1 mrg get_identifier (PREFIX("caf_sync_all")), ". w w . ", void_type_node,
3920 1.1 mrg 3, pint_type, pchar_type_node, size_type_node);
3921 1.1 mrg
3922 1.1 mrg gfor_fndecl_caf_sync_memory = gfc_build_library_function_decl_with_spec (
3923 1.1 mrg get_identifier (PREFIX("caf_sync_memory")), ". w w . ", void_type_node,
3924 1.1 mrg 3, pint_type, pchar_type_node, size_type_node);
3925 1.1 mrg
3926 1.1 mrg gfor_fndecl_caf_sync_images = gfc_build_library_function_decl_with_spec (
3927 1.1 mrg get_identifier (PREFIX("caf_sync_images")), ". . r w w . ", void_type_node,
3928 1.1 mrg 5, integer_type_node, pint_type, pint_type,
3929 1.1 mrg pchar_type_node, size_type_node);
3930 1.1 mrg
3931 1.1 mrg gfor_fndecl_caf_error_stop = gfc_build_library_function_decl (
3932 1.1 mrg get_identifier (PREFIX("caf_error_stop")),
3933 1.1 mrg void_type_node, 1, integer_type_node);
3934 1.1 mrg /* CAF's ERROR STOP doesn't return. */
3935 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop) = 1;
3936 1.1 mrg
3937 1.1 mrg gfor_fndecl_caf_error_stop_str = gfc_build_library_function_decl_with_spec (
3938 1.1 mrg get_identifier (PREFIX("caf_error_stop_str")), ". r . ",
3939 1.1 mrg void_type_node, 2, pchar_type_node, size_type_node);
3940 1.1 mrg /* CAF's ERROR STOP doesn't return. */
3941 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop_str) = 1;
3942 1.1 mrg
3943 1.1 mrg gfor_fndecl_caf_stop_numeric = gfc_build_library_function_decl (
3944 1.1 mrg get_identifier (PREFIX("caf_stop_numeric")),
3945 1.1 mrg void_type_node, 1, integer_type_node);
3946 1.1 mrg /* CAF's STOP doesn't return. */
3947 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_numeric) = 1;
3948 1.1 mrg
3949 1.1 mrg gfor_fndecl_caf_stop_str = gfc_build_library_function_decl_with_spec (
3950 1.1 mrg get_identifier (PREFIX("caf_stop_str")), ". r . ",
3951 1.1 mrg void_type_node, 2, pchar_type_node, size_type_node);
3952 1.1 mrg /* CAF's STOP doesn't return. */
3953 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1;
3954 1.1 mrg
3955 1.1 mrg gfor_fndecl_caf_atomic_def = gfc_build_library_function_decl_with_spec (
3956 1.1 mrg get_identifier (PREFIX("caf_atomic_define")), ". r . . w w . . ",
3957 1.1 mrg void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
3958 1.1 mrg pvoid_type_node, pint_type, integer_type_node, integer_type_node);
3959 1.1 mrg
3960 1.1 mrg gfor_fndecl_caf_atomic_ref = gfc_build_library_function_decl_with_spec (
3961 1.1 mrg get_identifier (PREFIX("caf_atomic_ref")), ". r . . w w . . ",
3962 1.1 mrg void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
3963 1.1 mrg pvoid_type_node, pint_type, integer_type_node, integer_type_node);
3964 1.1 mrg
3965 1.1 mrg gfor_fndecl_caf_atomic_cas = gfc_build_library_function_decl_with_spec (
3966 1.1 mrg get_identifier (PREFIX("caf_atomic_cas")), ". r . . w r r w . . ",
3967 1.1 mrg void_type_node, 9, pvoid_type_node, size_type_node, integer_type_node,
3968 1.1 mrg pvoid_type_node, pvoid_type_node, pvoid_type_node, pint_type,
3969 1.1 mrg integer_type_node, integer_type_node);
3970 1.1 mrg
3971 1.1 mrg gfor_fndecl_caf_atomic_op = gfc_build_library_function_decl_with_spec (
3972 1.1 mrg get_identifier (PREFIX("caf_atomic_op")), ". . r . . r w w . . ",
3973 1.1 mrg void_type_node, 9, integer_type_node, pvoid_type_node, size_type_node,
3974 1.1 mrg integer_type_node, pvoid_type_node, pvoid_type_node, pint_type,
3975 1.1 mrg integer_type_node, integer_type_node);
3976 1.1 mrg
3977 1.1 mrg gfor_fndecl_caf_lock = gfc_build_library_function_decl_with_spec (
3978 1.1 mrg get_identifier (PREFIX("caf_lock")), ". r . . w w w . ",
3979 1.1 mrg void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
3980 1.1 mrg pint_type, pint_type, pchar_type_node, size_type_node);
3981 1.1 mrg
3982 1.1 mrg gfor_fndecl_caf_unlock = gfc_build_library_function_decl_with_spec (
3983 1.1 mrg get_identifier (PREFIX("caf_unlock")), ". r . . w w . ",
3984 1.1 mrg void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
3985 1.1 mrg pint_type, pchar_type_node, size_type_node);
3986 1.1 mrg
3987 1.1 mrg gfor_fndecl_caf_event_post = gfc_build_library_function_decl_with_spec (
3988 1.1 mrg get_identifier (PREFIX("caf_event_post")), ". r . . w w . ",
3989 1.1 mrg void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
3990 1.1 mrg pint_type, pchar_type_node, size_type_node);
3991 1.1 mrg
3992 1.1 mrg gfor_fndecl_caf_event_wait = gfc_build_library_function_decl_with_spec (
3993 1.1 mrg get_identifier (PREFIX("caf_event_wait")), ". r . . w w . ",
3994 1.1 mrg void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
3995 1.1 mrg pint_type, pchar_type_node, size_type_node);
3996 1.1 mrg
3997 1.1 mrg gfor_fndecl_caf_event_query = gfc_build_library_function_decl_with_spec (
3998 1.1 mrg get_identifier (PREFIX("caf_event_query")), ". r . . w w ",
3999 1.1 mrg void_type_node, 5, pvoid_type_node, size_type_node, integer_type_node,
4000 1.1 mrg pint_type, pint_type);
4001 1.1 mrg
4002 1.1 mrg gfor_fndecl_caf_fail_image = gfc_build_library_function_decl (
4003 1.1 mrg get_identifier (PREFIX("caf_fail_image")), void_type_node, 0);
4004 1.1 mrg /* CAF's FAIL doesn't return. */
4005 1.1 mrg TREE_THIS_VOLATILE (gfor_fndecl_caf_fail_image) = 1;
4006 1.1 mrg
4007 1.1 mrg gfor_fndecl_caf_failed_images
4008 1.1 mrg = gfc_build_library_function_decl_with_spec (
4009 1.1 mrg get_identifier (PREFIX("caf_failed_images")), ". w . r ",
4010 1.1 mrg void_type_node, 3, pvoid_type_node, ppvoid_type_node,
4011 1.1 mrg integer_type_node);
4012 1.1 mrg
4013 1.1 mrg gfor_fndecl_caf_form_team
4014 1.1 mrg = gfc_build_library_function_decl_with_spec (
4015 1.1 mrg get_identifier (PREFIX("caf_form_team")), ". . W . ",
4016 1.1 mrg void_type_node, 3, integer_type_node, ppvoid_type_node,
4017 1.1 mrg integer_type_node);
4018 1.1 mrg
4019 1.1 mrg gfor_fndecl_caf_change_team
4020 1.1 mrg = gfc_build_library_function_decl_with_spec (
4021 1.1 mrg get_identifier (PREFIX("caf_change_team")), ". w . ",
4022 1.1 mrg void_type_node, 2, ppvoid_type_node,
4023 1.1 mrg integer_type_node);
4024 1.1 mrg
4025 1.1 mrg gfor_fndecl_caf_end_team
4026 1.1 mrg = gfc_build_library_function_decl (
4027 1.1 mrg get_identifier (PREFIX("caf_end_team")), void_type_node, 0);
4028 1.1 mrg
4029 1.1 mrg gfor_fndecl_caf_get_team
4030 1.1 mrg = gfc_build_library_function_decl (
4031 1.1 mrg get_identifier (PREFIX("caf_get_team")),
4032 1.1 mrg void_type_node, 1, integer_type_node);
4033 1.1 mrg
4034 1.1 mrg gfor_fndecl_caf_sync_team
4035 1.1 mrg = gfc_build_library_function_decl_with_spec (
4036 1.1 mrg get_identifier (PREFIX("caf_sync_team")), ". r . ",
4037 1.1 mrg void_type_node, 2, ppvoid_type_node,
4038 1.1 mrg integer_type_node);
4039 1.1 mrg
4040 1.1 mrg gfor_fndecl_caf_team_number
4041 1.1 mrg = gfc_build_library_function_decl_with_spec (
4042 1.1 mrg get_identifier (PREFIX("caf_team_number")), ". r ",
4043 1.1 mrg integer_type_node, 1, integer_type_node);
4044 1.1 mrg
4045 1.1 mrg gfor_fndecl_caf_image_status
4046 1.1 mrg = gfc_build_library_function_decl_with_spec (
4047 1.1 mrg get_identifier (PREFIX("caf_image_status")), ". . r ",
4048 1.1 mrg integer_type_node, 2, integer_type_node, ppvoid_type_node);
4049 1.1 mrg
4050 1.1 mrg gfor_fndecl_caf_stopped_images
4051 1.1 mrg = gfc_build_library_function_decl_with_spec (
4052 1.1 mrg get_identifier (PREFIX("caf_stopped_images")), ". w r r ",
4053 1.1 mrg void_type_node, 3, pvoid_type_node, ppvoid_type_node,
4054 1.1 mrg integer_type_node);
4055 1.1 mrg
4056 1.1 mrg gfor_fndecl_co_broadcast = gfc_build_library_function_decl_with_spec (
4057 1.1 mrg get_identifier (PREFIX("caf_co_broadcast")), ". w . w w . ",
4058 1.1 mrg void_type_node, 5, pvoid_type_node, integer_type_node,
4059 1.1 mrg pint_type, pchar_type_node, size_type_node);
4060 1.1 mrg
4061 1.1 mrg gfor_fndecl_co_max = gfc_build_library_function_decl_with_spec (
4062 1.1 mrg get_identifier (PREFIX("caf_co_max")), ". w . w w . . ",
4063 1.1 mrg void_type_node, 6, pvoid_type_node, integer_type_node,
4064 1.1 mrg pint_type, pchar_type_node, integer_type_node, size_type_node);
4065 1.1 mrg
4066 1.1 mrg gfor_fndecl_co_min = gfc_build_library_function_decl_with_spec (
4067 1.1 mrg get_identifier (PREFIX("caf_co_min")), ". w . w w . . ",
4068 1.1 mrg void_type_node, 6, pvoid_type_node, integer_type_node,
4069 1.1 mrg pint_type, pchar_type_node, integer_type_node, size_type_node);
4070 1.1 mrg
4071 1.1 mrg gfor_fndecl_co_reduce = gfc_build_library_function_decl_with_spec (
4072 1.1 mrg get_identifier (PREFIX("caf_co_reduce")), ". w r . . w w . . ",
4073 1.1 mrg void_type_node, 8, pvoid_type_node,
4074 1.1 mrg build_pointer_type (build_varargs_function_type_list (void_type_node,
4075 1.1 mrg NULL_TREE)),
4076 1.1 mrg integer_type_node, integer_type_node, pint_type, pchar_type_node,
4077 1.1 mrg integer_type_node, size_type_node);
4078 1.1 mrg
4079 1.1 mrg gfor_fndecl_co_sum = gfc_build_library_function_decl_with_spec (
4080 1.1 mrg get_identifier (PREFIX("caf_co_sum")), ". w . w w . ",
4081 1.1 mrg void_type_node, 5, pvoid_type_node, integer_type_node,
4082 1.1 mrg pint_type, pchar_type_node, size_type_node);
4083 1.1 mrg
4084 1.1 mrg gfor_fndecl_caf_is_present = gfc_build_library_function_decl_with_spec (
4085 1.1 mrg get_identifier (PREFIX("caf_is_present")), ". r . r ",
4086 1.1 mrg integer_type_node, 3, pvoid_type_node, integer_type_node,
4087 1.1 mrg pvoid_type_node);
4088 1.1 mrg
4089 1.1 mrg gfor_fndecl_caf_random_init = gfc_build_library_function_decl (
4090 1.1 mrg get_identifier (PREFIX("caf_random_init")),
4091 1.1 mrg void_type_node, 2, logical_type_node, logical_type_node);
4092 1.1 mrg }
4093 1.1 mrg
4094 1.1 mrg gfc_build_intrinsic_function_decls ();
4095 1.1 mrg gfc_build_intrinsic_lib_fndecls ();
4096 1.1 mrg gfc_build_io_library_fndecls ();
4097 1.1 mrg }
4098 1.1 mrg
4099 1.1 mrg
4100 1.1 mrg /* Evaluate the length of dummy character variables. */
4101 1.1 mrg
4102 1.1 mrg static void
4103 1.1 mrg gfc_trans_dummy_character (gfc_symbol *sym, gfc_charlen *cl,
4104 1.1 mrg gfc_wrapped_block *block)
4105 1.1 mrg {
4106 1.1 mrg stmtblock_t init;
4107 1.1 mrg
4108 1.1 mrg gfc_finish_decl (cl->backend_decl);
4109 1.1 mrg
4110 1.1 mrg gfc_start_block (&init);
4111 1.1 mrg
4112 1.1 mrg /* Evaluate the string length expression. */
4113 1.1 mrg gfc_conv_string_length (cl, NULL, &init);
4114 1.1 mrg
4115 1.1 mrg gfc_trans_vla_type_sizes (sym, &init);
4116 1.1 mrg
4117 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4118 1.1 mrg }
4119 1.1 mrg
4120 1.1 mrg
4121 1.1 mrg /* Allocate and cleanup an automatic character variable. */
4122 1.1 mrg
4123 1.1 mrg static void
4124 1.1 mrg gfc_trans_auto_character_variable (gfc_symbol * sym, gfc_wrapped_block * block)
4125 1.1 mrg {
4126 1.1 mrg stmtblock_t init;
4127 1.1 mrg tree decl;
4128 1.1 mrg tree tmp;
4129 1.1 mrg
4130 1.1 mrg gcc_assert (sym->backend_decl);
4131 1.1 mrg gcc_assert (sym->ts.u.cl && sym->ts.u.cl->length);
4132 1.1 mrg
4133 1.1 mrg gfc_init_block (&init);
4134 1.1 mrg
4135 1.1 mrg /* Evaluate the string length expression. */
4136 1.1 mrg gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4137 1.1 mrg
4138 1.1 mrg gfc_trans_vla_type_sizes (sym, &init);
4139 1.1 mrg
4140 1.1 mrg decl = sym->backend_decl;
4141 1.1 mrg
4142 1.1 mrg /* Emit a DECL_EXPR for this variable, which will cause the
4143 1.1 mrg gimplifier to allocate storage, and all that good stuff. */
4144 1.1 mrg tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
4145 1.1 mrg gfc_add_expr_to_block (&init, tmp);
4146 1.1 mrg
4147 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4148 1.1 mrg }
4149 1.1 mrg
4150 1.1 mrg /* Set the initial value of ASSIGN statement auxiliary variable explicitly. */
4151 1.1 mrg
4152 1.1 mrg static void
4153 1.1 mrg gfc_trans_assign_aux_var (gfc_symbol * sym, gfc_wrapped_block * block)
4154 1.1 mrg {
4155 1.1 mrg stmtblock_t init;
4156 1.1 mrg
4157 1.1 mrg gcc_assert (sym->backend_decl);
4158 1.1 mrg gfc_start_block (&init);
4159 1.1 mrg
4160 1.1 mrg /* Set the initial value to length. See the comments in
4161 1.1 mrg function gfc_add_assign_aux_vars in this file. */
4162 1.1 mrg gfc_add_modify (&init, GFC_DECL_STRING_LEN (sym->backend_decl),
4163 1.1 mrg build_int_cst (gfc_charlen_type_node, -2));
4164 1.1 mrg
4165 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4166 1.1 mrg }
4167 1.1 mrg
4168 1.1 mrg static void
4169 1.1 mrg gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
4170 1.1 mrg {
4171 1.1 mrg tree t = *tp, var, val;
4172 1.1 mrg
4173 1.1 mrg if (t == NULL || t == error_mark_node)
4174 1.1 mrg return;
4175 1.1 mrg if (TREE_CONSTANT (t) || DECL_P (t))
4176 1.1 mrg return;
4177 1.1 mrg
4178 1.1 mrg if (TREE_CODE (t) == SAVE_EXPR)
4179 1.1 mrg {
4180 1.1 mrg if (SAVE_EXPR_RESOLVED_P (t))
4181 1.1 mrg {
4182 1.1 mrg *tp = TREE_OPERAND (t, 0);
4183 1.1 mrg return;
4184 1.1 mrg }
4185 1.1 mrg val = TREE_OPERAND (t, 0);
4186 1.1 mrg }
4187 1.1 mrg else
4188 1.1 mrg val = t;
4189 1.1 mrg
4190 1.1 mrg var = gfc_create_var_np (TREE_TYPE (t), NULL);
4191 1.1 mrg gfc_add_decl_to_function (var);
4192 1.1 mrg gfc_add_modify (body, var, unshare_expr (val));
4193 1.1 mrg if (TREE_CODE (t) == SAVE_EXPR)
4194 1.1 mrg TREE_OPERAND (t, 0) = var;
4195 1.1 mrg *tp = var;
4196 1.1 mrg }
4197 1.1 mrg
4198 1.1 mrg static void
4199 1.1 mrg gfc_trans_vla_type_sizes_1 (tree type, stmtblock_t *body)
4200 1.1 mrg {
4201 1.1 mrg tree t;
4202 1.1 mrg
4203 1.1 mrg if (type == NULL || type == error_mark_node)
4204 1.1 mrg return;
4205 1.1 mrg
4206 1.1 mrg type = TYPE_MAIN_VARIANT (type);
4207 1.1 mrg
4208 1.1 mrg if (TREE_CODE (type) == INTEGER_TYPE)
4209 1.1 mrg {
4210 1.1 mrg gfc_trans_vla_one_sizepos (&TYPE_MIN_VALUE (type), body);
4211 1.1 mrg gfc_trans_vla_one_sizepos (&TYPE_MAX_VALUE (type), body);
4212 1.1 mrg
4213 1.1 mrg for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
4214 1.1 mrg {
4215 1.1 mrg TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
4216 1.1 mrg TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
4217 1.1 mrg }
4218 1.1 mrg }
4219 1.1 mrg else if (TREE_CODE (type) == ARRAY_TYPE)
4220 1.1 mrg {
4221 1.1 mrg gfc_trans_vla_type_sizes_1 (TREE_TYPE (type), body);
4222 1.1 mrg gfc_trans_vla_type_sizes_1 (TYPE_DOMAIN (type), body);
4223 1.1 mrg gfc_trans_vla_one_sizepos (&TYPE_SIZE (type), body);
4224 1.1 mrg gfc_trans_vla_one_sizepos (&TYPE_SIZE_UNIT (type), body);
4225 1.1 mrg
4226 1.1 mrg for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
4227 1.1 mrg {
4228 1.1 mrg TYPE_SIZE (t) = TYPE_SIZE (type);
4229 1.1 mrg TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
4230 1.1 mrg }
4231 1.1 mrg }
4232 1.1 mrg }
4233 1.1 mrg
4234 1.1 mrg /* Make sure all type sizes and array domains are either constant,
4235 1.1 mrg or variable or parameter decls. This is a simplified variant
4236 1.1 mrg of gimplify_type_sizes, but we can't use it here, as none of the
4237 1.1 mrg variables in the expressions have been gimplified yet.
4238 1.1 mrg As type sizes and domains for various variable length arrays
4239 1.1 mrg contain VAR_DECLs that are only initialized at gfc_trans_deferred_vars
4240 1.1 mrg time, without this routine gimplify_type_sizes in the middle-end
4241 1.1 mrg could result in the type sizes being gimplified earlier than where
4242 1.1 mrg those variables are initialized. */
4243 1.1 mrg
4244 1.1 mrg void
4245 1.1 mrg gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body)
4246 1.1 mrg {
4247 1.1 mrg tree type = TREE_TYPE (sym->backend_decl);
4248 1.1 mrg
4249 1.1 mrg if (TREE_CODE (type) == FUNCTION_TYPE
4250 1.1 mrg && (sym->attr.function || sym->attr.result || sym->attr.entry))
4251 1.1 mrg {
4252 1.1 mrg if (! current_fake_result_decl)
4253 1.1 mrg return;
4254 1.1 mrg
4255 1.1 mrg type = TREE_TYPE (TREE_VALUE (current_fake_result_decl));
4256 1.1 mrg }
4257 1.1 mrg
4258 1.1 mrg while (POINTER_TYPE_P (type))
4259 1.1 mrg type = TREE_TYPE (type);
4260 1.1 mrg
4261 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (type))
4262 1.1 mrg {
4263 1.1 mrg tree etype = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
4264 1.1 mrg
4265 1.1 mrg while (POINTER_TYPE_P (etype))
4266 1.1 mrg etype = TREE_TYPE (etype);
4267 1.1 mrg
4268 1.1 mrg gfc_trans_vla_type_sizes_1 (etype, body);
4269 1.1 mrg }
4270 1.1 mrg
4271 1.1 mrg gfc_trans_vla_type_sizes_1 (type, body);
4272 1.1 mrg }
4273 1.1 mrg
4274 1.1 mrg
4275 1.1 mrg /* Initialize a derived type by building an lvalue from the symbol
4276 1.1 mrg and using trans_assignment to do the work. Set dealloc to false
4277 1.1 mrg if no deallocation prior the assignment is needed. */
4278 1.1 mrg void
4279 1.1 mrg gfc_init_default_dt (gfc_symbol * sym, stmtblock_t * block, bool dealloc)
4280 1.1 mrg {
4281 1.1 mrg gfc_expr *e;
4282 1.1 mrg tree tmp;
4283 1.1 mrg tree present;
4284 1.1 mrg
4285 1.1 mrg gcc_assert (block);
4286 1.1 mrg
4287 1.1 mrg /* Initialization of PDTs is done elsewhere. */
4288 1.1 mrg if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
4289 1.1 mrg return;
4290 1.1 mrg
4291 1.1 mrg gcc_assert (!sym->attr.allocatable);
4292 1.1 mrg gfc_set_sym_referenced (sym);
4293 1.1 mrg e = gfc_lval_expr_from_sym (sym);
4294 1.1 mrg tmp = gfc_trans_assignment (e, sym->value, false, dealloc);
4295 1.1 mrg if (sym->attr.dummy && (sym->attr.optional
4296 1.1 mrg || sym->ns->proc_name->attr.entry_master))
4297 1.1 mrg {
4298 1.1 mrg present = gfc_conv_expr_present (sym);
4299 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
4300 1.1 mrg tmp, build_empty_stmt (input_location));
4301 1.1 mrg }
4302 1.1 mrg gfc_add_expr_to_block (block, tmp);
4303 1.1 mrg gfc_free_expr (e);
4304 1.1 mrg }
4305 1.1 mrg
4306 1.1 mrg
4307 1.1 mrg /* Initialize INTENT(OUT) derived type dummies. As well as giving
4308 1.1 mrg them their default initializer, if they do not have allocatable
4309 1.1 mrg components, they have their allocatable components deallocated. */
4310 1.1 mrg
4311 1.1 mrg static void
4312 1.1 mrg init_intent_out_dt (gfc_symbol * proc_sym, gfc_wrapped_block * block)
4313 1.1 mrg {
4314 1.1 mrg stmtblock_t init;
4315 1.1 mrg gfc_formal_arglist *f;
4316 1.1 mrg tree tmp;
4317 1.1 mrg tree present;
4318 1.1 mrg
4319 1.1 mrg gfc_init_block (&init);
4320 1.1 mrg for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
4321 1.1 mrg if (f->sym && f->sym->attr.intent == INTENT_OUT
4322 1.1 mrg && !f->sym->attr.pointer
4323 1.1 mrg && f->sym->ts.type == BT_DERIVED)
4324 1.1 mrg {
4325 1.1 mrg tmp = NULL_TREE;
4326 1.1 mrg
4327 1.1 mrg /* Note: Allocatables are excluded as they are already handled
4328 1.1 mrg by the caller. */
4329 1.1 mrg if (!f->sym->attr.allocatable
4330 1.1 mrg && gfc_is_finalizable (f->sym->ts.u.derived, NULL))
4331 1.1 mrg {
4332 1.1 mrg stmtblock_t block;
4333 1.1 mrg gfc_expr *e;
4334 1.1 mrg
4335 1.1 mrg gfc_init_block (&block);
4336 1.1 mrg f->sym->attr.referenced = 1;
4337 1.1 mrg e = gfc_lval_expr_from_sym (f->sym);
4338 1.1 mrg gfc_add_finalizer_call (&block, e);
4339 1.1 mrg gfc_free_expr (e);
4340 1.1 mrg tmp = gfc_finish_block (&block);
4341 1.1 mrg }
4342 1.1 mrg
4343 1.1 mrg if (tmp == NULL_TREE && !f->sym->attr.allocatable
4344 1.1 mrg && f->sym->ts.u.derived->attr.alloc_comp && !f->sym->value)
4345 1.1 mrg tmp = gfc_deallocate_alloc_comp (f->sym->ts.u.derived,
4346 1.1 mrg f->sym->backend_decl,
4347 1.1 mrg f->sym->as ? f->sym->as->rank : 0);
4348 1.1 mrg
4349 1.1 mrg if (tmp != NULL_TREE && (f->sym->attr.optional
4350 1.1 mrg || f->sym->ns->proc_name->attr.entry_master))
4351 1.1 mrg {
4352 1.1 mrg present = gfc_conv_expr_present (f->sym);
4353 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
4354 1.1 mrg present, tmp, build_empty_stmt (input_location));
4355 1.1 mrg }
4356 1.1 mrg
4357 1.1 mrg if (tmp != NULL_TREE)
4358 1.1 mrg gfc_add_expr_to_block (&init, tmp);
4359 1.1 mrg else if (f->sym->value && !f->sym->attr.allocatable)
4360 1.1 mrg gfc_init_default_dt (f->sym, &init, true);
4361 1.1 mrg }
4362 1.1 mrg else if (f->sym && f->sym->attr.intent == INTENT_OUT
4363 1.1 mrg && f->sym->ts.type == BT_CLASS
4364 1.1 mrg && !CLASS_DATA (f->sym)->attr.class_pointer
4365 1.1 mrg && !CLASS_DATA (f->sym)->attr.allocatable)
4366 1.1 mrg {
4367 1.1 mrg stmtblock_t block;
4368 1.1 mrg gfc_expr *e;
4369 1.1 mrg
4370 1.1 mrg gfc_init_block (&block);
4371 1.1 mrg f->sym->attr.referenced = 1;
4372 1.1 mrg e = gfc_lval_expr_from_sym (f->sym);
4373 1.1 mrg gfc_add_finalizer_call (&block, e);
4374 1.1 mrg gfc_free_expr (e);
4375 1.1 mrg tmp = gfc_finish_block (&block);
4376 1.1 mrg
4377 1.1 mrg if (f->sym->attr.optional || f->sym->ns->proc_name->attr.entry_master)
4378 1.1 mrg {
4379 1.1 mrg present = gfc_conv_expr_present (f->sym);
4380 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
4381 1.1 mrg present, tmp,
4382 1.1 mrg build_empty_stmt (input_location));
4383 1.1 mrg }
4384 1.1 mrg
4385 1.1 mrg gfc_add_expr_to_block (&init, tmp);
4386 1.1 mrg }
4387 1.1 mrg
4388 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4389 1.1 mrg }
4390 1.1 mrg
4391 1.1 mrg
4392 1.1 mrg /* Helper function to manage deferred string lengths. */
4393 1.1 mrg
4394 1.1 mrg static tree
4395 1.1 mrg gfc_null_and_pass_deferred_len (gfc_symbol *sym, stmtblock_t *init,
4396 1.1 mrg locus *loc)
4397 1.1 mrg {
4398 1.1 mrg tree tmp;
4399 1.1 mrg
4400 1.1 mrg /* Character length passed by reference. */
4401 1.1 mrg tmp = sym->ts.u.cl->passed_length;
4402 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
4403 1.1 mrg tmp = fold_convert (gfc_charlen_type_node, tmp);
4404 1.1 mrg
4405 1.1 mrg if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
4406 1.1 mrg /* Zero the string length when entering the scope. */
4407 1.1 mrg gfc_add_modify (init, sym->ts.u.cl->backend_decl,
4408 1.1 mrg build_int_cst (gfc_charlen_type_node, 0));
4409 1.1 mrg else
4410 1.1 mrg {
4411 1.1 mrg tree tmp2;
4412 1.1 mrg
4413 1.1 mrg tmp2 = fold_build2_loc (input_location, MODIFY_EXPR,
4414 1.1 mrg gfc_charlen_type_node,
4415 1.1 mrg sym->ts.u.cl->backend_decl, tmp);
4416 1.1 mrg if (sym->attr.optional)
4417 1.1 mrg {
4418 1.1 mrg tree present = gfc_conv_expr_present (sym);
4419 1.1 mrg tmp2 = build3_loc (input_location, COND_EXPR,
4420 1.1 mrg void_type_node, present, tmp2,
4421 1.1 mrg build_empty_stmt (input_location));
4422 1.1 mrg }
4423 1.1 mrg gfc_add_expr_to_block (init, tmp2);
4424 1.1 mrg }
4425 1.1 mrg
4426 1.1 mrg gfc_restore_backend_locus (loc);
4427 1.1 mrg
4428 1.1 mrg /* Pass the final character length back. */
4429 1.1 mrg if (sym->attr.intent != INTENT_IN)
4430 1.1 mrg {
4431 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4432 1.1 mrg gfc_charlen_type_node, tmp,
4433 1.1 mrg sym->ts.u.cl->backend_decl);
4434 1.1 mrg if (sym->attr.optional)
4435 1.1 mrg {
4436 1.1 mrg tree present = gfc_conv_expr_present (sym);
4437 1.1 mrg tmp = build3_loc (input_location, COND_EXPR,
4438 1.1 mrg void_type_node, present, tmp,
4439 1.1 mrg build_empty_stmt (input_location));
4440 1.1 mrg }
4441 1.1 mrg }
4442 1.1 mrg else
4443 1.1 mrg tmp = NULL_TREE;
4444 1.1 mrg
4445 1.1 mrg return tmp;
4446 1.1 mrg }
4447 1.1 mrg
4448 1.1 mrg
4449 1.1 mrg /* Get the result expression for a procedure. */
4450 1.1 mrg
4451 1.1 mrg static tree
4452 1.1 mrg get_proc_result (gfc_symbol* sym)
4453 1.1 mrg {
4454 1.1 mrg if (sym->attr.subroutine || sym == sym->result)
4455 1.1 mrg {
4456 1.1 mrg if (current_fake_result_decl != NULL)
4457 1.1 mrg return TREE_VALUE (current_fake_result_decl);
4458 1.1 mrg
4459 1.1 mrg return NULL_TREE;
4460 1.1 mrg }
4461 1.1 mrg
4462 1.1 mrg return sym->result->backend_decl;
4463 1.1 mrg }
4464 1.1 mrg
4465 1.1 mrg
4466 1.1 mrg /* Generate function entry and exit code, and add it to the function body.
4467 1.1 mrg This includes:
4468 1.1 mrg Allocation and initialization of array variables.
4469 1.1 mrg Allocation of character string variables.
4470 1.1 mrg Initialization and possibly repacking of dummy arrays.
4471 1.1 mrg Initialization of ASSIGN statement auxiliary variable.
4472 1.1 mrg Initialization of ASSOCIATE names.
4473 1.1 mrg Automatic deallocation. */
4474 1.1 mrg
4475 1.1 mrg void
4476 1.1 mrg gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
4477 1.1 mrg {
4478 1.1 mrg locus loc;
4479 1.1 mrg gfc_symbol *sym;
4480 1.1 mrg gfc_formal_arglist *f;
4481 1.1 mrg stmtblock_t tmpblock;
4482 1.1 mrg bool seen_trans_deferred_array = false;
4483 1.1 mrg bool is_pdt_type = false;
4484 1.1 mrg tree tmp = NULL;
4485 1.1 mrg gfc_expr *e;
4486 1.1 mrg gfc_se se;
4487 1.1 mrg stmtblock_t init;
4488 1.1 mrg
4489 1.1 mrg /* Deal with implicit return variables. Explicit return variables will
4490 1.1 mrg already have been added. */
4491 1.1 mrg if (gfc_return_by_reference (proc_sym) && proc_sym->result == proc_sym)
4492 1.1 mrg {
4493 1.1 mrg if (!current_fake_result_decl)
4494 1.1 mrg {
4495 1.1 mrg gfc_entry_list *el = NULL;
4496 1.1 mrg if (proc_sym->attr.entry_master)
4497 1.1 mrg {
4498 1.1 mrg for (el = proc_sym->ns->entries; el; el = el->next)
4499 1.1 mrg if (el->sym != el->sym->result)
4500 1.1 mrg break;
4501 1.1 mrg }
4502 1.1 mrg /* TODO: move to the appropriate place in resolve.cc. */
4503 1.1 mrg if (warn_return_type > 0 && el == NULL)
4504 1.1 mrg gfc_warning (OPT_Wreturn_type,
4505 1.1 mrg "Return value of function %qs at %L not set",
4506 1.1 mrg proc_sym->name, &proc_sym->declared_at);
4507 1.1 mrg }
4508 1.1 mrg else if (proc_sym->as)
4509 1.1 mrg {
4510 1.1 mrg tree result = TREE_VALUE (current_fake_result_decl);
4511 1.1 mrg gfc_save_backend_locus (&loc);
4512 1.1 mrg gfc_set_backend_locus (&proc_sym->declared_at);
4513 1.1 mrg gfc_trans_dummy_array_bias (proc_sym, result, block);
4514 1.1 mrg
4515 1.1 mrg /* An automatic character length, pointer array result. */
4516 1.1 mrg if (proc_sym->ts.type == BT_CHARACTER
4517 1.1 mrg && VAR_P (proc_sym->ts.u.cl->backend_decl))
4518 1.1 mrg {
4519 1.1 mrg tmp = NULL;
4520 1.1 mrg if (proc_sym->ts.deferred)
4521 1.1 mrg {
4522 1.1 mrg gfc_start_block (&init);
4523 1.1 mrg tmp = gfc_null_and_pass_deferred_len (proc_sym, &init, &loc);
4524 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4525 1.1 mrg }
4526 1.1 mrg else
4527 1.1 mrg gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
4528 1.1 mrg }
4529 1.1 mrg }
4530 1.1 mrg else if (proc_sym->ts.type == BT_CHARACTER)
4531 1.1 mrg {
4532 1.1 mrg if (proc_sym->ts.deferred)
4533 1.1 mrg {
4534 1.1 mrg tmp = NULL;
4535 1.1 mrg gfc_save_backend_locus (&loc);
4536 1.1 mrg gfc_set_backend_locus (&proc_sym->declared_at);
4537 1.1 mrg gfc_start_block (&init);
4538 1.1 mrg /* Zero the string length on entry. */
4539 1.1 mrg gfc_add_modify (&init, proc_sym->ts.u.cl->backend_decl,
4540 1.1 mrg build_int_cst (gfc_charlen_type_node, 0));
4541 1.1 mrg /* Null the pointer. */
4542 1.1 mrg e = gfc_lval_expr_from_sym (proc_sym);
4543 1.1 mrg gfc_init_se (&se, NULL);
4544 1.1 mrg se.want_pointer = 1;
4545 1.1 mrg gfc_conv_expr (&se, e);
4546 1.1 mrg gfc_free_expr (e);
4547 1.1 mrg tmp = se.expr;
4548 1.1 mrg gfc_add_modify (&init, tmp,
4549 1.1 mrg fold_convert (TREE_TYPE (se.expr),
4550 1.1 mrg null_pointer_node));
4551 1.1 mrg gfc_restore_backend_locus (&loc);
4552 1.1 mrg
4553 1.1 mrg /* Pass back the string length on exit. */
4554 1.1 mrg tmp = proc_sym->ts.u.cl->backend_decl;
4555 1.1 mrg if (TREE_CODE (tmp) != INDIRECT_REF
4556 1.1 mrg && proc_sym->ts.u.cl->passed_length)
4557 1.1 mrg {
4558 1.1 mrg tmp = proc_sym->ts.u.cl->passed_length;
4559 1.1 mrg tmp = build_fold_indirect_ref_loc (input_location, tmp);
4560 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4561 1.1 mrg TREE_TYPE (tmp), tmp,
4562 1.1 mrg fold_convert
4563 1.1 mrg (TREE_TYPE (tmp),
4564 1.1 mrg proc_sym->ts.u.cl->backend_decl));
4565 1.1 mrg }
4566 1.1 mrg else
4567 1.1 mrg tmp = NULL_TREE;
4568 1.1 mrg
4569 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4570 1.1 mrg }
4571 1.1 mrg else if (VAR_P (proc_sym->ts.u.cl->backend_decl))
4572 1.1 mrg gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
4573 1.1 mrg }
4574 1.1 mrg else
4575 1.1 mrg gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX);
4576 1.1 mrg }
4577 1.1 mrg else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym))
4578 1.1 mrg {
4579 1.1 mrg /* Nullify explicit return class arrays on entry. */
4580 1.1 mrg tree type;
4581 1.1 mrg tmp = get_proc_result (proc_sym);
4582 1.1 mrg if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
4583 1.1 mrg {
4584 1.1 mrg gfc_start_block (&init);
4585 1.1 mrg tmp = gfc_class_data_get (tmp);
4586 1.1 mrg type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp));
4587 1.1 mrg gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0));
4588 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4589 1.1 mrg }
4590 1.1 mrg }
4591 1.1 mrg
4592 1.1 mrg
4593 1.1 mrg /* Initialize the INTENT(OUT) derived type dummy arguments. This
4594 1.1 mrg should be done here so that the offsets and lbounds of arrays
4595 1.1 mrg are available. */
4596 1.1 mrg gfc_save_backend_locus (&loc);
4597 1.1 mrg gfc_set_backend_locus (&proc_sym->declared_at);
4598 1.1 mrg init_intent_out_dt (proc_sym, block);
4599 1.1 mrg gfc_restore_backend_locus (&loc);
4600 1.1 mrg
4601 1.1 mrg for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
4602 1.1 mrg {
4603 1.1 mrg bool alloc_comp_or_fini = (sym->ts.type == BT_DERIVED)
4604 1.1 mrg && (sym->ts.u.derived->attr.alloc_comp
4605 1.1 mrg || gfc_is_finalizable (sym->ts.u.derived,
4606 1.1 mrg NULL));
4607 1.1 mrg if (sym->assoc)
4608 1.1 mrg continue;
4609 1.1 mrg
4610 1.1 mrg if (sym->ts.type == BT_DERIVED
4611 1.1 mrg && sym->ts.u.derived
4612 1.1 mrg && sym->ts.u.derived->attr.pdt_type)
4613 1.1 mrg {
4614 1.1 mrg is_pdt_type = true;
4615 1.1 mrg gfc_init_block (&tmpblock);
4616 1.1 mrg if (!(sym->attr.dummy
4617 1.1 mrg || sym->attr.pointer
4618 1.1 mrg || sym->attr.allocatable))
4619 1.1 mrg {
4620 1.1 mrg tmp = gfc_allocate_pdt_comp (sym->ts.u.derived,
4621 1.1 mrg sym->backend_decl,
4622 1.1 mrg sym->as ? sym->as->rank : 0,
4623 1.1 mrg sym->param_list);
4624 1.1 mrg gfc_add_expr_to_block (&tmpblock, tmp);
4625 1.1 mrg if (!sym->attr.result)
4626 1.1 mrg tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived,
4627 1.1 mrg sym->backend_decl,
4628 1.1 mrg sym->as ? sym->as->rank : 0);
4629 1.1 mrg else
4630 1.1 mrg tmp = NULL_TREE;
4631 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
4632 1.1 mrg }
4633 1.1 mrg else if (sym->attr.dummy)
4634 1.1 mrg {
4635 1.1 mrg tmp = gfc_check_pdt_dummy (sym->ts.u.derived,
4636 1.1 mrg sym->backend_decl,
4637 1.1 mrg sym->as ? sym->as->rank : 0,
4638 1.1 mrg sym->param_list);
4639 1.1 mrg gfc_add_expr_to_block (&tmpblock, tmp);
4640 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
4641 1.1 mrg }
4642 1.1 mrg }
4643 1.1 mrg else if (sym->ts.type == BT_CLASS
4644 1.1 mrg && CLASS_DATA (sym)->ts.u.derived
4645 1.1 mrg && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
4646 1.1 mrg {
4647 1.1 mrg gfc_component *data = CLASS_DATA (sym);
4648 1.1 mrg is_pdt_type = true;
4649 1.1 mrg gfc_init_block (&tmpblock);
4650 1.1 mrg if (!(sym->attr.dummy
4651 1.1 mrg || CLASS_DATA (sym)->attr.pointer
4652 1.1 mrg || CLASS_DATA (sym)->attr.allocatable))
4653 1.1 mrg {
4654 1.1 mrg tmp = gfc_class_data_get (sym->backend_decl);
4655 1.1 mrg tmp = gfc_allocate_pdt_comp (data->ts.u.derived, tmp,
4656 1.1 mrg data->as ? data->as->rank : 0,
4657 1.1 mrg sym->param_list);
4658 1.1 mrg gfc_add_expr_to_block (&tmpblock, tmp);
4659 1.1 mrg tmp = gfc_class_data_get (sym->backend_decl);
4660 1.1 mrg if (!sym->attr.result)
4661 1.1 mrg tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp,
4662 1.1 mrg data->as ? data->as->rank : 0);
4663 1.1 mrg else
4664 1.1 mrg tmp = NULL_TREE;
4665 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
4666 1.1 mrg }
4667 1.1 mrg else if (sym->attr.dummy)
4668 1.1 mrg {
4669 1.1 mrg tmp = gfc_class_data_get (sym->backend_decl);
4670 1.1 mrg tmp = gfc_check_pdt_dummy (data->ts.u.derived, tmp,
4671 1.1 mrg data->as ? data->as->rank : 0,
4672 1.1 mrg sym->param_list);
4673 1.1 mrg gfc_add_expr_to_block (&tmpblock, tmp);
4674 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
4675 1.1 mrg }
4676 1.1 mrg }
4677 1.1 mrg
4678 1.1 mrg if (sym->attr.pointer && sym->attr.dimension
4679 1.1 mrg && sym->attr.save == SAVE_NONE
4680 1.1 mrg && !sym->attr.use_assoc
4681 1.1 mrg && !sym->attr.host_assoc
4682 1.1 mrg && !sym->attr.dummy
4683 1.1 mrg && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)))
4684 1.1 mrg {
4685 1.1 mrg gfc_init_block (&tmpblock);
4686 1.1 mrg gfc_conv_descriptor_span_set (&tmpblock, sym->backend_decl,
4687 1.1 mrg build_int_cst (gfc_array_index_type, 0));
4688 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
4689 1.1 mrg NULL_TREE);
4690 1.1 mrg }
4691 1.1 mrg
4692 1.1 mrg if (sym->ts.type == BT_CLASS
4693 1.1 mrg && (sym->attr.save || flag_max_stack_var_size == 0)
4694 1.1 mrg && CLASS_DATA (sym)->attr.allocatable)
4695 1.1 mrg {
4696 1.1 mrg tree vptr;
4697 1.1 mrg
4698 1.1 mrg if (UNLIMITED_POLY (sym))
4699 1.1 mrg vptr = null_pointer_node;
4700 1.1 mrg else
4701 1.1 mrg {
4702 1.1 mrg gfc_symbol *vsym;
4703 1.1 mrg vsym = gfc_find_derived_vtab (sym->ts.u.derived);
4704 1.1 mrg vptr = gfc_get_symbol_decl (vsym);
4705 1.1 mrg vptr = gfc_build_addr_expr (NULL, vptr);
4706 1.1 mrg }
4707 1.1 mrg
4708 1.1 mrg if (CLASS_DATA (sym)->attr.dimension
4709 1.1 mrg || (CLASS_DATA (sym)->attr.codimension
4710 1.1 mrg && flag_coarray != GFC_FCOARRAY_LIB))
4711 1.1 mrg {
4712 1.1 mrg tmp = gfc_class_data_get (sym->backend_decl);
4713 1.1 mrg tmp = gfc_build_null_descriptor (TREE_TYPE (tmp));
4714 1.1 mrg }
4715 1.1 mrg else
4716 1.1 mrg tmp = null_pointer_node;
4717 1.1 mrg
4718 1.1 mrg DECL_INITIAL (sym->backend_decl)
4719 1.1 mrg = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp);
4720 1.1 mrg TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1;
4721 1.1 mrg }
4722 1.1 mrg else if ((sym->attr.dimension || sym->attr.codimension
4723 1.1 mrg || (IS_CLASS_ARRAY (sym) && !CLASS_DATA (sym)->attr.allocatable)))
4724 1.1 mrg {
4725 1.1 mrg bool is_classarray = IS_CLASS_ARRAY (sym);
4726 1.1 mrg symbol_attribute *array_attr;
4727 1.1 mrg gfc_array_spec *as;
4728 1.1 mrg array_type type_of_array;
4729 1.1 mrg
4730 1.1 mrg array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
4731 1.1 mrg as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
4732 1.1 mrg /* Assumed-size Cray pointees need to be treated as AS_EXPLICIT. */
4733 1.1 mrg type_of_array = as->type;
4734 1.1 mrg if (type_of_array == AS_ASSUMED_SIZE && as->cp_was_assumed)
4735 1.1 mrg type_of_array = AS_EXPLICIT;
4736 1.1 mrg switch (type_of_array)
4737 1.1 mrg {
4738 1.1 mrg case AS_EXPLICIT:
4739 1.1 mrg if (sym->attr.dummy || sym->attr.result)
4740 1.1 mrg gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
4741 1.1 mrg /* Allocatable and pointer arrays need to processed
4742 1.1 mrg explicitly. */
4743 1.1 mrg else if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
4744 1.1 mrg || (sym->ts.type == BT_CLASS
4745 1.1 mrg && CLASS_DATA (sym)->attr.class_pointer)
4746 1.1 mrg || array_attr->allocatable)
4747 1.1 mrg {
4748 1.1 mrg if (TREE_STATIC (sym->backend_decl))
4749 1.1 mrg {
4750 1.1 mrg gfc_save_backend_locus (&loc);
4751 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
4752 1.1 mrg gfc_trans_static_array_pointer (sym);
4753 1.1 mrg gfc_restore_backend_locus (&loc);
4754 1.1 mrg }
4755 1.1 mrg else
4756 1.1 mrg {
4757 1.1 mrg seen_trans_deferred_array = true;
4758 1.1 mrg gfc_trans_deferred_array (sym, block);
4759 1.1 mrg }
4760 1.1 mrg }
4761 1.1 mrg else if (sym->attr.codimension
4762 1.1 mrg && TREE_STATIC (sym->backend_decl))
4763 1.1 mrg {
4764 1.1 mrg gfc_init_block (&tmpblock);
4765 1.1 mrg gfc_trans_array_cobounds (TREE_TYPE (sym->backend_decl),
4766 1.1 mrg &tmpblock, sym);
4767 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
4768 1.1 mrg NULL_TREE);
4769 1.1 mrg continue;
4770 1.1 mrg }
4771 1.1 mrg else
4772 1.1 mrg {
4773 1.1 mrg gfc_save_backend_locus (&loc);
4774 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
4775 1.1 mrg
4776 1.1 mrg if (alloc_comp_or_fini)
4777 1.1 mrg {
4778 1.1 mrg seen_trans_deferred_array = true;
4779 1.1 mrg gfc_trans_deferred_array (sym, block);
4780 1.1 mrg }
4781 1.1 mrg else if (sym->ts.type == BT_DERIVED
4782 1.1 mrg && sym->value
4783 1.1 mrg && !sym->attr.data
4784 1.1 mrg && sym->attr.save == SAVE_NONE)
4785 1.1 mrg {
4786 1.1 mrg gfc_start_block (&tmpblock);
4787 1.1 mrg gfc_init_default_dt (sym, &tmpblock, false);
4788 1.1 mrg gfc_add_init_cleanup (block,
4789 1.1 mrg gfc_finish_block (&tmpblock),
4790 1.1 mrg NULL_TREE);
4791 1.1 mrg }
4792 1.1 mrg
4793 1.1 mrg gfc_trans_auto_array_allocation (sym->backend_decl,
4794 1.1 mrg sym, block);
4795 1.1 mrg gfc_restore_backend_locus (&loc);
4796 1.1 mrg }
4797 1.1 mrg break;
4798 1.1 mrg
4799 1.1 mrg case AS_ASSUMED_SIZE:
4800 1.1 mrg /* Must be a dummy parameter. */
4801 1.1 mrg gcc_assert (sym->attr.dummy || as->cp_was_assumed);
4802 1.1 mrg
4803 1.1 mrg /* We should always pass assumed size arrays the g77 way. */
4804 1.1 mrg if (sym->attr.dummy)
4805 1.1 mrg gfc_trans_g77_array (sym, block);
4806 1.1 mrg break;
4807 1.1 mrg
4808 1.1 mrg case AS_ASSUMED_SHAPE:
4809 1.1 mrg /* Must be a dummy parameter. */
4810 1.1 mrg gcc_assert (sym->attr.dummy);
4811 1.1 mrg
4812 1.1 mrg gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
4813 1.1 mrg break;
4814 1.1 mrg
4815 1.1 mrg case AS_ASSUMED_RANK:
4816 1.1 mrg case AS_DEFERRED:
4817 1.1 mrg seen_trans_deferred_array = true;
4818 1.1 mrg gfc_trans_deferred_array (sym, block);
4819 1.1 mrg if (sym->ts.type == BT_CHARACTER && sym->ts.deferred
4820 1.1 mrg && sym->attr.result)
4821 1.1 mrg {
4822 1.1 mrg gfc_start_block (&init);
4823 1.1 mrg gfc_save_backend_locus (&loc);
4824 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
4825 1.1 mrg tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc);
4826 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4827 1.1 mrg }
4828 1.1 mrg break;
4829 1.1 mrg
4830 1.1 mrg default:
4831 1.1 mrg gcc_unreachable ();
4832 1.1 mrg }
4833 1.1 mrg if (alloc_comp_or_fini && !seen_trans_deferred_array)
4834 1.1 mrg gfc_trans_deferred_array (sym, block);
4835 1.1 mrg }
4836 1.1 mrg else if ((!sym->attr.dummy || sym->ts.deferred)
4837 1.1 mrg && (sym->ts.type == BT_CLASS
4838 1.1 mrg && CLASS_DATA (sym)->attr.class_pointer))
4839 1.1 mrg gfc_trans_class_array (sym, block);
4840 1.1 mrg else if ((!sym->attr.dummy || sym->ts.deferred)
4841 1.1 mrg && (sym->attr.allocatable
4842 1.1 mrg || (sym->attr.pointer && sym->attr.result)
4843 1.1 mrg || (sym->ts.type == BT_CLASS
4844 1.1 mrg && CLASS_DATA (sym)->attr.allocatable)))
4845 1.1 mrg {
4846 1.1 mrg if (!sym->attr.save && flag_max_stack_var_size != 0)
4847 1.1 mrg {
4848 1.1 mrg tree descriptor = NULL_TREE;
4849 1.1 mrg
4850 1.1 mrg gfc_save_backend_locus (&loc);
4851 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
4852 1.1 mrg gfc_start_block (&init);
4853 1.1 mrg
4854 1.1 mrg if (sym->ts.type == BT_CHARACTER
4855 1.1 mrg && sym->attr.allocatable
4856 1.1 mrg && !sym->attr.dimension
4857 1.1 mrg && sym->ts.u.cl && sym->ts.u.cl->length
4858 1.1 mrg && sym->ts.u.cl->length->expr_type == EXPR_VARIABLE)
4859 1.1 mrg gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4860 1.1 mrg
4861 1.1 mrg if (!sym->attr.pointer)
4862 1.1 mrg {
4863 1.1 mrg /* Nullify and automatic deallocation of allocatable
4864 1.1 mrg scalars. */
4865 1.1 mrg e = gfc_lval_expr_from_sym (sym);
4866 1.1 mrg if (sym->ts.type == BT_CLASS)
4867 1.1 mrg gfc_add_data_component (e);
4868 1.1 mrg
4869 1.1 mrg gfc_init_se (&se, NULL);
4870 1.1 mrg if (sym->ts.type != BT_CLASS
4871 1.1 mrg || sym->ts.u.derived->attr.dimension
4872 1.1 mrg || sym->ts.u.derived->attr.codimension)
4873 1.1 mrg {
4874 1.1 mrg se.want_pointer = 1;
4875 1.1 mrg gfc_conv_expr (&se, e);
4876 1.1 mrg }
4877 1.1 mrg else if (sym->ts.type == BT_CLASS
4878 1.1 mrg && !CLASS_DATA (sym)->attr.dimension
4879 1.1 mrg && !CLASS_DATA (sym)->attr.codimension)
4880 1.1 mrg {
4881 1.1 mrg se.want_pointer = 1;
4882 1.1 mrg gfc_conv_expr (&se, e);
4883 1.1 mrg }
4884 1.1 mrg else
4885 1.1 mrg {
4886 1.1 mrg se.descriptor_only = 1;
4887 1.1 mrg gfc_conv_expr (&se, e);
4888 1.1 mrg descriptor = se.expr;
4889 1.1 mrg se.expr = gfc_conv_descriptor_data_addr (se.expr);
4890 1.1 mrg se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
4891 1.1 mrg }
4892 1.1 mrg gfc_free_expr (e);
4893 1.1 mrg
4894 1.1 mrg if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
4895 1.1 mrg {
4896 1.1 mrg /* Nullify when entering the scope. */
4897 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4898 1.1 mrg TREE_TYPE (se.expr), se.expr,
4899 1.1 mrg fold_convert (TREE_TYPE (se.expr),
4900 1.1 mrg null_pointer_node));
4901 1.1 mrg if (sym->attr.optional)
4902 1.1 mrg {
4903 1.1 mrg tree present = gfc_conv_expr_present (sym);
4904 1.1 mrg tmp = build3_loc (input_location, COND_EXPR,
4905 1.1 mrg void_type_node, present, tmp,
4906 1.1 mrg build_empty_stmt (input_location));
4907 1.1 mrg }
4908 1.1 mrg gfc_add_expr_to_block (&init, tmp);
4909 1.1 mrg }
4910 1.1 mrg }
4911 1.1 mrg
4912 1.1 mrg if ((sym->attr.dummy || sym->attr.result)
4913 1.1 mrg && sym->ts.type == BT_CHARACTER
4914 1.1 mrg && sym->ts.deferred
4915 1.1 mrg && sym->ts.u.cl->passed_length)
4916 1.1 mrg tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc);
4917 1.1 mrg else
4918 1.1 mrg {
4919 1.1 mrg gfc_restore_backend_locus (&loc);
4920 1.1 mrg tmp = NULL_TREE;
4921 1.1 mrg }
4922 1.1 mrg
4923 1.1 mrg /* Initialize descriptor's TKR information. */
4924 1.1 mrg if (sym->ts.type == BT_CLASS)
4925 1.1 mrg gfc_trans_class_array (sym, block);
4926 1.1 mrg
4927 1.1 mrg /* Deallocate when leaving the scope. Nullifying is not
4928 1.1 mrg needed. */
4929 1.1 mrg if (!sym->attr.result && !sym->attr.dummy && !sym->attr.pointer
4930 1.1 mrg && !sym->ns->proc_name->attr.is_main_program)
4931 1.1 mrg {
4932 1.1 mrg if (sym->ts.type == BT_CLASS
4933 1.1 mrg && CLASS_DATA (sym)->attr.codimension)
4934 1.1 mrg tmp = gfc_deallocate_with_status (descriptor, NULL_TREE,
4935 1.1 mrg NULL_TREE, NULL_TREE,
4936 1.1 mrg NULL_TREE, true, NULL,
4937 1.1 mrg GFC_CAF_COARRAY_ANALYZE);
4938 1.1 mrg else
4939 1.1 mrg {
4940 1.1 mrg gfc_expr *expr = gfc_lval_expr_from_sym (sym);
4941 1.1 mrg tmp = gfc_deallocate_scalar_with_status (se.expr,
4942 1.1 mrg NULL_TREE,
4943 1.1 mrg NULL_TREE,
4944 1.1 mrg true, expr,
4945 1.1 mrg sym->ts);
4946 1.1 mrg gfc_free_expr (expr);
4947 1.1 mrg }
4948 1.1 mrg }
4949 1.1 mrg
4950 1.1 mrg if (sym->ts.type == BT_CLASS)
4951 1.1 mrg {
4952 1.1 mrg /* Initialize _vptr to declared type. */
4953 1.1 mrg gfc_symbol *vtab;
4954 1.1 mrg tree rhs;
4955 1.1 mrg
4956 1.1 mrg gfc_save_backend_locus (&loc);
4957 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
4958 1.1 mrg e = gfc_lval_expr_from_sym (sym);
4959 1.1 mrg gfc_add_vptr_component (e);
4960 1.1 mrg gfc_init_se (&se, NULL);
4961 1.1 mrg se.want_pointer = 1;
4962 1.1 mrg gfc_conv_expr (&se, e);
4963 1.1 mrg gfc_free_expr (e);
4964 1.1 mrg if (UNLIMITED_POLY (sym))
4965 1.1 mrg rhs = build_int_cst (TREE_TYPE (se.expr), 0);
4966 1.1 mrg else
4967 1.1 mrg {
4968 1.1 mrg vtab = gfc_find_derived_vtab (sym->ts.u.derived);
4969 1.1 mrg rhs = gfc_build_addr_expr (TREE_TYPE (se.expr),
4970 1.1 mrg gfc_get_symbol_decl (vtab));
4971 1.1 mrg }
4972 1.1 mrg gfc_add_modify (&init, se.expr, rhs);
4973 1.1 mrg gfc_restore_backend_locus (&loc);
4974 1.1 mrg }
4975 1.1 mrg
4976 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4977 1.1 mrg }
4978 1.1 mrg }
4979 1.1 mrg else if (sym->ts.type == BT_CHARACTER && sym->ts.deferred)
4980 1.1 mrg {
4981 1.1 mrg tree tmp = NULL;
4982 1.1 mrg stmtblock_t init;
4983 1.1 mrg
4984 1.1 mrg /* If we get to here, all that should be left are pointers. */
4985 1.1 mrg gcc_assert (sym->attr.pointer);
4986 1.1 mrg
4987 1.1 mrg if (sym->attr.dummy)
4988 1.1 mrg {
4989 1.1 mrg gfc_start_block (&init);
4990 1.1 mrg gfc_save_backend_locus (&loc);
4991 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
4992 1.1 mrg tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc);
4993 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4994 1.1 mrg }
4995 1.1 mrg }
4996 1.1 mrg else if (sym->ts.deferred)
4997 1.1 mrg gfc_fatal_error ("Deferred type parameter not yet supported");
4998 1.1 mrg else if (alloc_comp_or_fini)
4999 1.1 mrg gfc_trans_deferred_array (sym, block);
5000 1.1 mrg else if (sym->ts.type == BT_CHARACTER)
5001 1.1 mrg {
5002 1.1 mrg gfc_save_backend_locus (&loc);
5003 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
5004 1.1 mrg if (sym->attr.dummy || sym->attr.result)
5005 1.1 mrg gfc_trans_dummy_character (sym, sym->ts.u.cl, block);
5006 1.1 mrg else
5007 1.1 mrg gfc_trans_auto_character_variable (sym, block);
5008 1.1 mrg gfc_restore_backend_locus (&loc);
5009 1.1 mrg }
5010 1.1 mrg else if (sym->attr.assign)
5011 1.1 mrg {
5012 1.1 mrg gfc_save_backend_locus (&loc);
5013 1.1 mrg gfc_set_backend_locus (&sym->declared_at);
5014 1.1 mrg gfc_trans_assign_aux_var (sym, block);
5015 1.1 mrg gfc_restore_backend_locus (&loc);
5016 1.1 mrg }
5017 1.1 mrg else if (sym->ts.type == BT_DERIVED
5018 1.1 mrg && sym->value
5019 1.1 mrg && !sym->attr.data
5020 1.1 mrg && sym->attr.save == SAVE_NONE)
5021 1.1 mrg {
5022 1.1 mrg gfc_start_block (&tmpblock);
5023 1.1 mrg gfc_init_default_dt (sym, &tmpblock, false);
5024 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
5025 1.1 mrg NULL_TREE);
5026 1.1 mrg }
5027 1.1 mrg else if (!(UNLIMITED_POLY(sym)) && !is_pdt_type)
5028 1.1 mrg gcc_unreachable ();
5029 1.1 mrg }
5030 1.1 mrg
5031 1.1 mrg gfc_init_block (&tmpblock);
5032 1.1 mrg
5033 1.1 mrg for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
5034 1.1 mrg {
5035 1.1 mrg if (f->sym && f->sym->tlink == NULL && f->sym->ts.type == BT_CHARACTER
5036 1.1 mrg && f->sym->ts.u.cl->backend_decl)
5037 1.1 mrg {
5038 1.1 mrg if (TREE_CODE (f->sym->ts.u.cl->backend_decl) == PARM_DECL)
5039 1.1 mrg gfc_trans_vla_type_sizes (f->sym, &tmpblock);
5040 1.1 mrg }
5041 1.1 mrg }
5042 1.1 mrg
5043 1.1 mrg if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER
5044 1.1 mrg && current_fake_result_decl != NULL)
5045 1.1 mrg {
5046 1.1 mrg gcc_assert (proc_sym->ts.u.cl->backend_decl != NULL);
5047 1.1 mrg if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == PARM_DECL)
5048 1.1 mrg gfc_trans_vla_type_sizes (proc_sym, &tmpblock);
5049 1.1 mrg }
5050 1.1 mrg
5051 1.1 mrg gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE);
5052 1.1 mrg }
5053 1.1 mrg
5054 1.1 mrg
5055 1.1 mrg struct module_hasher : ggc_ptr_hash<module_htab_entry>
5056 1.1 mrg {
5057 1.1 mrg typedef const char *compare_type;
5058 1.1 mrg
5059 1.1 mrg static hashval_t hash (module_htab_entry *s)
5060 1.1 mrg {
5061 1.1 mrg return htab_hash_string (s->name);
5062 1.1 mrg }
5063 1.1 mrg
5064 1.1 mrg static bool
5065 1.1 mrg equal (module_htab_entry *a, const char *b)
5066 1.1 mrg {
5067 1.1 mrg return !strcmp (a->name, b);
5068 1.1 mrg }
5069 1.1 mrg };
5070 1.1 mrg
5071 1.1 mrg static GTY (()) hash_table<module_hasher> *module_htab;
5072 1.1 mrg
5073 1.1 mrg /* Hash and equality functions for module_htab's decls. */
5074 1.1 mrg
5075 1.1 mrg hashval_t
5076 1.1 mrg module_decl_hasher::hash (tree t)
5077 1.1 mrg {
5078 1.1 mrg const_tree n = DECL_NAME (t);
5079 1.1 mrg if (n == NULL_TREE)
5080 1.1 mrg n = TYPE_NAME (TREE_TYPE (t));
5081 1.1 mrg return htab_hash_string (IDENTIFIER_POINTER (n));
5082 1.1 mrg }
5083 1.1 mrg
5084 1.1 mrg bool
5085 1.1 mrg module_decl_hasher::equal (tree t1, const char *x2)
5086 1.1 mrg {
5087 1.1 mrg const_tree n1 = DECL_NAME (t1);
5088 1.1 mrg if (n1 == NULL_TREE)
5089 1.1 mrg n1 = TYPE_NAME (TREE_TYPE (t1));
5090 1.1 mrg return strcmp (IDENTIFIER_POINTER (n1), x2) == 0;
5091 1.1 mrg }
5092 1.1 mrg
5093 1.1 mrg struct module_htab_entry *
5094 1.1 mrg gfc_find_module (const char *name)
5095 1.1 mrg {
5096 1.1 mrg if (! module_htab)
5097 1.1 mrg module_htab = hash_table<module_hasher>::create_ggc (10);
5098 1.1 mrg
5099 1.1 mrg module_htab_entry **slot
5100 1.1 mrg = module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
5101 1.1 mrg if (*slot == NULL)
5102 1.1 mrg {
5103 1.1 mrg module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
5104 1.1 mrg
5105 1.1 mrg entry->name = gfc_get_string ("%s", name);
5106 1.1 mrg entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
5107 1.1 mrg *slot = entry;
5108 1.1 mrg }
5109 1.1 mrg return *slot;
5110 1.1 mrg }
5111 1.1 mrg
5112 1.1 mrg void
5113 1.1 mrg gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
5114 1.1 mrg {
5115 1.1 mrg const char *name;
5116 1.1 mrg
5117 1.1 mrg if (DECL_NAME (decl))
5118 1.1 mrg name = IDENTIFIER_POINTER (DECL_NAME (decl));
5119 1.1 mrg else
5120 1.1 mrg {
5121 1.1 mrg gcc_assert (TREE_CODE (decl) == TYPE_DECL);
5122 1.1 mrg name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
5123 1.1 mrg }
5124 1.1 mrg tree *slot
5125 1.1 mrg = entry->decls->find_slot_with_hash (name, htab_hash_string (name),
5126 1.1 mrg INSERT);
5127 1.1 mrg if (*slot == NULL)
5128 1.1 mrg *slot = decl;
5129 1.1 mrg }
5130 1.1 mrg
5131 1.1 mrg
5132 1.1 mrg /* Generate debugging symbols for namelists. This function must come after
5133 1.1 mrg generate_local_decl to ensure that the variables in the namelist are
5134 1.1 mrg already declared. */
5135 1.1 mrg
5136 1.1 mrg static tree
5137 1.1 mrg generate_namelist_decl (gfc_symbol * sym)
5138 1.1 mrg {
5139 1.1 mrg gfc_namelist *nml;
5140 1.1 mrg tree decl;
5141 1.1 mrg vec<constructor_elt, va_gc> *nml_decls = NULL;
5142 1.1 mrg
5143 1.1 mrg gcc_assert (sym->attr.flavor == FL_NAMELIST);
5144 1.1 mrg for (nml = sym->namelist; nml; nml = nml->next)
5145 1.1 mrg {
5146 1.1 mrg if (nml->sym->backend_decl == NULL_TREE)
5147 1.1 mrg {
5148 1.1 mrg nml->sym->attr.referenced = 1;
5149 1.1 mrg nml->sym->backend_decl = gfc_get_symbol_decl (nml->sym);
5150 1.1 mrg }
5151 1.1 mrg DECL_IGNORED_P (nml->sym->backend_decl) = 0;
5152 1.1 mrg CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, nml->sym->backend_decl);
5153 1.1 mrg }
5154 1.1 mrg
5155 1.1 mrg decl = make_node (NAMELIST_DECL);
5156 1.1 mrg TREE_TYPE (decl) = void_type_node;
5157 1.1 mrg NAMELIST_DECL_ASSOCIATED_DECL (decl) = build_constructor (NULL_TREE, nml_decls);
5158 1.1 mrg DECL_NAME (decl) = get_identifier (sym->name);
5159 1.1 mrg return decl;
5160 1.1 mrg }
5161 1.1 mrg
5162 1.1 mrg
5163 1.1 mrg /* Output an initialized decl for a module variable. */
5164 1.1 mrg
5165 1.1 mrg static void
5166 1.1 mrg gfc_create_module_variable (gfc_symbol * sym)
5167 1.1 mrg {
5168 1.1 mrg tree decl;
5169 1.1 mrg
5170 1.1 mrg /* Module functions with alternate entries are dealt with later and
5171 1.1 mrg would get caught by the next condition. */
5172 1.1 mrg if (sym->attr.entry)
5173 1.1 mrg return;
5174 1.1 mrg
5175 1.1 mrg /* Make sure we convert the types of the derived types from iso_c_binding
5176 1.1 mrg into (void *). */
5177 1.1 mrg if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
5178 1.1 mrg && sym->ts.type == BT_DERIVED)
5179 1.1 mrg sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
5180 1.1 mrg
5181 1.1 mrg if (gfc_fl_struct (sym->attr.flavor)
5182 1.1 mrg && sym->backend_decl
5183 1.1 mrg && TREE_CODE (sym->backend_decl) == RECORD_TYPE)
5184 1.1 mrg {
5185 1.1 mrg decl = sym->backend_decl;
5186 1.1 mrg gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5187 1.1 mrg
5188 1.1 mrg if (!sym->attr.use_assoc && !sym->attr.used_in_submodule)
5189 1.1 mrg {
5190 1.1 mrg gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE
5191 1.1 mrg || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl);
5192 1.1 mrg gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE
5193 1.1 mrg || DECL_CONTEXT (TYPE_STUB_DECL (decl))
5194 1.1 mrg == sym->ns->proc_name->backend_decl);
5195 1.1 mrg }
5196 1.1 mrg TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5197 1.1 mrg DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl;
5198 1.1 mrg gfc_module_add_decl (cur_module, TYPE_STUB_DECL (decl));
5199 1.1 mrg }
5200 1.1 mrg
5201 1.1 mrg /* Only output variables, procedure pointers and array valued,
5202 1.1 mrg or derived type, parameters. */
5203 1.1 mrg if (sym->attr.flavor != FL_VARIABLE
5204 1.1 mrg && !(sym->attr.flavor == FL_PARAMETER
5205 1.1 mrg && (sym->attr.dimension || sym->ts.type == BT_DERIVED))
5206 1.1 mrg && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer))
5207 1.1 mrg return;
5208 1.1 mrg
5209 1.1 mrg if ((sym->attr.in_common || sym->attr.in_equivalence) && sym->backend_decl)
5210 1.1 mrg {
5211 1.1 mrg decl = sym->backend_decl;
5212 1.1 mrg gcc_assert (DECL_FILE_SCOPE_P (decl));
5213 1.1 mrg gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5214 1.1 mrg DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5215 1.1 mrg gfc_module_add_decl (cur_module, decl);
5216 1.1 mrg }
5217 1.1 mrg
5218 1.1 mrg /* Don't generate variables from other modules. Variables from
5219 1.1 mrg COMMONs and Cray pointees will already have been generated. */
5220 1.1 mrg if (sym->attr.use_assoc || sym->attr.used_in_submodule
5221 1.1 mrg || sym->attr.in_common || sym->attr.cray_pointee)
5222 1.1 mrg return;
5223 1.1 mrg
5224 1.1 mrg /* Equivalenced variables arrive here after creation. */
5225 1.1 mrg if (sym->backend_decl
5226 1.1 mrg && (sym->equiv_built || sym->attr.in_equivalence))
5227 1.1 mrg return;
5228 1.1 mrg
5229 1.1 mrg if (sym->backend_decl && !sym->attr.vtab && !sym->attr.target)
5230 1.1 mrg gfc_internal_error ("backend decl for module variable %qs already exists",
5231 1.1 mrg sym->name);
5232 1.1 mrg
5233 1.1 mrg if (sym->module && !sym->attr.result && !sym->attr.dummy
5234 1.1 mrg && (sym->attr.access == ACCESS_UNKNOWN
5235 1.1 mrg && (sym->ns->default_access == ACCESS_PRIVATE
5236 1.1 mrg || (sym->ns->default_access == ACCESS_UNKNOWN
5237 1.1 mrg && flag_module_private))))
5238 1.1 mrg sym->attr.access = ACCESS_PRIVATE;
5239 1.1 mrg
5240 1.1 mrg if (warn_unused_variable && !sym->attr.referenced
5241 1.1 mrg && sym->attr.access == ACCESS_PRIVATE)
5242 1.1 mrg gfc_warning (OPT_Wunused_value,
5243 1.1 mrg "Unused PRIVATE module variable %qs declared at %L",
5244 1.1 mrg sym->name, &sym->declared_at);
5245 1.1 mrg
5246 1.1 mrg /* We always want module variables to be created. */
5247 1.1 mrg sym->attr.referenced = 1;
5248 1.1 mrg /* Create the decl. */
5249 1.1 mrg decl = gfc_get_symbol_decl (sym);
5250 1.1 mrg
5251 1.1 mrg /* Create the variable. */
5252 1.1 mrg pushdecl (decl);
5253 1.1 mrg gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
5254 1.1 mrg || ((sym->ns->parent->proc_name->attr.flavor == FL_MODULE
5255 1.1 mrg || sym->ns->parent->proc_name->attr.flavor == FL_PROCEDURE)
5256 1.1 mrg && sym->fn_result_spec));
5257 1.1 mrg DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5258 1.1 mrg rest_of_decl_compilation (decl, 1, 0);
5259 1.1 mrg gfc_module_add_decl (cur_module, decl);
5260 1.1 mrg
5261 1.1 mrg /* Also add length of strings. */
5262 1.1 mrg if (sym->ts.type == BT_CHARACTER)
5263 1.1 mrg {
5264 1.1 mrg tree length;
5265 1.1 mrg
5266 1.1 mrg length = sym->ts.u.cl->backend_decl;
5267 1.1 mrg gcc_assert (length || sym->attr.proc_pointer);
5268 1.1 mrg if (length && !INTEGER_CST_P (length))
5269 1.1 mrg {
5270 1.1 mrg pushdecl (length);
5271 1.1 mrg rest_of_decl_compilation (length, 1, 0);
5272 1.1 mrg }
5273 1.1 mrg }
5274 1.1 mrg
5275 1.1 mrg if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
5276 1.1 mrg && sym->attr.referenced && !sym->attr.use_assoc)
5277 1.1 mrg has_coarray_vars = true;
5278 1.1 mrg }
5279 1.1 mrg
5280 1.1 mrg /* Emit debug information for USE statements. */
5281 1.1 mrg
5282 1.1 mrg static void
5283 1.1 mrg gfc_trans_use_stmts (gfc_namespace * ns)
5284 1.1 mrg {
5285 1.1 mrg gfc_use_list *use_stmt;
5286 1.1 mrg for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next)
5287 1.1 mrg {
5288 1.1 mrg struct module_htab_entry *entry
5289 1.1 mrg = gfc_find_module (use_stmt->module_name);
5290 1.1 mrg gfc_use_rename *rent;
5291 1.1 mrg
5292 1.1 mrg if (entry->namespace_decl == NULL)
5293 1.1 mrg {
5294 1.1 mrg entry->namespace_decl
5295 1.1 mrg = build_decl (input_location,
5296 1.1 mrg NAMESPACE_DECL,
5297 1.1 mrg get_identifier (use_stmt->module_name),
5298 1.1 mrg void_type_node);
5299 1.1 mrg DECL_EXTERNAL (entry->namespace_decl) = 1;
5300 1.1 mrg }
5301 1.1 mrg gfc_set_backend_locus (&use_stmt->where);
5302 1.1 mrg if (!use_stmt->only_flag)
5303 1.1 mrg (*debug_hooks->imported_module_or_decl) (entry->namespace_decl,
5304 1.1 mrg NULL_TREE,
5305 1.1 mrg ns->proc_name->backend_decl,
5306 1.1 mrg false, false);
5307 1.1 mrg for (rent = use_stmt->rename; rent; rent = rent->next)
5308 1.1 mrg {
5309 1.1 mrg tree decl, local_name;
5310 1.1 mrg
5311 1.1 mrg if (rent->op != INTRINSIC_NONE)
5312 1.1 mrg continue;
5313 1.1 mrg
5314 1.1 mrg hashval_t hash = htab_hash_string (rent->use_name);
5315 1.1 mrg tree *slot = entry->decls->find_slot_with_hash (rent->use_name, hash,
5316 1.1 mrg INSERT);
5317 1.1 mrg if (*slot == NULL)
5318 1.1 mrg {
5319 1.1 mrg gfc_symtree *st;
5320 1.1 mrg
5321 1.1 mrg st = gfc_find_symtree (ns->sym_root,
5322 1.1 mrg rent->local_name[0]
5323 1.1 mrg ? rent->local_name : rent->use_name);
5324 1.1 mrg
5325 1.1 mrg /* The following can happen if a derived type is renamed. */
5326 1.1 mrg if (!st)
5327 1.1 mrg {
5328 1.1 mrg char *name;
5329 1.1 mrg name = xstrdup (rent->local_name[0]
5330 1.1 mrg ? rent->local_name : rent->use_name);
5331 1.1 mrg name[0] = (char) TOUPPER ((unsigned char) name[0]);
5332 1.1 mrg st = gfc_find_symtree (ns->sym_root, name);
5333 1.1 mrg free (name);
5334 1.1 mrg gcc_assert (st);
5335 1.1 mrg }
5336 1.1 mrg
5337 1.1 mrg /* Sometimes, generic interfaces wind up being over-ruled by a
5338 1.1 mrg local symbol (see PR41062). */
5339 1.1 mrg if (!st->n.sym->attr.use_assoc)
5340 1.1 mrg {
5341 1.1 mrg *slot = error_mark_node;
5342 1.1 mrg entry->decls->clear_slot (slot);
5343 1.1 mrg continue;
5344 1.1 mrg }
5345 1.1 mrg
5346 1.1 mrg if (st->n.sym->backend_decl
5347 1.1 mrg && DECL_P (st->n.sym->backend_decl)
5348 1.1 mrg && st->n.sym->module
5349 1.1 mrg && strcmp (st->n.sym->module, use_stmt->module_name) == 0)
5350 1.1 mrg {
5351 1.1 mrg gcc_assert (DECL_EXTERNAL (entry->namespace_decl)
5352 1.1 mrg || !VAR_P (st->n.sym->backend_decl));
5353 1.1 mrg decl = copy_node (st->n.sym->backend_decl);
5354 1.1 mrg DECL_CONTEXT (decl) = entry->namespace_decl;
5355 1.1 mrg DECL_EXTERNAL (decl) = 1;
5356 1.1 mrg DECL_IGNORED_P (decl) = 0;
5357 1.1 mrg DECL_INITIAL (decl) = NULL_TREE;
5358 1.1 mrg }
5359 1.1 mrg else if (st->n.sym->attr.flavor == FL_NAMELIST
5360 1.1 mrg && st->n.sym->attr.use_only
5361 1.1 mrg && st->n.sym->module
5362 1.1 mrg && strcmp (st->n.sym->module, use_stmt->module_name)
5363 1.1 mrg == 0)
5364 1.1 mrg {
5365 1.1 mrg decl = generate_namelist_decl (st->n.sym);
5366 1.1 mrg DECL_CONTEXT (decl) = entry->namespace_decl;
5367 1.1 mrg DECL_EXTERNAL (decl) = 1;
5368 1.1 mrg DECL_IGNORED_P (decl) = 0;
5369 1.1 mrg DECL_INITIAL (decl) = NULL_TREE;
5370 1.1 mrg }
5371 1.1 mrg else
5372 1.1 mrg {
5373 1.1 mrg *slot = error_mark_node;
5374 1.1 mrg entry->decls->clear_slot (slot);
5375 1.1 mrg continue;
5376 1.1 mrg }
5377 1.1 mrg *slot = decl;
5378 1.1 mrg }
5379 1.1 mrg decl = (tree) *slot;
5380 1.1 mrg if (rent->local_name[0])
5381 1.1 mrg local_name = get_identifier (rent->local_name);
5382 1.1 mrg else
5383 1.1 mrg local_name = NULL_TREE;
5384 1.1 mrg gfc_set_backend_locus (&rent->where);
5385 1.1 mrg (*debug_hooks->imported_module_or_decl) (decl, local_name,
5386 1.1 mrg ns->proc_name->backend_decl,
5387 1.1 mrg !use_stmt->only_flag,
5388 1.1 mrg false);
5389 1.1 mrg }
5390 1.1 mrg }
5391 1.1 mrg }
5392 1.1 mrg
5393 1.1 mrg
5394 1.1 mrg /* Return true if expr is a constant initializer that gfc_conv_initializer
5395 1.1 mrg will handle. */
5396 1.1 mrg
5397 1.1 mrg static bool
5398 1.1 mrg check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
5399 1.1 mrg bool pointer)
5400 1.1 mrg {
5401 1.1 mrg gfc_constructor *c;
5402 1.1 mrg gfc_component *cm;
5403 1.1 mrg
5404 1.1 mrg if (pointer)
5405 1.1 mrg return true;
5406 1.1 mrg else if (array)
5407 1.1 mrg {
5408 1.1 mrg if (expr->expr_type == EXPR_CONSTANT || expr->expr_type == EXPR_NULL)
5409 1.1 mrg return true;
5410 1.1 mrg else if (expr->expr_type == EXPR_STRUCTURE)
5411 1.1 mrg return check_constant_initializer (expr, ts, false, false);
5412 1.1 mrg else if (expr->expr_type != EXPR_ARRAY)
5413 1.1 mrg return false;
5414 1.1 mrg for (c = gfc_constructor_first (expr->value.constructor);
5415 1.1 mrg c; c = gfc_constructor_next (c))
5416 1.1 mrg {
5417 1.1 mrg if (c->iterator)
5418 1.1 mrg return false;
5419 1.1 mrg if (c->expr->expr_type == EXPR_STRUCTURE)
5420 1.1 mrg {
5421 1.1 mrg if (!check_constant_initializer (c->expr, ts, false, false))
5422 1.1 mrg return false;
5423 1.1 mrg }
5424 1.1 mrg else if (c->expr->expr_type != EXPR_CONSTANT)
5425 1.1 mrg return false;
5426 1.1 mrg }
5427 1.1 mrg return true;
5428 1.1 mrg }
5429 1.1 mrg else switch (ts->type)
5430 1.1 mrg {
5431 1.1 mrg case_bt_struct:
5432 1.1 mrg if (expr->expr_type != EXPR_STRUCTURE)
5433 1.1 mrg return false;
5434 1.1 mrg cm = expr->ts.u.derived->components;
5435 1.1 mrg for (c = gfc_constructor_first (expr->value.constructor);
5436 1.1 mrg c; c = gfc_constructor_next (c), cm = cm->next)
5437 1.1 mrg {
5438 1.1 mrg if (!c->expr || cm->attr.allocatable)
5439 1.1 mrg continue;
5440 1.1 mrg if (!check_constant_initializer (c->expr, &cm->ts,
5441 1.1 mrg cm->attr.dimension,
5442 1.1 mrg cm->attr.pointer))
5443 1.1 mrg return false;
5444 1.1 mrg }
5445 1.1 mrg return true;
5446 1.1 mrg default:
5447 1.1 mrg return expr->expr_type == EXPR_CONSTANT;
5448 1.1 mrg }
5449 1.1 mrg }
5450 1.1 mrg
5451 1.1 mrg /* Emit debug info for parameters and unreferenced variables with
5452 1.1 mrg initializers. */
5453 1.1 mrg
5454 1.1 mrg static void
5455 1.1 mrg gfc_emit_parameter_debug_info (gfc_symbol *sym)
5456 1.1 mrg {
5457 1.1 mrg tree decl;
5458 1.1 mrg
5459 1.1 mrg if (sym->attr.flavor != FL_PARAMETER
5460 1.1 mrg && (sym->attr.flavor != FL_VARIABLE || sym->attr.referenced))
5461 1.1 mrg return;
5462 1.1 mrg
5463 1.1 mrg if (sym->backend_decl != NULL
5464 1.1 mrg || sym->value == NULL
5465 1.1 mrg || sym->attr.use_assoc
5466 1.1 mrg || sym->attr.dummy
5467 1.1 mrg || sym->attr.result
5468 1.1 mrg || sym->attr.function
5469 1.1 mrg || sym->attr.intrinsic
5470 1.1 mrg || sym->attr.pointer
5471 1.1 mrg || sym->attr.allocatable
5472 1.1 mrg || sym->attr.cray_pointee
5473 1.1 mrg || sym->attr.threadprivate
5474 1.1 mrg || sym->attr.is_bind_c
5475 1.1 mrg || sym->attr.subref_array_pointer
5476 1.1 mrg || sym->attr.assign)
5477 1.1 mrg return;
5478 1.1 mrg
5479 1.1 mrg if (sym->ts.type == BT_CHARACTER)
5480 1.1 mrg {
5481 1.1 mrg gfc_conv_const_charlen (sym->ts.u.cl);
5482 1.1 mrg if (sym->ts.u.cl->backend_decl == NULL
5483 1.1 mrg || TREE_CODE (sym->ts.u.cl->backend_decl) != INTEGER_CST)
5484 1.1 mrg return;
5485 1.1 mrg }
5486 1.1 mrg else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.alloc_comp)
5487 1.1 mrg return;
5488 1.1 mrg
5489 1.1 mrg if (sym->as)
5490 1.1 mrg {
5491 1.1 mrg int n;
5492 1.1 mrg
5493 1.1 mrg if (sym->as->type != AS_EXPLICIT)
5494 1.1 mrg return;
5495 1.1 mrg for (n = 0; n < sym->as->rank; n++)
5496 1.1 mrg if (sym->as->lower[n]->expr_type != EXPR_CONSTANT
5497 1.1 mrg || sym->as->upper[n] == NULL
5498 1.1 mrg || sym->as->upper[n]->expr_type != EXPR_CONSTANT)
5499 1.1 mrg return;
5500 1.1 mrg }
5501 1.1 mrg
5502 1.1 mrg if (!check_constant_initializer (sym->value, &sym->ts,
5503 1.1 mrg sym->attr.dimension, false))
5504 1.1 mrg return;
5505 1.1 mrg
5506 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)
5507 1.1 mrg return;
5508 1.1 mrg
5509 1.1 mrg /* Create the decl for the variable or constant. */
5510 1.1 mrg decl = build_decl (input_location,
5511 1.1 mrg sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
5512 1.1 mrg gfc_sym_identifier (sym), gfc_sym_type (sym));
5513 1.1 mrg if (sym->attr.flavor == FL_PARAMETER)
5514 1.1 mrg TREE_READONLY (decl) = 1;
5515 1.1 mrg gfc_set_decl_location (decl, &sym->declared_at);
5516 1.1 mrg if (sym->attr.dimension)
5517 1.1 mrg GFC_DECL_PACKED_ARRAY (decl) = 1;
5518 1.1 mrg DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5519 1.1 mrg TREE_STATIC (decl) = 1;
5520 1.1 mrg TREE_USED (decl) = 1;
5521 1.1 mrg if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
5522 1.1 mrg TREE_PUBLIC (decl) = 1;
5523 1.1 mrg DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
5524 1.1 mrg TREE_TYPE (decl),
5525 1.1 mrg sym->attr.dimension,
5526 1.1 mrg false, false);
5527 1.1 mrg debug_hooks->early_global_decl (decl);
5528 1.1 mrg }
5529 1.1 mrg
5530 1.1 mrg
5531 1.1 mrg static void
5532 1.1 mrg generate_coarray_sym_init (gfc_symbol *sym)
5533 1.1 mrg {
5534 1.1 mrg tree tmp, size, decl, token, desc;
5535 1.1 mrg bool is_lock_type, is_event_type;
5536 1.1 mrg int reg_type;
5537 1.1 mrg gfc_se se;
5538 1.1 mrg symbol_attribute attr;
5539 1.1 mrg
5540 1.1 mrg if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
5541 1.1 mrg || sym->attr.use_assoc || !sym->attr.referenced
5542 1.1 mrg || sym->attr.associate_var
5543 1.1 mrg || sym->attr.select_type_temporary)
5544 1.1 mrg return;
5545 1.1 mrg
5546 1.1 mrg decl = sym->backend_decl;
5547 1.1 mrg TREE_USED(decl) = 1;
5548 1.1 mrg gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
5549 1.1 mrg
5550 1.1 mrg is_lock_type = sym->ts.type == BT_DERIVED
5551 1.1 mrg && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
5552 1.1 mrg && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE;
5553 1.1 mrg
5554 1.1 mrg is_event_type = sym->ts.type == BT_DERIVED
5555 1.1 mrg && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
5556 1.1 mrg && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE;
5557 1.1 mrg
5558 1.1 mrg /* FIXME: Workaround for PR middle-end/49106, cf. also PR middle-end/49108
5559 1.1 mrg to make sure the variable is not optimized away. */
5560 1.1 mrg DECL_PRESERVE_P (DECL_CONTEXT (decl)) = 1;
5561 1.1 mrg
5562 1.1 mrg /* For lock types, we pass the array size as only the library knows the
5563 1.1 mrg size of the variable. */
5564 1.1 mrg if (is_lock_type || is_event_type)
5565 1.1 mrg size = gfc_index_one_node;
5566 1.1 mrg else
5567 1.1 mrg size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (decl)));
5568 1.1 mrg
5569 1.1 mrg /* Ensure that we do not have size=0 for zero-sized arrays. */
5570 1.1 mrg size = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
5571 1.1 mrg fold_convert (size_type_node, size),
5572 1.1 mrg build_int_cst (size_type_node, 1));
5573 1.1 mrg
5574 1.1 mrg if (GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)))
5575 1.1 mrg {
5576 1.1 mrg tmp = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (decl));
5577 1.1 mrg size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
5578 1.1 mrg fold_convert (size_type_node, tmp), size);
5579 1.1 mrg }
5580 1.1 mrg
5581 1.1 mrg gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (decl)) != NULL_TREE);
5582 1.1 mrg token = gfc_build_addr_expr (ppvoid_type_node,
5583 1.1 mrg GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE(decl)));
5584 1.1 mrg if (is_lock_type)
5585 1.1 mrg reg_type = sym->attr.artificial ? GFC_CAF_CRITICAL : GFC_CAF_LOCK_STATIC;
5586 1.1 mrg else if (is_event_type)
5587 1.1 mrg reg_type = GFC_CAF_EVENT_STATIC;
5588 1.1 mrg else
5589 1.1 mrg reg_type = GFC_CAF_COARRAY_STATIC;
5590 1.1 mrg
5591 1.1 mrg /* Compile the symbol attribute. */
5592 1.1 mrg if (sym->ts.type == BT_CLASS)
5593 1.1 mrg {
5594 1.1 mrg attr = CLASS_DATA (sym)->attr;
5595 1.1 mrg /* The pointer attribute is always set on classes, overwrite it with the
5596 1.1 mrg class_pointer attribute, which denotes the pointer for classes. */
5597 1.1 mrg attr.pointer = attr.class_pointer;
5598 1.1 mrg }
5599 1.1 mrg else
5600 1.1 mrg attr = sym->attr;
5601 1.1 mrg gfc_init_se (&se, NULL);
5602 1.1 mrg desc = gfc_conv_scalar_to_descriptor (&se, decl, attr);
5603 1.1 mrg gfc_add_block_to_block (&caf_init_block, &se.pre);
5604 1.1 mrg
5605 1.1 mrg tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 7, size,
5606 1.1 mrg build_int_cst (integer_type_node, reg_type),
5607 1.1 mrg token, gfc_build_addr_expr (pvoid_type_node, desc),
5608 1.1 mrg null_pointer_node, /* stat. */
5609 1.1 mrg null_pointer_node, /* errgmsg. */
5610 1.1 mrg build_zero_cst (size_type_node)); /* errmsg_len. */
5611 1.1 mrg gfc_add_expr_to_block (&caf_init_block, tmp);
5612 1.1 mrg gfc_add_modify (&caf_init_block, decl, fold_convert (TREE_TYPE (decl),
5613 1.1 mrg gfc_conv_descriptor_data_get (desc)));
5614 1.1 mrg
5615 1.1 mrg /* Handle "static" initializer. */
5616 1.1 mrg if (sym->value)
5617 1.1 mrg {
5618 1.1 mrg if (sym->value->expr_type == EXPR_ARRAY)
5619 1.1 mrg {
5620 1.1 mrg gfc_constructor *c, *cnext;
5621 1.1 mrg
5622 1.1 mrg /* Test if the array has more than one element. */
5623 1.1 mrg c = gfc_constructor_first (sym->value->value.constructor);
5624 1.1 mrg gcc_assert (c); /* Empty constructor should not happen here. */
5625 1.1 mrg cnext = gfc_constructor_next (c);
5626 1.1 mrg
5627 1.1 mrg if (cnext)
5628 1.1 mrg {
5629 1.1 mrg /* An EXPR_ARRAY with a rank > 1 here has to come from a
5630 1.1 mrg DATA statement. Set its rank here as not to confuse
5631 1.1 mrg the following steps. */
5632 1.1 mrg sym->value->rank = 1;
5633 1.1 mrg }
5634 1.1 mrg else
5635 1.1 mrg {
5636 1.1 mrg /* There is only a single value in the constructor, use
5637 1.1 mrg it directly for the assignment. */
5638 1.1 mrg gfc_expr *new_expr;
5639 1.1 mrg new_expr = gfc_copy_expr (c->expr);
5640 1.1 mrg gfc_free_expr (sym->value);
5641 1.1 mrg sym->value = new_expr;
5642 1.1 mrg }
5643 1.1 mrg }
5644 1.1 mrg
5645 1.1 mrg sym->attr.pointer = 1;
5646 1.1 mrg tmp = gfc_trans_assignment (gfc_lval_expr_from_sym (sym), sym->value,
5647 1.1 mrg true, false);
5648 1.1 mrg sym->attr.pointer = 0;
5649 1.1 mrg gfc_add_expr_to_block (&caf_init_block, tmp);
5650 1.1 mrg }
5651 1.1 mrg else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pointer_comp)
5652 1.1 mrg {
5653 1.1 mrg tmp = gfc_nullify_alloc_comp (sym->ts.u.derived, decl, sym->as
5654 1.1 mrg ? sym->as->rank : 0,
5655 1.1 mrg GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
5656 1.1 mrg gfc_add_expr_to_block (&caf_init_block, tmp);
5657 1.1 mrg }
5658 1.1 mrg }
5659 1.1 mrg
5660 1.1 mrg
5661 1.1 mrg /* Generate constructor function to initialize static, nonallocatable
5662 1.1 mrg coarrays. */
5663 1.1 mrg
5664 1.1 mrg static void
5665 1.1 mrg generate_coarray_init (gfc_namespace * ns __attribute((unused)))
5666 1.1 mrg {
5667 1.1 mrg tree fndecl, tmp, decl, save_fn_decl;
5668 1.1 mrg
5669 1.1 mrg save_fn_decl = current_function_decl;
5670 1.1 mrg push_function_context ();
5671 1.1 mrg
5672 1.1 mrg tmp = build_function_type_list (void_type_node, NULL_TREE);
5673 1.1 mrg fndecl = build_decl (input_location, FUNCTION_DECL,
5674 1.1 mrg create_tmp_var_name ("_caf_init"), tmp);
5675 1.1 mrg
5676 1.1 mrg DECL_STATIC_CONSTRUCTOR (fndecl) = 1;
5677 1.1 mrg SET_DECL_INIT_PRIORITY (fndecl, DEFAULT_INIT_PRIORITY);
5678 1.1 mrg
5679 1.1 mrg decl = build_decl (input_location, RESULT_DECL, NULL_TREE, void_type_node);
5680 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
5681 1.1 mrg DECL_IGNORED_P (decl) = 1;
5682 1.1 mrg DECL_CONTEXT (decl) = fndecl;
5683 1.1 mrg DECL_RESULT (fndecl) = decl;
5684 1.1 mrg
5685 1.1 mrg pushdecl (fndecl);
5686 1.1 mrg current_function_decl = fndecl;
5687 1.1 mrg announce_function (fndecl);
5688 1.1 mrg
5689 1.1 mrg rest_of_decl_compilation (fndecl, 0, 0);
5690 1.1 mrg make_decl_rtl (fndecl);
5691 1.1 mrg allocate_struct_function (fndecl, false);
5692 1.1 mrg
5693 1.1 mrg pushlevel ();
5694 1.1 mrg gfc_init_block (&caf_init_block);
5695 1.1 mrg
5696 1.1 mrg gfc_traverse_ns (ns, generate_coarray_sym_init);
5697 1.1 mrg
5698 1.1 mrg DECL_SAVED_TREE (fndecl) = gfc_finish_block (&caf_init_block);
5699 1.1 mrg decl = getdecls ();
5700 1.1 mrg
5701 1.1 mrg poplevel (1, 1);
5702 1.1 mrg BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5703 1.1 mrg
5704 1.1 mrg DECL_SAVED_TREE (fndecl)
5705 1.1 mrg = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node,
5706 1.1 mrg decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl));
5707 1.1 mrg dump_function (TDI_original, fndecl);
5708 1.1 mrg
5709 1.1 mrg cfun->function_end_locus = input_location;
5710 1.1 mrg set_cfun (NULL);
5711 1.1 mrg
5712 1.1 mrg if (decl_function_context (fndecl))
5713 1.1 mrg (void) cgraph_node::create (fndecl);
5714 1.1 mrg else
5715 1.1 mrg cgraph_node::finalize_function (fndecl, true);
5716 1.1 mrg
5717 1.1 mrg pop_function_context ();
5718 1.1 mrg current_function_decl = save_fn_decl;
5719 1.1 mrg }
5720 1.1 mrg
5721 1.1 mrg
5722 1.1 mrg static void
5723 1.1 mrg create_module_nml_decl (gfc_symbol *sym)
5724 1.1 mrg {
5725 1.1 mrg if (sym->attr.flavor == FL_NAMELIST)
5726 1.1 mrg {
5727 1.1 mrg tree decl = generate_namelist_decl (sym);
5728 1.1 mrg pushdecl (decl);
5729 1.1 mrg gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5730 1.1 mrg DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5731 1.1 mrg rest_of_decl_compilation (decl, 1, 0);
5732 1.1 mrg gfc_module_add_decl (cur_module, decl);
5733 1.1 mrg }
5734 1.1 mrg }
5735 1.1 mrg
5736 1.1 mrg
5737 1.1 mrg /* Generate all the required code for module variables. */
5738 1.1 mrg
5739 1.1 mrg void
5740 1.1 mrg gfc_generate_module_vars (gfc_namespace * ns)
5741 1.1 mrg {
5742 1.1 mrg module_namespace = ns;
5743 1.1 mrg cur_module = gfc_find_module (ns->proc_name->name);
5744 1.1 mrg
5745 1.1 mrg /* Check if the frontend left the namespace in a reasonable state. */
5746 1.1 mrg gcc_assert (ns->proc_name && !ns->proc_name->tlink);
5747 1.1 mrg
5748 1.1 mrg /* Generate COMMON blocks. */
5749 1.1 mrg gfc_trans_common (ns);
5750 1.1 mrg
5751 1.1 mrg has_coarray_vars = false;
5752 1.1 mrg
5753 1.1 mrg /* Create decls for all the module variables. */
5754 1.1 mrg gfc_traverse_ns (ns, gfc_create_module_variable);
5755 1.1 mrg gfc_traverse_ns (ns, create_module_nml_decl);
5756 1.1 mrg
5757 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
5758 1.1 mrg generate_coarray_init (ns);
5759 1.1 mrg
5760 1.1 mrg cur_module = NULL;
5761 1.1 mrg
5762 1.1 mrg gfc_trans_use_stmts (ns);
5763 1.1 mrg gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
5764 1.1 mrg }
5765 1.1 mrg
5766 1.1 mrg
5767 1.1 mrg static void
5768 1.1 mrg gfc_generate_contained_functions (gfc_namespace * parent)
5769 1.1 mrg {
5770 1.1 mrg gfc_namespace *ns;
5771 1.1 mrg
5772 1.1 mrg /* We create all the prototypes before generating any code. */
5773 1.1 mrg for (ns = parent->contained; ns; ns = ns->sibling)
5774 1.1 mrg {
5775 1.1 mrg /* Skip namespaces from used modules. */
5776 1.1 mrg if (ns->parent != parent)
5777 1.1 mrg continue;
5778 1.1 mrg
5779 1.1 mrg gfc_create_function_decl (ns, false);
5780 1.1 mrg }
5781 1.1 mrg
5782 1.1 mrg for (ns = parent->contained; ns; ns = ns->sibling)
5783 1.1 mrg {
5784 1.1 mrg /* Skip namespaces from used modules. */
5785 1.1 mrg if (ns->parent != parent)
5786 1.1 mrg continue;
5787 1.1 mrg
5788 1.1 mrg gfc_generate_function_code (ns);
5789 1.1 mrg }
5790 1.1 mrg }
5791 1.1 mrg
5792 1.1 mrg
5793 1.1 mrg /* Drill down through expressions for the array specification bounds and
5794 1.1 mrg character length calling generate_local_decl for all those variables
5795 1.1 mrg that have not already been declared. */
5796 1.1 mrg
5797 1.1 mrg static void
5798 1.1 mrg generate_local_decl (gfc_symbol *);
5799 1.1 mrg
5800 1.1 mrg /* Traverse expr, marking all EXPR_VARIABLE symbols referenced. */
5801 1.1 mrg
5802 1.1 mrg static bool
5803 1.1 mrg expr_decls (gfc_expr *e, gfc_symbol *sym,
5804 1.1 mrg int *f ATTRIBUTE_UNUSED)
5805 1.1 mrg {
5806 1.1 mrg if (e->expr_type != EXPR_VARIABLE
5807 1.1 mrg || sym == e->symtree->n.sym
5808 1.1 mrg || e->symtree->n.sym->mark
5809 1.1 mrg || e->symtree->n.sym->ns != sym->ns)
5810 1.1 mrg return false;
5811 1.1 mrg
5812 1.1 mrg generate_local_decl (e->symtree->n.sym);
5813 1.1 mrg return false;
5814 1.1 mrg }
5815 1.1 mrg
5816 1.1 mrg static void
5817 1.1 mrg generate_expr_decls (gfc_symbol *sym, gfc_expr *e)
5818 1.1 mrg {
5819 1.1 mrg gfc_traverse_expr (e, sym, expr_decls, 0);
5820 1.1 mrg }
5821 1.1 mrg
5822 1.1 mrg
5823 1.1 mrg /* Check for dependencies in the character length and array spec. */
5824 1.1 mrg
5825 1.1 mrg static void
5826 1.1 mrg generate_dependency_declarations (gfc_symbol *sym)
5827 1.1 mrg {
5828 1.1 mrg int i;
5829 1.1 mrg
5830 1.1 mrg if (sym->ts.type == BT_CHARACTER
5831 1.1 mrg && sym->ts.u.cl
5832 1.1 mrg && sym->ts.u.cl->length
5833 1.1 mrg && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5834 1.1 mrg generate_expr_decls (sym, sym->ts.u.cl->length);
5835 1.1 mrg
5836 1.1 mrg if (sym->as && sym->as->rank)
5837 1.1 mrg {
5838 1.1 mrg for (i = 0; i < sym->as->rank; i++)
5839 1.1 mrg {
5840 1.1 mrg generate_expr_decls (sym, sym->as->lower[i]);
5841 1.1 mrg generate_expr_decls (sym, sym->as->upper[i]);
5842 1.1 mrg }
5843 1.1 mrg }
5844 1.1 mrg }
5845 1.1 mrg
5846 1.1 mrg
5847 1.1 mrg /* Generate decls for all local variables. We do this to ensure correct
5848 1.1 mrg handling of expressions which only appear in the specification of
5849 1.1 mrg other functions. */
5850 1.1 mrg
5851 1.1 mrg static void
5852 1.1 mrg generate_local_decl (gfc_symbol * sym)
5853 1.1 mrg {
5854 1.1 mrg if (sym->attr.flavor == FL_VARIABLE)
5855 1.1 mrg {
5856 1.1 mrg if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
5857 1.1 mrg && sym->attr.referenced && !sym->attr.use_assoc)
5858 1.1 mrg has_coarray_vars = true;
5859 1.1 mrg
5860 1.1 mrg if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master)
5861 1.1 mrg generate_dependency_declarations (sym);
5862 1.1 mrg
5863 1.1 mrg if (sym->attr.referenced)
5864 1.1 mrg gfc_get_symbol_decl (sym);
5865 1.1 mrg
5866 1.1 mrg /* Warnings for unused dummy arguments. */
5867 1.1 mrg else if (sym->attr.dummy && !sym->attr.in_namelist)
5868 1.1 mrg {
5869 1.1 mrg /* INTENT(out) dummy arguments are likely meant to be set. */
5870 1.1 mrg if (warn_unused_dummy_argument && sym->attr.intent == INTENT_OUT)
5871 1.1 mrg {
5872 1.1 mrg if (sym->ts.type != BT_DERIVED)
5873 1.1 mrg gfc_warning (OPT_Wunused_dummy_argument,
5874 1.1 mrg "Dummy argument %qs at %L was declared "
5875 1.1 mrg "INTENT(OUT) but was not set", sym->name,
5876 1.1 mrg &sym->declared_at);
5877 1.1 mrg else if (!gfc_has_default_initializer (sym->ts.u.derived)
5878 1.1 mrg && !sym->ts.u.derived->attr.zero_comp)
5879 1.1 mrg gfc_warning (OPT_Wunused_dummy_argument,
5880 1.1 mrg "Derived-type dummy argument %qs at %L was "
5881 1.1 mrg "declared INTENT(OUT) but was not set and "
5882 1.1 mrg "does not have a default initializer",
5883 1.1 mrg sym->name, &sym->declared_at);
5884 1.1 mrg if (sym->backend_decl != NULL_TREE)
5885 1.1 mrg suppress_warning (sym->backend_decl);
5886 1.1 mrg }
5887 1.1 mrg else if (warn_unused_dummy_argument)
5888 1.1 mrg {
5889 1.1 mrg if (!sym->attr.artificial)
5890 1.1 mrg gfc_warning (OPT_Wunused_dummy_argument,
5891 1.1 mrg "Unused dummy argument %qs at %L", sym->name,
5892 1.1 mrg &sym->declared_at);
5893 1.1 mrg
5894 1.1 mrg if (sym->backend_decl != NULL_TREE)
5895 1.1 mrg suppress_warning (sym->backend_decl);
5896 1.1 mrg }
5897 1.1 mrg }
5898 1.1 mrg
5899 1.1 mrg /* Warn for unused variables, but not if they're inside a common
5900 1.1 mrg block or a namelist. */
5901 1.1 mrg else if (warn_unused_variable
5902 1.1 mrg && !(sym->attr.in_common || sym->mark || sym->attr.in_namelist))
5903 1.1 mrg {
5904 1.1 mrg if (sym->attr.use_only)
5905 1.1 mrg {
5906 1.1 mrg gfc_warning (OPT_Wunused_variable,
5907 1.1 mrg "Unused module variable %qs which has been "
5908 1.1 mrg "explicitly imported at %L", sym->name,
5909 1.1 mrg &sym->declared_at);
5910 1.1 mrg if (sym->backend_decl != NULL_TREE)
5911 1.1 mrg suppress_warning (sym->backend_decl);
5912 1.1 mrg }
5913 1.1 mrg else if (!sym->attr.use_assoc)
5914 1.1 mrg {
5915 1.1 mrg /* Corner case: the symbol may be an entry point. At this point,
5916 1.1 mrg it may appear to be an unused variable. Suppress warning. */
5917 1.1 mrg bool enter = false;
5918 1.1 mrg gfc_entry_list *el;
5919 1.1 mrg
5920 1.1 mrg for (el = sym->ns->entries; el; el=el->next)
5921 1.1 mrg if (strcmp(sym->name, el->sym->name) == 0)
5922 1.1 mrg enter = true;
5923 1.1 mrg
5924 1.1 mrg if (!enter)
5925 1.1 mrg gfc_warning (OPT_Wunused_variable,
5926 1.1 mrg "Unused variable %qs declared at %L",
5927 1.1 mrg sym->name, &sym->declared_at);
5928 1.1 mrg if (sym->backend_decl != NULL_TREE)
5929 1.1 mrg suppress_warning (sym->backend_decl);
5930 1.1 mrg }
5931 1.1 mrg }
5932 1.1 mrg
5933 1.1 mrg /* For variable length CHARACTER parameters, the PARM_DECL already
5934 1.1 mrg references the length variable, so force gfc_get_symbol_decl
5935 1.1 mrg even when not referenced. If optimize > 0, it will be optimized
5936 1.1 mrg away anyway. But do this only after emitting -Wunused-parameter
5937 1.1 mrg warning if requested. */
5938 1.1 mrg if (sym->attr.dummy && !sym->attr.referenced
5939 1.1 mrg && sym->ts.type == BT_CHARACTER
5940 1.1 mrg && sym->ts.u.cl->backend_decl != NULL
5941 1.1 mrg && VAR_P (sym->ts.u.cl->backend_decl))
5942 1.1 mrg {
5943 1.1 mrg sym->attr.referenced = 1;
5944 1.1 mrg gfc_get_symbol_decl (sym);
5945 1.1 mrg }
5946 1.1 mrg
5947 1.1 mrg /* INTENT(out) dummy arguments and result variables with allocatable
5948 1.1 mrg components are reset by default and need to be set referenced to
5949 1.1 mrg generate the code for nullification and automatic lengths. */
5950 1.1 mrg if (!sym->attr.referenced
5951 1.1 mrg && sym->ts.type == BT_DERIVED
5952 1.1 mrg && sym->ts.u.derived->attr.alloc_comp
5953 1.1 mrg && !sym->attr.pointer
5954 1.1 mrg && ((sym->attr.dummy && sym->attr.intent == INTENT_OUT)
5955 1.1 mrg ||
5956 1.1 mrg (sym->attr.result && sym != sym->result)))
5957 1.1 mrg {
5958 1.1 mrg sym->attr.referenced = 1;
5959 1.1 mrg gfc_get_symbol_decl (sym);
5960 1.1 mrg }
5961 1.1 mrg
5962 1.1 mrg /* Check for dependencies in the array specification and string
5963 1.1 mrg length, adding the necessary declarations to the function. We
5964 1.1 mrg mark the symbol now, as well as in traverse_ns, to prevent
5965 1.1 mrg getting stuck in a circular dependency. */
5966 1.1 mrg sym->mark = 1;
5967 1.1 mrg }
5968 1.1 mrg else if (sym->attr.flavor == FL_PARAMETER)
5969 1.1 mrg {
5970 1.1 mrg if (warn_unused_parameter
5971 1.1 mrg && !sym->attr.referenced)
5972 1.1 mrg {
5973 1.1 mrg if (!sym->attr.use_assoc)
5974 1.1 mrg gfc_warning (OPT_Wunused_parameter,
5975 1.1 mrg "Unused parameter %qs declared at %L", sym->name,
5976 1.1 mrg &sym->declared_at);
5977 1.1 mrg else if (sym->attr.use_only)
5978 1.1 mrg gfc_warning (OPT_Wunused_parameter,
5979 1.1 mrg "Unused parameter %qs which has been explicitly "
5980 1.1 mrg "imported at %L", sym->name, &sym->declared_at);
5981 1.1 mrg }
5982 1.1 mrg
5983 1.1 mrg if (sym->ns && sym->ns->construct_entities)
5984 1.1 mrg {
5985 1.1 mrg /* Construction of the intrinsic modules within a BLOCK
5986 1.1 mrg construct, where ONLY and RENAMED entities are included,
5987 1.1 mrg seems to be bogus. This is a workaround that can be removed
5988 1.1 mrg if someone ever takes on the task to creating full-fledge
5989 1.1 mrg modules. See PR 69455. */
5990 1.1 mrg if (sym->attr.referenced
5991 1.1 mrg && sym->from_intmod != INTMOD_ISO_C_BINDING
5992 1.1 mrg && sym->from_intmod != INTMOD_ISO_FORTRAN_ENV)
5993 1.1 mrg gfc_get_symbol_decl (sym);
5994 1.1 mrg sym->mark = 1;
5995 1.1 mrg }
5996 1.1 mrg }
5997 1.1 mrg else if (sym->attr.flavor == FL_PROCEDURE)
5998 1.1 mrg {
5999 1.1 mrg /* TODO: move to the appropriate place in resolve.cc. */
6000 1.1 mrg if (warn_return_type > 0
6001 1.1 mrg && sym->attr.function
6002 1.1 mrg && sym->result
6003 1.1 mrg && sym != sym->result
6004 1.1 mrg && !sym->result->attr.referenced
6005 1.1 mrg && !sym->attr.use_assoc
6006 1.1 mrg && sym->attr.if_source != IFSRC_IFBODY)
6007 1.1 mrg {
6008 1.1 mrg gfc_warning (OPT_Wreturn_type,
6009 1.1 mrg "Return value %qs of function %qs declared at "
6010 1.1 mrg "%L not set", sym->result->name, sym->name,
6011 1.1 mrg &sym->result->declared_at);
6012 1.1 mrg
6013 1.1 mrg /* Prevents "Unused variable" warning for RESULT variables. */
6014 1.1 mrg sym->result->mark = 1;
6015 1.1 mrg }
6016 1.1 mrg }
6017 1.1 mrg
6018 1.1 mrg if (sym->attr.dummy == 1)
6019 1.1 mrg {
6020 1.1 mrg /* The tree type for scalar character dummy arguments of BIND(C)
6021 1.1 mrg procedures, if they are passed by value, should be unsigned char.
6022 1.1 mrg The value attribute implies the dummy is a scalar. */
6023 1.1 mrg if (sym->attr.value == 1 && sym->backend_decl != NULL
6024 1.1 mrg && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
6025 1.1 mrg && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
6026 1.1 mrg {
6027 1.1 mrg /* We used to modify the tree here. Now it is done earlier in
6028 1.1 mrg the front-end, so we only check it here to avoid regressions. */
6029 1.1 mrg gcc_assert (TREE_CODE (TREE_TYPE (sym->backend_decl)) == INTEGER_TYPE);
6030 1.1 mrg gcc_assert (TYPE_UNSIGNED (TREE_TYPE (sym->backend_decl)) == 1);
6031 1.1 mrg gcc_assert (TYPE_PRECISION (TREE_TYPE (sym->backend_decl)) == CHAR_TYPE_SIZE);
6032 1.1 mrg gcc_assert (DECL_BY_REFERENCE (sym->backend_decl) == 0);
6033 1.1 mrg }
6034 1.1 mrg
6035 1.1 mrg /* Unused procedure passed as dummy argument. */
6036 1.1 mrg if (sym->attr.flavor == FL_PROCEDURE)
6037 1.1 mrg {
6038 1.1 mrg if (!sym->attr.referenced && !sym->attr.artificial)
6039 1.1 mrg {
6040 1.1 mrg if (warn_unused_dummy_argument)
6041 1.1 mrg gfc_warning (OPT_Wunused_dummy_argument,
6042 1.1 mrg "Unused dummy argument %qs at %L", sym->name,
6043 1.1 mrg &sym->declared_at);
6044 1.1 mrg }
6045 1.1 mrg
6046 1.1 mrg /* Silence bogus "unused parameter" warnings from the
6047 1.1 mrg middle end. */
6048 1.1 mrg if (sym->backend_decl != NULL_TREE)
6049 1.1 mrg suppress_warning (sym->backend_decl);
6050 1.1 mrg }
6051 1.1 mrg }
6052 1.1 mrg
6053 1.1 mrg /* Make sure we convert the types of the derived types from iso_c_binding
6054 1.1 mrg into (void *). */
6055 1.1 mrg if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
6056 1.1 mrg && sym->ts.type == BT_DERIVED)
6057 1.1 mrg sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
6058 1.1 mrg }
6059 1.1 mrg
6060 1.1 mrg
6061 1.1 mrg static void
6062 1.1 mrg generate_local_nml_decl (gfc_symbol * sym)
6063 1.1 mrg {
6064 1.1 mrg if (sym->attr.flavor == FL_NAMELIST && !sym->attr.use_assoc)
6065 1.1 mrg {
6066 1.1 mrg tree decl = generate_namelist_decl (sym);
6067 1.1 mrg pushdecl (decl);
6068 1.1 mrg }
6069 1.1 mrg }
6070 1.1 mrg
6071 1.1 mrg
6072 1.1 mrg static void
6073 1.1 mrg generate_local_vars (gfc_namespace * ns)
6074 1.1 mrg {
6075 1.1 mrg gfc_traverse_ns (ns, generate_local_decl);
6076 1.1 mrg gfc_traverse_ns (ns, generate_local_nml_decl);
6077 1.1 mrg }
6078 1.1 mrg
6079 1.1 mrg
6080 1.1 mrg /* Generate a switch statement to jump to the correct entry point. Also
6081 1.1 mrg creates the label decls for the entry points. */
6082 1.1 mrg
6083 1.1 mrg static tree
6084 1.1 mrg gfc_trans_entry_master_switch (gfc_entry_list * el)
6085 1.1 mrg {
6086 1.1 mrg stmtblock_t block;
6087 1.1 mrg tree label;
6088 1.1 mrg tree tmp;
6089 1.1 mrg tree val;
6090 1.1 mrg
6091 1.1 mrg gfc_init_block (&block);
6092 1.1 mrg for (; el; el = el->next)
6093 1.1 mrg {
6094 1.1 mrg /* Add the case label. */
6095 1.1 mrg label = gfc_build_label_decl (NULL_TREE);
6096 1.1 mrg val = build_int_cst (gfc_array_index_type, el->id);
6097 1.1 mrg tmp = build_case_label (val, NULL_TREE, label);
6098 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6099 1.1 mrg
6100 1.1 mrg /* And jump to the actual entry point. */
6101 1.1 mrg label = gfc_build_label_decl (NULL_TREE);
6102 1.1 mrg tmp = build1_v (GOTO_EXPR, label);
6103 1.1 mrg gfc_add_expr_to_block (&block, tmp);
6104 1.1 mrg
6105 1.1 mrg /* Save the label decl. */
6106 1.1 mrg el->label = label;
6107 1.1 mrg }
6108 1.1 mrg tmp = gfc_finish_block (&block);
6109 1.1 mrg /* The first argument selects the entry point. */
6110 1.1 mrg val = DECL_ARGUMENTS (current_function_decl);
6111 1.1 mrg tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, val, tmp);
6112 1.1 mrg return tmp;
6113 1.1 mrg }
6114 1.1 mrg
6115 1.1 mrg
6116 1.1 mrg /* Add code to string lengths of actual arguments passed to a function against
6117 1.1 mrg the expected lengths of the dummy arguments. */
6118 1.1 mrg
6119 1.1 mrg static void
6120 1.1 mrg add_argument_checking (stmtblock_t *block, gfc_symbol *sym)
6121 1.1 mrg {
6122 1.1 mrg gfc_formal_arglist *formal;
6123 1.1 mrg
6124 1.1 mrg for (formal = gfc_sym_get_dummy_args (sym); formal; formal = formal->next)
6125 1.1 mrg if (formal->sym && formal->sym->ts.type == BT_CHARACTER
6126 1.1 mrg && !formal->sym->ts.deferred)
6127 1.1 mrg {
6128 1.1 mrg enum tree_code comparison;
6129 1.1 mrg tree cond;
6130 1.1 mrg tree argname;
6131 1.1 mrg gfc_symbol *fsym;
6132 1.1 mrg gfc_charlen *cl;
6133 1.1 mrg const char *message;
6134 1.1 mrg
6135 1.1 mrg fsym = formal->sym;
6136 1.1 mrg cl = fsym->ts.u.cl;
6137 1.1 mrg
6138 1.1 mrg gcc_assert (cl);
6139 1.1 mrg gcc_assert (cl->passed_length != NULL_TREE);
6140 1.1 mrg gcc_assert (cl->backend_decl != NULL_TREE);
6141 1.1 mrg
6142 1.1 mrg /* For POINTER, ALLOCATABLE and assumed-shape dummy arguments, the
6143 1.1 mrg string lengths must match exactly. Otherwise, it is only required
6144 1.1 mrg that the actual string length is *at least* the expected one.
6145 1.1 mrg Sequence association allows for a mismatch of the string length
6146 1.1 mrg if the actual argument is (part of) an array, but only if the
6147 1.1 mrg dummy argument is an array. (See "Sequence association" in
6148 1.1 mrg Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.) */
6149 1.1 mrg if (fsym->attr.pointer || fsym->attr.allocatable
6150 1.1 mrg || (fsym->as && (fsym->as->type == AS_ASSUMED_SHAPE
6151 1.1 mrg || fsym->as->type == AS_ASSUMED_RANK)))
6152 1.1 mrg {
6153 1.1 mrg comparison = NE_EXPR;
6154 1.1 mrg message = _("Actual string length does not match the declared one"
6155 1.1 mrg " for dummy argument '%s' (%ld/%ld)");
6156 1.1 mrg }
6157 1.1 mrg else if (fsym->as && fsym->as->rank != 0)
6158 1.1 mrg continue;
6159 1.1 mrg else
6160 1.1 mrg {
6161 1.1 mrg comparison = LT_EXPR;
6162 1.1 mrg message = _("Actual string length is shorter than the declared one"
6163 1.1 mrg " for dummy argument '%s' (%ld/%ld)");
6164 1.1 mrg }
6165 1.1 mrg
6166 1.1 mrg /* Build the condition. For optional arguments, an actual length
6167 1.1 mrg of 0 is also acceptable if the associated string is NULL, which
6168 1.1 mrg means the argument was not passed. */
6169 1.1 mrg cond = fold_build2_loc (input_location, comparison, logical_type_node,
6170 1.1 mrg cl->passed_length, cl->backend_decl);
6171 1.1 mrg if (fsym->attr.optional)
6172 1.1 mrg {
6173 1.1 mrg tree not_absent;
6174 1.1 mrg tree not_0length;
6175 1.1 mrg tree absent_failed;
6176 1.1 mrg
6177 1.1 mrg not_0length = fold_build2_loc (input_location, NE_EXPR,
6178 1.1 mrg logical_type_node,
6179 1.1 mrg cl->passed_length,
6180 1.1 mrg build_zero_cst
6181 1.1 mrg (TREE_TYPE (cl->passed_length)));
6182 1.1 mrg /* The symbol needs to be referenced for gfc_get_symbol_decl. */
6183 1.1 mrg fsym->attr.referenced = 1;
6184 1.1 mrg not_absent = gfc_conv_expr_present (fsym);
6185 1.1 mrg
6186 1.1 mrg absent_failed = fold_build2_loc (input_location, TRUTH_OR_EXPR,
6187 1.1 mrg logical_type_node, not_0length,
6188 1.1 mrg not_absent);
6189 1.1 mrg
6190 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6191 1.1 mrg logical_type_node, cond, absent_failed);
6192 1.1 mrg }
6193 1.1 mrg
6194 1.1 mrg /* Build the runtime check. */
6195 1.1 mrg argname = gfc_build_cstring_const (fsym->name);
6196 1.1 mrg argname = gfc_build_addr_expr (pchar_type_node, argname);
6197 1.1 mrg gfc_trans_runtime_check (true, false, cond, block, &fsym->declared_at,
6198 1.1 mrg message, argname,
6199 1.1 mrg fold_convert (long_integer_type_node,
6200 1.1 mrg cl->passed_length),
6201 1.1 mrg fold_convert (long_integer_type_node,
6202 1.1 mrg cl->backend_decl));
6203 1.1 mrg }
6204 1.1 mrg }
6205 1.1 mrg
6206 1.1 mrg
6207 1.1 mrg static void
6208 1.1 mrg create_main_function (tree fndecl)
6209 1.1 mrg {
6210 1.1 mrg tree old_context;
6211 1.1 mrg tree ftn_main;
6212 1.1 mrg tree tmp, decl, result_decl, argc, argv, typelist, arglist;
6213 1.1 mrg stmtblock_t body;
6214 1.1 mrg
6215 1.1 mrg old_context = current_function_decl;
6216 1.1 mrg
6217 1.1 mrg if (old_context)
6218 1.1 mrg {
6219 1.1 mrg push_function_context ();
6220 1.1 mrg saved_parent_function_decls = saved_function_decls;
6221 1.1 mrg saved_function_decls = NULL_TREE;
6222 1.1 mrg }
6223 1.1 mrg
6224 1.1 mrg /* main() function must be declared with global scope. */
6225 1.1 mrg gcc_assert (current_function_decl == NULL_TREE);
6226 1.1 mrg
6227 1.1 mrg /* Declare the function. */
6228 1.1 mrg tmp = build_function_type_list (integer_type_node, integer_type_node,
6229 1.1 mrg build_pointer_type (pchar_type_node),
6230 1.1 mrg NULL_TREE);
6231 1.1 mrg main_identifier_node = get_identifier ("main");
6232 1.1 mrg ftn_main = build_decl (input_location, FUNCTION_DECL,
6233 1.1 mrg main_identifier_node, tmp);
6234 1.1 mrg DECL_EXTERNAL (ftn_main) = 0;
6235 1.1 mrg TREE_PUBLIC (ftn_main) = 1;
6236 1.1 mrg TREE_STATIC (ftn_main) = 1;
6237 1.1 mrg DECL_ATTRIBUTES (ftn_main)
6238 1.1 mrg = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
6239 1.1 mrg
6240 1.1 mrg /* Setup the result declaration (for "return 0"). */
6241 1.1 mrg result_decl = build_decl (input_location,
6242 1.1 mrg RESULT_DECL, NULL_TREE, integer_type_node);
6243 1.1 mrg DECL_ARTIFICIAL (result_decl) = 1;
6244 1.1 mrg DECL_IGNORED_P (result_decl) = 1;
6245 1.1 mrg DECL_CONTEXT (result_decl) = ftn_main;
6246 1.1 mrg DECL_RESULT (ftn_main) = result_decl;
6247 1.1 mrg
6248 1.1 mrg pushdecl (ftn_main);
6249 1.1 mrg
6250 1.1 mrg /* Get the arguments. */
6251 1.1 mrg
6252 1.1 mrg arglist = NULL_TREE;
6253 1.1 mrg typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
6254 1.1 mrg
6255 1.1 mrg tmp = TREE_VALUE (typelist);
6256 1.1 mrg argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
6257 1.1 mrg DECL_CONTEXT (argc) = ftn_main;
6258 1.1 mrg DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
6259 1.1 mrg TREE_READONLY (argc) = 1;
6260 1.1 mrg gfc_finish_decl (argc);
6261 1.1 mrg arglist = chainon (arglist, argc);
6262 1.1 mrg
6263 1.1 mrg typelist = TREE_CHAIN (typelist);
6264 1.1 mrg tmp = TREE_VALUE (typelist);
6265 1.1 mrg argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
6266 1.1 mrg DECL_CONTEXT (argv) = ftn_main;
6267 1.1 mrg DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
6268 1.1 mrg TREE_READONLY (argv) = 1;
6269 1.1 mrg DECL_BY_REFERENCE (argv) = 1;
6270 1.1 mrg gfc_finish_decl (argv);
6271 1.1 mrg arglist = chainon (arglist, argv);
6272 1.1 mrg
6273 1.1 mrg DECL_ARGUMENTS (ftn_main) = arglist;
6274 1.1 mrg current_function_decl = ftn_main;
6275 1.1 mrg announce_function (ftn_main);
6276 1.1 mrg
6277 1.1 mrg rest_of_decl_compilation (ftn_main, 1, 0);
6278 1.1 mrg make_decl_rtl (ftn_main);
6279 1.1 mrg allocate_struct_function (ftn_main, false);
6280 1.1 mrg pushlevel ();
6281 1.1 mrg
6282 1.1 mrg gfc_init_block (&body);
6283 1.1 mrg
6284 1.1 mrg /* Call some libgfortran initialization routines, call then MAIN__(). */
6285 1.1 mrg
6286 1.1 mrg /* Call _gfortran_caf_init (*argc, ***argv). */
6287 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
6288 1.1 mrg {
6289 1.1 mrg tree pint_type, pppchar_type;
6290 1.1 mrg pint_type = build_pointer_type (integer_type_node);
6291 1.1 mrg pppchar_type
6292 1.1 mrg = build_pointer_type (build_pointer_type (pchar_type_node));
6293 1.1 mrg
6294 1.1 mrg tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_init, 2,
6295 1.1 mrg gfc_build_addr_expr (pint_type, argc),
6296 1.1 mrg gfc_build_addr_expr (pppchar_type, argv));
6297 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6298 1.1 mrg }
6299 1.1 mrg
6300 1.1 mrg /* Call _gfortran_set_args (argc, argv). */
6301 1.1 mrg TREE_USED (argc) = 1;
6302 1.1 mrg TREE_USED (argv) = 1;
6303 1.1 mrg tmp = build_call_expr_loc (input_location,
6304 1.1 mrg gfor_fndecl_set_args, 2, argc, argv);
6305 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6306 1.1 mrg
6307 1.1 mrg /* Add a call to set_options to set up the runtime library Fortran
6308 1.1 mrg language standard parameters. */
6309 1.1 mrg {
6310 1.1 mrg tree array_type, array, var;
6311 1.1 mrg vec<constructor_elt, va_gc> *v = NULL;
6312 1.1 mrg static const int noptions = 7;
6313 1.1 mrg
6314 1.1 mrg /* Passing a new option to the library requires three modifications:
6315 1.1 mrg + add it to the tree_cons list below
6316 1.1 mrg + change the noptions variable above
6317 1.1 mrg + modify the library (runtime/compile_options.c)! */
6318 1.1 mrg
6319 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6320 1.1 mrg build_int_cst (integer_type_node,
6321 1.1 mrg gfc_option.warn_std));
6322 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6323 1.1 mrg build_int_cst (integer_type_node,
6324 1.1 mrg gfc_option.allow_std));
6325 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6326 1.1 mrg build_int_cst (integer_type_node, pedantic));
6327 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6328 1.1 mrg build_int_cst (integer_type_node, flag_backtrace));
6329 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6330 1.1 mrg build_int_cst (integer_type_node, flag_sign_zero));
6331 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6332 1.1 mrg build_int_cst (integer_type_node,
6333 1.1 mrg (gfc_option.rtcheck
6334 1.1 mrg & GFC_RTCHECK_BOUNDS)));
6335 1.1 mrg CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6336 1.1 mrg build_int_cst (integer_type_node,
6337 1.1 mrg gfc_option.fpe_summary));
6338 1.1 mrg
6339 1.1 mrg array_type = build_array_type_nelts (integer_type_node, noptions);
6340 1.1 mrg array = build_constructor (array_type, v);
6341 1.1 mrg TREE_CONSTANT (array) = 1;
6342 1.1 mrg TREE_STATIC (array) = 1;
6343 1.1 mrg
6344 1.1 mrg /* Create a static variable to hold the jump table. */
6345 1.1 mrg var = build_decl (input_location, VAR_DECL,
6346 1.1 mrg create_tmp_var_name ("options"), array_type);
6347 1.1 mrg DECL_ARTIFICIAL (var) = 1;
6348 1.1 mrg DECL_IGNORED_P (var) = 1;
6349 1.1 mrg TREE_CONSTANT (var) = 1;
6350 1.1 mrg TREE_STATIC (var) = 1;
6351 1.1 mrg TREE_READONLY (var) = 1;
6352 1.1 mrg DECL_INITIAL (var) = array;
6353 1.1 mrg pushdecl (var);
6354 1.1 mrg var = gfc_build_addr_expr (build_pointer_type (integer_type_node), var);
6355 1.1 mrg
6356 1.1 mrg tmp = build_call_expr_loc (input_location,
6357 1.1 mrg gfor_fndecl_set_options, 2,
6358 1.1 mrg build_int_cst (integer_type_node, noptions), var);
6359 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6360 1.1 mrg }
6361 1.1 mrg
6362 1.1 mrg /* If -ffpe-trap option was provided, add a call to set_fpe so that
6363 1.1 mrg the library will raise a FPE when needed. */
6364 1.1 mrg if (gfc_option.fpe != 0)
6365 1.1 mrg {
6366 1.1 mrg tmp = build_call_expr_loc (input_location,
6367 1.1 mrg gfor_fndecl_set_fpe, 1,
6368 1.1 mrg build_int_cst (integer_type_node,
6369 1.1 mrg gfc_option.fpe));
6370 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6371 1.1 mrg }
6372 1.1 mrg
6373 1.1 mrg /* If this is the main program and an -fconvert option was provided,
6374 1.1 mrg add a call to set_convert. */
6375 1.1 mrg
6376 1.1 mrg if (flag_convert != GFC_FLAG_CONVERT_NATIVE)
6377 1.1 mrg {
6378 1.1 mrg tmp = build_call_expr_loc (input_location,
6379 1.1 mrg gfor_fndecl_set_convert, 1,
6380 1.1 mrg build_int_cst (integer_type_node, flag_convert));
6381 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6382 1.1 mrg }
6383 1.1 mrg
6384 1.1 mrg /* If this is the main program and an -frecord-marker option was provided,
6385 1.1 mrg add a call to set_record_marker. */
6386 1.1 mrg
6387 1.1 mrg if (flag_record_marker != 0)
6388 1.1 mrg {
6389 1.1 mrg tmp = build_call_expr_loc (input_location,
6390 1.1 mrg gfor_fndecl_set_record_marker, 1,
6391 1.1 mrg build_int_cst (integer_type_node,
6392 1.1 mrg flag_record_marker));
6393 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6394 1.1 mrg }
6395 1.1 mrg
6396 1.1 mrg if (flag_max_subrecord_length != 0)
6397 1.1 mrg {
6398 1.1 mrg tmp = build_call_expr_loc (input_location,
6399 1.1 mrg gfor_fndecl_set_max_subrecord_length, 1,
6400 1.1 mrg build_int_cst (integer_type_node,
6401 1.1 mrg flag_max_subrecord_length));
6402 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6403 1.1 mrg }
6404 1.1 mrg
6405 1.1 mrg /* Call MAIN__(). */
6406 1.1 mrg tmp = build_call_expr_loc (input_location,
6407 1.1 mrg fndecl, 0);
6408 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6409 1.1 mrg
6410 1.1 mrg /* Mark MAIN__ as used. */
6411 1.1 mrg TREE_USED (fndecl) = 1;
6412 1.1 mrg
6413 1.1 mrg /* Coarray: Call _gfortran_caf_finalize(void). */
6414 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB)
6415 1.1 mrg {
6416 1.1 mrg tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_finalize, 0);
6417 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6418 1.1 mrg }
6419 1.1 mrg
6420 1.1 mrg /* "return 0". */
6421 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, integer_type_node,
6422 1.1 mrg DECL_RESULT (ftn_main),
6423 1.1 mrg build_int_cst (integer_type_node, 0));
6424 1.1 mrg tmp = build1_v (RETURN_EXPR, tmp);
6425 1.1 mrg gfc_add_expr_to_block (&body, tmp);
6426 1.1 mrg
6427 1.1 mrg
6428 1.1 mrg DECL_SAVED_TREE (ftn_main) = gfc_finish_block (&body);
6429 1.1 mrg decl = getdecls ();
6430 1.1 mrg
6431 1.1 mrg /* Finish off this function and send it for code generation. */
6432 1.1 mrg poplevel (1, 1);
6433 1.1 mrg BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main;
6434 1.1 mrg
6435 1.1 mrg DECL_SAVED_TREE (ftn_main)
6436 1.1 mrg = fold_build3_loc (DECL_SOURCE_LOCATION (ftn_main), BIND_EXPR,
6437 1.1 mrg void_type_node, decl, DECL_SAVED_TREE (ftn_main),
6438 1.1 mrg DECL_INITIAL (ftn_main));
6439 1.1 mrg
6440 1.1 mrg /* Output the GENERIC tree. */
6441 1.1 mrg dump_function (TDI_original, ftn_main);
6442 1.1 mrg
6443 1.1 mrg cgraph_node::finalize_function (ftn_main, true);
6444 1.1 mrg
6445 1.1 mrg if (old_context)
6446 1.1 mrg {
6447 1.1 mrg pop_function_context ();
6448 1.1 mrg saved_function_decls = saved_parent_function_decls;
6449 1.1 mrg }
6450 1.1 mrg current_function_decl = old_context;
6451 1.1 mrg }
6452 1.1 mrg
6453 1.1 mrg
6454 1.1 mrg /* Generate an appropriate return-statement for a procedure. */
6455 1.1 mrg
6456 1.1 mrg tree
6457 1.1 mrg gfc_generate_return (void)
6458 1.1 mrg {
6459 1.1 mrg gfc_symbol* sym;
6460 1.1 mrg tree result;
6461 1.1 mrg tree fndecl;
6462 1.1 mrg
6463 1.1 mrg sym = current_procedure_symbol;
6464 1.1 mrg fndecl = sym->backend_decl;
6465 1.1 mrg
6466 1.1 mrg if (TREE_TYPE (DECL_RESULT (fndecl)) == void_type_node)
6467 1.1 mrg result = NULL_TREE;
6468 1.1 mrg else
6469 1.1 mrg {
6470 1.1 mrg result = get_proc_result (sym);
6471 1.1 mrg
6472 1.1 mrg /* Set the return value to the dummy result variable. The
6473 1.1 mrg types may be different for scalar default REAL functions
6474 1.1 mrg with -ff2c, therefore we have to convert. */
6475 1.1 mrg if (result != NULL_TREE)
6476 1.1 mrg {
6477 1.1 mrg result = convert (TREE_TYPE (DECL_RESULT (fndecl)), result);
6478 1.1 mrg result = fold_build2_loc (input_location, MODIFY_EXPR,
6479 1.1 mrg TREE_TYPE (result), DECL_RESULT (fndecl),
6480 1.1 mrg result);
6481 1.1 mrg }
6482 1.1 mrg else
6483 1.1 mrg {
6484 1.1 mrg /* If the function does not have a result variable, result is
6485 1.1 mrg NULL_TREE, and a 'return' is generated without a variable.
6486 1.1 mrg The following generates a 'return __result_XXX' where XXX is
6487 1.1 mrg the function name. */
6488 1.1 mrg if (sym == sym->result && sym->attr.function && !flag_f2c)
6489 1.1 mrg {
6490 1.1 mrg result = gfc_get_fake_result_decl (sym, 0);
6491 1.1 mrg result = fold_build2_loc (input_location, MODIFY_EXPR,
6492 1.1 mrg TREE_TYPE (result),
6493 1.1 mrg DECL_RESULT (fndecl), result);
6494 1.1 mrg }
6495 1.1 mrg }
6496 1.1 mrg }
6497 1.1 mrg
6498 1.1 mrg return build1_v (RETURN_EXPR, result);
6499 1.1 mrg }
6500 1.1 mrg
6501 1.1 mrg
6502 1.1 mrg static void
6503 1.1 mrg is_from_ieee_module (gfc_symbol *sym)
6504 1.1 mrg {
6505 1.1 mrg if (sym->from_intmod == INTMOD_IEEE_FEATURES
6506 1.1 mrg || sym->from_intmod == INTMOD_IEEE_EXCEPTIONS
6507 1.1 mrg || sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
6508 1.1 mrg seen_ieee_symbol = 1;
6509 1.1 mrg }
6510 1.1 mrg
6511 1.1 mrg
6512 1.1 mrg static int
6513 1.1 mrg is_ieee_module_used (gfc_namespace *ns)
6514 1.1 mrg {
6515 1.1 mrg seen_ieee_symbol = 0;
6516 1.1 mrg gfc_traverse_ns (ns, is_from_ieee_module);
6517 1.1 mrg return seen_ieee_symbol;
6518 1.1 mrg }
6519 1.1 mrg
6520 1.1 mrg
6521 1.1 mrg static gfc_omp_clauses *module_oacc_clauses;
6522 1.1 mrg
6523 1.1 mrg
6524 1.1 mrg static void
6525 1.1 mrg add_clause (gfc_symbol *sym, gfc_omp_map_op map_op)
6526 1.1 mrg {
6527 1.1 mrg gfc_omp_namelist *n;
6528 1.1 mrg
6529 1.1 mrg n = gfc_get_omp_namelist ();
6530 1.1 mrg n->sym = sym;
6531 1.1 mrg n->u.map_op = map_op;
6532 1.1 mrg
6533 1.1 mrg if (!module_oacc_clauses)
6534 1.1 mrg module_oacc_clauses = gfc_get_omp_clauses ();
6535 1.1 mrg
6536 1.1 mrg if (module_oacc_clauses->lists[OMP_LIST_MAP])
6537 1.1 mrg n->next = module_oacc_clauses->lists[OMP_LIST_MAP];
6538 1.1 mrg
6539 1.1 mrg module_oacc_clauses->lists[OMP_LIST_MAP] = n;
6540 1.1 mrg }
6541 1.1 mrg
6542 1.1 mrg
6543 1.1 mrg static void
6544 1.1 mrg find_module_oacc_declare_clauses (gfc_symbol *sym)
6545 1.1 mrg {
6546 1.1 mrg if (sym->attr.use_assoc)
6547 1.1 mrg {
6548 1.1 mrg gfc_omp_map_op map_op;
6549 1.1 mrg
6550 1.1 mrg if (sym->attr.oacc_declare_create)
6551 1.1 mrg map_op = OMP_MAP_FORCE_ALLOC;
6552 1.1 mrg
6553 1.1 mrg if (sym->attr.oacc_declare_copyin)
6554 1.1 mrg map_op = OMP_MAP_FORCE_TO;
6555 1.1 mrg
6556 1.1 mrg if (sym->attr.oacc_declare_deviceptr)
6557 1.1 mrg map_op = OMP_MAP_FORCE_DEVICEPTR;
6558 1.1 mrg
6559 1.1 mrg if (sym->attr.oacc_declare_device_resident)
6560 1.1 mrg map_op = OMP_MAP_DEVICE_RESIDENT;
6561 1.1 mrg
6562 1.1 mrg if (sym->attr.oacc_declare_create
6563 1.1 mrg || sym->attr.oacc_declare_copyin
6564 1.1 mrg || sym->attr.oacc_declare_deviceptr
6565 1.1 mrg || sym->attr.oacc_declare_device_resident)
6566 1.1 mrg {
6567 1.1 mrg sym->attr.referenced = 1;
6568 1.1 mrg add_clause (sym, map_op);
6569 1.1 mrg }
6570 1.1 mrg }
6571 1.1 mrg }
6572 1.1 mrg
6573 1.1 mrg
6574 1.1 mrg void
6575 1.1 mrg finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
6576 1.1 mrg {
6577 1.1 mrg gfc_code *code;
6578 1.1 mrg gfc_oacc_declare *oc;
6579 1.1 mrg locus where = gfc_current_locus;
6580 1.1 mrg gfc_omp_clauses *omp_clauses = NULL;
6581 1.1 mrg gfc_omp_namelist *n, *p;
6582 1.1 mrg
6583 1.1 mrg module_oacc_clauses = NULL;
6584 1.1 mrg gfc_traverse_ns (ns, find_module_oacc_declare_clauses);
6585 1.1 mrg
6586 1.1 mrg if (module_oacc_clauses && sym->attr.flavor == FL_PROGRAM)
6587 1.1 mrg {
6588 1.1 mrg gfc_oacc_declare *new_oc;
6589 1.1 mrg
6590 1.1 mrg new_oc = gfc_get_oacc_declare ();
6591 1.1 mrg new_oc->next = ns->oacc_declare;
6592 1.1 mrg new_oc->clauses = module_oacc_clauses;
6593 1.1 mrg
6594 1.1 mrg ns->oacc_declare = new_oc;
6595 1.1 mrg }
6596 1.1 mrg
6597 1.1 mrg if (!ns->oacc_declare)
6598 1.1 mrg return;
6599 1.1 mrg
6600 1.1 mrg for (oc = ns->oacc_declare; oc; oc = oc->next)
6601 1.1 mrg {
6602 1.1 mrg if (oc->module_var)
6603 1.1 mrg continue;
6604 1.1 mrg
6605 1.1 mrg if (block)
6606 1.1 mrg gfc_error ("Sorry, !$ACC DECLARE at %L is not allowed "
6607 1.1 mrg "in BLOCK construct", &oc->loc);
6608 1.1 mrg
6609 1.1 mrg
6610 1.1 mrg if (oc->clauses && oc->clauses->lists[OMP_LIST_MAP])
6611 1.1 mrg {
6612 1.1 mrg if (omp_clauses == NULL)
6613 1.1 mrg {
6614 1.1 mrg omp_clauses = oc->clauses;
6615 1.1 mrg continue;
6616 1.1 mrg }
6617 1.1 mrg
6618 1.1 mrg for (n = oc->clauses->lists[OMP_LIST_MAP]; n; p = n, n = n->next)
6619 1.1 mrg ;
6620 1.1 mrg
6621 1.1 mrg gcc_assert (p->next == NULL);
6622 1.1 mrg
6623 1.1 mrg p->next = omp_clauses->lists[OMP_LIST_MAP];
6624 1.1 mrg omp_clauses = oc->clauses;
6625 1.1 mrg }
6626 1.1 mrg }
6627 1.1 mrg
6628 1.1 mrg if (!omp_clauses)
6629 1.1 mrg return;
6630 1.1 mrg
6631 1.1 mrg for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
6632 1.1 mrg {
6633 1.1 mrg switch (n->u.map_op)
6634 1.1 mrg {
6635 1.1 mrg case OMP_MAP_DEVICE_RESIDENT:
6636 1.1 mrg n->u.map_op = OMP_MAP_FORCE_ALLOC;
6637 1.1 mrg break;
6638 1.1 mrg
6639 1.1 mrg default:
6640 1.1 mrg break;
6641 1.1 mrg }
6642 1.1 mrg }
6643 1.1 mrg
6644 1.1 mrg code = XCNEW (gfc_code);
6645 1.1 mrg code->op = EXEC_OACC_DECLARE;
6646 1.1 mrg code->loc = where;
6647 1.1 mrg
6648 1.1 mrg code->ext.oacc_declare = gfc_get_oacc_declare ();
6649 1.1 mrg code->ext.oacc_declare->clauses = omp_clauses;
6650 1.1 mrg
6651 1.1 mrg code->block = XCNEW (gfc_code);
6652 1.1 mrg code->block->op = EXEC_OACC_DECLARE;
6653 1.1 mrg code->block->loc = where;
6654 1.1 mrg
6655 1.1 mrg if (ns->code)
6656 1.1 mrg code->block->next = ns->code;
6657 1.1 mrg
6658 1.1 mrg ns->code = code;
6659 1.1 mrg
6660 1.1 mrg return;
6661 1.1 mrg }
6662 1.1 mrg
6663 1.1 mrg static void
6664 1.1 mrg gfc_conv_cfi_to_gfc (stmtblock_t *init, stmtblock_t *finally,
6665 1.1 mrg tree cfi_desc, tree gfc_desc, gfc_symbol *sym)
6666 1.1 mrg {
6667 1.1 mrg stmtblock_t block;
6668 1.1 mrg gfc_init_block (&block);
6669 1.1 mrg tree cfi = build_fold_indirect_ref_loc (input_location, cfi_desc);
6670 1.1 mrg tree idx, etype, tmp, tmp2, size_var = NULL_TREE, rank = NULL_TREE;
6671 1.1 mrg bool do_copy_inout = false;
6672 1.1 mrg
6673 1.1 mrg /* When allocatable + intent out, free the cfi descriptor. */
6674 1.1 mrg if (sym->attr.allocatable && sym->attr.intent == INTENT_OUT)
6675 1.1 mrg {
6676 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
6677 1.1 mrg tree call = builtin_decl_explicit (BUILT_IN_FREE);
6678 1.1 mrg call = build_call_expr_loc (input_location, call, 1, tmp);
6679 1.1 mrg gfc_add_expr_to_block (&block, fold_convert (void_type_node, call));
6680 1.1 mrg gfc_add_modify (&block, tmp,
6681 1.1 mrg fold_convert (TREE_TYPE (tmp), null_pointer_node));
6682 1.1 mrg }
6683 1.1 mrg
6684 1.1 mrg /* -fcheck=bound: Do version, rank, attribute, type and is-NULL checks. */
6685 1.1 mrg if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
6686 1.1 mrg {
6687 1.1 mrg char *msg;
6688 1.1 mrg tree tmp3;
6689 1.1 mrg msg = xasprintf ("Unexpected version %%d (expected %d) in CFI descriptor "
6690 1.1 mrg "passed to dummy argument %s", CFI_VERSION, sym->name);
6691 1.1 mrg tmp2 = gfc_get_cfi_desc_version (cfi);
6692 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp2,
6693 1.1 mrg build_int_cst (TREE_TYPE (tmp2), CFI_VERSION));
6694 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6695 1.1 mrg msg, tmp2);
6696 1.1 mrg free (msg);
6697 1.1 mrg
6698 1.1 mrg /* Rank check; however, for character(len=*), assumed/explicit-size arrays
6699 1.1 mrg are permitted to differ in rank according to the Fortran rules. */
6700 1.1 mrg if (sym->as && sym->as->type != AS_ASSUMED_SIZE
6701 1.1 mrg && sym->as->type != AS_EXPLICIT)
6702 1.1 mrg {
6703 1.1 mrg if (sym->as->rank != -1)
6704 1.1 mrg msg = xasprintf ("Invalid rank %%d (expected %d) in CFI descriptor "
6705 1.1 mrg "passed to dummy argument %s", sym->as->rank,
6706 1.1 mrg sym->name);
6707 1.1 mrg else
6708 1.1 mrg msg = xasprintf ("Invalid rank %%d (expected 0..%d) in CFI "
6709 1.1 mrg "descriptor passed to dummy argument %s",
6710 1.1 mrg CFI_MAX_RANK, sym->name);
6711 1.1 mrg
6712 1.1 mrg tmp3 = tmp2 = tmp = gfc_get_cfi_desc_rank (cfi);
6713 1.1 mrg if (sym->as->rank != -1)
6714 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6715 1.1 mrg tmp, build_int_cst (signed_char_type_node,
6716 1.1 mrg sym->as->rank));
6717 1.1 mrg else
6718 1.1 mrg {
6719 1.1 mrg tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
6720 1.1 mrg tmp, build_zero_cst (TREE_TYPE (tmp)));
6721 1.1 mrg tmp2 = fold_build2_loc (input_location, GT_EXPR,
6722 1.1 mrg boolean_type_node, tmp2,
6723 1.1 mrg build_int_cst (TREE_TYPE (tmp2),
6724 1.1 mrg CFI_MAX_RANK));
6725 1.1 mrg tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6726 1.1 mrg boolean_type_node, tmp, tmp2);
6727 1.1 mrg }
6728 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6729 1.1 mrg msg, tmp3);
6730 1.1 mrg free (msg);
6731 1.1 mrg }
6732 1.1 mrg
6733 1.1 mrg tmp3 = tmp = gfc_get_cfi_desc_attribute (cfi);
6734 1.1 mrg if (sym->attr.allocatable || sym->attr.pointer)
6735 1.1 mrg {
6736 1.1 mrg int attr = (sym->attr.pointer ? CFI_attribute_pointer
6737 1.1 mrg : CFI_attribute_allocatable);
6738 1.1 mrg msg = xasprintf ("Invalid attribute %%d (expected %d) in CFI "
6739 1.1 mrg "descriptor passed to dummy argument %s with %s "
6740 1.1 mrg "attribute", attr, sym->name,
6741 1.1 mrg sym->attr.pointer ? "pointer" : "allocatable");
6742 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6743 1.1 mrg tmp, build_int_cst (TREE_TYPE (tmp), attr));
6744 1.1 mrg }
6745 1.1 mrg else
6746 1.1 mrg {
6747 1.1 mrg int amin = MIN (CFI_attribute_pointer,
6748 1.1 mrg MIN (CFI_attribute_allocatable, CFI_attribute_other));
6749 1.1 mrg int amax = MAX (CFI_attribute_pointer,
6750 1.1 mrg MAX (CFI_attribute_allocatable, CFI_attribute_other));
6751 1.1 mrg msg = xasprintf ("Invalid attribute %%d (expected %d..%d) in CFI "
6752 1.1 mrg "descriptor passed to nonallocatable, nonpointer "
6753 1.1 mrg "dummy argument %s", amin, amax, sym->name);
6754 1.1 mrg tmp2 = tmp;
6755 1.1 mrg tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, tmp,
6756 1.1 mrg build_int_cst (TREE_TYPE (tmp), amin));
6757 1.1 mrg tmp2 = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, tmp2,
6758 1.1 mrg build_int_cst (TREE_TYPE (tmp2), amax));
6759 1.1 mrg tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR,
6760 1.1 mrg boolean_type_node, tmp, tmp2);
6761 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6762 1.1 mrg msg, tmp3);
6763 1.1 mrg free (msg);
6764 1.1 mrg msg = xasprintf ("Invalid unallocatated/unassociated CFI "
6765 1.1 mrg "descriptor passed to nonallocatable, nonpointer "
6766 1.1 mrg "dummy argument %s", sym->name);
6767 1.1 mrg tmp3 = tmp = gfc_get_cfi_desc_base_addr (cfi),
6768 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
6769 1.1 mrg tmp, null_pointer_node);
6770 1.1 mrg }
6771 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6772 1.1 mrg msg, tmp3);
6773 1.1 mrg free (msg);
6774 1.1 mrg
6775 1.1 mrg if (sym->ts.type != BT_ASSUMED)
6776 1.1 mrg {
6777 1.1 mrg int type = CFI_type_other;
6778 1.1 mrg if (sym->ts.f90_type == BT_VOID)
6779 1.1 mrg {
6780 1.1 mrg type = (sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
6781 1.1 mrg ? CFI_type_cfunptr : CFI_type_cptr);
6782 1.1 mrg }
6783 1.1 mrg else
6784 1.1 mrg switch (sym->ts.type)
6785 1.1 mrg {
6786 1.1 mrg case BT_INTEGER:
6787 1.1 mrg case BT_LOGICAL:
6788 1.1 mrg case BT_REAL:
6789 1.1 mrg case BT_COMPLEX:
6790 1.1 mrg type = CFI_type_from_type_kind (sym->ts.type, sym->ts.kind);
6791 1.1 mrg break;
6792 1.1 mrg case BT_CHARACTER:
6793 1.1 mrg type = CFI_type_from_type_kind (CFI_type_Character,
6794 1.1 mrg sym->ts.kind);
6795 1.1 mrg break;
6796 1.1 mrg case BT_DERIVED:
6797 1.1 mrg type = CFI_type_struct;
6798 1.1 mrg break;
6799 1.1 mrg case BT_VOID:
6800 1.1 mrg type = (sym->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR
6801 1.1 mrg ? CFI_type_cfunptr : CFI_type_cptr);
6802 1.1 mrg break;
6803 1.1 mrg case BT_ASSUMED:
6804 1.1 mrg case BT_CLASS:
6805 1.1 mrg case BT_PROCEDURE:
6806 1.1 mrg case BT_HOLLERITH:
6807 1.1 mrg case BT_UNION:
6808 1.1 mrg case BT_BOZ:
6809 1.1 mrg case BT_UNKNOWN:
6810 1.1 mrg gcc_unreachable ();
6811 1.1 mrg }
6812 1.1 mrg msg = xasprintf ("Unexpected type %%d (expected %d) in CFI descriptor"
6813 1.1 mrg " passed to dummy argument %s", type, sym->name);
6814 1.1 mrg tmp2 = tmp = gfc_get_cfi_desc_type (cfi);
6815 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6816 1.1 mrg tmp, build_int_cst (TREE_TYPE (tmp), type));
6817 1.1 mrg gfc_trans_runtime_check (true, false, tmp, &block, &sym->declared_at,
6818 1.1 mrg msg, tmp2);
6819 1.1 mrg free (msg);
6820 1.1 mrg }
6821 1.1 mrg }
6822 1.1 mrg
6823 1.1 mrg if (!sym->attr.referenced)
6824 1.1 mrg goto done;
6825 1.1 mrg
6826 1.1 mrg /* Set string length for len=* and len=:, otherwise, it is already set. */
6827 1.1 mrg if (sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length)
6828 1.1 mrg {
6829 1.1 mrg tmp = fold_convert (gfc_array_index_type,
6830 1.1 mrg gfc_get_cfi_desc_elem_len (cfi));
6831 1.1 mrg if (sym->ts.kind != 1)
6832 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
6833 1.1 mrg gfc_array_index_type, tmp,
6834 1.1 mrg build_int_cst (gfc_charlen_type_node,
6835 1.1 mrg sym->ts.kind));
6836 1.1 mrg gfc_add_modify (&block, sym->ts.u.cl->backend_decl, tmp);
6837 1.1 mrg }
6838 1.1 mrg
6839 1.1 mrg if (sym->ts.type == BT_CHARACTER
6840 1.1 mrg && !INTEGER_CST_P (sym->ts.u.cl->backend_decl))
6841 1.1 mrg {
6842 1.1 mrg gfc_conv_string_length (sym->ts.u.cl, NULL, init);
6843 1.1 mrg gfc_trans_vla_type_sizes (sym, init);
6844 1.1 mrg }
6845 1.1 mrg
6846 1.1 mrg /* gfc->data = cfi->base_addr - or for scalars: gfc = cfi->base_addr.
6847 1.1 mrg assumed-size/explicit-size arrays end up here for character(len=*)
6848 1.1 mrg only. */
6849 1.1 mrg if (!sym->attr.dimension || !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
6850 1.1 mrg {
6851 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
6852 1.1 mrg gfc_add_modify (&block, gfc_desc,
6853 1.1 mrg fold_convert (TREE_TYPE (gfc_desc), tmp));
6854 1.1 mrg if (!sym->attr.dimension)
6855 1.1 mrg goto done;
6856 1.1 mrg }
6857 1.1 mrg
6858 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
6859 1.1 mrg {
6860 1.1 mrg /* gfc->dtype = ... (from declaration, not from cfi). */
6861 1.1 mrg etype = gfc_get_element_type (TREE_TYPE (gfc_desc));
6862 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_dtype (gfc_desc),
6863 1.1 mrg gfc_get_dtype_rank_type (sym->as->rank, etype));
6864 1.1 mrg /* gfc->data = cfi->base_addr. */
6865 1.1 mrg gfc_conv_descriptor_data_set (&block, gfc_desc,
6866 1.1 mrg gfc_get_cfi_desc_base_addr (cfi));
6867 1.1 mrg }
6868 1.1 mrg
6869 1.1 mrg if (sym->ts.type == BT_ASSUMED)
6870 1.1 mrg {
6871 1.1 mrg /* For type(*), take elem_len + dtype.type from the actual argument. */
6872 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_elem_len (gfc_desc),
6873 1.1 mrg gfc_get_cfi_desc_elem_len (cfi));
6874 1.1 mrg tree cond;
6875 1.1 mrg tree ctype = gfc_get_cfi_desc_type (cfi);
6876 1.1 mrg ctype = fold_build2_loc (input_location, BIT_AND_EXPR, TREE_TYPE (ctype),
6877 1.1 mrg ctype, build_int_cst (TREE_TYPE (ctype),
6878 1.1 mrg CFI_type_mask));
6879 1.1 mrg tree type = gfc_conv_descriptor_type (gfc_desc);
6880 1.1 mrg
6881 1.1 mrg /* if (CFI_type_cptr) BT_VOID else BT_UNKNOWN */
6882 1.1 mrg /* Note: BT_VOID is could also be CFI_type_funcptr, but assume c_ptr. */
6883 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6884 1.1 mrg build_int_cst (TREE_TYPE (ctype), CFI_type_cptr));
6885 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
6886 1.1 mrg build_int_cst (TREE_TYPE (type), BT_VOID));
6887 1.1 mrg tmp2 = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6888 1.1 mrg type,
6889 1.1 mrg build_int_cst (TREE_TYPE (type), BT_UNKNOWN));
6890 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6891 1.1 mrg tmp, tmp2);
6892 1.1 mrg /* if (CFI_type_struct) BT_DERIVED else < tmp2 > */
6893 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6894 1.1 mrg build_int_cst (TREE_TYPE (ctype),
6895 1.1 mrg CFI_type_struct));
6896 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
6897 1.1 mrg build_int_cst (TREE_TYPE (type), BT_DERIVED));
6898 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6899 1.1 mrg tmp, tmp2);
6900 1.1 mrg /* if (CFI_type_Character) BT_CHARACTER else < tmp2 > */
6901 1.1 mrg /* Note: this is kind=1, CFI_type_ucs4_char is handled in the 'else if'
6902 1.1 mrg before (see below, as generated bottom up). */
6903 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6904 1.1 mrg build_int_cst (TREE_TYPE (ctype),
6905 1.1 mrg CFI_type_Character));
6906 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
6907 1.1 mrg build_int_cst (TREE_TYPE (type), BT_CHARACTER));
6908 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6909 1.1 mrg tmp, tmp2);
6910 1.1 mrg /* if (CFI_type_ucs4_char) BT_CHARACTER else < tmp2 > */
6911 1.1 mrg /* Note: gfc->elem_len = cfi->elem_len/4. */
6912 1.1 mrg /* However, assuming that CFI_type_ucs4_char cannot be recovered, leave
6913 1.1 mrg gfc->elem_len == cfi->elem_len, which helps with operations which use
6914 1.1 mrg sizeof() in Fortran and cfi->elem_len in C. */
6915 1.1 mrg tmp = gfc_get_cfi_desc_type (cfi);
6916 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, tmp,
6917 1.1 mrg build_int_cst (TREE_TYPE (tmp),
6918 1.1 mrg CFI_type_ucs4_char));
6919 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
6920 1.1 mrg build_int_cst (TREE_TYPE (type), BT_CHARACTER));
6921 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6922 1.1 mrg tmp, tmp2);
6923 1.1 mrg /* if (CFI_type_Complex) BT_COMPLEX + cfi->elem_len/2 else < tmp2 > */
6924 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6925 1.1 mrg build_int_cst (TREE_TYPE (ctype),
6926 1.1 mrg CFI_type_Complex));
6927 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node, type,
6928 1.1 mrg build_int_cst (TREE_TYPE (type), BT_COMPLEX));
6929 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6930 1.1 mrg tmp, tmp2);
6931 1.1 mrg /* if (CFI_type_Integer || CFI_type_Logical || CFI_type_Real)
6932 1.1 mrg ctype else <tmp2> */
6933 1.1 mrg cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6934 1.1 mrg build_int_cst (TREE_TYPE (ctype),
6935 1.1 mrg CFI_type_Integer));
6936 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6937 1.1 mrg build_int_cst (TREE_TYPE (ctype),
6938 1.1 mrg CFI_type_Logical));
6939 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
6940 1.1 mrg cond, tmp);
6941 1.1 mrg tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, ctype,
6942 1.1 mrg build_int_cst (TREE_TYPE (ctype),
6943 1.1 mrg CFI_type_Real));
6944 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
6945 1.1 mrg cond, tmp);
6946 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6947 1.1 mrg type, fold_convert (TREE_TYPE (type), ctype));
6948 1.1 mrg tmp2 = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
6949 1.1 mrg tmp, tmp2);
6950 1.1 mrg gfc_add_expr_to_block (&block, tmp2);
6951 1.1 mrg }
6952 1.1 mrg
6953 1.1 mrg if (sym->as->rank < 0)
6954 1.1 mrg {
6955 1.1 mrg /* Set gfc->dtype.rank, if assumed-rank. */
6956 1.1 mrg rank = gfc_get_cfi_desc_rank (cfi);
6957 1.1 mrg gfc_add_modify (&block, gfc_conv_descriptor_rank (gfc_desc), rank);
6958 1.1 mrg }
6959 1.1 mrg else if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
6960 1.1 mrg /* In that case, the CFI rank and the declared rank can differ. */
6961 1.1 mrg rank = gfc_get_cfi_desc_rank (cfi);
6962 1.1 mrg else
6963 1.1 mrg rank = build_int_cst (signed_char_type_node, sym->as->rank);
6964 1.1 mrg
6965 1.1 mrg /* With bind(C), the standard requires that both Fortran callers and callees
6966 1.1 mrg handle noncontiguous arrays passed to an dummy with 'contiguous' attribute
6967 1.1 mrg and with character(len=*) + assumed-size/explicit-size arrays.
6968 1.1 mrg cf. Fortran 2018, 18.3.6, paragraph 5 (and for the caller: para. 6). */
6969 1.1 mrg if ((sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length
6970 1.1 mrg && (sym->as->type == AS_ASSUMED_SIZE || sym->as->type == AS_EXPLICIT))
6971 1.1 mrg || sym->attr.contiguous)
6972 1.1 mrg {
6973 1.1 mrg do_copy_inout = true;
6974 1.1 mrg gcc_assert (!sym->attr.pointer);
6975 1.1 mrg stmtblock_t block2;
6976 1.1 mrg tree data;
6977 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
6978 1.1 mrg data = gfc_conv_descriptor_data_get (gfc_desc);
6979 1.1 mrg else if (!POINTER_TYPE_P (TREE_TYPE (gfc_desc)))
6980 1.1 mrg data = gfc_build_addr_expr (NULL, gfc_desc);
6981 1.1 mrg else
6982 1.1 mrg data = gfc_desc;
6983 1.1 mrg
6984 1.1 mrg /* Is copy-in/out needed? */
6985 1.1 mrg /* do_copyin = rank != 0 && !assumed-size */
6986 1.1 mrg tree cond_var = gfc_create_var (boolean_type_node, "do_copyin");
6987 1.1 mrg tree cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6988 1.1 mrg rank, build_zero_cst (TREE_TYPE (rank)));
6989 1.1 mrg /* dim[rank-1].extent != -1 -> assumed size*/
6990 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (rank),
6991 1.1 mrg rank, build_int_cst (TREE_TYPE (rank), 1));
6992 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6993 1.1 mrg gfc_get_cfi_dim_extent (cfi, tmp),
6994 1.1 mrg build_int_cst (gfc_array_index_type, -1));
6995 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
6996 1.1 mrg boolean_type_node, cond, tmp);
6997 1.1 mrg gfc_add_modify (&block, cond_var, cond);
6998 1.1 mrg /* if (do_copyin) do_copyin = ... || ... || ... */
6999 1.1 mrg gfc_init_block (&block2);
7000 1.1 mrg /* dim[0].sm != elem_len */
7001 1.1 mrg tmp = fold_convert (gfc_array_index_type,
7002 1.1 mrg gfc_get_cfi_desc_elem_len (cfi));
7003 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7004 1.1 mrg gfc_get_cfi_dim_sm (cfi, gfc_index_zero_node),
7005 1.1 mrg tmp);
7006 1.1 mrg gfc_add_modify (&block2, cond_var, cond);
7007 1.1 mrg
7008 1.1 mrg /* for (i = 1; i < rank; ++i)
7009 1.1 mrg cond &&= dim[i].sm != (dv->dim[i - 1].sm * dv->dim[i - 1].extent) */
7010 1.1 mrg idx = gfc_create_var (TREE_TYPE (rank), "idx");
7011 1.1 mrg stmtblock_t loop_body;
7012 1.1 mrg gfc_init_block (&loop_body);
7013 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
7014 1.1 mrg idx, build_int_cst (TREE_TYPE (idx), 1));
7015 1.1 mrg tree tmp2 = gfc_get_cfi_dim_sm (cfi, tmp);
7016 1.1 mrg tmp = gfc_get_cfi_dim_extent (cfi, tmp);
7017 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
7018 1.1 mrg tmp2, tmp);
7019 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7020 1.1 mrg gfc_get_cfi_dim_sm (cfi, idx), tmp);
7021 1.1 mrg cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
7022 1.1 mrg cond_var, cond);
7023 1.1 mrg gfc_add_modify (&loop_body, cond_var, cond);
7024 1.1 mrg gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 1),
7025 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7026 1.1 mrg gfc_finish_block (&loop_body));
7027 1.1 mrg tmp = build3_v (COND_EXPR, cond_var, gfc_finish_block (&block2),
7028 1.1 mrg build_empty_stmt (input_location));
7029 1.1 mrg gfc_add_expr_to_block (&block, tmp);
7030 1.1 mrg
7031 1.1 mrg /* Copy-in body. */
7032 1.1 mrg gfc_init_block (&block2);
7033 1.1 mrg /* size = dim[0].extent; for (i = 1; i < rank; ++i) size *= dim[i].extent */
7034 1.1 mrg size_var = gfc_create_var (size_type_node, "size");
7035 1.1 mrg tmp = fold_convert (size_type_node,
7036 1.1 mrg gfc_get_cfi_dim_extent (cfi, gfc_index_zero_node));
7037 1.1 mrg gfc_add_modify (&block2, size_var, tmp);
7038 1.1 mrg
7039 1.1 mrg gfc_init_block (&loop_body);
7040 1.1 mrg tmp = fold_convert (size_type_node,
7041 1.1 mrg gfc_get_cfi_dim_extent (cfi, idx));
7042 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7043 1.1 mrg size_var, fold_convert (size_type_node, tmp));
7044 1.1 mrg gfc_add_modify (&loop_body, size_var, tmp);
7045 1.1 mrg gfc_simple_for_loop (&block2, idx, build_int_cst (TREE_TYPE (idx), 1),
7046 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7047 1.1 mrg gfc_finish_block (&loop_body));
7048 1.1 mrg /* data = malloc (size * elem_len) */
7049 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7050 1.1 mrg size_var, gfc_get_cfi_desc_elem_len (cfi));
7051 1.1 mrg tree call = builtin_decl_explicit (BUILT_IN_MALLOC);
7052 1.1 mrg call = build_call_expr_loc (input_location, call, 1, tmp);
7053 1.1 mrg gfc_add_modify (&block2, data, fold_convert (TREE_TYPE (data), call));
7054 1.1 mrg
7055 1.1 mrg /* Copy the data:
7056 1.1 mrg for (idx = 0; idx < size; ++idx)
7057 1.1 mrg {
7058 1.1 mrg shift = 0;
7059 1.1 mrg tmpidx = idx
7060 1.1 mrg for (dim = 0; dim < rank; ++dim)
7061 1.1 mrg {
7062 1.1 mrg shift += (tmpidx % extent[d]) * sm[d]
7063 1.1 mrg tmpidx = tmpidx / extend[d]
7064 1.1 mrg }
7065 1.1 mrg memcpy (lhs + idx*elem_len, rhs + shift, elem_len)
7066 1.1 mrg } .*/
7067 1.1 mrg idx = gfc_create_var (size_type_node, "arrayidx");
7068 1.1 mrg gfc_init_block (&loop_body);
7069 1.1 mrg tree shift = gfc_create_var (size_type_node, "shift");
7070 1.1 mrg tree tmpidx = gfc_create_var (size_type_node, "tmpidx");
7071 1.1 mrg gfc_add_modify (&loop_body, shift, build_zero_cst (TREE_TYPE (shift)));
7072 1.1 mrg gfc_add_modify (&loop_body, tmpidx, idx);
7073 1.1 mrg stmtblock_t inner_loop;
7074 1.1 mrg gfc_init_block (&inner_loop);
7075 1.1 mrg tree dim = gfc_create_var (TREE_TYPE (rank), "dim");
7076 1.1 mrg /* shift += (tmpidx % extent[d]) * sm[d] */
7077 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
7078 1.1 mrg size_type_node, tmpidx,
7079 1.1 mrg fold_convert (size_type_node,
7080 1.1 mrg gfc_get_cfi_dim_extent (cfi, dim)));
7081 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
7082 1.1 mrg size_type_node, tmp,
7083 1.1 mrg fold_convert (size_type_node,
7084 1.1 mrg gfc_get_cfi_dim_sm (cfi, dim)));
7085 1.1 mrg gfc_add_modify (&inner_loop, shift,
7086 1.1 mrg fold_build2_loc (input_location, PLUS_EXPR,
7087 1.1 mrg size_type_node, shift, tmp));
7088 1.1 mrg /* tmpidx = tmpidx / extend[d] */
7089 1.1 mrg tmp = fold_convert (size_type_node, gfc_get_cfi_dim_extent (cfi, dim));
7090 1.1 mrg gfc_add_modify (&inner_loop, tmpidx,
7091 1.1 mrg fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7092 1.1 mrg size_type_node, tmpidx, tmp));
7093 1.1 mrg gfc_simple_for_loop (&loop_body, dim, build_zero_cst (TREE_TYPE (rank)),
7094 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (dim), 1),
7095 1.1 mrg gfc_finish_block (&inner_loop));
7096 1.1 mrg /* Assign. */
7097 1.1 mrg tmp = fold_convert (pchar_type_node, gfc_get_cfi_desc_base_addr (cfi));
7098 1.1 mrg tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, tmp, shift);
7099 1.1 mrg tree lhs;
7100 1.1 mrg /* memcpy (lhs + idx*elem_len, rhs + shift, elem_len) */
7101 1.1 mrg tree elem_len;
7102 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7103 1.1 mrg elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
7104 1.1 mrg else
7105 1.1 mrg elem_len = gfc_get_cfi_desc_elem_len (cfi);
7106 1.1 mrg lhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7107 1.1 mrg elem_len, idx);
7108 1.1 mrg lhs = fold_build2_loc (input_location, POINTER_PLUS_EXPR, pchar_type_node,
7109 1.1 mrg fold_convert (pchar_type_node, data), lhs);
7110 1.1 mrg tmp = fold_convert (pvoid_type_node, tmp);
7111 1.1 mrg lhs = fold_convert (pvoid_type_node, lhs);
7112 1.1 mrg call = builtin_decl_explicit (BUILT_IN_MEMCPY);
7113 1.1 mrg call = build_call_expr_loc (input_location, call, 3, lhs, tmp, elem_len);
7114 1.1 mrg gfc_add_expr_to_block (&loop_body, fold_convert (void_type_node, call));
7115 1.1 mrg gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7116 1.1 mrg size_var, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7117 1.1 mrg gfc_finish_block (&loop_body));
7118 1.1 mrg /* if (cond) { block2 } */
7119 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7120 1.1 mrg data, fold_convert (TREE_TYPE (data),
7121 1.1 mrg null_pointer_node));
7122 1.1 mrg tmp = build3_v (COND_EXPR, cond_var, gfc_finish_block (&block2),
7123 1.1 mrg build_empty_stmt (input_location));
7124 1.1 mrg gfc_add_expr_to_block (&block, tmp);
7125 1.1 mrg }
7126 1.1 mrg
7127 1.1 mrg if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7128 1.1 mrg {
7129 1.1 mrg tree offset, type;
7130 1.1 mrg type = TREE_TYPE (gfc_desc);
7131 1.1 mrg gfc_trans_array_bounds (type, sym, &offset, &block);
7132 1.1 mrg if (VAR_P (GFC_TYPE_ARRAY_OFFSET (type)))
7133 1.1 mrg gfc_add_modify (&block, GFC_TYPE_ARRAY_OFFSET (type), offset);
7134 1.1 mrg goto done;
7135 1.1 mrg }
7136 1.1 mrg
7137 1.1 mrg /* If cfi->data != NULL. */
7138 1.1 mrg stmtblock_t block2;
7139 1.1 mrg gfc_init_block (&block2);
7140 1.1 mrg
7141 1.1 mrg /* if do_copy_inout: gfc->dspan = gfc->dtype.elem_len
7142 1.1 mrg We use gfc instead of cfi on the RHS as this might be a constant. */
7143 1.1 mrg tmp = fold_convert (gfc_array_index_type,
7144 1.1 mrg gfc_conv_descriptor_elem_len (gfc_desc));
7145 1.1 mrg if (!do_copy_inout)
7146 1.1 mrg {
7147 1.1 mrg /* gfc->dspan = ((cfi->dim[0].sm % gfc->elem_len)
7148 1.1 mrg ? cfi->dim[0].sm : gfc->elem_len). */
7149 1.1 mrg tree cond;
7150 1.1 mrg tree tmp2 = gfc_get_cfi_dim_sm (cfi, gfc_rank_cst[0]);
7151 1.1 mrg cond = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
7152 1.1 mrg gfc_array_index_type, tmp2, tmp);
7153 1.1 mrg cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7154 1.1 mrg cond, gfc_index_zero_node);
7155 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
7156 1.1 mrg tmp2, tmp);
7157 1.1 mrg }
7158 1.1 mrg gfc_conv_descriptor_span_set (&block2, gfc_desc, tmp);
7159 1.1 mrg
7160 1.1 mrg /* Calculate offset + set lbound, ubound and stride. */
7161 1.1 mrg gfc_conv_descriptor_offset_set (&block2, gfc_desc, gfc_index_zero_node);
7162 1.1 mrg if (sym->as->rank > 0 && !sym->attr.pointer && !sym->attr.allocatable)
7163 1.1 mrg for (int i = 0; i < sym->as->rank; ++i)
7164 1.1 mrg {
7165 1.1 mrg gfc_se se;
7166 1.1 mrg gfc_init_se (&se, NULL );
7167 1.1 mrg if (sym->as->lower[i])
7168 1.1 mrg {
7169 1.1 mrg gfc_conv_expr (&se, sym->as->lower[i]);
7170 1.1 mrg tmp = se.expr;
7171 1.1 mrg }
7172 1.1 mrg else
7173 1.1 mrg tmp = gfc_index_one_node;
7174 1.1 mrg gfc_add_block_to_block (&block2, &se.pre);
7175 1.1 mrg gfc_conv_descriptor_lbound_set (&block2, gfc_desc, gfc_rank_cst[i],
7176 1.1 mrg tmp);
7177 1.1 mrg gfc_add_block_to_block (&block2, &se.post);
7178 1.1 mrg }
7179 1.1 mrg
7180 1.1 mrg /* Loop: for (i = 0; i < rank; ++i). */
7181 1.1 mrg idx = gfc_create_var (TREE_TYPE (rank), "idx");
7182 1.1 mrg
7183 1.1 mrg /* Loop body. */
7184 1.1 mrg stmtblock_t loop_body;
7185 1.1 mrg gfc_init_block (&loop_body);
7186 1.1 mrg /* gfc->dim[i].lbound = ... */
7187 1.1 mrg if (sym->attr.pointer || sym->attr.allocatable)
7188 1.1 mrg {
7189 1.1 mrg tmp = gfc_get_cfi_dim_lbound (cfi, idx);
7190 1.1 mrg gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx, tmp);
7191 1.1 mrg }
7192 1.1 mrg else if (sym->as->rank < 0)
7193 1.1 mrg gfc_conv_descriptor_lbound_set (&loop_body, gfc_desc, idx,
7194 1.1 mrg gfc_index_one_node);
7195 1.1 mrg
7196 1.1 mrg /* gfc->dim[i].ubound = gfc->dim[i].lbound + cfi->dim[i].extent - 1. */
7197 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7198 1.1 mrg gfc_conv_descriptor_lbound_get (gfc_desc, idx),
7199 1.1 mrg gfc_index_one_node);
7200 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
7201 1.1 mrg gfc_get_cfi_dim_extent (cfi, idx), tmp);
7202 1.1 mrg gfc_conv_descriptor_ubound_set (&loop_body, gfc_desc, idx, tmp);
7203 1.1 mrg
7204 1.1 mrg if (do_copy_inout)
7205 1.1 mrg {
7206 1.1 mrg /* gfc->dim[i].stride
7207 1.1 mrg = idx == 0 ? 1 : gfc->dim[i-1].stride * cfi->dim[i-1].extent */
7208 1.1 mrg tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
7209 1.1 mrg idx, build_zero_cst (TREE_TYPE (idx)));
7210 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx),
7211 1.1 mrg idx, build_int_cst (TREE_TYPE (idx), 1));
7212 1.1 mrg tree tmp2 = gfc_get_cfi_dim_extent (cfi, tmp);
7213 1.1 mrg tmp = gfc_conv_descriptor_stride_get (gfc_desc, tmp);
7214 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp2),
7215 1.1 mrg tmp2, tmp);
7216 1.1 mrg tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
7217 1.1 mrg gfc_index_one_node, tmp);
7218 1.1 mrg }
7219 1.1 mrg else
7220 1.1 mrg {
7221 1.1 mrg /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */
7222 1.1 mrg tmp = gfc_get_cfi_dim_sm (cfi, idx);
7223 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7224 1.1 mrg gfc_array_index_type, tmp,
7225 1.1 mrg fold_convert (gfc_array_index_type,
7226 1.1 mrg gfc_get_cfi_desc_elem_len (cfi)));
7227 1.1 mrg }
7228 1.1 mrg gfc_conv_descriptor_stride_set (&loop_body, gfc_desc, idx, tmp);
7229 1.1 mrg /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */
7230 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7231 1.1 mrg gfc_conv_descriptor_stride_get (gfc_desc, idx),
7232 1.1 mrg gfc_conv_descriptor_lbound_get (gfc_desc, idx));
7233 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7234 1.1 mrg gfc_conv_descriptor_offset_get (gfc_desc), tmp);
7235 1.1 mrg gfc_conv_descriptor_offset_set (&loop_body, gfc_desc, tmp);
7236 1.1 mrg
7237 1.1 mrg /* Generate loop. */
7238 1.1 mrg gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7239 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7240 1.1 mrg gfc_finish_block (&loop_body));
7241 1.1 mrg if (sym->attr.allocatable || sym->attr.pointer)
7242 1.1 mrg {
7243 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi),
7244 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7245 1.1 mrg tmp, null_pointer_node);
7246 1.1 mrg tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
7247 1.1 mrg build_empty_stmt (input_location));
7248 1.1 mrg gfc_add_expr_to_block (&block, tmp);
7249 1.1 mrg }
7250 1.1 mrg else
7251 1.1 mrg gfc_add_block_to_block (&block, &block2);
7252 1.1 mrg
7253 1.1 mrg done:
7254 1.1 mrg /* If optional arg: 'if (arg) { block } else { local_arg = NULL; }'. */
7255 1.1 mrg if (sym->attr.optional)
7256 1.1 mrg {
7257 1.1 mrg tree present = fold_build2_loc (input_location, NE_EXPR,
7258 1.1 mrg boolean_type_node, cfi_desc,
7259 1.1 mrg null_pointer_node);
7260 1.1 mrg tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
7261 1.1 mrg sym->backend_decl,
7262 1.1 mrg fold_convert (TREE_TYPE (sym->backend_decl),
7263 1.1 mrg null_pointer_node));
7264 1.1 mrg tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block), tmp);
7265 1.1 mrg gfc_add_expr_to_block (init, tmp);
7266 1.1 mrg }
7267 1.1 mrg else
7268 1.1 mrg gfc_add_block_to_block (init, &block);
7269 1.1 mrg
7270 1.1 mrg if (!sym->attr.referenced)
7271 1.1 mrg return;
7272 1.1 mrg
7273 1.1 mrg /* If pointer not changed, nothing to be done (except copy out) */
7274 1.1 mrg if (!do_copy_inout && ((!sym->attr.pointer && !sym->attr.allocatable)
7275 1.1 mrg || sym->attr.intent == INTENT_IN))
7276 1.1 mrg return;
7277 1.1 mrg
7278 1.1 mrg gfc_init_block (&block);
7279 1.1 mrg
7280 1.1 mrg /* For bind(C), Fortran does not permit mixing 'pointer' with 'contiguous' (or
7281 1.1 mrg len=*). Thus, when copy out is needed, the bounds ofthe descriptor remain
7282 1.1 mrg unchanged. */
7283 1.1 mrg if (do_copy_inout)
7284 1.1 mrg {
7285 1.1 mrg tree data, call;
7286 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7287 1.1 mrg data = gfc_conv_descriptor_data_get (gfc_desc);
7288 1.1 mrg else if (!POINTER_TYPE_P (TREE_TYPE (gfc_desc)))
7289 1.1 mrg data = gfc_build_addr_expr (NULL, gfc_desc);
7290 1.1 mrg else
7291 1.1 mrg data = gfc_desc;
7292 1.1 mrg gfc_init_block (&block2);
7293 1.1 mrg if (sym->attr.intent != INTENT_IN)
7294 1.1 mrg {
7295 1.1 mrg /* First, create the inner copy-out loop.
7296 1.1 mrg for (idx = 0; idx < size; ++idx)
7297 1.1 mrg {
7298 1.1 mrg shift = 0;
7299 1.1 mrg tmpidx = idx
7300 1.1 mrg for (dim = 0; dim < rank; ++dim)
7301 1.1 mrg {
7302 1.1 mrg shift += (tmpidx % extent[d]) * sm[d]
7303 1.1 mrg tmpidx = tmpidx / extend[d]
7304 1.1 mrg }
7305 1.1 mrg memcpy (lhs + shift, rhs + idx*elem_len, elem_len)
7306 1.1 mrg } .*/
7307 1.1 mrg stmtblock_t loop_body;
7308 1.1 mrg idx = gfc_create_var (size_type_node, "arrayidx");
7309 1.1 mrg gfc_init_block (&loop_body);
7310 1.1 mrg tree shift = gfc_create_var (size_type_node, "shift");
7311 1.1 mrg tree tmpidx = gfc_create_var (size_type_node, "tmpidx");
7312 1.1 mrg gfc_add_modify (&loop_body, shift,
7313 1.1 mrg build_zero_cst (TREE_TYPE (shift)));
7314 1.1 mrg gfc_add_modify (&loop_body, tmpidx, idx);
7315 1.1 mrg stmtblock_t inner_loop;
7316 1.1 mrg gfc_init_block (&inner_loop);
7317 1.1 mrg tree dim = gfc_create_var (TREE_TYPE (rank), "dim");
7318 1.1 mrg /* shift += (tmpidx % extent[d]) * sm[d] */
7319 1.1 mrg tmp = fold_convert (size_type_node,
7320 1.1 mrg gfc_get_cfi_dim_extent (cfi, dim));
7321 1.1 mrg tmp = fold_build2_loc (input_location, TRUNC_MOD_EXPR,
7322 1.1 mrg size_type_node, tmpidx, tmp);
7323 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
7324 1.1 mrg size_type_node, tmp,
7325 1.1 mrg fold_convert (size_type_node,
7326 1.1 mrg gfc_get_cfi_dim_sm (cfi, dim)));
7327 1.1 mrg gfc_add_modify (&inner_loop, shift,
7328 1.1 mrg fold_build2_loc (input_location, PLUS_EXPR,
7329 1.1 mrg size_type_node, shift, tmp));
7330 1.1 mrg /* tmpidx = tmpidx / extend[d] */
7331 1.1 mrg tmp = fold_convert (size_type_node,
7332 1.1 mrg gfc_get_cfi_dim_extent (cfi, dim));
7333 1.1 mrg gfc_add_modify (&inner_loop, tmpidx,
7334 1.1 mrg fold_build2_loc (input_location, TRUNC_DIV_EXPR,
7335 1.1 mrg size_type_node, tmpidx, tmp));
7336 1.1 mrg gfc_simple_for_loop (&loop_body, dim,
7337 1.1 mrg build_zero_cst (TREE_TYPE (rank)), rank, LT_EXPR,
7338 1.1 mrg build_int_cst (TREE_TYPE (dim), 1),
7339 1.1 mrg gfc_finish_block (&inner_loop));
7340 1.1 mrg /* Assign. */
7341 1.1 mrg tree rhs;
7342 1.1 mrg tmp = fold_convert (pchar_type_node,
7343 1.1 mrg gfc_get_cfi_desc_base_addr (cfi));
7344 1.1 mrg tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, tmp, shift);
7345 1.1 mrg /* memcpy (lhs + shift, rhs + idx*elem_len, elem_len) */
7346 1.1 mrg tree elem_len;
7347 1.1 mrg if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (gfc_desc)))
7348 1.1 mrg elem_len = gfc_conv_descriptor_elem_len (gfc_desc);
7349 1.1 mrg else
7350 1.1 mrg elem_len = gfc_get_cfi_desc_elem_len (cfi);
7351 1.1 mrg rhs = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
7352 1.1 mrg elem_len, idx);
7353 1.1 mrg rhs = fold_build2_loc (input_location, POINTER_PLUS_EXPR,
7354 1.1 mrg pchar_type_node,
7355 1.1 mrg fold_convert (pchar_type_node, data), rhs);
7356 1.1 mrg tmp = fold_convert (pvoid_type_node, tmp);
7357 1.1 mrg rhs = fold_convert (pvoid_type_node, rhs);
7358 1.1 mrg call = builtin_decl_explicit (BUILT_IN_MEMCPY);
7359 1.1 mrg call = build_call_expr_loc (input_location, call, 3, tmp, rhs,
7360 1.1 mrg elem_len);
7361 1.1 mrg gfc_add_expr_to_block (&loop_body,
7362 1.1 mrg fold_convert (void_type_node, call));
7363 1.1 mrg gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7364 1.1 mrg size_var, LT_EXPR,
7365 1.1 mrg build_int_cst (TREE_TYPE (idx), 1),
7366 1.1 mrg gfc_finish_block (&loop_body));
7367 1.1 mrg }
7368 1.1 mrg call = builtin_decl_explicit (BUILT_IN_FREE);
7369 1.1 mrg call = build_call_expr_loc (input_location, call, 1, data);
7370 1.1 mrg gfc_add_expr_to_block (&block2, call);
7371 1.1 mrg
7372 1.1 mrg /* if (cfi->base_addr != gfc->data) { copy out; free(var) }; return */
7373 1.1 mrg tree tmp2 = gfc_get_cfi_desc_base_addr (cfi);
7374 1.1 mrg tmp2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7375 1.1 mrg tmp2, fold_convert (TREE_TYPE (tmp2), data));
7376 1.1 mrg tmp = build3_v (COND_EXPR, tmp2, gfc_finish_block (&block2),
7377 1.1 mrg build_empty_stmt (input_location));
7378 1.1 mrg gfc_add_expr_to_block (&block, tmp);
7379 1.1 mrg goto done_finally;
7380 1.1 mrg }
7381 1.1 mrg
7382 1.1 mrg /* Update pointer + array data data on exit. */
7383 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi);
7384 1.1 mrg tmp2 = (!sym->attr.dimension
7385 1.1 mrg ? gfc_desc : gfc_conv_descriptor_data_get (gfc_desc));
7386 1.1 mrg gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));
7387 1.1 mrg
7388 1.1 mrg /* Set string length for len=:, only. */
7389 1.1 mrg if (sym->ts.type == BT_CHARACTER && !sym->ts.u.cl->length)
7390 1.1 mrg {
7391 1.1 mrg tmp = sym->ts.u.cl->backend_decl;
7392 1.1 mrg if (sym->ts.kind != 1)
7393 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR,
7394 1.1 mrg gfc_array_index_type,
7395 1.1 mrg sym->ts.u.cl->backend_decl, tmp);
7396 1.1 mrg tmp2 = gfc_get_cfi_desc_elem_len (cfi);
7397 1.1 mrg gfc_add_modify (&block, tmp2, fold_convert (TREE_TYPE (tmp2), tmp));
7398 1.1 mrg }
7399 1.1 mrg
7400 1.1 mrg if (!sym->attr.dimension)
7401 1.1 mrg goto done_finally;
7402 1.1 mrg
7403 1.1 mrg gfc_init_block (&block2);
7404 1.1 mrg
7405 1.1 mrg /* Loop: for (i = 0; i < rank; ++i). */
7406 1.1 mrg idx = gfc_create_var (TREE_TYPE (rank), "idx");
7407 1.1 mrg
7408 1.1 mrg /* Loop body. */
7409 1.1 mrg gfc_init_block (&loop_body);
7410 1.1 mrg /* cfi->dim[i].lower_bound = gfc->dim[i].lbound */
7411 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_lbound (cfi, idx),
7412 1.1 mrg gfc_conv_descriptor_lbound_get (gfc_desc, idx));
7413 1.1 mrg /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */
7414 1.1 mrg tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
7415 1.1 mrg gfc_conv_descriptor_ubound_get (gfc_desc, idx),
7416 1.1 mrg gfc_conv_descriptor_lbound_get (gfc_desc, idx));
7417 1.1 mrg tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, tmp,
7418 1.1 mrg gfc_index_one_node);
7419 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp);
7420 1.1 mrg /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */
7421 1.1 mrg tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
7422 1.1 mrg gfc_conv_descriptor_stride_get (gfc_desc, idx),
7423 1.1 mrg gfc_conv_descriptor_span_get (gfc_desc));
7424 1.1 mrg gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp);
7425 1.1 mrg
7426 1.1 mrg /* Generate loop. */
7427 1.1 mrg gfc_simple_for_loop (&block2, idx, build_zero_cst (TREE_TYPE (idx)),
7428 1.1 mrg rank, LT_EXPR, build_int_cst (TREE_TYPE (idx), 1),
7429 1.1 mrg gfc_finish_block (&loop_body));
7430 1.1 mrg /* if (gfc->data != NULL) { block2 }. */
7431 1.1 mrg tmp = gfc_get_cfi_desc_base_addr (cfi),
7432 1.1 mrg tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
7433 1.1 mrg tmp, null_pointer_node);
7434 1.1 mrg tmp = build3_v (COND_EXPR, tmp, gfc_finish_block (&block2),
7435 1.1 mrg build_empty_stmt (input_location));
7436 1.1 mrg gfc_add_expr_to_block (&block, tmp);
7437 1.1 mrg
7438 1.1 mrg done_finally:
7439 1.1 mrg /* If optional arg: 'if (arg) { block } else { local_arg = NULL; }'. */
7440 1.1 mrg if (sym->attr.optional)
7441 1.1 mrg {
7442 1.1 mrg tree present = fold_build2_loc (input_location, NE_EXPR,
7443 1.1 mrg boolean_type_node, cfi_desc,
7444 1.1 mrg null_pointer_node);
7445 1.1 mrg tmp = build3_v (COND_EXPR, present, gfc_finish_block (&block),
7446 1.1 mrg build_empty_stmt (input_location));
7447 1.1 mrg gfc_add_expr_to_block (finally, tmp);
7448 1.1 mrg }
7449 1.1 mrg else
7450 1.1 mrg gfc_add_block_to_block (finally, &block);
7451 1.1 mrg }
7452 1.1 mrg
7453 1.1 mrg /* Generate code for a function. */
7454 1.1 mrg
7455 1.1 mrg void
7456 1.1 mrg gfc_generate_function_code (gfc_namespace * ns)
7457 1.1 mrg {
7458 1.1 mrg tree fndecl;
7459 1.1 mrg tree old_context;
7460 1.1 mrg tree decl;
7461 1.1 mrg tree tmp;
7462 1.1 mrg tree fpstate = NULL_TREE;
7463 1.1 mrg stmtblock_t init, cleanup, outer_block;
7464 1.1 mrg stmtblock_t body;
7465 1.1 mrg gfc_wrapped_block try_block;
7466 1.1 mrg tree recurcheckvar = NULL_TREE;
7467 1.1 mrg gfc_symbol *sym;
7468 1.1 mrg gfc_symbol *previous_procedure_symbol;
7469 1.1 mrg int rank, ieee;
7470 1.1 mrg bool is_recursive;
7471 1.1 mrg
7472 1.1 mrg sym = ns->proc_name;
7473 1.1 mrg previous_procedure_symbol = current_procedure_symbol;
7474 1.1 mrg current_procedure_symbol = sym;
7475 1.1 mrg
7476 1.1 mrg /* Initialize sym->tlink so that gfc_trans_deferred_vars does not get
7477 1.1 mrg lost or worse. */
7478 1.1 mrg sym->tlink = sym;
7479 1.1 mrg
7480 1.1 mrg /* Create the declaration for functions with global scope. */
7481 1.1 mrg if (!sym->backend_decl)
7482 1.1 mrg gfc_create_function_decl (ns, false);
7483 1.1 mrg
7484 1.1 mrg fndecl = sym->backend_decl;
7485 1.1 mrg old_context = current_function_decl;
7486 1.1 mrg
7487 1.1 mrg if (old_context)
7488 1.1 mrg {
7489 1.1 mrg push_function_context ();
7490 1.1 mrg saved_parent_function_decls = saved_function_decls;
7491 1.1 mrg saved_function_decls = NULL_TREE;
7492 1.1 mrg }
7493 1.1 mrg
7494 1.1 mrg trans_function_start (sym);
7495 1.1 mrg
7496 1.1 mrg gfc_init_block (&init);
7497 1.1 mrg gfc_init_block (&cleanup);
7498 1.1 mrg gfc_init_block (&outer_block);
7499 1.1 mrg
7500 1.1 mrg if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER)
7501 1.1 mrg {
7502 1.1 mrg /* Copy length backend_decls to all entry point result
7503 1.1 mrg symbols. */
7504 1.1 mrg gfc_entry_list *el;
7505 1.1 mrg tree backend_decl;
7506 1.1 mrg
7507 1.1 mrg gfc_conv_const_charlen (ns->proc_name->ts.u.cl);
7508 1.1 mrg backend_decl = ns->proc_name->result->ts.u.cl->backend_decl;
7509 1.1 mrg for (el = ns->entries; el; el = el->next)
7510 1.1 mrg el->sym->result->ts.u.cl->backend_decl = backend_decl;
7511 1.1 mrg }
7512 1.1 mrg
7513 1.1 mrg /* Translate COMMON blocks. */
7514 1.1 mrg gfc_trans_common (ns);
7515 1.1 mrg
7516 1.1 mrg /* Null the parent fake result declaration if this namespace is
7517 1.1 mrg a module function or an external procedures. */
7518 1.1 mrg if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
7519 1.1 mrg || ns->parent == NULL)
7520 1.1 mrg parent_fake_result_decl = NULL_TREE;
7521 1.1 mrg
7522 1.1 mrg /* For BIND(C):
7523 1.1 mrg - deallocate intent-out allocatable dummy arguments.
7524 1.1 mrg - Create GFC variable which will later be populated by convert_CFI_desc */
7525 1.1 mrg if (sym->attr.is_bind_c)
7526 1.1 mrg for (gfc_formal_arglist *formal = gfc_sym_get_dummy_args (sym);
7527 1.1 mrg formal; formal = formal->next)
7528 1.1 mrg {
7529 1.1 mrg gfc_symbol *fsym = formal->sym;
7530 1.1 mrg if (!is_CFI_desc (fsym, NULL))
7531 1.1 mrg continue;
7532 1.1 mrg if (!fsym->attr.referenced)
7533 1.1 mrg {
7534 1.1 mrg gfc_conv_cfi_to_gfc (&init, &cleanup, fsym->backend_decl,
7535 1.1 mrg NULL_TREE, fsym);
7536 1.1 mrg continue;
7537 1.1 mrg }
7538 1.1 mrg /* Let's now create a local GFI descriptor. Afterwards:
7539 1.1 mrg desc is the local descriptor,
7540 1.1 mrg desc_p is a pointer to it
7541 1.1 mrg and stored in sym->backend_decl
7542 1.1 mrg GFC_DECL_SAVED_DESCRIPTOR (desc_p) contains the CFI descriptor
7543 1.1 mrg -> PARM_DECL and before sym->backend_decl.
7544 1.1 mrg For scalars, decl == decl_p is a pointer variable. */
7545 1.1 mrg tree desc_p, desc;
7546 1.1 mrg location_t loc = gfc_get_location (&sym->declared_at);
7547 1.1 mrg if (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->length)
7548 1.1 mrg fsym->ts.u.cl->backend_decl = gfc_create_var (gfc_array_index_type,
7549 1.1 mrg fsym->name);
7550 1.1 mrg else if (fsym->ts.type == BT_CHARACTER && !fsym->ts.u.cl->backend_decl)
7551 1.1 mrg {
7552 1.1 mrg gfc_se se;
7553 1.1 mrg gfc_init_se (&se, NULL );
7554 1.1 mrg gfc_conv_expr (&se, fsym->ts.u.cl->length);
7555 1.1 mrg gfc_add_block_to_block (&init, &se.pre);
7556 1.1 mrg fsym->ts.u.cl->backend_decl = se.expr;
7557 1.1 mrg gcc_assert(se.post.head == NULL_TREE);
7558 1.1 mrg }
7559 1.1 mrg /* Nullify, otherwise gfc_sym_type will return the CFI type. */
7560 1.1 mrg tree tmp = fsym->backend_decl;
7561 1.1 mrg fsym->backend_decl = NULL;
7562 1.1 mrg tree type = gfc_sym_type (fsym);
7563 1.1 mrg gcc_assert (POINTER_TYPE_P (type));
7564 1.1 mrg if (POINTER_TYPE_P (TREE_TYPE (type)))
7565 1.1 mrg /* For instance, allocatable scalars. */
7566 1.1 mrg type = TREE_TYPE (type);
7567 1.1 mrg if (TREE_CODE (type) == REFERENCE_TYPE)
7568 1.1 mrg type = build_pointer_type (TREE_TYPE (type));
7569 1.1 mrg desc_p = build_decl (loc, VAR_DECL, get_identifier (fsym->name), type);
7570 1.1 mrg if (!fsym->attr.dimension)
7571 1.1 mrg desc = desc_p;
7572 1.1 mrg else if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (TREE_TYPE (desc_p))))
7573 1.1 mrg {
7574 1.1 mrg /* Character(len=*) explict-size/assumed-size array. */
7575 1.1 mrg desc = desc_p;
7576 1.1 mrg gfc_build_qualified_array (desc, fsym);
7577 1.1 mrg }
7578 1.1 mrg else
7579 1.1 mrg {
7580 1.1 mrg tree size = size_in_bytes (TREE_TYPE (TREE_TYPE (desc_p)));
7581 1.1 mrg tree call = builtin_decl_explicit (BUILT_IN_ALLOCA);
7582 1.1 mrg call = build_call_expr_loc (input_location, call, 1, size);
7583 1.1 mrg gfc_add_modify (&outer_block, desc_p,
7584 1.1 mrg fold_convert (TREE_TYPE(desc_p), call));
7585 1.1 mrg desc = build_fold_indirect_ref_loc (input_location, desc_p);
7586 1.1 mrg }
7587 1.1 mrg pushdecl (desc_p);
7588 1.1 mrg if (fsym->attr.optional)
7589 1.1 mrg {
7590 1.1 mrg gfc_allocate_lang_decl (desc_p);
7591 1.1 mrg GFC_DECL_OPTIONAL_ARGUMENT (desc_p) = 1;
7592 1.1 mrg }
7593 1.1 mrg fsym->backend_decl = desc_p;
7594 1.1 mrg gfc_conv_cfi_to_gfc (&init, &cleanup, tmp, desc, fsym);
7595 1.1 mrg }
7596 1.1 mrg
7597 1.1 mrg gfc_generate_contained_functions (ns);
7598 1.1 mrg
7599 1.1 mrg has_coarray_vars = false;
7600 1.1 mrg generate_local_vars (ns);
7601 1.1 mrg
7602 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
7603 1.1 mrg generate_coarray_init (ns);
7604 1.1 mrg
7605 1.1 mrg /* Keep the parent fake result declaration in module functions
7606 1.1 mrg or external procedures. */
7607 1.1 mrg if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
7608 1.1 mrg || ns->parent == NULL)
7609 1.1 mrg current_fake_result_decl = parent_fake_result_decl;
7610 1.1 mrg else
7611 1.1 mrg current_fake_result_decl = NULL_TREE;
7612 1.1 mrg
7613 1.1 mrg is_recursive = sym->attr.recursive
7614 1.1 mrg || (sym->attr.entry_master
7615 1.1 mrg && sym->ns->entries->sym->attr.recursive);
7616 1.1 mrg if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
7617 1.1 mrg && !is_recursive && !flag_recursive && !sym->attr.artificial)
7618 1.1 mrg {
7619 1.1 mrg char * msg;
7620 1.1 mrg
7621 1.1 mrg msg = xasprintf ("Recursive call to nonrecursive procedure '%s'",
7622 1.1 mrg sym->name);
7623 1.1 mrg recurcheckvar = gfc_create_var (logical_type_node, "is_recursive");
7624 1.1 mrg TREE_STATIC (recurcheckvar) = 1;
7625 1.1 mrg DECL_INITIAL (recurcheckvar) = logical_false_node;
7626 1.1 mrg gfc_add_expr_to_block (&init, recurcheckvar);
7627 1.1 mrg gfc_trans_runtime_check (true, false, recurcheckvar, &init,
7628 1.1 mrg &sym->declared_at, msg);
7629 1.1 mrg gfc_add_modify (&init, recurcheckvar, logical_true_node);
7630 1.1 mrg free (msg);
7631 1.1 mrg }
7632 1.1 mrg
7633 1.1 mrg /* Check if an IEEE module is used in the procedure. If so, save
7634 1.1 mrg the floating point state. */
7635 1.1 mrg ieee = is_ieee_module_used (ns);
7636 1.1 mrg if (ieee)
7637 1.1 mrg fpstate = gfc_save_fp_state (&init);
7638 1.1 mrg
7639 1.1 mrg /* Now generate the code for the body of this function. */
7640 1.1 mrg gfc_init_block (&body);
7641 1.1 mrg
7642 1.1 mrg if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
7643 1.1 mrg && sym->attr.subroutine)
7644 1.1 mrg {
7645 1.1 mrg tree alternate_return;
7646 1.1 mrg alternate_return = gfc_get_fake_result_decl (sym, 0);
7647 1.1 mrg gfc_add_modify (&body, alternate_return, integer_zero_node);
7648 1.1 mrg }
7649 1.1 mrg
7650 1.1 mrg if (ns->entries)
7651 1.1 mrg {
7652 1.1 mrg /* Jump to the correct entry point. */
7653 1.1 mrg tmp = gfc_trans_entry_master_switch (ns->entries);
7654 1.1 mrg gfc_add_expr_to_block (&body, tmp);
7655 1.1 mrg }
7656 1.1 mrg
7657 1.1 mrg /* If bounds-checking is enabled, generate code to check passed in actual
7658 1.1 mrg arguments against the expected dummy argument attributes (e.g. string
7659 1.1 mrg lengths). */
7660 1.1 mrg if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !sym->attr.is_bind_c)
7661 1.1 mrg add_argument_checking (&body, sym);
7662 1.1 mrg
7663 1.1 mrg finish_oacc_declare (ns, sym, false);
7664 1.1 mrg
7665 1.1 mrg tmp = gfc_trans_code (ns->code);
7666 1.1 mrg gfc_add_expr_to_block (&body, tmp);
7667 1.1 mrg
7668 1.1 mrg if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
7669 1.1 mrg || (sym->result && sym->result != sym
7670 1.1 mrg && sym->result->ts.type == BT_DERIVED
7671 1.1 mrg && sym->result->ts.u.derived->attr.alloc_comp))
7672 1.1 mrg {
7673 1.1 mrg bool artificial_result_decl = false;
7674 1.1 mrg tree result = get_proc_result (sym);
7675 1.1 mrg gfc_symbol *rsym = sym == sym->result ? sym : sym->result;
7676 1.1 mrg
7677 1.1 mrg /* Make sure that a function returning an object with
7678 1.1 mrg alloc/pointer_components always has a result, where at least
7679 1.1 mrg the allocatable/pointer components are set to zero. */
7680 1.1 mrg if (result == NULL_TREE && sym->attr.function
7681 1.1 mrg && ((sym->result->ts.type == BT_DERIVED
7682 1.1 mrg && (sym->attr.allocatable
7683 1.1 mrg || sym->attr.pointer
7684 1.1 mrg || sym->result->ts.u.derived->attr.alloc_comp
7685 1.1 mrg || sym->result->ts.u.derived->attr.pointer_comp))
7686 1.1 mrg || (sym->result->ts.type == BT_CLASS
7687 1.1 mrg && (CLASS_DATA (sym)->attr.allocatable
7688 1.1 mrg || CLASS_DATA (sym)->attr.class_pointer
7689 1.1 mrg || CLASS_DATA (sym->result)->attr.alloc_comp
7690 1.1 mrg || CLASS_DATA (sym->result)->attr.pointer_comp))))
7691 1.1 mrg {
7692 1.1 mrg artificial_result_decl = true;
7693 1.1 mrg result = gfc_get_fake_result_decl (sym, 0);
7694 1.1 mrg }
7695 1.1 mrg
7696 1.1 mrg if (result != NULL_TREE && sym->attr.function && !sym->attr.pointer)
7697 1.1 mrg {
7698 1.1 mrg if (sym->attr.allocatable && sym->attr.dimension == 0
7699 1.1 mrg && sym->result == sym)
7700 1.1 mrg gfc_add_modify (&init, result, fold_convert (TREE_TYPE (result),
7701 1.1 mrg null_pointer_node));
7702 1.1 mrg else if (sym->ts.type == BT_CLASS
7703 1.1 mrg && CLASS_DATA (sym)->attr.allocatable
7704 1.1 mrg && CLASS_DATA (sym)->attr.dimension == 0
7705 1.1 mrg && sym->result == sym)
7706 1.1 mrg {
7707 1.1 mrg tmp = CLASS_DATA (sym)->backend_decl;
7708 1.1 mrg tmp = fold_build3_loc (input_location, COMPONENT_REF,
7709 1.1 mrg TREE_TYPE (tmp), result, tmp, NULL_TREE);
7710 1.1 mrg gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp),
7711 1.1 mrg null_pointer_node));
7712 1.1 mrg }
7713 1.1 mrg else if (sym->ts.type == BT_DERIVED
7714 1.1 mrg && !sym->attr.allocatable)
7715 1.1 mrg {
7716 1.1 mrg gfc_expr *init_exp;
7717 1.1 mrg /* Arrays are not initialized using the default initializer of
7718 1.1 mrg their elements. Therefore only check if a default
7719 1.1 mrg initializer is available when the result is scalar. */
7720 1.1 mrg init_exp = rsym->as ? NULL
7721 1.1 mrg : gfc_generate_initializer (&rsym->ts, true);
7722 1.1 mrg if (init_exp)
7723 1.1 mrg {
7724 1.1 mrg tmp = gfc_trans_structure_assign (result, init_exp, 0);
7725 1.1 mrg gfc_free_expr (init_exp);
7726 1.1 mrg gfc_add_expr_to_block (&init, tmp);
7727 1.1 mrg }
7728 1.1 mrg else if (rsym->ts.u.derived->attr.alloc_comp)
7729 1.1 mrg {
7730 1.1 mrg rank = rsym->as ? rsym->as->rank : 0;
7731 1.1 mrg tmp = gfc_nullify_alloc_comp (rsym->ts.u.derived, result,
7732 1.1 mrg rank);
7733 1.1 mrg gfc_prepend_expr_to_block (&body, tmp);
7734 1.1 mrg }
7735 1.1 mrg }
7736 1.1 mrg }
7737 1.1 mrg
7738 1.1 mrg if (result == NULL_TREE || artificial_result_decl)
7739 1.1 mrg {
7740 1.1 mrg /* TODO: move to the appropriate place in resolve.cc. */
7741 1.1 mrg if (warn_return_type > 0 && sym == sym->result)
7742 1.1 mrg gfc_warning (OPT_Wreturn_type,
7743 1.1 mrg "Return value of function %qs at %L not set",
7744 1.1 mrg sym->name, &sym->declared_at);
7745 1.1 mrg if (warn_return_type > 0)
7746 1.1 mrg suppress_warning (sym->backend_decl);
7747 1.1 mrg }
7748 1.1 mrg if (result != NULL_TREE)
7749 1.1 mrg gfc_add_expr_to_block (&body, gfc_generate_return ());
7750 1.1 mrg }
7751 1.1 mrg
7752 1.1 mrg /* Reset recursion-check variable. */
7753 1.1 mrg if (recurcheckvar != NULL_TREE)
7754 1.1 mrg {
7755 1.1 mrg gfc_add_modify (&cleanup, recurcheckvar, logical_false_node);
7756 1.1 mrg recurcheckvar = NULL;
7757 1.1 mrg }
7758 1.1 mrg
7759 1.1 mrg /* If IEEE modules are loaded, restore the floating-point state. */
7760 1.1 mrg if (ieee)
7761 1.1 mrg gfc_restore_fp_state (&cleanup, fpstate);
7762 1.1 mrg
7763 1.1 mrg /* Finish the function body and add init and cleanup code. */
7764 1.1 mrg tmp = gfc_finish_block (&body);
7765 1.1 mrg /* Add code to create and cleanup arrays. */
7766 1.1 mrg gfc_start_wrapped_block (&try_block, tmp);
7767 1.1 mrg gfc_trans_deferred_vars (sym, &try_block);
7768 1.1 mrg gfc_add_init_cleanup (&try_block, gfc_finish_block (&init),
7769 1.1 mrg gfc_finish_block (&cleanup));
7770 1.1 mrg
7771 1.1 mrg /* Add all the decls we created during processing. */
7772 1.1 mrg decl = nreverse (saved_function_decls);
7773 1.1 mrg while (decl)
7774 1.1 mrg {
7775 1.1 mrg tree next;
7776 1.1 mrg
7777 1.1 mrg next = DECL_CHAIN (decl);
7778 1.1 mrg DECL_CHAIN (decl) = NULL_TREE;
7779 1.1 mrg pushdecl (decl);
7780 1.1 mrg decl = next;
7781 1.1 mrg }
7782 1.1 mrg saved_function_decls = NULL_TREE;
7783 1.1 mrg
7784 1.1 mrg gfc_add_expr_to_block (&outer_block, gfc_finish_wrapped_block (&try_block));
7785 1.1 mrg DECL_SAVED_TREE (fndecl) = gfc_finish_block (&outer_block);
7786 1.1 mrg decl = getdecls ();
7787 1.1 mrg
7788 1.1 mrg /* Finish off this function and send it for code generation. */
7789 1.1 mrg poplevel (1, 1);
7790 1.1 mrg BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7791 1.1 mrg
7792 1.1 mrg DECL_SAVED_TREE (fndecl)
7793 1.1 mrg = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node,
7794 1.1 mrg decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl));
7795 1.1 mrg
7796 1.1 mrg /* Output the GENERIC tree. */
7797 1.1 mrg dump_function (TDI_original, fndecl);
7798 1.1 mrg
7799 1.1 mrg /* Store the end of the function, so that we get good line number
7800 1.1 mrg info for the epilogue. */
7801 1.1 mrg cfun->function_end_locus = input_location;
7802 1.1 mrg
7803 1.1 mrg /* We're leaving the context of this function, so zap cfun.
7804 1.1 mrg It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
7805 1.1 mrg tree_rest_of_compilation. */
7806 1.1 mrg set_cfun (NULL);
7807 1.1 mrg
7808 1.1 mrg if (old_context)
7809 1.1 mrg {
7810 1.1 mrg pop_function_context ();
7811 1.1 mrg saved_function_decls = saved_parent_function_decls;
7812 1.1 mrg }
7813 1.1 mrg current_function_decl = old_context;
7814 1.1 mrg
7815 1.1 mrg if (decl_function_context (fndecl))
7816 1.1 mrg {
7817 1.1 mrg /* Register this function with cgraph just far enough to get it
7818 1.1 mrg added to our parent's nested function list.
7819 1.1 mrg If there are static coarrays in this function, the nested _caf_init
7820 1.1 mrg function has already called cgraph_create_node, which also created
7821 1.1 mrg the cgraph node for this function. */
7822 1.1 mrg if (!has_coarray_vars || flag_coarray != GFC_FCOARRAY_LIB)
7823 1.1 mrg (void) cgraph_node::get_create (fndecl);
7824 1.1 mrg }
7825 1.1 mrg else
7826 1.1 mrg cgraph_node::finalize_function (fndecl, true);
7827 1.1 mrg
7828 1.1 mrg gfc_trans_use_stmts (ns);
7829 1.1 mrg gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
7830 1.1 mrg
7831 1.1 mrg if (sym->attr.is_main_program)
7832 1.1 mrg create_main_function (fndecl);
7833 1.1 mrg
7834 1.1 mrg current_procedure_symbol = previous_procedure_symbol;
7835 1.1 mrg }
7836 1.1 mrg
7837 1.1 mrg
7838 1.1 mrg void
7839 1.1 mrg gfc_generate_constructors (void)
7840 1.1 mrg {
7841 1.1 mrg gcc_assert (gfc_static_ctors == NULL_TREE);
7842 1.1 mrg #if 0
7843 1.1 mrg tree fnname;
7844 1.1 mrg tree type;
7845 1.1 mrg tree fndecl;
7846 1.1 mrg tree decl;
7847 1.1 mrg tree tmp;
7848 1.1 mrg
7849 1.1 mrg if (gfc_static_ctors == NULL_TREE)
7850 1.1 mrg return;
7851 1.1 mrg
7852 1.1 mrg fnname = get_file_function_name ("I");
7853 1.1 mrg type = build_function_type_list (void_type_node, NULL_TREE);
7854 1.1 mrg
7855 1.1 mrg fndecl = build_decl (input_location,
7856 1.1 mrg FUNCTION_DECL, fnname, type);
7857 1.1 mrg TREE_PUBLIC (fndecl) = 1;
7858 1.1 mrg
7859 1.1 mrg decl = build_decl (input_location,
7860 1.1 mrg RESULT_DECL, NULL_TREE, void_type_node);
7861 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
7862 1.1 mrg DECL_IGNORED_P (decl) = 1;
7863 1.1 mrg DECL_CONTEXT (decl) = fndecl;
7864 1.1 mrg DECL_RESULT (fndecl) = decl;
7865 1.1 mrg
7866 1.1 mrg pushdecl (fndecl);
7867 1.1 mrg
7868 1.1 mrg current_function_decl = fndecl;
7869 1.1 mrg
7870 1.1 mrg rest_of_decl_compilation (fndecl, 1, 0);
7871 1.1 mrg
7872 1.1 mrg make_decl_rtl (fndecl);
7873 1.1 mrg
7874 1.1 mrg allocate_struct_function (fndecl, false);
7875 1.1 mrg
7876 1.1 mrg pushlevel ();
7877 1.1 mrg
7878 1.1 mrg for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
7879 1.1 mrg {
7880 1.1 mrg tmp = build_call_expr_loc (input_location,
7881 1.1 mrg TREE_VALUE (gfc_static_ctors), 0);
7882 1.1 mrg DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp);
7883 1.1 mrg }
7884 1.1 mrg
7885 1.1 mrg decl = getdecls ();
7886 1.1 mrg poplevel (1, 1);
7887 1.1 mrg
7888 1.1 mrg BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
7889 1.1 mrg DECL_SAVED_TREE (fndecl)
7890 1.1 mrg = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
7891 1.1 mrg DECL_INITIAL (fndecl));
7892 1.1 mrg
7893 1.1 mrg free_after_parsing (cfun);
7894 1.1 mrg free_after_compilation (cfun);
7895 1.1 mrg
7896 1.1 mrg tree_rest_of_compilation (fndecl);
7897 1.1 mrg
7898 1.1 mrg current_function_decl = NULL_TREE;
7899 1.1 mrg #endif
7900 1.1 mrg }
7901 1.1 mrg
7902 1.1 mrg /* Translates a BLOCK DATA program unit. This means emitting the
7903 1.1 mrg commons contained therein plus their initializations. We also emit
7904 1.1 mrg a globally visible symbol to make sure that each BLOCK DATA program
7905 1.1 mrg unit remains unique. */
7906 1.1 mrg
7907 1.1 mrg void
7908 1.1 mrg gfc_generate_block_data (gfc_namespace * ns)
7909 1.1 mrg {
7910 1.1 mrg tree decl;
7911 1.1 mrg tree id;
7912 1.1 mrg
7913 1.1 mrg /* Tell the backend the source location of the block data. */
7914 1.1 mrg if (ns->proc_name)
7915 1.1 mrg gfc_set_backend_locus (&ns->proc_name->declared_at);
7916 1.1 mrg else
7917 1.1 mrg gfc_set_backend_locus (&gfc_current_locus);
7918 1.1 mrg
7919 1.1 mrg /* Process the DATA statements. */
7920 1.1 mrg gfc_trans_common (ns);
7921 1.1 mrg
7922 1.1 mrg /* Create a global symbol with the mane of the block data. This is to
7923 1.1 mrg generate linker errors if the same name is used twice. It is never
7924 1.1 mrg really used. */
7925 1.1 mrg if (ns->proc_name)
7926 1.1 mrg id = gfc_sym_mangled_function_id (ns->proc_name);
7927 1.1 mrg else
7928 1.1 mrg id = get_identifier ("__BLOCK_DATA__");
7929 1.1 mrg
7930 1.1 mrg decl = build_decl (input_location,
7931 1.1 mrg VAR_DECL, id, gfc_array_index_type);
7932 1.1 mrg TREE_PUBLIC (decl) = 1;
7933 1.1 mrg TREE_STATIC (decl) = 1;
7934 1.1 mrg DECL_IGNORED_P (decl) = 1;
7935 1.1 mrg
7936 1.1 mrg pushdecl (decl);
7937 1.1 mrg rest_of_decl_compilation (decl, 1, 0);
7938 1.1 mrg }
7939 1.1 mrg
7940 1.1 mrg
7941 1.1 mrg /* Process the local variables of a BLOCK construct. */
7942 1.1 mrg
7943 1.1 mrg void
7944 1.1 mrg gfc_process_block_locals (gfc_namespace* ns)
7945 1.1 mrg {
7946 1.1 mrg tree decl;
7947 1.1 mrg
7948 1.1 mrg saved_local_decls = NULL_TREE;
7949 1.1 mrg has_coarray_vars = false;
7950 1.1 mrg
7951 1.1 mrg generate_local_vars (ns);
7952 1.1 mrg
7953 1.1 mrg if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
7954 1.1 mrg generate_coarray_init (ns);
7955 1.1 mrg
7956 1.1 mrg decl = nreverse (saved_local_decls);
7957 1.1 mrg while (decl)
7958 1.1 mrg {
7959 1.1 mrg tree next;
7960 1.1 mrg
7961 1.1 mrg next = DECL_CHAIN (decl);
7962 1.1 mrg DECL_CHAIN (decl) = NULL_TREE;
7963 1.1 mrg pushdecl (decl);
7964 1.1 mrg decl = next;
7965 1.1 mrg }
7966 1.1 mrg saved_local_decls = NULL_TREE;
7967 1.1 mrg }
7968 1.1 mrg
7969 1.1 mrg
7970 1.1 mrg #include "gt-fortran-trans-decl.h"
7971