OLD | NEW |
1 /* Backend function setup | 1 /* Backend function setup |
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
4 Contributed by Paul Brook | 4 Contributed by Paul Brook |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
9 the terms of the GNU General Public License as published by the Free | 9 the terms of the GNU General Public License as published by the Free |
10 Software Foundation; either version 3, or (at your option) any later | 10 Software Foundation; either version 3, or (at your option) any later |
11 version. | 11 version. |
12 | 12 |
(...skipping 17 matching lines...) Expand all Loading... |
30 #include "ggc.h" | 30 #include "ggc.h" |
31 #include "toplev.h" | 31 #include "toplev.h" |
32 #include "tm.h" | 32 #include "tm.h" |
33 #include "rtl.h" | 33 #include "rtl.h" |
34 #include "target.h" | 34 #include "target.h" |
35 #include "function.h" | 35 #include "function.h" |
36 #include "flags.h" | 36 #include "flags.h" |
37 #include "cgraph.h" | 37 #include "cgraph.h" |
38 #include "debug.h" | 38 #include "debug.h" |
39 #include "gfortran.h" | 39 #include "gfortran.h" |
| 40 #include "pointer-set.h" |
40 #include "trans.h" | 41 #include "trans.h" |
41 #include "trans-types.h" | 42 #include "trans-types.h" |
42 #include "trans-array.h" | 43 #include "trans-array.h" |
43 #include "trans-const.h" | 44 #include "trans-const.h" |
44 /* Only for gfc_trans_code. Shouldn't need to include this. */ | 45 /* Only for gfc_trans_code. Shouldn't need to include this. */ |
45 #include "trans-stmt.h" | 46 #include "trans-stmt.h" |
46 | 47 |
47 #define MAX_LABEL_VALUE 99999 | 48 #define MAX_LABEL_VALUE 99999 |
48 | 49 |
49 | 50 |
50 /* Holds the result of the function if no result variable specified. */ | 51 /* Holds the result of the function if no result variable specified. */ |
51 | 52 |
52 static GTY(()) tree current_fake_result_decl; | 53 static GTY(()) tree current_fake_result_decl; |
53 static GTY(()) tree parent_fake_result_decl; | 54 static GTY(()) tree parent_fake_result_decl; |
54 | 55 |
55 static GTY(()) tree current_function_return_label; | 56 static GTY(()) tree current_function_return_label; |
56 | 57 |
57 | 58 |
58 /* Holds the variable DECLs for the current function. */ | 59 /* Holds the variable DECLs for the current function. */ |
59 | 60 |
60 static GTY(()) tree saved_function_decls; | 61 static GTY(()) tree saved_function_decls; |
61 static GTY(()) tree saved_parent_function_decls; | 62 static GTY(()) tree saved_parent_function_decls; |
62 | 63 |
| 64 static struct pointer_set_t *nonlocal_dummy_decl_pset; |
| 65 static GTY(()) tree nonlocal_dummy_decls; |
| 66 |
| 67 /* Holds the variable DECLs that are locals. */ |
| 68 |
| 69 static GTY(()) tree saved_local_decls; |
63 | 70 |
64 /* The namespace of the module we're currently generating. Only used while | 71 /* The namespace of the module we're currently generating. Only used while |
65 outputting decls for module variables. Do not rely on this being set. */ | 72 outputting decls for module variables. Do not rely on this being set. */ |
66 | 73 |
67 static gfc_namespace *module_namespace; | 74 static gfc_namespace *module_namespace; |
68 | 75 |
69 | 76 |
70 /* List of static constructor functions. */ | 77 /* List of static constructor functions. */ |
71 | 78 |
72 tree gfc_static_ctors; | 79 tree gfc_static_ctors; |
73 | 80 |
74 | 81 |
75 /* Function declarations for builtin library functions. */ | 82 /* Function declarations for builtin library functions. */ |
76 | 83 |
77 tree gfor_fndecl_pause_numeric; | 84 tree gfor_fndecl_pause_numeric; |
78 tree gfor_fndecl_pause_string; | 85 tree gfor_fndecl_pause_string; |
79 tree gfor_fndecl_stop_numeric; | 86 tree gfor_fndecl_stop_numeric; |
80 tree gfor_fndecl_stop_string; | 87 tree gfor_fndecl_stop_string; |
81 tree gfor_fndecl_runtime_error; | 88 tree gfor_fndecl_runtime_error; |
82 tree gfor_fndecl_runtime_error_at; | 89 tree gfor_fndecl_runtime_error_at; |
83 tree gfor_fndecl_runtime_warning_at; | 90 tree gfor_fndecl_runtime_warning_at; |
84 tree gfor_fndecl_os_error; | 91 tree gfor_fndecl_os_error; |
85 tree gfor_fndecl_generate_error; | 92 tree gfor_fndecl_generate_error; |
| 93 tree gfor_fndecl_set_args; |
86 tree gfor_fndecl_set_fpe; | 94 tree gfor_fndecl_set_fpe; |
87 tree gfor_fndecl_set_options; | 95 tree gfor_fndecl_set_options; |
88 tree gfor_fndecl_set_convert; | 96 tree gfor_fndecl_set_convert; |
89 tree gfor_fndecl_set_record_marker; | 97 tree gfor_fndecl_set_record_marker; |
90 tree gfor_fndecl_set_max_subrecord_length; | 98 tree gfor_fndecl_set_max_subrecord_length; |
91 tree gfor_fndecl_ctime; | 99 tree gfor_fndecl_ctime; |
92 tree gfor_fndecl_fdate; | 100 tree gfor_fndecl_fdate; |
93 tree gfor_fndecl_ttynam; | 101 tree gfor_fndecl_ttynam; |
94 tree gfor_fndecl_in_pack; | 102 tree gfor_fndecl_in_pack; |
95 tree gfor_fndecl_in_unpack; | 103 tree gfor_fndecl_in_unpack; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 void | 177 void |
170 gfc_add_decl_to_function (tree decl) | 178 gfc_add_decl_to_function (tree decl) |
171 { | 179 { |
172 gcc_assert (decl); | 180 gcc_assert (decl); |
173 TREE_USED (decl) = 1; | 181 TREE_USED (decl) = 1; |
174 DECL_CONTEXT (decl) = current_function_decl; | 182 DECL_CONTEXT (decl) = current_function_decl; |
175 TREE_CHAIN (decl) = saved_function_decls; | 183 TREE_CHAIN (decl) = saved_function_decls; |
176 saved_function_decls = decl; | 184 saved_function_decls = decl; |
177 } | 185 } |
178 | 186 |
| 187 static void |
| 188 add_decl_as_local (tree decl) |
| 189 { |
| 190 gcc_assert (decl); |
| 191 TREE_USED (decl) = 1; |
| 192 DECL_CONTEXT (decl) = current_function_decl; |
| 193 TREE_CHAIN (decl) = saved_local_decls; |
| 194 saved_local_decls = decl; |
| 195 } |
| 196 |
179 | 197 |
180 /* Build a backend label declaration. Set TREE_USED for named labels. | 198 /* Build a backend label declaration. Set TREE_USED for named labels. |
181 The context of the label is always the current_function_decl. All | 199 The context of the label is always the current_function_decl. All |
182 labels are marked artificial. */ | 200 labels are marked artificial. */ |
183 | 201 |
184 tree | 202 tree |
185 gfc_build_label_decl (tree label_id) | 203 gfc_build_label_decl (tree label_id) |
186 { | 204 { |
187 /* 2^32 temporaries should be enough. */ | 205 /* 2^32 temporaries should be enough. */ |
188 static unsigned int tmp_num = 1; | 206 static unsigned int tmp_num = 1; |
189 tree label_decl; | 207 tree label_decl; |
190 char *label_name; | 208 char *label_name; |
191 | 209 |
192 if (label_id == NULL_TREE) | 210 if (label_id == NULL_TREE) |
193 { | 211 { |
194 /* Build an internal label name. */ | 212 /* Build an internal label name. */ |
195 ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++); | 213 ASM_FORMAT_PRIVATE_NAME (label_name, "L", tmp_num++); |
196 label_id = get_identifier (label_name); | 214 label_id = get_identifier (label_name); |
197 } | 215 } |
198 else | 216 else |
199 label_name = NULL; | 217 label_name = NULL; |
200 | 218 |
201 /* Build the LABEL_DECL node. Labels have no type. */ | 219 /* Build the LABEL_DECL node. Labels have no type. */ |
202 label_decl = build_decl (LABEL_DECL, label_id, void_type_node); | 220 label_decl = build_decl (input_location, |
| 221 » » » LABEL_DECL, label_id, void_type_node); |
203 DECL_CONTEXT (label_decl) = current_function_decl; | 222 DECL_CONTEXT (label_decl) = current_function_decl; |
204 DECL_MODE (label_decl) = VOIDmode; | 223 DECL_MODE (label_decl) = VOIDmode; |
205 | 224 |
206 /* We always define the label as used, even if the original source | 225 /* We always define the label as used, even if the original source |
207 file never references the label. We don't want all kinds of | 226 file never references the label. We don't want all kinds of |
208 spurious warnings for old-style Fortran code with too many | 227 spurious warnings for old-style Fortran code with too many |
209 labels. */ | 228 labels. */ |
210 TREE_USED (label_decl) = 1; | 229 TREE_USED (label_decl) = 1; |
211 | 230 |
212 DECL_ARTIFICIAL (label_decl) = 1; | 231 DECL_ARTIFICIAL (label_decl) = 1; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 return label_decl; | 297 return label_decl; |
279 } | 298 } |
280 } | 299 } |
281 | 300 |
282 | 301 |
283 /* Convert a gfc_symbol to an identifier of the same name. */ | 302 /* Convert a gfc_symbol to an identifier of the same name. */ |
284 | 303 |
285 static tree | 304 static tree |
286 gfc_sym_identifier (gfc_symbol * sym) | 305 gfc_sym_identifier (gfc_symbol * sym) |
287 { | 306 { |
288 return (get_identifier (sym->name)); | 307 if (sym->attr.is_main_program && strcmp (sym->name, "main") == 0) |
| 308 return (get_identifier ("MAIN__")); |
| 309 else |
| 310 return (get_identifier (sym->name)); |
289 } | 311 } |
290 | 312 |
291 | 313 |
292 /* Construct mangled name from symbol name. */ | 314 /* Construct mangled name from symbol name. */ |
293 | 315 |
294 static tree | 316 static tree |
295 gfc_sym_mangled_identifier (gfc_symbol * sym) | 317 gfc_sym_mangled_identifier (gfc_symbol * sym) |
296 { | 318 { |
297 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1]; | 319 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1]; |
298 | 320 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 return get_identifier (sym->name); | 375 return get_identifier (sym->name); |
354 } | 376 } |
355 else | 377 else |
356 { | 378 { |
357 snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name); | 379 snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name); |
358 return get_identifier (name); | 380 return get_identifier (name); |
359 } | 381 } |
360 } | 382 } |
361 | 383 |
362 | 384 |
| 385 void |
| 386 gfc_set_decl_assembler_name (tree decl, tree name) |
| 387 { |
| 388 tree target_mangled = targetm.mangle_decl_assembler_name (decl, name); |
| 389 SET_DECL_ASSEMBLER_NAME (decl, target_mangled); |
| 390 } |
| 391 |
| 392 |
363 /* Returns true if a variable of specified size should go on the stack. */ | 393 /* Returns true if a variable of specified size should go on the stack. */ |
364 | 394 |
365 int | 395 int |
366 gfc_can_put_var_on_stack (tree size) | 396 gfc_can_put_var_on_stack (tree size) |
367 { | 397 { |
368 unsigned HOST_WIDE_INT low; | 398 unsigned HOST_WIDE_INT low; |
369 | 399 |
370 if (!INTEGER_CST_P (size)) | 400 if (!INTEGER_CST_P (size)) |
371 return 0; | 401 return 0; |
372 | 402 |
(...skipping 20 matching lines...) Expand all Loading... |
393 indirection. */ | 423 indirection. */ |
394 | 424 |
395 static void | 425 static void |
396 gfc_finish_cray_pointee (tree decl, gfc_symbol *sym) | 426 gfc_finish_cray_pointee (tree decl, gfc_symbol *sym) |
397 { | 427 { |
398 tree ptr_decl = gfc_get_symbol_decl (sym->cp_pointer); | 428 tree ptr_decl = gfc_get_symbol_decl (sym->cp_pointer); |
399 tree value; | 429 tree value; |
400 | 430 |
401 /* Parameters need to be dereferenced. */ | 431 /* Parameters need to be dereferenced. */ |
402 if (sym->cp_pointer->attr.dummy) | 432 if (sym->cp_pointer->attr.dummy) |
403 ptr_decl = build_fold_indirect_ref (ptr_decl); | 433 ptr_decl = build_fold_indirect_ref_loc (input_location, |
| 434 » » » » » ptr_decl); |
404 | 435 |
405 /* Check to see if we're dealing with a variable-sized array. */ | 436 /* Check to see if we're dealing with a variable-sized array. */ |
406 if (sym->attr.dimension | 437 if (sym->attr.dimension |
407 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) | 438 && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) |
408 { | 439 { |
409 /* These decls will be dereferenced later, so we don't dereference | 440 /* These decls will be dereferenced later, so we don't dereference |
410 them here. */ | 441 them here. */ |
411 value = convert (TREE_TYPE (decl), ptr_decl); | 442 value = convert (TREE_TYPE (decl), ptr_decl); |
412 } | 443 } |
413 else | 444 else |
414 { | 445 { |
415 ptr_decl = convert (build_pointer_type (TREE_TYPE (decl)), | 446 ptr_decl = convert (build_pointer_type (TREE_TYPE (decl)), |
416 ptr_decl); | 447 ptr_decl); |
417 value = build_fold_indirect_ref (ptr_decl); | 448 value = build_fold_indirect_ref_loc (input_location, |
| 449 » » » » ptr_decl); |
418 } | 450 } |
419 | 451 |
420 SET_DECL_VALUE_EXPR (decl, value); | 452 SET_DECL_VALUE_EXPR (decl, value); |
421 DECL_HAS_VALUE_EXPR_P (decl) = 1; | 453 DECL_HAS_VALUE_EXPR_P (decl) = 1; |
422 GFC_DECL_CRAY_POINTEE (decl) = 1; | 454 GFC_DECL_CRAY_POINTEE (decl) = 1; |
423 /* This is a fake variable just for debugging purposes. */ | 455 /* This is a fake variable just for debugging purposes. */ |
424 TREE_ASM_WRITTEN (decl) = 1; | 456 TREE_ASM_WRITTEN (decl) = 1; |
425 } | 457 } |
426 | 458 |
427 | 459 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 TREE_ADDRESSABLE (decl) = 1; | 511 TREE_ADDRESSABLE (decl) = 1; |
480 /* If it wasn't used we wouldn't be getting it. */ | 512 /* If it wasn't used we wouldn't be getting it. */ |
481 TREE_USED (decl) = 1; | 513 TREE_USED (decl) = 1; |
482 | 514 |
483 /* Chain this decl to the pending declarations. Don't do pushdecl() | 515 /* Chain this decl to the pending declarations. Don't do pushdecl() |
484 because this would add them to the current scope rather than the | 516 because this would add them to the current scope rather than the |
485 function scope. */ | 517 function scope. */ |
486 if (current_function_decl != NULL_TREE) | 518 if (current_function_decl != NULL_TREE) |
487 { | 519 { |
488 if (sym->ns->proc_name->backend_decl == current_function_decl | 520 if (sym->ns->proc_name->backend_decl == current_function_decl |
489 || sym->result == sym) | 521 » || sym->result == sym) |
490 gfc_add_decl_to_function (decl); | 522 gfc_add_decl_to_function (decl); |
| 523 else if (sym->ns->proc_name->attr.flavor == FL_LABEL) |
| 524 /* This is a BLOCK construct. */ |
| 525 add_decl_as_local (decl); |
491 else | 526 else |
492 gfc_add_decl_to_parent_function (decl); | 527 gfc_add_decl_to_parent_function (decl); |
493 } | 528 } |
494 | 529 |
495 if (sym->attr.cray_pointee) | 530 if (sym->attr.cray_pointee) |
496 return; | 531 return; |
497 | 532 |
498 if(sym->attr.is_bind_c == 1) | 533 if(sym->attr.is_bind_c == 1) |
499 { | 534 { |
500 /* We need to put variables that are bind(c) into the common | 535 /* We need to put variables that are bind(c) into the common |
501 segment of the object file, because this is what C would do. | 536 segment of the object file, because this is what C would do. |
502 gfortran would typically put them in either the BSS or | 537 gfortran would typically put them in either the BSS or |
503 initialized data segments, and only mark them as common if | 538 initialized data segments, and only mark them as common if |
504 they were part of common blocks. However, if they are not put | 539 they were part of common blocks. However, if they are not put |
505 » into common space, then C cannot initialize global fortran | 540 » into common space, then C cannot initialize global Fortran |
506 variables that it interoperates with and the draft says that | 541 variables that it interoperates with and the draft says that |
507 either Fortran or C should be able to initialize it (but not | 542 either Fortran or C should be able to initialize it (but not |
508 both, of course.) (J3/04-007, section 15.3). */ | 543 both, of course.) (J3/04-007, section 15.3). */ |
509 TREE_PUBLIC(decl) = 1; | 544 TREE_PUBLIC(decl) = 1; |
510 DECL_COMMON(decl) = 1; | 545 DECL_COMMON(decl) = 1; |
511 } | 546 } |
512 | 547 |
513 /* If a variable is USE associated, it's always external. */ | 548 /* If a variable is USE associated, it's always external. */ |
514 if (sym->attr.use_assoc) | 549 if (sym->attr.use_assoc) |
515 { | 550 { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 || sym->as->type != AS_EXPLICIT | 588 || sym->as->type != AS_EXPLICIT |
554 || sym->attr.pointer | 589 || sym->attr.pointer |
555 || sym->attr.allocatable) | 590 || sym->attr.allocatable) |
556 && !DECL_ARTIFICIAL (decl)) | 591 && !DECL_ARTIFICIAL (decl)) |
557 TREE_STATIC (decl) = 1; | 592 TREE_STATIC (decl) = 1; |
558 | 593 |
559 /* Handle threadprivate variables. */ | 594 /* Handle threadprivate variables. */ |
560 if (sym->attr.threadprivate | 595 if (sym->attr.threadprivate |
561 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | 596 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) |
562 DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); | 597 DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); |
| 598 |
| 599 if (!sym->attr.target |
| 600 && !sym->attr.pointer |
| 601 && !sym->attr.cray_pointee |
| 602 && !sym->attr.proc_pointer) |
| 603 DECL_RESTRICTED_P (decl) = 1; |
563 } | 604 } |
564 | 605 |
565 | 606 |
566 /* Allocate the lang-specific part of a decl. */ | 607 /* Allocate the lang-specific part of a decl. */ |
567 | 608 |
568 void | 609 void |
569 gfc_allocate_lang_decl (tree decl) | 610 gfc_allocate_lang_decl (tree decl) |
570 { | 611 { |
571 DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) | 612 DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) |
572 ggc_alloc_cleared (sizeof (struct lang_decl)); | 613 ggc_alloc_cleared (sizeof (struct lang_decl)); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 tree size, range; | 740 tree size, range; |
700 | 741 |
701 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, | 742 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, |
702 GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node); | 743 GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node); |
703 range = build_range_type (gfc_array_index_type, gfc_index_zero_node, | 744 range = build_range_type (gfc_array_index_type, gfc_index_zero_node, |
704 size); | 745 size); |
705 TYPE_DOMAIN (type) = range; | 746 TYPE_DOMAIN (type) = range; |
706 layout_type (type); | 747 layout_type (type); |
707 } | 748 } |
708 | 749 |
709 if (write_symbols == NO_DEBUG) | |
710 return; | |
711 | |
712 if (TYPE_NAME (type) != NULL_TREE | 750 if (TYPE_NAME (type) != NULL_TREE |
713 && GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1) != NULL_TREE | 751 && GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1) != NULL_TREE |
714 && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1)) == VAR_DECL
) | 752 && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1)) == VAR_DECL
) |
715 { | 753 { |
716 tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type)); | 754 tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type)); |
717 | 755 |
718 for (dim = 0; dim < sym->as->rank - 1; dim++) | 756 for (dim = 0; dim < sym->as->rank - 1; dim++) |
719 { | 757 { |
720 gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE); | 758 gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE); |
721 gtype = TREE_TYPE (gtype); | 759 gtype = TREE_TYPE (gtype); |
(...skipping 17 matching lines...) Expand all Loading... |
739 if (!optimize) | 777 if (!optimize) |
740 { | 778 { |
741 if (GFC_TYPE_ARRAY_LBOUND (type, dim) | 779 if (GFC_TYPE_ARRAY_LBOUND (type, dim) |
742 && TREE_CODE (GFC_TYPE_ARRAY_LBOUND (type, dim)) == VAR_DECL) | 780 && TREE_CODE (GFC_TYPE_ARRAY_LBOUND (type, dim)) == VAR_DECL) |
743 DECL_IGNORED_P (GFC_TYPE_ARRAY_LBOUND (type, dim)) = 0; | 781 DECL_IGNORED_P (GFC_TYPE_ARRAY_LBOUND (type, dim)) = 0; |
744 if (GFC_TYPE_ARRAY_UBOUND (type, dim) | 782 if (GFC_TYPE_ARRAY_UBOUND (type, dim) |
745 && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, dim)) == VAR_DECL) | 783 && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, dim)) == VAR_DECL) |
746 DECL_IGNORED_P (GFC_TYPE_ARRAY_UBOUND (type, dim)) = 0; | 784 DECL_IGNORED_P (GFC_TYPE_ARRAY_UBOUND (type, dim)) = 0; |
747 } | 785 } |
748 } | 786 } |
749 TYPE_NAME (type) = type_decl = build_decl (TYPE_DECL, NULL, gtype); | 787 TYPE_NAME (type) = type_decl = build_decl (input_location, |
| 788 » » » » » » TYPE_DECL, NULL, gtype); |
750 DECL_ORIGINAL_TYPE (type_decl) = gtype; | 789 DECL_ORIGINAL_TYPE (type_decl) = gtype; |
751 } | 790 } |
752 } | 791 } |
753 | 792 |
754 | 793 |
755 /* For some dummy arguments we don't use the actual argument directly. | 794 /* For some dummy arguments we don't use the actual argument directly. |
756 Instead we create a local decl and use that. This allows us to perform | 795 Instead we create a local decl and use that. This allows us to perform |
757 initialization, and construct full type information. */ | 796 initialization, and construct full type information. */ |
758 | 797 |
759 static tree | 798 static tree |
(...skipping 13 matching lines...) Expand all Loading... |
773 /* Add to list of variables if not a fake result variable. */ | 812 /* Add to list of variables if not a fake result variable. */ |
774 if (sym->attr.result || sym->attr.dummy) | 813 if (sym->attr.result || sym->attr.dummy) |
775 gfc_defer_symbol_init (sym); | 814 gfc_defer_symbol_init (sym); |
776 | 815 |
777 type = TREE_TYPE (dummy); | 816 type = TREE_TYPE (dummy); |
778 gcc_assert (TREE_CODE (dummy) == PARM_DECL | 817 gcc_assert (TREE_CODE (dummy) == PARM_DECL |
779 && POINTER_TYPE_P (type)); | 818 && POINTER_TYPE_P (type)); |
780 | 819 |
781 /* Do we know the element size? */ | 820 /* Do we know the element size? */ |
782 known_size = sym->ts.type != BT_CHARACTER | 821 known_size = sym->ts.type != BT_CHARACTER |
783 » || INTEGER_CST_P (sym->ts.cl->backend_decl); | 822 » || INTEGER_CST_P (sym->ts.u.cl->backend_decl); |
784 | 823 |
785 if (known_size && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))) | 824 if (known_size && !GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (type))) |
786 { | 825 { |
787 /* For descriptorless arrays with known element size the actual | 826 /* For descriptorless arrays with known element size the actual |
788 argument is sufficient. */ | 827 argument is sufficient. */ |
789 gcc_assert (GFC_ARRAY_TYPE_P (type)); | 828 gcc_assert (GFC_ARRAY_TYPE_P (type)); |
790 gfc_build_qualified_array (dummy, sym); | 829 gfc_build_qualified_array (dummy, sym); |
791 return dummy; | 830 return dummy; |
792 } | 831 } |
793 | 832 |
(...skipping 23 matching lines...) Expand all Loading... |
817 && as->upper[n]->expr_type == EXPR_CONSTANT | 856 && as->upper[n]->expr_type == EXPR_CONSTANT |
818 && as->lower[n]->expr_type == EXPR_CONSTANT)) | 857 && as->lower[n]->expr_type == EXPR_CONSTANT)) |
819 packed = PACKED_PARTIAL; | 858 packed = PACKED_PARTIAL; |
820 } | 859 } |
821 } | 860 } |
822 else | 861 else |
823 packed = PACKED_PARTIAL; | 862 packed = PACKED_PARTIAL; |
824 } | 863 } |
825 | 864 |
826 type = gfc_typenode_for_spec (&sym->ts); | 865 type = gfc_typenode_for_spec (&sym->ts); |
827 type = gfc_get_nodesc_array_type (type, sym->as, packed); | 866 type = gfc_get_nodesc_array_type (type, sym->as, packed, |
| 867 » » » » » !sym->attr.target); |
828 } | 868 } |
829 else | 869 else |
830 { | 870 { |
831 /* We now have an expression for the element size, so create a fully | 871 /* We now have an expression for the element size, so create a fully |
832 qualified type. Reset sym->backend decl or this will just return the | 872 qualified type. Reset sym->backend decl or this will just return the |
833 old type. */ | 873 old type. */ |
834 DECL_ARTIFICIAL (sym->backend_decl) = 1; | 874 DECL_ARTIFICIAL (sym->backend_decl) = 1; |
835 sym->backend_decl = NULL_TREE; | 875 sym->backend_decl = NULL_TREE; |
836 type = gfc_sym_type (sym); | 876 type = gfc_sym_type (sym); |
837 packed = PACKED_FULL; | 877 packed = PACKED_FULL; |
838 } | 878 } |
839 | 879 |
840 ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0); | 880 ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0); |
841 decl = build_decl (VAR_DECL, get_identifier (name), type); | 881 decl = build_decl (input_location, |
| 882 » » VAR_DECL, get_identifier (name), type); |
842 | 883 |
843 DECL_ARTIFICIAL (decl) = 1; | 884 DECL_ARTIFICIAL (decl) = 1; |
844 TREE_PUBLIC (decl) = 0; | 885 TREE_PUBLIC (decl) = 0; |
845 TREE_STATIC (decl) = 0; | 886 TREE_STATIC (decl) = 0; |
846 DECL_EXTERNAL (decl) = 0; | 887 DECL_EXTERNAL (decl) = 0; |
847 | 888 |
848 /* We should never get deferred shape arrays here. We used to because of | 889 /* We should never get deferred shape arrays here. We used to because of |
849 frontend bugs. */ | 890 frontend bugs. */ |
850 gcc_assert (sym->as->type != AS_DEFERRED); | 891 gcc_assert (sym->as->type != AS_DEFERRED); |
851 | 892 |
(...skipping 13 matching lines...) Expand all Loading... |
865 | 906 |
866 if (sym->ns->proc_name->backend_decl == current_function_decl | 907 if (sym->ns->proc_name->backend_decl == current_function_decl |
867 || sym->attr.contained) | 908 || sym->attr.contained) |
868 gfc_add_decl_to_function (decl); | 909 gfc_add_decl_to_function (decl); |
869 else | 910 else |
870 gfc_add_decl_to_parent_function (decl); | 911 gfc_add_decl_to_parent_function (decl); |
871 | 912 |
872 return decl; | 913 return decl; |
873 } | 914 } |
874 | 915 |
| 916 /* For symbol SYM with GFC_DECL_SAVED_DESCRIPTOR used in contained |
| 917 function add a VAR_DECL to the current function with DECL_VALUE_EXPR |
| 918 pointing to the artificial variable for debug info purposes. */ |
| 919 |
| 920 static void |
| 921 gfc_nonlocal_dummy_array_decl (gfc_symbol *sym) |
| 922 { |
| 923 tree decl, dummy; |
| 924 |
| 925 if (! nonlocal_dummy_decl_pset) |
| 926 nonlocal_dummy_decl_pset = pointer_set_create (); |
| 927 |
| 928 if (pointer_set_insert (nonlocal_dummy_decl_pset, sym->backend_decl)) |
| 929 return; |
| 930 |
| 931 dummy = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl); |
| 932 decl = build_decl (input_location, VAR_DECL, DECL_NAME (dummy), |
| 933 TREE_TYPE (sym->backend_decl)); |
| 934 DECL_ARTIFICIAL (decl) = 0; |
| 935 TREE_USED (decl) = 1; |
| 936 TREE_PUBLIC (decl) = 0; |
| 937 TREE_STATIC (decl) = 0; |
| 938 DECL_EXTERNAL (decl) = 0; |
| 939 if (DECL_BY_REFERENCE (dummy)) |
| 940 DECL_BY_REFERENCE (decl) = 1; |
| 941 DECL_LANG_SPECIFIC (decl) = DECL_LANG_SPECIFIC (sym->backend_decl); |
| 942 SET_DECL_VALUE_EXPR (decl, sym->backend_decl); |
| 943 DECL_HAS_VALUE_EXPR_P (decl) = 1; |
| 944 DECL_CONTEXT (decl) = DECL_CONTEXT (sym->backend_decl); |
| 945 TREE_CHAIN (decl) = nonlocal_dummy_decls; |
| 946 nonlocal_dummy_decls = decl; |
| 947 } |
875 | 948 |
876 /* Return a constant or a variable to use as a string length. Does not | 949 /* Return a constant or a variable to use as a string length. Does not |
877 add the decl to the current scope. */ | 950 add the decl to the current scope. */ |
878 | 951 |
879 static tree | 952 static tree |
880 gfc_create_string_length (gfc_symbol * sym) | 953 gfc_create_string_length (gfc_symbol * sym) |
881 { | 954 { |
882 tree length; | 955 gcc_assert (sym->ts.u.cl); |
| 956 gfc_conv_const_charlen (sym->ts.u.cl); |
883 | 957 |
884 gcc_assert (sym->ts.cl); | 958 if (sym->ts.u.cl->backend_decl == NULL_TREE) |
885 gfc_conv_const_charlen (sym->ts.cl); | |
886 | |
887 if (sym->ts.cl->backend_decl == NULL_TREE) | |
888 { | 959 { |
| 960 tree length; |
889 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2]; | 961 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2]; |
890 | 962 |
891 /* Also prefix the mangled name. */ | 963 /* Also prefix the mangled name. */ |
892 strcpy (&name[1], sym->name); | 964 strcpy (&name[1], sym->name); |
893 name[0] = '.'; | 965 name[0] = '.'; |
894 length = build_decl (VAR_DECL, get_identifier (name), | 966 length = build_decl (input_location, |
| 967 » » » VAR_DECL, get_identifier (name), |
895 gfc_charlen_type_node); | 968 gfc_charlen_type_node); |
896 DECL_ARTIFICIAL (length) = 1; | 969 DECL_ARTIFICIAL (length) = 1; |
897 TREE_USED (length) = 1; | 970 TREE_USED (length) = 1; |
898 if (sym->ns->proc_name->tlink != NULL) | 971 if (sym->ns->proc_name->tlink != NULL) |
899 gfc_defer_symbol_init (sym); | 972 gfc_defer_symbol_init (sym); |
900 sym->ts.cl->backend_decl = length; | 973 |
| 974 sym->ts.u.cl->backend_decl = length; |
901 } | 975 } |
902 | 976 |
903 return sym->ts.cl->backend_decl; | 977 gcc_assert (sym->ts.u.cl->backend_decl != NULL_TREE); |
| 978 return sym->ts.u.cl->backend_decl; |
904 } | 979 } |
905 | 980 |
906 /* If a variable is assigned a label, we add another two auxiliary | 981 /* If a variable is assigned a label, we add another two auxiliary |
907 variables. */ | 982 variables. */ |
908 | 983 |
909 static void | 984 static void |
910 gfc_add_assign_aux_vars (gfc_symbol * sym) | 985 gfc_add_assign_aux_vars (gfc_symbol * sym) |
911 { | 986 { |
912 tree addr; | 987 tree addr; |
913 tree length; | 988 tree length; |
914 tree decl; | 989 tree decl; |
915 | 990 |
916 gcc_assert (sym->backend_decl); | 991 gcc_assert (sym->backend_decl); |
917 | 992 |
918 decl = sym->backend_decl; | 993 decl = sym->backend_decl; |
919 gfc_allocate_lang_decl (decl); | 994 gfc_allocate_lang_decl (decl); |
920 GFC_DECL_ASSIGN (decl) = 1; | 995 GFC_DECL_ASSIGN (decl) = 1; |
921 length = build_decl (VAR_DECL, create_tmp_var_name (sym->name), | 996 length = build_decl (input_location, |
| 997 » » VAR_DECL, create_tmp_var_name (sym->name), |
922 gfc_charlen_type_node); | 998 gfc_charlen_type_node); |
923 addr = build_decl (VAR_DECL, create_tmp_var_name (sym->name), | 999 addr = build_decl (input_location, |
| 1000 » » VAR_DECL, create_tmp_var_name (sym->name), |
924 pvoid_type_node); | 1001 pvoid_type_node); |
925 gfc_finish_var_decl (length, sym); | 1002 gfc_finish_var_decl (length, sym); |
926 gfc_finish_var_decl (addr, sym); | 1003 gfc_finish_var_decl (addr, sym); |
927 /* STRING_LENGTH is also used as flag. Less than -1 means that | 1004 /* STRING_LENGTH is also used as flag. Less than -1 means that |
928 ASSIGN_ADDR can not be used. Equal -1 means that ASSIGN_ADDR is the | 1005 ASSIGN_ADDR can not be used. Equal -1 means that ASSIGN_ADDR is the |
929 target label's address. Otherwise, value is the length of a format string | 1006 target label's address. Otherwise, value is the length of a format string |
930 and ASSIGN_ADDR is its address. */ | 1007 and ASSIGN_ADDR is its address. */ |
931 if (TREE_STATIC (length)) | 1008 if (TREE_STATIC (length)) |
932 DECL_INITIAL (length) = build_int_cst (NULL_TREE, -2); | 1009 DECL_INITIAL (length) = build_int_cst (NULL_TREE, -2); |
933 else | 1010 else |
934 gfc_defer_symbol_init (sym); | 1011 gfc_defer_symbol_init (sym); |
935 | 1012 |
936 GFC_DECL_STRING_LEN (decl) = length; | 1013 GFC_DECL_STRING_LEN (decl) = length; |
937 GFC_DECL_ASSIGN_ADDR (decl) = addr; | 1014 GFC_DECL_ASSIGN_ADDR (decl) = addr; |
938 } | 1015 } |
939 | 1016 |
| 1017 |
| 1018 static tree |
| 1019 add_attributes_to_decl (symbol_attribute sym_attr, tree list) |
| 1020 { |
| 1021 unsigned id; |
| 1022 tree attr; |
| 1023 |
| 1024 for (id = 0; id < EXT_ATTR_NUM; id++) |
| 1025 if (sym_attr.ext_attr & (1 << id)) |
| 1026 { |
| 1027 attr = build_tree_list ( |
| 1028 get_identifier (ext_attr_list[id].middle_end_name), |
| 1029 NULL_TREE); |
| 1030 list = chainon (list, attr); |
| 1031 } |
| 1032 |
| 1033 return list; |
| 1034 } |
| 1035 |
| 1036 |
940 /* Return the decl for a gfc_symbol, create it if it doesn't already | 1037 /* Return the decl for a gfc_symbol, create it if it doesn't already |
941 exist. */ | 1038 exist. */ |
942 | 1039 |
943 tree | 1040 tree |
944 gfc_get_symbol_decl (gfc_symbol * sym) | 1041 gfc_get_symbol_decl (gfc_symbol * sym) |
945 { | 1042 { |
946 tree decl; | 1043 tree decl; |
947 tree length = NULL_TREE; | 1044 tree length = NULL_TREE; |
| 1045 tree attributes; |
948 int byref; | 1046 int byref; |
949 | 1047 |
950 gcc_assert (sym->attr.referenced | 1048 gcc_assert (sym->attr.referenced |
951 || sym->attr.use_assoc | 1049 || sym->attr.use_assoc |
952 || sym->ns->proc_name->attr.if_source == IFSRC_IFBODY); | 1050 || sym->ns->proc_name->attr.if_source == IFSRC_IFBODY); |
953 | 1051 |
954 if (sym->ns && sym->ns->proc_name->attr.function) | 1052 if (sym->ns && sym->ns->proc_name && sym->ns->proc_name->attr.function) |
955 byref = gfc_return_by_reference (sym->ns->proc_name); | 1053 byref = gfc_return_by_reference (sym->ns->proc_name); |
956 else | 1054 else |
957 byref = 0; | 1055 byref = 0; |
958 | 1056 |
959 if ((sym->attr.dummy && ! sym->attr.function) || (sym->attr.result && byref)) | 1057 if ((sym->attr.dummy && ! sym->attr.function) || (sym->attr.result && byref)) |
960 { | 1058 { |
961 /* Return via extra parameter. */ | 1059 /* Return via extra parameter. */ |
962 if (sym->attr.result && byref | 1060 if (sym->attr.result && byref |
963 && !sym->backend_decl) | 1061 && !sym->backend_decl) |
964 { | 1062 { |
965 sym->backend_decl = | 1063 sym->backend_decl = |
966 DECL_ARGUMENTS (sym->ns->proc_name->backend_decl); | 1064 DECL_ARGUMENTS (sym->ns->proc_name->backend_decl); |
967 /* For entry master function skip over the __entry | 1065 /* For entry master function skip over the __entry |
968 argument. */ | 1066 argument. */ |
969 if (sym->ns->proc_name->attr.entry_master) | 1067 if (sym->ns->proc_name->attr.entry_master) |
970 sym->backend_decl = TREE_CHAIN (sym->backend_decl); | 1068 sym->backend_decl = TREE_CHAIN (sym->backend_decl); |
971 } | 1069 } |
972 | 1070 |
973 /* Dummy variables should already have been created. */ | 1071 /* Dummy variables should already have been created. */ |
974 gcc_assert (sym->backend_decl); | 1072 gcc_assert (sym->backend_decl); |
975 | 1073 |
976 /* Create a character length variable. */ | 1074 /* Create a character length variable. */ |
977 if (sym->ts.type == BT_CHARACTER) | 1075 if (sym->ts.type == BT_CHARACTER) |
978 { | 1076 { |
979 » if (sym->ts.cl->backend_decl == NULL_TREE) | 1077 » if (sym->ts.u.cl->backend_decl == NULL_TREE) |
980 length = gfc_create_string_length (sym); | 1078 length = gfc_create_string_length (sym); |
981 else | 1079 else |
982 » length = sym->ts.cl->backend_decl; | 1080 » length = sym->ts.u.cl->backend_decl; |
983 if (TREE_CODE (length) == VAR_DECL | 1081 if (TREE_CODE (length) == VAR_DECL |
984 && DECL_CONTEXT (length) == NULL_TREE) | 1082 && DECL_CONTEXT (length) == NULL_TREE) |
985 { | 1083 { |
986 /* Add the string length to the same context as the symbol. */ | 1084 /* Add the string length to the same context as the symbol. */ |
987 if (DECL_CONTEXT (sym->backend_decl) == current_function_decl) | 1085 if (DECL_CONTEXT (sym->backend_decl) == current_function_decl) |
988 gfc_add_decl_to_function (length); | 1086 gfc_add_decl_to_function (length); |
989 else | 1087 else |
990 gfc_add_decl_to_parent_function (length); | 1088 gfc_add_decl_to_parent_function (length); |
991 | 1089 |
992 gcc_assert (DECL_CONTEXT (sym->backend_decl) == | 1090 gcc_assert (DECL_CONTEXT (sym->backend_decl) == |
(...skipping 11 matching lines...) Expand all Loading... |
1004 if (sym->backend_decl != NULL && decl != sym->backend_decl) | 1102 if (sym->backend_decl != NULL && decl != sym->backend_decl) |
1005 DECL_ARTIFICIAL (sym->backend_decl) = 1; | 1103 DECL_ARTIFICIAL (sym->backend_decl) = 1; |
1006 sym->backend_decl = decl; | 1104 sym->backend_decl = decl; |
1007 } | 1105 } |
1008 | 1106 |
1009 TREE_USED (sym->backend_decl) = 1; | 1107 TREE_USED (sym->backend_decl) = 1; |
1010 if (sym->attr.assign && GFC_DECL_ASSIGN (sym->backend_decl) == 0) | 1108 if (sym->attr.assign && GFC_DECL_ASSIGN (sym->backend_decl) == 0) |
1011 { | 1109 { |
1012 gfc_add_assign_aux_vars (sym); | 1110 gfc_add_assign_aux_vars (sym); |
1013 } | 1111 } |
| 1112 |
| 1113 if (sym->attr.dimension |
| 1114 && DECL_LANG_SPECIFIC (sym->backend_decl) |
| 1115 && GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl) |
| 1116 && DECL_CONTEXT (sym->backend_decl) != current_function_decl) |
| 1117 gfc_nonlocal_dummy_array_decl (sym); |
| 1118 |
1014 return sym->backend_decl; | 1119 return sym->backend_decl; |
1015 } | 1120 } |
1016 | 1121 |
1017 if (sym->backend_decl) | 1122 if (sym->backend_decl) |
1018 return sym->backend_decl; | 1123 return sym->backend_decl; |
1019 | 1124 |
| 1125 /* If use associated and whole file compilation, use the module |
| 1126 declaration. This is only needed for intrinsic types because |
| 1127 they are substituted for one another during optimization. */ |
| 1128 if (gfc_option.flag_whole_file |
| 1129 && sym->attr.flavor == FL_VARIABLE |
| 1130 && sym->ts.type != BT_DERIVED |
| 1131 && sym->attr.use_assoc |
| 1132 && sym->module) |
| 1133 { |
| 1134 gfc_gsymbol *gsym; |
| 1135 |
| 1136 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module); |
| 1137 if (gsym && gsym->ns && gsym->type == GSYM_MODULE) |
| 1138 { |
| 1139 gfc_symbol *s; |
| 1140 s = NULL; |
| 1141 gfc_find_symbol (sym->name, gsym->ns, 0, &s); |
| 1142 if (s && s->backend_decl) |
| 1143 { |
| 1144 if (sym->ts.type == BT_CHARACTER) |
| 1145 sym->ts.u.cl->backend_decl = s->ts.u.cl->backend_decl; |
| 1146 return s->backend_decl; |
| 1147 } |
| 1148 } |
| 1149 } |
| 1150 |
1020 /* Catch function declarations. Only used for actual parameters and | 1151 /* Catch function declarations. Only used for actual parameters and |
1021 procedure pointers. */ | 1152 procedure pointers. */ |
1022 if (sym->attr.flavor == FL_PROCEDURE) | 1153 if (sym->attr.flavor == FL_PROCEDURE) |
1023 { | 1154 { |
1024 decl = gfc_get_extern_function_decl (sym); | 1155 decl = gfc_get_extern_function_decl (sym); |
1025 gfc_set_decl_location (decl, &sym->declared_at); | 1156 gfc_set_decl_location (decl, &sym->declared_at); |
1026 return decl; | 1157 return decl; |
1027 } | 1158 } |
1028 | 1159 |
1029 if (sym->attr.intrinsic) | 1160 if (sym->attr.intrinsic) |
1030 internal_error ("intrinsic variable which isn't a procedure"); | 1161 internal_error ("intrinsic variable which isn't a procedure"); |
1031 | 1162 |
1032 /* Create string length decl first so that they can be used in the | 1163 /* Create string length decl first so that they can be used in the |
1033 type declaration. */ | 1164 type declaration. */ |
1034 if (sym->ts.type == BT_CHARACTER) | 1165 if (sym->ts.type == BT_CHARACTER) |
1035 length = gfc_create_string_length (sym); | 1166 length = gfc_create_string_length (sym); |
1036 | 1167 |
1037 /* Create the decl for the variable. */ | 1168 /* Create the decl for the variable. */ |
1038 decl = build_decl (VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym)); | 1169 decl = build_decl (sym->declared_at.lb->location, |
| 1170 » » VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym)); |
1039 | 1171 |
1040 gfc_set_decl_location (decl, &sym->declared_at); | 1172 /* Add attributes to variables. Functions are handled elsewhere. */ |
| 1173 attributes = add_attributes_to_decl (sym->attr, NULL_TREE); |
| 1174 decl_attributes (&decl, attributes, 0); |
1041 | 1175 |
1042 /* Symbols from modules should have their assembler names mangled. | 1176 /* Symbols from modules should have their assembler names mangled. |
1043 This is done here rather than in gfc_finish_var_decl because it | 1177 This is done here rather than in gfc_finish_var_decl because it |
1044 is different for string length variables. */ | 1178 is different for string length variables. */ |
1045 if (sym->module) | 1179 if (sym->module) |
1046 { | 1180 { |
1047 SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_identifier (sym)); | 1181 gfc_set_decl_assembler_name (decl, gfc_sym_mangled_identifier (sym)); |
1048 if (sym->attr.use_assoc) | 1182 if (sym->attr.use_assoc) |
1049 DECL_IGNORED_P (decl) = 1; | 1183 DECL_IGNORED_P (decl) = 1; |
1050 } | 1184 } |
1051 | 1185 |
1052 if (sym->attr.dimension) | 1186 if (sym->attr.dimension) |
1053 { | 1187 { |
1054 /* Create variables to hold the non-constant bits of array info. */ | 1188 /* Create variables to hold the non-constant bits of array info. */ |
1055 gfc_build_qualified_array (decl, sym); | 1189 gfc_build_qualified_array (decl, sym); |
1056 | 1190 |
1057 /* Remember this variable for allocation/cleanup. */ | |
1058 gfc_defer_symbol_init (sym); | |
1059 | |
1060 if ((sym->attr.allocatable || !sym->attr.dummy) && !sym->attr.pointer) | 1191 if ((sym->attr.allocatable || !sym->attr.dummy) && !sym->attr.pointer) |
1061 GFC_DECL_PACKED_ARRAY (decl) = 1; | 1192 GFC_DECL_PACKED_ARRAY (decl) = 1; |
1062 } | 1193 } |
1063 | 1194 |
1064 if (sym->ts.type == BT_DERIVED && sym->ts.derived->attr.alloc_comp) | 1195 /* Remember this variable for allocation/cleanup. */ |
1065 gfc_defer_symbol_init (sym); | 1196 if (sym->attr.dimension || sym->attr.allocatable |
1066 /* This applies a derived type default initializer. */ | 1197 || (sym->ts.type == BT_CLASS && |
1067 else if (sym->ts.type == BT_DERIVED | 1198 » (sym->ts.u.derived->components->attr.dimension |
1068 » && sym->attr.save == SAVE_NONE | 1199 » || sym->ts.u.derived->components->attr.allocatable)) |
1069 » && !sym->attr.data | 1200 || (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.alloc_comp) |
1070 » && !sym->attr.allocatable | 1201 /* This applies a derived type default initializer. */ |
1071 » && (sym->value && !sym->ns->proc_name->attr.is_main_program) | 1202 || (sym->ts.type == BT_DERIVED |
1072 » && !sym->attr.use_assoc) | 1203 » && sym->attr.save == SAVE_NONE |
| 1204 » && !sym->attr.data |
| 1205 » && !sym->attr.allocatable |
| 1206 » && (sym->value && !sym->ns->proc_name->attr.is_main_program) |
| 1207 » && !sym->attr.use_assoc)) |
1073 gfc_defer_symbol_init (sym); | 1208 gfc_defer_symbol_init (sym); |
1074 | 1209 |
1075 gfc_finish_var_decl (decl, sym); | 1210 gfc_finish_var_decl (decl, sym); |
1076 | 1211 |
1077 if (sym->ts.type == BT_CHARACTER) | 1212 if (sym->ts.type == BT_CHARACTER) |
1078 { | 1213 { |
1079 /* Character variables need special handling. */ | 1214 /* Character variables need special handling. */ |
1080 gfc_allocate_lang_decl (decl); | 1215 gfc_allocate_lang_decl (decl); |
1081 | 1216 |
1082 if (TREE_CODE (length) != INTEGER_CST) | 1217 if (TREE_CODE (length) != INTEGER_CST) |
1083 { | 1218 { |
1084 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2]; | 1219 char name[GFC_MAX_MANGLED_SYMBOL_LEN + 2]; |
1085 | 1220 |
1086 if (sym->module) | 1221 if (sym->module) |
1087 { | 1222 { |
1088 /* Also prefix the mangled name for symbols from modules. */ | 1223 /* Also prefix the mangled name for symbols from modules. */ |
1089 strcpy (&name[1], sym->name); | 1224 strcpy (&name[1], sym->name); |
1090 name[0] = '.'; | 1225 name[0] = '.'; |
1091 strcpy (&name[1], | 1226 strcpy (&name[1], |
1092 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (length))); | 1227 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (length))); |
1093 » SET_DECL_ASSEMBLER_NAME (decl, get_identifier (name)); | 1228 » gfc_set_decl_assembler_name (decl, get_identifier (name)); |
1094 } | 1229 } |
1095 gfc_finish_var_decl (length, sym); | 1230 gfc_finish_var_decl (length, sym); |
1096 gcc_assert (!sym->value); | 1231 gcc_assert (!sym->value); |
1097 } | 1232 } |
1098 } | 1233 } |
1099 else if (sym->attr.subref_array_pointer) | 1234 else if (sym->attr.subref_array_pointer) |
1100 { | 1235 { |
1101 /* We need the span for these beasts. */ | 1236 /* We need the span for these beasts. */ |
1102 gfc_allocate_lang_decl (decl); | 1237 gfc_allocate_lang_decl (decl); |
1103 } | 1238 } |
1104 | 1239 |
1105 if (sym->attr.subref_array_pointer) | 1240 if (sym->attr.subref_array_pointer) |
1106 { | 1241 { |
1107 tree span; | 1242 tree span; |
1108 GFC_DECL_SUBREF_ARRAY_P (decl) = 1; | 1243 GFC_DECL_SUBREF_ARRAY_P (decl) = 1; |
1109 span = build_decl (VAR_DECL, create_tmp_var_name ("span"), | 1244 span = build_decl (input_location, |
| 1245 » » » VAR_DECL, create_tmp_var_name ("span"), |
1110 gfc_array_index_type); | 1246 gfc_array_index_type); |
1111 gfc_finish_var_decl (span, sym); | 1247 gfc_finish_var_decl (span, sym); |
1112 TREE_STATIC (span) = TREE_STATIC (decl); | 1248 TREE_STATIC (span) = TREE_STATIC (decl); |
1113 DECL_ARTIFICIAL (span) = 1; | 1249 DECL_ARTIFICIAL (span) = 1; |
1114 DECL_INITIAL (span) = build_int_cst (gfc_array_index_type, 0); | 1250 DECL_INITIAL (span) = build_int_cst (gfc_array_index_type, 0); |
1115 | 1251 |
1116 GFC_DECL_SPAN (decl) = span; | 1252 GFC_DECL_SPAN (decl) = span; |
1117 GFC_TYPE_ARRAY_SPAN (TREE_TYPE (decl)) = span; | 1253 GFC_TYPE_ARRAY_SPAN (TREE_TYPE (decl)) = span; |
1118 } | 1254 } |
1119 | 1255 |
1120 sym->backend_decl = decl; | 1256 sym->backend_decl = decl; |
1121 | 1257 |
1122 if (sym->attr.assign) | 1258 if (sym->attr.assign) |
1123 gfc_add_assign_aux_vars (sym); | 1259 gfc_add_assign_aux_vars (sym); |
1124 | 1260 |
1125 if (TREE_STATIC (decl) && !sym->attr.use_assoc) | 1261 if (TREE_STATIC (decl) && !sym->attr.use_assoc) |
1126 { | 1262 { |
1127 /* Add static initializer. */ | 1263 /* Add static initializer. */ |
1128 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts, | 1264 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts, |
1129 TREE_TYPE (decl), sym->attr.dimension, | 1265 TREE_TYPE (decl), sym->attr.dimension, |
1130 sym->attr.pointer || sym->attr.allocatable); | 1266 sym->attr.pointer || sym->attr.allocatable); |
1131 } | 1267 } |
1132 | 1268 |
| 1269 if (!TREE_STATIC (decl) |
| 1270 && POINTER_TYPE_P (TREE_TYPE (decl)) |
| 1271 && !sym->attr.pointer |
| 1272 && !sym->attr.allocatable |
| 1273 && !sym->attr.proc_pointer) |
| 1274 DECL_BY_REFERENCE (decl) = 1; |
| 1275 |
1133 return decl; | 1276 return decl; |
1134 } | 1277 } |
1135 | 1278 |
1136 | 1279 |
1137 /* Substitute a temporary variable in place of the real one. */ | 1280 /* Substitute a temporary variable in place of the real one. */ |
1138 | 1281 |
1139 void | 1282 void |
1140 gfc_shadow_sym (gfc_symbol * sym, tree decl, gfc_saved_var * save) | 1283 gfc_shadow_sym (gfc_symbol * sym, tree decl, gfc_saved_var * save) |
1141 { | 1284 { |
1142 save->attr = sym->attr; | 1285 save->attr = sym->attr; |
(...skipping 16 matching lines...) Expand all Loading... |
1159 sym->backend_decl = save->decl; | 1302 sym->backend_decl = save->decl; |
1160 } | 1303 } |
1161 | 1304 |
1162 | 1305 |
1163 /* Declare a procedure pointer. */ | 1306 /* Declare a procedure pointer. */ |
1164 | 1307 |
1165 static tree | 1308 static tree |
1166 get_proc_pointer_decl (gfc_symbol *sym) | 1309 get_proc_pointer_decl (gfc_symbol *sym) |
1167 { | 1310 { |
1168 tree decl; | 1311 tree decl; |
| 1312 tree attributes; |
1169 | 1313 |
1170 decl = sym->backend_decl; | 1314 decl = sym->backend_decl; |
1171 if (decl) | 1315 if (decl) |
1172 return decl; | 1316 return decl; |
1173 | 1317 |
1174 decl = build_decl (VAR_DECL, get_identifier (sym->name), | 1318 decl = build_decl (input_location, |
| 1319 » » VAR_DECL, get_identifier (sym->name), |
1175 build_pointer_type (gfc_get_function_type (sym))); | 1320 build_pointer_type (gfc_get_function_type (sym))); |
1176 | 1321 |
1177 if ((sym->ns->proc_name | 1322 if ((sym->ns->proc_name |
1178 && sym->ns->proc_name->backend_decl == current_function_decl) | 1323 && sym->ns->proc_name->backend_decl == current_function_decl) |
1179 || sym->attr.contained) | 1324 || sym->attr.contained) |
1180 gfc_add_decl_to_function (decl); | 1325 gfc_add_decl_to_function (decl); |
1181 else if (sym->ns->proc_name->attr.flavor != FL_MODULE) | 1326 else if (sym->ns->proc_name->attr.flavor != FL_MODULE) |
1182 gfc_add_decl_to_parent_function (decl); | 1327 gfc_add_decl_to_parent_function (decl); |
1183 | 1328 |
1184 sym->backend_decl = decl; | 1329 sym->backend_decl = decl; |
(...skipping 13 matching lines...) Expand all Loading... |
1198 | 1343 |
1199 if (!sym->attr.use_assoc | 1344 if (!sym->attr.use_assoc |
1200 && (sym->attr.save != SAVE_NONE || sym->attr.data | 1345 && (sym->attr.save != SAVE_NONE || sym->attr.data |
1201 || (sym->value && sym->ns->proc_name->attr.is_main_program))) | 1346 || (sym->value && sym->ns->proc_name->attr.is_main_program))) |
1202 TREE_STATIC (decl) = 1; | 1347 TREE_STATIC (decl) = 1; |
1203 | 1348 |
1204 if (TREE_STATIC (decl) && sym->value) | 1349 if (TREE_STATIC (decl) && sym->value) |
1205 { | 1350 { |
1206 /* Add static initializer. */ | 1351 /* Add static initializer. */ |
1207 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts, | 1352 DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts, |
1208 » TREE_TYPE (decl), sym->attr.dimension, sym->attr.proc_pointer); | 1353 » TREE_TYPE (decl), |
| 1354 » sym->attr.proc_pointer ? false : sym->attr.dimension, |
| 1355 » sym->attr.proc_pointer); |
1209 } | 1356 } |
1210 | 1357 |
| 1358 attributes = add_attributes_to_decl (sym->attr, NULL_TREE); |
| 1359 decl_attributes (&decl, attributes, 0); |
| 1360 |
1211 return decl; | 1361 return decl; |
1212 } | 1362 } |
1213 | 1363 |
1214 | 1364 |
1215 /* Get a basic decl for an external function. */ | 1365 /* Get a basic decl for an external function. */ |
1216 | 1366 |
1217 tree | 1367 tree |
1218 gfc_get_extern_function_decl (gfc_symbol * sym) | 1368 gfc_get_extern_function_decl (gfc_symbol * sym) |
1219 { | 1369 { |
1220 tree type; | 1370 tree type; |
1221 tree fndecl; | 1371 tree fndecl; |
| 1372 tree attributes; |
1222 gfc_expr e; | 1373 gfc_expr e; |
1223 gfc_intrinsic_sym *isym; | 1374 gfc_intrinsic_sym *isym; |
1224 gfc_expr argexpr; | 1375 gfc_expr argexpr; |
1225 char s[GFC_MAX_SYMBOL_LEN + 23]; /* "_gfortran_f2c_specific" and '\0'. */ | 1376 char s[GFC_MAX_SYMBOL_LEN + 23]; /* "_gfortran_f2c_specific" and '\0'. */ |
1226 tree name; | 1377 tree name; |
1227 tree mangled_name; | 1378 tree mangled_name; |
| 1379 gfc_gsymbol *gsym; |
1228 | 1380 |
1229 if (sym->backend_decl) | 1381 if (sym->backend_decl) |
1230 return sym->backend_decl; | 1382 return sym->backend_decl; |
1231 | 1383 |
1232 /* We should never be creating external decls for alternate entry points. | 1384 /* We should never be creating external decls for alternate entry points. |
1233 The procedure may be an alternate entry point, but we don't want/need | 1385 The procedure may be an alternate entry point, but we don't want/need |
1234 to know that. */ | 1386 to know that. */ |
1235 gcc_assert (!(sym->attr.entry || sym->attr.entry_master)); | 1387 gcc_assert (!(sym->attr.entry || sym->attr.entry_master)); |
1236 | 1388 |
1237 if (sym->attr.proc_pointer) | 1389 if (sym->attr.proc_pointer) |
1238 return get_proc_pointer_decl (sym); | 1390 return get_proc_pointer_decl (sym); |
1239 | 1391 |
| 1392 /* See if this is an external procedure from the same file. If so, |
| 1393 return the backend_decl. */ |
| 1394 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name); |
| 1395 |
| 1396 if (gfc_option.flag_whole_file |
| 1397 && !sym->attr.use_assoc |
| 1398 && !sym->backend_decl |
| 1399 && gsym && gsym->ns |
| 1400 && ((gsym->type == GSYM_SUBROUTINE) || (gsym->type == GSYM_FUNCTION)) |
| 1401 && gsym->ns->proc_name->backend_decl) |
| 1402 { |
| 1403 /* If the namespace has entries, the proc_name is the |
| 1404 entry master. Find the entry and use its backend_decl. |
| 1405 otherwise, use the proc_name backend_decl. */ |
| 1406 if (gsym->ns->entries) |
| 1407 { |
| 1408 gfc_entry_list *entry = gsym->ns->entries; |
| 1409 |
| 1410 for (; entry; entry = entry->next) |
| 1411 { |
| 1412 if (strcmp (gsym->name, entry->sym->name) == 0) |
| 1413 { |
| 1414 sym->backend_decl = entry->sym->backend_decl; |
| 1415 break; |
| 1416 } |
| 1417 } |
| 1418 } |
| 1419 else |
| 1420 { |
| 1421 sym->backend_decl = gsym->ns->proc_name->backend_decl; |
| 1422 } |
| 1423 |
| 1424 if (sym->backend_decl) |
| 1425 return sym->backend_decl; |
| 1426 } |
| 1427 |
| 1428 /* See if this is a module procedure from the same file. If so, |
| 1429 return the backend_decl. */ |
| 1430 if (sym->module) |
| 1431 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->module); |
| 1432 |
| 1433 if (gfc_option.flag_whole_file |
| 1434 && gsym && gsym->ns |
| 1435 && gsym->type == GSYM_MODULE) |
| 1436 { |
| 1437 gfc_symbol *s; |
| 1438 |
| 1439 s = NULL; |
| 1440 gfc_find_symbol (sym->name, gsym->ns, 0, &s); |
| 1441 if (s && s->backend_decl) |
| 1442 { |
| 1443 sym->backend_decl = s->backend_decl; |
| 1444 return sym->backend_decl; |
| 1445 } |
| 1446 } |
| 1447 |
1240 if (sym->attr.intrinsic) | 1448 if (sym->attr.intrinsic) |
1241 { | 1449 { |
1242 /* Call the resolution function to get the actual name. This is | 1450 /* Call the resolution function to get the actual name. This is |
1243 a nasty hack which relies on the resolution functions only looking | 1451 a nasty hack which relies on the resolution functions only looking |
1244 at the first argument. We pass NULL for the second argument | 1452 at the first argument. We pass NULL for the second argument |
1245 otherwise things like AINT get confused. */ | 1453 otherwise things like AINT get confused. */ |
1246 isym = gfc_find_function (sym->name); | 1454 isym = gfc_find_function (sym->name); |
1247 gcc_assert (isym->resolve.f0 != NULL); | 1455 gcc_assert (isym->resolve.f0 != NULL); |
1248 | 1456 |
1249 memset (&e, 0, sizeof (e)); | 1457 memset (&e, 0, sizeof (e)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 name = get_identifier (s); | 1494 name = get_identifier (s); |
1287 mangled_name = name; | 1495 mangled_name = name; |
1288 } | 1496 } |
1289 else | 1497 else |
1290 { | 1498 { |
1291 name = gfc_sym_identifier (sym); | 1499 name = gfc_sym_identifier (sym); |
1292 mangled_name = gfc_sym_mangled_function_id (sym); | 1500 mangled_name = gfc_sym_mangled_function_id (sym); |
1293 } | 1501 } |
1294 | 1502 |
1295 type = gfc_get_function_type (sym); | 1503 type = gfc_get_function_type (sym); |
1296 fndecl = build_decl (FUNCTION_DECL, name, type); | 1504 fndecl = build_decl (input_location, |
| 1505 » » FUNCTION_DECL, name, type); |
1297 | 1506 |
1298 SET_DECL_ASSEMBLER_NAME (fndecl, mangled_name); | 1507 attributes = add_attributes_to_decl (sym->attr, NULL_TREE); |
1299 /* If the return type is a pointer, avoid alias issues by setting | 1508 decl_attributes (&fndecl, attributes, 0); |
1300 DECL_IS_MALLOC to nonzero. This means that the function should be | 1509 |
1301 treated as if it were a malloc, meaning it returns a pointer that | 1510 gfc_set_decl_assembler_name (fndecl, mangled_name); |
1302 is not an alias. */ | |
1303 if (POINTER_TYPE_P (type)) | |
1304 DECL_IS_MALLOC (fndecl) = 1; | |
1305 | 1511 |
1306 /* Set the context of this decl. */ | 1512 /* Set the context of this decl. */ |
1307 if (0 && sym->ns && sym->ns->proc_name) | 1513 if (0 && sym->ns && sym->ns->proc_name) |
1308 { | 1514 { |
1309 /* TODO: Add external decls to the appropriate scope. */ | 1515 /* TODO: Add external decls to the appropriate scope. */ |
1310 DECL_CONTEXT (fndecl) = sym->ns->proc_name->backend_decl; | 1516 DECL_CONTEXT (fndecl) = sym->ns->proc_name->backend_decl; |
1311 } | 1517 } |
1312 else | 1518 else |
1313 { | 1519 { |
1314 /* Global declaration, e.g. intrinsic subroutine. */ | 1520 /* Global declaration, e.g. intrinsic subroutine. */ |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 } | 1554 } |
1349 | 1555 |
1350 | 1556 |
1351 /* Create a declaration for a procedure. For external functions (in the C | 1557 /* Create a declaration for a procedure. For external functions (in the C |
1352 sense) use gfc_get_extern_function_decl. HAS_ENTRIES is true if this is | 1558 sense) use gfc_get_extern_function_decl. HAS_ENTRIES is true if this is |
1353 a master function with alternate entry points. */ | 1559 a master function with alternate entry points. */ |
1354 | 1560 |
1355 static void | 1561 static void |
1356 build_function_decl (gfc_symbol * sym) | 1562 build_function_decl (gfc_symbol * sym) |
1357 { | 1563 { |
1358 tree fndecl, type; | 1564 tree fndecl, type, attributes; |
1359 symbol_attribute attr; | 1565 symbol_attribute attr; |
1360 tree result_decl; | 1566 tree result_decl; |
1361 gfc_formal_arglist *f; | 1567 gfc_formal_arglist *f; |
1362 | 1568 |
1363 gcc_assert (!sym->backend_decl); | 1569 gcc_assert (!sym->backend_decl); |
1364 gcc_assert (!sym->attr.external); | 1570 gcc_assert (!sym->attr.external); |
1365 | 1571 |
1366 /* Set the line and filename. sym->declared_at seems to point to the | 1572 /* Set the line and filename. sym->declared_at seems to point to the |
1367 last statement for subroutines, but it'll do for now. */ | 1573 last statement for subroutines, but it'll do for now. */ |
1368 gfc_set_backend_locus (&sym->declared_at); | 1574 gfc_set_backend_locus (&sym->declared_at); |
1369 | 1575 |
1370 /* Allow only one nesting level. Allow public declarations. */ | 1576 /* Allow only one nesting level. Allow public declarations. */ |
1371 gcc_assert (current_function_decl == NULL_TREE | 1577 gcc_assert (current_function_decl == NULL_TREE |
1372 || DECL_CONTEXT (current_function_decl) == NULL_TREE | 1578 || DECL_CONTEXT (current_function_decl) == NULL_TREE |
1373 || TREE_CODE (DECL_CONTEXT (current_function_decl)) | 1579 || TREE_CODE (DECL_CONTEXT (current_function_decl)) |
1374 == NAMESPACE_DECL); | 1580 == NAMESPACE_DECL); |
1375 | 1581 |
1376 type = gfc_get_function_type (sym); | 1582 type = gfc_get_function_type (sym); |
1377 fndecl = build_decl (FUNCTION_DECL, gfc_sym_identifier (sym), type); | 1583 fndecl = build_decl (input_location, |
| 1584 » » FUNCTION_DECL, gfc_sym_identifier (sym), type); |
| 1585 |
| 1586 attr = sym->attr; |
| 1587 |
| 1588 attributes = add_attributes_to_decl (attr, NULL_TREE); |
| 1589 decl_attributes (&fndecl, attributes, 0); |
1378 | 1590 |
1379 /* Perform name mangling if this is a top level or module procedure. */ | 1591 /* Perform name mangling if this is a top level or module procedure. */ |
1380 if (current_function_decl == NULL_TREE) | 1592 if (current_function_decl == NULL_TREE) |
1381 SET_DECL_ASSEMBLER_NAME (fndecl, gfc_sym_mangled_function_id (sym)); | 1593 gfc_set_decl_assembler_name (fndecl, gfc_sym_mangled_function_id (sym)); |
1382 | 1594 |
1383 /* Figure out the return type of the declared function, and build a | 1595 /* Figure out the return type of the declared function, and build a |
1384 RESULT_DECL for it. If this is a subroutine with alternate | 1596 RESULT_DECL for it. If this is a subroutine with alternate |
1385 returns, build a RESULT_DECL for it. */ | 1597 returns, build a RESULT_DECL for it. */ |
1386 attr = sym->attr; | |
1387 | |
1388 result_decl = NULL_TREE; | 1598 result_decl = NULL_TREE; |
1389 /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)). */ | 1599 /* TODO: Shouldn't this just be TREE_TYPE (TREE_TYPE (fndecl)). */ |
1390 if (attr.function) | 1600 if (attr.function) |
1391 { | 1601 { |
1392 if (gfc_return_by_reference (sym)) | 1602 if (gfc_return_by_reference (sym)) |
1393 type = void_type_node; | 1603 type = void_type_node; |
1394 else | 1604 else |
1395 { | 1605 { |
1396 if (sym->result != sym) | 1606 if (sym->result != sym) |
1397 result_decl = gfc_sym_identifier (sym->result); | 1607 result_decl = gfc_sym_identifier (sym->result); |
(...skipping 13 matching lines...) Expand all Loading... |
1411 break; | 1621 break; |
1412 } | 1622 } |
1413 } | 1623 } |
1414 | 1624 |
1415 if (has_alternate_returns) | 1625 if (has_alternate_returns) |
1416 type = integer_type_node; | 1626 type = integer_type_node; |
1417 else | 1627 else |
1418 type = void_type_node; | 1628 type = void_type_node; |
1419 } | 1629 } |
1420 | 1630 |
1421 result_decl = build_decl (RESULT_DECL, result_decl, type); | 1631 result_decl = build_decl (input_location, |
| 1632 » » » RESULT_DECL, result_decl, type); |
1422 DECL_ARTIFICIAL (result_decl) = 1; | 1633 DECL_ARTIFICIAL (result_decl) = 1; |
1423 DECL_IGNORED_P (result_decl) = 1; | 1634 DECL_IGNORED_P (result_decl) = 1; |
1424 DECL_CONTEXT (result_decl) = fndecl; | 1635 DECL_CONTEXT (result_decl) = fndecl; |
1425 DECL_RESULT (fndecl) = result_decl; | 1636 DECL_RESULT (fndecl) = result_decl; |
1426 | 1637 |
1427 /* Don't call layout_decl for a RESULT_DECL. | 1638 /* Don't call layout_decl for a RESULT_DECL. |
1428 layout_decl (result_decl, 0); */ | 1639 layout_decl (result_decl, 0); */ |
1429 | 1640 |
1430 /* If the return type is a pointer, avoid alias issues by setting | |
1431 DECL_IS_MALLOC to nonzero. This means that the function should be | |
1432 treated as if it were a malloc, meaning it returns a pointer that | |
1433 is not an alias. */ | |
1434 if (POINTER_TYPE_P (type)) | |
1435 DECL_IS_MALLOC (fndecl) = 1; | |
1436 | |
1437 /* Set up all attributes for the function. */ | 1641 /* Set up all attributes for the function. */ |
1438 DECL_CONTEXT (fndecl) = current_function_decl; | 1642 DECL_CONTEXT (fndecl) = current_function_decl; |
1439 DECL_EXTERNAL (fndecl) = 0; | 1643 DECL_EXTERNAL (fndecl) = 0; |
1440 | 1644 |
1441 /* This specifies if a function is globally visible, i.e. it is | 1645 /* This specifies if a function is globally visible, i.e. it is |
1442 the opposite of declaring static in C. */ | 1646 the opposite of declaring static in C. */ |
1443 if (DECL_CONTEXT (fndecl) == NULL_TREE | 1647 if (DECL_CONTEXT (fndecl) == NULL_TREE |
1444 && !sym->attr.entry_master) | 1648 && !sym->attr.entry_master && !sym->attr.is_main_program) |
1445 TREE_PUBLIC (fndecl) = 1; | 1649 TREE_PUBLIC (fndecl) = 1; |
1446 | 1650 |
1447 /* TREE_STATIC means the function body is defined here. */ | 1651 /* TREE_STATIC means the function body is defined here. */ |
1448 TREE_STATIC (fndecl) = 1; | 1652 TREE_STATIC (fndecl) = 1; |
1449 | 1653 |
1450 /* Set attributes for PURE functions. A call to a PURE function in the | 1654 /* Set attributes for PURE functions. A call to a PURE function in the |
1451 Fortran 95 sense is both pure and without side effects in the C | 1655 Fortran 95 sense is both pure and without side effects in the C |
1452 sense. */ | 1656 sense. */ |
1453 if (attr.pure || attr.elemental) | 1657 if (attr.pure || attr.elemental) |
1454 { | 1658 { |
1455 /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments | 1659 /* TODO: check if a pure SUBROUTINE has no INTENT(OUT) arguments |
1456 including an alternate return. In that case it can also be | 1660 including an alternate return. In that case it can also be |
1457 marked as PURE. See also in gfc_get_extern_function_decl(). */ | 1661 marked as PURE. See also in gfc_get_extern_function_decl(). */ |
1458 if (attr.function && !gfc_return_by_reference (sym)) | 1662 if (attr.function && !gfc_return_by_reference (sym)) |
1459 DECL_PURE_P (fndecl) = 1; | 1663 DECL_PURE_P (fndecl) = 1; |
1460 TREE_SIDE_EFFECTS (fndecl) = 0; | 1664 TREE_SIDE_EFFECTS (fndecl) = 0; |
1461 } | 1665 } |
1462 | 1666 |
1463 /* For -fwhole-program to work well, the main program needs to have the | |
1464 "externally_visible" attribute. */ | |
1465 if (attr.is_main_program) | |
1466 DECL_ATTRIBUTES (fndecl) | |
1467 = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE); | |
1468 | 1667 |
1469 /* Layout the function declaration and put it in the binding level | 1668 /* Layout the function declaration and put it in the binding level |
1470 of the current function. */ | 1669 of the current function. */ |
1471 pushdecl (fndecl); | 1670 pushdecl (fndecl); |
1472 | 1671 |
1473 sym->backend_decl = fndecl; | 1672 sym->backend_decl = fndecl; |
1474 } | 1673 } |
1475 | 1674 |
1476 | 1675 |
1477 /* Create the DECL_ARGUMENTS for a procedure. */ | 1676 /* Create the DECL_ARGUMENTS for a procedure. */ |
(...skipping 12 matching lines...) Expand all Loading... |
1490 | 1689 |
1491 /* Build formal argument list. Make sure that their TREE_CONTEXT is | 1690 /* Build formal argument list. Make sure that their TREE_CONTEXT is |
1492 the new FUNCTION_DECL node. */ | 1691 the new FUNCTION_DECL node. */ |
1493 arglist = NULL_TREE; | 1692 arglist = NULL_TREE; |
1494 hidden_arglist = NULL_TREE; | 1693 hidden_arglist = NULL_TREE; |
1495 typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); | 1694 typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); |
1496 | 1695 |
1497 if (sym->attr.entry_master) | 1696 if (sym->attr.entry_master) |
1498 { | 1697 { |
1499 type = TREE_VALUE (typelist); | 1698 type = TREE_VALUE (typelist); |
1500 parm = build_decl (PARM_DECL, get_identifier ("__entry"), type); | 1699 parm = build_decl (input_location, |
| 1700 » » » PARM_DECL, get_identifier ("__entry"), type); |
1501 | 1701 |
1502 DECL_CONTEXT (parm) = fndecl; | 1702 DECL_CONTEXT (parm) = fndecl; |
1503 DECL_ARG_TYPE (parm) = type; | 1703 DECL_ARG_TYPE (parm) = type; |
1504 TREE_READONLY (parm) = 1; | 1704 TREE_READONLY (parm) = 1; |
1505 gfc_finish_decl (parm); | 1705 gfc_finish_decl (parm); |
1506 DECL_ARTIFICIAL (parm) = 1; | 1706 DECL_ARTIFICIAL (parm) = 1; |
1507 | 1707 |
1508 arglist = chainon (arglist, parm); | 1708 arglist = chainon (arglist, parm); |
1509 typelist = TREE_CHAIN (typelist); | 1709 typelist = TREE_CHAIN (typelist); |
1510 } | 1710 } |
1511 | 1711 |
1512 if (gfc_return_by_reference (sym)) | 1712 if (gfc_return_by_reference (sym)) |
1513 { | 1713 { |
1514 tree type = TREE_VALUE (typelist), length = NULL; | 1714 tree type = TREE_VALUE (typelist), length = NULL; |
1515 | 1715 |
1516 if (sym->ts.type == BT_CHARACTER) | 1716 if (sym->ts.type == BT_CHARACTER) |
1517 { | 1717 { |
1518 /* Length of character result. */ | 1718 /* Length of character result. */ |
1519 tree len_type = TREE_VALUE (TREE_CHAIN (typelist)); | 1719 tree len_type = TREE_VALUE (TREE_CHAIN (typelist)); |
1520 gcc_assert (len_type == gfc_charlen_type_node); | 1720 gcc_assert (len_type == gfc_charlen_type_node); |
1521 | 1721 |
1522 » length = build_decl (PARM_DECL, | 1722 » length = build_decl (input_location, |
| 1723 » » » PARM_DECL, |
1523 get_identifier (".__result"), | 1724 get_identifier (".__result"), |
1524 len_type); | 1725 len_type); |
1525 » if (!sym->ts.cl->length) | 1726 » if (!sym->ts.u.cl->length) |
1526 { | 1727 { |
1527 » sym->ts.cl->backend_decl = length; | 1728 » sym->ts.u.cl->backend_decl = length; |
1528 TREE_USED (length) = 1; | 1729 TREE_USED (length) = 1; |
1529 } | 1730 } |
1530 gcc_assert (TREE_CODE (length) == PARM_DECL); | 1731 gcc_assert (TREE_CODE (length) == PARM_DECL); |
1531 DECL_CONTEXT (length) = fndecl; | 1732 DECL_CONTEXT (length) = fndecl; |
1532 DECL_ARG_TYPE (length) = len_type; | 1733 DECL_ARG_TYPE (length) = len_type; |
1533 TREE_READONLY (length) = 1; | 1734 TREE_READONLY (length) = 1; |
1534 DECL_ARTIFICIAL (length) = 1; | 1735 DECL_ARTIFICIAL (length) = 1; |
1535 gfc_finish_decl (length); | 1736 gfc_finish_decl (length); |
1536 » if (sym->ts.cl->backend_decl == NULL | 1737 » if (sym->ts.u.cl->backend_decl == NULL |
1537 » || sym->ts.cl->backend_decl == length) | 1738 » || sym->ts.u.cl->backend_decl == length) |
1538 { | 1739 { |
1539 gfc_symbol *arg; | 1740 gfc_symbol *arg; |
1540 tree backend_decl; | 1741 tree backend_decl; |
1541 | 1742 |
1542 » if (sym->ts.cl->backend_decl == NULL) | 1743 » if (sym->ts.u.cl->backend_decl == NULL) |
1543 { | 1744 { |
1544 » » tree len = build_decl (VAR_DECL, | 1745 » » tree len = build_decl (input_location, |
| 1746 » » » » » VAR_DECL, |
1545 get_identifier ("..__result"), | 1747 get_identifier ("..__result"), |
1546 gfc_charlen_type_node); | 1748 gfc_charlen_type_node); |
1547 DECL_ARTIFICIAL (len) = 1; | 1749 DECL_ARTIFICIAL (len) = 1; |
1548 TREE_USED (len) = 1; | 1750 TREE_USED (len) = 1; |
1549 » » sym->ts.cl->backend_decl = len; | 1751 » » sym->ts.u.cl->backend_decl = len; |
1550 } | 1752 } |
1551 | 1753 |
1552 /* Make sure PARM_DECL type doesn't point to incomplete type. */ | 1754 /* Make sure PARM_DECL type doesn't point to incomplete type. */ |
1553 arg = sym->result ? sym->result : sym; | 1755 arg = sym->result ? sym->result : sym; |
1554 backend_decl = arg->backend_decl; | 1756 backend_decl = arg->backend_decl; |
1555 /* Temporary clear it, so that gfc_sym_type creates complete | 1757 /* Temporary clear it, so that gfc_sym_type creates complete |
1556 type. */ | 1758 type. */ |
1557 arg->backend_decl = NULL; | 1759 arg->backend_decl = NULL; |
1558 type = gfc_sym_type (arg); | 1760 type = gfc_sym_type (arg); |
1559 arg->backend_decl = backend_decl; | 1761 arg->backend_decl = backend_decl; |
1560 type = build_reference_type (type); | 1762 type = build_reference_type (type); |
1561 } | 1763 } |
1562 } | 1764 } |
1563 | 1765 |
1564 parm = build_decl (PARM_DECL, get_identifier ("__result"), type); | 1766 parm = build_decl (input_location, |
| 1767 » » » PARM_DECL, get_identifier ("__result"), type); |
1565 | 1768 |
1566 DECL_CONTEXT (parm) = fndecl; | 1769 DECL_CONTEXT (parm) = fndecl; |
1567 DECL_ARG_TYPE (parm) = TREE_VALUE (typelist); | 1770 DECL_ARG_TYPE (parm) = TREE_VALUE (typelist); |
1568 TREE_READONLY (parm) = 1; | 1771 TREE_READONLY (parm) = 1; |
1569 DECL_ARTIFICIAL (parm) = 1; | 1772 DECL_ARTIFICIAL (parm) = 1; |
1570 gfc_finish_decl (parm); | 1773 gfc_finish_decl (parm); |
1571 | 1774 |
1572 arglist = chainon (arglist, parm); | 1775 arglist = chainon (arglist, parm); |
1573 typelist = TREE_CHAIN (typelist); | 1776 typelist = TREE_CHAIN (typelist); |
1574 | 1777 |
(...skipping 13 matching lines...) Expand all Loading... |
1588 for (f = sym->formal; f; f = f->next) | 1791 for (f = sym->formal; f; f = f->next) |
1589 { | 1792 { |
1590 char name[GFC_MAX_SYMBOL_LEN + 2]; | 1793 char name[GFC_MAX_SYMBOL_LEN + 2]; |
1591 | 1794 |
1592 /* Ignore alternate returns. */ | 1795 /* Ignore alternate returns. */ |
1593 if (f->sym == NULL) | 1796 if (f->sym == NULL) |
1594 continue; | 1797 continue; |
1595 | 1798 |
1596 type = TREE_VALUE (typelist); | 1799 type = TREE_VALUE (typelist); |
1597 | 1800 |
1598 if (f->sym->ts.type == BT_CHARACTER) | 1801 if (f->sym->ts.type == BT_CHARACTER |
| 1802 » && (!sym->attr.is_bind_c || sym->attr.entry_master)) |
1599 { | 1803 { |
1600 tree len_type = TREE_VALUE (hidden_typelist); | 1804 tree len_type = TREE_VALUE (hidden_typelist); |
1601 tree length = NULL_TREE; | 1805 tree length = NULL_TREE; |
1602 gcc_assert (len_type == gfc_charlen_type_node); | 1806 gcc_assert (len_type == gfc_charlen_type_node); |
1603 | 1807 |
1604 strcpy (&name[1], f->sym->name); | 1808 strcpy (&name[1], f->sym->name); |
1605 name[0] = '_'; | 1809 name[0] = '_'; |
1606 » length = build_decl (PARM_DECL, get_identifier (name), len_type); | 1810 » length = build_decl (input_location, |
| 1811 » » » PARM_DECL, get_identifier (name), len_type); |
1607 | 1812 |
1608 hidden_arglist = chainon (hidden_arglist, length); | 1813 hidden_arglist = chainon (hidden_arglist, length); |
1609 DECL_CONTEXT (length) = fndecl; | 1814 DECL_CONTEXT (length) = fndecl; |
1610 DECL_ARTIFICIAL (length) = 1; | 1815 DECL_ARTIFICIAL (length) = 1; |
1611 DECL_ARG_TYPE (length) = len_type; | 1816 DECL_ARG_TYPE (length) = len_type; |
1612 TREE_READONLY (length) = 1; | 1817 TREE_READONLY (length) = 1; |
1613 gfc_finish_decl (length); | 1818 gfc_finish_decl (length); |
1614 | 1819 |
1615 » /* TODO: Check string lengths when -fbounds-check. */ | 1820 » /* Remember the passed value. */ |
| 1821 if (f->sym->ts.u.cl->passed_length != NULL) |
| 1822 { |
| 1823 » /* This can happen if the same type is used for multiple |
| 1824 » » arguments. We need to copy cl as otherwise |
| 1825 » » cl->passed_length gets overwritten. */ |
| 1826 » f->sym->ts.u.cl = gfc_new_charlen (f->sym->ns, f->sym->ts.u.cl); |
| 1827 } |
| 1828 » f->sym->ts.u.cl->passed_length = length; |
1616 | 1829 |
1617 /* Use the passed value for assumed length variables. */ | 1830 /* Use the passed value for assumed length variables. */ |
1618 » if (!f->sym->ts.cl->length) | 1831 » if (!f->sym->ts.u.cl->length) |
1619 { | 1832 { |
1620 TREE_USED (length) = 1; | 1833 TREE_USED (length) = 1; |
1621 » gcc_assert (!f->sym->ts.cl->backend_decl); | 1834 » gcc_assert (!f->sym->ts.u.cl->backend_decl); |
1622 » f->sym->ts.cl->backend_decl = length; | 1835 » f->sym->ts.u.cl->backend_decl = length; |
1623 } | 1836 } |
1624 | 1837 |
1625 hidden_typelist = TREE_CHAIN (hidden_typelist); | 1838 hidden_typelist = TREE_CHAIN (hidden_typelist); |
1626 | 1839 |
1627 » if (f->sym->ts.cl->backend_decl == NULL | 1840 » if (f->sym->ts.u.cl->backend_decl == NULL |
1628 » || f->sym->ts.cl->backend_decl == length) | 1841 » || f->sym->ts.u.cl->backend_decl == length) |
1629 { | 1842 { |
1630 » if (f->sym->ts.cl->backend_decl == NULL) | 1843 » if (f->sym->ts.u.cl->backend_decl == NULL) |
1631 gfc_create_string_length (f->sym); | 1844 gfc_create_string_length (f->sym); |
1632 | 1845 |
1633 /* Make sure PARM_DECL type doesn't point to incomplete type. */ | 1846 /* Make sure PARM_DECL type doesn't point to incomplete type. */ |
1634 if (f->sym->attr.flavor == FL_PROCEDURE) | 1847 if (f->sym->attr.flavor == FL_PROCEDURE) |
1635 type = build_pointer_type (gfc_get_function_type (f->sym)); | 1848 type = build_pointer_type (gfc_get_function_type (f->sym)); |
1636 else | 1849 else |
1637 type = gfc_sym_type (f->sym); | 1850 type = gfc_sym_type (f->sym); |
1638 } | 1851 } |
1639 } | 1852 } |
1640 | 1853 |
1641 /* For non-constant length array arguments, make sure they use | 1854 /* For non-constant length array arguments, make sure they use |
1642 a different type node from TYPE_ARG_TYPES type. */ | 1855 a different type node from TYPE_ARG_TYPES type. */ |
1643 if (f->sym->attr.dimension | 1856 if (f->sym->attr.dimension |
1644 && type == TREE_VALUE (typelist) | 1857 && type == TREE_VALUE (typelist) |
1645 && TREE_CODE (type) == POINTER_TYPE | 1858 && TREE_CODE (type) == POINTER_TYPE |
1646 && GFC_ARRAY_TYPE_P (type) | 1859 && GFC_ARRAY_TYPE_P (type) |
1647 && f->sym->as->type != AS_ASSUMED_SIZE | 1860 && f->sym->as->type != AS_ASSUMED_SIZE |
1648 && ! COMPLETE_TYPE_P (TREE_TYPE (type))) | 1861 && ! COMPLETE_TYPE_P (TREE_TYPE (type))) |
1649 { | 1862 { |
1650 if (f->sym->attr.flavor == FL_PROCEDURE) | 1863 if (f->sym->attr.flavor == FL_PROCEDURE) |
1651 type = build_pointer_type (gfc_get_function_type (f->sym)); | 1864 type = build_pointer_type (gfc_get_function_type (f->sym)); |
1652 else | 1865 else |
1653 type = gfc_sym_type (f->sym); | 1866 type = gfc_sym_type (f->sym); |
1654 } | 1867 } |
1655 | 1868 |
1656 if (f->sym->attr.proc_pointer) | 1869 if (f->sym->attr.proc_pointer) |
1657 type = build_pointer_type (type); | 1870 type = build_pointer_type (type); |
1658 | 1871 |
1659 /* Build the argument declaration. */ | 1872 /* Build the argument declaration. */ |
1660 parm = build_decl (PARM_DECL, gfc_sym_identifier (f->sym), type); | 1873 parm = build_decl (input_location, |
| 1874 » » » PARM_DECL, gfc_sym_identifier (f->sym), type); |
1661 | 1875 |
1662 /* Fill in arg stuff. */ | 1876 /* Fill in arg stuff. */ |
1663 DECL_CONTEXT (parm) = fndecl; | 1877 DECL_CONTEXT (parm) = fndecl; |
1664 DECL_ARG_TYPE (parm) = TREE_VALUE (typelist); | 1878 DECL_ARG_TYPE (parm) = TREE_VALUE (typelist); |
1665 /* All implementation args are read-only. */ | 1879 /* All implementation args are read-only. */ |
1666 TREE_READONLY (parm) = 1; | 1880 TREE_READONLY (parm) = 1; |
1667 if (POINTER_TYPE_P (type) | 1881 if (POINTER_TYPE_P (type) |
1668 && (!f->sym->attr.proc_pointer | 1882 && (!f->sym->attr.proc_pointer |
1669 && f->sym->attr.flavor != FL_PROCEDURE)) | 1883 && f->sym->attr.flavor != FL_PROCEDURE)) |
1670 DECL_BY_REFERENCE (parm) = 1; | 1884 DECL_BY_REFERENCE (parm) = 1; |
1671 | 1885 |
1672 gfc_finish_decl (parm); | 1886 gfc_finish_decl (parm); |
1673 | 1887 |
1674 f->sym->backend_decl = parm; | 1888 f->sym->backend_decl = parm; |
1675 | 1889 |
1676 arglist = chainon (arglist, parm); | 1890 arglist = chainon (arglist, parm); |
1677 typelist = TREE_CHAIN (typelist); | 1891 typelist = TREE_CHAIN (typelist); |
1678 } | 1892 } |
1679 | 1893 |
1680 /* Add the hidden string length parameters, unless the procedure | 1894 /* Add the hidden string length parameters, unless the procedure |
1681 is bind(C). */ | 1895 is bind(C). */ |
1682 if (!sym->attr.is_bind_c) | 1896 if (!sym->attr.is_bind_c) |
1683 arglist = chainon (arglist, hidden_arglist); | 1897 arglist = chainon (arglist, hidden_arglist); |
1684 | 1898 |
1685 gcc_assert (hidden_typelist == NULL_TREE | 1899 gcc_assert (hidden_typelist == NULL_TREE |
1686 || TREE_VALUE (hidden_typelist) == void_type_node); | 1900 || TREE_VALUE (hidden_typelist) == void_type_node); |
1687 DECL_ARGUMENTS (fndecl) = arglist; | 1901 DECL_ARGUMENTS (fndecl) = arglist; |
1688 } | 1902 } |
1689 | 1903 |
1690 /* Convert FNDECL's code to GIMPLE and handle any nested functions. */ | |
1691 | |
1692 static void | |
1693 gfc_gimplify_function (tree fndecl) | |
1694 { | |
1695 struct cgraph_node *cgn; | |
1696 | |
1697 gimplify_function_tree (fndecl); | |
1698 dump_function (TDI_generic, fndecl); | |
1699 | |
1700 /* Generate errors for structured block violations. */ | |
1701 /* ??? Could be done as part of resolve_labels. */ | |
1702 if (flag_openmp) | |
1703 diagnose_omp_structured_block_errors (fndecl); | |
1704 | |
1705 /* Convert all nested functions to GIMPLE now. We do things in this order | |
1706 so that items like VLA sizes are expanded properly in the context of the | |
1707 correct function. */ | |
1708 cgn = cgraph_node (fndecl); | |
1709 for (cgn = cgn->nested; cgn; cgn = cgn->next_nested) | |
1710 gfc_gimplify_function (cgn->decl); | |
1711 } | |
1712 | |
1713 | |
1714 /* Do the setup necessary before generating the body of a function. */ | 1904 /* Do the setup necessary before generating the body of a function. */ |
1715 | 1905 |
1716 static void | 1906 static void |
1717 trans_function_start (gfc_symbol * sym) | 1907 trans_function_start (gfc_symbol * sym) |
1718 { | 1908 { |
1719 tree fndecl; | 1909 tree fndecl; |
1720 | 1910 |
1721 fndecl = sym->backend_decl; | 1911 fndecl = sym->backend_decl; |
1722 | 1912 |
1723 /* Let GCC know the current scope is this function. */ | 1913 /* Let GCC know the current scope is this function. */ |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1814 } | 2004 } |
1815 | 2005 |
1816 if (thunk_formal) | 2006 if (thunk_formal) |
1817 { | 2007 { |
1818 /* Pass the argument. */ | 2008 /* Pass the argument. */ |
1819 DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1; | 2009 DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1; |
1820 args = tree_cons (NULL_TREE, thunk_formal->sym->backend_decl, | 2010 args = tree_cons (NULL_TREE, thunk_formal->sym->backend_decl, |
1821 args); | 2011 args); |
1822 if (formal->sym->ts.type == BT_CHARACTER) | 2012 if (formal->sym->ts.type == BT_CHARACTER) |
1823 { | 2013 { |
1824 » » tmp = thunk_formal->sym->ts.cl->backend_decl; | 2014 » » tmp = thunk_formal->sym->ts.u.cl->backend_decl; |
1825 string_args = tree_cons (NULL_TREE, tmp, string_args); | 2015 string_args = tree_cons (NULL_TREE, tmp, string_args); |
1826 } | 2016 } |
1827 } | 2017 } |
1828 else | 2018 else |
1829 { | 2019 { |
1830 /* Pass NULL for a missing argument. */ | 2020 /* Pass NULL for a missing argument. */ |
1831 args = tree_cons (NULL_TREE, null_pointer_node, args); | 2021 args = tree_cons (NULL_TREE, null_pointer_node, args); |
1832 if (formal->sym->ts.type == BT_CHARACTER) | 2022 if (formal->sym->ts.type == BT_CHARACTER) |
1833 { | 2023 { |
1834 tmp = build_int_cst (gfc_charlen_type_node, 0); | 2024 tmp = build_int_cst (gfc_charlen_type_node, 0); |
1835 string_args = tree_cons (NULL_TREE, tmp, string_args); | 2025 string_args = tree_cons (NULL_TREE, tmp, string_args); |
1836 } | 2026 } |
1837 } | 2027 } |
1838 } | 2028 } |
1839 | 2029 |
1840 /* Call the master function. */ | 2030 /* Call the master function. */ |
1841 args = nreverse (args); | 2031 args = nreverse (args); |
1842 args = chainon (args, nreverse (string_args)); | 2032 args = chainon (args, nreverse (string_args)); |
1843 tmp = ns->proc_name->backend_decl; | 2033 tmp = ns->proc_name->backend_decl; |
1844 tmp = build_function_call_expr (tmp, args); | 2034 tmp = build_function_call_expr (input_location, tmp, args); |
1845 if (ns->proc_name->attr.mixed_entry_master) | 2035 if (ns->proc_name->attr.mixed_entry_master) |
1846 { | 2036 { |
1847 tree union_decl, field; | 2037 tree union_decl, field; |
1848 tree master_type = TREE_TYPE (ns->proc_name->backend_decl); | 2038 tree master_type = TREE_TYPE (ns->proc_name->backend_decl); |
1849 | 2039 |
1850 » union_decl = build_decl (VAR_DECL, get_identifier ("__result"), | 2040 » union_decl = build_decl (input_location, |
| 2041 » » » » VAR_DECL, get_identifier ("__result"), |
1851 TREE_TYPE (master_type)); | 2042 TREE_TYPE (master_type)); |
1852 DECL_ARTIFICIAL (union_decl) = 1; | 2043 DECL_ARTIFICIAL (union_decl) = 1; |
1853 DECL_EXTERNAL (union_decl) = 0; | 2044 DECL_EXTERNAL (union_decl) = 0; |
1854 TREE_PUBLIC (union_decl) = 0; | 2045 TREE_PUBLIC (union_decl) = 0; |
1855 TREE_USED (union_decl) = 1; | 2046 TREE_USED (union_decl) = 1; |
1856 layout_decl (union_decl, 0); | 2047 layout_decl (union_decl, 0); |
1857 pushdecl (union_decl); | 2048 pushdecl (union_decl); |
1858 | 2049 |
1859 DECL_CONTEXT (union_decl) = current_function_decl; | 2050 DECL_CONTEXT (union_decl) = current_function_decl; |
1860 tmp = fold_build2 (MODIFY_EXPR, TREE_TYPE (union_decl), | 2051 tmp = fold_build2 (MODIFY_EXPR, TREE_TYPE (union_decl), |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 info for the epilogue. */ | 2091 info for the epilogue. */ |
1901 cfun->function_end_locus = input_location; | 2092 cfun->function_end_locus = input_location; |
1902 | 2093 |
1903 /* We're leaving the context of this function, so zap cfun. | 2094 /* We're leaving the context of this function, so zap cfun. |
1904 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in | 2095 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in |
1905 tree_rest_of_compilation. */ | 2096 tree_rest_of_compilation. */ |
1906 set_cfun (NULL); | 2097 set_cfun (NULL); |
1907 | 2098 |
1908 current_function_decl = NULL_TREE; | 2099 current_function_decl = NULL_TREE; |
1909 | 2100 |
1910 gfc_gimplify_function (thunk_fndecl); | 2101 cgraph_finalize_function (thunk_fndecl, true); |
1911 cgraph_finalize_function (thunk_fndecl, false); | |
1912 | 2102 |
1913 /* We share the symbols in the formal argument list with other entry | 2103 /* We share the symbols in the formal argument list with other entry |
1914 points and the master function. Clear them so that they are | 2104 points and the master function. Clear them so that they are |
1915 recreated for each function. */ | 2105 recreated for each function. */ |
1916 for (formal = thunk_sym->formal; formal; formal = formal->next) | 2106 for (formal = thunk_sym->formal; formal; formal = formal->next) |
1917 if (formal->sym != NULL) /* Ignore alternate returns. */ | 2107 if (formal->sym != NULL) /* Ignore alternate returns. */ |
1918 { | 2108 { |
1919 formal->sym->backend_decl = NULL_TREE; | 2109 formal->sym->backend_decl = NULL_TREE; |
1920 if (formal->sym->ts.type == BT_CHARACTER) | 2110 if (formal->sym->ts.type == BT_CHARACTER) |
1921 » formal->sym->ts.cl->backend_decl = NULL_TREE; | 2111 » formal->sym->ts.u.cl->backend_decl = NULL_TREE; |
1922 } | 2112 } |
1923 | 2113 |
1924 if (thunk_sym->attr.function) | 2114 if (thunk_sym->attr.function) |
1925 { | 2115 { |
1926 if (thunk_sym->ts.type == BT_CHARACTER) | 2116 if (thunk_sym->ts.type == BT_CHARACTER) |
1927 » thunk_sym->ts.cl->backend_decl = NULL_TREE; | 2117 » thunk_sym->ts.u.cl->backend_decl = NULL_TREE; |
1928 if (thunk_sym->result->ts.type == BT_CHARACTER) | 2118 if (thunk_sym->result->ts.type == BT_CHARACTER) |
1929 » thunk_sym->result->ts.cl->backend_decl = NULL_TREE; | 2119 » thunk_sym->result->ts.u.cl->backend_decl = NULL_TREE; |
1930 } | 2120 } |
1931 } | 2121 } |
1932 | 2122 |
1933 gfc_set_backend_locus (&old_loc); | 2123 gfc_set_backend_locus (&old_loc); |
1934 } | 2124 } |
1935 | 2125 |
1936 | 2126 |
1937 /* Create a decl for a function, and create any thunks for alternate entry | 2127 /* Create a decl for a function, and create any thunks for alternate entry |
1938 points. */ | 2128 points. */ |
1939 | 2129 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2028 if (this_fake_result_decl != NULL_TREE) | 2218 if (this_fake_result_decl != NULL_TREE) |
2029 return TREE_VALUE (this_fake_result_decl); | 2219 return TREE_VALUE (this_fake_result_decl); |
2030 | 2220 |
2031 /* Only when gfc_get_fake_result_decl is called by gfc_trans_return, | 2221 /* Only when gfc_get_fake_result_decl is called by gfc_trans_return, |
2032 sym is NULL. */ | 2222 sym is NULL. */ |
2033 if (!sym) | 2223 if (!sym) |
2034 return NULL_TREE; | 2224 return NULL_TREE; |
2035 | 2225 |
2036 if (sym->ts.type == BT_CHARACTER) | 2226 if (sym->ts.type == BT_CHARACTER) |
2037 { | 2227 { |
2038 if (sym->ts.cl->backend_decl == NULL_TREE) | 2228 if (sym->ts.u.cl->backend_decl == NULL_TREE) |
2039 length = gfc_create_string_length (sym); | 2229 length = gfc_create_string_length (sym); |
2040 else | 2230 else |
2041 » length = sym->ts.cl->backend_decl; | 2231 » length = sym->ts.u.cl->backend_decl; |
2042 if (TREE_CODE (length) == VAR_DECL | 2232 if (TREE_CODE (length) == VAR_DECL |
2043 && DECL_CONTEXT (length) == NULL_TREE) | 2233 && DECL_CONTEXT (length) == NULL_TREE) |
2044 gfc_add_decl_to_function (length); | 2234 gfc_add_decl_to_function (length); |
2045 } | 2235 } |
2046 | 2236 |
2047 if (gfc_return_by_reference (sym)) | 2237 if (gfc_return_by_reference (sym)) |
2048 { | 2238 { |
2049 decl = DECL_ARGUMENTS (this_function_decl); | 2239 decl = DECL_ARGUMENTS (this_function_decl); |
2050 | 2240 |
2051 if (sym->ns->proc_name->backend_decl == this_function_decl | 2241 if (sym->ns->proc_name->backend_decl == this_function_decl |
2052 && sym->ns->proc_name->attr.entry_master) | 2242 && sym->ns->proc_name->attr.entry_master) |
2053 decl = TREE_CHAIN (decl); | 2243 decl = TREE_CHAIN (decl); |
2054 | 2244 |
2055 TREE_USED (decl) = 1; | 2245 TREE_USED (decl) = 1; |
2056 if (sym->as) | 2246 if (sym->as) |
2057 decl = gfc_build_dummy_array_decl (sym, decl); | 2247 decl = gfc_build_dummy_array_decl (sym, decl); |
2058 } | 2248 } |
2059 else | 2249 else |
2060 { | 2250 { |
2061 sprintf (name, "__result_%.20s", | 2251 sprintf (name, "__result_%.20s", |
2062 IDENTIFIER_POINTER (DECL_NAME (this_function_decl))); | 2252 IDENTIFIER_POINTER (DECL_NAME (this_function_decl))); |
2063 | 2253 |
2064 if (!sym->attr.mixed_entry_master && sym->attr.function) | 2254 if (!sym->attr.mixed_entry_master && sym->attr.function) |
2065 » decl = build_decl (VAR_DECL, get_identifier (name), | 2255 » decl = build_decl (input_location, |
| 2256 » » » VAR_DECL, get_identifier (name), |
2066 gfc_sym_type (sym)); | 2257 gfc_sym_type (sym)); |
2067 else | 2258 else |
2068 » decl = build_decl (VAR_DECL, get_identifier (name), | 2259 » decl = build_decl (input_location, |
| 2260 » » » VAR_DECL, get_identifier (name), |
2069 TREE_TYPE (TREE_TYPE (this_function_decl))); | 2261 TREE_TYPE (TREE_TYPE (this_function_decl))); |
2070 DECL_ARTIFICIAL (decl) = 1; | 2262 DECL_ARTIFICIAL (decl) = 1; |
2071 DECL_EXTERNAL (decl) = 0; | 2263 DECL_EXTERNAL (decl) = 0; |
2072 TREE_PUBLIC (decl) = 0; | 2264 TREE_PUBLIC (decl) = 0; |
2073 TREE_USED (decl) = 1; | 2265 TREE_USED (decl) = 1; |
2074 GFC_DECL_RESULT (decl) = 1; | 2266 GFC_DECL_RESULT (decl) = 1; |
2075 TREE_ADDRESSABLE (decl) = 1; | 2267 TREE_ADDRESSABLE (decl) = 1; |
2076 | 2268 |
2077 layout_decl (decl, 0); | 2269 layout_decl (decl, 0); |
2078 | 2270 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2118 } | 2310 } |
2119 | 2311 |
2120 if (nargs >= 0) | 2312 if (nargs >= 0) |
2121 { | 2313 { |
2122 /* Terminate the list. */ | 2314 /* Terminate the list. */ |
2123 arglist = gfc_chainon_list (arglist, void_type_node); | 2315 arglist = gfc_chainon_list (arglist, void_type_node); |
2124 } | 2316 } |
2125 | 2317 |
2126 /* Build the function type and decl. */ | 2318 /* Build the function type and decl. */ |
2127 fntype = build_function_type (rettype, arglist); | 2319 fntype = build_function_type (rettype, arglist); |
2128 fndecl = build_decl (FUNCTION_DECL, name, fntype); | 2320 fndecl = build_decl (input_location, |
| 2321 » » FUNCTION_DECL, name, fntype); |
2129 | 2322 |
2130 /* Mark this decl as external. */ | 2323 /* Mark this decl as external. */ |
2131 DECL_EXTERNAL (fndecl) = 1; | 2324 DECL_EXTERNAL (fndecl) = 1; |
2132 TREE_PUBLIC (fndecl) = 1; | 2325 TREE_PUBLIC (fndecl) = 1; |
2133 | 2326 |
2134 va_end (p); | 2327 va_end (p); |
2135 | 2328 |
2136 pushdecl (fndecl); | 2329 pushdecl (fndecl); |
2137 | 2330 |
2138 rest_of_decl_compilation (fndecl, 1, 0); | 2331 rest_of_decl_compilation (fndecl, 1, 0); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2556 gfc_build_library_function_decl (get_identifier (PREFIX("generate_error")), | 2749 gfc_build_library_function_decl (get_identifier (PREFIX("generate_error")), |
2557 void_type_node, 3, pvoid_type_node, | 2750 void_type_node, 3, pvoid_type_node, |
2558 integer_type_node, pchar_type_node); | 2751 integer_type_node, pchar_type_node); |
2559 | 2752 |
2560 gfor_fndecl_os_error = | 2753 gfor_fndecl_os_error = |
2561 gfc_build_library_function_decl (get_identifier (PREFIX("os_error")), | 2754 gfc_build_library_function_decl (get_identifier (PREFIX("os_error")), |
2562 void_type_node, 1, pchar_type_node); | 2755 void_type_node, 1, pchar_type_node); |
2563 /* The runtime_error function does not return. */ | 2756 /* The runtime_error function does not return. */ |
2564 TREE_THIS_VOLATILE (gfor_fndecl_os_error) = 1; | 2757 TREE_THIS_VOLATILE (gfor_fndecl_os_error) = 1; |
2565 | 2758 |
| 2759 gfor_fndecl_set_args = |
| 2760 gfc_build_library_function_decl (get_identifier (PREFIX("set_args")), |
| 2761 void_type_node, 2, integer_type_node, |
| 2762 build_pointer_type (pchar_type_node)); |
| 2763 |
2566 gfor_fndecl_set_fpe = | 2764 gfor_fndecl_set_fpe = |
2567 gfc_build_library_function_decl (get_identifier (PREFIX("set_fpe")), | 2765 gfc_build_library_function_decl (get_identifier (PREFIX("set_fpe")), |
2568 void_type_node, 1, integer_type_node); | 2766 void_type_node, 1, integer_type_node); |
2569 | 2767 |
2570 /* Keep the array dimension in sync with the call, later in this file. */ | 2768 /* Keep the array dimension in sync with the call, later in this file. */ |
2571 gfor_fndecl_set_options = | 2769 gfor_fndecl_set_options = |
2572 gfc_build_library_function_decl (get_identifier (PREFIX("set_options")), | 2770 gfc_build_library_function_decl (get_identifier (PREFIX("set_options")), |
2573 void_type_node, 2, integer_type_node, | 2771 void_type_node, 2, integer_type_node, |
2574 » » » » pvoid_type_node); | 2772 » » » » build_pointer_type (integer_type_node)); |
2575 | 2773 |
2576 gfor_fndecl_set_convert = | 2774 gfor_fndecl_set_convert = |
2577 gfc_build_library_function_decl (get_identifier (PREFIX("set_convert")), | 2775 gfc_build_library_function_decl (get_identifier (PREFIX("set_convert")), |
2578 void_type_node, 1, integer_type_node); | 2776 void_type_node, 1, integer_type_node); |
2579 | 2777 |
2580 gfor_fndecl_set_record_marker = | 2778 gfor_fndecl_set_record_marker = |
2581 gfc_build_library_function_decl (get_identifier (PREFIX("set_record_marker")
), | 2779 gfc_build_library_function_decl (get_identifier (PREFIX("set_record_marker")
), |
2582 void_type_node, 1, integer_type_node); | 2780 void_type_node, 1, integer_type_node); |
2583 | 2781 |
2584 gfor_fndecl_set_max_subrecord_length = | 2782 gfor_fndecl_set_max_subrecord_length = |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 /* Allocate and cleanup an automatic character variable. */ | 2827 /* Allocate and cleanup an automatic character variable. */ |
2630 | 2828 |
2631 static tree | 2829 static tree |
2632 gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody) | 2830 gfc_trans_auto_character_variable (gfc_symbol * sym, tree fnbody) |
2633 { | 2831 { |
2634 stmtblock_t body; | 2832 stmtblock_t body; |
2635 tree decl; | 2833 tree decl; |
2636 tree tmp; | 2834 tree tmp; |
2637 | 2835 |
2638 gcc_assert (sym->backend_decl); | 2836 gcc_assert (sym->backend_decl); |
2639 gcc_assert (sym->ts.cl && sym->ts.cl->length); | 2837 gcc_assert (sym->ts.u.cl && sym->ts.u.cl->length); |
2640 | 2838 |
2641 gfc_start_block (&body); | 2839 gfc_start_block (&body); |
2642 | 2840 |
2643 /* Evaluate the string length expression. */ | 2841 /* Evaluate the string length expression. */ |
2644 gfc_conv_string_length (sym->ts.cl, NULL, &body); | 2842 gfc_conv_string_length (sym->ts.u.cl, NULL, &body); |
2645 | 2843 |
2646 gfc_trans_vla_type_sizes (sym, &body); | 2844 gfc_trans_vla_type_sizes (sym, &body); |
2647 | 2845 |
2648 decl = sym->backend_decl; | 2846 decl = sym->backend_decl; |
2649 | 2847 |
2650 /* Emit a DECL_EXPR for this variable, which will cause the | 2848 /* Emit a DECL_EXPR for this variable, which will cause the |
2651 gimplifier to allocate storage, and all that good stuff. */ | 2849 gimplifier to allocate storage, and all that good stuff. */ |
2652 tmp = fold_build1 (DECL_EXPR, TREE_TYPE (decl), decl); | 2850 tmp = fold_build1 (DECL_EXPR, TREE_TYPE (decl), decl); |
2653 gfc_add_expr_to_block (&body, tmp); | 2851 gfc_add_expr_to_block (&body, tmp); |
2654 | 2852 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2790 stmtblock_t fnblock; | 2988 stmtblock_t fnblock; |
2791 gfc_expr *e; | 2989 gfc_expr *e; |
2792 tree tmp; | 2990 tree tmp; |
2793 tree present; | 2991 tree present; |
2794 | 2992 |
2795 gfc_init_block (&fnblock); | 2993 gfc_init_block (&fnblock); |
2796 gcc_assert (!sym->attr.allocatable); | 2994 gcc_assert (!sym->attr.allocatable); |
2797 gfc_set_sym_referenced (sym); | 2995 gfc_set_sym_referenced (sym); |
2798 e = gfc_lval_expr_from_sym (sym); | 2996 e = gfc_lval_expr_from_sym (sym); |
2799 tmp = gfc_trans_assignment (e, sym->value, false); | 2997 tmp = gfc_trans_assignment (e, sym->value, false); |
2800 if (sym->attr.dummy) | 2998 if (sym->attr.dummy && (sym->attr.optional |
| 2999 » » » || sym->ns->proc_name->attr.entry_master)) |
2801 { | 3000 { |
2802 present = gfc_conv_expr_present (sym); | 3001 present = gfc_conv_expr_present (sym); |
2803 tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, | 3002 tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, |
2804 » » tmp, build_empty_stmt ()); | 3003 » » tmp, build_empty_stmt (input_location)); |
2805 } | 3004 } |
2806 gfc_add_expr_to_block (&fnblock, tmp); | 3005 gfc_add_expr_to_block (&fnblock, tmp); |
2807 gfc_free_expr (e); | 3006 gfc_free_expr (e); |
2808 if (body) | 3007 if (body) |
2809 gfc_add_expr_to_block (&fnblock, body); | 3008 gfc_add_expr_to_block (&fnblock, body); |
2810 return gfc_finish_block (&fnblock); | 3009 return gfc_finish_block (&fnblock); |
2811 } | 3010 } |
2812 | 3011 |
2813 | 3012 |
2814 /* Initialize INTENT(OUT) derived type dummies. As well as giving | 3013 /* Initialize INTENT(OUT) derived type dummies. As well as giving |
2815 them their default initializer, if they do not have allocatable | 3014 them their default initializer, if they do not have allocatable |
2816 components, they have their allocatable components deallocated. */ | 3015 components, they have their allocatable components deallocated. */ |
2817 | 3016 |
2818 static tree | 3017 static tree |
2819 init_intent_out_dt (gfc_symbol * proc_sym, tree body) | 3018 init_intent_out_dt (gfc_symbol * proc_sym, tree body) |
2820 { | 3019 { |
2821 stmtblock_t fnblock; | 3020 stmtblock_t fnblock; |
2822 gfc_formal_arglist *f; | 3021 gfc_formal_arglist *f; |
2823 tree tmp; | 3022 tree tmp; |
2824 tree present; | 3023 tree present; |
2825 | 3024 |
2826 gfc_init_block (&fnblock); | 3025 gfc_init_block (&fnblock); |
2827 for (f = proc_sym->formal; f; f = f->next) | 3026 for (f = proc_sym->formal; f; f = f->next) |
2828 if (f->sym && f->sym->attr.intent == INTENT_OUT | 3027 if (f->sym && f->sym->attr.intent == INTENT_OUT |
2829 && !f->sym->attr.pointer | 3028 && !f->sym->attr.pointer |
2830 && f->sym->ts.type == BT_DERIVED) | 3029 && f->sym->ts.type == BT_DERIVED) |
2831 { | 3030 { |
2832 » if (f->sym->ts.derived->attr.alloc_comp && !f->sym->value) | 3031 » if (f->sym->ts.u.derived->attr.alloc_comp && !f->sym->value) |
2833 { | 3032 { |
2834 » tmp = gfc_deallocate_alloc_comp (f->sym->ts.derived, | 3033 » tmp = gfc_deallocate_alloc_comp (f->sym->ts.u.derived, |
2835 f->sym->backend_decl, | 3034 f->sym->backend_decl, |
2836 f->sym->as ? f->sym->as->rank : 0); | 3035 f->sym->as ? f->sym->as->rank : 0); |
2837 | 3036 |
2838 » present = gfc_conv_expr_present (f->sym); | 3037 » if (f->sym->attr.optional |
2839 » tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, | 3038 » » || f->sym->ns->proc_name->attr.entry_master) |
2840 » » » tmp, build_empty_stmt ()); | 3039 » { |
| 3040 » » present = gfc_conv_expr_present (f->sym); |
| 3041 » » tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present, |
| 3042 » » » tmp, build_empty_stmt (input_location)); |
| 3043 » } |
2841 | 3044 |
2842 gfc_add_expr_to_block (&fnblock, tmp); | 3045 gfc_add_expr_to_block (&fnblock, tmp); |
2843 } | 3046 } |
2844 » else if (f->sym->value) | 3047 else if (f->sym->value) |
2845 body = gfc_init_default_dt (f->sym, body); | 3048 body = gfc_init_default_dt (f->sym, body); |
2846 } | 3049 } |
2847 | 3050 |
2848 gfc_add_expr_to_block (&fnblock, body); | 3051 gfc_add_expr_to_block (&fnblock, body); |
2849 return gfc_finish_block (&fnblock); | 3052 return gfc_finish_block (&fnblock); |
2850 } | 3053 } |
2851 | 3054 |
2852 | 3055 |
2853 /* Generate function entry and exit code, and add it to the function body. | 3056 /* Generate function entry and exit code, and add it to the function body. |
2854 This includes: | 3057 This includes: |
2855 Allocation and initialization of array variables. | 3058 Allocation and initialization of array variables. |
2856 Allocation of character string variables. | 3059 Allocation of character string variables. |
2857 Initialization and possibly repacking of dummy arrays. | 3060 Initialization and possibly repacking of dummy arrays. |
2858 Initialization of ASSIGN statement auxiliary variable. */ | 3061 Initialization of ASSIGN statement auxiliary variable. |
| 3062 Automatic deallocation. */ |
2859 | 3063 |
2860 static tree | 3064 tree |
2861 gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) | 3065 gfc_trans_deferred_vars (gfc_symbol * proc_sym, tree fnbody) |
2862 { | 3066 { |
2863 locus loc; | 3067 locus loc; |
2864 gfc_symbol *sym; | 3068 gfc_symbol *sym; |
2865 gfc_formal_arglist *f; | 3069 gfc_formal_arglist *f; |
2866 stmtblock_t body; | 3070 stmtblock_t body; |
2867 bool seen_trans_deferred_array = false; | 3071 bool seen_trans_deferred_array = false; |
2868 | 3072 |
2869 /* Deal with implicit return variables. Explicit return variables will | 3073 /* Deal with implicit return variables. Explicit return variables will |
2870 already have been added. */ | 3074 already have been added. */ |
(...skipping 13 matching lines...) Expand all Loading... |
2884 gfc_warning ("Return value of function '%s' at %L not set", | 3088 gfc_warning ("Return value of function '%s' at %L not set", |
2885 proc_sym->name, &proc_sym->declared_at); | 3089 proc_sym->name, &proc_sym->declared_at); |
2886 } | 3090 } |
2887 else if (proc_sym->as) | 3091 else if (proc_sym->as) |
2888 { | 3092 { |
2889 tree result = TREE_VALUE (current_fake_result_decl); | 3093 tree result = TREE_VALUE (current_fake_result_decl); |
2890 fnbody = gfc_trans_dummy_array_bias (proc_sym, result, fnbody); | 3094 fnbody = gfc_trans_dummy_array_bias (proc_sym, result, fnbody); |
2891 | 3095 |
2892 /* An automatic character length, pointer array result. */ | 3096 /* An automatic character length, pointer array result. */ |
2893 if (proc_sym->ts.type == BT_CHARACTER | 3097 if (proc_sym->ts.type == BT_CHARACTER |
2894 » » && TREE_CODE (proc_sym->ts.cl->backend_decl) == VAR_DECL) | 3098 » » && TREE_CODE (proc_sym->ts.u.cl->backend_decl) == VAR_DECL) |
2895 » fnbody = gfc_trans_dummy_character (proc_sym, proc_sym->ts.cl, | 3099 » fnbody = gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, |
2896 fnbody); | 3100 fnbody); |
2897 } | 3101 } |
2898 else if (proc_sym->ts.type == BT_CHARACTER) | 3102 else if (proc_sym->ts.type == BT_CHARACTER) |
2899 { | 3103 { |
2900 » if (TREE_CODE (proc_sym->ts.cl->backend_decl) == VAR_DECL) | 3104 » if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == VAR_DECL) |
2901 » fnbody = gfc_trans_dummy_character (proc_sym, proc_sym->ts.cl, | 3105 » fnbody = gfc_trans_dummy_character (proc_sym, proc_sym->ts.u.cl, |
2902 fnbody); | 3106 fnbody); |
2903 } | 3107 } |
2904 else | 3108 else |
2905 gcc_assert (gfc_option.flag_f2c | 3109 gcc_assert (gfc_option.flag_f2c |
2906 && proc_sym->ts.type == BT_COMPLEX); | 3110 && proc_sym->ts.type == BT_COMPLEX); |
2907 } | 3111 } |
2908 | 3112 |
2909 /* Initialize the INTENT(OUT) derived type dummy arguments. This | 3113 /* Initialize the INTENT(OUT) derived type dummy arguments. This |
2910 should be done here so that the offsets and lbounds of arrays | 3114 should be done here so that the offsets and lbounds of arrays |
2911 are available. */ | 3115 are available. */ |
2912 fnbody = init_intent_out_dt (proc_sym, fnbody); | 3116 fnbody = init_intent_out_dt (proc_sym, fnbody); |
2913 | 3117 |
2914 for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink) | 3118 for (sym = proc_sym->tlink; sym != proc_sym; sym = sym->tlink) |
2915 { | 3119 { |
2916 bool sym_has_alloc_comp = (sym->ts.type == BT_DERIVED) | 3120 bool sym_has_alloc_comp = (sym->ts.type == BT_DERIVED) |
2917 » » » » && sym->ts.derived->attr.alloc_comp; | 3121 » » » » && sym->ts.u.derived->attr.alloc_comp; |
2918 if (sym->attr.dimension) | 3122 if (sym->attr.dimension) |
2919 { | 3123 { |
2920 switch (sym->as->type) | 3124 switch (sym->as->type) |
2921 { | 3125 { |
2922 case AS_EXPLICIT: | 3126 case AS_EXPLICIT: |
2923 if (sym->attr.dummy || sym->attr.result) | 3127 if (sym->attr.dummy || sym->attr.result) |
2924 fnbody = | 3128 fnbody = |
2925 gfc_trans_dummy_array_bias (sym, sym->backend_decl, fnbody); | 3129 gfc_trans_dummy_array_bias (sym, sym->backend_decl, fnbody); |
2926 else if (sym->attr.pointer || sym->attr.allocatable) | 3130 else if (sym->attr.pointer || sym->attr.allocatable) |
2927 { | 3131 { |
(...skipping 21 matching lines...) Expand all Loading... |
2949 gfc_get_backend_locus (&loc); | 3153 gfc_get_backend_locus (&loc); |
2950 gfc_set_backend_locus (&sym->declared_at); | 3154 gfc_set_backend_locus (&sym->declared_at); |
2951 fnbody = gfc_trans_auto_array_allocation (sym->backend_decl, | 3155 fnbody = gfc_trans_auto_array_allocation (sym->backend_decl, |
2952 sym, fnbody); | 3156 sym, fnbody); |
2953 gfc_set_backend_locus (&loc); | 3157 gfc_set_backend_locus (&loc); |
2954 } | 3158 } |
2955 break; | 3159 break; |
2956 | 3160 |
2957 case AS_ASSUMED_SIZE: | 3161 case AS_ASSUMED_SIZE: |
2958 /* Must be a dummy parameter. */ | 3162 /* Must be a dummy parameter. */ |
2959 » gcc_assert (sym->attr.dummy); | 3163 » gcc_assert (sym->attr.dummy || sym->as->cp_was_assumed); |
2960 | 3164 |
2961 /* We should always pass assumed size arrays the g77 way. */ | 3165 /* We should always pass assumed size arrays the g77 way. */ |
2962 » fnbody = gfc_trans_g77_array (sym, fnbody); | 3166 » if (sym->attr.dummy) |
| 3167 » » fnbody = gfc_trans_g77_array (sym, fnbody); |
2963 break; | 3168 break; |
2964 | 3169 |
2965 case AS_ASSUMED_SHAPE: | 3170 case AS_ASSUMED_SHAPE: |
2966 /* Must be a dummy parameter. */ | 3171 /* Must be a dummy parameter. */ |
2967 gcc_assert (sym->attr.dummy); | 3172 gcc_assert (sym->attr.dummy); |
2968 | 3173 |
2969 fnbody = gfc_trans_dummy_array_bias (sym, sym->backend_decl, | 3174 fnbody = gfc_trans_dummy_array_bias (sym, sym->backend_decl, |
2970 fnbody); | 3175 fnbody); |
2971 break; | 3176 break; |
2972 | 3177 |
2973 case AS_DEFERRED: | 3178 case AS_DEFERRED: |
2974 seen_trans_deferred_array = true; | 3179 seen_trans_deferred_array = true; |
2975 fnbody = gfc_trans_deferred_array (sym, fnbody); | 3180 fnbody = gfc_trans_deferred_array (sym, fnbody); |
2976 break; | 3181 break; |
2977 | 3182 |
2978 default: | 3183 default: |
2979 gcc_unreachable (); | 3184 gcc_unreachable (); |
2980 } | 3185 } |
2981 if (sym_has_alloc_comp && !seen_trans_deferred_array) | 3186 if (sym_has_alloc_comp && !seen_trans_deferred_array) |
2982 fnbody = gfc_trans_deferred_array (sym, fnbody); | 3187 fnbody = gfc_trans_deferred_array (sym, fnbody); |
2983 } | 3188 } |
2984 else if (sym_has_alloc_comp) | 3189 else if (sym_has_alloc_comp) |
2985 fnbody = gfc_trans_deferred_array (sym, fnbody); | 3190 fnbody = gfc_trans_deferred_array (sym, fnbody); |
| 3191 else if (sym->attr.allocatable |
| 3192 || (sym->ts.type == BT_CLASS |
| 3193 && sym->ts.u.derived->components->attr.allocatable)) |
| 3194 { |
| 3195 if (!sym->attr.save) |
| 3196 { |
| 3197 /* Nullify and automatic deallocation of allocatable |
| 3198 scalars. */ |
| 3199 tree tmp; |
| 3200 gfc_expr *e; |
| 3201 gfc_se se; |
| 3202 stmtblock_t block; |
| 3203 |
| 3204 e = gfc_lval_expr_from_sym (sym); |
| 3205 if (sym->ts.type == BT_CLASS) |
| 3206 gfc_add_component_ref (e, "$data"); |
| 3207 |
| 3208 gfc_init_se (&se, NULL); |
| 3209 se.want_pointer = 1; |
| 3210 gfc_conv_expr (&se, e); |
| 3211 gfc_free_expr (e); |
| 3212 |
| 3213 /* Nullify when entering the scope. */ |
| 3214 gfc_start_block (&block); |
| 3215 gfc_add_modify (&block, se.expr, |
| 3216 fold_convert (TREE_TYPE (se.expr), |
| 3217 null_pointer_node)); |
| 3218 gfc_add_expr_to_block (&block, fnbody); |
| 3219 |
| 3220 /* Deallocate when leaving the scope. Nullifying is not |
| 3221 needed. */ |
| 3222 tmp = gfc_deallocate_with_status (se.expr, NULL_TREE, true, |
| 3223 NULL); |
| 3224 gfc_add_expr_to_block (&block, tmp); |
| 3225 fnbody = gfc_finish_block (&block); |
| 3226 } |
| 3227 } |
2986 else if (sym->ts.type == BT_CHARACTER) | 3228 else if (sym->ts.type == BT_CHARACTER) |
2987 { | 3229 { |
2988 gfc_get_backend_locus (&loc); | 3230 gfc_get_backend_locus (&loc); |
2989 gfc_set_backend_locus (&sym->declared_at); | 3231 gfc_set_backend_locus (&sym->declared_at); |
2990 if (sym->attr.dummy || sym->attr.result) | 3232 if (sym->attr.dummy || sym->attr.result) |
2991 » fnbody = gfc_trans_dummy_character (sym, sym->ts.cl, fnbody); | 3233 » fnbody = gfc_trans_dummy_character (sym, sym->ts.u.cl, fnbody); |
2992 else | 3234 else |
2993 fnbody = gfc_trans_auto_character_variable (sym, fnbody); | 3235 fnbody = gfc_trans_auto_character_variable (sym, fnbody); |
2994 gfc_set_backend_locus (&loc); | 3236 gfc_set_backend_locus (&loc); |
2995 } | 3237 } |
2996 else if (sym->attr.assign) | 3238 else if (sym->attr.assign) |
2997 { | 3239 { |
2998 gfc_get_backend_locus (&loc); | 3240 gfc_get_backend_locus (&loc); |
2999 gfc_set_backend_locus (&sym->declared_at); | 3241 gfc_set_backend_locus (&sym->declared_at); |
3000 fnbody = gfc_trans_assign_aux_var (sym, fnbody); | 3242 fnbody = gfc_trans_assign_aux_var (sym, fnbody); |
3001 gfc_set_backend_locus (&loc); | 3243 gfc_set_backend_locus (&loc); |
3002 } | 3244 } |
3003 else if (sym->ts.type == BT_DERIVED | 3245 else if (sym->ts.type == BT_DERIVED |
3004 && sym->value | 3246 && sym->value |
3005 && !sym->attr.data | 3247 && !sym->attr.data |
3006 && sym->attr.save == SAVE_NONE) | 3248 && sym->attr.save == SAVE_NONE) |
3007 fnbody = gfc_init_default_dt (sym, fnbody); | 3249 fnbody = gfc_init_default_dt (sym, fnbody); |
3008 else | 3250 else |
3009 gcc_unreachable (); | 3251 gcc_unreachable (); |
3010 } | 3252 } |
3011 | 3253 |
3012 gfc_init_block (&body); | 3254 gfc_init_block (&body); |
3013 | 3255 |
3014 for (f = proc_sym->formal; f; f = f->next) | 3256 for (f = proc_sym->formal; f; f = f->next) |
3015 { | 3257 { |
3016 if (f->sym && f->sym->tlink == NULL && f->sym->ts.type == BT_CHARACTER) | 3258 if (f->sym && f->sym->tlink == NULL && f->sym->ts.type == BT_CHARACTER) |
3017 { | 3259 { |
3018 » gcc_assert (f->sym->ts.cl->backend_decl != NULL); | 3260 » gcc_assert (f->sym->ts.u.cl->backend_decl != NULL); |
3019 » if (TREE_CODE (f->sym->ts.cl->backend_decl) == PARM_DECL) | 3261 » if (TREE_CODE (f->sym->ts.u.cl->backend_decl) == PARM_DECL) |
3020 gfc_trans_vla_type_sizes (f->sym, &body); | 3262 gfc_trans_vla_type_sizes (f->sym, &body); |
3021 } | 3263 } |
3022 } | 3264 } |
3023 | 3265 |
3024 if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER | 3266 if (gfc_return_by_reference (proc_sym) && proc_sym->ts.type == BT_CHARACTER |
3025 && current_fake_result_decl != NULL) | 3267 && current_fake_result_decl != NULL) |
3026 { | 3268 { |
3027 gcc_assert (proc_sym->ts.cl->backend_decl != NULL); | 3269 gcc_assert (proc_sym->ts.u.cl->backend_decl != NULL); |
3028 if (TREE_CODE (proc_sym->ts.cl->backend_decl) == PARM_DECL) | 3270 if (TREE_CODE (proc_sym->ts.u.cl->backend_decl) == PARM_DECL) |
3029 gfc_trans_vla_type_sizes (proc_sym, &body); | 3271 gfc_trans_vla_type_sizes (proc_sym, &body); |
3030 } | 3272 } |
3031 | 3273 |
3032 gfc_add_expr_to_block (&body, fnbody); | 3274 gfc_add_expr_to_block (&body, fnbody); |
3033 return gfc_finish_block (&body); | 3275 return gfc_finish_block (&body); |
3034 } | 3276 } |
3035 | 3277 |
3036 static GTY ((param_is (struct module_htab_entry))) htab_t module_htab; | 3278 static GTY ((param_is (struct module_htab_entry))) htab_t module_htab; |
3037 | 3279 |
3038 /* Hash and equality functions for module_htab. */ | 3280 /* Hash and equality functions for module_htab. */ |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c | 3375 if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c |
3134 && sym->ts.type == BT_DERIVED) | 3376 && sym->ts.type == BT_DERIVED) |
3135 sym->backend_decl = gfc_typenode_for_spec (&(sym->ts)); | 3377 sym->backend_decl = gfc_typenode_for_spec (&(sym->ts)); |
3136 | 3378 |
3137 if (sym->attr.flavor == FL_DERIVED | 3379 if (sym->attr.flavor == FL_DERIVED |
3138 && sym->backend_decl | 3380 && sym->backend_decl |
3139 && TREE_CODE (sym->backend_decl) == RECORD_TYPE) | 3381 && TREE_CODE (sym->backend_decl) == RECORD_TYPE) |
3140 { | 3382 { |
3141 decl = sym->backend_decl; | 3383 decl = sym->backend_decl; |
3142 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); | 3384 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); |
3143 gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE | 3385 |
3144 » » || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl); | 3386 /* -fwhole-file mixes up the contexts so these asserts are unnecessary. *
/ |
3145 gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE | 3387 if (!(gfc_option.flag_whole_file && sym->attr.use_assoc)) |
3146 » » || DECL_CONTEXT (TYPE_STUB_DECL (decl)) | 3388 » { |
3147 » » == sym->ns->proc_name->backend_decl); | 3389 » gcc_assert (TYPE_CONTEXT (decl) == NULL_TREE |
| 3390 » » || TYPE_CONTEXT (decl) == sym->ns->proc_name->backend_decl
); |
| 3391 » gcc_assert (DECL_CONTEXT (TYPE_STUB_DECL (decl)) == NULL_TREE |
| 3392 » » || DECL_CONTEXT (TYPE_STUB_DECL (decl)) |
| 3393 » » » == sym->ns->proc_name->backend_decl); |
| 3394 » } |
3148 TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl; | 3395 TYPE_CONTEXT (decl) = sym->ns->proc_name->backend_decl; |
3149 DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl; | 3396 DECL_CONTEXT (TYPE_STUB_DECL (decl)) = sym->ns->proc_name->backend_decl; |
3150 gfc_module_add_decl (cur_module, TYPE_STUB_DECL (decl)); | 3397 gfc_module_add_decl (cur_module, TYPE_STUB_DECL (decl)); |
3151 } | 3398 } |
3152 | 3399 |
3153 /* Only output variables, procedure pointers and array valued, | 3400 /* Only output variables, procedure pointers and array valued, |
3154 or derived type, parameters. */ | 3401 or derived type, parameters. */ |
3155 if (sym->attr.flavor != FL_VARIABLE | 3402 if (sym->attr.flavor != FL_VARIABLE |
3156 && !(sym->attr.flavor == FL_PARAMETER | 3403 && !(sym->attr.flavor == FL_PARAMETER |
3157 && (sym->attr.dimension || sym->ts.type == BT_DERIVED)) | 3404 && (sym->attr.dimension || sym->ts.type == BT_DERIVED)) |
(...skipping 12 matching lines...) Expand all Loading... |
3170 /* Don't generate variables from other modules. Variables from | 3417 /* Don't generate variables from other modules. Variables from |
3171 COMMONs will already have been generated. */ | 3418 COMMONs will already have been generated. */ |
3172 if (sym->attr.use_assoc || sym->attr.in_common) | 3419 if (sym->attr.use_assoc || sym->attr.in_common) |
3173 return; | 3420 return; |
3174 | 3421 |
3175 /* Equivalenced variables arrive here after creation. */ | 3422 /* Equivalenced variables arrive here after creation. */ |
3176 if (sym->backend_decl | 3423 if (sym->backend_decl |
3177 && (sym->equiv_built || sym->attr.in_equivalence)) | 3424 && (sym->equiv_built || sym->attr.in_equivalence)) |
3178 return; | 3425 return; |
3179 | 3426 |
3180 if (sym->backend_decl) | 3427 if (sym->backend_decl && !sym->attr.vtab) |
3181 internal_error ("backend decl for module variable %s already exists", | 3428 internal_error ("backend decl for module variable %s already exists", |
3182 sym->name); | 3429 sym->name); |
3183 | 3430 |
3184 /* We always want module variables to be created. */ | 3431 /* We always want module variables to be created. */ |
3185 sym->attr.referenced = 1; | 3432 sym->attr.referenced = 1; |
3186 /* Create the decl. */ | 3433 /* Create the decl. */ |
3187 decl = gfc_get_symbol_decl (sym); | 3434 decl = gfc_get_symbol_decl (sym); |
3188 | 3435 |
3189 /* Create the variable. */ | 3436 /* Create the variable. */ |
3190 pushdecl (decl); | 3437 pushdecl (decl); |
3191 gcc_assert (DECL_CONTEXT (decl) == NULL_TREE); | 3438 gcc_assert (DECL_CONTEXT (decl) == NULL_TREE); |
3192 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); | 3439 gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE); |
3193 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl; | 3440 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl; |
3194 rest_of_decl_compilation (decl, 1, 0); | 3441 rest_of_decl_compilation (decl, 1, 0); |
3195 gfc_module_add_decl (cur_module, decl); | 3442 gfc_module_add_decl (cur_module, decl); |
3196 | 3443 |
3197 /* Also add length of strings. */ | 3444 /* Also add length of strings. */ |
3198 if (sym->ts.type == BT_CHARACTER) | 3445 if (sym->ts.type == BT_CHARACTER) |
3199 { | 3446 { |
3200 tree length; | 3447 tree length; |
3201 | 3448 |
3202 length = sym->ts.cl->backend_decl; | 3449 length = sym->ts.u.cl->backend_decl; |
3203 if (!INTEGER_CST_P (length)) | 3450 gcc_assert (length || sym->attr.proc_pointer); |
| 3451 if (length && !INTEGER_CST_P (length)) |
3204 { | 3452 { |
3205 pushdecl (length); | 3453 pushdecl (length); |
3206 rest_of_decl_compilation (length, 1, 0); | 3454 rest_of_decl_compilation (length, 1, 0); |
3207 } | 3455 } |
3208 } | 3456 } |
3209 } | 3457 } |
3210 | 3458 |
3211 /* Emit debug information for USE statements. */ | 3459 /* Emit debug information for USE statements. */ |
3212 | 3460 |
3213 static void | 3461 static void |
3214 gfc_trans_use_stmts (gfc_namespace * ns) | 3462 gfc_trans_use_stmts (gfc_namespace * ns) |
3215 { | 3463 { |
3216 gfc_use_list *use_stmt; | 3464 gfc_use_list *use_stmt; |
3217 for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next) | 3465 for (use_stmt = ns->use_stmts; use_stmt; use_stmt = use_stmt->next) |
3218 { | 3466 { |
3219 struct module_htab_entry *entry | 3467 struct module_htab_entry *entry |
3220 = gfc_find_module (use_stmt->module_name); | 3468 = gfc_find_module (use_stmt->module_name); |
3221 gfc_use_rename *rent; | 3469 gfc_use_rename *rent; |
3222 | 3470 |
3223 if (entry->namespace_decl == NULL) | 3471 if (entry->namespace_decl == NULL) |
3224 { | 3472 { |
3225 entry->namespace_decl | 3473 entry->namespace_decl |
3226 » = build_decl (NAMESPACE_DECL, | 3474 » = build_decl (input_location, |
| 3475 » » » NAMESPACE_DECL, |
3227 get_identifier (use_stmt->module_name), | 3476 get_identifier (use_stmt->module_name), |
3228 void_type_node); | 3477 void_type_node); |
3229 DECL_EXTERNAL (entry->namespace_decl) = 1; | 3478 DECL_EXTERNAL (entry->namespace_decl) = 1; |
3230 } | 3479 } |
3231 gfc_set_backend_locus (&use_stmt->where); | 3480 gfc_set_backend_locus (&use_stmt->where); |
3232 if (!use_stmt->only_flag) | 3481 if (!use_stmt->only_flag) |
3233 (*debug_hooks->imported_module_or_decl) (entry->namespace_decl, | 3482 (*debug_hooks->imported_module_or_decl) (entry->namespace_decl, |
3234 NULL_TREE, | 3483 NULL_TREE, |
3235 ns->proc_name->backend_decl, | 3484 ns->proc_name->backend_decl, |
3236 false); | 3485 false); |
(...skipping 10 matching lines...) Expand all Loading... |
3247 INSERT); | 3496 INSERT); |
3248 if (*slot == NULL) | 3497 if (*slot == NULL) |
3249 { | 3498 { |
3250 gfc_symtree *st; | 3499 gfc_symtree *st; |
3251 | 3500 |
3252 st = gfc_find_symtree (ns->sym_root, | 3501 st = gfc_find_symtree (ns->sym_root, |
3253 rent->local_name[0] | 3502 rent->local_name[0] |
3254 ? rent->local_name : rent->use_name); | 3503 ? rent->local_name : rent->use_name); |
3255 gcc_assert (st); | 3504 gcc_assert (st); |
3256 | 3505 |
3257 » /* Fixing-up doubly contained symbols, sometimes results in | 3506 » /* Sometimes, generic interfaces wind up being over-ruled by a |
3258 » » ambiguity, which is caught here. */ | 3507 » » local symbol (see PR41062). */ |
3259 if (!st->n.sym->attr.use_assoc) | 3508 if (!st->n.sym->attr.use_assoc) |
3260 continue; | 3509 continue; |
3261 | 3510 |
3262 if (st->n.sym->backend_decl | 3511 if (st->n.sym->backend_decl |
3263 && DECL_P (st->n.sym->backend_decl) | 3512 && DECL_P (st->n.sym->backend_decl) |
3264 && st->n.sym->module | 3513 && st->n.sym->module |
3265 && strcmp (st->n.sym->module, use_stmt->module_name) == 0) | 3514 && strcmp (st->n.sym->module, use_stmt->module_name) == 0) |
3266 { | 3515 { |
3267 gcc_assert (DECL_EXTERNAL (entry->namespace_decl) | 3516 gcc_assert (DECL_EXTERNAL (entry->namespace_decl) |
3268 || (TREE_CODE (st->n.sym->backend_decl) | 3517 || (TREE_CODE (st->n.sym->backend_decl) |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3327 else if (c->expr->expr_type != EXPR_CONSTANT) | 3576 else if (c->expr->expr_type != EXPR_CONSTANT) |
3328 return false; | 3577 return false; |
3329 } | 3578 } |
3330 return true; | 3579 return true; |
3331 } | 3580 } |
3332 else switch (ts->type) | 3581 else switch (ts->type) |
3333 { | 3582 { |
3334 case BT_DERIVED: | 3583 case BT_DERIVED: |
3335 if (expr->expr_type != EXPR_STRUCTURE) | 3584 if (expr->expr_type != EXPR_STRUCTURE) |
3336 return false; | 3585 return false; |
3337 cm = expr->ts.derived->components; | 3586 cm = expr->ts.u.derived->components; |
3338 for (c = expr->value.constructor; c; c = c->next, cm = cm->next) | 3587 for (c = expr->value.constructor; c; c = c->next, cm = cm->next) |
3339 { | 3588 { |
3340 if (!c->expr || cm->attr.allocatable) | 3589 if (!c->expr || cm->attr.allocatable) |
3341 continue; | 3590 continue; |
3342 if (!check_constant_initializer (c->expr, &cm->ts, | 3591 if (!check_constant_initializer (c->expr, &cm->ts, |
3343 cm->attr.dimension, | 3592 cm->attr.dimension, |
3344 cm->attr.pointer)) | 3593 cm->attr.pointer)) |
3345 return false; | 3594 return false; |
3346 } | 3595 } |
3347 return true; | 3596 return true; |
(...skipping 25 matching lines...) Expand all Loading... |
3373 || sym->attr.allocatable | 3622 || sym->attr.allocatable |
3374 || sym->attr.cray_pointee | 3623 || sym->attr.cray_pointee |
3375 || sym->attr.threadprivate | 3624 || sym->attr.threadprivate |
3376 || sym->attr.is_bind_c | 3625 || sym->attr.is_bind_c |
3377 || sym->attr.subref_array_pointer | 3626 || sym->attr.subref_array_pointer |
3378 || sym->attr.assign) | 3627 || sym->attr.assign) |
3379 return; | 3628 return; |
3380 | 3629 |
3381 if (sym->ts.type == BT_CHARACTER) | 3630 if (sym->ts.type == BT_CHARACTER) |
3382 { | 3631 { |
3383 gfc_conv_const_charlen (sym->ts.cl); | 3632 gfc_conv_const_charlen (sym->ts.u.cl); |
3384 if (sym->ts.cl->backend_decl == NULL | 3633 if (sym->ts.u.cl->backend_decl == NULL |
3385 » || TREE_CODE (sym->ts.cl->backend_decl) != INTEGER_CST) | 3634 » || TREE_CODE (sym->ts.u.cl->backend_decl) != INTEGER_CST) |
3386 return; | 3635 return; |
3387 } | 3636 } |
3388 else if (sym->ts.type == BT_DERIVED && sym->ts.derived->attr.alloc_comp) | 3637 else if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.alloc_comp) |
3389 return; | 3638 return; |
3390 | 3639 |
3391 if (sym->as) | 3640 if (sym->as) |
3392 { | 3641 { |
3393 int n; | 3642 int n; |
3394 | 3643 |
3395 if (sym->as->type != AS_EXPLICIT) | 3644 if (sym->as->type != AS_EXPLICIT) |
3396 return; | 3645 return; |
3397 for (n = 0; n < sym->as->rank; n++) | 3646 for (n = 0; n < sym->as->rank; n++) |
3398 if (sym->as->lower[n]->expr_type != EXPR_CONSTANT | 3647 if (sym->as->lower[n]->expr_type != EXPR_CONSTANT |
3399 || sym->as->upper[n] == NULL | 3648 || sym->as->upper[n] == NULL |
3400 || sym->as->upper[n]->expr_type != EXPR_CONSTANT) | 3649 || sym->as->upper[n]->expr_type != EXPR_CONSTANT) |
3401 return; | 3650 return; |
3402 } | 3651 } |
3403 | 3652 |
3404 if (!check_constant_initializer (sym->value, &sym->ts, | 3653 if (!check_constant_initializer (sym->value, &sym->ts, |
3405 sym->attr.dimension, false)) | 3654 sym->attr.dimension, false)) |
3406 return; | 3655 return; |
3407 | 3656 |
3408 /* Create the decl for the variable or constant. */ | 3657 /* Create the decl for the variable or constant. */ |
3409 decl = build_decl (sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL, | 3658 decl = build_decl (input_location, |
| 3659 » » sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL, |
3410 gfc_sym_identifier (sym), gfc_sym_type (sym)); | 3660 gfc_sym_identifier (sym), gfc_sym_type (sym)); |
3411 if (sym->attr.flavor == FL_PARAMETER) | 3661 if (sym->attr.flavor == FL_PARAMETER) |
3412 TREE_READONLY (decl) = 1; | 3662 TREE_READONLY (decl) = 1; |
3413 gfc_set_decl_location (decl, &sym->declared_at); | 3663 gfc_set_decl_location (decl, &sym->declared_at); |
3414 if (sym->attr.dimension) | 3664 if (sym->attr.dimension) |
3415 GFC_DECL_PACKED_ARRAY (decl) = 1; | 3665 GFC_DECL_PACKED_ARRAY (decl) = 1; |
3416 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl; | 3666 DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl; |
3417 TREE_STATIC (decl) = 1; | 3667 TREE_STATIC (decl) = 1; |
3418 TREE_USED (decl) = 1; | 3668 TREE_USED (decl) = 1; |
3419 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL) | 3669 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL) |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3505 | 3755 |
3506 | 3756 |
3507 /* Check for dependencies in the character length and array spec. */ | 3757 /* Check for dependencies in the character length and array spec. */ |
3508 | 3758 |
3509 static void | 3759 static void |
3510 generate_dependency_declarations (gfc_symbol *sym) | 3760 generate_dependency_declarations (gfc_symbol *sym) |
3511 { | 3761 { |
3512 int i; | 3762 int i; |
3513 | 3763 |
3514 if (sym->ts.type == BT_CHARACTER | 3764 if (sym->ts.type == BT_CHARACTER |
3515 && sym->ts.cl | 3765 && sym->ts.u.cl |
3516 && sym->ts.cl->length | 3766 && sym->ts.u.cl->length |
3517 && sym->ts.cl->length->expr_type != EXPR_CONSTANT) | 3767 && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT) |
3518 generate_expr_decls (sym, sym->ts.cl->length); | 3768 generate_expr_decls (sym, sym->ts.u.cl->length); |
3519 | 3769 |
3520 if (sym->as && sym->as->rank) | 3770 if (sym->as && sym->as->rank) |
3521 { | 3771 { |
3522 for (i = 0; i < sym->as->rank; i++) | 3772 for (i = 0; i < sym->as->rank; i++) |
3523 { | 3773 { |
3524 generate_expr_decls (sym, sym->as->lower[i]); | 3774 generate_expr_decls (sym, sym->as->lower[i]); |
3525 generate_expr_decls (sym, sym->as->upper[i]); | 3775 generate_expr_decls (sym, sym->as->upper[i]); |
3526 } | 3776 } |
3527 } | 3777 } |
3528 } | 3778 } |
(...skipping 10 matching lines...) Expand all Loading... |
3539 { | 3789 { |
3540 if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master) | 3790 if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master) |
3541 generate_dependency_declarations (sym); | 3791 generate_dependency_declarations (sym); |
3542 | 3792 |
3543 if (sym->attr.referenced) | 3793 if (sym->attr.referenced) |
3544 gfc_get_symbol_decl (sym); | 3794 gfc_get_symbol_decl (sym); |
3545 /* INTENT(out) dummy arguments are likely meant to be set. */ | 3795 /* INTENT(out) dummy arguments are likely meant to be set. */ |
3546 else if (warn_unused_variable | 3796 else if (warn_unused_variable |
3547 && sym->attr.dummy | 3797 && sym->attr.dummy |
3548 && sym->attr.intent == INTENT_OUT) | 3798 && sym->attr.intent == INTENT_OUT) |
3549 » gfc_warning ("Dummy argument '%s' at %L was declared INTENT(OUT) but was
not set", | 3799 » { |
3550 » » sym->name, &sym->declared_at); | 3800 » if (!(sym->ts.type == BT_DERIVED |
| 3801 » » && sym->ts.u.derived->components->initializer)) |
| 3802 » gfc_warning ("Dummy argument '%s' at %L was declared INTENT(OUT) " |
| 3803 » » "but was not set", sym->name, &sym->declared_at); |
| 3804 » } |
3551 /* Specific warning for unused dummy arguments. */ | 3805 /* Specific warning for unused dummy arguments. */ |
3552 else if (warn_unused_variable && sym->attr.dummy) | 3806 else if (warn_unused_variable && sym->attr.dummy) |
3553 gfc_warning ("Unused dummy argument '%s' at %L", sym->name, | 3807 gfc_warning ("Unused dummy argument '%s' at %L", sym->name, |
3554 &sym->declared_at); | 3808 &sym->declared_at); |
3555 /* Warn for unused variables, but not if they're inside a common | 3809 /* Warn for unused variables, but not if they're inside a common |
3556 block or are use-associated. */ | 3810 block or are use-associated. */ |
3557 else if (warn_unused_variable | 3811 else if (warn_unused_variable |
3558 && !(sym->attr.in_common || sym->attr.use_assoc || sym->mark)) | 3812 && !(sym->attr.in_common || sym->attr.use_assoc || sym->mark)) |
3559 gfc_warning ("Unused variable '%s' declared at %L", sym->name, | 3813 gfc_warning ("Unused variable '%s' declared at %L", sym->name, |
3560 &sym->declared_at); | 3814 &sym->declared_at); |
3561 | 3815 |
3562 /* For variable length CHARACTER parameters, the PARM_DECL already | 3816 /* For variable length CHARACTER parameters, the PARM_DECL already |
3563 references the length variable, so force gfc_get_symbol_decl | 3817 references the length variable, so force gfc_get_symbol_decl |
3564 even when not referenced. If optimize > 0, it will be optimized | 3818 even when not referenced. If optimize > 0, it will be optimized |
3565 away anyway. But do this only after emitting -Wunused-parameter | 3819 away anyway. But do this only after emitting -Wunused-parameter |
3566 warning if requested. */ | 3820 warning if requested. */ |
3567 if (sym->attr.dummy && !sym->attr.referenced | 3821 if (sym->attr.dummy && !sym->attr.referenced |
3568 && sym->ts.type == BT_CHARACTER | 3822 && sym->ts.type == BT_CHARACTER |
3569 » && sym->ts.cl->backend_decl != NULL | 3823 » && sym->ts.u.cl->backend_decl != NULL |
3570 » && TREE_CODE (sym->ts.cl->backend_decl) == VAR_DECL) | 3824 » && TREE_CODE (sym->ts.u.cl->backend_decl) == VAR_DECL) |
3571 { | 3825 { |
3572 sym->attr.referenced = 1; | 3826 sym->attr.referenced = 1; |
3573 gfc_get_symbol_decl (sym); | 3827 gfc_get_symbol_decl (sym); |
3574 } | 3828 } |
3575 | 3829 |
3576 /* INTENT(out) dummy arguments with allocatable components are reset | 3830 /* INTENT(out) dummy arguments and result variables with allocatable |
3577 » by default and need to be set referenced to generate the code for | 3831 » components are reset by default and need to be set referenced to |
3578 » automatic lengths. */ | 3832 » generate the code for nullification and automatic lengths. */ |
3579 if (sym->attr.dummy && !sym->attr.referenced | 3833 if (!sym->attr.referenced |
3580 && sym->ts.type == BT_DERIVED | 3834 && sym->ts.type == BT_DERIVED |
| 3835 && sym->ts.u.derived->attr.alloc_comp |
3581 && !sym->attr.pointer | 3836 && !sym->attr.pointer |
3582 » && sym->ts.derived->attr.alloc_comp | 3837 » && ((sym->attr.dummy && sym->attr.intent == INTENT_OUT) |
3583 » && sym->attr.intent == INTENT_OUT) | 3838 » » || |
| 3839 » » (sym->attr.result && sym != sym->result))) |
3584 { | 3840 { |
3585 sym->attr.referenced = 1; | 3841 sym->attr.referenced = 1; |
3586 gfc_get_symbol_decl (sym); | 3842 gfc_get_symbol_decl (sym); |
3587 } | 3843 } |
3588 | 3844 |
3589 | |
3590 /* Check for dependencies in the array specification and string | 3845 /* Check for dependencies in the array specification and string |
3591 length, adding the necessary declarations to the function. We | 3846 length, adding the necessary declarations to the function. We |
3592 mark the symbol now, as well as in traverse_ns, to prevent | 3847 mark the symbol now, as well as in traverse_ns, to prevent |
3593 getting stuck in a circular dependency. */ | 3848 getting stuck in a circular dependency. */ |
3594 sym->mark = 1; | 3849 sym->mark = 1; |
3595 | 3850 |
3596 /* We do not want the middle-end to warn about unused parameters | 3851 /* We do not want the middle-end to warn about unused parameters |
3597 as this was already done above. */ | 3852 as this was already done above. */ |
3598 if (sym->attr.dummy && sym->backend_decl != NULL_TREE) | 3853 if (sym->attr.dummy && sym->backend_decl != NULL_TREE) |
3599 TREE_NO_WARNING(sym->backend_decl) = 1; | 3854 TREE_NO_WARNING(sym->backend_decl) = 1; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3682 el->label = label; | 3937 el->label = label; |
3683 } | 3938 } |
3684 tmp = gfc_finish_block (&block); | 3939 tmp = gfc_finish_block (&block); |
3685 /* The first argument selects the entry point. */ | 3940 /* The first argument selects the entry point. */ |
3686 val = DECL_ARGUMENTS (current_function_decl); | 3941 val = DECL_ARGUMENTS (current_function_decl); |
3687 tmp = build3_v (SWITCH_EXPR, val, tmp, NULL_TREE); | 3942 tmp = build3_v (SWITCH_EXPR, val, tmp, NULL_TREE); |
3688 return tmp; | 3943 return tmp; |
3689 } | 3944 } |
3690 | 3945 |
3691 | 3946 |
| 3947 /* Add code to string lengths of actual arguments passed to a function against |
| 3948 the expected lengths of the dummy arguments. */ |
| 3949 |
| 3950 static void |
| 3951 add_argument_checking (stmtblock_t *block, gfc_symbol *sym) |
| 3952 { |
| 3953 gfc_formal_arglist *formal; |
| 3954 |
| 3955 for (formal = sym->formal; formal; formal = formal->next) |
| 3956 if (formal->sym && formal->sym->ts.type == BT_CHARACTER) |
| 3957 { |
| 3958 enum tree_code comparison; |
| 3959 tree cond; |
| 3960 tree argname; |
| 3961 gfc_symbol *fsym; |
| 3962 gfc_charlen *cl; |
| 3963 const char *message; |
| 3964 |
| 3965 fsym = formal->sym; |
| 3966 cl = fsym->ts.u.cl; |
| 3967 |
| 3968 gcc_assert (cl); |
| 3969 gcc_assert (cl->passed_length != NULL_TREE); |
| 3970 gcc_assert (cl->backend_decl != NULL_TREE); |
| 3971 |
| 3972 /* For POINTER, ALLOCATABLE and assumed-shape dummy arguments, the |
| 3973 string lengths must match exactly. Otherwise, it is only required |
| 3974 that the actual string length is *at least* the expected one. |
| 3975 Sequence association allows for a mismatch of the string length |
| 3976 if the actual argument is (part of) an array, but only if the |
| 3977 dummy argument is an array. (See "Sequence association" in |
| 3978 Section 12.4.1.4 for F95 and 12.4.1.5 for F2003.) */ |
| 3979 if (fsym->attr.pointer || fsym->attr.allocatable |
| 3980 || (fsym->as && fsym->as->type == AS_ASSUMED_SHAPE)) |
| 3981 { |
| 3982 comparison = NE_EXPR; |
| 3983 message = _("Actual string length does not match the declared one" |
| 3984 " for dummy argument '%s' (%ld/%ld)"); |
| 3985 } |
| 3986 else if (fsym->as && fsym->as->rank != 0) |
| 3987 continue; |
| 3988 else |
| 3989 { |
| 3990 comparison = LT_EXPR; |
| 3991 message = _("Actual string length is shorter than the declared one" |
| 3992 " for dummy argument '%s' (%ld/%ld)"); |
| 3993 } |
| 3994 |
| 3995 /* Build the condition. For optional arguments, an actual length |
| 3996 of 0 is also acceptable if the associated string is NULL, which |
| 3997 means the argument was not passed. */ |
| 3998 cond = fold_build2 (comparison, boolean_type_node, |
| 3999 cl->passed_length, cl->backend_decl); |
| 4000 if (fsym->attr.optional) |
| 4001 { |
| 4002 tree not_absent; |
| 4003 tree not_0length; |
| 4004 tree absent_failed; |
| 4005 |
| 4006 not_0length = fold_build2 (NE_EXPR, boolean_type_node, |
| 4007 cl->passed_length, |
| 4008 fold_convert (gfc_charlen_type_node, |
| 4009 integer_zero_node)); |
| 4010 /* The symbol needs to be referenced for gfc_get_symbol_decl. */ |
| 4011 fsym->attr.referenced = 1; |
| 4012 not_absent = gfc_conv_expr_present (fsym); |
| 4013 |
| 4014 absent_failed = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, |
| 4015 not_0length, not_absent); |
| 4016 |
| 4017 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, |
| 4018 cond, absent_failed); |
| 4019 } |
| 4020 |
| 4021 /* Build the runtime check. */ |
| 4022 argname = gfc_build_cstring_const (fsym->name); |
| 4023 argname = gfc_build_addr_expr (pchar_type_node, argname); |
| 4024 gfc_trans_runtime_check (true, false, cond, block, &fsym->declared_at, |
| 4025 message, argname, |
| 4026 fold_convert (long_integer_type_node, |
| 4027 cl->passed_length), |
| 4028 fold_convert (long_integer_type_node, |
| 4029 cl->backend_decl)); |
| 4030 } |
| 4031 } |
| 4032 |
| 4033 |
| 4034 static void |
| 4035 create_main_function (tree fndecl) |
| 4036 { |
| 4037 tree old_context; |
| 4038 tree ftn_main; |
| 4039 tree tmp, decl, result_decl, argc, argv, typelist, arglist; |
| 4040 stmtblock_t body; |
| 4041 |
| 4042 old_context = current_function_decl; |
| 4043 |
| 4044 if (old_context) |
| 4045 { |
| 4046 push_function_context (); |
| 4047 saved_parent_function_decls = saved_function_decls; |
| 4048 saved_function_decls = NULL_TREE; |
| 4049 } |
| 4050 |
| 4051 /* main() function must be declared with global scope. */ |
| 4052 gcc_assert (current_function_decl == NULL_TREE); |
| 4053 |
| 4054 /* Declare the function. */ |
| 4055 tmp = build_function_type_list (integer_type_node, integer_type_node, |
| 4056 build_pointer_type (pchar_type_node), |
| 4057 NULL_TREE); |
| 4058 main_identifier_node = get_identifier ("main"); |
| 4059 ftn_main = build_decl (input_location, FUNCTION_DECL, |
| 4060 main_identifier_node, tmp); |
| 4061 DECL_EXTERNAL (ftn_main) = 0; |
| 4062 TREE_PUBLIC (ftn_main) = 1; |
| 4063 TREE_STATIC (ftn_main) = 1; |
| 4064 DECL_ATTRIBUTES (ftn_main) |
| 4065 = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE); |
| 4066 |
| 4067 /* Setup the result declaration (for "return 0"). */ |
| 4068 result_decl = build_decl (input_location, |
| 4069 RESULT_DECL, NULL_TREE, integer_type_node); |
| 4070 DECL_ARTIFICIAL (result_decl) = 1; |
| 4071 DECL_IGNORED_P (result_decl) = 1; |
| 4072 DECL_CONTEXT (result_decl) = ftn_main; |
| 4073 DECL_RESULT (ftn_main) = result_decl; |
| 4074 |
| 4075 pushdecl (ftn_main); |
| 4076 |
| 4077 /* Get the arguments. */ |
| 4078 |
| 4079 arglist = NULL_TREE; |
| 4080 typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main)); |
| 4081 |
| 4082 tmp = TREE_VALUE (typelist); |
| 4083 argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp); |
| 4084 DECL_CONTEXT (argc) = ftn_main; |
| 4085 DECL_ARG_TYPE (argc) = TREE_VALUE (typelist); |
| 4086 TREE_READONLY (argc) = 1; |
| 4087 gfc_finish_decl (argc); |
| 4088 arglist = chainon (arglist, argc); |
| 4089 |
| 4090 typelist = TREE_CHAIN (typelist); |
| 4091 tmp = TREE_VALUE (typelist); |
| 4092 argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp); |
| 4093 DECL_CONTEXT (argv) = ftn_main; |
| 4094 DECL_ARG_TYPE (argv) = TREE_VALUE (typelist); |
| 4095 TREE_READONLY (argv) = 1; |
| 4096 DECL_BY_REFERENCE (argv) = 1; |
| 4097 gfc_finish_decl (argv); |
| 4098 arglist = chainon (arglist, argv); |
| 4099 |
| 4100 DECL_ARGUMENTS (ftn_main) = arglist; |
| 4101 current_function_decl = ftn_main; |
| 4102 announce_function (ftn_main); |
| 4103 |
| 4104 rest_of_decl_compilation (ftn_main, 1, 0); |
| 4105 make_decl_rtl (ftn_main); |
| 4106 init_function_start (ftn_main); |
| 4107 pushlevel (0); |
| 4108 |
| 4109 gfc_init_block (&body); |
| 4110 |
| 4111 /* Call some libgfortran initialization routines, call then MAIN__(). */ |
| 4112 |
| 4113 /* Call _gfortran_set_args (argc, argv). */ |
| 4114 TREE_USED (argc) = 1; |
| 4115 TREE_USED (argv) = 1; |
| 4116 tmp = build_call_expr_loc (input_location, |
| 4117 gfor_fndecl_set_args, 2, argc, argv); |
| 4118 gfc_add_expr_to_block (&body, tmp); |
| 4119 |
| 4120 /* Add a call to set_options to set up the runtime library Fortran |
| 4121 language standard parameters. */ |
| 4122 { |
| 4123 tree array_type, array, var; |
| 4124 |
| 4125 /* Passing a new option to the library requires four modifications: |
| 4126 + add it to the tree_cons list below |
| 4127 + change the array size in the call to build_array_type |
| 4128 + change the first argument to the library call |
| 4129 gfor_fndecl_set_options |
| 4130 + modify the library (runtime/compile_options.c)! */ |
| 4131 |
| 4132 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4133 gfc_option.warn_std), NULL_TREE); |
| 4134 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4135 gfc_option.allow_std), array); |
| 4136 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, pedantic), |
| 4137 array); |
| 4138 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4139 gfc_option.flag_dump_core), array); |
| 4140 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4141 gfc_option.flag_backtrace), array); |
| 4142 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4143 gfc_option.flag_sign_zero), array); |
| 4144 |
| 4145 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4146 (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)), array); |
| 4147 |
| 4148 array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, |
| 4149 gfc_option.flag_range_check), array); |
| 4150 |
| 4151 array_type = build_array_type (integer_type_node, |
| 4152 build_index_type (build_int_cst (NULL_TREE, 7))); |
| 4153 array = build_constructor_from_list (array_type, nreverse (array)); |
| 4154 TREE_CONSTANT (array) = 1; |
| 4155 TREE_STATIC (array) = 1; |
| 4156 |
| 4157 /* Create a static variable to hold the jump table. */ |
| 4158 var = gfc_create_var (array_type, "options"); |
| 4159 TREE_CONSTANT (var) = 1; |
| 4160 TREE_STATIC (var) = 1; |
| 4161 TREE_READONLY (var) = 1; |
| 4162 DECL_INITIAL (var) = array; |
| 4163 var = gfc_build_addr_expr (build_pointer_type (integer_type_node), var); |
| 4164 |
| 4165 tmp = build_call_expr_loc (input_location, |
| 4166 gfor_fndecl_set_options, 2, |
| 4167 build_int_cst (integer_type_node, 8), var); |
| 4168 gfc_add_expr_to_block (&body, tmp); |
| 4169 } |
| 4170 |
| 4171 /* If -ffpe-trap option was provided, add a call to set_fpe so that |
| 4172 the library will raise a FPE when needed. */ |
| 4173 if (gfc_option.fpe != 0) |
| 4174 { |
| 4175 tmp = build_call_expr_loc (input_location, |
| 4176 gfor_fndecl_set_fpe, 1, |
| 4177 build_int_cst (integer_type_node, |
| 4178 gfc_option.fpe)); |
| 4179 gfc_add_expr_to_block (&body, tmp); |
| 4180 } |
| 4181 |
| 4182 /* If this is the main program and an -fconvert option was provided, |
| 4183 add a call to set_convert. */ |
| 4184 |
| 4185 if (gfc_option.convert != GFC_CONVERT_NATIVE) |
| 4186 { |
| 4187 tmp = build_call_expr_loc (input_location, |
| 4188 gfor_fndecl_set_convert, 1, |
| 4189 build_int_cst (integer_type_node, |
| 4190 gfc_option.convert)); |
| 4191 gfc_add_expr_to_block (&body, tmp); |
| 4192 } |
| 4193 |
| 4194 /* If this is the main program and an -frecord-marker option was provided, |
| 4195 add a call to set_record_marker. */ |
| 4196 |
| 4197 if (gfc_option.record_marker != 0) |
| 4198 { |
| 4199 tmp = build_call_expr_loc (input_location, |
| 4200 gfor_fndecl_set_record_marker, 1, |
| 4201 build_int_cst (integer_type_node, |
| 4202 gfc_option.record_marker)); |
| 4203 gfc_add_expr_to_block (&body, tmp); |
| 4204 } |
| 4205 |
| 4206 if (gfc_option.max_subrecord_length != 0) |
| 4207 { |
| 4208 tmp = build_call_expr_loc (input_location, |
| 4209 gfor_fndecl_set_max_subrecord_length, 1, |
| 4210 build_int_cst (integer_type_node, |
| 4211 gfc_option.max_subrecord_length)); |
| 4212 gfc_add_expr_to_block (&body, tmp); |
| 4213 } |
| 4214 |
| 4215 /* Call MAIN__(). */ |
| 4216 tmp = build_call_expr_loc (input_location, |
| 4217 fndecl, 0); |
| 4218 gfc_add_expr_to_block (&body, tmp); |
| 4219 |
| 4220 /* Mark MAIN__ as used. */ |
| 4221 TREE_USED (fndecl) = 1; |
| 4222 |
| 4223 /* "return 0". */ |
| 4224 tmp = fold_build2 (MODIFY_EXPR, integer_type_node, DECL_RESULT (ftn_main), |
| 4225 build_int_cst (integer_type_node, 0)); |
| 4226 tmp = build1_v (RETURN_EXPR, tmp); |
| 4227 gfc_add_expr_to_block (&body, tmp); |
| 4228 |
| 4229 |
| 4230 DECL_SAVED_TREE (ftn_main) = gfc_finish_block (&body); |
| 4231 decl = getdecls (); |
| 4232 |
| 4233 /* Finish off this function and send it for code generation. */ |
| 4234 poplevel (1, 0, 1); |
| 4235 BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main; |
| 4236 |
| 4237 DECL_SAVED_TREE (ftn_main) |
| 4238 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (ftn_main), |
| 4239 DECL_INITIAL (ftn_main)); |
| 4240 |
| 4241 /* Output the GENERIC tree. */ |
| 4242 dump_function (TDI_original, ftn_main); |
| 4243 |
| 4244 cgraph_finalize_function (ftn_main, true); |
| 4245 |
| 4246 if (old_context) |
| 4247 { |
| 4248 pop_function_context (); |
| 4249 saved_function_decls = saved_parent_function_decls; |
| 4250 } |
| 4251 current_function_decl = old_context; |
| 4252 } |
| 4253 |
| 4254 |
3692 /* Generate code for a function. */ | 4255 /* Generate code for a function. */ |
3693 | 4256 |
3694 void | 4257 void |
3695 gfc_generate_function_code (gfc_namespace * ns) | 4258 gfc_generate_function_code (gfc_namespace * ns) |
3696 { | 4259 { |
3697 tree fndecl; | 4260 tree fndecl; |
3698 tree old_context; | 4261 tree old_context; |
3699 tree decl; | 4262 tree decl; |
3700 tree tmp; | 4263 tree tmp; |
3701 tree tmp2; | 4264 tree tmp2; |
3702 stmtblock_t block; | 4265 stmtblock_t block; |
3703 stmtblock_t body; | 4266 stmtblock_t body; |
3704 tree result; | 4267 tree result; |
| 4268 tree recurcheckvar = NULL_TREE; |
3705 gfc_symbol *sym; | 4269 gfc_symbol *sym; |
3706 int rank; | 4270 int rank; |
| 4271 bool is_recursive; |
3707 | 4272 |
3708 sym = ns->proc_name; | 4273 sym = ns->proc_name; |
3709 | 4274 |
3710 /* Check that the frontend isn't still using this. */ | 4275 /* Check that the frontend isn't still using this. */ |
3711 gcc_assert (sym->tlink == NULL); | 4276 gcc_assert (sym->tlink == NULL); |
3712 sym->tlink = sym; | 4277 sym->tlink = sym; |
3713 | 4278 |
3714 /* Create the declaration for functions with global scope. */ | 4279 /* Create the declaration for functions with global scope. */ |
3715 if (!sym->backend_decl) | 4280 if (!sym->backend_decl) |
3716 gfc_create_function_decl (ns); | 4281 gfc_create_function_decl (ns); |
(...skipping 12 matching lines...) Expand all Loading... |
3729 | 4294 |
3730 gfc_init_block (&block); | 4295 gfc_init_block (&block); |
3731 | 4296 |
3732 if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER) | 4297 if (ns->entries && ns->proc_name->ts.type == BT_CHARACTER) |
3733 { | 4298 { |
3734 /* Copy length backend_decls to all entry point result | 4299 /* Copy length backend_decls to all entry point result |
3735 symbols. */ | 4300 symbols. */ |
3736 gfc_entry_list *el; | 4301 gfc_entry_list *el; |
3737 tree backend_decl; | 4302 tree backend_decl; |
3738 | 4303 |
3739 gfc_conv_const_charlen (ns->proc_name->ts.cl); | 4304 gfc_conv_const_charlen (ns->proc_name->ts.u.cl); |
3740 backend_decl = ns->proc_name->result->ts.cl->backend_decl; | 4305 backend_decl = ns->proc_name->result->ts.u.cl->backend_decl; |
3741 for (el = ns->entries; el; el = el->next) | 4306 for (el = ns->entries; el; el = el->next) |
3742 » el->sym->result->ts.cl->backend_decl = backend_decl; | 4307 » el->sym->result->ts.u.cl->backend_decl = backend_decl; |
3743 } | 4308 } |
3744 | 4309 |
3745 /* Translate COMMON blocks. */ | 4310 /* Translate COMMON blocks. */ |
3746 gfc_trans_common (ns); | 4311 gfc_trans_common (ns); |
3747 | 4312 |
3748 /* Null the parent fake result declaration if this namespace is | 4313 /* Null the parent fake result declaration if this namespace is |
3749 a module function or an external procedures. */ | 4314 a module function or an external procedures. */ |
3750 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE) | 4315 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE) |
3751 || ns->parent == NULL) | 4316 || ns->parent == NULL) |
3752 parent_fake_result_decl = NULL_TREE; | 4317 parent_fake_result_decl = NULL_TREE; |
3753 | 4318 |
3754 gfc_generate_contained_functions (ns); | 4319 gfc_generate_contained_functions (ns); |
3755 | 4320 |
| 4321 nonlocal_dummy_decls = NULL; |
| 4322 nonlocal_dummy_decl_pset = NULL; |
| 4323 |
3756 generate_local_vars (ns); | 4324 generate_local_vars (ns); |
3757 | 4325 |
3758 /* Keep the parent fake result declaration in module functions | 4326 /* Keep the parent fake result declaration in module functions |
3759 or external procedures. */ | 4327 or external procedures. */ |
3760 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE) | 4328 if ((ns->parent && ns->parent->proc_name->attr.flavor == FL_MODULE) |
3761 || ns->parent == NULL) | 4329 || ns->parent == NULL) |
3762 current_fake_result_decl = parent_fake_result_decl; | 4330 current_fake_result_decl = parent_fake_result_decl; |
3763 else | 4331 else |
3764 current_fake_result_decl = NULL_TREE; | 4332 current_fake_result_decl = NULL_TREE; |
3765 | 4333 |
3766 current_function_return_label = NULL; | 4334 current_function_return_label = NULL; |
3767 | 4335 |
3768 /* Now generate the code for the body of this function. */ | 4336 /* Now generate the code for the body of this function. */ |
3769 gfc_init_block (&body); | 4337 gfc_init_block (&body); |
3770 | 4338 |
3771 /* If this is the main program, add a call to set_options to set up the | 4339 is_recursive = sym->attr.recursive |
3772 runtime library Fortran language standard parameters. */ | 4340 » » || (sym->attr.entry_master |
3773 if (sym->attr.is_main_program) | 4341 » » && sym->ns->entries->sym->attr.recursive); |
3774 { | 4342 if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) |
3775 tree array_type, array, var; | 4343 » && !is_recursive |
| 4344 » && !gfc_option.flag_recursive) |
| 4345 { |
| 4346 char * msg; |
3776 | 4347 |
3777 /* Passing a new option to the library requires four modifications: | 4348 asprintf (&msg, "Recursive call to nonrecursive procedure '%s'", |
3778 » + add it to the tree_cons list below | 4349 » » sym->name); |
3779 » + change the array size in the call to build_array_type | 4350 recurcheckvar = gfc_create_var (boolean_type_node, "is_recursive"); |
3780 » + change the first argument to the library call | 4351 TREE_STATIC (recurcheckvar) = 1; |
3781 » gfor_fndecl_set_options | 4352 DECL_INITIAL (recurcheckvar) = boolean_false_node; |
3782 » + modify the library (runtime/compile_options.c)! */ | 4353 gfc_add_expr_to_block (&block, recurcheckvar); |
3783 array = tree_cons (NULL_TREE, | 4354 gfc_trans_runtime_check (true, false, recurcheckvar, &block, |
3784 » » » build_int_cst (integer_type_node, | 4355 » » » » &sym->declared_at, msg); |
3785 » » » » » gfc_option.warn_std), NULL_TREE); | 4356 gfc_add_modify (&block, recurcheckvar, boolean_true_node); |
3786 array = tree_cons (NULL_TREE, | 4357 gfc_free (msg); |
3787 » » » build_int_cst (integer_type_node, | |
3788 » » » » » gfc_option.allow_std), array); | |
3789 array = tree_cons (NULL_TREE, | |
3790 » » » build_int_cst (integer_type_node, pedantic), array); | |
3791 array = tree_cons (NULL_TREE, | |
3792 » » » build_int_cst (integer_type_node, | |
3793 » » » » » gfc_option.flag_dump_core), array); | |
3794 array = tree_cons (NULL_TREE, | |
3795 » » » build_int_cst (integer_type_node, | |
3796 » » » » » gfc_option.flag_backtrace), array); | |
3797 array = tree_cons (NULL_TREE, | |
3798 » » » build_int_cst (integer_type_node, | |
3799 » » » » » gfc_option.flag_sign_zero), array); | |
3800 | |
3801 array = tree_cons (NULL_TREE, | |
3802 » » » build_int_cst (integer_type_node, | |
3803 » » » » » flag_bounds_check), array); | |
3804 | |
3805 array = tree_cons (NULL_TREE, | |
3806 » » » build_int_cst (integer_type_node, | |
3807 » » » » » gfc_option.flag_range_check), array); | |
3808 | |
3809 array_type = build_array_type (integer_type_node, | |
3810 » » » » build_index_type (build_int_cst (NULL_TREE, | |
3811 » » » » » » » » 7))); | |
3812 array = build_constructor_from_list (array_type, nreverse (array)); | |
3813 TREE_CONSTANT (array) = 1; | |
3814 TREE_STATIC (array) = 1; | |
3815 | |
3816 /* Create a static variable to hold the jump table. */ | |
3817 var = gfc_create_var (array_type, "options"); | |
3818 TREE_CONSTANT (var) = 1; | |
3819 TREE_STATIC (var) = 1; | |
3820 TREE_READONLY (var) = 1; | |
3821 DECL_INITIAL (var) = array; | |
3822 var = gfc_build_addr_expr (pvoid_type_node, var); | |
3823 | |
3824 tmp = build_call_expr (gfor_fndecl_set_options, 2, | |
3825 » » » build_int_cst (integer_type_node, 8), var); | |
3826 gfc_add_expr_to_block (&body, tmp); | |
3827 } | |
3828 | |
3829 /* If this is the main program and a -ffpe-trap option was provided, | |
3830 add a call to set_fpe so that the library will raise a FPE when | |
3831 needed. */ | |
3832 if (sym->attr.is_main_program && gfc_option.fpe != 0) | |
3833 { | |
3834 tmp = build_call_expr (gfor_fndecl_set_fpe, 1, | |
3835 » » » build_int_cst (integer_type_node, | |
3836 » » » » » gfc_option.fpe)); | |
3837 gfc_add_expr_to_block (&body, tmp); | |
3838 } | |
3839 | |
3840 /* If this is the main program and an -fconvert option was provided, | |
3841 add a call to set_convert. */ | |
3842 | |
3843 if (sym->attr.is_main_program && gfc_option.convert != GFC_CONVERT_NATIVE) | |
3844 { | |
3845 tmp = build_call_expr (gfor_fndecl_set_convert, 1, | |
3846 » » » build_int_cst (integer_type_node, | |
3847 » » » » » gfc_option.convert)); | |
3848 gfc_add_expr_to_block (&body, tmp); | |
3849 } | |
3850 | |
3851 /* If this is the main program and an -frecord-marker option was provided, | |
3852 add a call to set_record_marker. */ | |
3853 | |
3854 if (sym->attr.is_main_program && gfc_option.record_marker != 0) | |
3855 { | |
3856 tmp = build_call_expr (gfor_fndecl_set_record_marker, 1, | |
3857 » » » build_int_cst (integer_type_node, | |
3858 » » » » » gfc_option.record_marker)); | |
3859 gfc_add_expr_to_block (&body, tmp); | |
3860 } | |
3861 | |
3862 if (sym->attr.is_main_program && gfc_option.max_subrecord_length != 0) | |
3863 { | |
3864 tmp = build_call_expr (gfor_fndecl_set_max_subrecord_length, | |
3865 » » » 1, | |
3866 » » » build_int_cst (integer_type_node, | |
3867 » » » » » gfc_option.max_subrecord_length)); | |
3868 gfc_add_expr_to_block (&body, tmp); | |
3869 } | 4358 } |
3870 | 4359 |
3871 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node | 4360 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node |
3872 && sym->attr.subroutine) | 4361 && sym->attr.subroutine) |
3873 { | 4362 { |
3874 tree alternate_return; | 4363 tree alternate_return; |
3875 alternate_return = gfc_get_fake_result_decl (sym, 0); | 4364 alternate_return = gfc_get_fake_result_decl (sym, 0); |
3876 gfc_add_modify (&body, alternate_return, integer_zero_node); | 4365 gfc_add_modify (&body, alternate_return, integer_zero_node); |
3877 } | 4366 } |
3878 | 4367 |
3879 if (ns->entries) | 4368 if (ns->entries) |
3880 { | 4369 { |
3881 /* Jump to the correct entry point. */ | 4370 /* Jump to the correct entry point. */ |
3882 tmp = gfc_trans_entry_master_switch (ns->entries); | 4371 tmp = gfc_trans_entry_master_switch (ns->entries); |
3883 gfc_add_expr_to_block (&body, tmp); | 4372 gfc_add_expr_to_block (&body, tmp); |
3884 } | 4373 } |
3885 | 4374 |
| 4375 /* If bounds-checking is enabled, generate code to check passed in actual |
| 4376 arguments against the expected dummy argument attributes (e.g. string |
| 4377 lengths). */ |
| 4378 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && !sym->attr.is_bind_c) |
| 4379 add_argument_checking (&body, sym); |
| 4380 |
3886 tmp = gfc_trans_code (ns->code); | 4381 tmp = gfc_trans_code (ns->code); |
3887 gfc_add_expr_to_block (&body, tmp); | 4382 gfc_add_expr_to_block (&body, tmp); |
3888 | 4383 |
3889 /* Add a return label if needed. */ | 4384 /* Add a return label if needed. */ |
3890 if (current_function_return_label) | 4385 if (current_function_return_label) |
3891 { | 4386 { |
3892 tmp = build1_v (LABEL_EXPR, current_function_return_label); | 4387 tmp = build1_v (LABEL_EXPR, current_function_return_label); |
3893 gfc_add_expr_to_block (&body, tmp); | 4388 gfc_add_expr_to_block (&body, tmp); |
3894 } | 4389 } |
3895 | 4390 |
3896 tmp = gfc_finish_block (&body); | 4391 tmp = gfc_finish_block (&body); |
3897 /* Add code to create and cleanup arrays. */ | 4392 /* Add code to create and cleanup arrays. */ |
3898 tmp = gfc_trans_deferred_vars (sym, tmp); | 4393 tmp = gfc_trans_deferred_vars (sym, tmp); |
3899 | 4394 |
3900 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node) | 4395 if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node) |
3901 { | 4396 { |
3902 if (sym->attr.subroutine || sym == sym->result) | 4397 if (sym->attr.subroutine || sym == sym->result) |
3903 { | 4398 { |
3904 if (current_fake_result_decl != NULL) | 4399 if (current_fake_result_decl != NULL) |
3905 result = TREE_VALUE (current_fake_result_decl); | 4400 result = TREE_VALUE (current_fake_result_decl); |
3906 else | 4401 else |
3907 result = NULL_TREE; | 4402 result = NULL_TREE; |
3908 current_fake_result_decl = NULL_TREE; | 4403 current_fake_result_decl = NULL_TREE; |
3909 } | 4404 } |
3910 else | 4405 else |
3911 result = sym->result->backend_decl; | 4406 result = sym->result->backend_decl; |
3912 | 4407 |
3913 if (result != NULL_TREE && sym->attr.function | 4408 if (result != NULL_TREE |
3914 » && sym->ts.type == BT_DERIVED | 4409 » && sym->attr.function |
3915 » && sym->ts.derived->attr.alloc_comp | |
3916 && !sym->attr.pointer) | 4410 && !sym->attr.pointer) |
3917 { | 4411 { |
3918 » rank = sym->as ? sym->as->rank : 0; | 4412 » if (sym->ts.type == BT_DERIVED |
3919 » tmp2 = gfc_nullify_alloc_comp (sym->ts.derived, result, rank); | 4413 » && sym->ts.u.derived->attr.alloc_comp) |
3920 » gfc_add_expr_to_block (&block, tmp2); | 4414 » { |
| 4415 » rank = sym->as ? sym->as->rank : 0; |
| 4416 » tmp2 = gfc_nullify_alloc_comp (sym->ts.u.derived, result, rank); |
| 4417 » gfc_add_expr_to_block (&block, tmp2); |
| 4418 » } |
| 4419 » else if (sym->attr.allocatable && sym->attr.dimension == 0) |
| 4420 » gfc_add_modify (&block, result, fold_convert (TREE_TYPE (result), |
| 4421 » » » » » » » null_pointer_node)); |
3921 } | 4422 } |
3922 | 4423 |
3923 gfc_add_expr_to_block (&block, tmp); | 4424 gfc_add_expr_to_block (&block, tmp); |
3924 | 4425 |
| 4426 /* Reset recursion-check variable. */ |
| 4427 if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) |
| 4428 && !is_recursive |
| 4429 && !gfc_option.flag_openmp |
| 4430 && recurcheckvar != NULL_TREE) |
| 4431 { |
| 4432 gfc_add_modify (&block, recurcheckvar, boolean_false_node); |
| 4433 recurcheckvar = NULL; |
| 4434 } |
| 4435 |
3925 if (result == NULL_TREE) | 4436 if (result == NULL_TREE) |
3926 { | 4437 { |
3927 /* TODO: move to the appropriate place in resolve.c. */ | 4438 /* TODO: move to the appropriate place in resolve.c. */ |
3928 if (warn_return_type && !sym->attr.referenced && sym == sym->result) | 4439 if (warn_return_type && !sym->attr.referenced && sym == sym->result) |
3929 gfc_warning ("Return value of function '%s' at %L not set", | 4440 gfc_warning ("Return value of function '%s' at %L not set", |
3930 sym->name, &sym->declared_at); | 4441 sym->name, &sym->declared_at); |
3931 | 4442 |
3932 TREE_NO_WARNING(sym->backend_decl) = 1; | 4443 TREE_NO_WARNING(sym->backend_decl) = 1; |
3933 } | 4444 } |
3934 else | 4445 else |
3935 { | 4446 { |
3936 /* Set the return value to the dummy result variable. The | 4447 /* Set the return value to the dummy result variable. The |
3937 types may be different for scalar default REAL functions | 4448 types may be different for scalar default REAL functions |
3938 with -ff2c, therefore we have to convert. */ | 4449 with -ff2c, therefore we have to convert. */ |
3939 tmp = convert (TREE_TYPE (DECL_RESULT (fndecl)), result); | 4450 tmp = convert (TREE_TYPE (DECL_RESULT (fndecl)), result); |
3940 tmp = fold_build2 (MODIFY_EXPR, TREE_TYPE (tmp), | 4451 tmp = fold_build2 (MODIFY_EXPR, TREE_TYPE (tmp), |
3941 DECL_RESULT (fndecl), tmp); | 4452 DECL_RESULT (fndecl), tmp); |
3942 tmp = build1_v (RETURN_EXPR, tmp); | 4453 tmp = build1_v (RETURN_EXPR, tmp); |
3943 gfc_add_expr_to_block (&block, tmp); | 4454 gfc_add_expr_to_block (&block, tmp); |
3944 } | 4455 } |
3945 } | 4456 } |
3946 else | 4457 else |
3947 gfc_add_expr_to_block (&block, tmp); | 4458 { |
| 4459 gfc_add_expr_to_block (&block, tmp); |
| 4460 /* Reset recursion-check variable. */ |
| 4461 if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) |
| 4462 » && !is_recursive |
| 4463 » && !gfc_option.flag_openmp |
| 4464 » && recurcheckvar != NULL_TREE) |
| 4465 » { |
| 4466 » gfc_add_modify (&block, recurcheckvar, boolean_false_node); |
| 4467 » recurcheckvar = NULL_TREE; |
| 4468 » } |
| 4469 } |
3948 | 4470 |
3949 | 4471 |
3950 /* Add all the decls we created during processing. */ | 4472 /* Add all the decls we created during processing. */ |
3951 decl = saved_function_decls; | 4473 decl = saved_function_decls; |
3952 while (decl) | 4474 while (decl) |
3953 { | 4475 { |
3954 tree next; | 4476 tree next; |
3955 | 4477 |
3956 next = TREE_CHAIN (decl); | 4478 next = TREE_CHAIN (decl); |
3957 TREE_CHAIN (decl) = NULL_TREE; | 4479 TREE_CHAIN (decl) = NULL_TREE; |
3958 pushdecl (decl); | 4480 pushdecl (decl); |
3959 decl = next; | 4481 decl = next; |
3960 } | 4482 } |
3961 saved_function_decls = NULL_TREE; | 4483 saved_function_decls = NULL_TREE; |
3962 | 4484 |
3963 DECL_SAVED_TREE (fndecl) = gfc_finish_block (&block); | 4485 DECL_SAVED_TREE (fndecl) = gfc_finish_block (&block); |
3964 decl = getdecls (); | 4486 decl = getdecls (); |
3965 | 4487 |
3966 /* Finish off this function and send it for code generation. */ | 4488 /* Finish off this function and send it for code generation. */ |
3967 poplevel (1, 0, 1); | 4489 poplevel (1, 0, 1); |
3968 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; | 4490 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; |
3969 | 4491 |
3970 DECL_SAVED_TREE (fndecl) | 4492 DECL_SAVED_TREE (fndecl) |
3971 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), | 4493 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), |
3972 DECL_INITIAL (fndecl)); | 4494 DECL_INITIAL (fndecl)); |
3973 | 4495 |
| 4496 if (nonlocal_dummy_decls) |
| 4497 { |
| 4498 BLOCK_VARS (DECL_INITIAL (fndecl)) |
| 4499 = chainon (BLOCK_VARS (DECL_INITIAL (fndecl)), nonlocal_dummy_decls); |
| 4500 pointer_set_destroy (nonlocal_dummy_decl_pset); |
| 4501 nonlocal_dummy_decls = NULL; |
| 4502 nonlocal_dummy_decl_pset = NULL; |
| 4503 } |
| 4504 |
3974 /* Output the GENERIC tree. */ | 4505 /* Output the GENERIC tree. */ |
3975 dump_function (TDI_original, fndecl); | 4506 dump_function (TDI_original, fndecl); |
3976 | 4507 |
3977 /* Store the end of the function, so that we get good line number | 4508 /* Store the end of the function, so that we get good line number |
3978 info for the epilogue. */ | 4509 info for the epilogue. */ |
3979 cfun->function_end_locus = input_location; | 4510 cfun->function_end_locus = input_location; |
3980 | 4511 |
3981 /* We're leaving the context of this function, so zap cfun. | 4512 /* We're leaving the context of this function, so zap cfun. |
3982 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in | 4513 It's still in DECL_STRUCT_FUNCTION, and we'll restore it in |
3983 tree_rest_of_compilation. */ | 4514 tree_rest_of_compilation. */ |
3984 set_cfun (NULL); | 4515 set_cfun (NULL); |
3985 | 4516 |
3986 if (old_context) | 4517 if (old_context) |
3987 { | 4518 { |
3988 pop_function_context (); | 4519 pop_function_context (); |
3989 saved_function_decls = saved_parent_function_decls; | 4520 saved_function_decls = saved_parent_function_decls; |
3990 } | 4521 } |
3991 current_function_decl = old_context; | 4522 current_function_decl = old_context; |
3992 | 4523 |
3993 if (decl_function_context (fndecl)) | 4524 if (decl_function_context (fndecl)) |
3994 /* Register this function with cgraph just far enough to get it | 4525 /* Register this function with cgraph just far enough to get it |
3995 added to our parent's nested function list. */ | 4526 added to our parent's nested function list. */ |
3996 (void) cgraph_node (fndecl); | 4527 (void) cgraph_node (fndecl); |
3997 else | 4528 else |
3998 { | 4529 cgraph_finalize_function (fndecl, true); |
3999 gfc_gimplify_function (fndecl); | |
4000 cgraph_finalize_function (fndecl, false); | |
4001 } | |
4002 | 4530 |
4003 gfc_trans_use_stmts (ns); | 4531 gfc_trans_use_stmts (ns); |
4004 gfc_traverse_ns (ns, gfc_emit_parameter_debug_info); | 4532 gfc_traverse_ns (ns, gfc_emit_parameter_debug_info); |
| 4533 |
| 4534 if (sym->attr.is_main_program) |
| 4535 create_main_function (fndecl); |
4005 } | 4536 } |
4006 | 4537 |
| 4538 |
4007 void | 4539 void |
4008 gfc_generate_constructors (void) | 4540 gfc_generate_constructors (void) |
4009 { | 4541 { |
4010 gcc_assert (gfc_static_ctors == NULL_TREE); | 4542 gcc_assert (gfc_static_ctors == NULL_TREE); |
4011 #if 0 | 4543 #if 0 |
4012 tree fnname; | 4544 tree fnname; |
4013 tree type; | 4545 tree type; |
4014 tree fndecl; | 4546 tree fndecl; |
4015 tree decl; | 4547 tree decl; |
4016 tree tmp; | 4548 tree tmp; |
4017 | 4549 |
4018 if (gfc_static_ctors == NULL_TREE) | 4550 if (gfc_static_ctors == NULL_TREE) |
4019 return; | 4551 return; |
4020 | 4552 |
4021 fnname = get_file_function_name ("I"); | 4553 fnname = get_file_function_name ("I"); |
4022 type = build_function_type (void_type_node, | 4554 type = build_function_type (void_type_node, |
4023 gfc_chainon_list (NULL_TREE, void_type_node)); | 4555 gfc_chainon_list (NULL_TREE, void_type_node)); |
4024 | 4556 |
4025 fndecl = build_decl (FUNCTION_DECL, fnname, type); | 4557 fndecl = build_decl (input_location, |
| 4558 » » FUNCTION_DECL, fnname, type); |
4026 TREE_PUBLIC (fndecl) = 1; | 4559 TREE_PUBLIC (fndecl) = 1; |
4027 | 4560 |
4028 decl = build_decl (RESULT_DECL, NULL_TREE, void_type_node); | 4561 decl = build_decl (input_location, |
| 4562 » » RESULT_DECL, NULL_TREE, void_type_node); |
4029 DECL_ARTIFICIAL (decl) = 1; | 4563 DECL_ARTIFICIAL (decl) = 1; |
4030 DECL_IGNORED_P (decl) = 1; | 4564 DECL_IGNORED_P (decl) = 1; |
4031 DECL_CONTEXT (decl) = fndecl; | 4565 DECL_CONTEXT (decl) = fndecl; |
4032 DECL_RESULT (fndecl) = decl; | 4566 DECL_RESULT (fndecl) = decl; |
4033 | 4567 |
4034 pushdecl (fndecl); | 4568 pushdecl (fndecl); |
4035 | 4569 |
4036 current_function_decl = fndecl; | 4570 current_function_decl = fndecl; |
4037 | 4571 |
4038 rest_of_decl_compilation (fndecl, 1, 0); | 4572 rest_of_decl_compilation (fndecl, 1, 0); |
4039 | 4573 |
4040 make_decl_rtl (fndecl); | 4574 make_decl_rtl (fndecl); |
4041 | 4575 |
4042 init_function_start (fndecl); | 4576 init_function_start (fndecl); |
4043 | 4577 |
4044 pushlevel (0); | 4578 pushlevel (0); |
4045 | 4579 |
4046 for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors)) | 4580 for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors)) |
4047 { | 4581 { |
4048 tmp = build_call_expr (TREE_VALUE (gfc_static_ctors), 0); | 4582 tmp = build_call_expr_loc (input_location, |
4049 DECL_SAVED_TREE (fndecl) = build_stmt (EXPR_STMT, tmp); | 4583 » » » TREE_VALUE (gfc_static_ctors), 0); |
| 4584 DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp); |
4050 } | 4585 } |
4051 | 4586 |
4052 decl = getdecls (); | 4587 decl = getdecls (); |
4053 poplevel (1, 0, 1); | 4588 poplevel (1, 0, 1); |
4054 | 4589 |
4055 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; | 4590 BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; |
4056 DECL_SAVED_TREE (fndecl) | 4591 DECL_SAVED_TREE (fndecl) |
4057 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), | 4592 = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), |
4058 DECL_INITIAL (fndecl)); | 4593 DECL_INITIAL (fndecl)); |
4059 | 4594 |
(...skipping 27 matching lines...) Expand all Loading... |
4087 gfc_trans_common (ns); | 4622 gfc_trans_common (ns); |
4088 | 4623 |
4089 /* Create a global symbol with the mane of the block data. This is to | 4624 /* Create a global symbol with the mane of the block data. This is to |
4090 generate linker errors if the same name is used twice. It is never | 4625 generate linker errors if the same name is used twice. It is never |
4091 really used. */ | 4626 really used. */ |
4092 if (ns->proc_name) | 4627 if (ns->proc_name) |
4093 id = gfc_sym_mangled_function_id (ns->proc_name); | 4628 id = gfc_sym_mangled_function_id (ns->proc_name); |
4094 else | 4629 else |
4095 id = get_identifier ("__BLOCK_DATA__"); | 4630 id = get_identifier ("__BLOCK_DATA__"); |
4096 | 4631 |
4097 decl = build_decl (VAR_DECL, id, gfc_array_index_type); | 4632 decl = build_decl (input_location, |
| 4633 » » VAR_DECL, id, gfc_array_index_type); |
4098 TREE_PUBLIC (decl) = 1; | 4634 TREE_PUBLIC (decl) = 1; |
4099 TREE_STATIC (decl) = 1; | 4635 TREE_STATIC (decl) = 1; |
4100 DECL_IGNORED_P (decl) = 1; | 4636 DECL_IGNORED_P (decl) = 1; |
4101 | 4637 |
4102 pushdecl (decl); | 4638 pushdecl (decl); |
4103 rest_of_decl_compilation (decl, 1, 0); | 4639 rest_of_decl_compilation (decl, 1, 0); |
4104 } | 4640 } |
4105 | 4641 |
4106 | 4642 |
| 4643 /* Process the local variables of a BLOCK construct. */ |
| 4644 |
| 4645 void |
| 4646 gfc_process_block_locals (gfc_namespace* ns) |
| 4647 { |
| 4648 tree decl; |
| 4649 |
| 4650 gcc_assert (saved_local_decls == NULL_TREE); |
| 4651 generate_local_vars (ns); |
| 4652 |
| 4653 decl = saved_local_decls; |
| 4654 while (decl) |
| 4655 { |
| 4656 tree next; |
| 4657 |
| 4658 next = TREE_CHAIN (decl); |
| 4659 TREE_CHAIN (decl) = NULL_TREE; |
| 4660 pushdecl (decl); |
| 4661 decl = next; |
| 4662 } |
| 4663 saved_local_decls = NULL_TREE; |
| 4664 } |
| 4665 |
| 4666 |
4107 #include "gt-fortran-trans-decl.h" | 4667 #include "gt-fortran-trans-decl.h" |
OLD | NEW |