tree gfc_trans_code (gfc_code * code) { stmtblock_t block; tree res; if (!code) return build_empty_stmt (); gfc_start_block (&block); /* Translate statements one by one to GIMPLE trees until we reach the end of this gfc_code branch. */ for (; code; code = code->next) { if (code->here != 0) { res = gfc_trans_label_here (code); gfc_add_expr_to_block (&block, res); } switch (code->op) { case EXEC_NOP: res = NULL_TREE; break; case EXEC_ASSIGN: res = gfc_trans_assign (code); break; case EXEC_LABEL_ASSIGN: res = gfc_trans_label_assign (code); break; case EXEC_POINTER_ASSIGN: res = gfc_trans_pointer_assign (code); break; case EXEC_INIT_ASSIGN: res = gfc_trans_init_assign (code); break; case EXEC_CONTINUE: res = NULL_TREE; break; case EXEC_CYCLE: res = gfc_trans_cycle (code); break; case EXEC_EXIT: res = gfc_trans_exit (code); break; case EXEC_GOTO: res = gfc_trans_goto (code); break; case EXEC_ENTRY: res = gfc_trans_entry (code); break; case EXEC_PAUSE: res = gfc_trans_pause (code); break; case EXEC_STOP: res = gfc_trans_stop (code); break; case EXEC_CALL: res = gfc_trans_call (code, false); break; case EXEC_ASSIGN_CALL: res = gfc_trans_call (code, true); break; case EXEC_RETURN: res = gfc_trans_return (code); break; case EXEC_IF: res = gfc_trans_if (code); break; case EXEC_ARITHMETIC_IF: res = gfc_trans_arithmetic_if (code); break; case EXEC_DO: res = gfc_trans_do (code); break; case EXEC_DO_WHILE: res = gfc_trans_do_while (code); break; case EXEC_SELECT: res = gfc_trans_select (code); break; case EXEC_FLUSH: res = gfc_trans_flush (code); break; case EXEC_FORALL: res = gfc_trans_forall (code); break; case EXEC_WHERE: res = gfc_trans_where (code); break; case EXEC_ALLOCATE: res = gfc_trans_allocate (code); break; case EXEC_DEALLOCATE: res = gfc_trans_deallocate (code); break; case EXEC_OPEN: res = gfc_trans_open (code); break; case EXEC_CLOSE: res = gfc_trans_close (code); break; case EXEC_READ: res = gfc_trans_read (code); break; case EXEC_WRITE: res = gfc_trans_write (code); break; case EXEC_IOLENGTH: res = gfc_trans_iolength (code); break; case EXEC_BACKSPACE: res = gfc_trans_backspace (code); break; case EXEC_ENDFILE: res = gfc_trans_endfile (code); break; case EXEC_INQUIRE: res = gfc_trans_inquire (code); break; case EXEC_REWIND: res = gfc_trans_rewind (code); break; case EXEC_TRANSFER: res = gfc_trans_transfer (code); break; case EXEC_DT_END: res = gfc_trans_dt_end (code); break; case EXEC_OMP_ATOMIC: case EXEC_OMP_BARRIER: case EXEC_OMP_CRITICAL: case EXEC_OMP_DO: case EXEC_OMP_FLUSH: case EXEC_OMP_MASTER: case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SECTIONS: case EXEC_OMP_SINGLE: case EXEC_OMP_WORKSHARE: res = gfc_trans_omp_directive (code); break; default: internal_error ("gfc_trans_code(): Bad statement code"); } gfc_set_backend_locus (&code->loc); if (res != NULL_TREE && ! IS_EMPTY_STMT (res)) { if (TREE_CODE (res) == STATEMENT_LIST) annotate_all_with_locus (&res, input_location); else SET_EXPR_LOCATION (res, input_location); /* Add the new statement to the block. */ gfc_add_expr_to_block (&block, res); } } /* Return the finished block. */ return gfc_finish_block (&block); }
static tree trans_code (gfc_code * code, tree cond) { stmtblock_t block; tree res; if (!code) return build_empty_stmt (input_location); gfc_start_block (&block); /* Translate statements one by one into GENERIC trees until we reach the end of this gfc_code branch. */ for (; code; code = code->next) { if (code->here != 0) { res = gfc_trans_label_here (code); gfc_add_expr_to_block (&block, res); } gfc_set_backend_locus (&code->loc); switch (code->op) { case EXEC_NOP: case EXEC_END_BLOCK: case EXEC_END_NESTED_BLOCK: case EXEC_END_PROCEDURE: res = NULL_TREE; break; case EXEC_ASSIGN: if (code->expr1->ts.type == BT_CLASS) res = gfc_trans_class_assign (code->expr1, code->expr2, code->op); else res = gfc_trans_assign (code); break; case EXEC_LABEL_ASSIGN: res = gfc_trans_label_assign (code); break; case EXEC_POINTER_ASSIGN: if (code->expr1->ts.type == BT_CLASS) res = gfc_trans_class_assign (code->expr1, code->expr2, code->op); else res = gfc_trans_pointer_assign (code); break; case EXEC_INIT_ASSIGN: if (code->expr1->ts.type == BT_CLASS) res = gfc_trans_class_init_assign (code); else res = gfc_trans_init_assign (code); break; case EXEC_CONTINUE: res = NULL_TREE; break; case EXEC_CRITICAL: res = gfc_trans_critical (code); break; case EXEC_CYCLE: res = gfc_trans_cycle (code); break; case EXEC_EXIT: res = gfc_trans_exit (code); break; case EXEC_GOTO: res = gfc_trans_goto (code); break; case EXEC_ENTRY: res = gfc_trans_entry (code); break; case EXEC_PAUSE: res = gfc_trans_pause (code); break; case EXEC_STOP: case EXEC_ERROR_STOP: res = gfc_trans_stop (code, code->op == EXEC_ERROR_STOP); break; case EXEC_CALL: /* For MVBITS we've got the special exception that we need a dependency check, too. */ { bool is_mvbits = false; if (code->resolved_isym) { res = gfc_conv_intrinsic_subroutine (code); if (res != NULL_TREE) break; } if (code->resolved_isym && code->resolved_isym->id == GFC_ISYM_MVBITS) is_mvbits = true; res = gfc_trans_call (code, is_mvbits, NULL_TREE, NULL_TREE, false); } break; case EXEC_CALL_PPC: res = gfc_trans_call (code, false, NULL_TREE, NULL_TREE, false); break; case EXEC_ASSIGN_CALL: res = gfc_trans_call (code, true, NULL_TREE, NULL_TREE, false); break; case EXEC_RETURN: res = gfc_trans_return (code); break; case EXEC_IF: res = gfc_trans_if (code); break; case EXEC_ARITHMETIC_IF: res = gfc_trans_arithmetic_if (code); break; case EXEC_BLOCK: res = gfc_trans_block_construct (code); break; case EXEC_DO: res = gfc_trans_do (code, cond); break; case EXEC_DO_CONCURRENT: res = gfc_trans_do_concurrent (code); break; case EXEC_DO_WHILE: res = gfc_trans_do_while (code); break; case EXEC_SELECT: res = gfc_trans_select (code); break; case EXEC_SELECT_TYPE: /* Do nothing. SELECT TYPE statements should be transformed into an ordinary SELECT CASE at resolution stage. TODO: Add an error message here once this is done. */ res = NULL_TREE; break; case EXEC_FLUSH: res = gfc_trans_flush (code); break; case EXEC_SYNC_ALL: case EXEC_SYNC_IMAGES: case EXEC_SYNC_MEMORY: res = gfc_trans_sync (code, code->op); break; case EXEC_LOCK: case EXEC_UNLOCK: res = gfc_trans_lock_unlock (code, code->op); break; case EXEC_FORALL: res = gfc_trans_forall (code); break; case EXEC_WHERE: res = gfc_trans_where (code); break; case EXEC_ALLOCATE: res = gfc_trans_allocate (code); break; case EXEC_DEALLOCATE: res = gfc_trans_deallocate (code); break; case EXEC_OPEN: res = gfc_trans_open (code); break; case EXEC_CLOSE: res = gfc_trans_close (code); break; case EXEC_READ: res = gfc_trans_read (code); break; case EXEC_WRITE: res = gfc_trans_write (code); break; case EXEC_IOLENGTH: res = gfc_trans_iolength (code); break; case EXEC_BACKSPACE: res = gfc_trans_backspace (code); break; case EXEC_ENDFILE: res = gfc_trans_endfile (code); break; case EXEC_INQUIRE: res = gfc_trans_inquire (code); break; case EXEC_WAIT: res = gfc_trans_wait (code); break; case EXEC_REWIND: res = gfc_trans_rewind (code); break; case EXEC_TRANSFER: res = gfc_trans_transfer (code); break; case EXEC_DT_END: res = gfc_trans_dt_end (code); break; case EXEC_OMP_ATOMIC: case EXEC_OMP_BARRIER: case EXEC_OMP_CRITICAL: case EXEC_OMP_DO: case EXEC_OMP_FLUSH: case EXEC_OMP_MASTER: case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SECTIONS: case EXEC_OMP_SINGLE: case EXEC_OMP_TASK: case EXEC_OMP_TASKWAIT: case EXEC_OMP_TASKYIELD: case EXEC_OMP_WORKSHARE: res = gfc_trans_omp_directive (code); break; default: internal_error ("gfc_trans_code(): Bad statement code"); } gfc_set_backend_locus (&code->loc); if (res != NULL_TREE && ! IS_EMPTY_STMT (res)) { if (TREE_CODE (res) != STATEMENT_LIST) SET_EXPR_LOCATION (res, input_location); /* Add the new statement to the block. */ gfc_add_expr_to_block (&block, res); } } /* Return the finished block. */ return gfc_finish_block (&block); }