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