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