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