OLD | NEW |
1 /* Code translation -- generate GCC trees from gfc_code. | 1 /* Code translation -- generate GCC trees from gfc_code. |
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software | 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
3 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 |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
(...skipping 26 matching lines...) Expand all Loading... |
40 /* Naming convention for backend interface code: | 40 /* Naming convention for backend interface code: |
41 | 41 |
42 gfc_trans_* translate gfc_code into STMT trees. | 42 gfc_trans_* translate gfc_code into STMT trees. |
43 | 43 |
44 gfc_conv_* expression conversion | 44 gfc_conv_* expression conversion |
45 | 45 |
46 gfc_get_* get a backend tree representation of a decl or type */ | 46 gfc_get_* get a backend tree representation of a decl or type */ |
47 | 47 |
48 static gfc_file *gfc_current_backend_file; | 48 static gfc_file *gfc_current_backend_file; |
49 | 49 |
50 const char gfc_msg_bounds[] = N_("Array bound mismatch"); | |
51 const char gfc_msg_fault[] = N_("Array reference out of bounds"); | 50 const char gfc_msg_fault[] = N_("Array reference out of bounds"); |
52 const char gfc_msg_wrong_return[] = N_("Incorrect function return value"); | 51 const char gfc_msg_wrong_return[] = N_("Incorrect function return value"); |
53 | 52 |
54 | 53 |
55 /* Advance along TREE_CHAIN n times. */ | 54 /* Advance along TREE_CHAIN n times. */ |
56 | 55 |
57 tree | 56 tree |
58 gfc_advance_chain (tree t, int n) | 57 gfc_advance_chain (tree t, int n) |
59 { | 58 { |
60 for (; n > 0; n--) | 59 for (; n > 0; n--) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK. | 151 /* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK. |
153 A MODIFY_EXPR is an assignment: | 152 A MODIFY_EXPR is an assignment: |
154 LHS <- RHS. */ | 153 LHS <- RHS. */ |
155 | 154 |
156 void | 155 void |
157 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs) | 156 gfc_add_modify (stmtblock_t * pblock, tree lhs, tree rhs) |
158 { | 157 { |
159 tree tmp; | 158 tree tmp; |
160 | 159 |
161 #ifdef ENABLE_CHECKING | 160 #ifdef ENABLE_CHECKING |
| 161 tree t1, t2; |
| 162 t1 = TREE_TYPE (rhs); |
| 163 t2 = TREE_TYPE (lhs); |
162 /* Make sure that the types of the rhs and the lhs are the same | 164 /* Make sure that the types of the rhs and the lhs are the same |
163 for scalar assignments. We should probably have something | 165 for scalar assignments. We should probably have something |
164 similar for aggregates, but right now removing that check just | 166 similar for aggregates, but right now removing that check just |
165 breaks everything. */ | 167 breaks everything. */ |
166 gcc_assert (TREE_TYPE (rhs) == TREE_TYPE (lhs) | 168 gcc_assert (t1 == t2 |
167 || AGGREGATE_TYPE_P (TREE_TYPE (lhs))); | 169 || AGGREGATE_TYPE_P (TREE_TYPE (lhs))); |
168 #endif | 170 #endif |
169 | 171 |
170 tmp = fold_build2 (MODIFY_EXPR, void_type_node, lhs, rhs); | 172 tmp = fold_build2 (MODIFY_EXPR, void_type_node, lhs, rhs); |
171 gfc_add_expr_to_block (pblock, tmp); | 173 gfc_add_expr_to_block (pblock, tmp); |
172 } | 174 } |
173 | 175 |
174 | 176 |
175 /* Create a new scope/binding level and initialize a block. Care must be | 177 /* Create a new scope/binding level and initialize a block. Care must be |
176 taken when translating expressions as any temporaries will be placed in | 178 taken when translating expressions as any temporaries will be placed in |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 | 233 |
232 tree | 234 tree |
233 gfc_finish_block (stmtblock_t * stmtblock) | 235 gfc_finish_block (stmtblock_t * stmtblock) |
234 { | 236 { |
235 tree decl; | 237 tree decl; |
236 tree expr; | 238 tree expr; |
237 tree block; | 239 tree block; |
238 | 240 |
239 expr = stmtblock->head; | 241 expr = stmtblock->head; |
240 if (!expr) | 242 if (!expr) |
241 expr = build_empty_stmt (); | 243 expr = build_empty_stmt (input_location); |
242 | 244 |
243 stmtblock->head = NULL_TREE; | 245 stmtblock->head = NULL_TREE; |
244 | 246 |
245 if (stmtblock->has_scope) | 247 if (stmtblock->has_scope) |
246 { | 248 { |
247 decl = getdecls (); | 249 decl = getdecls (); |
248 | 250 |
249 if (decl) | 251 if (decl) |
250 { | 252 { |
251 block = poplevel (1, 0, 0); | 253 block = poplevel (1, 0, 0); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 288 |
287 if (TREE_CODE (t) == INDIRECT_REF) | 289 if (TREE_CODE (t) == INDIRECT_REF) |
288 { | 290 { |
289 if (!type) | 291 if (!type) |
290 type = natural_type; | 292 type = natural_type; |
291 t = TREE_OPERAND (t, 0); | 293 t = TREE_OPERAND (t, 0); |
292 natural_type = TREE_TYPE (t); | 294 natural_type = TREE_TYPE (t); |
293 } | 295 } |
294 else | 296 else |
295 { | 297 { |
296 if (DECL_P (t)) | 298 tree base = get_base_address (t); |
297 TREE_ADDRESSABLE (t) = 1; | 299 if (base && DECL_P (base)) |
| 300 TREE_ADDRESSABLE (base) = 1; |
298 t = fold_build1 (ADDR_EXPR, natural_type, t); | 301 t = fold_build1 (ADDR_EXPR, natural_type, t); |
299 } | 302 } |
300 | 303 |
301 if (type && natural_type != type) | 304 if (type && natural_type != type) |
302 t = convert (type, t); | 305 t = convert (type, t); |
303 | 306 |
304 return t; | 307 return t; |
305 } | 308 } |
306 | 309 |
307 | 310 |
(...skipping 23 matching lines...) Expand all Loading... |
331 && GFC_DECL_SUBREF_ARRAY_P (decl) | 334 && GFC_DECL_SUBREF_ARRAY_P (decl) |
332 && !integer_zerop (GFC_DECL_SPAN(decl))) | 335 && !integer_zerop (GFC_DECL_SPAN(decl))) |
333 { | 336 { |
334 offset = fold_build2 (MULT_EXPR, gfc_array_index_type, | 337 offset = fold_build2 (MULT_EXPR, gfc_array_index_type, |
335 offset, GFC_DECL_SPAN(decl)); | 338 offset, GFC_DECL_SPAN(decl)); |
336 tmp = gfc_build_addr_expr (pvoid_type_node, base); | 339 tmp = gfc_build_addr_expr (pvoid_type_node, base); |
337 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node, | 340 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node, |
338 tmp, fold_convert (sizetype, offset)); | 341 tmp, fold_convert (sizetype, offset)); |
339 tmp = fold_convert (build_pointer_type (type), tmp); | 342 tmp = fold_convert (build_pointer_type (type), tmp); |
340 if (!TYPE_STRING_FLAG (type)) | 343 if (!TYPE_STRING_FLAG (type)) |
341 » tmp = build_fold_indirect_ref (tmp); | 344 » tmp = build_fold_indirect_ref_loc (input_location, tmp); |
342 return tmp; | 345 return tmp; |
343 } | 346 } |
344 else | 347 else |
345 /* Otherwise use a straightforward array reference. */ | 348 /* Otherwise use a straightforward array reference. */ |
346 return build4 (ARRAY_REF, type, base, offset, NULL_TREE, NULL_TREE); | 349 return build4 (ARRAY_REF, type, base, offset, NULL_TREE, NULL_TREE); |
347 } | 350 } |
348 | 351 |
349 | 352 |
350 /* Generate a call to print a runtime error possibly including multiple | 353 /* Generate a call to print a runtime error possibly including multiple |
351 arguments and a locus. */ | 354 arguments and a locus. */ |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 408 |
406 /* Build the argument array. */ | 409 /* Build the argument array. */ |
407 argarray = (tree *) alloca (sizeof (tree) * (nargs + 2)); | 410 argarray = (tree *) alloca (sizeof (tree) * (nargs + 2)); |
408 argarray[0] = arg; | 411 argarray[0] = arg; |
409 argarray[1] = arg2; | 412 argarray[1] = arg2; |
410 for (i = 0; i < nargs; i++) | 413 for (i = 0; i < nargs; i++) |
411 argarray[2 + i] = va_arg (ap, tree); | 414 argarray[2 + i] = va_arg (ap, tree); |
412 va_end (ap); | 415 va_end (ap); |
413 | 416 |
414 /* Build the function call to runtime_(warning,error)_at; because of the | 417 /* Build the function call to runtime_(warning,error)_at; because of the |
415 variable number of arguments, we can't use build_call_expr directly. */ | 418 variable number of arguments, we can't use build_call_expr_loc dinput_locat
ion, |
| 419 irectly. */ |
416 if (error) | 420 if (error) |
417 fntype = TREE_TYPE (gfor_fndecl_runtime_error_at); | 421 fntype = TREE_TYPE (gfor_fndecl_runtime_error_at); |
418 else | 422 else |
419 fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at); | 423 fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at); |
420 | 424 |
421 tmp = fold_builtin_call_array (TREE_TYPE (fntype), | 425 tmp = fold_builtin_call_array (input_location, TREE_TYPE (fntype), |
422 fold_build1 (ADDR_EXPR, | 426 fold_build1 (ADDR_EXPR, |
423 build_pointer_type (fntype), | 427 build_pointer_type (fntype), |
424 error | 428 error |
425 ? gfor_fndecl_runtime_error_at | 429 ? gfor_fndecl_runtime_error_at |
426 : gfor_fndecl_runtime_warning_at), | 430 : gfor_fndecl_runtime_warning_at), |
427 nargs + 2, argarray); | 431 nargs + 2, argarray); |
428 gfc_add_expr_to_block (&block, tmp); | 432 gfc_add_expr_to_block (&block, tmp); |
429 | 433 |
430 return gfc_finish_block (&block); | 434 return gfc_finish_block (&block); |
431 } | 435 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 else | 478 else |
475 { | 479 { |
476 /* Tell the compiler that this isn't likely. */ | 480 /* Tell the compiler that this isn't likely. */ |
477 if (once) | 481 if (once) |
478 cond = fold_build2 (TRUTH_AND_EXPR, long_integer_type_node, tmpvar, | 482 cond = fold_build2 (TRUTH_AND_EXPR, long_integer_type_node, tmpvar, |
479 cond); | 483 cond); |
480 else | 484 else |
481 cond = fold_convert (long_integer_type_node, cond); | 485 cond = fold_convert (long_integer_type_node, cond); |
482 | 486 |
483 tmp = build_int_cst (long_integer_type_node, 0); | 487 tmp = build_int_cst (long_integer_type_node, 0); |
484 cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp); | 488 cond = build_call_expr_loc (input_location, |
| 489 » » » built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp); |
485 cond = fold_convert (boolean_type_node, cond); | 490 cond = fold_convert (boolean_type_node, cond); |
486 | 491 |
487 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ()); | 492 tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location)); |
488 gfc_add_expr_to_block (pblock, tmp); | 493 gfc_add_expr_to_block (pblock, tmp); |
489 } | 494 } |
490 } | 495 } |
491 | 496 |
492 | 497 |
493 /* Call malloc to allocate size bytes of memory, with special conditions: | 498 /* Call malloc to allocate size bytes of memory, with special conditions: |
494 + if size < 0, generate a runtime error, | 499 + if size <= 0, return a malloced area of size 1, |
495 + if size == 0, return a malloced area of size 1, | |
496 + if malloc returns NULL, issue a runtime error. */ | 500 + if malloc returns NULL, issue a runtime error. */ |
497 tree | 501 tree |
498 gfc_call_malloc (stmtblock_t * block, tree type, tree size) | 502 gfc_call_malloc (stmtblock_t * block, tree type, tree size) |
499 { | 503 { |
500 tree tmp, msg, negative, malloc_result, null_result, res; | 504 tree tmp, msg, malloc_result, null_result, res; |
501 stmtblock_t block2; | 505 stmtblock_t block2; |
502 | 506 |
503 size = gfc_evaluate_now (size, block); | 507 size = gfc_evaluate_now (size, block); |
504 | 508 |
505 if (TREE_TYPE (size) != TREE_TYPE (size_type_node)) | 509 if (TREE_TYPE (size) != TREE_TYPE (size_type_node)) |
506 size = fold_convert (size_type_node, size); | 510 size = fold_convert (size_type_node, size); |
507 | 511 |
508 /* Create a variable to hold the result. */ | 512 /* Create a variable to hold the result. */ |
509 res = gfc_create_var (pvoid_type_node, NULL); | 513 res = gfc_create_var (prvoid_type_node, NULL); |
510 | 514 |
511 /* size < 0 ? */ | 515 /* Call malloc. */ |
512 negative = fold_build2 (LT_EXPR, boolean_type_node, size, | |
513 » » » build_int_cst (size_type_node, 0)); | |
514 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const | |
515 ("Attempt to allocate a negative amount of memory.")); | |
516 tmp = fold_build3 (COND_EXPR, void_type_node, negative, | |
517 » » build_call_expr (gfor_fndecl_runtime_error, 1, msg), | |
518 » » build_empty_stmt ()); | |
519 gfc_add_expr_to_block (block, tmp); | |
520 | |
521 /* Call malloc and check the result. */ | |
522 gfc_start_block (&block2); | 516 gfc_start_block (&block2); |
523 | 517 |
524 size = fold_build2 (MAX_EXPR, size_type_node, size, | 518 size = fold_build2 (MAX_EXPR, size_type_node, size, |
525 build_int_cst (size_type_node, 1)); | 519 build_int_cst (size_type_node, 1)); |
526 | 520 |
527 gfc_add_modify (&block2, res, | 521 gfc_add_modify (&block2, res, |
528 » » build_call_expr (built_in_decls[BUILT_IN_MALLOC], 1, | 522 » » fold_convert (prvoid_type_node, |
529 » » size)); | 523 » » » » build_call_expr_loc (input_location, |
530 null_result = fold_build2 (EQ_EXPR, boolean_type_node, res, | 524 » » » » built_in_decls[BUILT_IN_MALLOC], 1, size))); |
531 » » » build_int_cst (pvoid_type_node, 0)); | 525 |
532 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const | 526 /* Optionally check whether malloc was successful. */ |
533 ("Memory allocation failed")); | 527 if (gfc_option.rtcheck & GFC_RTCHECK_MEM) |
534 tmp = fold_build3 (COND_EXPR, void_type_node, null_result, | 528 { |
535 » » build_call_expr (gfor_fndecl_os_error, 1, msg), | 529 null_result = fold_build2 (EQ_EXPR, boolean_type_node, res, |
536 » » build_empty_stmt ()); | 530 » » » » build_int_cst (pvoid_type_node, 0)); |
537 gfc_add_expr_to_block (&block2, tmp); | 531 msg = gfc_build_addr_expr (pchar_type_node, |
| 532 » gfc_build_localized_cstring_const ("Memory allocation failed")); |
| 533 tmp = fold_build3 (COND_EXPR, void_type_node, null_result, |
| 534 » build_call_expr_loc (input_location, |
| 535 » » » » gfor_fndecl_os_error, 1, msg), |
| 536 » » » » build_empty_stmt (input_location)); |
| 537 gfc_add_expr_to_block (&block2, tmp); |
| 538 } |
| 539 |
538 malloc_result = gfc_finish_block (&block2); | 540 malloc_result = gfc_finish_block (&block2); |
539 | 541 |
540 gfc_add_expr_to_block (block, malloc_result); | 542 gfc_add_expr_to_block (block, malloc_result); |
541 | 543 |
542 if (type != NULL) | 544 if (type != NULL) |
543 res = fold_convert (type, res); | 545 res = fold_convert (type, res); |
544 return res; | 546 return res; |
545 } | 547 } |
546 | 548 |
| 549 |
547 /* Allocate memory, using an optional status argument. | 550 /* Allocate memory, using an optional status argument. |
548 | 551 |
549 This function follows the following pseudo-code: | 552 This function follows the following pseudo-code: |
550 | 553 |
551 void * | 554 void * |
552 allocate (size_t size, integer_type* stat) | 555 allocate (size_t size, integer_type* stat) |
553 { | 556 { |
554 void *newmem; | 557 void *newmem; |
555 | 558 |
556 if (stat) | 559 if (stat) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 stmtblock_t alloc_block; | 591 stmtblock_t alloc_block; |
589 tree res, tmp, error, msg, cond; | 592 tree res, tmp, error, msg, cond; |
590 tree status_type = status ? TREE_TYPE (TREE_TYPE (status)) : NULL_TREE; | 593 tree status_type = status ? TREE_TYPE (TREE_TYPE (status)) : NULL_TREE; |
591 | 594 |
592 /* Evaluate size only once, and make sure it has the right type. */ | 595 /* Evaluate size only once, and make sure it has the right type. */ |
593 size = gfc_evaluate_now (size, block); | 596 size = gfc_evaluate_now (size, block); |
594 if (TREE_TYPE (size) != TREE_TYPE (size_type_node)) | 597 if (TREE_TYPE (size) != TREE_TYPE (size_type_node)) |
595 size = fold_convert (size_type_node, size); | 598 size = fold_convert (size_type_node, size); |
596 | 599 |
597 /* Create a variable to hold the result. */ | 600 /* Create a variable to hold the result. */ |
598 res = gfc_create_var (pvoid_type_node, NULL); | 601 res = gfc_create_var (prvoid_type_node, NULL); |
599 | 602 |
600 /* Set the optional status variable to zero. */ | 603 /* Set the optional status variable to zero. */ |
601 if (status != NULL_TREE && !integer_zerop (status)) | 604 if (status != NULL_TREE && !integer_zerop (status)) |
602 { | 605 { |
603 tmp = fold_build2 (MODIFY_EXPR, status_type, | 606 tmp = fold_build2 (MODIFY_EXPR, status_type, |
604 fold_build1 (INDIRECT_REF, status_type, status), | 607 fold_build1 (INDIRECT_REF, status_type, status), |
605 build_int_cst (status_type, 0)); | 608 build_int_cst (status_type, 0)); |
606 tmp = fold_build3 (COND_EXPR, void_type_node, | 609 tmp = fold_build3 (COND_EXPR, void_type_node, |
607 » » » fold_build2 (NE_EXPR, boolean_type_node, | 610 » » » fold_build2 (NE_EXPR, boolean_type_node, status, |
608 » » » » status, build_int_cst (status_type, 0)), | 611 » » » » build_int_cst (TREE_TYPE (status), 0)), |
609 » » » tmp, build_empty_stmt ()); | 612 » » » tmp, build_empty_stmt (input_location)); |
610 gfc_add_expr_to_block (block, tmp); | 613 gfc_add_expr_to_block (block, tmp); |
611 } | 614 } |
612 | 615 |
613 /* Generate the block of code handling (size < 0). */ | 616 /* Generate the block of code handling (size < 0). */ |
614 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const | 617 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const |
615 ("Attempt to allocate negative amount of memory. " | 618 ("Attempt to allocate negative amount of memory. " |
616 "Possible integer overflow")); | 619 "Possible integer overflow")); |
617 error = build_call_expr (gfor_fndecl_runtime_error, 1, msg); | 620 error = build_call_expr_loc (input_location, |
| 621 » » » gfor_fndecl_runtime_error, 1, msg); |
618 | 622 |
619 if (status != NULL_TREE && !integer_zerop (status)) | 623 if (status != NULL_TREE && !integer_zerop (status)) |
620 { | 624 { |
621 /* Set the status variable if it's present. */ | 625 /* Set the status variable if it's present. */ |
622 stmtblock_t set_status_block; | 626 stmtblock_t set_status_block; |
623 | 627 |
624 gfc_start_block (&set_status_block); | 628 gfc_start_block (&set_status_block); |
625 gfc_add_modify (&set_status_block, | 629 gfc_add_modify (&set_status_block, |
626 » » » fold_build1 (INDIRECT_REF, status_type, status), | 630 » » fold_build1 (INDIRECT_REF, status_type, status), |
627 build_int_cst (status_type, LIBERROR_ALLOCATION)); | 631 build_int_cst (status_type, LIBERROR_ALLOCATION)); |
628 gfc_add_modify (&set_status_block, res, | 632 gfc_add_modify (&set_status_block, res, |
629 » » » build_int_cst (pvoid_type_node, 0)); | 633 » » » build_int_cst (prvoid_type_node, 0)); |
630 | 634 |
631 tmp = fold_build2 (EQ_EXPR, boolean_type_node, status, | 635 tmp = fold_build2 (EQ_EXPR, boolean_type_node, status, |
632 » » » build_int_cst (status_type, 0)); | 636 » » » build_int_cst (TREE_TYPE (status), 0)); |
633 error = fold_build3 (COND_EXPR, void_type_node, tmp, error, | 637 error = fold_build3 (COND_EXPR, void_type_node, tmp, error, |
634 gfc_finish_block (&set_status_block)); | 638 gfc_finish_block (&set_status_block)); |
635 } | 639 } |
636 | 640 |
637 /* The allocation itself. */ | 641 /* The allocation itself. */ |
638 gfc_start_block (&alloc_block); | 642 gfc_start_block (&alloc_block); |
639 gfc_add_modify (&alloc_block, res, | 643 gfc_add_modify (&alloc_block, res, |
640 » » build_call_expr (built_in_decls[BUILT_IN_MALLOC], 1, | 644 » » fold_convert (prvoid_type_node, |
| 645 » » » » build_call_expr_loc (input_location, |
| 646 » » » » built_in_decls[BUILT_IN_MALLOC], 1, |
641 fold_build2 (MAX_EXPR, size_type_node, | 647 fold_build2 (MAX_EXPR, size_type_node, |
642 size, | 648 size, |
643 » » » » » » build_int_cst (size_type_no
de, 1)))); | 649 » » » » » » build_int_cst (size_type_no
de, 1))))); |
644 | 650 |
645 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const | 651 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const |
646 ("Out of memory")); | 652 ("Out of memory")); |
647 tmp = build_call_expr (gfor_fndecl_os_error, 1, msg); | 653 tmp = build_call_expr_loc (input_location, |
| 654 » » » gfor_fndecl_os_error, 1, msg); |
648 | 655 |
649 if (status != NULL_TREE && !integer_zerop (status)) | 656 if (status != NULL_TREE && !integer_zerop (status)) |
650 { | 657 { |
651 /* Set the status variable if it's present. */ | 658 /* Set the status variable if it's present. */ |
652 tree tmp2; | 659 tree tmp2; |
653 | 660 |
654 cond = fold_build2 (EQ_EXPR, boolean_type_node, status, | 661 cond = fold_build2 (EQ_EXPR, boolean_type_node, status, |
655 » » » build_int_cst (status_type, 0)); | 662 » » » build_int_cst (TREE_TYPE (status), 0)); |
656 tmp2 = fold_build2 (MODIFY_EXPR, status_type, | 663 tmp2 = fold_build2 (MODIFY_EXPR, status_type, |
657 fold_build1 (INDIRECT_REF, status_type, status), | 664 fold_build1 (INDIRECT_REF, status_type, status), |
658 build_int_cst (status_type, LIBERROR_ALLOCATION)); | 665 build_int_cst (status_type, LIBERROR_ALLOCATION)); |
659 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, | 666 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, |
660 tmp2); | 667 tmp2); |
661 } | 668 } |
662 | 669 |
663 tmp = fold_build3 (COND_EXPR, void_type_node, | 670 tmp = fold_build3 (COND_EXPR, void_type_node, |
664 fold_build2 (EQ_EXPR, boolean_type_node, res, | 671 fold_build2 (EQ_EXPR, boolean_type_node, res, |
665 » » » » build_int_cst (pvoid_type_node, 0)), | 672 » » » » build_int_cst (prvoid_type_node, 0)), |
666 » » tmp, build_empty_stmt ()); | 673 » » tmp, build_empty_stmt (input_location)); |
667 gfc_add_expr_to_block (&alloc_block, tmp); | 674 gfc_add_expr_to_block (&alloc_block, tmp); |
668 | 675 |
669 cond = fold_build2 (LT_EXPR, boolean_type_node, size, | 676 cond = fold_build2 (LT_EXPR, boolean_type_node, size, |
670 build_int_cst (TREE_TYPE (size), 0)); | 677 build_int_cst (TREE_TYPE (size), 0)); |
671 tmp = fold_build3 (COND_EXPR, void_type_node, cond, error, | 678 tmp = fold_build3 (COND_EXPR, void_type_node, cond, error, |
672 gfc_finish_block (&alloc_block)); | 679 gfc_finish_block (&alloc_block)); |
673 gfc_add_expr_to_block (block, tmp); | 680 gfc_add_expr_to_block (block, tmp); |
674 | 681 |
675 return res; | 682 return res; |
676 } | 683 } |
(...skipping 14 matching lines...) Expand all Loading... |
691 { | 698 { |
692 if (stat) | 699 if (stat) |
693 { | 700 { |
694 free (mem); | 701 free (mem); |
695 mem = allocate (size, stat); | 702 mem = allocate (size, stat); |
696 *stat = LIBERROR_ALLOCATION; | 703 *stat = LIBERROR_ALLOCATION; |
697 return mem; | 704 return mem; |
698 } | 705 } |
699 else | 706 else |
700 runtime_error ("Attempting to allocate already allocated array"); | 707 runtime_error ("Attempting to allocate already allocated array"); |
| 708 } |
701 } | 709 } |
702 | 710 |
703 expr must be set to the original expression being allocated for its locus | 711 expr must be set to the original expression being allocated for its locus |
704 and variable name in case a runtime error has to be printed. */ | 712 and variable name in case a runtime error has to be printed. */ |
705 tree | 713 tree |
706 gfc_allocate_array_with_status (stmtblock_t * block, tree mem, tree size, | 714 gfc_allocate_array_with_status (stmtblock_t * block, tree mem, tree size, |
707 tree status, gfc_expr* expr) | 715 tree status, gfc_expr* expr) |
708 { | 716 { |
709 stmtblock_t alloc_block; | 717 stmtblock_t alloc_block; |
710 tree res, tmp, null_mem, alloc, error; | 718 tree res, tmp, null_mem, alloc, error; |
711 tree type = TREE_TYPE (mem); | 719 tree type = TREE_TYPE (mem); |
712 | 720 |
713 if (TREE_TYPE (size) != TREE_TYPE (size_type_node)) | 721 if (TREE_TYPE (size) != TREE_TYPE (size_type_node)) |
714 size = fold_convert (size_type_node, size); | 722 size = fold_convert (size_type_node, size); |
715 | 723 |
716 /* Create a variable to hold the result. */ | 724 /* Create a variable to hold the result. */ |
717 res = gfc_create_var (pvoid_type_node, NULL); | 725 res = gfc_create_var (type, NULL); |
718 null_mem = fold_build2 (EQ_EXPR, boolean_type_node, mem, | 726 null_mem = fold_build2 (EQ_EXPR, boolean_type_node, mem, |
719 build_int_cst (type, 0)); | 727 build_int_cst (type, 0)); |
720 | 728 |
721 /* If mem is NULL, we call gfc_allocate_with_status. */ | 729 /* If mem is NULL, we call gfc_allocate_with_status. */ |
722 gfc_start_block (&alloc_block); | 730 gfc_start_block (&alloc_block); |
723 tmp = gfc_allocate_with_status (&alloc_block, size, status); | 731 tmp = gfc_allocate_with_status (&alloc_block, size, status); |
724 gfc_add_modify (&alloc_block, res, fold_convert (type, tmp)); | 732 gfc_add_modify (&alloc_block, res, fold_convert (type, tmp)); |
725 alloc = gfc_finish_block (&alloc_block); | 733 alloc = gfc_finish_block (&alloc_block); |
726 | 734 |
727 /* Otherwise, we issue a runtime error or set the status variable. */ | 735 /* Otherwise, we issue a runtime error or set the status variable. */ |
(...skipping 14 matching lines...) Expand all Loading... |
742 error = gfc_trans_runtime_error (true, NULL, | 750 error = gfc_trans_runtime_error (true, NULL, |
743 "Attempting to allocate already allocated" | 751 "Attempting to allocate already allocated" |
744 "array"); | 752 "array"); |
745 | 753 |
746 if (status != NULL_TREE && !integer_zerop (status)) | 754 if (status != NULL_TREE && !integer_zerop (status)) |
747 { | 755 { |
748 tree status_type = TREE_TYPE (TREE_TYPE (status)); | 756 tree status_type = TREE_TYPE (TREE_TYPE (status)); |
749 stmtblock_t set_status_block; | 757 stmtblock_t set_status_block; |
750 | 758 |
751 gfc_start_block (&set_status_block); | 759 gfc_start_block (&set_status_block); |
752 tmp = build_call_expr (built_in_decls[BUILT_IN_FREE], 1, | 760 tmp = build_call_expr_loc (input_location, |
| 761 » » » built_in_decls[BUILT_IN_FREE], 1, |
753 fold_convert (pvoid_type_node, mem)); | 762 fold_convert (pvoid_type_node, mem)); |
754 gfc_add_expr_to_block (&set_status_block, tmp); | 763 gfc_add_expr_to_block (&set_status_block, tmp); |
755 | 764 |
756 tmp = gfc_allocate_with_status (&set_status_block, size, status); | 765 tmp = gfc_allocate_with_status (&set_status_block, size, status); |
757 gfc_add_modify (&set_status_block, res, fold_convert (type, tmp)); | 766 gfc_add_modify (&set_status_block, res, fold_convert (type, tmp)); |
758 | 767 |
759 gfc_add_modify (&set_status_block, | 768 gfc_add_modify (&set_status_block, |
760 fold_build1 (INDIRECT_REF, status_type, status), | 769 fold_build1 (INDIRECT_REF, status_type, status), |
761 build_int_cst (status_type, LIBERROR_ALLOCATION)); | 770 build_int_cst (status_type, LIBERROR_ALLOCATION)); |
762 | 771 |
(...skipping 17 matching lines...) Expand all Loading... |
780 stmtblock_t block; | 789 stmtblock_t block; |
781 tree tmp, cond, call; | 790 tree tmp, cond, call; |
782 | 791 |
783 if (TREE_TYPE (var) != TREE_TYPE (pvoid_type_node)) | 792 if (TREE_TYPE (var) != TREE_TYPE (pvoid_type_node)) |
784 var = fold_convert (pvoid_type_node, var); | 793 var = fold_convert (pvoid_type_node, var); |
785 | 794 |
786 gfc_start_block (&block); | 795 gfc_start_block (&block); |
787 var = gfc_evaluate_now (var, &block); | 796 var = gfc_evaluate_now (var, &block); |
788 cond = fold_build2 (NE_EXPR, boolean_type_node, var, | 797 cond = fold_build2 (NE_EXPR, boolean_type_node, var, |
789 build_int_cst (pvoid_type_node, 0)); | 798 build_int_cst (pvoid_type_node, 0)); |
790 call = build_call_expr (built_in_decls[BUILT_IN_FREE], 1, var); | 799 call = build_call_expr_loc (input_location, |
| 800 » » » built_in_decls[BUILT_IN_FREE], 1, var); |
791 tmp = fold_build3 (COND_EXPR, void_type_node, cond, call, | 801 tmp = fold_build3 (COND_EXPR, void_type_node, cond, call, |
792 » » build_empty_stmt ()); | 802 » » build_empty_stmt (input_location)); |
793 gfc_add_expr_to_block (&block, tmp); | 803 gfc_add_expr_to_block (&block, tmp); |
794 | 804 |
795 return gfc_finish_block (&block); | 805 return gfc_finish_block (&block); |
796 } | 806 } |
797 | 807 |
798 | 808 |
799 | 809 |
800 /* User-deallocate; we emit the code directly from the front-end, and the | 810 /* User-deallocate; we emit the code directly from the front-end, and the |
801 logic is the same as the previous library function: | 811 logic is the same as the previous library function: |
802 | 812 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree); | 856 gcc_assert (expr && expr->expr_type == EXPR_VARIABLE && expr->symtree); |
847 | 857 |
848 varname = gfc_build_cstring_const (expr->symtree->name); | 858 varname = gfc_build_cstring_const (expr->symtree->name); |
849 varname = gfc_build_addr_expr (pchar_type_node, varname); | 859 varname = gfc_build_addr_expr (pchar_type_node, varname); |
850 | 860 |
851 error = gfc_trans_runtime_error (true, &expr->where, | 861 error = gfc_trans_runtime_error (true, &expr->where, |
852 "Attempt to DEALLOCATE unallocated '%s'", | 862 "Attempt to DEALLOCATE unallocated '%s'", |
853 varname); | 863 varname); |
854 } | 864 } |
855 else | 865 else |
856 error = build_empty_stmt (); | 866 error = build_empty_stmt (input_location); |
857 | 867 |
858 if (status != NULL_TREE && !integer_zerop (status)) | 868 if (status != NULL_TREE && !integer_zerop (status)) |
859 { | 869 { |
860 tree status_type = TREE_TYPE (TREE_TYPE (status)); | 870 tree status_type = TREE_TYPE (TREE_TYPE (status)); |
861 tree cond2; | 871 tree cond2; |
862 | 872 |
863 cond2 = fold_build2 (NE_EXPR, boolean_type_node, status, | 873 cond2 = fold_build2 (NE_EXPR, boolean_type_node, status, |
864 build_int_cst (TREE_TYPE (status), 0)); | 874 build_int_cst (TREE_TYPE (status), 0)); |
865 tmp = fold_build2 (MODIFY_EXPR, status_type, | 875 tmp = fold_build2 (MODIFY_EXPR, status_type, |
866 fold_build1 (INDIRECT_REF, status_type, status), | 876 fold_build1 (INDIRECT_REF, status_type, status), |
867 build_int_cst (status_type, 1)); | 877 build_int_cst (status_type, 1)); |
868 error = fold_build3 (COND_EXPR, void_type_node, cond2, tmp, error); | 878 error = fold_build3 (COND_EXPR, void_type_node, cond2, tmp, error); |
869 } | 879 } |
870 | 880 |
871 gfc_add_expr_to_block (&null, error); | 881 gfc_add_expr_to_block (&null, error); |
872 | 882 |
873 /* When POINTER is not NULL, we free it. */ | 883 /* When POINTER is not NULL, we free it. */ |
874 gfc_start_block (&non_null); | 884 gfc_start_block (&non_null); |
875 tmp = build_call_expr (built_in_decls[BUILT_IN_FREE], 1, | 885 tmp = build_call_expr_loc (input_location, |
| 886 » » » built_in_decls[BUILT_IN_FREE], 1, |
876 fold_convert (pvoid_type_node, pointer)); | 887 fold_convert (pvoid_type_node, pointer)); |
877 gfc_add_expr_to_block (&non_null, tmp); | 888 gfc_add_expr_to_block (&non_null, tmp); |
878 | 889 |
879 if (status != NULL_TREE && !integer_zerop (status)) | 890 if (status != NULL_TREE && !integer_zerop (status)) |
880 { | 891 { |
881 /* We set STATUS to zero if it is present. */ | 892 /* We set STATUS to zero if it is present. */ |
882 tree status_type = TREE_TYPE (TREE_TYPE (status)); | 893 tree status_type = TREE_TYPE (TREE_TYPE (status)); |
883 tree cond2; | 894 tree cond2; |
884 | 895 |
885 cond2 = fold_build2 (NE_EXPR, boolean_type_node, status, | 896 cond2 = fold_build2 (NE_EXPR, boolean_type_node, status, |
886 build_int_cst (TREE_TYPE (status), 0)); | 897 build_int_cst (TREE_TYPE (status), 0)); |
887 tmp = fold_build2 (MODIFY_EXPR, status_type, | 898 tmp = fold_build2 (MODIFY_EXPR, status_type, |
888 fold_build1 (INDIRECT_REF, status_type, status), | 899 fold_build1 (INDIRECT_REF, status_type, status), |
889 build_int_cst (status_type, 0)); | 900 build_int_cst (status_type, 0)); |
890 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp, | 901 tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp, |
891 » » » build_empty_stmt ()); | 902 » » » build_empty_stmt (input_location)); |
892 gfc_add_expr_to_block (&non_null, tmp); | 903 gfc_add_expr_to_block (&non_null, tmp); |
893 } | 904 } |
894 | 905 |
895 return fold_build3 (COND_EXPR, void_type_node, cond, | 906 return fold_build3 (COND_EXPR, void_type_node, cond, |
896 gfc_finish_block (&null), gfc_finish_block (&non_null)); | 907 gfc_finish_block (&null), gfc_finish_block (&non_null)); |
897 } | 908 } |
898 | 909 |
899 | 910 |
900 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the | 911 /* Reallocate MEM so it has SIZE bytes of data. This behaves like the |
901 following pseudo-code: | 912 following pseudo-code: |
(...skipping 25 matching lines...) Expand all Loading... |
927 | 938 |
928 /* Create a variable to hold the result. */ | 939 /* Create a variable to hold the result. */ |
929 res = gfc_create_var (type, NULL); | 940 res = gfc_create_var (type, NULL); |
930 | 941 |
931 /* size < 0 ? */ | 942 /* size < 0 ? */ |
932 negative = fold_build2 (LT_EXPR, boolean_type_node, size, | 943 negative = fold_build2 (LT_EXPR, boolean_type_node, size, |
933 build_int_cst (size_type_node, 0)); | 944 build_int_cst (size_type_node, 0)); |
934 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const | 945 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const |
935 ("Attempt to allocate a negative amount of memory.")); | 946 ("Attempt to allocate a negative amount of memory.")); |
936 tmp = fold_build3 (COND_EXPR, void_type_node, negative, | 947 tmp = fold_build3 (COND_EXPR, void_type_node, negative, |
937 » » build_call_expr (gfor_fndecl_runtime_error, 1, msg), | 948 » » build_call_expr_loc (input_location, |
938 » » build_empty_stmt ()); | 949 » » » » gfor_fndecl_runtime_error, 1, msg), |
| 950 » » build_empty_stmt (input_location)); |
939 gfc_add_expr_to_block (block, tmp); | 951 gfc_add_expr_to_block (block, tmp); |
940 | 952 |
941 /* Call realloc and check the result. */ | 953 /* Call realloc and check the result. */ |
942 tmp = build_call_expr (built_in_decls[BUILT_IN_REALLOC], 2, | 954 tmp = build_call_expr_loc (input_location, |
| 955 » » » built_in_decls[BUILT_IN_REALLOC], 2, |
943 fold_convert (pvoid_type_node, mem), size); | 956 fold_convert (pvoid_type_node, mem), size); |
944 gfc_add_modify (block, res, fold_convert (type, tmp)); | 957 gfc_add_modify (block, res, fold_convert (type, tmp)); |
945 null_result = fold_build2 (EQ_EXPR, boolean_type_node, res, | 958 null_result = fold_build2 (EQ_EXPR, boolean_type_node, res, |
946 build_int_cst (pvoid_type_node, 0)); | 959 build_int_cst (pvoid_type_node, 0)); |
947 nonzero = fold_build2 (NE_EXPR, boolean_type_node, size, | 960 nonzero = fold_build2 (NE_EXPR, boolean_type_node, size, |
948 build_int_cst (size_type_node, 0)); | 961 build_int_cst (size_type_node, 0)); |
949 null_result = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, null_result, | 962 null_result = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, null_result, |
950 nonzero); | 963 nonzero); |
951 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const | 964 msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const |
952 ("Out of memory")); | 965 ("Out of memory")); |
953 tmp = fold_build3 (COND_EXPR, void_type_node, null_result, | 966 tmp = fold_build3 (COND_EXPR, void_type_node, null_result, |
954 » » build_call_expr (gfor_fndecl_os_error, 1, msg), | 967 » » build_call_expr_loc (input_location, |
955 » » build_empty_stmt ()); | 968 » » » » gfor_fndecl_os_error, 1, msg), |
| 969 » » build_empty_stmt (input_location)); |
956 gfc_add_expr_to_block (block, tmp); | 970 gfc_add_expr_to_block (block, tmp); |
957 | 971 |
958 /* if (size == 0) then the result is NULL. */ | 972 /* if (size == 0) then the result is NULL. */ |
959 tmp = fold_build2 (MODIFY_EXPR, type, res, build_int_cst (type, 0)); | 973 tmp = fold_build2 (MODIFY_EXPR, type, res, build_int_cst (type, 0)); |
960 zero = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, nonzero); | 974 zero = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, nonzero); |
961 tmp = fold_build3 (COND_EXPR, void_type_node, zero, tmp, | 975 tmp = fold_build3 (COND_EXPR, void_type_node, zero, tmp, |
962 » » build_empty_stmt ()); | 976 » » build_empty_stmt (input_location)); |
963 gfc_add_expr_to_block (block, tmp); | 977 gfc_add_expr_to_block (block, tmp); |
964 | 978 |
965 return res; | 979 return res; |
966 } | 980 } |
967 | 981 |
968 /* Add a statement to a block. */ | 982 /* Add a statement to a block. */ |
969 | 983 |
970 void | 984 void |
971 gfc_add_expr_to_block (stmtblock_t * block, tree expr) | 985 gfc_add_expr_to_block (stmtblock_t * block, tree expr) |
972 { | 986 { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 /* Set the current locus. */ | 1035 /* Set the current locus. */ |
1022 | 1036 |
1023 void | 1037 void |
1024 gfc_set_backend_locus (locus * loc) | 1038 gfc_set_backend_locus (locus * loc) |
1025 { | 1039 { |
1026 gfc_current_backend_file = loc->lb->file; | 1040 gfc_current_backend_file = loc->lb->file; |
1027 input_location = loc->lb->location; | 1041 input_location = loc->lb->location; |
1028 } | 1042 } |
1029 | 1043 |
1030 | 1044 |
1031 /* Translate an executable statement. */ | 1045 /* Translate an executable statement. The tree cond is used by gfc_trans_do. |
| 1046 This static function is wrapped by gfc_trans_code_cond and |
| 1047 gfc_trans_code. */ |
1032 | 1048 |
1033 tree | 1049 static tree |
1034 gfc_trans_code (gfc_code * code) | 1050 trans_code (gfc_code * code, tree cond) |
1035 { | 1051 { |
1036 stmtblock_t block; | 1052 stmtblock_t block; |
1037 tree res; | 1053 tree res; |
1038 | 1054 |
1039 if (!code) | 1055 if (!code) |
1040 return build_empty_stmt (); | 1056 return build_empty_stmt (input_location); |
1041 | 1057 |
1042 gfc_start_block (&block); | 1058 gfc_start_block (&block); |
1043 | 1059 |
1044 /* Translate statements one by one into GENERIC trees until we reach | 1060 /* Translate statements one by one into GENERIC trees until we reach |
1045 the end of this gfc_code branch. */ | 1061 the end of this gfc_code branch. */ |
1046 for (; code; code = code->next) | 1062 for (; code; code = code->next) |
1047 { | 1063 { |
1048 if (code->here != 0) | 1064 if (code->here != 0) |
1049 { | 1065 { |
1050 res = gfc_trans_label_here (code); | 1066 res = gfc_trans_label_here (code); |
1051 gfc_add_expr_to_block (&block, res); | 1067 gfc_add_expr_to_block (&block, res); |
1052 } | 1068 } |
1053 | 1069 |
1054 switch (code->op) | 1070 switch (code->op) |
1055 { | 1071 { |
1056 case EXEC_NOP: | 1072 case EXEC_NOP: |
| 1073 case EXEC_END_BLOCK: |
| 1074 case EXEC_END_PROCEDURE: |
1057 res = NULL_TREE; | 1075 res = NULL_TREE; |
1058 break; | 1076 break; |
1059 | 1077 |
1060 case EXEC_ASSIGN: | 1078 case EXEC_ASSIGN: |
1061 » res = gfc_trans_assign (code); | 1079 » if (code->expr1->ts.type == BT_CLASS) |
| 1080 » res = gfc_trans_class_assign (code); |
| 1081 » else |
| 1082 » res = gfc_trans_assign (code); |
1062 break; | 1083 break; |
1063 | 1084 |
1064 case EXEC_LABEL_ASSIGN: | 1085 case EXEC_LABEL_ASSIGN: |
1065 res = gfc_trans_label_assign (code); | 1086 res = gfc_trans_label_assign (code); |
1066 break; | 1087 break; |
1067 | 1088 |
1068 case EXEC_POINTER_ASSIGN: | 1089 case EXEC_POINTER_ASSIGN: |
1069 » res = gfc_trans_pointer_assign (code); | 1090 » if (code->expr1->ts.type == BT_CLASS) |
| 1091 » res = gfc_trans_class_assign (code); |
| 1092 » else |
| 1093 » res = gfc_trans_pointer_assign (code); |
1070 break; | 1094 break; |
1071 | 1095 |
1072 case EXEC_INIT_ASSIGN: | 1096 case EXEC_INIT_ASSIGN: |
1073 » res = gfc_trans_init_assign (code); | 1097 » if (code->expr1->ts.type == BT_CLASS) |
| 1098 » res = gfc_trans_class_assign (code); |
| 1099 » else |
| 1100 » res = gfc_trans_init_assign (code); |
1074 break; | 1101 break; |
1075 | 1102 |
1076 case EXEC_CONTINUE: | 1103 case EXEC_CONTINUE: |
1077 res = NULL_TREE; | 1104 res = NULL_TREE; |
1078 break; | 1105 break; |
1079 | 1106 |
1080 case EXEC_CYCLE: | 1107 case EXEC_CYCLE: |
1081 res = gfc_trans_cycle (code); | 1108 res = gfc_trans_cycle (code); |
1082 break; | 1109 break; |
1083 | 1110 |
(...skipping 23 matching lines...) Expand all Loading... |
1107 { | 1134 { |
1108 bool is_mvbits = false; | 1135 bool is_mvbits = false; |
1109 if (code->resolved_isym | 1136 if (code->resolved_isym |
1110 && code->resolved_isym->id == GFC_ISYM_MVBITS) | 1137 && code->resolved_isym->id == GFC_ISYM_MVBITS) |
1111 is_mvbits = true; | 1138 is_mvbits = true; |
1112 res = gfc_trans_call (code, is_mvbits, NULL_TREE, | 1139 res = gfc_trans_call (code, is_mvbits, NULL_TREE, |
1113 NULL_TREE, false); | 1140 NULL_TREE, false); |
1114 } | 1141 } |
1115 break; | 1142 break; |
1116 | 1143 |
| 1144 case EXEC_CALL_PPC: |
| 1145 res = gfc_trans_call (code, false, NULL_TREE, |
| 1146 NULL_TREE, false); |
| 1147 break; |
| 1148 |
1117 case EXEC_ASSIGN_CALL: | 1149 case EXEC_ASSIGN_CALL: |
1118 res = gfc_trans_call (code, true, NULL_TREE, | 1150 res = gfc_trans_call (code, true, NULL_TREE, |
1119 NULL_TREE, false); | 1151 NULL_TREE, false); |
1120 break; | 1152 break; |
1121 | 1153 |
1122 case EXEC_RETURN: | 1154 case EXEC_RETURN: |
1123 res = gfc_trans_return (code); | 1155 res = gfc_trans_return (code); |
1124 break; | 1156 break; |
1125 | 1157 |
1126 case EXEC_IF: | 1158 case EXEC_IF: |
1127 res = gfc_trans_if (code); | 1159 res = gfc_trans_if (code); |
1128 break; | 1160 break; |
1129 | 1161 |
1130 case EXEC_ARITHMETIC_IF: | 1162 case EXEC_ARITHMETIC_IF: |
1131 res = gfc_trans_arithmetic_if (code); | 1163 res = gfc_trans_arithmetic_if (code); |
1132 break; | 1164 break; |
1133 | 1165 |
| 1166 case EXEC_BLOCK: |
| 1167 res = gfc_trans_block_construct (code); |
| 1168 break; |
| 1169 |
1134 case EXEC_DO: | 1170 case EXEC_DO: |
1135 » res = gfc_trans_do (code); | 1171 » res = gfc_trans_do (code, cond); |
1136 break; | 1172 break; |
1137 | 1173 |
1138 case EXEC_DO_WHILE: | 1174 case EXEC_DO_WHILE: |
1139 res = gfc_trans_do_while (code); | 1175 res = gfc_trans_do_while (code); |
1140 break; | 1176 break; |
1141 | 1177 |
1142 case EXEC_SELECT: | 1178 case EXEC_SELECT: |
1143 res = gfc_trans_select (code); | 1179 res = gfc_trans_select (code); |
1144 break; | 1180 break; |
1145 | 1181 |
| 1182 case EXEC_SELECT_TYPE: |
| 1183 /* Do nothing. SELECT TYPE statements should be transformed into |
| 1184 an ordinary SELECT CASE at resolution stage. |
| 1185 TODO: Add an error message here once this is done. */ |
| 1186 res = NULL_TREE; |
| 1187 break; |
| 1188 |
1146 case EXEC_FLUSH: | 1189 case EXEC_FLUSH: |
1147 res = gfc_trans_flush (code); | 1190 res = gfc_trans_flush (code); |
1148 break; | 1191 break; |
1149 | 1192 |
1150 case EXEC_FORALL: | 1193 case EXEC_FORALL: |
1151 res = gfc_trans_forall (code); | 1194 res = gfc_trans_forall (code); |
1152 break; | 1195 break; |
1153 | 1196 |
1154 case EXEC_WHERE: | 1197 case EXEC_WHERE: |
1155 res = gfc_trans_where (code); | 1198 res = gfc_trans_where (code); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 break; | 1274 break; |
1232 | 1275 |
1233 default: | 1276 default: |
1234 internal_error ("gfc_trans_code(): Bad statement code"); | 1277 internal_error ("gfc_trans_code(): Bad statement code"); |
1235 } | 1278 } |
1236 | 1279 |
1237 gfc_set_backend_locus (&code->loc); | 1280 gfc_set_backend_locus (&code->loc); |
1238 | 1281 |
1239 if (res != NULL_TREE && ! IS_EMPTY_STMT (res)) | 1282 if (res != NULL_TREE && ! IS_EMPTY_STMT (res)) |
1240 { | 1283 { |
1241 » if (TREE_CODE (res) == STATEMENT_LIST) | 1284 » if (TREE_CODE (res) != STATEMENT_LIST) |
1242 » tree_annotate_all_with_location (&res, input_location); | |
1243 » else | |
1244 SET_EXPR_LOCATION (res, input_location); | 1285 SET_EXPR_LOCATION (res, input_location); |
1245 | 1286 |
1246 /* Add the new statement to the block. */ | 1287 /* Add the new statement to the block. */ |
1247 gfc_add_expr_to_block (&block, res); | 1288 gfc_add_expr_to_block (&block, res); |
1248 } | 1289 } |
1249 } | 1290 } |
1250 | 1291 |
1251 /* Return the finished block. */ | 1292 /* Return the finished block. */ |
1252 return gfc_finish_block (&block); | 1293 return gfc_finish_block (&block); |
1253 } | 1294 } |
1254 | 1295 |
1255 | 1296 |
| 1297 /* Translate an executable statement with condition, cond. The condition is |
| 1298 used by gfc_trans_do to test for IO result conditions inside implied |
| 1299 DO loops of READ and WRITE statements. See build_dt in trans-io.c. */ |
| 1300 |
| 1301 tree |
| 1302 gfc_trans_code_cond (gfc_code * code, tree cond) |
| 1303 { |
| 1304 return trans_code (code, cond); |
| 1305 } |
| 1306 |
| 1307 /* Translate an executable statement without condition. */ |
| 1308 |
| 1309 tree |
| 1310 gfc_trans_code (gfc_code * code) |
| 1311 { |
| 1312 return trans_code (code, NULL_TREE); |
| 1313 } |
| 1314 |
| 1315 |
1256 /* This function is called after a complete program unit has been parsed | 1316 /* This function is called after a complete program unit has been parsed |
1257 and resolved. */ | 1317 and resolved. */ |
1258 | 1318 |
1259 void | 1319 void |
1260 gfc_generate_code (gfc_namespace * ns) | 1320 gfc_generate_code (gfc_namespace * ns) |
1261 { | 1321 { |
| 1322 ompws_flags = 0; |
1262 if (ns->is_block_data) | 1323 if (ns->is_block_data) |
1263 { | 1324 { |
1264 gfc_generate_block_data (ns); | 1325 gfc_generate_block_data (ns); |
1265 return; | 1326 return; |
1266 } | 1327 } |
1267 | 1328 |
1268 gfc_generate_function_code (ns); | 1329 gfc_generate_function_code (ns); |
1269 } | 1330 } |
1270 | 1331 |
1271 | 1332 |
1272 /* This function is called after a complete module has been parsed | 1333 /* This function is called after a complete module has been parsed |
1273 and resolved. */ | 1334 and resolved. */ |
1274 | 1335 |
1275 void | 1336 void |
1276 gfc_generate_module_code (gfc_namespace * ns) | 1337 gfc_generate_module_code (gfc_namespace * ns) |
1277 { | 1338 { |
1278 gfc_namespace *n; | 1339 gfc_namespace *n; |
1279 struct module_htab_entry *entry; | 1340 struct module_htab_entry *entry; |
1280 | 1341 |
1281 gcc_assert (ns->proc_name->backend_decl == NULL); | 1342 gcc_assert (ns->proc_name->backend_decl == NULL); |
1282 ns->proc_name->backend_decl | 1343 ns->proc_name->backend_decl |
1283 = build_decl (NAMESPACE_DECL, get_identifier (ns->proc_name->name), | 1344 = build_decl (ns->proc_name->declared_at.lb->location, |
| 1345 » » NAMESPACE_DECL, get_identifier (ns->proc_name->name), |
1284 void_type_node); | 1346 void_type_node); |
1285 gfc_set_decl_location (ns->proc_name->backend_decl, | |
1286 &ns->proc_name->declared_at); | |
1287 entry = gfc_find_module (ns->proc_name->name); | 1347 entry = gfc_find_module (ns->proc_name->name); |
1288 if (entry->namespace_decl) | 1348 if (entry->namespace_decl) |
1289 /* Buggy sourcecode, using a module before defining it? */ | 1349 /* Buggy sourcecode, using a module before defining it? */ |
1290 htab_empty (entry->decls); | 1350 htab_empty (entry->decls); |
1291 entry->namespace_decl = ns->proc_name->backend_decl; | 1351 entry->namespace_decl = ns->proc_name->backend_decl; |
1292 | 1352 |
1293 gfc_generate_module_vars (ns); | 1353 gfc_generate_module_vars (ns); |
1294 | 1354 |
1295 /* We need to generate all module function prototypes first, to allow | 1355 /* We need to generate all module function prototypes first, to allow |
1296 sibling calls. */ | 1356 sibling calls. */ |
(...skipping 18 matching lines...) Expand all Loading... |
1315 | 1375 |
1316 for (n = ns->contained; n; n = n->sibling) | 1376 for (n = ns->contained; n; n = n->sibling) |
1317 { | 1377 { |
1318 if (!n->proc_name) | 1378 if (!n->proc_name) |
1319 continue; | 1379 continue; |
1320 | 1380 |
1321 gfc_generate_function_code (n); | 1381 gfc_generate_function_code (n); |
1322 } | 1382 } |
1323 } | 1383 } |
1324 | 1384 |
OLD | NEW |