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