]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/trans-decl.c
Add "native" as a valid option value for -march= on i386 (PR driver/83193).
[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{
90ba9145 3502 tree gfc_int4_type_node = gfc_get_int_type (4);
4ee9c684 3503
241ecdc7 3504 gfor_fndecl_stop_numeric = gfc_build_library_function_decl (
3505 get_identifier (PREFIX("stop_numeric")),
3506 void_type_node, 1, gfc_int4_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.",
3512 void_type_node, 2, pchar_type_node, gfc_int4_type_node);
070cc790 3513 /* STOP doesn't return. */
241ecdc7 3514 TREE_THIS_VOLATILE (gfor_fndecl_stop_string) = 1;
537824d1 3515
241ecdc7 3516 gfor_fndecl_error_stop_numeric = gfc_build_library_function_decl (
3517 get_identifier (PREFIX("error_stop_numeric")),
3518 void_type_node, 1, gfc_int4_type_node);
070cc790 3519 /* ERROR STOP doesn't return. */
3520 TREE_THIS_VOLATILE (gfor_fndecl_error_stop_numeric) = 1;
3521
241ecdc7 3522 gfor_fndecl_error_stop_string = gfc_build_library_function_decl_with_spec (
3523 get_identifier (PREFIX("error_stop_string")), ".R.",
3524 void_type_node, 2, pchar_type_node, gfc_int4_type_node);
c6cd3066 3525 /* ERROR STOP doesn't return. */
3526 TREE_THIS_VOLATILE (gfor_fndecl_error_stop_string) = 1;
3527
241ecdc7 3528 gfor_fndecl_pause_numeric = gfc_build_library_function_decl (
3529 get_identifier (PREFIX("pause_numeric")),
3530 void_type_node, 1, gfc_int4_type_node);
070cc790 3531
241ecdc7 3532 gfor_fndecl_pause_string = gfc_build_library_function_decl_with_spec (
3533 get_identifier (PREFIX("pause_string")), ".R.",
3534 void_type_node, 2, pchar_type_node, gfc_int4_type_node);
4ee9c684 3535
241ecdc7 3536 gfor_fndecl_runtime_error = gfc_build_library_function_decl_with_spec (
3537 get_identifier (PREFIX("runtime_error")), ".R",
3538 void_type_node, -1, pchar_type_node);
9c0f3811 3539 /* The runtime_error function does not return. */
3540 TREE_THIS_VOLATILE (gfor_fndecl_runtime_error) = 1;
4ee9c684 3541
241ecdc7 3542 gfor_fndecl_runtime_error_at = gfc_build_library_function_decl_with_spec (
3543 get_identifier (PREFIX("runtime_error_at")), ".RR",
3544 void_type_node, -2, pchar_type_node, pchar_type_node);
50ad5fa2 3545 /* The runtime_error_at function does not return. */
3546 TREE_THIS_VOLATILE (gfor_fndecl_runtime_error_at) = 1;
a90fe829 3547
241ecdc7 3548 gfor_fndecl_runtime_warning_at = gfc_build_library_function_decl_with_spec (
3549 get_identifier (PREFIX("runtime_warning_at")), ".RR",
3550 void_type_node, -2, pchar_type_node, pchar_type_node);
3551
3552 gfor_fndecl_generate_error = gfc_build_library_function_decl_with_spec (
3553 get_identifier (PREFIX("generate_error")), ".R.R",
3554 void_type_node, 3, pvoid_type_node, integer_type_node,
3555 pchar_type_node);
3556
3557 gfor_fndecl_os_error = gfc_build_library_function_decl_with_spec (
3558 get_identifier (PREFIX("os_error")), ".R",
3559 void_type_node, 1, pchar_type_node);
9915365e 3560 /* The runtime_error function does not return. */
3561 TREE_THIS_VOLATILE (gfor_fndecl_os_error) = 1;
3562
241ecdc7 3563 gfor_fndecl_set_args = gfc_build_library_function_decl (
3564 get_identifier (PREFIX("set_args")),
3565 void_type_node, 2, integer_type_node,
3566 build_pointer_type (pchar_type_node));
7257a5d2 3567
241ecdc7 3568 gfor_fndecl_set_fpe = gfc_build_library_function_decl (
3569 get_identifier (PREFIX("set_fpe")),
3570 void_type_node, 1, integer_type_node);
8c84a5de 3571
d566c3e0 3572 gfor_fndecl_ieee_procedure_entry = gfc_build_library_function_decl (
3573 get_identifier (PREFIX("ieee_procedure_entry")),
3574 void_type_node, 1, pvoid_type_node);
3575
3576 gfor_fndecl_ieee_procedure_exit = gfc_build_library_function_decl (
3577 get_identifier (PREFIX("ieee_procedure_exit")),
3578 void_type_node, 1, pvoid_type_node);
3579
56c7c2d7 3580 /* Keep the array dimension in sync with the call, later in this file. */
241ecdc7 3581 gfor_fndecl_set_options = gfc_build_library_function_decl_with_spec (
3582 get_identifier (PREFIX("set_options")), "..R",
3583 void_type_node, 2, integer_type_node,
3584 build_pointer_type (integer_type_node));
64fc3c4c 3585
241ecdc7 3586 gfor_fndecl_set_convert = gfc_build_library_function_decl (
3587 get_identifier (PREFIX("set_convert")),
3588 void_type_node, 1, integer_type_node);
15774a8b 3589
241ecdc7 3590 gfor_fndecl_set_record_marker = gfc_build_library_function_decl (
3591 get_identifier (PREFIX("set_record_marker")),
3592 void_type_node, 1, integer_type_node);
f23886ab 3593
241ecdc7 3594 gfor_fndecl_set_max_subrecord_length = gfc_build_library_function_decl (
3595 get_identifier (PREFIX("set_max_subrecord_length")),
3596 void_type_node, 1, integer_type_node);
bbaaa7b1 3597
8ce86007 3598 gfor_fndecl_in_pack = gfc_build_library_function_decl_with_spec (
241ecdc7 3599 get_identifier (PREFIX("internal_pack")), ".r",
3600 pvoid_type_node, 1, pvoid_type_node);
4ee9c684 3601
8ce86007 3602 gfor_fndecl_in_unpack = gfc_build_library_function_decl_with_spec (
241ecdc7 3603 get_identifier (PREFIX("internal_unpack")), ".wR",
3604 void_type_node, 2, pvoid_type_node, pvoid_type_node);
3605
3606 gfor_fndecl_associated = gfc_build_library_function_decl_with_spec (
3607 get_identifier (PREFIX("associated")), ".RR",
3608 integer_type_node, 2, ppvoid_type_node, ppvoid_type_node);
537824d1 3609 DECL_PURE_P (gfor_fndecl_associated) = 1;
bc351485 3610 TREE_NOTHROW (gfor_fndecl_associated) = 1;
4ee9c684 3611
70b5944a 3612 /* Coarray library calls. */
4fe73152 3613 if (flag_coarray == GFC_FCOARRAY_LIB)
70b5944a 3614 {
3615 tree pint_type, pppchar_type;
3616
3617 pint_type = build_pointer_type (integer_type_node);
3618 pppchar_type
3619 = build_pointer_type (build_pointer_type (pchar_type_node));
3620
3621 gfor_fndecl_caf_init = gfc_build_library_function_decl (
65cbb21d 3622 get_identifier (PREFIX("caf_init")), void_type_node,
3623 2, pint_type, pppchar_type);
70b5944a 3624
3625 gfor_fndecl_caf_finalize = gfc_build_library_function_decl (
3626 get_identifier (PREFIX("caf_finalize")), void_type_node, 0);
3627
d44f2f7c 3628 gfor_fndecl_caf_this_image = gfc_build_library_function_decl (
65cbb21d 3629 get_identifier (PREFIX("caf_this_image")), integer_type_node,
3630 1, integer_type_node);
d44f2f7c 3631
3632 gfor_fndecl_caf_num_images = gfc_build_library_function_decl (
65cbb21d 3633 get_identifier (PREFIX("caf_num_images")), integer_type_node,
3634 2, integer_type_node, integer_type_node);
d44f2f7c 3635
a961ca30 3636 gfor_fndecl_caf_register = gfc_build_library_function_decl_with_spec (
eee0cf09 3637 get_identifier (PREFIX("caf_register")), "RRWWWWR", void_type_node, 7,
3638 size_type_node, integer_type_node, ppvoid_type_node, pvoid_type_node,
3639 pint_type, pchar_type_node, integer_type_node);
d0d776fb 3640
3641 gfor_fndecl_caf_deregister = gfc_build_library_function_decl_with_spec (
3d2aa0e8 3642 get_identifier (PREFIX("caf_deregister")), "WRWWR", void_type_node, 5,
3643 ppvoid_type_node, integer_type_node, pint_type, pchar_type_node,
3644 integer_type_node);
a961ca30 3645
5f4a118e 3646 gfor_fndecl_caf_get = gfc_build_library_function_decl_with_spec (
65cbb21d 3647 get_identifier (PREFIX("caf_get")), ".R.RRWRRRW", void_type_node, 10,
3648 pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
9f1c76f9 3649 pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
6b5471d8 3650 boolean_type_node, pint_type);
5f4a118e 3651
3652 gfor_fndecl_caf_send = gfc_build_library_function_decl_with_spec (
6d3cbc0c 3653 get_identifier (PREFIX("caf_send")), ".R.RRRRRRWR", void_type_node, 11,
65cbb21d 3654 pvoid_type_node, size_type_node, integer_type_node, pvoid_type_node,
9f1c76f9 3655 pvoid_type_node, pvoid_type_node, integer_type_node, integer_type_node,
6d3cbc0c 3656 boolean_type_node, pint_type, pvoid_type_node);
5f4a118e 3657
3658 gfor_fndecl_caf_sendget = gfc_build_library_function_decl_with_spec (
eee0cf09 3659 get_identifier (PREFIX("caf_sendget")), ".R.RRRR.RRRRRR",
3660 void_type_node, 14, pvoid_type_node, size_type_node, integer_type_node,
3661 pvoid_type_node, pvoid_type_node, pvoid_type_node, size_type_node,
3662 integer_type_node, pvoid_type_node, pvoid_type_node, integer_type_node,
3663 integer_type_node, boolean_type_node, integer_type_node);
3664
3665 gfor_fndecl_caf_get_by_ref = gfc_build_library_function_decl_with_spec (
7d96ee9e 3666 get_identifier (PREFIX("caf_get_by_ref")), ".RWRRRRRWR", void_type_node,
3667 10, pvoid_type_node, integer_type_node, pvoid_type_node,
3668 pvoid_type_node, integer_type_node, integer_type_node,
3669 boolean_type_node, boolean_type_node, pint_type, integer_type_node);
eee0cf09 3670
3671 gfor_fndecl_caf_send_by_ref = gfc_build_library_function_decl_with_spec (
7d96ee9e 3672 get_identifier (PREFIX("caf_send_by_ref")), ".RRRRRRRWR",
3673 void_type_node, 10, pvoid_type_node, integer_type_node, pvoid_type_node,
3674 pvoid_type_node, integer_type_node, integer_type_node,
3675 boolean_type_node, boolean_type_node, pint_type, integer_type_node);
eee0cf09 3676
3677 gfor_fndecl_caf_sendget_by_ref
3678 = gfc_build_library_function_decl_with_spec (
7d96ee9e 3679 get_identifier (PREFIX("caf_sendget_by_ref")), ".RR.RRRRRWWRR",
3680 void_type_node, 13, pvoid_type_node, integer_type_node,
eee0cf09 3681 pvoid_type_node, pvoid_type_node, integer_type_node,
3682 pvoid_type_node, integer_type_node, integer_type_node,
7d96ee9e 3683 boolean_type_node, pint_type, pint_type, integer_type_node,
3684 integer_type_node);
5f4a118e 3685
70b5944a 3686 gfor_fndecl_caf_sync_all = gfc_build_library_function_decl_with_spec (
96b417f0 3687 get_identifier (PREFIX("caf_sync_all")), ".WW", void_type_node,
79ed4a8e 3688 3, pint_type, pchar_type_node, integer_type_node);
70b5944a 3689
71cf3ae6 3690 gfor_fndecl_caf_sync_memory = gfc_build_library_function_decl_with_spec (
3691 get_identifier (PREFIX("caf_sync_memory")), ".WW", void_type_node,
3692 3, pint_type, pchar_type_node, integer_type_node);
3693
70b5944a 3694 gfor_fndecl_caf_sync_images = gfc_build_library_function_decl_with_spec (
96b417f0 3695 get_identifier (PREFIX("caf_sync_images")), ".RRWW", void_type_node,
3696 5, integer_type_node, pint_type, pint_type,
79ed4a8e 3697 pchar_type_node, integer_type_node);
70b5944a 3698
3699 gfor_fndecl_caf_error_stop = gfc_build_library_function_decl (
3700 get_identifier (PREFIX("caf_error_stop")),
3701 void_type_node, 1, gfc_int4_type_node);
3702 /* CAF's ERROR STOP doesn't return. */
3703 TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop) = 1;
3704
3705 gfor_fndecl_caf_error_stop_str = gfc_build_library_function_decl_with_spec (
3706 get_identifier (PREFIX("caf_error_stop_str")), ".R.",
3707 void_type_node, 2, pchar_type_node, gfc_int4_type_node);
3708 /* CAF's ERROR STOP doesn't return. */
3709 TREE_THIS_VOLATILE (gfor_fndecl_caf_error_stop_str) = 1;
79ed4a8e 3710
ba4d9b7e 3711 gfor_fndecl_caf_stop_numeric = gfc_build_library_function_decl_with_spec (
65cbb21d 3712 get_identifier (PREFIX("caf_stop_numeric")), ".R.",
3713 void_type_node, 1, gfc_int4_type_node);
ba4d9b7e 3714 /* CAF's STOP doesn't return. */
3715 TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_numeric) = 1;
3716
3717 gfor_fndecl_caf_stop_str = gfc_build_library_function_decl_with_spec (
65cbb21d 3718 get_identifier (PREFIX("caf_stop_str")), ".R.",
3719 void_type_node, 2, pchar_type_node, gfc_int4_type_node);
ba4d9b7e 3720 /* CAF's STOP doesn't return. */
3721 TREE_THIS_VOLATILE (gfor_fndecl_caf_stop_str) = 1;
3722
97b9ac34 3723 gfor_fndecl_caf_atomic_def = gfc_build_library_function_decl_with_spec (
3724 get_identifier (PREFIX("caf_atomic_define")), "R..RW",
3725 void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
65cbb21d 3726 pvoid_type_node, pint_type, integer_type_node, integer_type_node);
97b9ac34 3727
3728 gfor_fndecl_caf_atomic_ref = gfc_build_library_function_decl_with_spec (
3729 get_identifier (PREFIX("caf_atomic_ref")), "R..WW",
3730 void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
65cbb21d 3731 pvoid_type_node, pint_type, integer_type_node, integer_type_node);
97b9ac34 3732
3733 gfor_fndecl_caf_atomic_cas = gfc_build_library_function_decl_with_spec (
3734 get_identifier (PREFIX("caf_atomic_cas")), "R..WRRW",
3735 void_type_node, 9, pvoid_type_node, size_type_node, integer_type_node,
65cbb21d 3736 pvoid_type_node, pvoid_type_node, pvoid_type_node, pint_type,
97b9ac34 3737 integer_type_node, integer_type_node);
3738
3739 gfor_fndecl_caf_atomic_op = gfc_build_library_function_decl_with_spec (
3740 get_identifier (PREFIX("caf_atomic_op")), ".R..RWW",
3741 void_type_node, 9, integer_type_node, pvoid_type_node, size_type_node,
3742 integer_type_node, pvoid_type_node, pvoid_type_node, pint_type,
3743 integer_type_node, integer_type_node);
3744
498b946e 3745 gfor_fndecl_caf_lock = gfc_build_library_function_decl_with_spec (
3746 get_identifier (PREFIX("caf_lock")), "R..WWW",
3747 void_type_node, 7, pvoid_type_node, size_type_node, integer_type_node,
3748 pint_type, pint_type, pchar_type_node, integer_type_node);
3749
3750 gfor_fndecl_caf_unlock = gfc_build_library_function_decl_with_spec (
3751 get_identifier (PREFIX("caf_unlock")), "R..WW",
87550f4f 3752 void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
498b946e 3753 pint_type, pchar_type_node, integer_type_node);
3754
bd47f0bc 3755 gfor_fndecl_caf_event_post = gfc_build_library_function_decl_with_spec (
3756 get_identifier (PREFIX("caf_event_post")), "R..WW",
3757 void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
3758 pint_type, pchar_type_node, integer_type_node);
3759
3760 gfor_fndecl_caf_event_wait = gfc_build_library_function_decl_with_spec (
3761 get_identifier (PREFIX("caf_event_wait")), "R..WW",
3762 void_type_node, 6, pvoid_type_node, size_type_node, integer_type_node,
3763 pint_type, pchar_type_node, integer_type_node);
3764
3765 gfor_fndecl_caf_event_query = gfc_build_library_function_decl_with_spec (
3766 get_identifier (PREFIX("caf_event_query")), "R..WW",
3767 void_type_node, 5, pvoid_type_node, size_type_node, integer_type_node,
3768 pint_type, pint_type);
3769
d9ca273e 3770 gfor_fndecl_caf_fail_image = gfc_build_library_function_decl (
3771 get_identifier (PREFIX("caf_fail_image")), void_type_node, 0);
3772 /* CAF's FAIL doesn't return. */
3773 TREE_THIS_VOLATILE (gfor_fndecl_caf_fail_image) = 1;
3774
3775 gfor_fndecl_caf_failed_images
3776 = gfc_build_library_function_decl_with_spec (
3777 get_identifier (PREFIX("caf_failed_images")), "WRR",
3778 void_type_node, 3, pvoid_type_node, ppvoid_type_node,
3779 integer_type_node);
3780
6d3cbc0c 3781 gfor_fndecl_caf_form_team
3782 = gfc_build_library_function_decl_with_spec (
3783 get_identifier (PREFIX("caf_form_team")), "RWR",
3784 void_type_node, 3, integer_type_node, ppvoid_type_node,
3785 integer_type_node);
3786
3787 gfor_fndecl_caf_change_team
3788 = gfc_build_library_function_decl_with_spec (
3789 get_identifier (PREFIX("caf_change_team")), "RR",
3790 void_type_node, 2, ppvoid_type_node,
3791 integer_type_node);
3792
3793 gfor_fndecl_caf_end_team
3794 = gfc_build_library_function_decl (
3795 get_identifier (PREFIX("caf_end_team")), void_type_node, 0);
3796
3797 gfor_fndecl_caf_get_team
3798 = gfc_build_library_function_decl_with_spec (
3799 get_identifier (PREFIX("caf_get_team")), "R",
3800 void_type_node, 1, integer_type_node);
3801
3802 gfor_fndecl_caf_sync_team
3803 = gfc_build_library_function_decl_with_spec (
3804 get_identifier (PREFIX("caf_sync_team")), "RR",
3805 void_type_node, 2, ppvoid_type_node,
3806 integer_type_node);
3807
3808 gfor_fndecl_caf_team_number
3809 = gfc_build_library_function_decl_with_spec (
3810 get_identifier (PREFIX("caf_team_number")), "R",
3811 integer_type_node, 1, integer_type_node);
3812
d9ca273e 3813 gfor_fndecl_caf_image_status
3814 = gfc_build_library_function_decl_with_spec (
3815 get_identifier (PREFIX("caf_image_status")), "RR",
3816 integer_type_node, 2, integer_type_node, ppvoid_type_node);
3817
3818 gfor_fndecl_caf_stopped_images
3819 = gfc_build_library_function_decl_with_spec (
3820 get_identifier (PREFIX("caf_stopped_images")), "WRR",
3821 void_type_node, 3, pvoid_type_node, ppvoid_type_node,
3822 integer_type_node);
3823
52306a18 3824 gfor_fndecl_co_broadcast = gfc_build_library_function_decl_with_spec (
3825 get_identifier (PREFIX("caf_co_broadcast")), "W.WW",
3826 void_type_node, 5, pvoid_type_node, integer_type_node,
3827 pint_type, pchar_type_node, integer_type_node);
3828
79ed4a8e 3829 gfor_fndecl_co_max = gfc_build_library_function_decl_with_spec (
5f4a118e 3830 get_identifier (PREFIX("caf_co_max")), "W.WW",
3831 void_type_node, 6, pvoid_type_node, integer_type_node,
79ed4a8e 3832 pint_type, pchar_type_node, integer_type_node, integer_type_node);
3833
3834 gfor_fndecl_co_min = gfc_build_library_function_decl_with_spec (
5f4a118e 3835 get_identifier (PREFIX("caf_co_min")), "W.WW",
3836 void_type_node, 6, pvoid_type_node, integer_type_node,
79ed4a8e 3837 pint_type, pchar_type_node, integer_type_node, integer_type_node);
3838
e39efcef 3839 gfor_fndecl_co_reduce = gfc_build_library_function_decl_with_spec (
3840 get_identifier (PREFIX("caf_co_reduce")), "W.R.WW",
3841 void_type_node, 8, pvoid_type_node,
65cbb21d 3842 build_pointer_type (build_varargs_function_type_list (void_type_node,
e39efcef 3843 NULL_TREE)),
3844 integer_type_node, integer_type_node, pint_type, pchar_type_node,
3845 integer_type_node, integer_type_node);
3846
79ed4a8e 3847 gfor_fndecl_co_sum = gfc_build_library_function_decl_with_spec (
5f4a118e 3848 get_identifier (PREFIX("caf_co_sum")), "W.WW",
3849 void_type_node, 5, pvoid_type_node, integer_type_node,
79ed4a8e 3850 pint_type, pchar_type_node, integer_type_node);
3d2aa0e8 3851
3852 gfor_fndecl_caf_is_present = gfc_build_library_function_decl_with_spec (
3853 get_identifier (PREFIX("caf_is_present")), "RRR",
3854 integer_type_node, 3, pvoid_type_node, integer_type_node,
3855 pvoid_type_node);
70b5944a 3856 }
3857
4ee9c684 3858 gfc_build_intrinsic_function_decls ();
3859 gfc_build_intrinsic_lib_fndecls ();
3860 gfc_build_io_library_fndecls ();
3861}
3862
3863
231e961a 3864/* Evaluate the length of dummy character variables. */
4ee9c684 3865
c5faa799 3866static void
3867gfc_trans_dummy_character (gfc_symbol *sym, gfc_charlen *cl,
3868 gfc_wrapped_block *block)
4ee9c684 3869{
c5faa799 3870 stmtblock_t init;
4ee9c684 3871
b9c7fce7 3872 gfc_finish_decl (cl->backend_decl);
4ee9c684 3873
c5faa799 3874 gfc_start_block (&init);
4ee9c684 3875
3876 /* Evaluate the string length expression. */
c5faa799 3877 gfc_conv_string_length (cl, NULL, &init);
d4163395 3878
c5faa799 3879 gfc_trans_vla_type_sizes (sym, &init);
d4163395 3880
c5faa799 3881 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4ee9c684 3882}
3883
3884
3885/* Allocate and cleanup an automatic character variable. */
3886
c5faa799 3887static void
3888gfc_trans_auto_character_variable (gfc_symbol * sym, gfc_wrapped_block * block)
4ee9c684 3889{
c5faa799 3890 stmtblock_t init;
4ee9c684 3891 tree decl;
4ee9c684 3892 tree tmp;
3893
22d678e8 3894 gcc_assert (sym->backend_decl);
eeebe20b 3895 gcc_assert (sym->ts.u.cl && sym->ts.u.cl->length);
4ee9c684 3896
3714c8b6 3897 gfc_init_block (&init);
4ee9c684 3898
3899 /* Evaluate the string length expression. */
c5faa799 3900 gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
4ee9c684 3901
c5faa799 3902 gfc_trans_vla_type_sizes (sym, &init);
d4163395 3903
4ee9c684 3904 decl = sym->backend_decl;
3905
afcf285e 3906 /* Emit a DECL_EXPR for this variable, which will cause the
4b3a701c 3907 gimplifier to allocate storage, and all that good stuff. */
fd779e1d 3908 tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
c5faa799 3909 gfc_add_expr_to_block (&init, tmp);
afcf285e 3910
c5faa799 3911 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4ee9c684 3912}
3913
c8f1568f 3914/* Set the initial value of ASSIGN statement auxiliary variable explicitly. */
3915
c5faa799 3916static void
3917gfc_trans_assign_aux_var (gfc_symbol * sym, gfc_wrapped_block * block)
c8f1568f 3918{
c5faa799 3919 stmtblock_t init;
c8f1568f 3920
3921 gcc_assert (sym->backend_decl);
c5faa799 3922 gfc_start_block (&init);
c8f1568f 3923
3924 /* Set the initial value to length. See the comments in
3925 function gfc_add_assign_aux_vars in this file. */
c5faa799 3926 gfc_add_modify (&init, GFC_DECL_STRING_LEN (sym->backend_decl),
35bf1214 3927 build_int_cst (gfc_charlen_type_node, -2));
c8f1568f 3928
c5faa799 3929 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
c8f1568f 3930}
3931
d4163395 3932static void
3933gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
3934{
3935 tree t = *tp, var, val;
3936
3937 if (t == NULL || t == error_mark_node)
3938 return;
3939 if (TREE_CONSTANT (t) || DECL_P (t))
3940 return;
3941
3942 if (TREE_CODE (t) == SAVE_EXPR)
3943 {
3944 if (SAVE_EXPR_RESOLVED_P (t))
3945 {
3946 *tp = TREE_OPERAND (t, 0);
3947 return;
3948 }
3949 val = TREE_OPERAND (t, 0);
3950 }
3951 else
3952 val = t;
3953
3954 var = gfc_create_var_np (TREE_TYPE (t), NULL);
3955 gfc_add_decl_to_function (var);
1ec957b0 3956 gfc_add_modify (body, var, unshare_expr (val));
d4163395 3957 if (TREE_CODE (t) == SAVE_EXPR)
3958 TREE_OPERAND (t, 0) = var;
3959 *tp = var;
3960}
3961
3962static void
3963gfc_trans_vla_type_sizes_1 (tree type, stmtblock_t *body)
3964{
3965 tree t;
3966
3967 if (type == NULL || type == error_mark_node)
3968 return;
3969
3970 type = TYPE_MAIN_VARIANT (type);
3971
3972 if (TREE_CODE (type) == INTEGER_TYPE)
3973 {
3974 gfc_trans_vla_one_sizepos (&TYPE_MIN_VALUE (type), body);
3975 gfc_trans_vla_one_sizepos (&TYPE_MAX_VALUE (type), body);
3976
3977 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
3978 {
3979 TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
3980 TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
3981 }
3982 }
3983 else if (TREE_CODE (type) == ARRAY_TYPE)
3984 {
3985 gfc_trans_vla_type_sizes_1 (TREE_TYPE (type), body);
3986 gfc_trans_vla_type_sizes_1 (TYPE_DOMAIN (type), body);
3987 gfc_trans_vla_one_sizepos (&TYPE_SIZE (type), body);
3988 gfc_trans_vla_one_sizepos (&TYPE_SIZE_UNIT (type), body);
3989
3990 for (t = TYPE_NEXT_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
3991 {
3992 TYPE_SIZE (t) = TYPE_SIZE (type);
3993 TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
3994 }
3995 }
3996}
3997
3998/* Make sure all type sizes and array domains are either constant,
3999 or variable or parameter decls. This is a simplified variant
4000 of gimplify_type_sizes, but we can't use it here, as none of the
4001 variables in the expressions have been gimplified yet.
4002 As type sizes and domains for various variable length arrays
4003 contain VAR_DECLs that are only initialized at gfc_trans_deferred_vars
4004 time, without this routine gimplify_type_sizes in the middle-end
4005 could result in the type sizes being gimplified earlier than where
4006 those variables are initialized. */
4007
4008void
4009gfc_trans_vla_type_sizes (gfc_symbol *sym, stmtblock_t *body)
4010{
4011 tree type = TREE_TYPE (sym->backend_decl);
4012
4013 if (TREE_CODE (type) == FUNCTION_TYPE
4014 && (sym->attr.function || sym->attr.result || sym->attr.entry))
4015 {
4016 if (! current_fake_result_decl)
4017 return;
4018
4019 type = TREE_TYPE (TREE_VALUE (current_fake_result_decl));
4020 }
4021
4022 while (POINTER_TYPE_P (type))
4023 type = TREE_TYPE (type);
4024
4025 if (GFC_DESCRIPTOR_TYPE_P (type))
4026 {
4027 tree etype = GFC_TYPE_ARRAY_DATAPTR_TYPE (type);
4028
4029 while (POINTER_TYPE_P (etype))
4030 etype = TREE_TYPE (etype);
4031
4032 gfc_trans_vla_type_sizes_1 (etype, body);
4033 }
4034
4035 gfc_trans_vla_type_sizes_1 (type, body);
4036}
4037
4ee9c684 4038
f0d4969f 4039/* Initialize a derived type by building an lvalue from the symbol
a545a8f8 4040 and using trans_assignment to do the work. Set dealloc to false
4041 if no deallocation prior the assignment is needed. */
c5faa799 4042void
4043gfc_init_default_dt (gfc_symbol * sym, stmtblock_t * block, bool dealloc)
87114d2e 4044{
f0d4969f 4045 gfc_expr *e;
87114d2e 4046 tree tmp;
4047 tree present;
4048
c5faa799 4049 gcc_assert (block);
4050
f0efd2e8 4051 /* Initialization of PDTs is done elsewhere. */
4052 if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
4053 return;
4054
f0d4969f 4055 gcc_assert (!sym->attr.allocatable);
4056 gfc_set_sym_referenced (sym);
4057 e = gfc_lval_expr_from_sym (sym);
a545a8f8 4058 tmp = gfc_trans_assignment (e, sym->value, false, dealloc);
c38054a8 4059 if (sym->attr.dummy && (sym->attr.optional
4060 || sym->ns->proc_name->attr.entry_master))
87114d2e 4061 {
f0d4969f 4062 present = gfc_conv_expr_present (sym);
2be9d8f1 4063 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp), present,
4064 tmp, build_empty_stmt (input_location));
87114d2e 4065 }
c5faa799 4066 gfc_add_expr_to_block (block, tmp);
f0d4969f 4067 gfc_free_expr (e);
87114d2e 4068}
4069
4070
8714fc76 4071/* Initialize INTENT(OUT) derived type dummies. As well as giving
4072 them their default initializer, if they do not have allocatable
293d72e0 4073 components, they have their allocatable components deallocated. */
8714fc76 4074
c5faa799 4075static void
4076init_intent_out_dt (gfc_symbol * proc_sym, gfc_wrapped_block * block)
f0d4969f 4077{
c5faa799 4078 stmtblock_t init;
f0d4969f 4079 gfc_formal_arglist *f;
8714fc76 4080 tree tmp;
5907c3ea 4081 tree present;
f0d4969f 4082
c5faa799 4083 gfc_init_block (&init);
6777213b 4084 for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
f0d4969f 4085 if (f->sym && f->sym->attr.intent == INTENT_OUT
c49db15e 4086 && !f->sym->attr.pointer
4087 && f->sym->ts.type == BT_DERIVED)
8714fc76 4088 {
942ba353 4089 tmp = NULL_TREE;
4090
4091 /* Note: Allocatables are excluded as they are already handled
4092 by the caller. */
4093 if (!f->sym->attr.allocatable
4094 && gfc_is_finalizable (f->sym->ts.u.derived, NULL))
8714fc76 4095 {
942ba353 4096 stmtblock_t block;
4097 gfc_expr *e;
4098
4099 gfc_init_block (&block);
4100 f->sym->attr.referenced = 1;
4101 e = gfc_lval_expr_from_sym (f->sym);
4102 gfc_add_finalizer_call (&block, e);
4103 gfc_free_expr (e);
4104 tmp = gfc_finish_block (&block);
4105 }
5907c3ea 4106
942ba353 4107 if (tmp == NULL_TREE && !f->sym->attr.allocatable
4108 && f->sym->ts.u.derived->attr.alloc_comp && !f->sym->value)
4109 tmp = gfc_deallocate_alloc_comp (f->sym->ts.u.derived,
4110 f->sym->backend_decl,
4111 f->sym->as ? f->sym->as->rank : 0);
5907c3ea 4112
942ba353 4113 if (tmp != NULL_TREE && (f->sym->attr.optional
4114 || f->sym->ns->proc_name->attr.entry_master))
4115 {
4116 present = gfc_conv_expr_present (f->sym);
4117 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
4118 present, tmp, build_empty_stmt (input_location));
8714fc76 4119 }
942ba353 4120
4121 if (tmp != NULL_TREE)
4122 gfc_add_expr_to_block (&init, tmp);
4123 else if (f->sym->value && !f->sym->attr.allocatable)
c5faa799 4124 gfc_init_default_dt (f->sym, &init, true);
8714fc76 4125 }
c56d57d6 4126 else if (f->sym && f->sym->attr.intent == INTENT_OUT
4127 && f->sym->ts.type == BT_CLASS
4128 && !CLASS_DATA (f->sym)->attr.class_pointer
942ba353 4129 && !CLASS_DATA (f->sym)->attr.allocatable)
c56d57d6 4130 {
942ba353 4131 stmtblock_t block;
4132 gfc_expr *e;
4133
4134 gfc_init_block (&block);
4135 f->sym->attr.referenced = 1;
4136 e = gfc_lval_expr_from_sym (f->sym);
4137 gfc_add_finalizer_call (&block, e);
4138 gfc_free_expr (e);
4139 tmp = gfc_finish_block (&block);
c56d57d6 4140
4141 if (f->sym->attr.optional || f->sym->ns->proc_name->attr.entry_master)
4142 {
4143 present = gfc_conv_expr_present (f->sym);
4144 tmp = build3_loc (input_location, COND_EXPR, TREE_TYPE (tmp),
4145 present, tmp,
4146 build_empty_stmt (input_location));
4147 }
4148
4149 gfc_add_expr_to_block (&init, tmp);
4150 }
f0d4969f 4151
c5faa799 4152 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
f0d4969f 4153}
4154
87114d2e 4155
b345a09f 4156/* Helper function to manage deferred string lengths. */
4157
4158static tree
4159gfc_null_and_pass_deferred_len (gfc_symbol *sym, stmtblock_t *init,
4160 locus *loc)
4161{
4162 tree tmp;
4163
4164 /* Character length passed by reference. */
4165 tmp = sym->ts.u.cl->passed_length;
4166 tmp = build_fold_indirect_ref_loc (input_location, tmp);
4167 tmp = fold_convert (gfc_charlen_type_node, tmp);
4168
4169 if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
4170 /* Zero the string length when entering the scope. */
4171 gfc_add_modify (init, sym->ts.u.cl->backend_decl,
4172 build_int_cst (gfc_charlen_type_node, 0));
4173 else
4174 {
4175 tree tmp2;
4176
4177 tmp2 = fold_build2_loc (input_location, MODIFY_EXPR,
4178 gfc_charlen_type_node,
4179 sym->ts.u.cl->backend_decl, tmp);
4180 if (sym->attr.optional)
4181 {
4182 tree present = gfc_conv_expr_present (sym);
4183 tmp2 = build3_loc (input_location, COND_EXPR,
4184 void_type_node, present, tmp2,
4185 build_empty_stmt (input_location));
4186 }
4187 gfc_add_expr_to_block (init, tmp2);
4188 }
4189
4190 gfc_restore_backend_locus (loc);
4191
4192 /* Pass the final character length back. */
4193 if (sym->attr.intent != INTENT_IN)
4194 {
4195 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
4196 gfc_charlen_type_node, tmp,
4197 sym->ts.u.cl->backend_decl);
4198 if (sym->attr.optional)
4199 {
4200 tree present = gfc_conv_expr_present (sym);
4201 tmp = build3_loc (input_location, COND_EXPR,
4202 void_type_node, present, tmp,
4203 build_empty_stmt (input_location));
4204 }
4205 }
4206 else
4207 tmp = NULL_TREE;
4208
4209 return tmp;
4210}
4211
9ead5324 4212
4213/* Get the result expression for a procedure. */
4214
4215static tree
4216get_proc_result (gfc_symbol* sym)
4217{
4218 if (sym->attr.subroutine || sym == sym->result)
4219 {
4220 if (current_fake_result_decl != NULL)
4221 return TREE_VALUE (current_fake_result_decl);
4222
4223 return NULL_TREE;
4224 }
4225
4226 return sym->result->backend_decl;
4227}
4228
4229
4ee9c684 4230/* Generate function entry and exit code, and add it to the function body.
4231 This includes:
f888a3fb 4232 Allocation and initialization of array variables.
4ee9c684 4233 Allocation of character string variables.
c8f1568f 4234 Initialization and possibly repacking of dummy arrays.
0a96a7cc 4235 Initialization of ASSIGN statement auxiliary variable.
8f3f9eab 4236 Initialization of ASSOCIATE names.
0a96a7cc 4237 Automatic deallocation. */
4ee9c684 4238
89ac8ba1 4239void
4240gfc_trans_deferred_vars (gfc_symbol * proc_sym, gfc_wrapped_block * block)
4ee9c684 4241{
4242 locus loc;
4243 gfc_symbol *sym;
d4163395 4244 gfc_formal_arglist *f;
c5faa799 4245 stmtblock_t tmpblock;
25dd7350 4246 bool seen_trans_deferred_array = false;
9d958d5b 4247 bool is_pdt_type = false;
617125a6 4248 tree tmp = NULL;
4249 gfc_expr *e;
4250 gfc_se se;
4251 stmtblock_t init;
4ee9c684 4252
4253 /* Deal with implicit return variables. Explicit return variables will
4254 already have been added. */
4255 if (gfc_return_by_reference (proc_sym) && proc_sym->result == proc_sym)
4256 {
4257 if (!current_fake_result_decl)
4258 {
c6871095 4259 gfc_entry_list *el = NULL;
4260 if (proc_sym->attr.entry_master)
4261 {
4262 for (el = proc_sym->ns->entries; el; el = el->next)
4263 if (el->sym != el->sym->result)
4264 break;
4265 }
fa7b6574 4266 /* TODO: move to the appropriate place in resolve.c. */
8b72061f 4267 if (warn_return_type > 0 && el == NULL)
4166acc7 4268 gfc_warning (OPT_Wreturn_type,
4269 "Return value of function %qs at %L not set",
fa7b6574 4270 proc_sym->name, &proc_sym->declared_at);
4ee9c684 4271 }
c6871095 4272 else if (proc_sym->as)
4ee9c684 4273 {
d4163395 4274 tree result = TREE_VALUE (current_fake_result_decl);
9da84a54 4275 gfc_save_backend_locus (&loc);
4276 gfc_set_backend_locus (&proc_sym->declared_at);
89ac8ba1 4277 gfc_trans_dummy_array_bias (proc_sym, result, block);
10b07432 4278
4279 /* An automatic character length, pointer array result. */
4280 if (proc_sym->ts.type == BT_CHARACTER
fe732a9b 4281 && VAR_P (proc_sym->ts.u.cl->backend_decl))
b345a09f 4282 {
4283 tmp = NULL;
4284 if (proc_sym->ts.deferred)
4285 {
b345a09f 4286 gfc_start_block (&init);
4287 tmp = gfc_null_and_pass_deferred_len (proc_sym, &init, &loc);
4288 gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4289 }
4290 else
4291 gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
4292 }
4ee9c684 4293 }
4294 else if (proc_sym->ts.type == BT_CHARACTER)
4295 {
617125a6 4296 if (proc_sym->ts.deferred)
4297 {
4298 tmp = NULL;
da2c4122 4299 gfc_save_backend_locus (&loc);
4300 gfc_set_backend_locus (&proc_sym->declared_at);
617125a6 4301 gfc_start_block (&init);
4302 /* Zero the string length on entry. */
4303 gfc_add_modify (&init, proc_sym->ts.u.cl->backend_decl,
4304 build_int_cst (gfc_charlen_type_node, 0));
4305 /* Null the pointer. */
4306 e = gfc_lval_expr_from_sym (proc_sym);
4307 gfc_init_se (&se, NULL);
4308 se.want_pointer = 1;
4309 gfc_conv_expr (&se, e);
4310 gfc_free_expr (e);
4311 tmp = se.expr;
4312 gfc_add_modify (&init, tmp,
4313 fold_convert (TREE_TYPE (se.expr),
4314 null_pointer_node));
da2c4122 4315 gfc_restore_backend_locus (&loc);
617125a6 4316
4317 /* Pass back the string length on exit. */
ddcfeaf1 4318 tmp = proc_sym->ts.u.cl->backend_decl;
b345a09f 4319 if (TREE_CODE (tmp) != INDIRECT_REF
4320 && proc_sym->ts.u.cl->passed_length)
ddcfeaf1 4321 {
a4731200 4322 tmp = proc_sym->ts.u.cl->passed_length;
4323 tmp = build_fold_indirect_ref_loc (input_location, tmp);
a4731200 4324 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
9f4d9f83 4325 TREE_TYPE (tmp), tmp,
4326 fold_convert
4327 (TREE_TYPE (tmp),
4328 proc_sym->ts.u.cl->backend_decl));
ddcfeaf1 4329 }
4330 else
4331 tmp = NULL_TREE;
4332
617125a6 4333 gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4334 }
fe732a9b 4335 else if (VAR_P (proc_sym->ts.u.cl->backend_decl))
89ac8ba1 4336 gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, block);
4ee9c684 4337 }
4338 else
829d7a08 4339 gcc_assert (flag_f2c && proc_sym->ts.type == BT_COMPLEX);
4ee9c684 4340 }
9ead5324 4341 else if (proc_sym == proc_sym->result && IS_CLASS_ARRAY (proc_sym))
4342 {
4343 /* Nullify explicit return class arrays on entry. */
4344 tree type;
4345 tmp = get_proc_result (proc_sym);
4346 if (tmp && GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
4347 {
4348 gfc_start_block (&init);
4349 tmp = gfc_class_data_get (tmp);
4350 type = TREE_TYPE (gfc_conv_descriptor_data_get (tmp));
4351 gfc_conv_descriptor_data_set (&init, tmp, build_int_cst (type, 0));
4352 gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
4353 }
4354 }
4355
4ee9c684 4356
87114d2e 4357 /* Initialize the INTENT(OUT) derived type dummy arguments. This
4358 should be done here so that the offsets and lbounds of arrays
4359 are available. */
da2c4122 4360 gfc_save_backend_locus (&loc);
4361 gfc_set_backend_locus (&proc_sym->declared_at);
89ac8ba1 4362 init_intent_out_dt (proc_sym, block);
da2c4122 4363 gfc_restore_backend_locus (&loc);
87114d2e 4364
4ee9c684 4365 for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink)
4366 {
6b3ceb4e 4367 bool alloc_comp_or_fini = (sym->ts.type == BT_DERIVED)
4368 && (sym->ts.u.derived->attr.alloc_comp
4369 || gfc_is_finalizable (sym->ts.u.derived,
4370 NULL));
8f3f9eab 4371 if (sym->assoc)
3c82e013 4372 continue;
4373
9d958d5b 4374 if (sym->ts.type == BT_DERIVED
4375 && sym->ts.u.derived
4376 && sym->ts.u.derived->attr.pdt_type)
4377 {
4378 is_pdt_type = true;
4379 gfc_init_block (&tmpblock);
4380 if (!(sym->attr.dummy
4381 || sym->attr.pointer
4382 || sym->attr.allocatable))
4383 {
4384 tmp = gfc_allocate_pdt_comp (sym->ts.u.derived,
4385 sym->backend_decl,
4386 sym->as ? sym->as->rank : 0,
4387 sym->param_list);
4388 gfc_add_expr_to_block (&tmpblock, tmp);
2222c3ab 4389 if (!sym->attr.result)
4390 tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived,
4391 sym->backend_decl,
4392 sym->as ? sym->as->rank : 0);
4393 else
4394 tmp = NULL_TREE;
9d958d5b 4395 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
4396 }
4397 else if (sym->attr.dummy)
4398 {
4399 tmp = gfc_check_pdt_dummy (sym->ts.u.derived,
4400 sym->backend_decl,
4401 sym->as ? sym->as->rank : 0,
4402 sym->param_list);
4403 gfc_add_expr_to_block (&tmpblock, tmp);
4404 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
4405 }
4406 }
4407 else if (sym->ts.type == BT_CLASS
4408 && CLASS_DATA (sym)->ts.u.derived
4409 && CLASS_DATA (sym)->ts.u.derived->attr.pdt_type)
4410 {
4411 gfc_component *data = CLASS_DATA (sym);
4412 is_pdt_type = true;
4413 gfc_init_block (&tmpblock);
4414 if (!(sym->attr.dummy
4415 || CLASS_DATA (sym)->attr.pointer
4416 || CLASS_DATA (sym)->attr.allocatable))
4417 {
4418 tmp = gfc_class_data_get (sym->backend_decl);
4419 tmp = gfc_allocate_pdt_comp (data->ts.u.derived, tmp,
4420 data->as ? data->as->rank : 0,
4421 sym->param_list);
4422 gfc_add_expr_to_block (&tmpblock, tmp);
4423 tmp = gfc_class_data_get (sym->backend_decl);
2222c3ab 4424 if (!sym->attr.result)
4425 tmp = gfc_deallocate_pdt_comp (data->ts.u.derived, tmp,
4426 data->as ? data->as->rank : 0);
4427 else
4428 tmp = NULL_TREE;
9d958d5b 4429 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), tmp);
4430 }
4431 else if (sym->attr.dummy)
4432 {
4433 tmp = gfc_class_data_get (sym->backend_decl);
4434 tmp = gfc_check_pdt_dummy (data->ts.u.derived, tmp,
4435 data->as ? data->as->rank : 0,
4436 sym->param_list);
4437 gfc_add_expr_to_block (&tmpblock, tmp);
4438 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL);
4439 }
4440 }
4441
47e6a59a 4442 if (sym->attr.pointer && sym->attr.dimension
0a5fd921 4443 && sym->attr.save == SAVE_NONE
47e6a59a 4444 && !sym->attr.use_assoc
4445 && !sym->attr.host_assoc
4446 && !sym->attr.dummy
4447 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)))
a56d63bc 4448 {
4449 gfc_init_block (&tmpblock);
47e6a59a 4450 gfc_conv_descriptor_span_set (&tmpblock, sym->backend_decl,
4451 build_int_cst (gfc_array_index_type, 0));
a56d63bc 4452 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
4453 NULL_TREE);
4454 }
4455
85ae3cab 4456 if (sym->ts.type == BT_CLASS
eb106faf 4457 && (sym->attr.save || flag_max_stack_var_size == 0)
fb139b21 4458 && CLASS_DATA (sym)->attr.allocatable)
4459 {
4460 tree vptr;
4461
4462 if (UNLIMITED_POLY (sym))
4463 vptr = null_pointer_node;
4464 else
4465 {
4466 gfc_symbol *vsym;
4467 vsym = gfc_find_derived_vtab (sym->ts.u.derived);
4468 vptr = gfc_get_symbol_decl (vsym);
4469 vptr = gfc_build_addr_expr (NULL, vptr);
4470 }
4471
4472 if (CLASS_DATA (sym)->attr.dimension
4473 || (CLASS_DATA (sym)->attr.codimension
4fe73152 4474 && flag_coarray != GFC_FCOARRAY_LIB))
fb139b21 4475 {
4476 tmp = gfc_class_data_get (sym->backend_decl);
4477 tmp = gfc_build_null_descriptor (TREE_TYPE (tmp));
4478 }
4479 else
4480 tmp = null_pointer_node;
4481
4482 DECL_INITIAL (sym->backend_decl)
4483 = gfc_class_set_static_fields (sym->backend_decl, vptr, tmp);
4484 TREE_CONSTANT (DECL_INITIAL (sym->backend_decl)) = 1;
4485 }
b345a09f 4486 else if ((sym->attr.dimension || sym->attr.codimension
4487 || (IS_CLASS_ARRAY (sym) && !CLASS_DATA (sym)->attr.allocatable)))
4ee9c684 4488 {
c6793847 4489 bool is_classarray = IS_CLASS_ARRAY (sym);
4490 symbol_attribute *array_attr;
4491 gfc_array_spec *as;
b345a09f 4492 array_type type_of_array;
c6793847 4493
4494 array_attr = is_classarray ? &CLASS_DATA (sym)->attr : &sym->attr;
4495 as = is_classarray ? CLASS_DATA (sym)->as : sym->as;
4496 /* Assumed-size Cray pointees need to be treated as AS_EXPLICIT. */
b345a09f 4497 type_of_array = as->type;
4498 if (type_of_array == AS_ASSUMED_SIZE && as->cp_was_assumed)
4499 type_of_array = AS_EXPLICIT;
4500 switch (type_of_array)
4ee9c684 4501 {
4502 case AS_EXPLICIT:
4503 if (sym->attr.dummy || sym->attr.result)
89ac8ba1 4504 gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
c6793847 4505 /* Allocatable and pointer arrays need to processed
4506 explicitly. */
4507 else if ((sym->ts.type != BT_CLASS && sym->attr.pointer)
4508 || (sym->ts.type == BT_CLASS
4509 && CLASS_DATA (sym)->attr.class_pointer)
4510 || array_attr->allocatable)
4ee9c684 4511 {
4512 if (TREE_STATIC (sym->backend_decl))
da2c4122 4513 {
4514 gfc_save_backend_locus (&loc);
4515 gfc_set_backend_locus (&sym->declared_at);
4516 gfc_trans_static_array_pointer (sym);
4517 gfc_restore_backend_locus (&loc);
4518 }
4ee9c684 4519 else
25dd7350 4520 {
4521 seen_trans_deferred_array = true;
89ac8ba1 4522 gfc_trans_deferred_array (sym, block);
25dd7350 4523 }
4ee9c684 4524 }
c6793847 4525 else if (sym->attr.codimension
4526 && TREE_STATIC (sym->backend_decl))
7c7db7f6 4527 {
4528 gfc_init_block (&tmpblock);
4529 gfc_trans_array_cobounds (TREE_TYPE (sym->backend_decl),
4530 &tmpblock, sym);
4531 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
4532 NULL_TREE);
4533 continue;
4534 }
197423f5 4535 else
4ee9c684 4536 {
da2c4122 4537 gfc_save_backend_locus (&loc);
4538 gfc_set_backend_locus (&sym->declared_at);
4539
6b3ceb4e 4540 if (alloc_comp_or_fini)
25dd7350 4541 {
4542 seen_trans_deferred_array = true;
89ac8ba1 4543 gfc_trans_deferred_array (sym, block);
25dd7350 4544 }
f0d4969f 4545 else if (sym->ts.type == BT_DERIVED
4546 && sym->value
4547 && !sym->attr.data
4548 && sym->attr.save == SAVE_NONE)
c5faa799 4549 {
4550 gfc_start_block (&tmpblock);
4551 gfc_init_default_dt (sym, &tmpblock, false);
89ac8ba1 4552 gfc_add_init_cleanup (block,
c5faa799 4553 gfc_finish_block (&tmpblock),
4554 NULL_TREE);
4555 }
25dd7350 4556
c5faa799 4557 gfc_trans_auto_array_allocation (sym->backend_decl,
89ac8ba1 4558 sym, block);
4671339c 4559 gfc_restore_backend_locus (&loc);
4ee9c684 4560 }
4561 break;
4562
4563 case AS_ASSUMED_SIZE:
4564 /* Must be a dummy parameter. */
c6793847 4565 gcc_assert (sym->attr.dummy || as->cp_was_assumed);
4ee9c684 4566
4567 /* We should always pass assumed size arrays the g77 way. */
452695a8 4568 if (sym->attr.dummy)
89ac8ba1 4569 gfc_trans_g77_array (sym, block);
c5faa799 4570 break;
4ee9c684 4571
4572 case AS_ASSUMED_SHAPE:
4573 /* Must be a dummy parameter. */
22d678e8 4574 gcc_assert (sym->attr.dummy);
4ee9c684 4575
89ac8ba1 4576 gfc_trans_dummy_array_bias (sym, sym->backend_decl, block);
4ee9c684 4577 break;
4578
f00f6dd6 4579 case AS_ASSUMED_RANK:
4ee9c684 4580 case AS_DEFERRED:
25dd7350 4581 seen_trans_deferred_array = true;
89ac8ba1 4582 gfc_trans_deferred_array (sym, block);
b345a09f 4583 if (sym->ts.type == BT_CHARACTER && sym->ts.deferred
4584 && sym->attr.result)
4585 {
4586 gfc_start_block (&init);
4587 gfc_save_backend_locus (&loc);
4588 gfc_set_backend_locus (&sym->declared_at);
4589 tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc);
4590 gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4591 }
4ee9c684 4592 break;
4593
4594 default:
22d678e8 4595 gcc_unreachable ();
4ee9c684 4596 }
6b3ceb4e 4597 if (alloc_comp_or_fini && !seen_trans_deferred_array)
89ac8ba1 4598 gfc_trans_deferred_array (sym, block);
4ee9c684 4599 }
fd23cc08 4600 else if ((!sym->attr.dummy || sym->ts.deferred)
4601 && (sym->ts.type == BT_CLASS
3a19c063 4602 && CLASS_DATA (sym)->attr.class_pointer))
2930c007 4603 continue;
617125a6 4604 else if ((!sym->attr.dummy || sym->ts.deferred)
456dd7d6 4605 && (sym->attr.allocatable
b345a09f 4606 || (sym->attr.pointer && sym->attr.result)
456dd7d6 4607 || (sym->ts.type == BT_CLASS
4608 && CLASS_DATA (sym)->attr.allocatable)))
0a96a7cc 4609 {
eb106faf 4610 if (!sym->attr.save && flag_max_stack_var_size != 0)
908e9973 4611 {
d0d776fb 4612 tree descriptor = NULL_TREE;
4613
da2c4122 4614 gfc_save_backend_locus (&loc);
4615 gfc_set_backend_locus (&sym->declared_at);
c5faa799 4616 gfc_start_block (&init);
617125a6 4617
b345a09f 4618 if (!sym->attr.pointer)
617125a6 4619 {
b345a09f 4620 /* Nullify and automatic deallocation of allocatable
4621 scalars. */
4622 e = gfc_lval_expr_from_sym (sym);
4623 if (sym->ts.type == BT_CLASS)
4624 gfc_add_data_component (e);
4625
4626 gfc_init_se (&se, NULL);
4627 if (sym->ts.type != BT_CLASS
4628 || sym->ts.u.derived->attr.dimension
4629 || sym->ts.u.derived->attr.codimension)
883d6776 4630 {
b345a09f 4631 se.want_pointer = 1;
4632 gfc_conv_expr (&se, e);
4633 }
4634 else if (sym->ts.type == BT_CLASS
4635 && !CLASS_DATA (sym)->attr.dimension
4636 && !CLASS_DATA (sym)->attr.codimension)
4637 {
4638 se.want_pointer = 1;
4639 gfc_conv_expr (&se, e);
883d6776 4640 }
617125a6 4641 else
883d6776 4642 {
b345a09f 4643 se.descriptor_only = 1;
4644 gfc_conv_expr (&se, e);
4645 descriptor = se.expr;
4646 se.expr = gfc_conv_descriptor_data_addr (se.expr);
4647 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
883d6776 4648 }
b345a09f 4649 gfc_free_expr (e);
617125a6 4650
b345a09f 4651 if (!sym->attr.dummy || sym->attr.intent == INTENT_OUT)
883d6776 4652 {
b345a09f 4653 /* Nullify when entering the scope. */
883d6776 4654 tmp = fold_build2_loc (input_location, MODIFY_EXPR,
b345a09f 4655 TREE_TYPE (se.expr), se.expr,
4656 fold_convert (TREE_TYPE (se.expr),
4657 null_pointer_node));
883d6776 4658 if (sym->attr.optional)
4659 {
4660 tree present = gfc_conv_expr_present (sym);
4661 tmp = build3_loc (input_location, COND_EXPR,
4662 void_type_node, present, tmp,
4663 build_empty_stmt (input_location));
4664 }
b345a09f 4665 gfc_add_expr_to_block (&init, tmp);
883d6776 4666 }
617125a6 4667 }
b345a09f 4668
4669 if ((sym->attr.dummy || sym->attr.result)
4670 && sym->ts.type == BT_CHARACTER
4671 && sym->ts.deferred
4672 && sym->ts.u.cl->passed_length)
4673 tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc);
da2c4122 4674 else
8c089b5c 4675 {
4676 gfc_restore_backend_locus (&loc);
4677 tmp = NULL_TREE;
4678 }
908e9973 4679
4680 /* Deallocate when leaving the scope. Nullifying is not
4681 needed. */
b345a09f 4682 if (!sym->attr.result && !sym->attr.dummy && !sym->attr.pointer
afb69dbf 4683 && !sym->ns->proc_name->attr.is_main_program)
d0d776fb 4684 {
4685 if (sym->ts.type == BT_CLASS
4686 && CLASS_DATA (sym)->attr.codimension)
4687 tmp = gfc_deallocate_with_status (descriptor, NULL_TREE,
4688 NULL_TREE, NULL_TREE,
4689 NULL_TREE, true, NULL,
3d2aa0e8 4690 GFC_CAF_COARRAY_ANALYZE);
d0d776fb 4691 else
c23adf93 4692 {
4693 gfc_expr *expr = gfc_lval_expr_from_sym (sym);
3d2aa0e8 4694 tmp = gfc_deallocate_scalar_with_status (se.expr,
4695 NULL_TREE,
4696 NULL_TREE,
4697 true, expr,
4698 sym->ts);
c23adf93 4699 gfc_free_expr (expr);
4700 }
d0d776fb 4701 }
b345a09f 4702
afc44c79 4703 if (sym->ts.type == BT_CLASS)
4704 {
4705 /* Initialize _vptr to declared type. */
a90fe829 4706 gfc_symbol *vtab;
afc44c79 4707 tree rhs;
da2c4122 4708
4709 gfc_save_backend_locus (&loc);
4710 gfc_set_backend_locus (&sym->declared_at);
afc44c79 4711 e = gfc_lval_expr_from_sym (sym);
4712 gfc_add_vptr_component (e);
4713 gfc_init_se (&se, NULL);
4714 se.want_pointer = 1;
4715 gfc_conv_expr (&se, e);
4716 gfc_free_expr (e);
a90fe829 4717 if (UNLIMITED_POLY (sym))
4718 rhs = build_int_cst (TREE_TYPE (se.expr), 0);
4719 else
4720 {
4721 vtab = gfc_find_derived_vtab (sym->ts.u.derived);
4722 rhs = gfc_build_addr_expr (TREE_TYPE (se.expr),
4723 gfc_get_symbol_decl (vtab));
4724 }
afc44c79 4725 gfc_add_modify (&init, se.expr, rhs);
da2c4122 4726 gfc_restore_backend_locus (&loc);
afc44c79 4727 }
4728
89ac8ba1 4729 gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
908e9973 4730 }
0a96a7cc 4731 }
617125a6 4732 else if (sym->ts.type == BT_CHARACTER && sym->ts.deferred)
4733 {
4734 tree tmp = NULL;
4735 stmtblock_t init;
4736
4737 /* If we get to here, all that should be left are pointers. */
4738 gcc_assert (sym->attr.pointer);
4739
4740 if (sym->attr.dummy)
4741 {
4742 gfc_start_block (&init);
b345a09f 4743 gfc_save_backend_locus (&loc);
4744 gfc_set_backend_locus (&sym->declared_at);
4745 tmp = gfc_null_and_pass_deferred_len (sym, &init, &loc);
617125a6 4746 gfc_add_init_cleanup (block, gfc_finish_block (&init), tmp);
4747 }
4748 }
3e715c81 4749 else if (sym->ts.deferred)
4750 gfc_fatal_error ("Deferred type parameter not yet supported");
6b3ceb4e 4751 else if (alloc_comp_or_fini)
89ac8ba1 4752 gfc_trans_deferred_array (sym, block);
4ee9c684 4753 else if (sym->ts.type == BT_CHARACTER)
4754 {
4671339c 4755 gfc_save_backend_locus (&loc);
4ee9c684 4756 gfc_set_backend_locus (&sym->declared_at);
4757 if (sym->attr.dummy || sym->attr.result)
89ac8ba1 4758 gfc_trans_dummy_character (sym, sym->ts.u.cl, block);
4ee9c684 4759 else
89ac8ba1 4760 gfc_trans_auto_character_variable (sym, block);
4671339c 4761 gfc_restore_backend_locus (&loc);
4ee9c684 4762 }
c8f1568f 4763 else if (sym->attr.assign)
4764 {
4671339c 4765 gfc_save_backend_locus (&loc);
c8f1568f 4766 gfc_set_backend_locus (&sym->declared_at);
89ac8ba1 4767 gfc_trans_assign_aux_var (sym, block);
4671339c 4768 gfc_restore_backend_locus (&loc);
c8f1568f 4769 }
f0d4969f 4770 else if (sym->ts.type == BT_DERIVED
4771 && sym->value
4772 && !sym->attr.data
4773 && sym->attr.save == SAVE_NONE)
c5faa799 4774 {
4775 gfc_start_block (&tmpblock);
4776 gfc_init_default_dt (sym, &tmpblock, false);
89ac8ba1 4777 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock),
c5faa799 4778 NULL_TREE);
4779 }
9d958d5b 4780 else if (!(UNLIMITED_POLY(sym)) && !is_pdt_type)
22d678e8 4781 gcc_unreachable ();
4ee9c684 4782 }
4783
c5faa799 4784 gfc_init_block (&tmpblock);
d4163395 4785
6777213b 4786 for (f = gfc_sym_get_dummy_args (proc_sym); f; f = f->next)
1e853e89 4787 {
4788 if (f->sym && f->sym->tlink == NULL && f->sym->ts.type == BT_CHARACTER)
4789 {
eeebe20b 4790 gcc_assert (f->sym->ts.u.cl->backend_decl != NULL);
4791 if (TREE_CODE (f->sym->ts.u.cl->backend_decl) == PARM_DECL)
c5faa799 4792 gfc_trans_vla_type_sizes (f->sym, &tmpblock);
1e853e89 4793 }
1e853e89 4794 }
d4163395 4795
4796 if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER
4797 && current_fake_result_decl != NULL)
4798 {
eeebe20b 4799 gcc_assert (proc_sym->ts.u.cl->backend_decl != NULL);
4800 if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == PARM_DECL)
c5faa799 4801 gfc_trans_vla_type_sizes (proc_sym, &tmpblock);
d4163395 4802 }
4803
89ac8ba1 4804 gfc_add_init_cleanup (block, gfc_finish_block (&tmpblock), NULL_TREE);
4ee9c684 4805}
4806
b345a09f 4807
b594087e 4808struct module_hasher : ggc_ptr_hash<module_htab_entry>
df4d540f 4809{
2ef51f0e 4810 typedef const char *compare_type;
df4d540f 4811
2ef51f0e 4812 static hashval_t hash (module_htab_entry *s) { return htab_hash_string (s); }
4813 static bool
4814 equal (module_htab_entry *a, const char *b)
4815 {
4816 return !strcmp (a->name, b);
4817 }
4818};
4819
4820static GTY (()) hash_table<module_hasher> *module_htab;
df4d540f 4821
4822/* Hash and equality functions for module_htab's decls. */
4823
2ef51f0e 4824hashval_t
4825module_decl_hasher::hash (tree t)
df4d540f 4826{
df4d540f 4827 const_tree n = DECL_NAME (t);
4828 if (n == NULL_TREE)
4829 n = TYPE_NAME (TREE_TYPE (t));
8f1e8e0e 4830 return htab_hash_string (IDENTIFIER_POINTER (n));
df4d540f 4831}
4832
2ef51f0e 4833bool
4834module_decl_hasher::equal (tree t1, const char *x2)
df4d540f 4835{
df4d540f 4836 const_tree n1 = DECL_NAME (t1);
4837 if (n1 == NULL_TREE)
4838 n1 = TYPE_NAME (TREE_TYPE (t1));
2ef51f0e 4839 return strcmp (IDENTIFIER_POINTER (n1), x2) == 0;
df4d540f 4840}
4841
4842struct module_htab_entry *
4843gfc_find_module (const char *name)
4844{
df4d540f 4845 if (! module_htab)
2ef51f0e 4846 module_htab = hash_table<module_hasher>::create_ggc (10);
df4d540f 4847
2ef51f0e 4848 module_htab_entry **slot
4849 = module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
df4d540f 4850 if (*slot == NULL)
4851 {
25a27413 4852 module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
df4d540f 4853
dc326dc0 4854 entry->name = gfc_get_string ("%s", name);
2ef51f0e 4855 entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
4856 *slot = entry;
df4d540f 4857 }
2ef51f0e 4858 return *slot;
df4d540f 4859}
4860
4861void
4862gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
4863{
df4d540f 4864 const char *name;
4865
4866 if (DECL_NAME (decl))
4867 name = IDENTIFIER_POINTER (DECL_NAME (decl));
4868 else
4869 {
4870 gcc_assert (TREE_CODE (decl) == TYPE_DECL);
4871 name = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)));
4872 }
2ef51f0e 4873 tree *slot
4874 = entry->decls->find_slot_with_hash (name, htab_hash_string (name),
4875 INSERT);
df4d540f 4876 if (*slot == NULL)
2ef51f0e 4877 *slot = decl;
df4d540f 4878}
4879
c40a5c1b 4880
4881/* Generate debugging symbols for namelists. This function must come after
4882 generate_local_decl to ensure that the variables in the namelist are
4883 already declared. */
4884
4885static tree
4886generate_namelist_decl (gfc_symbol * sym)
4887{
4888 gfc_namelist *nml;
4889 tree decl;
4890 vec<constructor_elt, va_gc> *nml_decls = NULL;
4891
4892 gcc_assert (sym->attr.flavor == FL_NAMELIST);
4893 for (nml = sym->namelist; nml; nml = nml->next)
4894 {
4895 if (nml->sym->backend_decl == NULL_TREE)
4896 {
4897 nml->sym->attr.referenced = 1;
4898 nml->sym->backend_decl = gfc_get_symbol_decl (nml->sym);
4899 }
0a32260c 4900 DECL_IGNORED_P (nml->sym->backend_decl) = 0;
c40a5c1b 4901 CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, nml->sym->backend_decl);
4902 }
4903
4904 decl = make_node (NAMELIST_DECL);
4905 TREE_TYPE (decl) = void_type_node;
4906 NAMELIST_DECL_ASSOCIATED_DECL (decl) = build_constructor (NULL_TREE, nml_decls);
4907 DECL_NAME (decl) = get_identifier (sym->name);
4908 return decl;
4909}
4910
4911
4ee9c684 4912/* Output an initialized decl for a module variable. */
4913
4914static void
4915gfc_create_module_variable (gfc_symbol * sym)
4916{
4917 tree decl;
4ee9c684 4918
d77f260f 4919 /* Module functions with alternate entries are dealt with later and
4920 would get caught by the next condition. */
4921 if (sym->attr.entry)
4922 return;
4923
c5d33754 4924 /* Make sure we convert the types of the derived types from iso_c_binding
4925 into (void *). */
4926 if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
4927 && sym->ts.type == BT_DERIVED)
4928 sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
4929
d7cd448a 4930 if (gfc_fl_struct (sym->attr.flavor)
df4d540f 4931 && sym->backend_decl
4932 && TREE_CODE (sym->backend_decl) == RECORD_TYPE)
4933 {
4934 decl = sym->backend_decl;
4935 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
9f1470cb 4936
fe9d2f5a 4937 if (!sym->attr.use_assoc && !sym->attr.used_in_submodule)
9f1470cb 4938 {
4939 gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE
4940 || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl);
4941 gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE
4942 || DECL_CONTEXT (TYPE_STUB_DECL (decl))
4943 == sym->ns->proc_name->backend_decl);
4944 }
df4d540f 4945 TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
4946 DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl;
4947 gfc_module_add_decl (cur_module, TYPE_STUB_DECL (decl));
4948 }
4949
cf269acc 4950 /* Only output variables, procedure pointers and array valued,
4951 or derived type, parameters. */
4ee9c684 4952 if (sym->attr.flavor != FL_VARIABLE
be0f1581 4953 && !(sym->attr.flavor == FL_PARAMETER
cf269acc 4954 && (sym->attr.dimension || sym->ts.type == BT_DERIVED))
4955 && !(sym->attr.flavor == FL_PROCEDURE && sym->attr.proc_pointer))
4ee9c684 4956 return;
4957
df4d540f 4958 if ((sym->attr.in_common || sym->attr.in_equivalence) && sym->backend_decl)
4959 {
4960 decl = sym->backend_decl;
16a40513 4961 gcc_assert (DECL_FILE_SCOPE_P (decl));
df4d540f 4962 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
4963 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
4964 gfc_module_add_decl (cur_module, decl);
4965 }
4966
d43a7f7f 4967 /* Don't generate variables from other modules. Variables from
cd958916 4968 COMMONs and Cray pointees will already have been generated. */
fe9d2f5a 4969 if (sym->attr.use_assoc || sym->attr.used_in_submodule
4970 || sym->attr.in_common || sym->attr.cray_pointee)
4ee9c684 4971 return;
4972
2b685f8e 4973 /* Equivalenced variables arrive here after creation. */
976d903a 4974 if (sym->backend_decl
df4d540f 4975 && (sym->equiv_built || sym->attr.in_equivalence))
4976 return;
2b685f8e 4977
23d075f4 4978 if (sym->backend_decl && !sym->attr.vtab && !sym->attr.target)
382ad5c3 4979 gfc_internal_error ("backend decl for module variable %qs already exists",
4980 sym->name);
4ee9c684 4981
92983bfd 4982 if (sym->module && !sym->attr.result && !sym->attr.dummy
4983 && (sym->attr.access == ACCESS_UNKNOWN
4984 && (sym->ns->default_access == ACCESS_PRIVATE
4985 || (sym->ns->default_access == ACCESS_UNKNOWN
829d7a08 4986 && flag_module_private))))
92983bfd 4987 sym->attr.access = ACCESS_PRIVATE;
4988
4989 if (warn_unused_variable && !sym->attr.referenced
4990 && sym->attr.access == ACCESS_PRIVATE)
4166acc7 4991 gfc_warning (OPT_Wunused_value,
4992 "Unused PRIVATE module variable %qs declared at %L",
92983bfd 4993 sym->name, &sym->declared_at);
4994
4ee9c684 4995 /* We always want module variables to be created. */
4996 sym->attr.referenced = 1;
4997 /* Create the decl. */
4998 decl = gfc_get_symbol_decl (sym);
4999
4ee9c684 5000 /* Create the variable. */
5001 pushdecl (decl);
8b7e5587 5002 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE
5003 || (sym->ns->parent->proc_name->attr.flavor == FL_MODULE
5004 && sym->fn_result_spec));
df4d540f 5005 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
b2c4af5e 5006 rest_of_decl_compilation (decl, 1, 0);
df4d540f 5007 gfc_module_add_decl (cur_module, decl);
4ee9c684 5008
5009 /* Also add length of strings. */
5010 if (sym->ts.type == BT_CHARACTER)
5011 {
5012 tree length;
5013
eeebe20b 5014 length = sym->ts.u.cl->backend_decl;
cf4b41d8 5015 gcc_assert (length || sym->attr.proc_pointer);
5016 if (length && !INTEGER_CST_P (length))
4ee9c684 5017 {
5018 pushdecl (length);
b2c4af5e 5019 rest_of_decl_compilation (length, 1, 0);
4ee9c684 5020 }
5021 }
a961ca30 5022
5023 if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
5024 && sym->attr.referenced && !sym->attr.use_assoc)
5025 has_coarray_vars = true;
4ee9c684 5026}
5027
51d9479b 5028/* Emit debug information for USE statements. */
df4d540f 5029
5030static void
5031gfc_trans_use_stmts (gfc_namespace * ns)
5032{
5033 gfc_use_list *use_stmt;
5034 for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next)
5035 {
5036 struct module_htab_entry *entry
5037 = gfc_find_module (use_stmt->module_name);
5038 gfc_use_rename *rent;
5039
5040 if (entry->namespace_decl == NULL)
5041 {
5042 entry->namespace_decl
e60a6f7b 5043 = build_decl (input_location,
5044 NAMESPACE_DECL,
df4d540f 5045 get_identifier (use_stmt->module_name),
5046 void_type_node);
5047 DECL_EXTERNAL (entry->namespace_decl) = 1;
5048 }
51d9479b 5049 gfc_set_backend_locus (&use_stmt->where);
df4d540f 5050 if (!use_stmt->only_flag)
5051 (*debug_hooks->imported_module_or_decl) (entry->namespace_decl,
5052 NULL_TREE,
5053 ns->proc_name->backend_decl,
41d01e67 5054 false, false);
df4d540f 5055 for (rent = use_stmt->rename; rent; rent = rent->next)
5056 {
5057 tree decl, local_name;
df4d540f 5058
5059 if (rent->op != INTRINSIC_NONE)
5060 continue;
5061
2ef51f0e 5062 hashval_t hash = htab_hash_string (rent->use_name);
5063 tree *slot = entry->decls->find_slot_with_hash (rent->use_name, hash,
5064 INSERT);
df4d540f 5065 if (*slot == NULL)
5066 {
5067 gfc_symtree *st;
5068
5069 st = gfc_find_symtree (ns->sym_root,
5070 rent->local_name[0]
5071 ? rent->local_name : rent->use_name);
c2958b6b 5072
5073 /* The following can happen if a derived type is renamed. */
5074 if (!st)
5075 {
5076 char *name;
5077 name = xstrdup (rent->local_name[0]
5078 ? rent->local_name : rent->use_name);
5079 name[0] = (char) TOUPPER ((unsigned char) name[0]);
5080 st = gfc_find_symtree (ns->sym_root, name);
5081 free (name);
5082 gcc_assert (st);
5083 }
857c96ba 5084
5085 /* Sometimes, generic interfaces wind up being over-ruled by a
5086 local symbol (see PR41062). */
5087 if (!st->n.sym->attr.use_assoc)
5088 continue;
5089
51d9479b 5090 if (st->n.sym->backend_decl
5091 && DECL_P (st->n.sym->backend_decl)
5092 && st->n.sym->module
5093 && strcmp (st->n.sym->module, use_stmt->module_name) == 0)
df4d540f 5094 {
51d9479b 5095 gcc_assert (DECL_EXTERNAL (entry->namespace_decl)
fe732a9b 5096 || !VAR_P (st->n.sym->backend_decl));
df4d540f 5097 decl = copy_node (st->n.sym->backend_decl);
5098 DECL_CONTEXT (decl) = entry->namespace_decl;
5099 DECL_EXTERNAL (decl) = 1;
5100 DECL_IGNORED_P (decl) = 0;
5101 DECL_INITIAL (decl) = NULL_TREE;
5102 }
c40a5c1b 5103 else if (st->n.sym->attr.flavor == FL_NAMELIST
5104 && st->n.sym->attr.use_only
5105 && st->n.sym->module
5106 && strcmp (st->n.sym->module, use_stmt->module_name)
5107 == 0)
5108 {
5109 decl = generate_namelist_decl (st->n.sym);
5110 DECL_CONTEXT (decl) = entry->namespace_decl;
5111 DECL_EXTERNAL (decl) = 1;
5112 DECL_IGNORED_P (decl) = 0;
5113 DECL_INITIAL (decl) = NULL_TREE;
5114 }
df4d540f 5115 else
5116 {
5117 *slot = error_mark_node;
2ef51f0e 5118 entry->decls->clear_slot (slot);
df4d540f 5119 continue;
5120 }
5121 *slot = decl;
5122 }
5123 decl = (tree) *slot;
5124 if (rent->local_name[0])
5125 local_name = get_identifier (rent->local_name);
5126 else
5127 local_name = NULL_TREE;
51d9479b 5128 gfc_set_backend_locus (&rent->where);
df4d540f 5129 (*debug_hooks->imported_module_or_decl) (decl, local_name,
5130 ns->proc_name->backend_decl,
41d01e67 5131 !use_stmt->only_flag,
5132 false);
df4d540f 5133 }
5134 }
4ee9c684 5135}
5136
51d9479b 5137
2eb674c9 5138/* Return true if expr is a constant initializer that gfc_conv_initializer
5139 will handle. */
5140
5141static bool
5142check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
5143 bool pointer)
5144{
5145 gfc_constructor *c;
5146 gfc_component *cm;
5147
5148 if (pointer)
5149 return true;
5150 else if (array)
5151 {
5152 if (expr->expr_type == EXPR_CONSTANT || expr->expr_type == EXPR_NULL)
5153 return true;
5154 else if (expr->expr_type == EXPR_STRUCTURE)
5155 return check_constant_initializer (expr, ts, false, false);
5156 else if (expr->expr_type != EXPR_ARRAY)
5157 return false;
126387b5 5158 for (c = gfc_constructor_first (expr->value.constructor);
5159 c; c = gfc_constructor_next (c))
2eb674c9 5160 {
5161 if (c->iterator)
5162 return false;
5163 if (c->expr->expr_type == EXPR_STRUCTURE)
5164 {
5165 if (!check_constant_initializer (c->expr, ts, false, false))
5166 return false;
5167 }
5168 else if (c->expr->expr_type != EXPR_CONSTANT)
5169 return false;
5170 }
5171 return true;
5172 }
5173 else switch (ts->type)
5174 {
d7cd448a 5175 case_bt_struct:
2eb674c9 5176 if (expr->expr_type != EXPR_STRUCTURE)
5177 return false;
eeebe20b 5178 cm = expr->ts.u.derived->components;
126387b5 5179 for (c = gfc_constructor_first (expr->value.constructor);
5180 c; c = gfc_constructor_next (c), cm = cm->next)
2eb674c9 5181 {
5182 if (!c->expr || cm->attr.allocatable)
5183 continue;
5184 if (!check_constant_initializer (c->expr, &cm->ts,
5185 cm->attr.dimension,
5186 cm->attr.pointer))
5187 return false;
5188 }
5189 return true;
5190 default:
5191 return expr->expr_type == EXPR_CONSTANT;
5192 }
5193}
5194
5195/* Emit debug info for parameters and unreferenced variables with
5196 initializers. */
5197
5198static void
5199gfc_emit_parameter_debug_info (gfc_symbol *sym)
5200{
5201 tree decl;
5202
5203 if (sym->attr.flavor != FL_PARAMETER
5204 && (sym->attr.flavor != FL_VARIABLE || sym->attr.referenced))
5205 return;
5206
5207 if (sym->backend_decl != NULL
5208 || sym->value == NULL
5209 || sym->attr.use_assoc
5210 || sym->attr.dummy
5211 || sym->attr.result
5212 || sym->attr.function
5213 || sym->attr.intrinsic
5214 || sym->attr.pointer
5215 || sym->attr.allocatable
5216 || sym->attr.cray_pointee
5217 || sym->attr.threadprivate
5218 || sym->attr.is_bind_c
5219 || sym->attr.subref_array_pointer
5220 || sym->attr.assign)
5221 return;
5222
5223 if (sym->ts.type == BT_CHARACTER)
5224 {
eeebe20b 5225 gfc_conv_const_charlen (sym->ts.u.cl);
5226 if (sym->ts.u.cl->backend_decl == NULL
5227 || TREE_CODE (sym->ts.u.cl->backend_decl) != INTEGER_CST)
2eb674c9 5228 return;
5229 }
eeebe20b 5230 else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.alloc_comp)
2eb674c9 5231 return;
5232
5233 if (sym->as)
5234 {
5235 int n;
5236
5237 if (sym->as->type != AS_EXPLICIT)
5238 return;
5239 for (n = 0; n < sym->as->rank; n++)
5240 if (sym->as->lower[n]->expr_type != EXPR_CONSTANT
5241 || sym->as->upper[n] == NULL
5242 || sym->as->upper[n]->expr_type != EXPR_CONSTANT)
5243 return;
5244 }
5245
5246 if (!check_constant_initializer (sym->value, &sym->ts,
5247 sym->attr.dimension, false))
5248 return;
5249
4fe73152 5250 if (flag_coarray == GFC_FCOARRAY_LIB && sym->attr.codimension)
a961ca30 5251 return;
5252
2eb674c9 5253 /* Create the decl for the variable or constant. */
e60a6f7b 5254 decl = build_decl (input_location,
5255 sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
2eb674c9 5256 gfc_sym_identifier (sym), gfc_sym_type (sym));
5257 if (sym->attr.flavor == FL_PARAMETER)
5258 TREE_READONLY (decl) = 1;
5259 gfc_set_decl_location (decl, &sym->declared_at);
5260 if (sym->attr.dimension)
5261 GFC_DECL_PACKED_ARRAY (decl) = 1;
5262 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5263 TREE_STATIC (decl) = 1;
5264 TREE_USED (decl) = 1;
5265 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
5266 TREE_PUBLIC (decl) = 1;
802532b9 5267 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
5268 TREE_TYPE (decl),
5269 sym->attr.dimension,
5270 false, false);
3a1c9df2 5271 debug_hooks->early_global_decl (decl);
2eb674c9 5272}
5273
a961ca30 5274
5275static void
5276generate_coarray_sym_init (gfc_symbol *sym)
5277{
eee0cf09 5278 tree tmp, size, decl, token, desc;
bd47f0bc 5279 bool is_lock_type, is_event_type;
498b946e 5280 int reg_type;
eee0cf09 5281 gfc_se se;
5282 symbol_attribute attr;
a961ca30 5283
5284 if (sym->attr.dummy || sym->attr.allocatable || !sym->attr.codimension
102abea2 5285 || sym->attr.use_assoc || !sym->attr.referenced
5286 || sym->attr.select_type_temporary)
a961ca30 5287 return;
5288
5289 decl = sym->backend_decl;
5290 TREE_USED(decl) = 1;
5291 gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (decl)));
5292
498b946e 5293 is_lock_type = sym->ts.type == BT_DERIVED
5294 && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
5295 && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE;
5296
bd47f0bc 5297 is_event_type = sym->ts.type == BT_DERIVED
5298 && sym->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
5299 && sym->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE;
5300
a961ca30 5301 /* FIXME: Workaround for PR middle-end/49106, cf. also PR middle-end/49108
5302 to make sure the variable is not optimized away. */
5303 DECL_PRESERVE_P (DECL_CONTEXT (decl)) = 1;
5304
498b946e 5305 /* For lock types, we pass the array size as only the library knows the
5306 size of the variable. */
bd47f0bc 5307 if (is_lock_type || is_event_type)
498b946e 5308 size = gfc_index_one_node;
5309 else
5310 size = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (decl)));
a961ca30 5311
a90fe829 5312 /* Ensure that we do not have size=0 for zero-sized arrays. */
ee4e7a5e 5313 size = fold_build2_loc (input_location, MAX_EXPR, size_type_node,
5314 fold_convert (size_type_node, size),
5315 build_int_cst (size_type_node, 1));
5316
a961ca30 5317 if (GFC_TYPE_ARRAY_RANK (TREE_TYPE (decl)))
5318 {
5319 tmp = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (decl));
5320 size = fold_build2_loc (input_location, MULT_EXPR, size_type_node,
ee4e7a5e 5321 fold_convert (size_type_node, tmp), size);
a961ca30 5322 }
5323
5324 gcc_assert (GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (decl)) != NULL_TREE);
5325 token = gfc_build_addr_expr (ppvoid_type_node,
5326 GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE(decl)));
498b946e 5327 if (is_lock_type)
5328 reg_type = sym->attr.artificial ? GFC_CAF_CRITICAL : GFC_CAF_LOCK_STATIC;
bd47f0bc 5329 else if (is_event_type)
5330 reg_type = GFC_CAF_EVENT_STATIC;
498b946e 5331 else
5332 reg_type = GFC_CAF_COARRAY_STATIC;
eee0cf09 5333
f991680c 5334 /* Compile the symbol attribute. */
5335 if (sym->ts.type == BT_CLASS)
5336 {
5337 attr = CLASS_DATA (sym)->attr;
5338 /* The pointer attribute is always set on classes, overwrite it with the
5339 class_pointer attribute, which denotes the pointer for classes. */
5340 attr.pointer = attr.class_pointer;
5341 }
5342 else
5343 attr = sym->attr;
eee0cf09 5344 gfc_init_se (&se, NULL);
5345 desc = gfc_conv_scalar_to_descriptor (&se, decl, attr);
5346 gfc_add_block_to_block (&caf_init_block, &se.pre);
5347
5348 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_register, 7, size,
498b946e 5349 build_int_cst (integer_type_node, reg_type),
eee0cf09 5350 token, gfc_build_addr_expr (pvoid_type_node, desc),
5351 null_pointer_node, /* stat. */
3d2aa0e8 5352 null_pointer_node, /* errgmsg. */
5353 integer_zero_node); /* errmsg_len. */
eee0cf09 5354 gfc_add_expr_to_block (&caf_init_block, tmp);
5355 gfc_add_modify (&caf_init_block, decl, fold_convert (TREE_TYPE (decl),
5356 gfc_conv_descriptor_data_get (desc)));
a961ca30 5357
a961ca30 5358 /* Handle "static" initializer. */
5359 if (sym->value)
5360 {
5361 sym->attr.pointer = 1;
5362 tmp = gfc_trans_assignment (gfc_lval_expr_from_sym (sym), sym->value,
5363 true, false);
5364 sym->attr.pointer = 0;
5365 gfc_add_expr_to_block (&caf_init_block, tmp);
5366 }
942ef29d 5367 else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pointer_comp)
5368 {
5369 tmp = gfc_nullify_alloc_comp (sym->ts.u.derived, decl, sym->as
5370 ? sym->as->rank : 0,
5371 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
5372 gfc_add_expr_to_block (&caf_init_block, tmp);
5373 }
a961ca30 5374}
5375
5376
5377/* Generate constructor function to initialize static, nonallocatable
5378 coarrays. */
5379
5380static void
5381generate_coarray_init (gfc_namespace * ns __attribute((unused)))
5382{
5383 tree fndecl, tmp, decl, save_fn_decl;
5384
5385 save_fn_decl = current_function_decl;
5386 push_function_context ();
5387
5388 tmp = build_function_type_list (void_type_node, NULL_TREE);
5389 fndecl = build_decl (input_location, FUNCTION_DECL,
5390 create_tmp_var_name ("_caf_init"), tmp);
5391
5392 DECL_STATIC_CONSTRUCTOR (fndecl) = 1;
5393 SET_DECL_INIT_PRIORITY (fndecl, DEFAULT_INIT_PRIORITY);
5394
5395 decl = build_decl (input_location, RESULT_DECL, NULL_TREE, void_type_node);
5396 DECL_ARTIFICIAL (decl) = 1;
5397 DECL_IGNORED_P (decl) = 1;
5398 DECL_CONTEXT (decl) = fndecl;
5399 DECL_RESULT (fndecl) = decl;
5400
5401 pushdecl (fndecl);
5402 current_function_decl = fndecl;
5403 announce_function (fndecl);
5404
5405 rest_of_decl_compilation (fndecl, 0, 0);
5406 make_decl_rtl (fndecl);
00cf115c 5407 allocate_struct_function (fndecl, false);
a961ca30 5408
cde2be84 5409 pushlevel ();
a961ca30 5410 gfc_init_block (&caf_init_block);
5411
5412 gfc_traverse_ns (ns, generate_coarray_sym_init);
5413
5414 DECL_SAVED_TREE (fndecl) = gfc_finish_block (&caf_init_block);
5415 decl = getdecls ();
5416
cde2be84 5417 poplevel (1, 1);
a961ca30 5418 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
5419
5420 DECL_SAVED_TREE (fndecl)
5421 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
5422 DECL_INITIAL (fndecl));
5423 dump_function (TDI_original, fndecl);
5424
5425 cfun->function_end_locus = input_location;
5426 set_cfun (NULL);
5427
5428 if (decl_function_context (fndecl))
415d1b9a 5429 (void) cgraph_node::create (fndecl);
a961ca30 5430 else
35ee1c66 5431 cgraph_node::finalize_function (fndecl, true);
a961ca30 5432
5433 pop_function_context ();
5434 current_function_decl = save_fn_decl;
5435}
5436
5437
c40a5c1b 5438static void
5439create_module_nml_decl (gfc_symbol *sym)
5440{
5441 if (sym->attr.flavor == FL_NAMELIST)
5442 {
5443 tree decl = generate_namelist_decl (sym);
5444 pushdecl (decl);
5445 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
5446 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
5447 rest_of_decl_compilation (decl, 1, 0);
5448 gfc_module_add_decl (cur_module, decl);
5449 }
5450}
5451
5452
51d9479b 5453/* Generate all the required code for module variables. */
5454
5455void
5456gfc_generate_module_vars (gfc_namespace * ns)
5457{
5458 module_namespace = ns;
5459 cur_module = gfc_find_module (ns->proc_name->name);
5460
5461 /* Check if the frontend left the namespace in a reasonable state. */
5462 gcc_assert (ns->proc_name && !ns->proc_name->tlink);
5463
5464 /* Generate COMMON blocks. */
5465 gfc_trans_common (ns);
5466
a961ca30 5467 has_coarray_vars = false;
5468
51d9479b 5469 /* Create decls for all the module variables. */
5470 gfc_traverse_ns (ns, gfc_create_module_variable);
c40a5c1b 5471 gfc_traverse_ns (ns, create_module_nml_decl);
51d9479b 5472
4fe73152 5473 if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
a961ca30 5474 generate_coarray_init (ns);
5475
51d9479b 5476 cur_module = NULL;
5477
5478 gfc_trans_use_stmts (ns);
2eb674c9 5479 gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
51d9479b 5480}
5481
5482
4ee9c684 5483static void
5484gfc_generate_contained_functions (gfc_namespace * parent)
5485{
5486 gfc_namespace *ns;
5487
5488 /* We create all the prototypes before generating any code. */
5489 for (ns = parent->contained; ns; ns = ns->sibling)
5490 {
5491 /* Skip namespaces from used modules. */
5492 if (ns->parent != parent)
5493 continue;
5494
d896f9b3 5495 gfc_create_function_decl (ns, false);
4ee9c684 5496 }
5497
5498 for (ns = parent->contained; ns; ns = ns->sibling)
5499 {
5500 /* Skip namespaces from used modules. */
5501 if (ns->parent != parent)
5502 continue;
5503
5504 gfc_generate_function_code (ns);
5505 }
5506}
5507
5508
d95efb59 5509/* Drill down through expressions for the array specification bounds and
5510 character length calling generate_local_decl for all those variables
5511 that have not already been declared. */
5512
5513static void
5514generate_local_decl (gfc_symbol *);
5515
1acb400a 5516/* Traverse expr, marking all EXPR_VARIABLE symbols referenced. */
d95efb59 5517
1acb400a 5518static bool
5519expr_decls (gfc_expr *e, gfc_symbol *sym,
5520 int *f ATTRIBUTE_UNUSED)
5521{
5522 if (e->expr_type != EXPR_VARIABLE
5523 || sym == e->symtree->n.sym
d95efb59 5524 || e->symtree->n.sym->mark
5525 || e->symtree->n.sym->ns != sym->ns)
1acb400a 5526 return false;
d95efb59 5527
1acb400a 5528 generate_local_decl (e->symtree->n.sym);
5529 return false;
5530}
d95efb59 5531
1acb400a 5532static void
5533generate_expr_decls (gfc_symbol *sym, gfc_expr *e)
5534{
5535 gfc_traverse_expr (e, sym, expr_decls, 0);
d95efb59 5536}
5537
5538
f6d0e37a 5539/* Check for dependencies in the character length and array spec. */
d95efb59 5540
5541static void
5542generate_dependency_declarations (gfc_symbol *sym)
5543{
5544 int i;
5545
5546 if (sym->ts.type == BT_CHARACTER
eeebe20b 5547 && sym->ts.u.cl
5548 && sym->ts.u.cl->length
5549 && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
5550 generate_expr_decls (sym, sym->ts.u.cl->length);
d95efb59 5551
5552 if (sym->as && sym->as->rank)
5553 {
5554 for (i = 0; i < sym->as->rank; i++)
5555 {
5556 generate_expr_decls (sym, sym->as->lower[i]);
5557 generate_expr_decls (sym, sym->as->upper[i]);
5558 }
5559 }
5560}
5561
5562
4ee9c684 5563/* Generate decls for all local variables. We do this to ensure correct
5564 handling of expressions which only appear in the specification of
5565 other functions. */
5566
5567static void
5568generate_local_decl (gfc_symbol * sym)
5569{
5570 if (sym->attr.flavor == FL_VARIABLE)
5571 {
a961ca30 5572 if (sym->attr.codimension && !sym->attr.dummy && !sym->attr.allocatable
5573 && sym->attr.referenced && !sym->attr.use_assoc)
5574 has_coarray_vars = true;
5575
d95efb59 5576 if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master)
8714fc76 5577 generate_dependency_declarations (sym);
d95efb59 5578
4ee9c684 5579 if (sym->attr.referenced)
8714fc76 5580 gfc_get_symbol_decl (sym);
4acad347 5581
5582 /* Warnings for unused dummy arguments. */
6992b8c8 5583 else if (sym->attr.dummy && !sym->attr.in_namelist)
7c0ca46e 5584 {
4acad347 5585 /* INTENT(out) dummy arguments are likely meant to be set. */
8290d53f 5586 if (warn_unused_dummy_argument && sym->attr.intent == INTENT_OUT)
4acad347 5587 {
5588 if (sym->ts.type != BT_DERIVED)
4166acc7 5589 gfc_warning (OPT_Wunused_dummy_argument,
5590 "Dummy argument %qs at %L was declared "
4acad347 5591 "INTENT(OUT) but was not set", sym->name,
5592 &sym->declared_at);
48cb4748 5593 else if (!gfc_has_default_initializer (sym->ts.u.derived)
5594 && !sym->ts.u.derived->attr.zero_comp)
4166acc7 5595 gfc_warning (OPT_Wunused_dummy_argument,
5596 "Derived-type dummy argument %qs at %L was "
4acad347 5597 "declared INTENT(OUT) but was not set and "
5598 "does not have a default initializer",
5599 sym->name, &sym->declared_at);
90a4a5a6 5600 if (sym->backend_decl != NULL_TREE)
5601 TREE_NO_WARNING(sym->backend_decl) = 1;
4acad347 5602 }
8290d53f 5603 else if (warn_unused_dummy_argument)
90a4a5a6 5604 {
4166acc7 5605 gfc_warning (OPT_Wunused_dummy_argument,
5606 "Unused dummy argument %qs at %L", sym->name,
5607 &sym->declared_at);
90a4a5a6 5608 if (sym->backend_decl != NULL_TREE)
5609 TREE_NO_WARNING(sym->backend_decl) = 1;
5610 }
7c0ca46e 5611 }
4acad347 5612
f888a3fb 5613 /* Warn for unused variables, but not if they're inside a common
1dbfac29 5614 block or a namelist. */
36609028 5615 else if (warn_unused_variable
1dbfac29 5616 && !(sym->attr.in_common || sym->mark || sym->attr.in_namelist))
90a4a5a6 5617 {
1dbfac29 5618 if (sym->attr.use_only)
5619 {
4166acc7 5620 gfc_warning (OPT_Wunused_variable,
5621 "Unused module variable %qs which has been "
1dbfac29 5622 "explicitly imported at %L", sym->name,
5623 &sym->declared_at);
5624 if (sym->backend_decl != NULL_TREE)
5625 TREE_NO_WARNING(sym->backend_decl) = 1;
5626 }
5627 else if (!sym->attr.use_assoc)
5628 {
99af6e70 5629 /* Corner case: the symbol may be an entry point. At this point,
5630 it may appear to be an unused variable. Suppress warning. */
5631 bool enter = false;
5632 gfc_entry_list *el;
5633
5634 for (el = sym->ns->entries; el; el=el->next)
5635 if (strcmp(sym->name, el->sym->name) == 0)
5636 enter = true;
5637
5638 if (!enter)
5639 gfc_warning (OPT_Wunused_variable,
5640 "Unused variable %qs declared at %L",
5641 sym->name, &sym->declared_at);
1dbfac29 5642 if (sym->backend_decl != NULL_TREE)
5643 TREE_NO_WARNING(sym->backend_decl) = 1;
5644 }
90a4a5a6 5645 }
8714fc76 5646
d4163395 5647 /* For variable length CHARACTER parameters, the PARM_DECL already
5648 references the length variable, so force gfc_get_symbol_decl
5649 even when not referenced. If optimize > 0, it will be optimized
5650 away anyway. But do this only after emitting -Wunused-parameter
5651 warning if requested. */
8714fc76 5652 if (sym->attr.dummy && !sym->attr.referenced
5653 && sym->ts.type == BT_CHARACTER
eeebe20b 5654 && sym->ts.u.cl->backend_decl != NULL
fe732a9b 5655 && VAR_P (sym->ts.u.cl->backend_decl))
d4163395 5656 {
5657 sym->attr.referenced = 1;
5658 gfc_get_symbol_decl (sym);
5659 }
76776e6d 5660
d0163401 5661 /* INTENT(out) dummy arguments and result variables with allocatable
5662 components are reset by default and need to be set referenced to
5663 generate the code for nullification and automatic lengths. */
5664 if (!sym->attr.referenced
8714fc76 5665 && sym->ts.type == BT_DERIVED
eeebe20b 5666 && sym->ts.u.derived->attr.alloc_comp
c49db15e 5667 && !sym->attr.pointer
d0163401 5668 && ((sym->attr.dummy && sym->attr.intent == INTENT_OUT)
5669 ||
5670 (sym->attr.result && sym != sym->result)))
8714fc76 5671 {
5672 sym->attr.referenced = 1;
5673 gfc_get_symbol_decl (sym);
5674 }
5675
e72f979a 5676 /* Check for dependencies in the array specification and string
5677 length, adding the necessary declarations to the function. We
5678 mark the symbol now, as well as in traverse_ns, to prevent
5679 getting stuck in a circular dependency. */
5680 sym->mark = 1;
4ee9c684 5681 }
5dd246c1 5682 else if (sym->attr.flavor == FL_PARAMETER)
5683 {
6ecfe89d 5684 if (warn_unused_parameter
f326eb81 5685 && !sym->attr.referenced)
5686 {
5687 if (!sym->attr.use_assoc)
4166acc7 5688 gfc_warning (OPT_Wunused_parameter,
5689 "Unused parameter %qs declared at %L", sym->name,
f326eb81 5690 &sym->declared_at);
5691 else if (sym->attr.use_only)
4166acc7 5692 gfc_warning (OPT_Wunused_parameter,
5693 "Unused parameter %qs which has been explicitly "
f326eb81 5694 "imported at %L", sym->name, &sym->declared_at);
5695 }
758c9897 5696
5697 if (sym->ns
5698 && sym->ns->parent
5699 && sym->ns->parent->code
5700 && sym->ns->parent->code->op == EXEC_BLOCK)
5701 {
5702 if (sym->attr.referenced)
5703 gfc_get_symbol_decl (sym);
5704 sym->mark = 1;
5705 }
5dd246c1 5706 }
fa7b6574 5707 else if (sym->attr.flavor == FL_PROCEDURE)
5708 {
5709 /* TODO: move to the appropriate place in resolve.c. */
8b72061f 5710 if (warn_return_type > 0
fa7b6574 5711 && sym->attr.function
5712 && sym->result
5713 && sym != sym->result
5714 && !sym->result->attr.referenced
5715 && !sym->attr.use_assoc
5716 && sym->attr.if_source != IFSRC_IFBODY)
5717 {
4166acc7 5718 gfc_warning (OPT_Wreturn_type,
5719 "Return value %qs of function %qs declared at "
fa7b6574 5720 "%L not set", sym->result->name, sym->name,
5721 &sym->result->declared_at);
5722
5723 /* Prevents "Unused variable" warning for RESULT variables. */
e72f979a 5724 sym->result->mark = 1;
fa7b6574 5725 }
5726 }
c5d33754 5727
19ba2ad8 5728 if (sym->attr.dummy == 1)
5729 {
5730 /* Modify the tree type for scalar character dummy arguments of bind(c)
5731 procedures if they are passed by value. The tree type for them will
5732 be promoted to INTEGER_TYPE for the middle end, which appears to be
5733 what C would do with characters passed by-value. The value attribute
5734 implies the dummy is a scalar. */
5735 if (sym->attr.value == 1 && sym->backend_decl != NULL
5736 && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
5737 && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
4c47c8b7 5738 gfc_conv_scalar_char_value (sym, NULL, NULL);
fc6338c7 5739
5740 /* Unused procedure passed as dummy argument. */
5741 if (sym->attr.flavor == FL_PROCEDURE)
5742 {
5743 if (!sym->attr.referenced)
5744 {
8290d53f 5745 if (warn_unused_dummy_argument)
4166acc7 5746 gfc_warning (OPT_Wunused_dummy_argument,
5747 "Unused dummy argument %qs at %L", sym->name,
a90fe829 5748 &sym->declared_at);
fc6338c7 5749 }
5750
5751 /* Silence bogus "unused parameter" warnings from the
5752 middle end. */
5753 if (sym->backend_decl != NULL_TREE)
5754 TREE_NO_WARNING (sym->backend_decl) = 1;
5755 }
19ba2ad8 5756 }
5757
c5d33754 5758 /* Make sure we convert the types of the derived types from iso_c_binding
5759 into (void *). */
5760 if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
5761 && sym->ts.type == BT_DERIVED)
5762 sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
4ee9c684 5763}
5764
c40a5c1b 5765
5766static void
5767generate_local_nml_decl (gfc_symbol * sym)
5768{
5769 if (sym->attr.flavor == FL_NAMELIST && !sym->attr.use_assoc)
5770 {
5771 tree decl = generate_namelist_decl (sym);
5772 pushdecl (decl);
5773 }
5774}
5775
5776
4ee9c684 5777static void
5778generate_local_vars (gfc_namespace * ns)
5779{
5780 gfc_traverse_ns (ns, generate_local_decl);
c40a5c1b 5781 gfc_traverse_ns (ns, generate_local_nml_decl);
4ee9c684 5782}
5783
5784
1b716045 5785/* Generate a switch statement to jump to the correct entry point. Also
5786 creates the label decls for the entry points. */
4ee9c684 5787
1b716045 5788static tree
5789gfc_trans_entry_master_switch (gfc_entry_list * el)
4ee9c684 5790{
1b716045 5791 stmtblock_t block;
5792 tree label;
5793 tree tmp;
5794 tree val;
4ee9c684 5795
1b716045 5796 gfc_init_block (&block);
5797 for (; el; el = el->next)
5798 {
5799 /* Add the case label. */
b797d6d3 5800 label = gfc_build_label_decl (NULL_TREE);
7016c612 5801 val = build_int_cst (gfc_array_index_type, el->id);
b6e3dd65 5802 tmp = build_case_label (val, NULL_TREE, label);
1b716045 5803 gfc_add_expr_to_block (&block, tmp);
5b11d932 5804
1b716045 5805 /* And jump to the actual entry point. */
5806 label = gfc_build_label_decl (NULL_TREE);
1b716045 5807 tmp = build1_v (GOTO_EXPR, label);
5808 gfc_add_expr_to_block (&block, tmp);
5809
5810 /* Save the label decl. */
5811 el->label = label;
5812 }
5813 tmp = gfc_finish_block (&block);
5814 /* The first argument selects the entry point. */
5815 val = DECL_ARGUMENTS (current_function_decl);
bd37ce3e 5816 tmp = fold_build2_loc (input_location, SWITCH_EXPR, NULL_TREE, val, tmp);
1b716045 5817 return tmp;
4ee9c684 5818}
5819
6374121b 5820
a4abf8a0 5821/* Add code to string lengths of actual arguments passed to a function against
5822 the expected lengths of the dummy arguments. */
5823
5824static void
5825add_argument_checking (stmtblock_t *block, gfc_symbol *sym)
5826{
5827 gfc_formal_arglist *formal;
5828
6777213b 5829 for (formal = gfc_sym_get_dummy_args (sym); formal; formal = formal->next)
517c89e5 5830 if (formal->sym && formal->sym->ts.type == BT_CHARACTER
6c3000f4 5831 && !formal->sym->ts.deferred)
a4abf8a0 5832 {
5833 enum tree_code comparison;
5834 tree cond;
5835 tree argname;
5836 gfc_symbol *fsym;
5837 gfc_charlen *cl;
5838 const char *message;
5839
5840 fsym = formal->sym;
eeebe20b 5841 cl = fsym->ts.u.cl;
a4abf8a0 5842
5843 gcc_assert (cl);
5844 gcc_assert (cl->passed_length != NULL_TREE);
5845 gcc_assert (cl->backend_decl != NULL_TREE);
5846
5847 /* For POINTER, ALLOCATABLE and assumed-shape dummy arguments, the
5848 string lengths must match exactly. Otherwise, it is only required
be4be771 5849 that the actual string length is *at least* the expected one.
5850 Sequence association allows for a mismatch of the string length
5851 if the actual argument is (part of) an array, but only if the
5852 dummy argument is an array. (See "Sequence association" in
5853 Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.) */
517c89e5 5854 if (fsym->attr.pointer || fsym->attr.allocatable
f00f6dd6 5855 || (fsym->as && (fsym->as->type == AS_ASSUMED_SHAPE
5856 || fsym->as->type == AS_ASSUMED_RANK)))
a4abf8a0 5857 {
5858 comparison = NE_EXPR;
5859 message = _("Actual string length does not match the declared one"
5860 " for dummy argument '%s' (%ld/%ld)");
5861 }
be4be771 5862 else if (fsym->as && fsym->as->rank != 0)
5863 continue;
a4abf8a0 5864 else
5865 {
5866 comparison = LT_EXPR;
5867 message = _("Actual string length is shorter than the declared one"
5868 " for dummy argument '%s' (%ld/%ld)");
5869 }
5870
5871 /* Build the condition. For optional arguments, an actual length
5872 of 0 is also acceptable if the associated string is NULL, which
5873 means the argument was not passed. */
4c796f54 5874 cond = fold_build2_loc (input_location, comparison, logical_type_node,
fd779e1d 5875 cl->passed_length, cl->backend_decl);
a4abf8a0 5876 if (fsym->attr.optional)
5877 {
5878 tree not_absent;
5879 tree not_0length;
5880 tree absent_failed;
5881
fd779e1d 5882 not_0length = fold_build2_loc (input_location, NE_EXPR,
4c796f54 5883 logical_type_node,
fd779e1d 5884 cl->passed_length,
9f4d9f83 5885 build_zero_cst
5886 (TREE_TYPE (cl->passed_length)));
5fa0fdc2 5887 /* The symbol needs to be referenced for gfc_get_symbol_decl. */
5888 fsym->attr.referenced = 1;
5889 not_absent = gfc_conv_expr_present (fsym);
a4abf8a0 5890
fd779e1d 5891 absent_failed = fold_build2_loc (input_location, TRUTH_OR_EXPR,
4c796f54 5892 logical_type_node, not_0length,
fd779e1d 5893 not_absent);
a4abf8a0 5894
fd779e1d 5895 cond = fold_build2_loc (input_location, TRUTH_AND_EXPR,
4c796f54 5896 logical_type_node, cond, absent_failed);
a4abf8a0 5897 }
5898
5899 /* Build the runtime check. */
5900 argname = gfc_build_cstring_const (fsym->name);
5901 argname = gfc_build_addr_expr (pchar_type_node, argname);
5902 gfc_trans_runtime_check (true, false, cond, block, &fsym->declared_at,
5903 message, argname,
5904 fold_convert (long_integer_type_node,
5905 cl->passed_length),
5906 fold_convert (long_integer_type_node,
5907 cl->backend_decl));
5908 }
5909}
5910
5911
7257a5d2 5912static void
5913create_main_function (tree fndecl)
5914{
43702da6 5915 tree old_context;
7257a5d2 5916 tree ftn_main;
5917 tree tmp, decl, result_decl, argc, argv, typelist, arglist;
5918 stmtblock_t body;
5919
43702da6 5920 old_context = current_function_decl;
5921
5922 if (old_context)
5923 {
5924 push_function_context ();
5925 saved_parent_function_decls = saved_function_decls;
5926 saved_function_decls = NULL_TREE;
5927 }
5928
7257a5d2 5929 /* main() function must be declared with global scope. */
5930 gcc_assert (current_function_decl == NULL_TREE);
5931
5932 /* Declare the function. */
5933 tmp = build_function_type_list (integer_type_node, integer_type_node,
5934 build_pointer_type (pchar_type_node),
5935 NULL_TREE);
0509d0ee 5936 main_identifier_node = get_identifier ("main");
e60a6f7b 5937 ftn_main = build_decl (input_location, FUNCTION_DECL,
5938 main_identifier_node, tmp);
7257a5d2 5939 DECL_EXTERNAL (ftn_main) = 0;
5940 TREE_PUBLIC (ftn_main) = 1;
5941 TREE_STATIC (ftn_main) = 1;
5942 DECL_ATTRIBUTES (ftn_main)
5943 = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
5944
5945 /* Setup the result declaration (for "return 0"). */
e60a6f7b 5946 result_decl = build_decl (input_location,
5947 RESULT_DECL, NULL_TREE, integer_type_node);
7257a5d2 5948 DECL_ARTIFICIAL (result_decl) = 1;
5949 DECL_IGNORED_P (result_decl) = 1;
5950 DECL_CONTEXT (result_decl) = ftn_main;
5951 DECL_RESULT (ftn_main) = result_decl;
5952
5953 pushdecl (ftn_main);
5954
5955 /* Get the arguments. */
5956
5957 arglist = NULL_TREE;
5958 typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
5959
5960 tmp = TREE_VALUE (typelist);
e60a6f7b 5961 argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
7257a5d2 5962 DECL_CONTEXT (argc) = ftn_main;
5963 DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
5964 TREE_READONLY (argc) = 1;
5965 gfc_finish_decl (argc);
5966 arglist = chainon (arglist, argc);
5967
5968 typelist = TREE_CHAIN (typelist);
5969 tmp = TREE_VALUE (typelist);
e60a6f7b 5970 argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
7257a5d2 5971 DECL_CONTEXT (argv) = ftn_main;
5972 DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
5973 TREE_READONLY (argv) = 1;
5974 DECL_BY_REFERENCE (argv) = 1;
5975 gfc_finish_decl (argv);
5976 arglist = chainon (arglist, argv);
5977
5978 DECL_ARGUMENTS (ftn_main) = arglist;
5979 current_function_decl = ftn_main;
5980 announce_function (ftn_main);
5981
5982 rest_of_decl_compilation (ftn_main, 1, 0);
5983 make_decl_rtl (ftn_main);
00cf115c 5984 allocate_struct_function (ftn_main, false);
cde2be84 5985 pushlevel ();
7257a5d2 5986
5987 gfc_init_block (&body);
5988
293d72e0 5989 /* Call some libgfortran initialization routines, call then MAIN__(). */
7257a5d2 5990
d44f2f7c 5991 /* Call _gfortran_caf_init (*argc, ***argv). */
4fe73152 5992 if (flag_coarray == GFC_FCOARRAY_LIB)
70b5944a 5993 {
5994 tree pint_type, pppchar_type;
5995 pint_type = build_pointer_type (integer_type_node);
5996 pppchar_type
5997 = build_pointer_type (build_pointer_type (pchar_type_node));
5998
d44f2f7c 5999 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_init, 2,
70b5944a 6000 gfc_build_addr_expr (pint_type, argc),
d44f2f7c 6001 gfc_build_addr_expr (pppchar_type, argv));
70b5944a 6002 gfc_add_expr_to_block (&body, tmp);
6003 }
6004
7257a5d2 6005 /* Call _gfortran_set_args (argc, argv). */
43702da6 6006 TREE_USED (argc) = 1;
6007 TREE_USED (argv) = 1;
389dd41b 6008 tmp = build_call_expr_loc (input_location,
6009 gfor_fndecl_set_args, 2, argc, argv);
7257a5d2 6010 gfc_add_expr_to_block (&body, tmp);
6011
6012 /* Add a call to set_options to set up the runtime library Fortran
6013 language standard parameters. */
6014 {
6015 tree array_type, array, var;
f1f41a6c 6016 vec<constructor_elt, va_gc> *v = NULL;
f7619ded 6017 static const int noptions = 7;
7257a5d2 6018
f7619ded 6019 /* Passing a new option to the library requires three modifications:
6020 + add it to the tree_cons list below
6021 + change the noptions variable above
7257a5d2 6022 + modify the library (runtime/compile_options.c)! */
6023
06f13dc1 6024 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6025 build_int_cst (integer_type_node,
6026 gfc_option.warn_std));
6027 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6028 build_int_cst (integer_type_node,
6029 gfc_option.allow_std));
6030 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6031 build_int_cst (integer_type_node, pedantic));
06f13dc1 6032 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
829d7a08 6033 build_int_cst (integer_type_node, flag_backtrace));
06f13dc1 6034 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
829d7a08 6035 build_int_cst (integer_type_node, flag_sign_zero));
06f13dc1 6036 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6037 build_int_cst (integer_type_node,
6038 (gfc_option.rtcheck
6039 & GFC_RTCHECK_BOUNDS)));
6040 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
6041 build_int_cst (integer_type_node,
553e7cef 6042 gfc_option.fpe_summary));
7257a5d2 6043
f7619ded 6044 array_type = build_array_type_nelts (integer_type_node, noptions);
06f13dc1 6045 array = build_constructor (array_type, v);
7257a5d2 6046 TREE_CONSTANT (array) = 1;
6047 TREE_STATIC (array) = 1;
6048
6049 /* Create a static variable to hold the jump table. */
bf77f8ee 6050 var = build_decl (input_location, VAR_DECL,
f7619ded 6051 create_tmp_var_name ("options"), array_type);
bf77f8ee 6052 DECL_ARTIFICIAL (var) = 1;
6053 DECL_IGNORED_P (var) = 1;
7257a5d2 6054 TREE_CONSTANT (var) = 1;
6055 TREE_STATIC (var) = 1;
6056 TREE_READONLY (var) = 1;
6057 DECL_INITIAL (var) = array;
bf77f8ee 6058 pushdecl (var);
7257a5d2 6059 var = gfc_build_addr_expr (build_pointer_type (integer_type_node), var);
6060
389dd41b 6061 tmp = build_call_expr_loc (input_location,
6062 gfor_fndecl_set_options, 2,
f7619ded 6063 build_int_cst (integer_type_node, noptions), var);
7257a5d2 6064 gfc_add_expr_to_block (&body, tmp);
6065 }
6066
6067 /* If -ffpe-trap option was provided, add a call to set_fpe so that
6068 the library will raise a FPE when needed. */
6069 if (gfc_option.fpe != 0)
6070 {
389dd41b 6071 tmp = build_call_expr_loc (input_location,
6072 gfor_fndecl_set_fpe, 1,
7257a5d2 6073 build_int_cst (integer_type_node,
6074 gfc_option.fpe));
6075 gfc_add_expr_to_block (&body, tmp);
6076 }
6077
6078 /* If this is the main program and an -fconvert option was provided,
6079 add a call to set_convert. */
6080
4fe73152 6081 if (flag_convert != GFC_FLAG_CONVERT_NATIVE)
7257a5d2 6082 {
389dd41b 6083 tmp = build_call_expr_loc (input_location,
6084 gfor_fndecl_set_convert, 1,
4fe73152 6085 build_int_cst (integer_type_node, flag_convert));
7257a5d2 6086 gfc_add_expr_to_block (&body, tmp);
6087 }
6088
6089 /* If this is the main program and an -frecord-marker option was provided,
6090 add a call to set_record_marker. */
6091
eb106faf 6092 if (flag_record_marker != 0)
7257a5d2 6093 {
389dd41b 6094 tmp = build_call_expr_loc (input_location,
6095 gfor_fndecl_set_record_marker, 1,
7257a5d2 6096 build_int_cst (integer_type_node,
eb106faf 6097 flag_record_marker));
7257a5d2 6098 gfc_add_expr_to_block (&body, tmp);
6099 }
6100
eb106faf 6101 if (flag_max_subrecord_length != 0)
7257a5d2 6102 {
389dd41b 6103 tmp = build_call_expr_loc (input_location,
6104 gfor_fndecl_set_max_subrecord_length, 1,
7257a5d2 6105 build_int_cst (integer_type_node,
eb106faf 6106 flag_max_subrecord_length));
7257a5d2 6107 gfc_add_expr_to_block (&body, tmp);
6108 }
6109
6110 /* Call MAIN__(). */
389dd41b 6111 tmp = build_call_expr_loc (input_location,
6112 fndecl, 0);
7257a5d2 6113 gfc_add_expr_to_block (&body, tmp);
6114
43702da6 6115 /* Mark MAIN__ as used. */
6116 TREE_USED (fndecl) = 1;
6117
70b5944a 6118 /* Coarray: Call _gfortran_caf_finalize(void). */
4fe73152 6119 if (flag_coarray == GFC_FCOARRAY_LIB)
a90fe829 6120 {
70b5944a 6121 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_finalize, 0);
6122 gfc_add_expr_to_block (&body, tmp);
6123 }
6124
7257a5d2 6125 /* "return 0". */
fd779e1d 6126 tmp = fold_build2_loc (input_location, MODIFY_EXPR, integer_type_node,
6127 DECL_RESULT (ftn_main),
6128 build_int_cst (integer_type_node, 0));
7257a5d2 6129 tmp = build1_v (RETURN_EXPR, tmp);
6130 gfc_add_expr_to_block (&body, tmp);
6131
6132
6133 DECL_SAVED_TREE (ftn_main) = gfc_finish_block (&body);
6134 decl = getdecls ();
6135
6136 /* Finish off this function and send it for code generation. */
cde2be84 6137 poplevel (1, 1);
7257a5d2 6138 BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main;
6139
6140 DECL_SAVED_TREE (ftn_main)
6141 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (ftn_main),
6142 DECL_INITIAL (ftn_main));
6143
6144 /* Output the GENERIC tree. */
6145 dump_function (TDI_original, ftn_main);
6146
35ee1c66 6147 cgraph_node::finalize_function (ftn_main, true);
43702da6 6148
6149 if (old_context)
6150 {
6151 pop_function_context ();
6152 saved_function_decls = saved_parent_function_decls;
6153 }
6154 current_function_decl = old_context;
7257a5d2 6155}
6156
6157
89ac8ba1 6158/* Generate an appropriate return-statement for a procedure. */
6159
6160tree
6161gfc_generate_return (void)
6162{
6163 gfc_symbol* sym;
6164 tree result;
6165 tree fndecl;
6166
6167 sym = current_procedure_symbol;
6168 fndecl = sym->backend_decl;
6169
6170 if (TREE_TYPE (DECL_RESULT (fndecl)) == void_type_node)
6171 result = NULL_TREE;
6172 else
6173 {
6174 result = get_proc_result (sym);
6175
6176 /* Set the return value to the dummy result variable. The
6177 types may be different for scalar default REAL functions
6178 with -ff2c, therefore we have to convert. */
6179 if (result != NULL_TREE)
6180 {
6181 result = convert (TREE_TYPE (DECL_RESULT (fndecl)), result);
fd779e1d 6182 result = fold_build2_loc (input_location, MODIFY_EXPR,
6183 TREE_TYPE (result), DECL_RESULT (fndecl),
6184 result);
89ac8ba1 6185 }
6186 }
6187
6188 return build1_v (RETURN_EXPR, result);
6189}
6190
6191
d566c3e0 6192static void
6193is_from_ieee_module (gfc_symbol *sym)
6194{
6195 if (sym->from_intmod == INTMOD_IEEE_FEATURES
6196 || sym->from_intmod == INTMOD_IEEE_EXCEPTIONS
6197 || sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
6198 seen_ieee_symbol = 1;
6199}
6200
6201
6202static int
6203is_ieee_module_used (gfc_namespace *ns)
6204{
6205 seen_ieee_symbol = 0;
6206 gfc_traverse_ns (ns, is_from_ieee_module);
6207 return seen_ieee_symbol;
6208}
6209
6210
01d728a4 6211static gfc_omp_clauses *module_oacc_clauses;
6212
6213
6214static void
6215add_clause (gfc_symbol *sym, gfc_omp_map_op map_op)
6216{
6217 gfc_omp_namelist *n;
6218
6219 n = gfc_get_omp_namelist ();
6220 n->sym = sym;
6221 n->u.map_op = map_op;
6222
6223 if (!module_oacc_clauses)
6224 module_oacc_clauses = gfc_get_omp_clauses ();
6225
6226 if (module_oacc_clauses->lists[OMP_LIST_MAP])
6227 n->next = module_oacc_clauses->lists[OMP_LIST_MAP];
6228
6229 module_oacc_clauses->lists[OMP_LIST_MAP] = n;
6230}
6231
6232
6233static void
6234find_module_oacc_declare_clauses (gfc_symbol *sym)
6235{
6236 if (sym->attr.use_assoc)
6237 {
6238 gfc_omp_map_op map_op;
6239
6240 if (sym->attr.oacc_declare_create)
6241 map_op = OMP_MAP_FORCE_ALLOC;
6242
6243 if (sym->attr.oacc_declare_copyin)
6244 map_op = OMP_MAP_FORCE_TO;
6245
6246 if (sym->attr.oacc_declare_deviceptr)
6247 map_op = OMP_MAP_FORCE_DEVICEPTR;
6248
6249 if (sym->attr.oacc_declare_device_resident)
6250 map_op = OMP_MAP_DEVICE_RESIDENT;
6251
6252 if (sym->attr.oacc_declare_create
6253 || sym->attr.oacc_declare_copyin
6254 || sym->attr.oacc_declare_deviceptr
6255 || sym->attr.oacc_declare_device_resident)
6256 {
6257 sym->attr.referenced = 1;
6258 add_clause (sym, map_op);
6259 }
6260 }
6261}
6262
6263
6264void
6265finish_oacc_declare (gfc_namespace *ns, gfc_symbol *sym, bool block)
6266{
6267 gfc_code *code;
6268 gfc_oacc_declare *oc;
6269 locus where = gfc_current_locus;
6270 gfc_omp_clauses *omp_clauses = NULL;
6271 gfc_omp_namelist *n, *p;
6272
6273 gfc_traverse_ns (ns, find_module_oacc_declare_clauses);
6274
6275 if (module_oacc_clauses && sym->attr.flavor == FL_PROGRAM)
6276 {
6277 gfc_oacc_declare *new_oc;
6278
6279 new_oc = gfc_get_oacc_declare ();
6280 new_oc->next = ns->oacc_declare;
6281 new_oc->clauses = module_oacc_clauses;
6282
6283 ns->oacc_declare = new_oc;
6284 module_oacc_clauses = NULL;
6285 }
6286
6287 if (!ns->oacc_declare)
6288 return;
6289
6290 for (oc = ns->oacc_declare; oc; oc = oc->next)
6291 {
6292 if (oc->module_var)
6293 continue;
6294
6295 if (block)
f187ad6c 6296 gfc_error ("Sorry, !$ACC DECLARE at %L is not allowed "
01d728a4 6297 "in BLOCK construct", &oc->loc);
6298
6299
6300 if (oc->clauses && oc->clauses->lists[OMP_LIST_MAP])
6301 {
6302 if (omp_clauses == NULL)
6303 {
6304 omp_clauses = oc->clauses;
6305 continue;
6306 }
6307
6308 for (n = oc->clauses->lists[OMP_LIST_MAP]; n; p = n, n = n->next)
6309 ;
6310
6311 gcc_assert (p->next == NULL);
6312
6313 p->next = omp_clauses->lists[OMP_LIST_MAP];
6314 omp_clauses = oc->clauses;
6315 }
6316 }
6317
6318 if (!omp_clauses)
6319 return;
6320
6321 for (n = omp_clauses->lists[OMP_LIST_MAP]; n; n = n->next)
6322 {
6323 switch (n->u.map_op)
6324 {
6325 case OMP_MAP_DEVICE_RESIDENT:
6326 n->u.map_op = OMP_MAP_FORCE_ALLOC;
6327 break;
6328
6329 default:
6330 break;
6331 }
6332 }
6333
6334 code = XCNEW (gfc_code);
6335 code->op = EXEC_OACC_DECLARE;
6336 code->loc = where;
6337
6338 code->ext.oacc_declare = gfc_get_oacc_declare ();
6339 code->ext.oacc_declare->clauses = omp_clauses;
6340
6341 code->block = XCNEW (gfc_code);
6342 code->block->op = EXEC_OACC_DECLARE;
6343 code->block->loc = where;
6344
6345 if (ns->code)
6346 code->block->next = ns->code;
6347
6348 ns->code = code;
6349
6350 return;
6351}
6352
6353
4ee9c684 6354/* Generate code for a function. */
6355
6356void
6357gfc_generate_function_code (gfc_namespace * ns)
6358{
6359 tree fndecl;
6360 tree old_context;
6361 tree decl;
6362 tree tmp;
d566c3e0 6363 tree fpstate = NULL_TREE;
89ac8ba1 6364 stmtblock_t init, cleanup;
4ee9c684 6365 stmtblock_t body;
89ac8ba1 6366 gfc_wrapped_block try_block;
5fa0fdc2 6367 tree recurcheckvar = NULL_TREE;
4ee9c684 6368 gfc_symbol *sym;
89ac8ba1 6369 gfc_symbol *previous_procedure_symbol;
d566c3e0 6370 int rank, ieee;
e50e62f5 6371 bool is_recursive;
4ee9c684 6372
6373 sym = ns->proc_name;
89ac8ba1 6374 previous_procedure_symbol = current_procedure_symbol;
6375 current_procedure_symbol = sym;
1b716045 6376
8b7e5587 6377 /* Initialize sym->tlink so that gfc_trans_deferred_vars does not get
6378 lost or worse. */
4ee9c684 6379 sym->tlink = sym;
6380
6381 /* Create the declaration for functions with global scope. */
6382 if (!sym->backend_decl)
d896f9b3 6383 gfc_create_function_decl (ns, false);
4ee9c684 6384
6385 fndecl = sym->backend_decl;
6386 old_context = current_function_decl;
6387
6388 if (old_context)
6389 {
6390 push_function_context ();
6391 saved_parent_function_decls = saved_function_decls;
6392 saved_function_decls = NULL_TREE;
6393 }
6394
1b716045 6395 trans_function_start (sym);
4ee9c684 6396
89ac8ba1 6397 gfc_init_block (&init);
4ee9c684 6398
c6871095 6399 if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER)
6400 {
6401 /* Copy length backend_decls to all entry point result
6402 symbols. */
6403 gfc_entry_list *el;
6404 tree backend_decl;
6405
eeebe20b 6406 gfc_conv_const_charlen (ns->proc_name->ts.u.cl);
6407 backend_decl = ns->proc_name->result->ts.u.cl->backend_decl;
c6871095 6408 for (el = ns->entries; el; el = el->next)
eeebe20b 6409 el->sym->result->ts.u.cl->backend_decl = backend_decl;
c6871095 6410 }
6411
4ee9c684 6412 /* Translate COMMON blocks. */
6413 gfc_trans_common (ns);
6414
c750cc52 6415 /* Null the parent fake result declaration if this namespace is
6416 a module function or an external procedures. */
6417 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
6418 || ns->parent == NULL)
6419 parent_fake_result_decl = NULL_TREE;
6420
2b685f8e 6421 gfc_generate_contained_functions (ns);
6422
9579733e 6423 nonlocal_dummy_decls = NULL;
6424 nonlocal_dummy_decl_pset = NULL;
6425
a961ca30 6426 has_coarray_vars = false;
4ee9c684 6427 generate_local_vars (ns);
5b11d932 6428
4fe73152 6429 if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
a961ca30 6430 generate_coarray_init (ns);
6431
c750cc52 6432 /* Keep the parent fake result declaration in module functions
6433 or external procedures. */
6434 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE)
6435 || ns->parent == NULL)
6436 current_fake_result_decl = parent_fake_result_decl;
6437 else
6438 current_fake_result_decl = NULL_TREE;
6439
89ac8ba1 6440 is_recursive = sym->attr.recursive
6441 || (sym->attr.entry_master
6442 && sym->ns->entries->sym->attr.recursive);
6443 if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
829d7a08 6444 && !is_recursive && !flag_recursive)
89ac8ba1 6445 {
6446 char * msg;
6447
87fda26c 6448 msg = xasprintf ("Recursive call to nonrecursive procedure '%s'",
6449 sym->name);
4c796f54 6450 recurcheckvar = gfc_create_var (logical_type_node, "is_recursive");
89ac8ba1 6451 TREE_STATIC (recurcheckvar) = 1;
4c796f54 6452 DECL_INITIAL (recurcheckvar) = logical_false_node;
89ac8ba1 6453 gfc_add_expr_to_block (&init, recurcheckvar);
6454 gfc_trans_runtime_check (true, false, recurcheckvar, &init,
6455 &sym->declared_at, msg);
4c796f54 6456 gfc_add_modify (&init, recurcheckvar, logical_true_node);
434f0922 6457 free (msg);
89ac8ba1 6458 }
4ee9c684 6459
d566c3e0 6460 /* Check if an IEEE module is used in the procedure. If so, save
6461 the floating point state. */
6462 ieee = is_ieee_module_used (ns);
6463 if (ieee)
d7333535 6464 fpstate = gfc_save_fp_state (&init);
d566c3e0 6465
4ee9c684 6466 /* Now generate the code for the body of this function. */
6467 gfc_init_block (&body);
6468
6469 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
89ac8ba1 6470 && sym->attr.subroutine)
4ee9c684 6471 {
6472 tree alternate_return;
c750cc52 6473 alternate_return = gfc_get_fake_result_decl (sym, 0);
75a70cf9 6474 gfc_add_modify (&body, alternate_return, integer_zero_node);
4ee9c684 6475 }
6476
1b716045 6477 if (ns->entries)
6478 {
6479 /* Jump to the correct entry point. */
6480 tmp = gfc_trans_entry_master_switch (ns->entries);
6481 gfc_add_expr_to_block (&body, tmp);
6482 }
6483
a4abf8a0 6484 /* If bounds-checking is enabled, generate code to check passed in actual
6485 arguments against the expected dummy argument attributes (e.g. string
6486 lengths). */
c1630d65 6487 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !sym->attr.is_bind_c)
a4abf8a0 6488 add_argument_checking (&body, sym);
6489
01d728a4 6490 finish_oacc_declare (ns, sym, false);
ca4c3545 6491
4ee9c684 6492 tmp = gfc_trans_code (ns->code);
6493 gfc_add_expr_to_block (&body, tmp);
6494
1caa6ab1 6495 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
6496 || (sym->result && sym->result != sym
6497 && sym->result->ts.type == BT_DERIVED
6498 && sym->result->ts.u.derived->attr.alloc_comp))
4ee9c684 6499 {
1caa6ab1 6500 bool artificial_result_decl = false;
89ac8ba1 6501 tree result = get_proc_result (sym);
1caa6ab1 6502 gfc_symbol *rsym = sym == sym->result ? sym : sym->result;
6503
6504 /* Make sure that a function returning an object with
6505 alloc/pointer_components always has a result, where at least
6506 the allocatable/pointer components are set to zero. */
6507 if (result == NULL_TREE && sym->attr.function
6508 && ((sym->result->ts.type == BT_DERIVED
6509 && (sym->attr.allocatable
6510 || sym->attr.pointer
6511 || sym->result->ts.u.derived->attr.alloc_comp
6512 || sym->result->ts.u.derived->attr.pointer_comp))
6513 || (sym->result->ts.type == BT_CLASS
6514 && (CLASS_DATA (sym)->attr.allocatable
6515 || CLASS_DATA (sym)->attr.class_pointer
6516 || CLASS_DATA (sym->result)->attr.alloc_comp
6517 || CLASS_DATA (sym->result)->attr.pointer_comp))))
6518 {
6519 artificial_result_decl = true;
6520 result = gfc_get_fake_result_decl (sym, 0);
6521 }
4ee9c684 6522
42766cb3 6523 if (result != NULL_TREE && sym->attr.function && !sym->attr.pointer)
2294b616 6524 {
deb7edfc 6525 if (sym->attr.allocatable && sym->attr.dimension == 0
6526 && sym->result == sym)
6527 gfc_add_modify (&init, result, fold_convert (TREE_TYPE (result),
6528 null_pointer_node));
42766cb3 6529 else if (sym->ts.type == BT_CLASS
6530 && CLASS_DATA (sym)->attr.allocatable
3a19c063 6531 && CLASS_DATA (sym)->attr.dimension == 0
6532 && sym->result == sym)
42766cb3 6533 {
6534 tmp = CLASS_DATA (sym)->backend_decl;
6535 tmp = fold_build3_loc (input_location, COMPONENT_REF,
6536 TREE_TYPE (tmp), result, tmp, NULL_TREE);
6537 gfc_add_modify (&init, tmp, fold_convert (TREE_TYPE (tmp),
6538 null_pointer_node));
6539 }
deb7edfc 6540 else if (sym->ts.type == BT_DERIVED
42766cb3 6541 && !sym->attr.allocatable)
53169279 6542 {
1caa6ab1 6543 gfc_expr *init_exp;
6544 /* Arrays are not initialized using the default initializer of
6545 their elements. Therefore only check if a default
6546 initializer is available when the result is scalar. */
36d310d0 6547 init_exp = rsym->as ? NULL
6548 : gfc_generate_initializer (&rsym->ts, true);
1caa6ab1 6549 if (init_exp)
6550 {
6551 tmp = gfc_trans_structure_assign (result, init_exp, 0);
6552 gfc_free_expr (init_exp);
6553 gfc_add_expr_to_block (&init, tmp);
6554 }
6555 else if (rsym->ts.u.derived->attr.alloc_comp)
6556 {
6557 rank = rsym->as ? rsym->as->rank : 0;
6558 tmp = gfc_nullify_alloc_comp (rsym->ts.u.derived, result,
6559 rank);
6560 gfc_prepend_expr_to_block (&body, tmp);
6561 }
53169279 6562 }
5176859a 6563 }
e50e62f5 6564
1caa6ab1 6565 if (result == NULL_TREE || artificial_result_decl)
fa7b6574 6566 {
6567 /* TODO: move to the appropriate place in resolve.c. */
8b72061f 6568 if (warn_return_type > 0 && sym == sym->result)
4166acc7 6569 gfc_warning (OPT_Wreturn_type,
6570 "Return value of function %qs at %L not set",
fa7b6574 6571 sym->name, &sym->declared_at);
8b72061f 6572 if (warn_return_type > 0)
90a4a5a6 6573 TREE_NO_WARNING(sym->backend_decl) = 1;
fa7b6574 6574 }
1caa6ab1 6575 if (result != NULL_TREE)
89ac8ba1 6576 gfc_add_expr_to_block (&body, gfc_generate_return ());
4ee9c684 6577 }
89ac8ba1 6578
6579 gfc_init_block (&cleanup);
6580
6581 /* Reset recursion-check variable. */
6582 if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
829d7a08 6583 && !is_recursive && !flag_openmp && recurcheckvar != NULL_TREE)
e50e62f5 6584 {
4c796f54 6585 gfc_add_modify (&cleanup, recurcheckvar, logical_false_node);
89ac8ba1 6586 recurcheckvar = NULL;
e50e62f5 6587 }
2294b616 6588
d566c3e0 6589 /* If IEEE modules are loaded, restore the floating-point state. */
6590 if (ieee)
d7333535 6591 gfc_restore_fp_state (&cleanup, fpstate);
d566c3e0 6592
89ac8ba1 6593 /* Finish the function body and add init and cleanup code. */
6594 tmp = gfc_finish_block (&body);
6595 gfc_start_wrapped_block (&try_block, tmp);
6596 /* Add code to create and cleanup arrays. */
6597 gfc_trans_deferred_vars (sym, &try_block);
6598 gfc_add_init_cleanup (&try_block, gfc_finish_block (&init),
6599 gfc_finish_block (&cleanup));
4ee9c684 6600
6601 /* Add all the decls we created during processing. */
267f3c67 6602 decl = nreverse (saved_function_decls);
4ee9c684 6603 while (decl)
6604 {
6605 tree next;
6606
1767a056 6607 next = DECL_CHAIN (decl);
6608 DECL_CHAIN (decl) = NULL_TREE;
4c197fd0 6609 pushdecl (decl);
4ee9c684 6610 decl = next;
6611 }
6612 saved_function_decls = NULL_TREE;
6613
89ac8ba1 6614 DECL_SAVED_TREE (fndecl) = gfc_finish_wrapped_block (&try_block);
e5004242 6615 decl = getdecls ();
4ee9c684 6616
6617 /* Finish off this function and send it for code generation. */
cde2be84 6618 poplevel (1, 1);
4ee9c684 6619 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
6620
e5004242 6621 DECL_SAVED_TREE (fndecl)
6622 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
6623 DECL_INITIAL (fndecl));
6624
9579733e 6625 if (nonlocal_dummy_decls)
6626 {
6627 BLOCK_VARS (DECL_INITIAL (fndecl))
6628 = chainon (BLOCK_VARS (DECL_INITIAL (fndecl)), nonlocal_dummy_decls);
431205b7 6629 delete nonlocal_dummy_decl_pset;
9579733e 6630 nonlocal_dummy_decls = NULL;
6631 nonlocal_dummy_decl_pset = NULL;
6632 }
6633
4ee9c684 6634 /* Output the GENERIC tree. */
6635 dump_function (TDI_original, fndecl);
6636
6637 /* Store the end of the function, so that we get good line number
6638 info for the epilogue. */
6639 cfun->function_end_locus = input_location;
6640
6641 /* We're leaving the context of this function, so zap cfun.
6642 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
6643 tree_rest_of_compilation. */
87d4aa85 6644 set_cfun (NULL);
4ee9c684 6645
6646 if (old_context)
6647 {
6648 pop_function_context ();
6649 saved_function_decls = saved_parent_function_decls;
6650 }
6651 current_function_decl = old_context;
6652
1f7747bd 6653 if (decl_function_context (fndecl))
6654 {
6655 /* Register this function with cgraph just far enough to get it
6656 added to our parent's nested function list.
6657 If there are static coarrays in this function, the nested _caf_init
6658 function has already called cgraph_create_node, which also created
6659 the cgraph node for this function. */
4fe73152 6660 if (!has_coarray_vars || flag_coarray != GFC_FCOARRAY_LIB)
0d565f19 6661 (void) cgraph_node::get_create (fndecl);
1f7747bd 6662 }
4ee9c684 6663 else
35ee1c66 6664 cgraph_node::finalize_function (fndecl, true);
df4d540f 6665
6666 gfc_trans_use_stmts (ns);
2eb674c9 6667 gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
7257a5d2 6668
6669 if (sym->attr.is_main_program)
6670 create_main_function (fndecl);
89ac8ba1 6671
6672 current_procedure_symbol = previous_procedure_symbol;
4ee9c684 6673}
6674
7257a5d2 6675
4ee9c684 6676void
6677gfc_generate_constructors (void)
6678{
22d678e8 6679 gcc_assert (gfc_static_ctors == NULL_TREE);
4ee9c684 6680#if 0
6681 tree fnname;
6682 tree type;
6683 tree fndecl;
6684 tree decl;
6685 tree tmp;
6686
6687 if (gfc_static_ctors == NULL_TREE)
6688 return;
6689
db85cc4f 6690 fnname = get_file_function_name ("I");
e1036019 6691 type = build_function_type_list (void_type_node, NULL_TREE);
4ee9c684 6692
e60a6f7b 6693 fndecl = build_decl (input_location,
6694 FUNCTION_DECL, fnname, type);
4ee9c684 6695 TREE_PUBLIC (fndecl) = 1;
6696
e60a6f7b 6697 decl = build_decl (input_location,
6698 RESULT_DECL, NULL_TREE, void_type_node);
540edea7 6699 DECL_ARTIFICIAL (decl) = 1;
6700 DECL_IGNORED_P (decl) = 1;
4ee9c684 6701 DECL_CONTEXT (decl) = fndecl;
6702 DECL_RESULT (fndecl) = decl;
6703
6704 pushdecl (fndecl);
6705
6706 current_function_decl = fndecl;
6707
b2c4af5e 6708 rest_of_decl_compilation (fndecl, 1, 0);
4ee9c684 6709
b2c4af5e 6710 make_decl_rtl (fndecl);
4ee9c684 6711
00cf115c 6712 allocate_struct_function (fndecl, false);
4ee9c684 6713
cde2be84 6714 pushlevel ();
4ee9c684 6715
6716 for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
6717 {
389dd41b 6718 tmp = build_call_expr_loc (input_location,
6719 TREE_VALUE (gfc_static_ctors), 0);
e60a6f7b 6720 DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp);
4ee9c684 6721 }
6722
e5004242 6723 decl = getdecls ();
cde2be84 6724 poplevel (1, 1);
4ee9c684 6725
6726 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
e5004242 6727 DECL_SAVED_TREE (fndecl)
6728 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl),
6729 DECL_INITIAL (fndecl));
4ee9c684 6730
6731 free_after_parsing (cfun);
6732 free_after_compilation (cfun);
6733
6148a911 6734 tree_rest_of_compilation (fndecl);
4ee9c684 6735
6736 current_function_decl = NULL_TREE;
6737#endif
6738}
6739
9ec7c303 6740/* Translates a BLOCK DATA program unit. This means emitting the
6741 commons contained therein plus their initializations. We also emit
6742 a globally visible symbol to make sure that each BLOCK DATA program
6743 unit remains unique. */
6744
6745void
6746gfc_generate_block_data (gfc_namespace * ns)
6747{
6748 tree decl;
6749 tree id;
6750
b31f705b 6751 /* Tell the backend the source location of the block data. */
6752 if (ns->proc_name)
6753 gfc_set_backend_locus (&ns->proc_name->declared_at);
6754 else
6755 gfc_set_backend_locus (&gfc_current_locus);
6756
6757 /* Process the DATA statements. */
9ec7c303 6758 gfc_trans_common (ns);
6759
b31f705b 6760 /* Create a global symbol with the mane of the block data. This is to
6761 generate linker errors if the same name is used twice. It is never
6762 really used. */
9ec7c303 6763 if (ns->proc_name)
6764 id = gfc_sym_mangled_function_id (ns->proc_name);
6765 else
6766 id = get_identifier ("__BLOCK_DATA__");
6767
e60a6f7b 6768 decl = build_decl (input_location,
6769 VAR_DECL, id, gfc_array_index_type);
9ec7c303 6770 TREE_PUBLIC (decl) = 1;
6771 TREE_STATIC (decl) = 1;
df4d540f 6772 DECL_IGNORED_P (decl) = 1;
9ec7c303 6773
6774 pushdecl (decl);
6775 rest_of_decl_compilation (decl, 1, 0);
6776}
6777
b549d2a5 6778
6a7084d7 6779/* Process the local variables of a BLOCK construct. */
6780
6781void
3c82e013 6782gfc_process_block_locals (gfc_namespace* ns)
6a7084d7 6783{
6784 tree decl;
6785
6786 gcc_assert (saved_local_decls == NULL_TREE);
a961ca30 6787 has_coarray_vars = false;
6788
6a7084d7 6789 generate_local_vars (ns);
6790
4fe73152 6791 if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
a961ca30 6792 generate_coarray_init (ns);
6793
267f3c67 6794 decl = nreverse (saved_local_decls);
6a7084d7 6795 while (decl)
6796 {
6797 tree next;
6798
1767a056 6799 next = DECL_CHAIN (decl);
6800 DECL_CHAIN (decl) = NULL_TREE;
6a7084d7 6801 pushdecl (decl);
6802 decl = next;
6803 }
6804 saved_local_decls = NULL_TREE;
6805}
6806
6807
4ee9c684 6808#include "gt-fortran-trans-decl.h"