Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 00037 static char USMID[] = "\n@(#)5.0_pl/sources/p_ctl_flow.c 5.11 10/12/99 10:54:10\n"; 00038 00039 # include "defines.h" /* Machine dependent ifdefs */ 00040 00041 # include "host.m" /* Host machine dependent macros.*/ 00042 # include "host.h" /* Host machine dependent header.*/ 00043 # include "target.m" /* Target machine dependent macros.*/ 00044 # include "target.h" /* Target machine dependent header.*/ 00045 00046 # include "globals.m" 00047 # include "tokens.m" 00048 # include "sytb.m" 00049 # include "p_globals.m" 00050 # include "debug.m" 00051 00052 # include "globals.h" 00053 # include "tokens.h" 00054 # include "sytb.h" 00055 # include "p_globals.h" 00056 00057 00058 /*****************************************************************\ 00059 |* Function prototypes of static functions declared in this file *| 00060 \*****************************************************************/ 00061 00062 static boolean change_subscript (opnd_type *); 00063 static boolean loop_top_is_perfectly_nested (char *); 00064 static int match_blk (blk_cntxt_type, boolean); 00065 static boolean parse_label_list (int); 00066 static void process_blockable_dir (void); 00067 static void process_interchange_dir (void); 00068 static void check_mp_dir_nesting (void); 00069 static void gen_if_ir(int, int, int, int); 00070 00071 00072 /****************************************************\ 00073 |* Static variables declared and used in this file. *| 00074 \****************************************************/ 00075 00076 /* The following entities are used in DO loop processing. */ 00077 00078 static int last_unlbld_loop_line = 0; 00079 static int last_unlbld_loop_num; 00080 00081 boolean star_expected = FALSE; 00082 00083 00084 /******************************************************************************\ 00085 |* *| 00086 |* Description: *| 00087 |* BNF - ALLOCATE ( allocation-list [, STAT = stat-variable] ) *| 00088 |* *| 00089 |* Input parameters: *| 00090 |* NONE *| 00091 |* *| 00092 |* Output parameters: *| 00093 |* NONE *| 00094 |* *| 00095 |* Returns: *| 00096 |* NONE *| 00097 |* *| 00098 \******************************************************************************/ 00099 00100 void parse_allocate_stmt (void) 00101 00102 { 00103 boolean had_stat = FALSE; 00104 int ir_idx; 00105 int list1_idx; 00106 int list2_idx = 0; 00107 opnd_type opnd; 00108 boolean parsed_ok = TRUE; 00109 token_type stat_token; 00110 00111 00112 TRACE (Func_Entry, "parse_allocate_stmt", NULL); 00113 00114 if (LA_CH_VALUE != LPAREN) { 00115 parse_err_flush(Find_EOS, "("); 00116 goto EXIT; 00117 } 00118 00119 if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) { 00120 curr_stmt_category = Executable_Stmt_Cat; 00121 } 00122 00123 NTR_IR_TBL(ir_idx); 00124 SH_STMT_TYPE(curr_stmt_sh_idx) = Allocate_Stmt; 00125 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 00126 00127 IR_OPR(ir_idx) = Allocate_Opr; 00128 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 00129 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 00130 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 00131 IR_FLD_L(ir_idx) = IL_Tbl_Idx; 00132 IR_LIST_CNT_L(ir_idx) = 0; 00133 00134 do { 00135 NEXT_LA_CH; 00136 00137 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 00138 00139 if (strcmp(TOKEN_STR(token),"STAT") == 0) { 00140 stat_token = token; 00141 00142 if (LA_CH_VALUE == EQUAL) { 00143 NEXT_LA_CH; 00144 had_stat = TRUE; 00145 00146 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 00147 /* have stat var */ 00148 /* do that stat stuff */ 00149 00150 parsed_ok = parse_deref(&opnd, NULL_IDX) && parsed_ok; 00151 COPY_OPND(IR_OPND_R(ir_idx), opnd); 00152 00153 mark_attr_defined(&opnd); 00154 continue; 00155 } 00156 else { 00157 00158 parse_err_flush(Find_Comma_Rparen, 00159 "scalar integer STAT variable"); 00160 continue; 00161 } 00162 } /* if (matched_specific_token(Tok_Punct_Eq, Tok_Class_Punct)) */ 00163 } /* if (strcmp(TOKEN_STR(token),"STAT")) */ 00164 00165 NTR_IR_LIST_TBL(list1_idx); 00166 00167 if (list2_idx) { 00168 IL_NEXT_LIST_IDX(list2_idx) = list1_idx; 00169 IL_PREV_LIST_IDX(list1_idx) = list2_idx; 00170 } 00171 else { 00172 IR_IDX_L(ir_idx) = list1_idx; 00173 } 00174 list2_idx = list1_idx; 00175 00176 (IR_LIST_CNT_L(ir_idx))++; 00177 00178 /* have token */ 00179 if (had_stat) { 00180 PRINTMSG(TOKEN_LINE(stat_token),203, Error, 00181 TOKEN_COLUMN(stat_token), NULL); 00182 } 00183 00184 star_expected = TRUE; 00185 if (parse_deref(&opnd, NULL_IDX)) { 00186 parsed_ok =change_subscript(&opnd) && parsed_ok; 00187 } 00188 else { 00189 parsed_ok = FALSE; 00190 } 00191 star_expected = FALSE; 00192 00193 COPY_OPND(IL_OPND(list1_idx), opnd); 00194 00195 if (LA_CH_VALUE != COMMA && LA_CH_VALUE != RPAREN) { 00196 00197 parse_err_flush(Find_Comma_Rparen,", or )"); 00198 } 00199 00200 if (LA_CH_VALUE == EOS) { 00201 goto EXIT; 00202 } 00203 00204 } else { 00205 parse_err_flush(Find_EOS, "allocation object or STAT = "); 00206 goto EXIT; 00207 } 00208 } 00209 while (LA_CH_VALUE == COMMA); 00210 00211 if (LA_CH_VALUE != RPAREN) { 00212 parse_err_flush(Find_EOS, ")"); 00213 } 00214 else { 00215 NEXT_LA_CH; 00216 } 00217 00218 EXIT: 00219 00220 if (LA_CH_VALUE != EOS) { 00221 parse_err_flush(Find_EOS, EOS_STR); 00222 } 00223 00224 matched_specific_token(Tok_EOS, Tok_Class_Punct); 00225 00226 TRACE (Func_Exit, "parse_allocate_stmt", NULL); 00227 00228 return; 00229 00230 } /* parse_allocate_stmt */ 00231 00232 00233 /******************************************************************************\ 00234 |* *| 00235 |* Description: *| 00236 |* This procedure parses the ASSIGN statement: *| 00237 |* *| 00238 |* ASSIGN label TO scalar-int-variable *| 00239 |* *| 00240 |* Input parameters: *| 00241 |* NONE *| 00242 |* *| 00243 |* Output parameters: *| 00244 |* NONE *| 00245 |* *| 00246 |* Global data changed: *| 00247 |* curr_stmt_category *| 00248 |* *| 00249 |* Returns: *| 00250 |* NONE *| 00251 |* *| 00252 \******************************************************************************/ 00253 00254 void parse_assign_stmt(void) 00255 00256 { 00257 opnd_type asg_var_opnd; 00258 token_type asg_var_token; 00259 int attr_idx; 00260 int name_idx; 00261 int ir_idx; 00262 00263 00264 TRACE (Func_Entry, "parse_assign_stmt", NULL); 00265 00266 if ( ! CURR_BLK_NO_EXEC || ! iss_blk_stk_err() ) { 00267 curr_stmt_category = Executable_Stmt_Cat; 00268 } 00269 00270 /* ASSIGN statement is obsolescent. */ 00271 00272 PRINTMSG(stmt_start_line, 1568, Ansi, stmt_start_col, "ASSIGN"); 00273 00274 NTR_IR_TBL(ir_idx); 00275 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 00276 IR_OPR(ir_idx) = Asg_Opr; 00277 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 00278 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 00279 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 00280 00281 /* Have the keyword ASSIGN. The next token must be a label. */ 00282 00283 if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) { 00284 00285 if (TOKEN_ERR(token)) { 00286 parse_err_flush(Find_EOS, NULL); 00287 goto EXIT; 00288 } 00289 00290 attr_idx = srch_sym_tbl(TOKEN_STR(token), TOKEN_LEN(token), &name_idx); 00291 00292 if (attr_idx == NULL_IDX) { 00293 attr_idx = ntr_sym_tbl(&token, name_idx); 00294 AT_OBJ_CLASS(attr_idx) = Label; 00295 AT_REFERENCED(attr_idx) = Referenced; 00296 LN_DEF_LOC(name_idx) = TRUE; 00297 build_fwd_ref_entry(attr_idx, Assign_Ref); 00298 } 00299 else if (! AT_DCL_ERR(attr_idx) ) { 00300 00301 if (AT_DEFINED(attr_idx) ) { 00302 00303 /* If the ASSIGN stmt is: "10 ASSIGN 10 TO var", need to set */ 00304 /* ATL_EXECUTABLE now so label_ref_semantics will work correctly. */ 00305 00306 if (stmt_label_idx != NULL_IDX && 00307 ATL_DEF_STMT_IDX(attr_idx) == curr_stmt_sh_idx) { 00308 ATL_EXECUTABLE(attr_idx) = TRUE; 00309 } 00310 00311 label_ref_semantics(attr_idx, Assign_Ref, NULL_IDX, 00312 TOKEN_LINE(token), TOKEN_COLUMN(token)); 00313 } 00314 else { 00315 build_fwd_ref_entry(attr_idx, Assign_Ref); 00316 } 00317 } 00318 else { 00319 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 00320 } 00321 00322 ATL_IN_ASSIGN(attr_idx) = TRUE; 00323 AT_REFERENCED(attr_idx) = Referenced; 00324 00325 IR_LINE_NUM_L(ir_idx) = TOKEN_LINE(token); 00326 IR_COL_NUM_L(ir_idx) = TOKEN_COLUMN(token); 00327 IR_FLD_L(ir_idx) = AT_Tbl_Idx; 00328 IR_IDX_L(ir_idx) = attr_idx; 00329 00330 if (cif_flags & XREF_RECS) { 00331 cif_usage_rec(attr_idx, AT_Tbl_Idx, 00332 IR_LINE_NUM_L(ir_idx), IR_COL_NUM_L(ir_idx), 00333 CIF_Label_Referenced_In_ASSIGN); 00334 } 00335 00336 if (matched_specific_token(Tok_Kwd_To, Tok_Class_Keyword)) { 00337 00338 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 00339 asg_var_token = token; 00340 00341 if (parse_deref(&asg_var_opnd, NULL_IDX)) { 00342 00343 if (OPND_FLD(asg_var_opnd) == AT_Tbl_Idx) { 00344 COPY_OPND(IR_OPND_R(ir_idx), asg_var_opnd); 00345 00346 if (AT_OBJ_CLASS(OPND_IDX(asg_var_opnd)) == Data_Obj) { 00347 ATD_IN_ASSIGN(OPND_IDX(asg_var_opnd)) = TRUE; 00348 } 00349 00350 mark_attr_defined(&asg_var_opnd); 00351 00352 if (LA_CH_VALUE != EOS) { 00353 parse_err_flush(Find_EOS, EOS_STR); 00354 } 00355 } 00356 else { 00357 PRINTMSG(TOKEN_LINE(asg_var_token), 172, Error, 00358 TOKEN_COLUMN(asg_var_token)); 00359 parse_err_flush(Find_EOS, NULL); 00360 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 00361 } 00362 } 00363 else { /* Id found but error later in the reference. */ 00364 parse_err_flush(Find_EOS, NULL); 00365 } 00366 } 00367 else { /* No Id found at all. */ 00368 parse_err_flush(Find_EOS, "scalar-int-variable"); 00369 } 00370 } 00371 else { 00372 parse_err_flush(Find_EOS, "TO"); 00373 } 00374 } 00375 else { 00376 parse_err_flush(Find_EOS, "label"); 00377 } 00378 00379 EXIT: 00380 00381 matched_specific_token(Tok_EOS, Tok_Class_Punct); 00382 00383 TRACE (Func_Exit, "parse_assign_stmt", NULL); 00384 00385 return; 00386 00387 } /* parse_assign_stmt */ 00388 00389 00390 /******************************************************************************\ 00391 |* *| 00392 |* Description: *| 00393 |* BRIEF DESCRIPTION OF THIS FUNCTION'S PURPOSE *| 00394 |* *| 00395 |* Input parameters: *| 00396 |* NONE *| 00397 |* *| 00398 |* Output parameters: *| 00399 |* NONE *| 00400 |* *| 00401 |* Returns: *| 00402 |* NONE *| 00403 |* *| 00404 \******************************************************************************/ 00405 00406 void parse_call_stmt (void) 00407 00408 { 00409 boolean amb_ref = FALSE; 00410 int attr_idx; 00411 int call_idx; 00412 int col; 00413 int host_attr_idx; 00414 int host_name_idx; 00415 int line; 00416 int name_idx; 00417 opnd_type opnd; 00418 boolean parsed_ok = TRUE; 00419 00420 00421 TRACE (Func_Entry, "parse_call_stmt", NULL); 00422 00423 if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) { 00424 curr_stmt_category = Executable_Stmt_Cat; 00425 } 00426 00427 if (cmd_line_flags.debug_lvl == Debug_Lvl_1) { /* -ez -G1 */ 00428 gen_debug_lbl_stmt(curr_stmt_sh_idx, Ldbg_Stmt_Lbl, NULL_IDX); 00429 } 00430 00431 NTR_IR_TBL(call_idx); 00432 SH_IR_IDX(curr_stmt_sh_idx) = call_idx; 00433 00434 IR_OPR(call_idx) = Call_Opr; 00435 IR_TYPE_IDX(call_idx) = TYPELESS_DEFAULT_TYPE; 00436 IR_COL_NUM(call_idx) = TOKEN_COLUMN(token); 00437 IR_LINE_NUM(call_idx) = TOKEN_LINE(token); 00438 00439 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 00440 line = TOKEN_LINE(token); 00441 col = TOKEN_COLUMN(token); 00442 00443 attr_idx = srch_sym_tbl(TOKEN_STR(token), 00444 TOKEN_LEN(token), 00445 &name_idx); 00446 00447 if (attr_idx != NULL_IDX) { 00448 host_attr_idx = attr_idx; 00449 00450 if (! LN_DEF_LOC(name_idx)) { 00451 amb_ref = TRUE; 00452 00453 while (AT_ATTR_LINK(host_attr_idx) != NULL_IDX) { 00454 host_attr_idx = AT_ATTR_LINK(host_attr_idx); 00455 } 00456 } 00457 } 00458 else { /* any other reference is ambiguous */ 00459 amb_ref = TRUE; 00460 00461 /* search host sym tab */ 00462 00463 host_attr_idx = srch_host_sym_tbl(TOKEN_STR(token), 00464 TOKEN_LEN(token), 00465 &host_name_idx, 00466 TRUE); 00467 00468 /* if we are copying info down from the host scope */ 00469 00470 if (host_attr_idx != NULL_IDX) { 00471 00472 if (LA_CH_VALUE != LPAREN && 00473 AT_IS_INTRIN(host_attr_idx) && 00474 AT_OBJ_CLASS(host_attr_idx) == Interface && 00475 (strcmp(AT_OBJ_NAME_PTR(host_attr_idx), "SYNCHRONIZE") != 0) && 00476 (strcmp(AT_OBJ_NAME_PTR(host_attr_idx), "RANDOM_SEED") != 0)) { 00477 host_attr_idx = NULL_IDX; 00478 } 00479 00480 /* We don't want to copy down the host attr if the host */ 00481 /* attr is a FUNCTION attr. We are dealing with a CALL */ 00482 /* at this point. */ 00483 00484 if (AT_IS_INTRIN(host_attr_idx) && 00485 AT_OBJ_CLASS(host_attr_idx) == Interface && 00486 ATI_INTERFACE_CLASS(host_attr_idx) == 00487 Generic_Function_Interface) { 00488 host_attr_idx = NULL_IDX; 00489 } 00490 } 00491 00492 if (host_attr_idx != NULL_IDX) { /* copy the attr into the local scp */ 00493 attr_idx = ntr_host_in_sym_tbl(&token, 00494 name_idx, 00495 host_attr_idx, 00496 host_name_idx, 00497 TRUE); 00498 00499 AT_ATTR_LINK(attr_idx) = host_attr_idx; 00500 00501 while (AT_ATTR_LINK(host_attr_idx) != NULL_IDX) { 00502 host_attr_idx = AT_ATTR_LINK(host_attr_idx); 00503 } 00504 00505 if (AT_IS_INTRIN(host_attr_idx) && 00506 AT_OBJ_CLASS(host_attr_idx) == Interface) { 00507 00508 if (ATI_FIRST_SPECIFIC_IDX(host_attr_idx) == NULL_IDX) { 00509 complete_intrinsic_definition(host_attr_idx); 00510 } 00511 00512 /* copy intrinsic attr to the local scope from the 0th scope */ 00513 /* and break the link to the host scope. */ 00514 COPY_ATTR_NTRY(attr_idx, host_attr_idx); 00515 AT_CIF_SYMBOL_ID(attr_idx) = 0; 00516 AT_ATTR_LINK(attr_idx) = NULL_IDX; 00517 host_attr_idx = NULL_IDX; 00518 AT_DEF_LINE(attr_idx) = TOKEN_LINE(token); 00519 AT_DEF_COLUMN(attr_idx) = TOKEN_COLUMN(token); 00520 attr_idx = srch_sym_tbl(TOKEN_STR(token), 00521 TOKEN_LEN(token), 00522 &name_idx); 00523 } 00524 } 00525 } 00526 00527 if (attr_idx == NULL_IDX) { 00528 attr_idx = ntr_sym_tbl(&token, name_idx); 00529 AT_OBJ_CLASS(attr_idx) = Pgm_Unit; 00530 ATP_PGM_UNIT(attr_idx) = Subroutine; 00531 ATP_SCP_IDX(attr_idx) = curr_scp_idx; 00532 MAKE_EXTERNAL_NAME(attr_idx, 00533 AT_NAME_IDX(attr_idx), 00534 AT_NAME_LEN(attr_idx)); 00535 ATP_PROC(attr_idx) = Unknown_Proc; 00536 } 00537 else if (!amb_ref) { 00538 00539 if (AT_OBJ_CLASS(attr_idx) == Pgm_Unit && 00540 !AT_NOT_VISIBLE(attr_idx) && 00541 (ATP_PGM_UNIT(attr_idx) == Subroutine || 00542 ATP_PGM_UNIT(attr_idx) == Pgm_Unknown)) { 00543 ATP_PGM_UNIT(attr_idx) = Subroutine; 00544 } 00545 else if (fnd_semantic_err(Obj_Use_Extern_Subr, 00546 line, 00547 col, 00548 attr_idx, 00549 TRUE)) { 00550 parse_err_flush(Find_EOS, NULL); 00551 parsed_ok = FALSE; 00552 goto EXIT; 00553 } 00554 else if (AT_OBJ_CLASS(attr_idx) == Data_Obj) { 00555 chg_data_obj_to_pgm_unit(attr_idx, Subroutine, Extern_Proc); 00556 } 00557 } 00558 else { 00559 if (AT_OBJ_CLASS(attr_idx) == Interface) { 00560 /* do nothing if it is an interface */ 00561 } 00562 else if (AT_REFERENCED(attr_idx) == Not_Referenced && 00563 AT_OBJ_CLASS(attr_idx) == Data_Obj) { 00564 00565 /* assumes that if not referenced then we just put it in */ 00566 00567 chg_data_obj_to_pgm_unit(attr_idx, Subroutine, Extern_Proc); 00568 } 00569 } 00570 00571 AT_REFERENCED(attr_idx) = Referenced; 00572 IR_FLD_L(call_idx) = AT_Tbl_Idx; 00573 IR_IDX_L(call_idx) = attr_idx; 00574 IR_LINE_NUM_L(call_idx) = line; 00575 IR_COL_NUM_L(call_idx) = col; 00576 00577 if (LA_CH_VALUE == LPAREN) { 00578 parsed_ok = parse_actual_arg_spec(&opnd, FALSE, attr_idx) && 00579 parsed_ok; 00580 COPY_OPND(IR_OPND_R(call_idx), opnd); 00581 } 00582 else { 00583 00584 if (LA_CH_VALUE != EOS) { 00585 parse_err_flush(Find_EOS, "( or "EOS_STR); 00586 parsed_ok = FALSE; 00587 } 00588 else { 00589 IR_FLD_R(call_idx) = IL_Tbl_Idx; 00590 IR_IDX_R(call_idx) = NULL_IDX; 00591 IR_LIST_CNT_R(call_idx) = 0; 00592 } 00593 } 00594 } 00595 else { 00596 parse_err_flush(Find_EOS, "SUBROUTINE NAME"); 00597 parsed_ok = FALSE; 00598 } 00599 00600 EXIT: 00601 00602 if (LA_CH_VALUE != EOS) { 00603 parse_err_flush(Find_EOS, EOS_STR); 00604 parsed_ok = FALSE; 00605 } 00606 00607 matched_specific_token(Tok_EOS, Tok_Class_Punct); 00608 00609 SH_ERR_FLG(curr_stmt_sh_idx) = ! parsed_ok; 00610 00611 TRACE (Func_Exit, "parse_call_stmt", NULL); 00612 00613 return; 00614 00615 } /* parse_call_stmt */ 00616 00617 00618 /******************************************************************************\ 00619 |* *| 00620 |* Description: *| 00621 |* Parse a CASE statement of a SELECT CASE construct. *| 00622 |* *| 00623 |* Input parameters: *| 00624 |* NONE *| 00625 |* *| 00626 |* Output parameters: *| 00627 |* NONE *| 00628 |* *| 00629 |* Returns: *| 00630 |* NONE *| 00631 |* *| 00632 \******************************************************************************/ 00633 00634 void parse_case_stmt (void) 00635 00636 { 00637 int blk_idx; 00638 int case_ir_idx; 00639 int case_lbl_idx; 00640 int cont_stmt_sh_idx; 00641 int expr_start_col; 00642 int expr_start_line; 00643 boolean fnd_colon; 00644 boolean fnd_default = FALSE; 00645 boolean fnd_name = FALSE; 00646 int ir_idx; 00647 boolean matched_blk = FALSE; 00648 int num_cases = 0; 00649 opnd_type opnd; 00650 int range_ir_idx; 00651 int save_curr_stmt_sh_idx; 00652 00653 00654 TRACE (Func_Entry, "parse_case_stmt", NULL); 00655 00656 check_for_vestigial_task_blks(); 00657 00658 /* PDGCS wants a label to precede each CASE in a CASE construct. If a */ 00659 /* case-selector contains more than one case-value-range, only one label */ 00660 /* is generated to precede the first CASE SH. Insert a CONTINUE stmt */ 00661 /* ahead of the CASE SH to define the label needed by PDGCS. If the CASE */ 00662 /* stmt is labeled, insert the CONTINUE ahead of the user label. */ 00663 00664 save_curr_stmt_sh_idx = curr_stmt_sh_idx; 00665 00666 if (SH_LABELED(curr_stmt_sh_idx)) { 00667 curr_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 00668 } 00669 00670 /* Back up before the debug label, if one has been generated in p_driver. */ 00671 00672 if (cmd_line_flags.debug_lvl == Debug_Lvl_0 && 00673 SH_IR_IDX(curr_stmt_sh_idx) != NULL_IDX && 00674 IR_OPR(SH_IR_IDX(curr_stmt_sh_idx)) == Label_Opr) { /* -ed -G0 */ 00675 00676 curr_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 00677 } 00678 00679 gen_sh(Before, Continue_Stmt, stmt_start_line, stmt_start_col, 00680 FALSE, TRUE, TRUE); 00681 00682 cont_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 00683 00684 case_lbl_idx = gen_internal_lbl(stmt_start_line); 00685 00686 NTR_IR_TBL(ir_idx); 00687 SH_IR_IDX(cont_stmt_sh_idx) = ir_idx; 00688 IR_OPR(ir_idx) = Label_Opr; 00689 /* LRR - bhj put in short typeless as type idx */ 00690 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 00691 IR_LINE_NUM(ir_idx) = stmt_start_line; 00692 IR_COL_NUM(ir_idx) = stmt_start_col; 00693 IR_LINE_NUM_L(ir_idx) = stmt_start_line; 00694 IR_COL_NUM_L(ir_idx) = stmt_start_col; 00695 IR_FLD_L(ir_idx) = AT_Tbl_Idx; 00696 IR_IDX_L(ir_idx) = case_lbl_idx; 00697 00698 AT_REFERENCED(case_lbl_idx) = Referenced; 00699 AT_DEFINED(case_lbl_idx) = TRUE; 00700 AT_DEF_LINE(case_lbl_idx) = stmt_start_line; 00701 ATL_DEF_STMT_IDX(case_lbl_idx) = cont_stmt_sh_idx; 00702 00703 curr_stmt_sh_idx = save_curr_stmt_sh_idx; 00704 00705 /* Generate the Case IR. By default, set the right operand to point at */ 00706 /* the constant 0 to indicate that there is only a single case value for */ 00707 /* this case. If a comma is encountered, the right operand will be */ 00708 /* switched to point to the constant 1. PDGCS needs this flag. */ 00709 00710 NTR_IR_TBL(case_ir_idx); 00711 SH_IR_IDX(curr_stmt_sh_idx) = case_ir_idx; 00712 IR_OPR(case_ir_idx) = Case_Opr; 00713 /* LRR - bhj put in short typeless as type idx */ 00714 IR_TYPE_IDX(case_ir_idx) = TYPELESS_DEFAULT_TYPE; 00715 IR_LINE_NUM(case_ir_idx) = stmt_start_line; 00716 IR_COL_NUM(case_ir_idx) = stmt_start_col; 00717 IR_FLD_R(case_ir_idx) = CN_Tbl_Idx; 00718 IR_IDX_R(case_ir_idx) = CN_INTEGER_ZERO_IDX; 00719 IR_LINE_NUM_R(case_ir_idx) = stmt_start_line; 00720 IR_COL_NUM_R(case_ir_idx) = stmt_start_col; 00721 00722 if (LA_CH_VALUE == LPAREN) { 00723 00724 /* ATL_CASE_LABEL is to be set to TRUE only for non-DEFAULT CASE stmts. */ 00725 00726 ATL_CASE_LABEL(case_lbl_idx) = TRUE; 00727 00728 00729 do { 00730 00731 /* First trip through, eat the left paren. All subsequent trips, */ 00732 /* eat the comma. */ 00733 00734 NEXT_LA_CH; 00735 00736 opnd = null_opnd; 00737 00738 if (LA_CH_VALUE != COLON) { 00739 strcpy(parse_operand_insert, "operand or :"); 00740 00741 /* Capture the first character of the case-value expression for */ 00742 /* better diagnostics in the Semantics Pass. */ 00743 00744 expr_start_line = LA_CH_LINE; 00745 expr_start_col = LA_CH_COLUMN; 00746 00747 if (! parse_expr(&opnd)) { 00748 parse_err_flush(Find_Rparen, NULL); 00749 break; 00750 } 00751 00752 fnd_colon = FALSE; 00753 } 00754 00755 if (LA_CH_VALUE == COLON) { 00756 fnd_colon = TRUE; 00757 NTR_IR_TBL(range_ir_idx); 00758 /* LRR - bhj put in short typeless as type idx */ 00759 IR_FLD_L(case_ir_idx) = IR_Tbl_Idx; 00760 IR_IDX_L(case_ir_idx) = range_ir_idx; 00761 IR_OPR(range_ir_idx) = Case_Range_Opr; 00762 IR_TYPE_IDX(range_ir_idx) = TYPELESS_DEFAULT_TYPE; 00763 IR_LINE_NUM(range_ir_idx) = LA_CH_LINE; 00764 IR_COL_NUM(range_ir_idx) = LA_CH_COLUMN; 00765 00766 if (OPND_FLD(opnd) != NO_Tbl_Idx) { 00767 COPY_OPND(IR_OPND_L(range_ir_idx), opnd); 00768 IR_LINE_NUM_L(range_ir_idx) = expr_start_line; 00769 IR_COL_NUM_L(range_ir_idx) = expr_start_col; 00770 } 00771 00772 NEXT_LA_CH; 00773 00774 if (LA_CH_VALUE != COMMA && LA_CH_VALUE != RPAREN) { 00775 strcpy(parse_operand_insert, "operand, comma, or )"); 00776 00777 expr_start_line = LA_CH_LINE; 00778 expr_start_col = LA_CH_COLUMN; 00779 00780 if (parse_expr(&opnd)) { 00781 COPY_OPND(IR_OPND_R(range_ir_idx), opnd); 00782 IR_LINE_NUM_R(range_ir_idx) = expr_start_line; 00783 IR_COL_NUM_R(range_ir_idx) = expr_start_col; 00784 } 00785 else { 00786 parse_err_flush(Find_Rparen, NULL); 00787 } 00788 } 00789 else { 00790 00791 if (OPND_FLD(opnd) == NO_Tbl_Idx) { 00792 PRINTMSG(IR_LINE_NUM(range_ir_idx), 789, Error, 00793 IR_COL_NUM(range_ir_idx)); 00794 continue; 00795 } 00796 00797 } 00798 } 00799 else { 00800 COPY_OPND(IR_OPND_L(case_ir_idx), opnd); 00801 IR_LINE_NUM_L(case_ir_idx) = expr_start_line; 00802 IR_COL_NUM_L(case_ir_idx) = expr_start_col; 00803 } 00804 00805 ++num_cases; 00806 00807 /* Link this CASE stmt to its parent SELECT CASE stmt. The Block */ 00808 /* Stack checks for complete validity are made later. Assume we */ 00809 /* have correct cases for now (and if we don't, not setting */ 00810 /* SH_PARENT_BLK_IDX won't make any difference any how). */ 00811 00812 if (CURR_BLK == Select_Blk) { 00813 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = CURR_BLK_FIRST_SH_IDX; 00814 } 00815 else if (CURR_BLK == Case_Blk && 00816 BLK_TYPE(blk_stk_idx - 1) == Select_Blk) { 00817 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = 00818 BLK_FIRST_SH_IDX(blk_stk_idx - 1); 00819 } 00820 00821 /* If there is another case-value, generate an SH for it. Indicate */ 00822 /* that this CASE stmt has multiple case-values by setting the right */ 00823 /* operand index to point to 1. */ 00824 00825 if (LA_CH_VALUE == COMMA) { 00826 IR_IDX_R(case_ir_idx) = CN_INTEGER_ONE_IDX; 00827 00828 gen_sh(After, Case_Stmt, stmt_start_line, stmt_start_col, FALSE, 00829 FALSE, TRUE); 00830 00831 NTR_IR_TBL(case_ir_idx); 00832 SH_IR_IDX(curr_stmt_sh_idx) = case_ir_idx; 00833 IR_OPR(case_ir_idx) = Case_Opr; 00834 /* LRR - bhj put in short typeless as type idx */ 00835 IR_TYPE_IDX(case_ir_idx) = TYPELESS_DEFAULT_TYPE; 00836 IR_LINE_NUM(case_ir_idx) = stmt_start_line; 00837 IR_COL_NUM(case_ir_idx) = stmt_start_col; 00838 IR_FLD_R(case_ir_idx) = CN_Tbl_Idx; 00839 IR_IDX_R(case_ir_idx) = CN_INTEGER_ZERO_IDX; 00840 IR_LINE_NUM_R(case_ir_idx) = stmt_start_line; 00841 IR_COL_NUM_R(case_ir_idx) = stmt_start_col; 00842 } 00843 00844 } while (LA_CH_VALUE == COMMA); 00845 00846 if (LA_CH_VALUE == RPAREN) { 00847 NEXT_LA_CH; 00848 } 00849 else { 00850 parse_err_flush(Find_EOS, 00851 (fnd_colon) ? "comma or )" : "comma, :, or )"); 00852 } 00853 00854 fnd_name = MATCHED_TOKEN_CLASS(Tok_Class_Id); 00855 } 00856 else if (matched_specific_token(Tok_Kwd_Default, Tok_Class_Keyword)) { 00857 fnd_name = MATCHED_TOKEN_CLASS(Tok_Class_Id); 00858 fnd_default = TRUE; 00859 } 00860 else { 00861 parse_err_flush(Find_EOS, "( or DEFAULT"); 00862 } 00863 00864 if (LA_CH_VALUE != EOS) { 00865 parse_err_flush(Find_EOS, EOS_STR); 00866 } 00867 00868 00869 if (STMT_LEGAL_IN_BLK(Case_Stmt, CURR_BLK)) { 00870 00871 matched_blk = (fnd_name) ? (CURR_BLK_NAME != NULL_IDX && 00872 (compare_names(TOKEN_ID(token).words, 00873 TOKEN_LEN(token), 00874 AT_OBJ_NAME_LONG(CURR_BLK_NAME), 00875 AT_NAME_LEN(CURR_BLK_NAME)) == 0)): 00876 TRUE; 00877 } 00878 00879 if (matched_blk) { 00880 00881 if ((cif_flags & XREF_RECS) && fnd_name && matched_blk) { 00882 cif_usage_rec(CURR_BLK_NAME, AT_Tbl_Idx, 00883 TOKEN_LINE(token), TOKEN_COLUMN(token), 00884 CIF_Construct_Name_Reference); 00885 } 00886 curr_stmt_category = Executable_Stmt_Cat; 00887 blk_idx = (CURR_BLK == Select_Blk) ? 00888 blk_stk_idx : blk_stk_idx - 1; 00889 } 00890 else { 00891 blk_idx = blk_match_err(Select_Blk, fnd_name, FALSE); 00892 00893 if (blk_idx == NULL_IDX) { 00894 goto EXIT; 00895 } 00896 00897 if (CURR_BLK == Case_Blk) { 00898 blk_idx = blk_stk_idx - 1; 00899 } 00900 else if (CURR_BLK == Select_Blk) { 00901 blk_idx = blk_stk_idx; 00902 } 00903 else { 00904 goto EXIT; 00905 } 00906 } 00907 00908 BLK_NUM_CASES(blk_idx) += num_cases; 00909 00910 if (fnd_default) { 00911 00912 if (BLK_FND_DEFAULT(blk_idx) && ! BLK_ERR(blk_idx)) { 00913 00914 /* This SELECT has a default CASE already. */ 00915 00916 PRINTMSG(stmt_start_line, 159, Error, stmt_start_col, 00917 BLK_DEF_LINE(blk_idx)); 00918 } 00919 else { 00920 BLK_CASE_DEFAULT_LBL_LINE_NUM(blk_idx) = stmt_start_line; 00921 BLK_CASE_DEFAULT_LBL_COL_NUM(blk_idx) = stmt_start_col; 00922 BLK_CASE_DEFAULT_LBL_FLD(blk_idx) = AT_Tbl_Idx; 00923 BLK_CASE_DEFAULT_LBL_IDX(blk_idx) = case_lbl_idx; 00924 } 00925 00926 BLK_FND_DEFAULT(blk_idx) = TRUE; 00927 } 00928 00929 if (CURR_BLK == Case_Blk) { 00930 00931 /* Reuse the Block Stack frame. */ 00932 00933 CURR_BLK_DEF_LINE = stmt_start_line; 00934 CURR_BLK_DEF_COLUMN = stmt_start_col; 00935 00936 /* Generate a GO TO at the end of the previous CASE block to branch to */ 00937 /* the end of the construct. */ 00938 00939 save_curr_stmt_sh_idx = curr_stmt_sh_idx; 00940 curr_stmt_sh_idx = cont_stmt_sh_idx; 00941 00942 gen_sh(Before, Goto_Stmt, SH_GLB_LINE(SH_PREV_IDX(curr_stmt_sh_idx)), 00943 SH_COL_NUM(SH_PREV_IDX(curr_stmt_sh_idx)), FALSE, FALSE, TRUE); 00944 00945 curr_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 00946 00947 NTR_IR_TBL(ir_idx); 00948 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 00949 IR_OPR(ir_idx) = Br_Uncond_Opr; 00950 /* LRR - bhj put in short typeless as type idx */ 00951 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 00952 IR_LINE_NUM(ir_idx) = SH_GLB_LINE(curr_stmt_sh_idx); 00953 IR_COL_NUM(ir_idx) = SH_COL_NUM(curr_stmt_sh_idx); 00954 IR_LINE_NUM_R(ir_idx) = IR_LINE_NUM(ir_idx); 00955 IR_COL_NUM_R(ir_idx) = IR_COL_NUM(ir_idx); 00956 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 00957 IR_IDX_R(ir_idx) = BLK_LABEL(blk_idx); 00958 00959 curr_stmt_sh_idx = save_curr_stmt_sh_idx; 00960 } 00961 else { 00962 PUSH_BLK_STK(Case_Blk); 00963 CURR_BLK_ERR = BLK_ERR(blk_idx); 00964 CURR_BLK_NAME = BLK_NAME(blk_idx); 00965 } 00966 00967 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 00968 LINK_TO_PARENT_BLK; 00969 00970 if (cif_flags & MISC_RECS) { 00971 cif_stmt_type_rec(TRUE, 00972 (fnd_default) ? CIF_Case_Default_Stmt : CIF_Case_Stmt, 00973 statement_number); 00974 } 00975 00976 EXIT: 00977 00978 NEXT_LA_CH; 00979 strcpy(parse_operand_insert, "operand"); 00980 00981 TRACE (Func_Exit, "parse_case_stmt", NULL); 00982 00983 return; 00984 00985 } /* parse_case_stmt */ 00986 00987 00988 /******************************************************************************\ 00989 |* *| 00990 |* Description: *| 00991 |* BRIEF DESCRIPTION OF THIS FUNCTION'S PURPOSE *| 00992 |* *| 00993 |* Input parameters: *| 00994 |* NONE *| 00995 |* *| 00996 |* Output parameters: *| 00997 |* NONE *| 00998 |* *| 00999 |* Returns: *| 01000 |* NONE *| 01001 |* *| 01002 \******************************************************************************/ 01003 01004 void parse_continue_stmt (void) 01005 01006 { 01007 TRACE (Func_Entry, "parse_continue_stmt", NULL); 01008 01009 if (LA_CH_VALUE != EOS) { 01010 parse_err_flush(Find_EOS, EOS_STR); 01011 } 01012 01013 if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) { 01014 curr_stmt_category = Executable_Stmt_Cat; 01015 } 01016 01017 NEXT_LA_CH; 01018 01019 TRACE (Func_Exit, "parse_continue_stmt", NULL); 01020 01021 return; 01022 01023 } /* parse_continue_stmt */ 01024 01025 01026 /******************************************************************************\ 01027 |* *| 01028 |* Description: *| 01029 |* Parse the CYCLE statement. If a matching DO construct is found, *| 01030 |* generate the internal cycle point label and a Br_Uncond IR to jump to *| 01031 |* it. *| 01032 |* *| 01033 |* Input parameters: *| 01034 |* NONE *| 01035 |* *| 01036 |* Output parameters: *| 01037 |* NONE *| 01038 |* *| 01039 |* Returns: *| 01040 |* NONE *| 01041 |* *| 01042 \******************************************************************************/ 01043 01044 void parse_cycle_stmt (void) 01045 01046 { 01047 int blk_idx; 01048 boolean fnd_name = FALSE; 01049 int ir_idx; 01050 01051 01052 TRACE (Func_Entry, "parse_cycle_stmt", NULL); 01053 01054 if (LA_CH_VALUE != EOS) { 01055 fnd_name = MATCHED_TOKEN_CLASS(Tok_Class_Id); 01056 01057 if (fnd_name) { 01058 01059 if (LA_CH_VALUE != EOS) { 01060 parse_err_flush(Find_EOS, EOS_STR); 01061 } 01062 01063 } 01064 else { 01065 parse_err_flush(Find_EOS, "construct-name or EOS"); 01066 goto EXIT; 01067 } 01068 01069 } 01070 01071 blk_idx = match_blk(Do_Blk, fnd_name); 01072 01073 if (blk_idx != NULL_IDX) { 01074 01075 if (! CURR_BLK_NO_EXEC || ! iss_blk_stk_err()) { 01076 curr_stmt_category = Executable_Stmt_Cat; 01077 SH_P2_SKIP_ME(curr_stmt_sh_idx) = TRUE; 01078 BLK_CYCLE_STMT(blk_idx) = TRUE; 01079 01080 NTR_IR_TBL(ir_idx); 01081 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 01082 IR_OPR(ir_idx) = Br_Uncond_Opr; 01083 /* LRR - bhj put in short typeless as type idx */ 01084 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 01085 IR_LINE_NUM(ir_idx) = stmt_start_line; 01086 IR_COL_NUM(ir_idx) = stmt_start_col; 01087 IR_LINE_NUM_R(ir_idx) = stmt_start_line; 01088 IR_COL_NUM_R(ir_idx) = stmt_start_col; 01089 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 01090 IR_IDX_R(ir_idx) = gen_loop_lbl_name(blk_idx, Cycle_Lbl); 01091 01092 if (fnd_name && (cif_flags & XREF_RECS)) { 01093 cif_usage_rec(BLK_NAME(blk_idx), AT_Tbl_Idx, 01094 TOKEN_LINE(token), TOKEN_COLUMN(token), 01095 CIF_Construct_Name_Reference); 01096 } 01097 } 01098 01099 } 01100 else { 01101 PRINTMSG(stmt_start_line, 262, Error, stmt_start_col, "CYCLE"); 01102 } 01103 01104 EXIT: 01105 01106 NEXT_LA_CH; 01107 01108 TRACE (Func_Exit, "parse_cycle_stmt", NULL); 01109 01110 return; 01111 01112 } /* parse_cycle_stmt */ 01113 01114 01115 /******************************************************************************\ 01116 |* *| 01117 |* Description: *| 01118 |* BNF - DEALLOCATE ( allocation-list [, STAT = stat-variable] ) *| 01119 |* *| 01120 |* Input parameters: *| 01121 |* NONE *| 01122 |* *| 01123 |* Output parameters: *| 01124 |* NONE *| 01125 |* *| 01126 |* Returns: *| 01127 |* NONE *| 01128 |* *| 01129 \******************************************************************************/ 01130 01131 void parse_deallocate_stmt (void) 01132 01133 { 01134 boolean had_stat = FALSE; 01135 int ir_idx; 01136 int list1_idx; 01137 int list2_idx = 0; 01138 opnd_type opnd; 01139 boolean parsed_ok = TRUE; 01140 token_type stat_token; 01141 01142 01143 TRACE (Func_Entry, "parse_deallocate_stmt", NULL); 01144 01145 if (LA_CH_VALUE != LPAREN) { 01146 parse_err_flush(Find_EOS, "("); 01147 goto EXIT; 01148 } 01149 01150 if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) { 01151 curr_stmt_category = Executable_Stmt_Cat; 01152 } 01153 01154 NTR_IR_TBL(ir_idx); 01155 SH_STMT_TYPE(curr_stmt_sh_idx) = Deallocate_Stmt; 01156 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 01157 01158 IR_OPR(ir_idx) = Deallocate_Opr; 01159 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 01160 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 01161 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 01162 IR_FLD_L(ir_idx) = IL_Tbl_Idx; 01163 IR_LIST_CNT_L(ir_idx) = 0; 01164 01165 do { 01166 NEXT_LA_CH; 01167 01168 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 01169 01170 if (strcmp(TOKEN_STR(token),"STAT") == 0) { 01171 stat_token = token; 01172 01173 if (LA_CH_VALUE == EQUAL) { 01174 NEXT_LA_CH; 01175 had_stat = TRUE; 01176 01177 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 01178 /* have stat var */ 01179 /* do that stat stuff */ 01180 01181 parsed_ok = parse_deref(&opnd, NULL_IDX) && parsed_ok; 01182 COPY_OPND(IR_OPND_R(ir_idx), opnd); 01183 01184 mark_attr_defined(&opnd); 01185 continue; 01186 } 01187 else { 01188 01189 parse_err_flush(Find_Comma_Rparen, 01190 "scalar integer STAT variable"); 01191 continue; 01192 } 01193 } /* if (matched_specific_token(Tok_Punct_Eq, Tok_Class_Punct)) */ 01194 } /* if (strcmp(TOKEN_STR(token),"STAT")) */ 01195 01196 NTR_IR_LIST_TBL(list1_idx); 01197 01198 if (list2_idx) { 01199 IL_NEXT_LIST_IDX(list2_idx) = list1_idx; 01200 IL_PREV_LIST_IDX(list1_idx) = list2_idx; 01201 } 01202 else { 01203 IR_IDX_L(ir_idx) = list1_idx; 01204 } 01205 list2_idx = list1_idx; 01206 01207 (IR_LIST_CNT_L(ir_idx))++; 01208 01209 /* have token */ 01210 if (had_stat) { 01211 PRINTMSG(TOKEN_LINE(stat_token), 203, Error, 01212 TOKEN_COLUMN(stat_token), NULL); 01213 } 01214 01215 if (parse_deref(&opnd, NULL_IDX)) { 01216 parsed_ok = change_subscript(&opnd) && parsed_ok;/*don't know why it's dispeared-Dec*/ 01217 } 01218 else { 01219 parsed_ok = FALSE; 01220 } 01221 01222 COPY_OPND(IL_OPND(list1_idx), opnd); 01223 01224 if (LA_CH_VALUE != COMMA && LA_CH_VALUE != RPAREN) { 01225 01226 parse_err_flush(Find_Comma_Rparen,", or )"); 01227 } 01228 01229 if (LA_CH_VALUE == EOS) { 01230 goto EXIT; 01231 } 01232 01233 } else { 01234 parse_err_flush(Find_EOS, "allocation object or STAT = "); 01235 goto EXIT; 01236 } 01237 } 01238 while (LA_CH_VALUE == COMMA); 01239 01240 if (LA_CH_VALUE != RPAREN) { 01241 parse_err_flush(Find_EOS, ")"); 01242 } 01243 else { 01244 NEXT_LA_CH; 01245 } 01246 01247 EXIT: 01248 01249 if (LA_CH_VALUE != EOS) { 01250 parse_err_flush(Find_EOS, EOS_STR); 01251 } 01252 01253 matched_specific_token(Tok_EOS, Tok_Class_Punct); 01254 01255 TRACE (Func_Exit, "parse_deallocate_stmt", NULL); 01256 01257 return; 01258 01259 } /* parse_deallocate_stmt */ 01260 01261 01262 /******************************************************************************\ 01263 |* *| 01264 |* Description: *| 01265 |* This function parses all forms of the DO statement. *| 01266 |* *| 01267 |* R819 label-do-stmt is [do-construct-name:] DO label [loop-control] *| 01268 |* R820 nonlabel-do-stmt is [do-construct-name:] DO [loop-control] *| 01269 |* R821 loop-control is [,] do-variable = scalar-numeric-expr, *| 01270 |* scalar-numeric-expr, scalar-numeric-expr *| 01271 |* or [,] WHILE(scalar-logical-expr) *| 01272 |* *| 01273 |* The leading token possibilities are: *| 01274 |* *| 01275 |* DO *| 01276 |* | *| 01277 |* ----------------------------------------------------- *| 01278 |* | | | | | *| 01279 |* label , WHILE variable EOS *| 01280 |* | | *| 01281 |* ---------------------- ---------- *| 01282 |* | | | | | *| 01283 |* , variable WHILE variable WHILE *| 01284 |* | *| 01285 |* ------------ *| 01286 |* | | *| 01287 |* variable WHILE *| 01288 |* *| 01289 |* Input parameters: *| 01290 |* NONE *| 01291 |* *| 01292 |* Output parameters: *| 01293 |* NONE *| 01294 |* *| 01295 |* Returns: *| 01296 |* NONE *| 01297 |* *| 01298 \******************************************************************************/ 01299 01300 void parse_do_stmt (void) 01301 01302 { 01303 int blk_idx; 01304 int cif_il_idx; 01305 boolean comma_found = FALSE; 01306 opnd_type do_variable; 01307 int expr_start_col; 01308 int expr_start_line; 01309 int idx; 01310 int il_idx; 01311 int il_idx_2; 01312 boolean label_found = FALSE; 01313 int last_il_idx; 01314 int loop_info_idx; 01315 int loop_control_il_idx; 01316 opnd_type loop_expr; 01317 int loop_labels_il_idx; 01318 int mp_nest_list_idx = NULL_IDX; 01319 int mp_prev_idx; 01320 int name_idx; 01321 opnd_type while_expr; 01322 01323 01324 TRACE (Func_Entry, "parse_do_stmt", NULL); 01325 01326 if (! CURR_BLK_NO_EXEC || ! iss_blk_stk_err()) { 01327 01328 if (cdir_switches.doall_sh_idx != NULL_IDX) { 01329 PUSH_BLK_STK (Doall_Blk); 01330 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01331 CURR_BLK_FIRST_SH_IDX = cdir_switches.doall_sh_idx; 01332 cdir_switches.doall_sh_idx = NULL_IDX; 01333 cdir_switches.doall_region = TRUE; 01334 } 01335 else if (cdir_switches.doacross_sh_idx != NULL_IDX) { 01336 /* need BLK stack stuff here BHJ */ 01337 PUSH_BLK_STK (SGI_Doacross_Blk); 01338 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01339 CURR_BLK_FIRST_SH_IDX = cdir_switches.doacross_sh_idx; 01340 mp_nest_list_idx = IR_IDX_L(SH_IR_IDX( 01341 cdir_switches.doacross_sh_idx)); 01342 01343 idx = 0; 01344 01345 while (idx < MP_DIR_NEST_IDX) { 01346 mp_nest_list_idx = 01347 IL_NEXT_LIST_IDX(mp_nest_list_idx); 01348 idx++; 01349 } 01350 01351 if (IL_FLD(mp_nest_list_idx) == NO_Tbl_Idx) { 01352 NTR_IR_LIST_TBL(idx); 01353 IL_FLD(mp_nest_list_idx) = IL_Tbl_Idx; 01354 IL_IDX(mp_nest_list_idx) = idx; 01355 IL_LIST_CNT(mp_nest_list_idx) = 1; 01356 mp_prev_idx = mp_nest_list_idx; 01357 mp_nest_list_idx = idx; 01358 } 01359 else { 01360 mp_nest_list_idx = NULL_IDX; 01361 } 01362 01363 cdir_switches.dir_nest_check_sh_idx = cdir_switches.doacross_sh_idx; 01364 cdir_switches.doacross_sh_idx = NULL_IDX; 01365 } 01366 else if (cdir_switches.paralleldo_sh_idx != NULL_IDX) { 01367 /* need BLK stack stuff here BHJ */ 01368 PUSH_BLK_STK (SGI_Parallel_Do_Blk); 01369 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01370 CURR_BLK_FIRST_SH_IDX = cdir_switches.paralleldo_sh_idx; 01371 mp_nest_list_idx = IR_IDX_L(SH_IR_IDX( 01372 cdir_switches.paralleldo_sh_idx)); 01373 01374 idx = 0; 01375 01376 while (idx < MP_DIR_NEST_IDX) { 01377 mp_nest_list_idx = 01378 IL_NEXT_LIST_IDX(mp_nest_list_idx); 01379 idx++; 01380 } 01381 01382 if (IL_FLD(mp_nest_list_idx) == NO_Tbl_Idx) { 01383 NTR_IR_LIST_TBL(idx); 01384 IL_FLD(mp_nest_list_idx) = IL_Tbl_Idx; 01385 IL_IDX(mp_nest_list_idx) = idx; 01386 IL_LIST_CNT(mp_nest_list_idx) = 1; 01387 mp_prev_idx = mp_nest_list_idx; 01388 mp_nest_list_idx = idx; 01389 } 01390 else { 01391 mp_nest_list_idx = NULL_IDX; 01392 } 01393 01394 cdir_switches.dir_nest_check_sh_idx = cdir_switches.paralleldo_sh_idx; 01395 cdir_switches.paralleldo_sh_idx = NULL_IDX; 01396 } 01397 else if (cdir_switches.pdo_sh_idx != NULL_IDX) { 01398 /* need BLK stack stuff here BHJ */ 01399 PUSH_BLK_STK (SGI_Pdo_Blk); 01400 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01401 CURR_BLK_FIRST_SH_IDX = cdir_switches.pdo_sh_idx; 01402 mp_nest_list_idx = IR_IDX_L(SH_IR_IDX( 01403 cdir_switches.pdo_sh_idx)); 01404 01405 idx = 0; 01406 01407 while (idx < MP_DIR_NEST_IDX) { 01408 mp_nest_list_idx = 01409 IL_NEXT_LIST_IDX(mp_nest_list_idx); 01410 idx++; 01411 } 01412 01413 if (IL_FLD(mp_nest_list_idx) == NO_Tbl_Idx) { 01414 NTR_IR_LIST_TBL(idx); 01415 IL_FLD(mp_nest_list_idx) = IL_Tbl_Idx; 01416 IL_IDX(mp_nest_list_idx) = idx; 01417 IL_LIST_CNT(mp_nest_list_idx) = 1; 01418 mp_prev_idx = mp_nest_list_idx; 01419 mp_nest_list_idx = idx; 01420 } 01421 else { 01422 mp_nest_list_idx = NULL_IDX; 01423 } 01424 01425 cdir_switches.dir_nest_check_sh_idx = cdir_switches.pdo_sh_idx; 01426 cdir_switches.pdo_sh_idx = NULL_IDX; 01427 } 01428 else if (cdir_switches.dopar_sh_idx != NULL_IDX) { 01429 PUSH_BLK_STK (Do_Parallel_Blk); 01430 CURR_BLK_FIRST_SH_IDX = cdir_switches.dopar_sh_idx; 01431 cdir_switches.dopar_sh_idx = NULL_IDX; 01432 } 01433 else if (cdir_switches.do_omp_sh_idx != NULL_IDX) { 01434 PUSH_BLK_STK (Open_Mp_Do_Blk); 01435 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01436 mp_nest_list_idx = IR_IDX_L(SH_IR_IDX( 01437 cdir_switches.do_omp_sh_idx)); 01438 01439 idx = 0; 01440 01441 while (idx < OPEN_MP_NEST_IDX) { 01442 mp_nest_list_idx = 01443 IL_NEXT_LIST_IDX(mp_nest_list_idx); 01444 idx++; 01445 } 01446 01447 if (IL_FLD(mp_nest_list_idx) == NO_Tbl_Idx) { 01448 NTR_IR_LIST_TBL(idx); 01449 IL_FLD(mp_nest_list_idx) = IL_Tbl_Idx; 01450 IL_IDX(mp_nest_list_idx) = idx; 01451 IL_LIST_CNT(mp_nest_list_idx) = 1; 01452 mp_prev_idx = mp_nest_list_idx; 01453 mp_nest_list_idx = idx; 01454 } 01455 else { 01456 mp_nest_list_idx = NULL_IDX; 01457 } 01458 01459 CURR_BLK_FIRST_SH_IDX = cdir_switches.do_omp_sh_idx; 01460 cdir_switches.do_omp_sh_idx = NULL_IDX; 01461 } 01462 else if (cdir_switches.paralleldo_omp_sh_idx != NULL_IDX) { 01463 PUSH_BLK_STK (Open_Mp_Parallel_Do_Blk); 01464 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01465 mp_nest_list_idx = IR_IDX_L(SH_IR_IDX( 01466 cdir_switches.paralleldo_omp_sh_idx)); 01467 01468 idx = 0; 01469 01470 while (idx < OPEN_MP_NEST_IDX) { 01471 mp_nest_list_idx = 01472 IL_NEXT_LIST_IDX(mp_nest_list_idx); 01473 idx++; 01474 } 01475 01476 if (IL_FLD(mp_nest_list_idx) == NO_Tbl_Idx) { 01477 NTR_IR_LIST_TBL(idx); 01478 IL_FLD(mp_nest_list_idx) = IL_Tbl_Idx; 01479 IL_IDX(mp_nest_list_idx) = idx; 01480 IL_LIST_CNT(mp_nest_list_idx) = 1; 01481 mp_prev_idx = mp_nest_list_idx; 01482 mp_nest_list_idx = idx; 01483 } 01484 else { 01485 mp_nest_list_idx = NULL_IDX; 01486 } 01487 01488 CURR_BLK_FIRST_SH_IDX = cdir_switches.paralleldo_omp_sh_idx; 01489 cdir_switches.paralleldo_omp_sh_idx = NULL_IDX; 01490 } 01491 01492 PUSH_BLK_STK (Do_Blk); 01493 curr_stmt_category = Executable_Stmt_Cat; 01494 } 01495 else { 01496 01497 if (cdir_switches.doall_sh_idx != NULL_IDX) { 01498 PUSH_BLK_STK (Doall_Blk); 01499 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01500 CURR_BLK_FIRST_SH_IDX = cdir_switches.doall_sh_idx; 01501 cdir_switches.doall_sh_idx = NULL_IDX; 01502 cdir_switches.doall_region = TRUE; 01503 } 01504 else if (cdir_switches.doacross_sh_idx != NULL_IDX) { 01505 /* need BLK stack stuff here BHJ */ 01506 PUSH_BLK_STK (SGI_Doacross_Blk); 01507 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01508 CURR_BLK_FIRST_SH_IDX = cdir_switches.doacross_sh_idx; 01509 cdir_switches.dir_nest_check_sh_idx = cdir_switches.doacross_sh_idx; 01510 cdir_switches.doacross_sh_idx = NULL_IDX; 01511 } 01512 else if (cdir_switches.paralleldo_sh_idx != NULL_IDX) { 01513 /* need BLK stack stuff here BHJ */ 01514 PUSH_BLK_STK (SGI_Parallel_Do_Blk); 01515 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01516 CURR_BLK_FIRST_SH_IDX = cdir_switches.paralleldo_sh_idx; 01517 cdir_switches.dir_nest_check_sh_idx = cdir_switches.paralleldo_sh_idx; 01518 cdir_switches.paralleldo_sh_idx = NULL_IDX; 01519 } 01520 else if (cdir_switches.pdo_sh_idx != NULL_IDX) { 01521 /* need BLK stack stuff here BHJ */ 01522 PUSH_BLK_STK (SGI_Pdo_Blk); 01523 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01524 CURR_BLK_FIRST_SH_IDX = cdir_switches.pdo_sh_idx; 01525 cdir_switches.dir_nest_check_sh_idx = cdir_switches.pdo_sh_idx; 01526 cdir_switches.pdo_sh_idx = NULL_IDX; 01527 } 01528 else if (cdir_switches.dopar_sh_idx != NULL_IDX) { 01529 PUSH_BLK_STK (Do_Parallel_Blk); 01530 CURR_BLK_FIRST_SH_IDX = cdir_switches.dopar_sh_idx; 01531 cdir_switches.dopar_sh_idx = NULL_IDX; 01532 } 01533 else if (cdir_switches.do_omp_sh_idx != NULL_IDX) { 01534 PUSH_BLK_STK (Open_Mp_Do_Blk); 01535 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01536 CURR_BLK_FIRST_SH_IDX = cdir_switches.do_omp_sh_idx; 01537 cdir_switches.do_omp_sh_idx = NULL_IDX; 01538 } 01539 else if (cdir_switches.paralleldo_omp_sh_idx != NULL_IDX) { 01540 PUSH_BLK_STK (Open_Mp_Parallel_Do_Blk); 01541 BLK_IS_PARALLEL_REGION(blk_stk_idx) = TRUE; 01542 CURR_BLK_FIRST_SH_IDX = cdir_switches.paralleldo_omp_sh_idx; 01543 cdir_switches.paralleldo_omp_sh_idx = NULL_IDX; 01544 } 01545 01546 PUSH_BLK_STK (Do_Blk); 01547 CURR_BLK_ERR = TRUE; 01548 } 01549 01550 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 01551 LINK_TO_PARENT_BLK; 01552 01553 /* Generate the Loop_Info IR. It's left operand will eventually point at */ 01554 /* the SH for the stmt that ends the loop. It's right operand will point */ 01555 /* at a series of ILs. The first IL will point at a list of ILs that */ 01556 /* represent the loop control info (for iterative or WHILE loops); for an */ 01557 /* infinite loop, there is no loop control info so the first IL is null. */ 01558 /* The second IL will point at a list of ILs for the top, bottom, and skip */ 01559 /* labels for an iterative or WHILE loop; for an infinite loop, the IL */ 01560 /* will point directly at the top label. */ 01561 /* If Miscellaneous CIF records are being produced, a third IL exists in */ 01562 /* the chain attached to the Loop_Info IR. This IL points at a list of */ 01563 /* ILs for the DO construct name and the loop label. */ 01564 01565 NTR_IR_TBL(loop_info_idx); 01566 SH_IR_IDX(curr_stmt_sh_idx) = loop_info_idx; 01567 IR_OPR(loop_info_idx) = Loop_Info_Opr; 01568 /* LRR - bhj put in short typeless as type idx */ 01569 IR_TYPE_IDX(loop_info_idx) = TYPELESS_DEFAULT_TYPE; 01570 IR_LINE_NUM(loop_info_idx) = stmt_start_line; 01571 IR_COL_NUM(loop_info_idx) = stmt_start_col; 01572 01573 NTR_IR_LIST_TBL(loop_control_il_idx); 01574 IR_LIST_CNT_R(loop_info_idx) = 1; 01575 IR_FLD_R(loop_info_idx) = IL_Tbl_Idx; 01576 IR_IDX_R(loop_info_idx) = loop_control_il_idx; 01577 01578 NTR_IR_LIST_TBL(loop_labels_il_idx); 01579 IL_NEXT_LIST_IDX(loop_control_il_idx) = loop_labels_il_idx; 01580 IL_PREV_LIST_IDX(loop_labels_il_idx) = loop_control_il_idx; 01581 ++IR_LIST_CNT_R(loop_info_idx); 01582 01583 if (cif_flags & MISC_RECS) { 01584 NTR_IR_LIST_TBL(cif_il_idx); 01585 IL_NEXT_LIST_IDX(loop_labels_il_idx) = cif_il_idx; 01586 IL_PREV_LIST_IDX(cif_il_idx) = loop_labels_il_idx; 01587 ++IR_LIST_CNT_R(loop_info_idx); 01588 01589 /* Always generate the ILs for the construct name and loop label if */ 01590 /* these "labels" are to be saved. */ 01591 01592 NTR_IR_LIST_TBL(il_idx); 01593 NTR_IR_LIST_TBL(il_idx_2); 01594 IL_NEXT_LIST_IDX(il_idx) = il_idx_2; 01595 IL_PREV_LIST_IDX(il_idx_2) = il_idx; 01596 01597 IL_FLD(cif_il_idx) = IL_Tbl_Idx; 01598 IL_IDX(cif_il_idx) = il_idx; 01599 IL_LIST_CNT(cif_il_idx) = 2; 01600 } 01601 01602 if (stmt_construct_idx != NULL_IDX) { 01603 CURR_BLK_NAME = stmt_construct_idx; 01604 ATL_CLASS(stmt_construct_idx) = Lbl_Construct; 01605 ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx; 01606 SH_ERR_FLG(curr_stmt_sh_idx) = SH_ERR_FLG(curr_stmt_sh_idx) | 01607 AT_DCL_ERR(stmt_construct_idx); 01608 01609 /* Save the construct name's Attr index in the second IL attached to the*/ 01610 /* CIF IL node. It's needed for production of the Loop Definition */ 01611 /* record in the Semantics Pass. (Can't output the record now because */ 01612 /* the DO-variable of an iterative DO hasn't been resolved.) */ 01613 01614 if (cif_flags & MISC_RECS) { 01615 IL_FLD(il_idx_2) = AT_Tbl_Idx; 01616 IL_IDX(il_idx_2) = stmt_construct_idx; 01617 IL_LINE_NUM(il_idx_2) = stmt_start_line; 01618 IL_COL_NUM(il_idx_2) = stmt_start_col; 01619 } 01620 01621 stmt_construct_idx = NULL_IDX; 01622 } 01623 01624 if (MATCHED_TOKEN_CLASS(Tok_Class_Label) && ! TOKEN_ERR(token)) { 01625 01626 CURR_BLK_LABEL = srch_sym_tbl(TOKEN_STR(token), TOKEN_LEN(token), 01627 &name_idx); 01628 01629 if (CURR_BLK_LABEL == NULL_IDX) { 01630 CURR_BLK_LABEL = ntr_sym_tbl(&token, name_idx); 01631 AT_OBJ_CLASS(CURR_BLK_LABEL) = Label; 01632 LN_DEF_LOC(name_idx) = TRUE; 01633 01634 if (cmd_line_flags.debug_lvl == Debug_Lvl_1) { /* -ez -G1 */ 01635 ATL_DEBUG_CLASS(CURR_BLK_LABEL) = Ldbg_User_Lbl; 01636 } 01637 } 01638 else if (AT_DEFINED(CURR_BLK_LABEL)) { 01639 PRINTMSG(TOKEN_LINE(token), 248, Error, TOKEN_COLUMN(token)); 01640 parse_err_flush(Find_EOS, NULL); 01641 goto EXIT; 01642 } 01643 01644 AT_REFERENCED(CURR_BLK_LABEL) = Referenced; 01645 label_found = TRUE; 01646 01647 build_fwd_ref_entry(CURR_BLK_LABEL, Do_Ref); 01648 01649 blk_idx = blk_stk_idx - 1; 01650 01651 while (BLK_IS_PARALLEL_REGION(blk_idx) || 01652 BLK_TYPE(blk_idx) == Do_Parallel_Blk || 01653 BLK_TYPE(blk_idx) == Wait_Blk || 01654 BLK_TYPE(blk_idx) == SGI_Region_Blk || 01655 BLK_TYPE(blk_idx) == Open_Mp_Section_Blk) { 01656 blk_idx--; 01657 } 01658 01659 if (BLK_TYPE(blk_idx) == Do_Blk && 01660 BLK_LABEL(blk_idx) == CURR_BLK_LABEL) { 01661 01662 if (BLK_LOOP_NUM(blk_idx) == MAX_BLK_LOOP_NUM) { 01663 PRINTMSG(stmt_start_line, 1324, Internal, stmt_start_col, 01664 MAX_BLK_LOOP_NUM); 01665 } 01666 else { 01667 BLK_LOOP_NUM(blk_stk_idx) = BLK_LOOP_NUM(blk_idx) + 1; 01668 } 01669 } 01670 else { 01671 BLK_LOOP_NUM(blk_stk_idx) = 1; 01672 } 01673 01674 if (cif_flags & XREF_RECS) { 01675 cif_usage_rec(CURR_BLK_LABEL, AT_Tbl_Idx, 01676 TOKEN_LINE(token), TOKEN_COLUMN(token), 01677 CIF_Do_Loop_Label); 01678 } 01679 01680 /* Save the loop label's Attr index in the first IL attached to the */ 01681 /* CIF IL node. It's also needed for production of the Loop Definition */ 01682 /* record in the Semantics Pass. */ 01683 01684 if (cif_flags & MISC_RECS) { 01685 IL_FLD(il_idx) = AT_Tbl_Idx; 01686 IL_IDX(il_idx) = CURR_BLK_LABEL; 01687 IL_LINE_NUM(il_idx) = stmt_start_line; 01688 IL_COL_NUM(il_idx) = stmt_start_col; 01689 } 01690 } 01691 else { 01692 01693 if (last_unlbld_loop_line == stmt_start_line) { 01694 01695 if (last_unlbld_loop_num == MAX_BLK_LOOP_NUM) { 01696 PRINTMSG(stmt_start_line, 1324, Internal, stmt_start_col, 01697 MAX_BLK_LOOP_NUM); 01698 } 01699 else { 01700 BLK_LOOP_NUM(blk_stk_idx) = ++last_unlbld_loop_num; 01701 } 01702 } 01703 else { 01704 last_unlbld_loop_line = stmt_start_line; 01705 last_unlbld_loop_num = 1; 01706 BLK_LOOP_NUM(blk_stk_idx) = 1; 01707 } 01708 } 01709 01710 if (LA_CH_VALUE == COMMA) { 01711 NEXT_LA_CH; 01712 comma_found = TRUE; 01713 } 01714 01715 01716 if (matched_specific_token(Tok_Kwd_While, Tok_Class_Keyword)) { 01717 01718 /* -------------------------------------------------------------------- */ 01719 /* DO WHILE */ 01720 /* -------------------------------------------------------------------- */ 01721 01722 if (LA_CH_VALUE == LPAREN) { 01723 NEXT_LA_CH; 01724 SH_STMT_TYPE(curr_stmt_sh_idx) = Do_While_Stmt; 01725 stmt_type = Do_While_Stmt; 01726 BLK_DO_TYPE(blk_stk_idx) = While_Loop; 01727 01728 expr_start_line = LA_CH_LINE; 01729 expr_start_col = LA_CH_COLUMN; 01730 01731 if (parse_expr(&while_expr)) { 01732 01733 if (LA_CH_VALUE == RPAREN) { 01734 NEXT_LA_CH; 01735 01736 if (LA_CH_VALUE == EOS) { 01737 01738 NTR_IR_LIST_TBL(il_idx); 01739 IL_LIST_CNT(loop_control_il_idx) = 1; 01740 IL_FLD(loop_control_il_idx) = IL_Tbl_Idx; 01741 IL_IDX(loop_control_il_idx) = il_idx; 01742 COPY_OPND(IL_OPND(il_idx), while_expr); 01743 IL_LINE_NUM(il_idx) = expr_start_line; 01744 IL_COL_NUM(il_idx) = expr_start_col; 01745 01746 /* Generate the name of the skip label. */ 01747 /* Attach it to the loop labels IL node. */ 01748 01749 BLK_SKIP_LBL_IDX(blk_stk_idx) = 01750 gen_loop_lbl_name(blk_stk_idx, Skip_Lbl); 01751 01752 if (BLK_SKIP_LBL_IDX(blk_stk_idx) == NULL_IDX) { 01753 goto EXIT; 01754 } 01755 01756 # ifndef _HIGH_LEVEL_DO_LOOP_FORM 01757 01758 NTR_IR_LIST_TBL(il_idx); 01759 IL_LIST_CNT(loop_labels_il_idx) = 1; 01760 IL_FLD(loop_labels_il_idx) = IL_Tbl_Idx; 01761 IL_IDX(loop_labels_il_idx) = il_idx; 01762 01763 IL_LINE_NUM(il_idx) = stmt_start_line; 01764 IL_COL_NUM(il_idx) = stmt_start_col; 01765 IL_FLD(il_idx) = AT_Tbl_Idx; 01766 IL_IDX(il_idx) = BLK_SKIP_LBL_IDX(blk_stk_idx); 01767 01768 01769 /* Generate the name of the top-of-loop label. */ 01770 /* Attach it to the loop labels IL node ahead of the skip */ 01771 /* label IL. */ 01772 01773 NTR_IR_LIST_TBL(il_idx); 01774 IL_NEXT_LIST_IDX(il_idx) = IL_IDX(loop_labels_il_idx); 01775 IL_PREV_LIST_IDX(IL_IDX(loop_labels_il_idx)) = il_idx; 01776 01777 ++IL_LIST_CNT(loop_labels_il_idx); 01778 IL_IDX(loop_labels_il_idx) = il_idx; 01779 01780 IL_LINE_NUM(il_idx) = stmt_start_line; 01781 IL_COL_NUM(il_idx) = stmt_start_col; 01782 IL_FLD(il_idx) = AT_Tbl_Idx; 01783 IL_IDX(il_idx) = gen_loop_lbl_name(blk_stk_idx, Top_Lbl); 01784 01785 AT_DEFINED(IL_IDX(il_idx)) = TRUE; 01786 01787 # endif 01788 01789 if (cif_flags & MISC_RECS) { 01790 cif_stmt_type_rec(TRUE, 01791 (CURR_BLK_LABEL == NULL_IDX) ? 01792 CIF_Do_Unlabeled_While_Stmt : 01793 CIF_Do_Labeled_While_Stmt, 01794 statement_number); 01795 } 01796 } 01797 else { 01798 parse_err_flush(Find_EOS, EOS_STR); 01799 } 01800 } 01801 else { 01802 parse_err_flush(Find_EOS, ")"); 01803 } 01804 } 01805 else { 01806 parse_err_flush(Find_EOS, NULL); 01807 } 01808 } 01809 else if (LA_CH_CLASS == Ch_Class_Letter || 01810 LA_CH_CLASS == Ch_Class_Digit || 01811 LA_CH_VALUE == USCORE || 01812 LA_CH_VALUE == DOLLAR || 01813 LA_CH_VALUE == AT_SIGN) { 01814 reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token)); 01815 goto CHECK_FOR_VARIABLE; 01816 } 01817 else { 01818 parse_err_flush(Find_EOS, "( or ="); 01819 } 01820 01821 goto EXIT; 01822 } 01823 01824 01825 CHECK_FOR_VARIABLE: 01826 01827 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 01828 01829 /* -------------------------------------------------------------------- */ 01830 /* Iterative DO */ 01831 /* -------------------------------------------------------------------- */ 01832 01833 SH_STMT_TYPE(curr_stmt_sh_idx) = Do_Iterative_Stmt; 01834 stmt_type = Do_Iterative_Stmt; 01835 BLK_DO_TYPE(blk_stk_idx) = Iterative_Loop; 01836 01837 expr_start_line = TOKEN_LINE(token); 01838 expr_start_col = TOKEN_COLUMN(token); 01839 01840 if (parse_deref(&do_variable, NULL_IDX)) { 01841 01842 if (mp_nest_list_idx != NULL_IDX) { 01843 COPY_OPND(IL_OPND(mp_nest_list_idx), do_variable); 01844 } 01845 01846 COPY_OPND(BLK_DO_VAR_OPND(blk_stk_idx), do_variable); 01847 BLK_DO_VAR_LINE_NUM(blk_stk_idx) = expr_start_line; 01848 BLK_DO_VAR_COL_NUM(blk_stk_idx) = expr_start_col; 01849 01850 NTR_IR_LIST_TBL(last_il_idx); 01851 IL_LIST_CNT(loop_control_il_idx) = 1; 01852 IL_FLD(loop_control_il_idx) = IL_Tbl_Idx; 01853 IL_IDX(loop_control_il_idx) = last_il_idx; 01854 COPY_OPND(IL_OPND(last_il_idx), BLK_DO_VAR_OPND(blk_stk_idx)); 01855 01856 if (BLK_DO_VAR_FLD(blk_stk_idx) == AT_Tbl_Idx) { 01857 01858 /* If the DO-variable is a function result, we need to set */ 01859 /* AT_DEFINED in the functions' Attr now because */ 01860 /* prog_unit_semantics checks this right away in the Semantics */ 01861 /* Pass driver (if the flag is not set, a warning is issued about*/ 01862 /* the function result not being defined). */ 01863 01864 if (AT_OBJ_CLASS(OPND_IDX(do_variable)) == Data_Obj && 01865 ATD_CLASS(OPND_IDX(do_variable)) == Function_Result) { 01866 AT_DEFINED(ATD_FUNC_IDX(OPND_IDX(do_variable))) = TRUE; 01867 } 01868 01869 01870 blk_idx = blk_stk_idx - 1; 01871 01872 while (BLK_TYPE(blk_idx) > Module_Proc_Blk) { 01873 01874 if (BLK_TYPE(blk_idx) == Do_Blk) { 01875 01876 if ((BLK_DO_VAR_FLD(blk_idx) == 01877 BLK_DO_VAR_FLD(blk_stk_idx)) && 01878 (BLK_DO_VAR_IDX(blk_idx) == 01879 BLK_DO_VAR_IDX(blk_stk_idx)) && 01880 ! BLK_ERR(blk_idx)) { 01881 PRINTMSG(TOKEN_LINE(token), 517, Error, 01882 TOKEN_COLUMN(token)); 01883 break; 01884 } 01885 } 01886 01887 --blk_idx; 01888 } 01889 } 01890 01891 # if defined(CDIR_INTERCHANGE) 01892 process_interchange_dir(); 01893 # endif 01894 01895 # if defined(CDIR_BLOCKABLE) 01896 process_blockable_dir(); 01897 # endif 01898 01899 # if defined(GENERATE_WHIRL) 01900 check_mp_dir_nesting(); 01901 # endif 01902 01903 } 01904 else { 01905 parse_err_flush(Find_EOS, NULL); 01906 goto EXIT; 01907 } 01908 01909 if (LA_CH_VALUE == EQUAL) { 01910 NEXT_LA_CH; 01911 } 01912 else { 01913 parse_err_flush(Find_EOS, "="); 01914 goto EXIT; 01915 } 01916 01917 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 01918 /* Parse the start expression. */ 01919 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 01920 01921 expr_start_line = LA_CH_LINE; 01922 expr_start_col = LA_CH_COLUMN; 01923 01924 if (parse_expr(&loop_expr)) { 01925 01926 /* Note: parse_expr can return TRUE even though an error message is */ 01927 /* produced (like if the start value is a constant with an invalid */ 01928 /* kind parameter). This will cause the DO SH to be marked in */ 01929 /* error but that's OK. */ 01930 01931 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 01932 NTR_IR_LIST_TBL(il_idx); 01933 IL_NEXT_LIST_IDX(last_il_idx) = il_idx; 01934 IL_PREV_LIST_IDX(il_idx) = last_il_idx; 01935 COPY_OPND(IL_OPND(il_idx), loop_expr); 01936 IL_LINE_NUM(il_idx) = expr_start_line; 01937 IL_COL_NUM(il_idx) = expr_start_col; 01938 last_il_idx = il_idx; 01939 ++IL_LIST_CNT(loop_control_il_idx); 01940 } 01941 else { 01942 parse_err_flush(Find_EOS, NULL); 01943 goto EXIT; 01944 } 01945 } 01946 else { 01947 parse_err_flush(Find_EOS, NULL); 01948 goto EXIT; 01949 } 01950 01951 if (LA_CH_VALUE == COMMA) { 01952 NEXT_LA_CH; 01953 } 01954 else { 01955 parse_err_flush(Find_EOS, ","); 01956 goto EXIT; 01957 } 01958 01959 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 01960 /* Parse the end expression. */ 01961 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 01962 01963 expr_start_line = LA_CH_LINE; 01964 expr_start_col = LA_CH_COLUMN; 01965 01966 if (parse_expr(&loop_expr)) { 01967 01968 /* parse_expr could return TRUE because the expression is */ 01969 /* sytactically correct but an error message could still have been */ 01970 /* issued (like for a constant that has an invalid type parameter */ 01971 /* value attached to it) so SH_ERR_FLG of the current stmt must also */ 01972 /* be checked. */ 01973 01974 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 01975 NTR_IR_LIST_TBL(il_idx); 01976 IL_NEXT_LIST_IDX(last_il_idx) = il_idx; 01977 IL_PREV_LIST_IDX(il_idx) = last_il_idx; 01978 COPY_OPND(IL_OPND(il_idx), loop_expr); 01979 IL_LINE_NUM(il_idx) = expr_start_line; 01980 IL_COL_NUM(il_idx) = expr_start_col; 01981 last_il_idx = il_idx; 01982 ++IL_LIST_CNT(loop_control_il_idx); 01983 } 01984 else { 01985 parse_err_flush(Find_EOS, NULL); 01986 goto EXIT; 01987 } 01988 } 01989 else { 01990 parse_err_flush(Find_EOS, NULL); 01991 goto EXIT; 01992 } 01993 01994 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 01995 /* Parse the inc expression. */ 01996 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 01997 01998 if (LA_CH_VALUE == COMMA) { 01999 NEXT_LA_CH; 02000 expr_start_line = LA_CH_LINE; 02001 expr_start_col = LA_CH_COLUMN; 02002 02003 if (parse_expr(&loop_expr)) { 02004 02005 if (LA_CH_VALUE == EOS) { 02006 02007 /* parse_expr could return TRUE because the expression is */ 02008 /* sytactically correct but an error message could still have */ 02009 /* been issued (like for a constant that has an invalid type */ 02010 /* parameter value attached to it) so SH_ERR_FLG of the */ 02011 /* current stmt must also be checked. */ 02012 02013 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 02014 NTR_IR_LIST_TBL(il_idx); 02015 IL_NEXT_LIST_IDX(last_il_idx) = il_idx; 02016 IL_PREV_LIST_IDX(il_idx) = last_il_idx; 02017 COPY_OPND(IL_OPND(il_idx), loop_expr); 02018 IL_LINE_NUM(il_idx) = expr_start_line; 02019 IL_COL_NUM(il_idx) = expr_start_col; 02020 ++IL_LIST_CNT(loop_control_il_idx); 02021 } 02022 else { 02023 parse_err_flush(Find_EOS, NULL); 02024 } 02025 } 02026 else { 02027 parse_err_flush(Find_EOS, EOS_STR); 02028 } 02029 } 02030 else { 02031 parse_err_flush(Find_EOS, NULL); 02032 } 02033 } 02034 else if (LA_CH_VALUE == EOS) { 02035 NTR_IR_LIST_TBL(il_idx); 02036 IL_NEXT_LIST_IDX(last_il_idx) = il_idx; 02037 IL_PREV_LIST_IDX(il_idx) = last_il_idx; 02038 IL_LINE_NUM(il_idx) = expr_start_line; 02039 IL_COL_NUM(il_idx) = expr_start_col; 02040 IL_FLD(il_idx) = CN_Tbl_Idx; 02041 IL_IDX(il_idx) = CN_INTEGER_ONE_IDX; 02042 ++IL_LIST_CNT(loop_control_il_idx); 02043 } 02044 else { 02045 parse_err_flush(Find_EOS, ", or EOS"); 02046 } 02047 02048 /* Generate the name of the skip label. (It gets entered in the */ 02049 /* dictionary and the current block stack entry.) It's generated now */ 02050 /* so that we can tell if there are overlapped blocking stmts (see */ 02051 /* gen_loop_lbl_name for details). If there are overlapped blocking */ 02052 /* stmts, we'll never get to the interface so don't bother doing */ 02053 /* anything more for this DO loop. */ 02054 /* Note: The skip label is generated even when doing "one-trip" DO */ 02055 /* loops (so overlapping block errors will be caught). The label won't */ 02056 /* be used. */ 02057 02058 # ifndef _HIGH_LEVEL_DO_LOOP_FORM 02059 02060 NTR_IR_LIST_TBL(il_idx); 02061 IL_LIST_CNT(loop_labels_il_idx) = 1; 02062 IL_FLD(loop_labels_il_idx) = IL_Tbl_Idx; 02063 IL_IDX(loop_labels_il_idx) = il_idx; 02064 02065 # endif 02066 02067 BLK_SKIP_LBL_IDX(blk_stk_idx) = gen_loop_lbl_name(blk_stk_idx, Skip_Lbl); 02068 02069 if (BLK_SKIP_LBL_IDX(blk_stk_idx) != NULL_IDX) { 02070 02071 # ifndef _HIGH_LEVEL_DO_LOOP_FORM 02072 02073 IL_FLD(il_idx) = AT_Tbl_Idx; 02074 IL_IDX(il_idx) = BLK_SKIP_LBL_IDX(blk_stk_idx); 02075 IL_LINE_NUM(il_idx) = expr_start_line; 02076 IL_COL_NUM(il_idx) = expr_start_col; 02077 02078 # endif 02079 02080 } 02081 else { 02082 goto EXIT; 02083 } 02084 02085 02086 # ifndef _HIGH_LEVEL_DO_LOOP_FORM 02087 02088 /* Generate the name of the top-of-loop label. (It gets entered in the */ 02089 /* dictionary and the current block stack entry.) Put its IL ahead of */ 02090 /* the IL for the skip label. */ 02091 02092 NTR_IR_LIST_TBL(il_idx); 02093 ++IL_LIST_CNT(loop_labels_il_idx); 02094 IL_NEXT_LIST_IDX(il_idx) = IL_IDX(loop_labels_il_idx); 02095 IL_PREV_LIST_IDX(IL_IDX(loop_labels_il_idx)) = il_idx; 02096 IL_IDX(loop_labels_il_idx) = il_idx; 02097 02098 BLK_TOP_LBL_IDX(blk_stk_idx) = gen_loop_lbl_name(blk_stk_idx, Top_Lbl); 02099 02100 IL_LINE_NUM(il_idx) = stmt_start_line; 02101 IL_COL_NUM(il_idx) = stmt_start_col; 02102 IL_FLD(il_idx) = AT_Tbl_Idx; 02103 IL_IDX(il_idx) = BLK_TOP_LBL_IDX(blk_stk_idx); 02104 02105 # endif 02106 02107 if (cif_flags & MISC_RECS) { 02108 cif_stmt_type_rec(TRUE, 02109 (CURR_BLK_LABEL == NULL_IDX) ? 02110 CIF_Do_Unlabeled_Iterative_Stmt : 02111 CIF_Do_Labeled_Iterative_Stmt, 02112 statement_number); 02113 } 02114 02115 goto EXIT; 02116 } 02117 02118 02119 /* ----------------------------------------------------------------------- */ 02120 /* Is this an "infinite" DO loop (that is, "DO ... END DO" or */ 02121 /* "DO <label> ... <label> <term-stmt>")? */ 02122 /* ----------------------------------------------------------------------- */ 02123 02124 if (LA_CH_VALUE == EOS) { 02125 02126 if (comma_found) { 02127 parse_err_flush(Find_EOS, "do-variable or WHILE"); 02128 } 02129 else { 02130 SH_STMT_TYPE(curr_stmt_sh_idx) = Do_Infinite_Stmt; 02131 stmt_type = Do_Infinite_Stmt; 02132 BLK_DO_TYPE(blk_stk_idx) = Infinite_Loop; 02133 02134 /* Generate the name of the top-of-loop label. */ 02135 02136 NTR_IR_LIST_TBL(il_idx); 02137 IL_LIST_CNT(loop_labels_il_idx) = 1; 02138 IL_FLD(loop_labels_il_idx) = IL_Tbl_Idx; 02139 IL_IDX(loop_labels_il_idx) = il_idx; 02140 02141 # ifndef _ACSET 02142 02143 IL_LINE_NUM(il_idx) = stmt_start_line; 02144 IL_COL_NUM(il_idx) = stmt_start_col; 02145 IL_FLD(il_idx) = AT_Tbl_Idx; 02146 IL_IDX(il_idx) = gen_loop_lbl_name(blk_stk_idx, Top_Lbl); 02147 02148 # endif 02149 02150 if (cif_flags & MISC_RECS) { 02151 cif_stmt_type_rec(TRUE, 02152 (CURR_BLK_LABEL == NULL_IDX) ? 02153 CIF_Do_Unlabeled_Infinite_Stmt : 02154 CIF_Do_Labeled_Infinite_Stmt, 02155 statement_number); 02156 } 02157 } 02158 } 02159 else { 02160 02161 if (comma_found) { 02162 parse_err_flush(Find_EOS, "do-variable or WHILE"); 02163 } 02164 else if (label_found) { 02165 PRINTMSG(LA_CH_LINE, 513, Error, LA_CH_COLUMN, LA_CH_VALUE); 02166 parse_err_flush(Find_EOS, NULL); 02167 } 02168 else { 02169 PRINTMSG(LA_CH_LINE, 515, Error, LA_CH_COLUMN, LA_CH_VALUE); 02170 parse_err_flush(Find_EOS, NULL); 02171 } 02172 } 02173 02174 EXIT: 02175 02176 if (mp_nest_list_idx != NULL_IDX && 02177 IL_FLD(mp_nest_list_idx) == NO_Tbl_Idx) { 02178 02179 /* error situation, free the list entry */ 02180 FREE_IR_LIST_NODE(mp_nest_list_idx); 02181 IL_OPND(mp_prev_idx) = null_opnd; 02182 } 02183 02184 NEXT_LA_CH; 02185 02186 /* Clear out the shortloop flags. They will be reset in pass 2. */ 02187 02188 cdir_switches.shortloop = FALSE; 02189 cdir_switches.shortloop128 = FALSE; 02190 02191 TRACE (Func_Exit, "parse_do_stmt", NULL); 02192 02193 return; 02194 02195 } /* parse_do_stmt */ 02196 02197 02198 /******************************************************************************\ 02199 |* *| 02200 |* Description: *| 02201 |* This function handles the following syntax: *| 02202 |* else-stmt => ELSE [if-construct-name] *| 02203 |* else-if-stmt => ELSE IF (scalar-logical-expr) THEN *| 02204 |* [if-construct-name] *| 02205 |* elsewhere-stmt => ELSE WHERE *| 02206 |* *| 02207 |* Note that ELSE WHERE will require consulting the block stack to *| 02208 |* determine if it is actually an ELSEWHERE stmt or an ELSE stmt with a *| 02209 |* construct name of WHERE. *| 02210 |* *| 02211 |* Input parameters: *| 02212 |* NONE *| 02213 |* *| 02214 |* Output parameters: *| 02215 |* NONE *| 02216 |* *| 02217 |* Returns: *| 02218 |* NONE *| 02219 |* *| 02220 \******************************************************************************/ 02221 02222 void parse_else_stmt (void) 02223 02224 { 02225 int blk_idx; 02226 blk_cntxt_type blk_type = If_Else_Blk; 02227 opnd_type cond_expr; 02228 02229 # if 0 02230 int cont_lbl_idx; 02231 int end_lbl_idx; 02232 # endif 02233 02234 blk_cntxt_type err_blk; 02235 int expr_start_line; 02236 int expr_start_col; 02237 boolean found_name = FALSE; 02238 int il_idx_1; 02239 int il_idx_2; 02240 int ir_idx; 02241 boolean matched_blk = FALSE; 02242 int name_idx; 02243 boolean prev_clause_in_err; 02244 int sh_idx; 02245 02246 02247 TRACE (Func_Entry, "parse_else_stmt", NULL); 02248 02249 check_for_vestigial_task_blks(); 02250 02251 /* ----------------------------------------------------------------------- */ 02252 /* ELSE (with no if-construct-name) */ 02253 /* ----------------------------------------------------------------------- */ 02254 02255 if (LA_CH_VALUE == EOS) { 02256 matched_blk = STMT_LEGAL_IN_BLK(Else_Stmt, CURR_BLK); 02257 02258 if (cif_flags & MISC_RECS) { 02259 cif_stmt_type_rec(TRUE, CIF_Else_Stmt, statement_number); 02260 } 02261 } 02262 02263 else if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) { 02264 02265 /* -------------------------------------------------------------------- */ 02266 /* ELSE IF, or ELSEWHERE, or ELSE with if-construct-name */ 02267 /* -------------------------------------------------------------------- */ 02268 02269 if (TOKEN_VALUE(token) == Tok_Kwd_If && LA_CH_VALUE == LPAREN) { 02270 02271 /* ----------------------------------------------------------------- */ 02272 /* ELSE IF */ 02273 /* ----------------------------------------------------------------- */ 02274 02275 blk_type = If_Else_If_Blk; 02276 stmt_type = Else_If_Stmt; 02277 SH_STMT_TYPE(curr_stmt_sh_idx) = Else_If_Stmt; 02278 02279 NEXT_LA_CH; 02280 02281 expr_start_line = LA_CH_LINE; 02282 expr_start_col = LA_CH_COLUMN; 02283 02284 if (parse_expr(&cond_expr)) { 02285 02286 if (LA_CH_VALUE == RPAREN) { 02287 NEXT_LA_CH; 02288 02289 if (matched_specific_token(Tok_Kwd_Then, Tok_Class_Keyword)) { 02290 02291 if (LA_CH_VALUE != EOS) { 02292 02293 if ( (found_name = MATCHED_TOKEN_CLASS(Tok_Class_Id)) ) { 02294 02295 if (LA_CH_VALUE != EOS) { 02296 parse_err_flush(Find_EOS, EOS_STR); 02297 } 02298 } 02299 else { 02300 parse_err_flush(Find_EOS, "if-construct-name"); 02301 } 02302 } 02303 } 02304 else { 02305 parse_err_flush(Find_EOS, "THEN"); 02306 } 02307 } 02308 else { 02309 parse_err_flush(Find_EOS, ")"); 02310 } 02311 } 02312 else { 02313 parse_err_flush(Find_EOS, NULL); 02314 } 02315 02316 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 02317 goto EXIT; 02318 } 02319 02320 if (cif_flags & MISC_RECS) { 02321 cif_stmt_type_rec(TRUE, CIF_Else_If_Stmt, statement_number); 02322 } 02323 02324 if (STMT_LEGAL_IN_BLK(Else_If_Stmt, CURR_BLK)) { 02325 matched_blk = (found_name) ? (CURR_BLK_NAME != NULL_IDX && 02326 (compare_names(TOKEN_ID(token).words, 02327 TOKEN_LEN(token), 02328 AT_OBJ_NAME_LONG(CURR_BLK_NAME), 02329 AT_NAME_LEN(CURR_BLK_NAME)) == 0)): 02330 TRUE; 02331 } 02332 } 02333 else if (TOKEN_VALUE(token) == Tok_Kwd_Where && LA_CH_VALUE == LPAREN) { 02334 /* ----------------------------------------------------------------- */ 02335 /* ELSE WHERE (mask) [construct_name] */ 02336 /* ----------------------------------------------------------------- */ 02337 02338 blk_type = Where_Else_Mask_Blk; 02339 stmt_type = Else_Where_Mask_Stmt; 02340 SH_STMT_TYPE(curr_stmt_sh_idx) = Else_Where_Mask_Stmt; 02341 02342 NTR_IR_TBL(ir_idx); 02343 IR_OPR(ir_idx) = Else_Where_Mask_Opr; 02344 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 02345 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 02346 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 02347 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 02348 02349 NEXT_LA_CH; 02350 02351 expr_start_line = LA_CH_LINE; 02352 expr_start_col = LA_CH_COLUMN; 02353 02354 if (parse_expr(&cond_expr)) { 02355 02356 COPY_OPND(IR_OPND_L(ir_idx), cond_expr); 02357 02358 if (LA_CH_VALUE == RPAREN) { 02359 NEXT_LA_CH; 02360 02361 if (LA_CH_VALUE != EOS) { 02362 02363 if ( (found_name = MATCHED_TOKEN_CLASS(Tok_Class_Id)) ) { 02364 02365 if (LA_CH_VALUE != EOS) { 02366 parse_err_flush(Find_EOS, EOS_STR); 02367 } 02368 } 02369 else { 02370 parse_err_flush(Find_EOS, "where-construct-name"); 02371 } 02372 } 02373 } 02374 else { 02375 parse_err_flush(Find_EOS, ")"); 02376 } 02377 } 02378 else { 02379 parse_err_flush(Find_EOS, NULL); 02380 } 02381 02382 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 02383 goto EXIT; 02384 } 02385 02386 if (cif_flags & MISC_RECS) { 02387 cif_stmt_type_rec(TRUE, CIF_Elsewhere_Stmt, statement_number); 02388 } 02389 02390 if (STMT_LEGAL_IN_BLK(Else_Where_Mask_Stmt, CURR_BLK)) { 02391 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = CURR_BLK_FIRST_SH_IDX; 02392 02393 matched_blk = (found_name) ? (CURR_BLK_NAME != NULL_IDX && 02394 (compare_names(TOKEN_ID(token).words, 02395 TOKEN_LEN(token), 02396 AT_OBJ_NAME_LONG(CURR_BLK_NAME), 02397 AT_NAME_LEN(CURR_BLK_NAME)) == 0)): 02398 TRUE; 02399 } 02400 } 02401 else if (TOKEN_VALUE(token) == Tok_Kwd_Where && 02402 (CURR_BLK == Where_Then_Blk || 02403 CURR_BLK == Where_Else_Mask_Blk)) { 02404 02405 /* -------------------------------------------------------------- */ 02406 /* ELSEWHERE [construct_name] */ 02407 /* -------------------------------------------------------------- */ 02408 02409 stmt_type = Else_Where_Stmt; 02410 SH_STMT_TYPE(curr_stmt_sh_idx) = Else_Where_Stmt; 02411 blk_type = Where_Else_Blk; 02412 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = CURR_BLK_FIRST_SH_IDX; 02413 02414 NTR_IR_TBL(ir_idx); 02415 IR_OPR(ir_idx) = Else_Where_Opr; 02416 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 02417 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 02418 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 02419 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 02420 02421 02422 if (LA_CH_VALUE != EOS) { 02423 02424 if ( (found_name = MATCHED_TOKEN_CLASS(Tok_Class_Id)) ) { 02425 02426 if (LA_CH_VALUE != EOS) { 02427 parse_err_flush(Find_EOS, EOS_STR); 02428 } 02429 } 02430 else { 02431 parse_err_flush(Find_EOS, "where-construct-name"); 02432 } 02433 } 02434 02435 matched_blk = (found_name) ? (CURR_BLK_NAME != NULL_IDX && 02436 (compare_names(TOKEN_ID(token).words, 02437 TOKEN_LEN(token), 02438 AT_OBJ_NAME_LONG(CURR_BLK_NAME), 02439 AT_NAME_LEN(CURR_BLK_NAME)) == 0)): 02440 TRUE; 02441 02442 if (cif_flags & MISC_RECS) { 02443 cif_stmt_type_rec(TRUE, CIF_Elsewhere_Stmt, statement_number); 02444 } 02445 } 02446 else if (TOKEN_VALUE(token) == Tok_Kwd_Where && LA_CH_VALUE == EOS) { 02447 02448 if (STMT_LEGAL_IN_BLK(Else_Stmt, CURR_BLK) && 02449 (CURR_BLK_NAME != NULL_IDX && 02450 (compare_names(TOKEN_ID(token).words, 02451 TOKEN_LEN(token), 02452 AT_OBJ_NAME_LONG(CURR_BLK_NAME), 02453 AT_NAME_LEN(CURR_BLK_NAME)) == 0)) ) { 02454 02455 /* -------------------------------------------------------------- */ 02456 /* ELSE with if-construct-name WHERE */ 02457 /* -------------------------------------------------------------- */ 02458 02459 matched_blk = TRUE; 02460 found_name = TRUE; 02461 02462 if (cif_flags & MISC_RECS) { 02463 cif_stmt_type_rec(TRUE, CIF_Else_Stmt, statement_number); 02464 } 02465 } 02466 else if (match_blk(Where_Then_Blk, FALSE) >= 02467 match_blk(If_Blk, FALSE)) { 02468 02469 /* We got to this "else if" due to an error case: either the ELSE*/ 02470 /* is not valid in the current block, or the ELSE is valid but */ 02471 /* WHERE does not match the if-construct-name on the if-then-stmt.*/ 02472 /* Reaching this point means match_blk found a Where_Then_Blk */ 02473 /* before an If_Blk, or neither a matching If_Blk nor a matching */ 02474 /* Where_Then_Blk was found. */ 02475 02476 stmt_type = Else_Where_Stmt; 02477 SH_STMT_TYPE(curr_stmt_sh_idx) = Else_Where_Stmt; 02478 blk_type = Where_Else_Blk; 02479 02480 if (cif_flags & MISC_RECS) { 02481 cif_stmt_type_rec(TRUE, CIF_Elsewhere_Stmt, statement_number); 02482 } 02483 } 02484 else { 02485 02486 /* We've found a matching if-then-stmt but it either has no if- */ 02487 /* construct-name, or it does but it's not WHERE. */ 02488 02489 found_name = TRUE; 02490 02491 if (cif_flags & MISC_RECS) { 02492 cif_stmt_type_rec(TRUE, CIF_Else_Stmt, statement_number); 02493 } 02494 } 02495 } 02496 else { 02497 02498 /* ----------------------------------------------------------------- */ 02499 /* ELSE statement with construct-name starting with WHERE or IF. */ 02500 /* ----------------------------------------------------------------- */ 02501 02502 found_name = TRUE; 02503 02504 if (TOKEN_VALUE(token) != Tok_Id) { /* In case its WHEREABC */ 02505 reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token)); 02506 MATCHED_TOKEN_CLASS(Tok_Class_Id); 02507 } 02508 02509 if (CURR_BLK == If_Then_Blk || CURR_BLK == If_Else_If_Blk) { 02510 matched_blk = CURR_BLK_NAME != NULL_IDX && 02511 (compare_names(TOKEN_ID(token).words, 02512 TOKEN_LEN(token), 02513 AT_OBJ_NAME_LONG(CURR_BLK_NAME), 02514 AT_NAME_LEN(CURR_BLK_NAME)) == 0); 02515 } 02516 02517 if (cif_flags & MISC_RECS) { 02518 cif_stmt_type_rec(TRUE, CIF_Else_Stmt, statement_number); 02519 } 02520 02521 if (LA_CH_VALUE != EOS) { 02522 parse_err_flush(Find_EOS, EOS_STR); 02523 } 02524 } 02525 } 02526 else { 02527 parse_err_flush(Find_EOS, "IF, WHERE, a construct name or EOS"); 02528 } 02529 02530 /* ----------------------------------------------------------------------- */ 02531 /* If the ELSE, ELSE IF, or ELSEWHERE is in a valid location, adjust the */ 02532 /* block stack and generate the IR (actually for the previous clause) to */ 02533 /* jump around the clause currently being processed. Otherwise, recover */ 02534 /* from the misplaced statement. */ 02535 /* ----------------------------------------------------------------------- */ 02536 02537 if (matched_blk) { 02538 curr_stmt_category = Executable_Stmt_Cat; 02539 02540 if ((cif_flags & XREF_RECS) && found_name) { 02541 cif_usage_rec(CURR_BLK_NAME, AT_Tbl_Idx, 02542 TOKEN_LINE(token), TOKEN_COLUMN(token), 02543 CIF_Construct_Name_Reference); 02544 } 02545 02546 if (blk_type != Where_Else_Blk && 02547 blk_type != Where_Else_Mask_Blk && 02548 ! SH_ERR_FLG(curr_stmt_sh_idx)) { 02549 02550 /* If we are currently processing the ELSE stmt or the first ELSE IF */ 02551 /* stmt of this IF construct, grab the branch-around label from the */ 02552 /* If_Blk block stack entry and replace it with the label that will */ 02553 /* be used by all following clauses for the "end IF" label. For an */ 02554 /* ELSE, this just ends up being its branch-around label. */ 02555 /* */ 02556 /* Otherwise, we are processing the second (or beyond) ELSE IF or an */ 02557 /* ELSE following such an ELSE IF. Since the ELSE IF/ELSE currently */ 02558 /* being processed has not yet been pushed on the block stack, the */ 02559 /* current block stack entry is for the previous ELSE IF. Thus, the */ 02560 /* label being plucked out of the block stack entry is the branch- */ 02561 /* around label for the previous ELSE IF which defines the beginning */ 02562 /* of the current ELSE IF or ELSE clause. */ 02563 02564 # ifdef _DEBUG 02565 if (BLK_TYPE(blk_stk_idx - 1) != If_Blk) { 02566 PRINTMSG(stmt_start_line, 160, Internal, 0, blk_stk_idx); 02567 } 02568 # endif 02569 02570 #if 0 02571 if (CURR_BLK == If_Then_Blk) { 02572 cont_lbl_idx = BLK_LABEL(blk_stk_idx - 1); 02573 end_lbl_idx = gen_internal_lbl(stmt_start_line); 02574 BLK_LABEL(blk_stk_idx - 1) = end_lbl_idx; 02575 } 02576 else { 02577 cont_lbl_idx = CURR_BLK_LABEL; 02578 end_lbl_idx = BLK_LABEL(blk_stk_idx - 1); 02579 } 02580 #endif 02581 02582 } 02583 02584 prev_clause_in_err = SH_ERR_FLG(CURR_BLK_FIRST_SH_IDX); 02585 02586 if (blk_type != Where_Else_Blk && 02587 blk_type != Where_Else_Mask_Blk) { 02588 blk_idx = blk_stk_idx; 02589 02590 if (CURR_BLK == If_Then_Blk) { 02591 --blk_idx; 02592 } 02593 02594 sh_idx = BLK_FIRST_SH_IDX(blk_idx); 02595 } 02596 02597 if (blk_type == Where_Else_Blk || 02598 blk_type == Where_Else_Mask_Blk) { 02599 name_idx = CURR_BLK_NAME; 02600 } 02601 02602 POP_BLK_STK; 02603 PUSH_BLK_STK(blk_type); 02604 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 02605 02606 if (blk_type == Where_Else_Blk || 02607 blk_type == Where_Else_Mask_Blk) { 02608 CURR_BLK_NAME = name_idx; 02609 CURR_BLK_NO_EXEC = TRUE; 02610 } 02611 else { 02612 CURR_BLK_NAME = BLK_NAME(blk_stk_idx - 1); 02613 LINK_TO_PARENT_BLK; 02614 02615 if (SH_ERR_FLG(SH_PARENT_BLK_IDX(curr_stmt_sh_idx)) || 02616 prev_clause_in_err) { 02617 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 02618 } 02619 02620 /* If the ELSE IF (and IF) are OK, generate a Br_True IR to hold the */ 02621 /* conditional expression and branch-around label. The .NOT. */ 02622 /* subtree is added by the Semantics Pass if the expression is OK. */ 02623 /* Since the SH_PARENT_BLK_IDX field is needed to link to actual */ 02624 /* parent blocks for invalid label reference detection and since */ 02625 /* there is no more room in an SH for another SH index, we need to */ 02626 /* hold the "previous IF construct part" SH index elsewhere. For an */ 02627 /* ELSE IF, generate a Br_True IR and attach two ILs to the right */ 02628 /* operand. Save the "previous IF construct part" SH index in the */ 02629 /* second IL. The Semantics Pass will put the branch-around label */ 02630 /* in the first IL. For an ELSE, generate an If IR and save the SH */ 02631 /* index in the left operand. */ 02632 02633 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 02634 NTR_IR_TBL(ir_idx); 02635 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 02636 IR_TYPE_IDX(ir_idx) = LOGICAL_DEFAULT_TYPE; 02637 IR_LINE_NUM(ir_idx) = expr_start_line; 02638 IR_COL_NUM(ir_idx) = expr_start_col; 02639 02640 if (blk_type == If_Else_If_Blk) { 02641 IR_OPR(ir_idx) = Br_True_Opr; 02642 COPY_OPND(IR_OPND_L(ir_idx), cond_expr); 02643 NTR_IR_LIST_TBL(il_idx_1); 02644 IR_LIST_CNT_R(ir_idx) = 1; 02645 IR_FLD_R(ir_idx) = IL_Tbl_Idx; 02646 IR_IDX_R(ir_idx) = il_idx_1; 02647 NTR_IR_LIST_TBL(il_idx_2); 02648 IR_LIST_CNT_R(ir_idx) = 2; 02649 IL_NEXT_LIST_IDX(il_idx_1) = il_idx_2; 02650 IL_PREV_LIST_IDX(il_idx_2) = il_idx_1; 02651 IL_LINE_NUM(il_idx_2) = stmt_start_line; 02652 IL_COL_NUM(il_idx_2) = stmt_start_col; 02653 IL_FLD(il_idx_2) = SH_Tbl_Idx; 02654 IL_IDX(il_idx_2) = sh_idx; 02655 } 02656 else { 02657 IR_OPR(ir_idx) = Else_Opr; 02658 IR_LINE_NUM(ir_idx) = stmt_start_line; 02659 IR_COL_NUM(ir_idx) = stmt_start_col; 02660 IR_FLD_L(ir_idx) = SH_Tbl_Idx; 02661 IR_IDX_L(ir_idx) = sh_idx; 02662 } 02663 #if 0 02664 CURR_BLK_LABEL = gen_internal_lbl(stmt_start_line); 02665 IR_LINE_NUM_R(ir_idx) = stmt_start_line; 02666 IR_COL_NUM_R(ir_idx) = stmt_start_col; 02667 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 02668 IR_IDX_R(ir_idx) = CURR_BLK_LABEL; 02669 #endif 02670 02671 02672 #if 0 02673 /* Now AHEAD of the ELSE IF or ELSE SH, generate a GO TO stmt to */ 02674 /* branch to the end of the IF construct and a CONTINUE stmt to */ 02675 /* define the start of the ELSE IF or ELSE. */ 02676 02677 gen_sh(Before, Goto_Stmt, 02678 SH_GLB_LINE(SH_PREV_IDX(curr_stmt_sh_idx)), 02679 SH_COL_NUM(SH_PREV_IDX(curr_stmt_sh_idx)), 02680 FALSE, FALSE, TRUE); 02681 02682 sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 02683 NTR_IR_TBL(ir_idx); 02684 SH_IR_IDX(sh_idx) = ir_idx; 02685 IR_OPR(ir_idx) = Br_Uncond_Opr; 02686 /* LRR - bhj put in short typeless as type idx */ 02687 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 02688 IR_LINE_NUM(ir_idx) = SH_GLB_LINE(SH_PREV_IDX(sh_idx)); 02689 IR_COL_NUM(ir_idx) = SH_COL_NUM(SH_PREV_IDX(sh_idx)); 02690 02691 IR_LINE_NUM_R(ir_idx) = SH_GLB_LINE(SH_PREV_IDX(sh_idx)); 02692 IR_COL_NUM_R(ir_idx) = SH_COL_NUM(SH_PREV_IDX(sh_idx)); 02693 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 02694 IR_IDX_R(ir_idx) = end_lbl_idx; 02695 02696 gen_sh(Before, Continue_Stmt, stmt_start_line, stmt_start_col, 02697 FALSE, TRUE, TRUE); 02698 02699 sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 02700 NTR_IR_TBL(ir_idx); 02701 SH_IR_IDX(sh_idx) = ir_idx; 02702 IR_OPR(ir_idx) = Label_Opr; 02703 /* LRR - bhj put in short typeless as type idx */ 02704 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 02705 IR_LINE_NUM(ir_idx) = stmt_start_line; 02706 IR_COL_NUM(ir_idx) = stmt_start_col; 02707 IR_LINE_NUM_L(ir_idx) = stmt_start_line; 02708 IR_COL_NUM_L(ir_idx) = stmt_start_col; 02709 IR_FLD_L(ir_idx) = AT_Tbl_Idx; 02710 IR_IDX_L(ir_idx) = cont_lbl_idx; 02711 AT_DEFINED(cont_lbl_idx) = TRUE; 02712 AT_DEF_LINE(cont_lbl_idx) = stmt_start_line; 02713 AT_DEF_COLUMN(cont_lbl_idx) = stmt_start_col; 02714 AT_REFERENCED(cont_lbl_idx) = Referenced; 02715 ATL_DEF_STMT_IDX(cont_lbl_idx) = sh_idx; 02716 #endif 02717 } 02718 } 02719 } 02720 else { 02721 err_blk = (blk_type == Where_Else_Blk || 02722 blk_type == Where_Else_Mask_Blk) ? Where_Then_Blk : If_Blk; 02723 blk_idx = blk_match_err(err_blk, found_name, FALSE); 02724 02725 /* blk_match_err moves the matched block to the current block */ 02726 02727 if (blk_idx != NULL_IDX) { 02728 if (blk_type == Where_Else_Blk || 02729 blk_type == Where_Else_Mask_Blk) { 02730 name_idx = CURR_BLK_NAME; 02731 } 02732 02733 POP_BLK_STK; 02734 PUSH_BLK_STK(blk_type); 02735 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 02736 02737 if (blk_type == Where_Else_Blk || 02738 blk_type == Where_Else_Mask_Blk) { 02739 CURR_BLK_NAME = name_idx; 02740 CURR_BLK_NO_EXEC = TRUE; 02741 } 02742 else { 02743 CURR_BLK_NAME = BLK_NAME(blk_stk_idx - 1); 02744 LINK_TO_PARENT_BLK; 02745 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 02746 } 02747 02748 # if 0 02749 if (cif_flags & XREF_RECS) { 02750 cif_usage_rec(CURR_BLK_NAME, AT_Tbl_Idx, 02751 TOKEN_LINE(token), TOKEN_COLUMN(token), 02752 CIF_Construct_Name_Reference); 02753 } 02754 # endif 02755 } 02756 } 02757 02758 EXIT: 02759 02760 NEXT_LA_CH; 02761 02762 TRACE (Func_Exit, "parse_else_stmt", NULL); 02763 02764 return; 02765 02766 } /* parse_else_stmt */ 02767 02768 02769 /******************************************************************************\ 02770 |* *| 02771 |* Description: *| 02772 |* Parse the EXIT statement. If a matching DO construct is found, *| 02773 |* generate the internal exit point label and a Br_Uncond IR to jump to *| 02774 |* it. *| 02775 |* *| 02776 |* Input parameters: *| 02777 |* NONE *| 02778 |* *| 02779 |* Output parameters: *| 02780 |* NONE *| 02781 |* *| 02782 |* Returns: *| 02783 |* NONE *| 02784 |* *| 02785 \******************************************************************************/ 02786 02787 void parse_exit_stmt (void) 02788 02789 { 02790 int blk_idx; 02791 boolean fnd_name = FALSE; 02792 int ir_idx; 02793 02794 02795 TRACE (Func_Entry, "parse_exit_stmt", NULL); 02796 02797 if (LA_CH_VALUE != EOS) { 02798 fnd_name = MATCHED_TOKEN_CLASS(Tok_Class_Id); 02799 02800 if (fnd_name) { 02801 02802 if (LA_CH_VALUE != EOS) { 02803 parse_err_flush(Find_EOS, EOS_STR); 02804 } 02805 02806 } 02807 else { 02808 parse_err_flush(Find_EOS, "construct-name or EOS"); 02809 goto EXIT; 02810 } 02811 02812 } 02813 02814 blk_idx = match_blk(Do_Blk, fnd_name); 02815 02816 if (blk_idx != NULL_IDX) { 02817 02818 if (! CURR_BLK_NO_EXEC || ! iss_blk_stk_err()) { 02819 curr_stmt_category = Executable_Stmt_Cat; 02820 SH_P2_SKIP_ME(curr_stmt_sh_idx) = TRUE; 02821 BLK_EXIT_STMT(blk_idx) = TRUE; 02822 02823 NTR_IR_TBL(ir_idx); 02824 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 02825 IR_OPR(ir_idx) = Br_Uncond_Opr; 02826 /* LRR - bhj put in short typeless as type idx */ 02827 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 02828 IR_LINE_NUM(ir_idx) = stmt_start_line; 02829 IR_COL_NUM(ir_idx) = stmt_start_col; 02830 IR_LINE_NUM_R(ir_idx) = stmt_start_line; 02831 IR_COL_NUM_R(ir_idx) = stmt_start_col; 02832 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 02833 IR_IDX_R(ir_idx) = gen_loop_lbl_name(blk_idx, Exit_Lbl); 02834 02835 if (fnd_name && (cif_flags & XREF_RECS)) { 02836 cif_usage_rec(BLK_NAME(blk_idx), AT_Tbl_Idx, 02837 TOKEN_LINE(token), TOKEN_COLUMN(token), 02838 CIF_Construct_Name_Reference); 02839 } 02840 } 02841 02842 } 02843 else { 02844 PRINTMSG(stmt_start_line, 262, Error, stmt_start_col, "EXIT"); 02845 } 02846 02847 EXIT: 02848 02849 NEXT_LA_CH; 02850 02851 TRACE (Func_Exit, "parse_exit_stmt", NULL); 02852 02853 return; 02854 02855 } /* parse_exit_stmt */ 02856 02857 /******************************************************************************\ 02858 |* *| 02859 |* Description: *| 02860 |* This function parses both the FORALL construct statement and the *| 02861 |* FORALL statement. *| 02862 |* *| 02863 |* Input parameters: *| 02864 |* NONE *| 02865 |* *| 02866 |* Output parameters: *| 02867 |* NONE *| 02868 |* *| 02869 |* Returns: *| 02870 |* NONE *| 02871 |* *| 02872 \******************************************************************************/ 02873 02874 void parse_forall (void) 02875 02876 { 02877 opnd_type an_opnd; 02878 int blk_stk_start; 02879 int expr_start_line; 02880 int expr_start_col; 02881 int forall_ir_idx; 02882 int forall_sh_idx; 02883 boolean found_colon; 02884 boolean found_comma; 02885 int i; 02886 int il_idx; 02887 int index_name_il_idx; 02888 int mask_il_idx; 02889 int stride_il_idx; 02890 int subscript1_il_idx; 02891 int subscript2_il_idx; 02892 int triplet_spec_il_idx; 02893 02894 02895 TRACE (Func_Entry, "parse_forall", NULL); 02896 02897 /* Generate the Forall IR. If the FORALL turns out to be a FORALL */ 02898 /* construct, the left operand will eventually point at the END FORALL SH. */ 02899 /* The right operand will point at an IL list. If you think of the ILs */ 02900 /* in a horizontal list, there will be one IL for each */ 02901 /* <forall-triplet-spec> and one (at the end of the chain) for the */ 02902 /* <scalar-mask-expr> (if such an expression is present). Each of the ILs */ 02903 /* for the triplet specs points at a chain of ILs (think of them as being */ 02904 /* vertical below the triplet spec ILs) that hold the info for the index */ 02905 /* name, both subscript expressions, and the stride expression. If the */ 02906 /* user does not specify the stride, the compiler will supply the default */ 02907 /* 1 so the list for each triplet spec is always complete. */ 02908 02909 NTR_IR_TBL(forall_ir_idx); 02910 SH_IR_IDX(curr_stmt_sh_idx) = forall_ir_idx; 02911 IR_OPR(forall_ir_idx) = Forall_Opr; 02912 IR_TYPE_IDX(forall_ir_idx) = TYPELESS_DEFAULT_TYPE; 02913 IR_LINE_NUM(forall_ir_idx) = stmt_start_line; 02914 IR_COL_NUM(forall_ir_idx) = stmt_start_col; 02915 02916 02917 /* ----------------------------------------------------------------------- */ 02918 /* Parse the <forall-header>: */ 02919 /* ( <forall-triplet-spec-list> [ , <scalar-mask-expr> ] ) */ 02920 /* */ 02921 /* <forall-triplet-spec> is <index-name> = <subscript> : <subscript> */ 02922 /* [ : <stride> ] */ 02923 /* ----------------------------------------------------------------------- */ 02924 02925 /* Look for the left paren and then the <index-name>. If there is */ 02926 /* anything wrong, don't try to recover to the right paren (in the hopes */ 02927 /* of being able to parse the <forall-assignment-stmt> if this is a FORALL */ 02928 /* stmt because the subscript, stride, and mask can all be expressions */ 02929 /* that could contain right parens. Don't check here for the <index-name> */ 02930 /* being a (unqualified) name. Like the DO-variable check, this is done */ 02931 /* in semantic processing. Also, don't check for the <index-name> */ 02932 /* duplicating an <index-name> of an outer FORALL until we know we've got */ 02933 /* a valid FORALL. */ 02934 02935 if (LA_CH_VALUE == LPAREN) { 02936 NEXT_LA_CH; 02937 02938 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 02939 expr_start_line = TOKEN_LINE(token); 02940 expr_start_col = TOKEN_COLUMN(token); 02941 02942 if (parse_deref(&an_opnd, NULL_IDX)) { 02943 NTR_IR_LIST_TBL(triplet_spec_il_idx); 02944 IR_LIST_CNT_R(forall_ir_idx) = 1; 02945 IR_FLD_R(forall_ir_idx) = IL_Tbl_Idx; 02946 IR_IDX_R(forall_ir_idx) = triplet_spec_il_idx; 02947 02948 NTR_IR_LIST_TBL(index_name_il_idx); 02949 IL_FLD(triplet_spec_il_idx) = IL_Tbl_Idx; 02950 IL_IDX(triplet_spec_il_idx) = index_name_il_idx; 02951 IL_LIST_CNT(triplet_spec_il_idx) = 1; 02952 02953 COPY_OPND(IL_OPND(index_name_il_idx), an_opnd); 02954 } 02955 else { 02956 parse_err_flush(Find_EOS, NULL); 02957 goto EXIT; 02958 } 02959 } 02960 else { 02961 parse_err_flush(Find_EOS, "index-name"); 02962 goto EXIT; 02963 } 02964 } 02965 else { 02966 parse_err_flush(Find_EOS, "("); 02967 goto EXIT; 02968 } 02969 02970 NEXT_TRIPLET_SPEC: 02971 02972 if (LA_CH_VALUE == EQUAL) { 02973 NEXT_LA_CH; 02974 } 02975 else { 02976 parse_err_flush(Find_EOS, "="); 02977 goto EXIT; 02978 } 02979 02980 02981 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 02982 /* Parse the first subscript expression. */ 02983 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 02984 02985 /* Capture the beginning of the expression so the IL line and column will */ 02986 /* point at the beginning of the expression as opposed to the line and */ 02987 /* column from the root IR of the expression. */ 02988 02989 expr_start_line = LA_CH_LINE; 02990 expr_start_col = LA_CH_COLUMN; 02991 02992 02993 if (parse_expr(&an_opnd)) { 02994 02995 /* Note: parse_expr can return TRUE even though an error message is */ 02996 /* produced (like if the subscript is a constant with an invalid kind */ 02997 /* parameter). This will cause the FORALL SH to be marked in error */ 02998 /* but that's OK. */ 02999 03000 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 03001 NTR_IR_LIST_TBL(subscript1_il_idx); 03002 IL_NEXT_LIST_IDX(index_name_il_idx) = subscript1_il_idx; 03003 IL_PREV_LIST_IDX(subscript1_il_idx) = index_name_il_idx; 03004 COPY_OPND(IL_OPND(subscript1_il_idx), an_opnd); 03005 IL_LINE_NUM(subscript1_il_idx) = expr_start_line; 03006 IL_COL_NUM(subscript1_il_idx) = expr_start_col; 03007 ++IL_LIST_CNT(triplet_spec_il_idx); 03008 } 03009 else { 03010 parse_err_flush(Find_EOS, NULL); 03011 goto EXIT; 03012 } 03013 } 03014 else { 03015 parse_err_flush(Find_EOS, NULL); 03016 goto EXIT; 03017 } 03018 03019 03020 if (LA_CH_VALUE == COLON) { 03021 NEXT_LA_CH; 03022 } 03023 else { 03024 parse_err_flush(Find_EOS, ":"); 03025 goto EXIT; 03026 } 03027 03028 03029 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 03030 /* Parse the second subscript expression. */ 03031 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 03032 03033 expr_start_line = LA_CH_LINE; 03034 expr_start_col = LA_CH_COLUMN; 03035 03036 if (parse_expr(&an_opnd)) { 03037 03038 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 03039 NTR_IR_LIST_TBL(subscript2_il_idx); 03040 IL_NEXT_LIST_IDX(subscript1_il_idx) = subscript2_il_idx; 03041 IL_PREV_LIST_IDX(subscript2_il_idx) = subscript1_il_idx; 03042 COPY_OPND(IL_OPND(subscript2_il_idx), an_opnd); 03043 IL_LINE_NUM(subscript2_il_idx) = expr_start_line; 03044 IL_COL_NUM(subscript2_il_idx) = expr_start_col; 03045 ++IL_LIST_CNT(triplet_spec_il_idx); 03046 } 03047 else { 03048 parse_err_flush(Find_EOS, NULL); 03049 goto EXIT; 03050 } 03051 } 03052 else { 03053 parse_err_flush(Find_EOS, NULL); 03054 goto EXIT; 03055 } 03056 03057 03058 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 03059 /* If the stride expression is present, parse it. Else supply the 1. */ 03060 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 03061 03062 /* Set up some flags to allow us to issue reasonably specific error */ 03063 /* recovery messages. */ 03064 03065 found_colon = FALSE; 03066 found_comma = FALSE; 03067 03068 03069 NTR_IR_LIST_TBL(stride_il_idx); 03070 IL_NEXT_LIST_IDX(subscript2_il_idx) = stride_il_idx; 03071 IL_PREV_LIST_IDX(stride_il_idx) = subscript2_il_idx; 03072 ++IL_LIST_CNT(triplet_spec_il_idx); 03073 03074 if (LA_CH_VALUE == COLON) { 03075 NEXT_LA_CH; 03076 found_colon = TRUE; 03077 03078 expr_start_line = LA_CH_LINE; 03079 expr_start_col = LA_CH_COLUMN; 03080 03081 if (parse_expr(&an_opnd)) { 03082 03083 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 03084 COPY_OPND(IL_OPND(stride_il_idx), an_opnd); 03085 IL_LINE_NUM(stride_il_idx) = expr_start_line; 03086 IL_COL_NUM(stride_il_idx) = expr_start_col; 03087 } 03088 else { 03089 parse_err_flush(Find_EOS, NULL); 03090 goto EXIT; 03091 } 03092 } 03093 else { 03094 parse_err_flush(Find_EOS, NULL); 03095 goto EXIT; 03096 } 03097 } 03098 else { 03099 IL_LINE_NUM(stride_il_idx) = LA_CH_LINE; 03100 IL_COL_NUM(stride_il_idx) = LA_CH_COLUMN; 03101 IL_FLD(stride_il_idx) = CN_Tbl_Idx; 03102 IL_IDX(stride_il_idx) = CN_INTEGER_ONE_IDX; 03103 } 03104 03105 03106 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 03107 /* If the next token is a comma, figure out if it is followed by another */ 03108 /* <forall-triplet-spec> or the <scalar-mask-expr>. The only way to tell */ 03109 /* is if an equal sign follows whatever follows the comma. Nice language */ 03110 /* design, eh? */ 03111 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 03112 03113 if (LA_CH_VALUE == COMMA) { 03114 NEXT_LA_CH; 03115 found_colon = TRUE; /* Fake this if FALSE so insert is meaningful. */ 03116 found_comma = TRUE; 03117 03118 expr_start_line = LA_CH_LINE; 03119 expr_start_col = LA_CH_COLUMN; 03120 03121 03122 /* If the next token is a valid <index-name> or a valid token to start */ 03123 /* a mask expr, reset the source location so parse_expr will start at */ 03124 /* the right place (so LA_CH is set up correctly). Else issue a */ 03125 /* message and bail now. */ 03126 03127 if (MATCHED_TOKEN_CLASS(Tok_Class_Opnd)) { 03128 reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token)); 03129 } 03130 else if (MATCHED_TOKEN_CLASS(Tok_Class_Op)) { 03131 reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token)); 03132 } 03133 else { 03134 parse_err_flush(Find_EOS, "index-name or mask expression"); 03135 goto EXIT; 03136 } 03137 03138 if (parse_expr(&an_opnd)) { 03139 03140 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 03141 03142 if (LA_CH_VALUE == EQUAL) { 03143 il_idx = triplet_spec_il_idx; 03144 NTR_IR_LIST_TBL(triplet_spec_il_idx); 03145 ++IR_LIST_CNT_R(forall_ir_idx); 03146 IL_NEXT_LIST_IDX(il_idx) = triplet_spec_il_idx; 03147 IL_PREV_LIST_IDX(triplet_spec_il_idx) = il_idx; 03148 03149 NTR_IR_LIST_TBL(index_name_il_idx); 03150 IL_FLD(triplet_spec_il_idx) = IL_Tbl_Idx; 03151 IL_IDX(triplet_spec_il_idx) = index_name_il_idx; 03152 IL_LIST_CNT(triplet_spec_il_idx) = 1; 03153 03154 COPY_OPND(IL_OPND(index_name_il_idx), an_opnd); 03155 03156 goto NEXT_TRIPLET_SPEC; 03157 } 03158 else { 03159 NTR_IR_LIST_TBL(mask_il_idx); 03160 ++IR_LIST_CNT_R(forall_ir_idx); 03161 IL_NEXT_LIST_IDX(triplet_spec_il_idx) = mask_il_idx; 03162 IL_PREV_LIST_IDX(mask_il_idx) = triplet_spec_il_idx; 03163 03164 COPY_OPND(IL_OPND(mask_il_idx), an_opnd); 03165 IL_LINE_NUM(mask_il_idx) = expr_start_line; 03166 IL_COL_NUM(mask_il_idx) = expr_start_col; 03167 } 03168 } 03169 else { 03170 parse_err_flush(Find_EOS, NULL); 03171 goto EXIT; 03172 } 03173 } 03174 else { 03175 parse_err_flush(Find_EOS, NULL); 03176 goto EXIT; 03177 } 03178 } 03179 03180 03181 if (LA_CH_VALUE == RPAREN) { 03182 NEXT_LA_CH; 03183 } 03184 else { 03185 03186 if (! found_colon) { 03187 parse_err_flush(Find_EOS, "colon, comma, or right parenthesis"); 03188 } 03189 else if (! found_comma) { 03190 parse_err_flush(Find_EOS, "comma or )"); 03191 } 03192 else if (OPND_FLD(an_opnd) == AT_Tbl_Idx) { 03193 parse_err_flush(Find_EOS, "= or )"); 03194 } 03195 else { 03196 parse_err_flush(Find_EOS, ")"); 03197 } 03198 03199 goto EXIT; 03200 } 03201 03202 forall_sh_idx = curr_stmt_sh_idx; 03203 03204 if (LA_CH_VALUE == EOS) { 03205 NEXT_LA_CH; 03206 03207 /* The FORALL is a FORALL construct. Push it onto the Blocking Stmt */ 03208 /* stack. We'll use common code later to search the stack for its */ 03209 /* parent (if there is one). Set CURR_BLK_NO_EXEC to TRUE to force */ 03210 /* other stmt parsers to call iss_blk_stk_err to check to see if the */ 03211 /* stmt is allowed in a FORALL construct. */ 03212 03213 if (! CURR_BLK_NO_EXEC || CURR_BLK == Forall_Blk) { 03214 PUSH_BLK_STK(Forall_Blk); 03215 } 03216 else { 03217 iss_blk_stk_err(); 03218 PUSH_BLK_STK(Forall_Blk); 03219 CURR_BLK_ERR = TRUE; 03220 } 03221 03222 if (stmt_construct_idx != NULL_IDX) { 03223 CURR_BLK_NAME = stmt_construct_idx; 03224 ATL_CLASS(stmt_construct_idx) = Lbl_Construct; 03225 ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx; 03226 SH_ERR_FLG(curr_stmt_sh_idx) = 03227 SH_ERR_FLG(curr_stmt_sh_idx) || AT_DCL_ERR(stmt_construct_idx); 03228 stmt_construct_idx = NULL_IDX; 03229 } 03230 03231 curr_stmt_category = Executable_Stmt_Cat; 03232 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 03233 CURR_BLK_NO_EXEC = TRUE; 03234 blk_stk_start = blk_stk_idx - 1; 03235 } 03236 else { 03237 03238 /* The tokens following the right paren are assumed to be a */ 03239 /* <forall-assignment-stmt>. Call MATCHED_TOKEN_CLASS to force the */ 03240 /* current token to be the first token of the FORALL assignment stmt. */ 03241 /* Parse the assignment stmt. determine_stmt_type fills in the stmt */ 03242 /* type, line number, and column number. */ 03243 03244 stmt_type = Forall_Stmt; 03245 SH_STMT_TYPE(curr_stmt_sh_idx) = Forall_Stmt; 03246 03247 if (! CURR_BLK_NO_EXEC || CURR_BLK == Forall_Blk) { 03248 curr_stmt_category = Executable_Stmt_Cat; 03249 } 03250 else { 03251 iss_blk_stk_err(); 03252 parse_err_flush(Find_EOS, NULL); 03253 goto EXIT; 03254 } 03255 03256 03257 if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) { 03258 gen_sh(After, Null_Stmt, 0, 0, FALSE, FALSE, FALSE); 03259 03260 determine_stmt_type(); 03261 03262 if (stmt_type == Assignment_Stmt) { 03263 03264 /* The action statement needs to have its statement */ 03265 /* number be 1 greater than the if statement. */ 03266 03267 /* KAY - This needs to be checked to see if this is okay here */ 03268 03269 INCREMENT_STATEMENT_NUMBER; 03270 in_action_stmt_of_if_where_or_forall = TRUE; 03271 03272 (*stmt_parsers[Assignment_Stmt])(); 03273 03274 in_action_stmt_of_if_where_or_forall = FALSE; 03275 03276 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 03277 SH_ERR_FLG(forall_sh_idx) = TRUE; 03278 goto EXIT; 03279 } 03280 03281 blk_stk_start = blk_stk_idx; 03282 03283 /* generate an end forall after the assignment */ 03284 03285 gen_sh(After, End_Forall_Stmt, SH_GLB_LINE(forall_sh_idx), 03286 SH_COL_NUM(forall_sh_idx), FALSE, FALSE, FALSE); 03287 03288 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = forall_sh_idx; 03289 IR_FLD_L(SH_IR_IDX(forall_sh_idx)) = SH_Tbl_Idx; 03290 IR_IDX_L(SH_IR_IDX(forall_sh_idx)) = curr_stmt_sh_idx; 03291 IR_LINE_NUM_L(SH_IR_IDX(forall_sh_idx)) = 03292 SH_GLB_LINE(forall_sh_idx); 03293 IR_COL_NUM_L(SH_IR_IDX(forall_sh_idx)) = 03294 SH_COL_NUM(forall_sh_idx); 03295 03296 } 03297 else { 03298 PRINTMSG(stmt_start_line, 365, Error, stmt_start_col); 03299 parse_err_flush(Find_EOS, NULL); 03300 NEXT_LA_CH; 03301 SH_ERR_FLG(forall_sh_idx) = TRUE; 03302 } 03303 } 03304 else { 03305 parse_err_flush(Find_EOS, "identifier or EOS"); 03306 goto EXIT; 03307 } 03308 } 03309 03310 03311 /* Now look back through the Blocking Stmt stack to see if we can find an */ 03312 /* outer FORALL constructs. If we find one, link the current FORALL to */ 03313 /* to the outer one so we can find it in the Semantics Pass. */ 03314 03315 for (i = blk_stk_start; i > 0; --i) { 03316 03317 if (BLK_TYPE(i) == Forall_Blk) { 03318 SH_PARENT_BLK_IDX(forall_sh_idx) = BLK_FIRST_SH_IDX(i); 03319 break; 03320 } 03321 } 03322 03323 EXIT: 03324 03325 if (LA_CH_VALUE == EOS) { 03326 NEXT_LA_CH; 03327 } 03328 03329 TRACE (Func_Exit, "parse_forall", NULL); 03330 03331 return; 03332 03333 } /* parse_forall */ 03334 03335 /******************************************************************************\ 03336 |* *| 03337 |* Description: *| 03338 |* This procedure parses the three GO TO statement forms: *| 03339 |* *| 03340 |* Unconditional: GO TO label *| 03341 |* *| 03342 |* Computed: GO TO (label-list) [,] scalar-int-expr *| 03343 |* *| 03344 |* Assigned: GO TO scalar-int-variable [ [,] (label-list) ] *| 03345 |* *| 03346 |* Input parameters: *| 03347 |* NONE *| 03348 |* *| 03349 |* Output parameters: *| 03350 |* NONE *| 03351 |* *| 03352 |* Returns: *| 03353 |* NONE *| 03354 |* *| 03355 \******************************************************************************/ 03356 03357 void parse_goto_stmt(void) 03358 03359 { 03360 int attr_idx; 03361 int col; 03362 boolean comma_found = FALSE; 03363 int host_attr_idx; 03364 int host_name_idx; 03365 int ir_idx; 03366 boolean label_list_found = FALSE; 03367 int lbl_attr_idx; 03368 int line; 03369 int name_idx; 03370 opnd_type opnd; 03371 03372 03373 TRACE (Func_Entry, "parse_goto_stmt", NULL); 03374 03375 /* Have the keyword GO. The next token must be TO. */ 03376 /* Keep parsing to expose as many syntax errors as possible even though */ 03377 /* the statement might be out of context. No labels will be checked */ 03378 /* (because error flags are set) in order to prevent cascading errors. */ 03379 03380 line = TOKEN_LINE(token); 03381 col = TOKEN_COLUMN(token); 03382 03383 if (matched_specific_token(Tok_Kwd_To, Tok_Class_Keyword)) { 03384 if ( ! CURR_BLK_NO_EXEC || ! iss_blk_stk_err() ) { 03385 curr_stmt_category = Executable_Stmt_Cat; 03386 } 03387 } 03388 else { 03389 parse_err_flush(Find_EOS, "TO"); 03390 goto EXIT; 03391 } 03392 03393 /* Let's rashly assume that the stmt is correctly formed and allocate */ 03394 /* the branch IR now so we have a place to hang things. */ 03395 03396 NTR_IR_TBL(ir_idx); 03397 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 03398 IR_LINE_NUM(ir_idx) = line; 03399 IR_COL_NUM(ir_idx) = col; 03400 03401 03402 /* ----------------------------------------------------------------------- */ 03403 /* Unconditional GO TO? GO TO label */ 03404 /* ----------------------------------------------------------------------- */ 03405 03406 if (LA_CH_CLASS == Ch_Class_Digit) { 03407 03408 MATCHED_TOKEN_CLASS(Tok_Class_Label); 03409 03410 if ( ! TOKEN_ERR(token)) { 03411 03412 if (LA_CH_VALUE == EOS) { 03413 03414 /* We've found an unconditional GO TO. Check the reference to */ 03415 /* the label and complete the Br_Uncond_Opr IR. */ 03416 03417 lbl_attr_idx = check_label_ref(); 03418 03419 IR_OPR(ir_idx) = Br_Uncond_Opr; 03420 /* LRR - bhj put in short typeless as type idx */ 03421 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 03422 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 03423 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 03424 IR_LINE_NUM_R(ir_idx) = TOKEN_LINE(token); 03425 IR_COL_NUM_R(ir_idx) = TOKEN_COLUMN(token); 03426 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 03427 IR_IDX_R(ir_idx) = lbl_attr_idx; 03428 AT_REFERENCED(lbl_attr_idx) = Referenced; 03429 03430 if (cif_flags & MISC_RECS) { 03431 cif_stmt_type_rec(TRUE, 03432 CIF_Go_To_Unconditional_Stmt, 03433 statement_number); 03434 } 03435 } 03436 else { 03437 03438 /* Have garbage at the end of the statement. */ 03439 03440 parse_err_flush(Find_EOS, EOS_STR); 03441 } 03442 } 03443 else { 03444 03445 /* Something is wrong with the label (like it's too long). Message */ 03446 /* has already been issued. Flush. */ 03447 03448 parse_err_flush(Find_EOS, NULL); 03449 } 03450 03451 goto EXIT; 03452 } 03453 03454 03455 /* ----------------------------------------------------------------------- */ 03456 /* Computed GO TO? GO TO (label-list) [,] scalar-int-expr */ 03457 /* ----------------------------------------------------------------------- */ 03458 03459 if (LA_CH_VALUE == LPAREN) { 03460 03461 IR_OPR(ir_idx) = Br_Index_Opr; 03462 /* LRR - bhj put in integer as type idx */ 03463 IR_TYPE_IDX(ir_idx) = INTEGER_DEFAULT_TYPE; 03464 03465 /* Parse the label-list. If bad, the label-list parser has already */ 03466 /* issued messages so give up. */ 03467 03468 if (parse_label_list(ir_idx)) { 03469 03470 /* Recognize and toss the comma following the label-list, if the */ 03471 /* comma exists. */ 03472 03473 if (LA_CH_VALUE == COMMA) { 03474 NEXT_LA_CH; 03475 } 03476 03477 /* Parse the expression. The Semantics Pass will verify that it's */ 03478 /* scalar and type integer. */ 03479 03480 if (parse_expr(&opnd)) { 03481 03482 COPY_OPND(IR_OPND_L(ir_idx), opnd); 03483 03484 if (LA_CH_VALUE != EOS) { 03485 03486 /* Have garbage at the end of the statement. */ 03487 03488 parse_err_flush(Find_EOS, EOS_STR); 03489 } 03490 } 03491 else { 03492 parse_err_flush(Find_EOS, NULL); 03493 } 03494 } 03495 03496 if (cif_flags & MISC_RECS) { 03497 cif_stmt_type_rec(TRUE, CIF_Go_To_Computed_Stmt, statement_number); 03498 } 03499 03500 goto EXIT; 03501 } 03502 03503 03504 /* ----------------------------------------------------------------------- */ 03505 /* Must be an assigned GO TO. GO TO scalar-int-var [ [,] (label-list) ] */ 03506 /* ----------------------------------------------------------------------- */ 03507 03508 if ( ! MATCHED_TOKEN_CLASS(Tok_Class_Id) ) { 03509 PRINTMSG(LA_CH_LINE, 339, Error, LA_CH_COLUMN, 03510 (LA_CH_CLASS == Ch_Class_EOS) ? "EOS" : &LA_CH_VALUE); 03511 parse_err_flush(Find_EOS, NULL); 03512 goto EXIT; 03513 } 03514 03515 IR_OPR(ir_idx) = Br_Asg_Opr; 03516 /* LRR - bhj put in Integer as type idx */ 03517 IR_TYPE_IDX(ir_idx) = INTEGER_DEFAULT_TYPE; 03518 03519 /* Duplicate the bare bones of parse_deref to find (or enter) the Attr */ 03520 /* entry and get it marked as being referenced. */ 03521 /* parse_deref can't be used directly because it would try to parse the */ 03522 /* "lbl (2,3)" in GO TO lbl (2,3) as an array element designator. */ 03523 03524 attr_idx = srch_sym_tbl(TOKEN_STR(token), TOKEN_LEN(token), &name_idx); 03525 03526 if (attr_idx == NULL_IDX) { 03527 host_attr_idx = 03528 srch_host_sym_tbl(TOKEN_STR(token), 03529 TOKEN_LEN(token), 03530 &host_name_idx, 03531 TRUE); 03532 03533 if (host_attr_idx == NULL_IDX) { 03534 attr_idx = ntr_sym_tbl(&token, name_idx); 03535 SET_IMPL_TYPE(attr_idx); 03536 } 03537 else { 03538 attr_idx = ntr_host_in_sym_tbl(&token, name_idx, 03539 host_attr_idx, host_name_idx, 03540 TRUE); 03541 } 03542 } 03543 03544 if (AT_DCL_ERR(attr_idx)) { 03545 parse_err_flush(Find_EOS, NULL); 03546 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 03547 goto EXIT; 03548 } 03549 03550 AT_REFERENCED(attr_idx) = Referenced; 03551 03552 IR_FLD_L(ir_idx) = AT_Tbl_Idx; 03553 IR_IDX_L(ir_idx) = attr_idx; 03554 IR_LINE_NUM_L(ir_idx) = TOKEN_LINE(token); 03555 IR_COL_NUM_L(ir_idx) = TOKEN_COLUMN(token); 03556 03557 /* If the optional comma exists, absorb it and note its presence. */ 03558 03559 if (LA_CH_VALUE == COMMA) { 03560 comma_found = TRUE; 03561 NEXT_LA_CH; 03562 } 03563 03564 /* If the comma exists, the label-list must exist. If the label-list */ 03565 /* exists, parse it. */ 03566 03567 if (LA_CH_VALUE == LPAREN) { 03568 label_list_found = TRUE; 03569 03570 if ( ! parse_label_list(ir_idx) ) { 03571 goto EXIT; 03572 } 03573 } 03574 else { 03575 if (comma_found) { 03576 parse_err_flush(Find_EOS, "("); 03577 goto EXIT; 03578 } 03579 } 03580 03581 /* If the next token is the EOS, we're home free. If not, there are two */ 03582 /* possibilities: */ 03583 /* */ 03584 /* - If the label-list exists, then not finding the EOS means there is */ 03585 /* junk at the end of the statement (following the label-list). */ 03586 /* */ 03587 /* - Otherwise, there is junk following the label variable. */ 03588 03589 if (LA_CH_VALUE == EOS) { 03590 PRINTMSG(stmt_start_line, 1568, Ansi, stmt_start_col, "assign GOTO"); 03591 } 03592 else { 03593 03594 if (label_list_found) { 03595 parse_err_flush(Find_EOS, EOS_STR); 03596 } 03597 else { 03598 parse_err_flush(Find_EOS, ", or ( or EOS"); 03599 } 03600 03601 } 03602 03603 if (cif_flags & MISC_RECS) { 03604 cif_stmt_type_rec(TRUE, CIF_Go_To_Assigned_Stmt, statement_number); 03605 } 03606 03607 EXIT: 03608 03609 NEXT_LA_CH; 03610 03611 TRACE (Func_Exit, "parse_goto_stmt", NULL); 03612 03613 return; 03614 03615 } /* parse_goto_stmt */ 03616 03617 03618 /******************************************************************************\ 03619 |* *| 03620 |* Description: *| 03621 |* This function parses all forms of statements beginning with the key- *| 03622 |* word IF: *| 03623 |* [if-construct-name:] IF (scalar-logical-expr) THEN *| 03624 |* IF (scalar-logical-expr) action-stmt *| 03625 |* IF (scalar-numeric-expr) label, label, label {obsolescent} *| 03626 |* IF (scalar-logical-expr) label, label {outmoded} *| 03627 |* IF (scalar-numeric-expr) label, label {outmoded} *| 03628 |* *| 03629 |* Input parameters: *| 03630 |* NONE *| 03631 |* *| 03632 |* Output parameters: *| 03633 |* NONE *| 03634 |* *| 03635 |* Returns: *| 03636 |* NONE *| 03637 |* *| 03638 |* Algorithm notes: *| 03639 |* This procedure is called recursively to process the action-stmt of a *| 03640 |* logical IF if the action-stmt is an arithmetic IF or one of the outmoded *| 03641 |* IF forms (or, erroneously, another logical IF or IF construct). *| 03642 |* *| 03643 \******************************************************************************/ 03644 03645 void parse_if_stmt (void) 03646 03647 { 03648 opnd_type cond_expr; 03649 int expr_start_line; 03650 int expr_start_col; 03651 int if_stmt_sh_idx; 03652 int ir_idx; 03653 int lbl_attr_idx; 03654 int neg_il_idx; 03655 int pos_il_idx; 03656 int save_if_stmt_start_line; 03657 int save_if_stmt_start_col; 03658 int sh_idx; 03659 boolean stmt_parsers_called; 03660 int zero_il_idx; 03661 03662 03663 TRACE (Func_Entry, "parse_if_stmt", NULL); 03664 03665 /* ----------------------------------------------------------------------- */ 03666 /* Parse "(conditional-expr)". */ 03667 /* ----------------------------------------------------------------------- */ 03668 03669 if (LA_CH_VALUE == LPAREN) { 03670 NEXT_LA_CH; 03671 03672 expr_start_line = LA_CH_LINE; 03673 expr_start_col = LA_CH_COLUMN; 03674 03675 parse_expr(&cond_expr); 03676 03677 if (LA_CH_VALUE != RPAREN) { 03678 03679 if ( ! parse_err_flush(Find_Rparen, ")") ) { 03680 parse_err_flush(Find_EOS, NULL); 03681 goto EXIT; 03682 } 03683 } 03684 } 03685 else { 03686 parse_err_flush(Find_EOS, "("); 03687 goto EXIT; 03688 } 03689 03690 NEXT_LA_CH; 03691 03692 03693 /* ----------------------------------------------------------------------- */ 03694 /* Now figure out what kind of IF we're parsing. */ 03695 /* ----------------------------------------------------------------------- */ 03696 03697 if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) { 03698 03699 if (TOKEN_VALUE(token) == Tok_Kwd_Then) { 03700 03701 if (LA_CH_VALUE != EOS) { 03702 03703 /* Identifier starting with THEN or bad character following THEN? */ 03704 03705 if (LA_CH_VALUE == USCORE || LA_CH_CLASS == Ch_Class_Letter || 03706 LA_CH_CLASS == Ch_Class_Digit) { 03707 reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token)); 03708 MATCHED_TOKEN_CLASS(Tok_Class_Id); 03709 goto PARSE_LOGICAL_IF; 03710 } 03711 else if (LA_CH_VALUE == LPAREN || LA_CH_VALUE == PERCENT || 03712 LA_CH_VALUE == EQUAL) { 03713 goto PARSE_LOGICAL_IF; 03714 } 03715 else { 03716 03717 /* Have THEN <bad-char>. Let it go through so that a Block */ 03718 /* Stack entry will be created so a later END IF will have an */ 03719 /* entry to match. */ 03720 03721 parse_err_flush(Find_EOS, EOS_STR); 03722 } 03723 } 03724 03725 /* ----------------------------------------------------------------- */ 03726 /* IF THEN of an IF construct */ 03727 /* ----------------------------------------------------------------- */ 03728 03729 if (if_stmt_lbl_idx == NULL_IDX) { 03730 03731 /* It's not the action-stmt of a logical IF (which would be an */ 03732 /* error). */ 03733 03734 if ( ! CURR_BLK_NO_EXEC || ! iss_blk_stk_err() ) { 03735 curr_stmt_category = Executable_Stmt_Cat; 03736 PUSH_BLK_STK (If_Blk); 03737 } 03738 else { 03739 PUSH_BLK_STK (If_Blk); 03740 CURR_BLK_ERR = TRUE; 03741 } 03742 03743 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 03744 LINK_TO_PARENT_BLK; 03745 03746 if (stmt_construct_idx != NULL_IDX) { 03747 CURR_BLK_NAME = stmt_construct_idx; 03748 ATL_CLASS(stmt_construct_idx) = Lbl_Construct; 03749 ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx; 03750 SH_ERR_FLG(curr_stmt_sh_idx) = 03751 SH_ERR_FLG(curr_stmt_sh_idx) | AT_DCL_ERR(stmt_construct_idx); 03752 stmt_construct_idx = NULL_IDX; 03753 } 03754 03755 /* Generate a Br_True IR to hold the conditional expression and */ 03756 /* branch-around label. The .NOT. subtree is added by the */ 03757 /* Semantics Pass if the expression is OK. The label's Attr entry*/ 03758 /* fields are completed as a part of END IF processing. */ 03759 03760 if ( ! SH_ERR_FLG(curr_stmt_sh_idx) ) { 03761 NTR_IR_TBL(ir_idx); 03762 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 03763 IR_OPR(ir_idx) = Br_True_Opr; 03764 IR_TYPE_IDX(ir_idx) = LOGICAL_DEFAULT_TYPE; 03765 IR_LINE_NUM(ir_idx) = expr_start_line; 03766 IR_COL_NUM(ir_idx) = expr_start_col; 03767 COPY_OPND(IR_OPND_L(ir_idx), cond_expr); 03768 #if 0 03769 CURR_BLK_LABEL = gen_internal_lbl(stmt_start_line); 03770 IR_LINE_NUM_R(ir_idx) = expr_start_line; 03771 IR_COL_NUM_R(ir_idx) = expr_start_col; 03772 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 03773 IR_IDX_R(ir_idx) = CURR_BLK_LABEL; 03774 #endif 03775 } 03776 03777 /* Generate a Then_Stmt SH and block stack entry. This is needed */ 03778 /* now to check the validity of label references. It'll be */ 03779 /* thrown away by the Semantics Pass. */ 03780 03781 gen_sh(After, Then_Stmt, TOKEN_LINE(token), TOKEN_COLUMN(token), 03782 SH_ERR_FLG(curr_stmt_sh_idx), FALSE, FALSE); 03783 03784 PUSH_BLK_STK(If_Then_Blk); 03785 blk_stk[blk_stk_idx] = blk_stk[blk_stk_idx - 1]; 03786 CURR_BLK = If_Then_Blk; 03787 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 03788 LINK_TO_PARENT_BLK; 03789 03790 if (cif_flags & MISC_RECS) { 03791 cif_stmt_type_rec(TRUE, CIF_If_Construct, statement_number); 03792 } 03793 } 03794 else { 03795 03796 /* The IF-THEN stmt of an IF construct can not be the action-stmt */ 03797 /* of a logical IF. */ 03798 03799 PRINTMSG(stmt_start_line, 365, Error, stmt_start_col); 03800 } 03801 03802 goto EXIT; 03803 03804 } 03805 03806 /* -------------------------------------------------------------------- */ 03807 /* Must be parsing a logical IF. */ 03808 /* Note that the identifier following the closing paren of the */ 03809 /* conditional expression might have started with the letters THEN */ 03810 /* (token scanning was reset above). */ 03811 /*--------------------------------------------------------------------- */ 03812 03813 PARSE_LOGICAL_IF: 03814 03815 stmt_type = If_Stmt; 03816 SH_STMT_TYPE(curr_stmt_sh_idx) = If_Stmt; 03817 if_stmt_sh_idx = curr_stmt_sh_idx; 03818 save_if_stmt_start_line = stmt_start_line; 03819 save_if_stmt_start_col = stmt_start_col; 03820 03821 if ( ! CURR_BLK_NO_EXEC || ! iss_blk_stk_err() ) { 03822 curr_stmt_category = Executable_Stmt_Cat; 03823 } 03824 03825 if (if_stmt_lbl_idx == NULL_IDX) { 03826 if_stmt_lbl_idx = gen_internal_lbl(stmt_start_line); 03827 } 03828 else { 03829 PRINTMSG(stmt_start_line, 365, Error, stmt_start_col); 03830 parse_err_flush(Find_EOS, NULL); 03831 NEXT_LA_CH; 03832 goto EXIT; 03833 } 03834 03835 if (cif_flags & MISC_RECS) { 03836 cif_stmt_type_rec(TRUE, CIF_If_Logical_Stmt, statement_number); 03837 } 03838 03839 03840 /* If the IF stmt to this point is OK, generate the Br_True IR to hold */ 03841 /* the index to the conditional expression tree (temporarily) and the */ 03842 /* index of the compiler-generated branch-around label. This label is */ 03843 /* not needed for the high-level form of the IF but it's presence is */ 03844 /* used as a flag to determine whether or not an IF stmt is being */ 03845 /* parsed. It is better to just not perturb the code and let the */ 03846 /* Semantics Pass ignore this label when in high-level IF mode. */ 03847 03848 if ( ! SH_ERR_FLG(curr_stmt_sh_idx) ) { 03849 NTR_IR_TBL(ir_idx); 03850 SH_IR_IDX(if_stmt_sh_idx) = ir_idx; 03851 IR_OPR(ir_idx) = Br_True_Opr; 03852 IR_TYPE_IDX(ir_idx) = LOGICAL_DEFAULT_TYPE; 03853 IR_LINE_NUM(ir_idx) = expr_start_line; 03854 IR_COL_NUM(ir_idx) = expr_start_col; 03855 03856 COPY_OPND(IR_OPND_L(ir_idx), cond_expr); 03857 IR_LINE_NUM_R(ir_idx) = expr_start_line; 03858 IR_COL_NUM_R(ir_idx) = expr_start_col; 03859 IR_FLD_R(ir_idx) = AT_Tbl_Idx; 03860 IR_IDX_R(ir_idx) = if_stmt_lbl_idx; 03861 AT_REFERENCED(if_stmt_lbl_idx) = Referenced; 03862 } 03863 03864 03865 /* Now parse the action-stmt. */ 03866 /* determine_stmt_type fills in the stmt type, line number, column */ 03867 /* number, and whether or not the statement is labeled. */ 03868 03869 gen_sh(After, Null_Stmt, 0, 0, FALSE, FALSE, FALSE); 03870 03871 SH_ACTION_STMT(curr_stmt_sh_idx) = TRUE; 03872 stmt_parsers_called = FALSE; 03873 03874 determine_stmt_type(); 03875 03876 if (stmt_type == Where_Cstrct_Stmt || 03877 stmt_type == End_Stmt || 03878 stmt_type == Forall_Cstrct_Stmt) { 03879 03880 /* Where_Cstrct_Stmt */ 03881 /* Procedure determine_stmt_type does not distinguish */ 03882 /* between a WHERE stmt and a WHERE construct so we must */ 03883 /* actually parse the WHERE to determine what it is. */ 03884 03885 /* End_Stmt */ 03886 /* The stmt has to be parsed because determine_stmt_type */ 03887 /* can't tell a real END statement from an ENDFILE stmt. */ 03888 03889 /* Forall_Cstrct_Stmt */ 03890 /* Procedure determine_stmt_type does not distinguish */ 03891 /* between a FORALL stmt and a FORALL construct so we */ 03892 /* must actually parse the FORALL to determine what it is. */ 03893 03894 INCREMENT_STATEMENT_NUMBER; 03895 stmt_parsers_called = TRUE; 03896 in_action_stmt_of_if_where_or_forall = TRUE; 03897 03898 (*stmt_parsers[stmt_type])(); 03899 03900 in_action_stmt_of_if_where_or_forall = FALSE; 03901 } 03902 03903 switch (stmt_type) { 03904 case Allocatable_Stmt: 03905 case Automatic_Stmt: 03906 case Common_Stmt: 03907 case Contains_Stmt: 03908 case Cpnt_Decl_Stmt: 03909 case Data_Stmt: 03910 case Derived_Type_Stmt: 03911 case Dimension_Stmt: 03912 case Directive_Stmt: 03913 case Equivalence_Stmt: 03914 case External_Stmt: 03915 case Format_Stmt: 03916 case Implicit_Stmt: 03917 case Implicit_None_Stmt: 03918 case Intent_Stmt: 03919 case Interface_Stmt: 03920 case Intrinsic_Stmt: 03921 case Module_Proc_Stmt: 03922 case Namelist_Stmt: 03923 case Optional_Stmt: 03924 case Parameter_Stmt: 03925 case Pointer_Stmt: 03926 case Private_Stmt: 03927 case Public_Stmt: 03928 case Save_Stmt: 03929 case Sequence_Stmt: 03930 case Stmt_Func_Stmt: 03931 case Target_Stmt: 03932 case Task_Common_Stmt: 03933 case Type_Decl_Stmt: 03934 case Use_Stmt: 03935 case Volatile_Stmt: 03936 case Blockdata_Stmt: 03937 case Elemental_Stmt: 03938 case Function_Stmt: 03939 case Module_Stmt: 03940 case Program_Stmt: 03941 case Pure_Stmt: 03942 case Recursive_Stmt: 03943 case Subroutine_Stmt: 03944 03945 PRINTMSG(stmt_start_line, 365, Error, stmt_start_col); 03946 parse_err_flush(Find_EOS, NULL); 03947 NEXT_LA_CH; 03948 SH_ERR_FLG(if_stmt_sh_idx) = TRUE; 03949 stmt_type = If_Stmt; 03950 break; 03951 03952 case Where_Cstrct_Stmt: 03953 case Forall_Cstrct_Stmt: 03954 03955 /* Pop the Block Stack (carefully) and mark all statement */ 03956 /* headers back to the IF statement header as being in error */ 03957 /* so the Semantics Pass won't try to process them. */ 03958 03959 if (CURR_BLK == Where_Then_Blk) { 03960 POP_BLK_STK; 03961 } 03962 03963 sh_idx = curr_stmt_sh_idx; 03964 03965 while (SH_STMT_TYPE(sh_idx) != If_Stmt) { 03966 SH_ERR_FLG(sh_idx) = TRUE; 03967 sh_idx = SH_PREV_IDX(sh_idx); 03968 } 03969 03970 /* Intentional fall through */ 03971 03972 case Case_Stmt: 03973 case Do_Iterative_Stmt: 03974 case Do_While_Stmt: 03975 case Do_Infinite_Stmt: 03976 case Else_Stmt: 03977 case Entry_Stmt: 03978 case Select_Stmt: 03979 03980 PRINTMSG(stmt_start_line, 365, Error, stmt_start_col); 03981 03982 if (stmt_type != Where_Cstrct_Stmt) { 03983 parse_err_flush(Find_EOS, NULL); 03984 NEXT_LA_CH; 03985 } 03986 03987 SH_ERR_FLG(if_stmt_sh_idx) = TRUE; 03988 stmt_type = If_Stmt; 03989 goto EXIT; 03990 03991 case Allocate_Stmt: 03992 case Arith_If_Stmt: 03993 case Assign_Stmt: 03994 case Assignment_Stmt: 03995 case Backspace_Stmt: 03996 case Buffer_Stmt: 03997 case Call_Stmt: 03998 case Close_Stmt: 03999 case Continue_Stmt: 04000 case Cycle_Stmt: 04001 case Deallocate_Stmt: 04002 case Decode_Stmt: 04003 case Else_If_Stmt: 04004 case Else_Where_Stmt: 04005 case Encode_Stmt: 04006 case Exit_Stmt: 04007 case Goto_Stmt: 04008 case If_Cstrct_Stmt: 04009 case If_Stmt: 04010 case Inquire_Stmt: 04011 case Nullify_Stmt: 04012 case Open_Stmt: 04013 case Outmoded_If_Stmt: 04014 case Pause_Stmt: 04015 case Print_Stmt: 04016 case Read_Stmt: 04017 case Return_Stmt: 04018 case Rewind_Stmt: 04019 case Stop_Stmt: 04020 case Then_Stmt: 04021 case Write_Stmt: 04022 case Endfile_Stmt: 04023 case Where_Stmt: 04024 case Forall_Stmt: 04025 04026 04027 if (!stmt_parsers_called) { 04028 04029 /* The action statement needs to have its statement */ 04030 /* number be 1 greater than the if statement. */ 04031 04032 INCREMENT_STATEMENT_NUMBER; 04033 in_action_stmt_of_if_where_or_forall = TRUE; 04034 04035 (*stmt_parsers[stmt_type])(); 04036 04037 in_action_stmt_of_if_where_or_forall = FALSE; 04038 } 04039 04040 /* If the IF portion and the action-stmt are OK, generate a */ 04041 /* CONTINUE stmt to define the branch-around label. Otherwise, */ 04042 /* mark the If_Stmt SH in error if the action-stmt is bad. */ 04043 /* Note: The Semantics Pass will fill in AT_DEF_LINE and */ 04044 /* AT_DEF_COL for the label with the info from the stmt */ 04045 /* following the compiler-generated CONTINUE statement. */ 04046 04047 gen_if_ir(if_stmt_lbl_idx, 04048 if_stmt_sh_idx, 04049 save_if_stmt_start_line, 04050 save_if_stmt_start_col); 04051 04052 stmt_type = If_Stmt; 04053 break; 04054 04055 case End_Stmt: 04056 case End_Blockdata_Stmt: 04057 case End_Do_Stmt: 04058 case End_Function_Stmt: 04059 case End_If_Stmt: 04060 case End_Interface_Stmt: 04061 case End_Module_Stmt: 04062 case End_Program_Stmt: 04063 case End_Select_Stmt: 04064 case End_Subroutine_Stmt: 04065 case End_Type_Stmt: 04066 case End_Where_Stmt: 04067 case End_Forall_Stmt: 04068 04069 PRINTMSG(stmt_start_line, 365, Error, stmt_start_col); 04070 SH_ERR_FLG(if_stmt_sh_idx) = TRUE; 04071 stmt_type = If_Stmt; 04072 break; 04073 04074 case Null_Stmt: 04075 case Type_Init_Stmt: 04076 case Label_Def: 04077 case Construct_Def: 04078 case Automatic_Base_Calc_Stmt: 04079 case Automatic_Base_Size_Stmt: 04080 case End_Parallel_Stmt: 04081 case End_Do_Parallel_Stmt: 04082 case End_Parallel_Case_Stmt: 04083 case Parallel_Case_Stmt: 04084 case End_Guard_Stmt: 04085 case Statement_Num_Stmt: 04086 case SGI_Section_Stmt: 04087 case SGI_End_Psection_Stmt: 04088 case SGI_End_Pdo_Stmt: 04089 case SGI_End_Parallel_Stmt: 04090 case SGI_End_Critical_Section_Stmt: 04091 case SGI_End_Single_Process_Stmt: 04092 case SGI_Region_End_Stmt: 04093 case Open_MP_Section_Stmt: 04094 case Open_MP_End_Parallel_Stmt: 04095 case Open_MP_End_Do_Stmt: 04096 case Open_MP_End_Parallel_Sections_Stmt: 04097 case Open_MP_End_Sections_Stmt: 04098 case Open_MP_End_Section_Stmt: 04099 case Open_MP_End_Single_Stmt: 04100 case Open_MP_End_Parallel_Do_Stmt: 04101 case Open_MP_End_Master_Stmt: 04102 case Open_MP_End_Critical_Stmt: 04103 case Open_MP_End_Ordered_Stmt: 04104 04105 # if defined(_DEBUG) 04106 04107 /* ELSE IF and ELSE WHERE should never be seen because they */ 04108 /* should be classified as ELSE. */ 04109 /* stmt_type = If_Cstrct_Stmt should never be seen because it */ 04110 /* will be caught above in IF construct processing. */ 04111 /* stmt_type = Then_Stmt should never be seen because THEN */ 04112 /* is not a beginning-of-stmt keyword. */ 04113 /* None of the END stmt types except End_Stmt should be seen */ 04114 /* because they should all be classified as just END. */ 04115 04116 PRINTMSG(stmt_start_line, 366, Internal, stmt_start_col); 04117 # endif 04118 break; 04119 04120 } /* End switch (stmt_type) */ 04121 04122 goto EXIT; /* Get out so other IFs aren't deeply nested else's. */ 04123 04124 } /* if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) */ 04125 04126 04127 /* ----------------------------------------------------------------------- */ 04128 /* If the token following the right paren is a label, we are parsing an */ 04129 /* (obsolescent) arithmetic IF, an outmoded (CFT77 extension) indirect */ 04130 /* logical IF, or an outmoded (CFT77 extension) two-branch arithmetic IF. */ 04131 /* ----------------------------------------------------------------------- */ 04132 04133 if (LA_CH_CLASS == Ch_Class_Digit) { 04134 04135 if ( ! CURR_BLK_NO_EXEC || ! iss_blk_stk_err() ) { 04136 curr_stmt_category = Executable_Stmt_Cat; 04137 } 04138 04139 stmt_type = Arith_If_Stmt; 04140 SH_STMT_TYPE(curr_stmt_sh_idx) = Arith_If_Stmt; 04141 04142 /* Attach a Br_Aif_Opr IR entry to the SH to hold the conditional */ 04143 /* expression and the list of labels. */ 04144 04145 NTR_IR_TBL(ir_idx); 04146 IR_OPR(ir_idx) = Br_Aif_Opr; 04147 /* LRR - bhj put in Integer for type idx */ 04148 IR_TYPE_IDX(ir_idx) = INTEGER_DEFAULT_TYPE; 04149 IR_LINE_NUM(ir_idx) = expr_start_line; 04150 IR_COL_NUM(ir_idx) = expr_start_col; 04151 COPY_OPND(IR_OPND_L(ir_idx), cond_expr); 04152 04153 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 04154 04155 /* MATCHED_TOKEN_CLASS is normally invoked as a function but we need */ 04156 /* not check its result because we already know the token starts with */ 04157 /* a digit. */ 04158 04159 MATCHED_TOKEN_CLASS(Tok_Class_Label); 04160 04161 if (TOKEN_ERR(token)) { 04162 parse_err_flush(Find_EOS, NULL); 04163 goto EXIT; 04164 } 04165 04166 /* Produce label list in the order: zero-label, positive-label, */ 04167 /* negative-label. */ 04168 04169 lbl_attr_idx = check_label_ref(); 04170 04171 NTR_IR_LIST_TBL(neg_il_idx); 04172 IL_LINE_NUM(neg_il_idx) = TOKEN_LINE(token); 04173 IL_COL_NUM(neg_il_idx) = TOKEN_COLUMN(token); 04174 IL_FLD(neg_il_idx) = AT_Tbl_Idx; 04175 IL_IDX(neg_il_idx) = lbl_attr_idx; 04176 AT_REFERENCED(lbl_attr_idx) = Referenced; 04177 04178 IR_FLD_R(ir_idx) = IL_Tbl_Idx; 04179 IR_IDX_R(ir_idx) = neg_il_idx; 04180 ++IR_LIST_CNT_R(ir_idx); 04181 04182 if (LA_CH_VALUE == COMMA) { 04183 NEXT_LA_CH; 04184 04185 if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) { 04186 04187 if (TOKEN_ERR(token)) { 04188 parse_err_flush(Find_EOS, NULL); 04189 goto EXIT; 04190 } 04191 04192 lbl_attr_idx = check_label_ref(); 04193 04194 NTR_IR_LIST_TBL(zero_il_idx); 04195 IL_LINE_NUM(zero_il_idx) = TOKEN_LINE(token); 04196 IL_COL_NUM(zero_il_idx) = TOKEN_COLUMN(token); 04197 IL_FLD(zero_il_idx) = AT_Tbl_Idx; 04198 IL_IDX(zero_il_idx) = lbl_attr_idx; 04199 AT_REFERENCED(lbl_attr_idx) = Referenced; 04200 04201 IL_NEXT_LIST_IDX(zero_il_idx) = neg_il_idx; 04202 IL_PREV_LIST_IDX(neg_il_idx) = zero_il_idx; 04203 04204 IR_IDX_R(ir_idx) = zero_il_idx; 04205 ++IR_LIST_CNT_R(ir_idx); 04206 04207 if (LA_CH_VALUE == COMMA) { 04208 NEXT_LA_CH; 04209 04210 if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) { 04211 04212 if (TOKEN_ERR(token)) { 04213 parse_err_flush(Find_EOS, NULL); 04214 goto EXIT; 04215 } 04216 04217 lbl_attr_idx = check_label_ref(); 04218 04219 NTR_IR_LIST_TBL(pos_il_idx); 04220 IL_LINE_NUM(pos_il_idx) = TOKEN_LINE(token); 04221 IL_COL_NUM(pos_il_idx) = TOKEN_COLUMN(token); 04222 IL_FLD(pos_il_idx) = AT_Tbl_Idx; 04223 IL_IDX(pos_il_idx) = lbl_attr_idx; 04224 AT_REFERENCED(lbl_attr_idx) = Referenced; 04225 04226 IL_NEXT_LIST_IDX(zero_il_idx) = pos_il_idx; 04227 IL_PREV_LIST_IDX(pos_il_idx) = zero_il_idx; 04228 IL_NEXT_LIST_IDX(pos_il_idx) = neg_il_idx; 04229 IL_PREV_LIST_IDX(neg_il_idx) = pos_il_idx; 04230 04231 ++IR_LIST_CNT_R(ir_idx); 04232 04233 if (LA_CH_VALUE == EOS) { 04234 04235 /* ----------------------------------------------------- */ 04236 /* Arithmetic IF. */ 04237 /* ----------------------------------------------------- */ 04238 04239 PRINTMSG(stmt_start_line, 112, Comment, stmt_start_col); 04240 04241 if (cif_flags & MISC_RECS) { 04242 cif_stmt_type_rec(TRUE, 04243 CIF_If_Arithmetic_Stmt, 04244 statement_number); 04245 } 04246 } 04247 else { 04248 parse_err_flush(Find_EOS, EOS_STR); 04249 } 04250 } 04251 else { 04252 parse_err_flush(Find_EOS, "label"); 04253 } 04254 } 04255 else { 04256 04257 if (LA_CH_VALUE == EOS) { 04258 04259 /* -------------------------------------------------------- */ 04260 /* Outmoded indirect logical IF or outmoded two-branch */ 04261 /* arithmetic IF. */ 04262 /* -------------------------------------------------------- */ 04263 04264 stmt_type = Outmoded_If_Stmt; 04265 SH_STMT_TYPE(curr_stmt_sh_idx) = Outmoded_If_Stmt; 04266 04267 PRINTMSG(stmt_start_line, 406, Ansi, stmt_start_col); 04268 04269 if (cif_flags & MISC_RECS) { 04270 gen_sh(Before, Statement_Num_Stmt, statement_number, 0, 04271 FALSE, FALSE, TRUE); 04272 } 04273 } 04274 else { 04275 parse_err_flush(Find_EOS, ", or EOS"); 04276 } 04277 } 04278 } 04279 else { 04280 parse_err_flush(Find_EOS, "label"); 04281 } 04282 } 04283 else { 04284 parse_err_flush(Find_EOS, ","); 04285 } 04286 } 04287 else { 04288 04289 /* Expecting the keyword THEN, beginning of an action-stmt, or a label. */ 04290 04291 PRINTMSG(LA_CH_LINE, 377, Error, LA_CH_COLUMN); 04292 parse_err_flush(Find_EOS, NULL); 04293 } 04294 04295 EXIT: 04296 04297 if (stmt_type == If_Stmt) { 04298 if_stmt_lbl_idx = NULL_IDX; 04299 } 04300 else { 04301 04302 if (stmt_type == If_Cstrct_Stmt && SH_ERR_FLG(curr_stmt_sh_idx) && 04303 stmt_label_idx != NULL_IDX) { 04304 AT_DCL_ERR(stmt_label_idx) = TRUE; 04305 } 04306 04307 NEXT_LA_CH; 04308 } 04309 04310 TRACE (Func_Exit, "parse_if_stmt", NULL); 04311 04312 return; 04313 04314 } /* parse_if_stmt */ 04315 04316 04317 /******************************************************************************\ 04318 |* *| 04319 |* Description: *| 04320 |* BRIEF DESCRIPTION OF THIS FUNCTION'S PURPOSE *| 04321 |* *| 04322 |* Input parameters: *| 04323 |* NONE *| 04324 |* *| 04325 |* Output parameters: *| 04326 |* NONE *| 04327 |* *| 04328 |* Returns: *| 04329 |* NONE *| 04330 |* *| 04331 \******************************************************************************/ 04332 04333 void parse_nullify_stmt (void) 04334 04335 { 04336 int ir_idx; 04337 int list1_idx; 04338 int list2_idx = NULL_IDX; 04339 int num_items = 0; 04340 opnd_type opnd; 04341 boolean parsed_ok = TRUE; 04342 04343 TRACE (Func_Entry, "parse_nullify_stmt", NULL); 04344 04345 if (LA_CH_VALUE != LPAREN) { 04346 parse_err_flush(Find_EOS, "("); 04347 goto EXIT; 04348 } 04349 04350 04351 if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) { 04352 curr_stmt_category = Executable_Stmt_Cat; 04353 } 04354 04355 NTR_IR_TBL(ir_idx); 04356 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 04357 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 04358 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 04359 IR_OPR(ir_idx) = Nullify_Opr; 04360 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 04361 IR_FLD_L(ir_idx) = IL_Tbl_Idx; 04362 04363 do { 04364 NEXT_LA_CH; 04365 num_items++; 04366 04367 NTR_IR_LIST_TBL(list1_idx); 04368 04369 if (list2_idx) { 04370 IL_NEXT_LIST_IDX(list2_idx) = list1_idx; 04371 IL_PREV_LIST_IDX(list1_idx) = list2_idx; 04372 } 04373 else { 04374 IR_IDX_L(ir_idx) = list1_idx; 04375 } 04376 list2_idx = list1_idx; 04377 04378 if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) { 04379 parsed_ok = parse_deref(&opnd, NULL_IDX) && parsed_ok; 04380 COPY_OPND(IL_OPND(list1_idx), opnd); 04381 04382 mark_attr_defined(&opnd); 04383 } 04384 else { 04385 parsed_ok = FALSE; 04386 parse_err_flush(Find_Comma_Rparen, "IDENTIFIER"); 04387 } 04388 } 04389 while (LA_CH_VALUE == COMMA); 04390 04391 IR_LIST_CNT_L(ir_idx) = num_items; 04392 04393 if (LA_CH_VALUE != RPAREN) { 04394 parse_err_flush(Find_EOS, ")"); 04395 } 04396 else { 04397 NEXT_LA_CH; 04398 } 04399 04400 EXIT: 04401 04402 if (LA_CH_VALUE != EOS) { 04403 parse_err_flush(Find_EOS, EOS_STR); 04404 } 04405 04406 matched_specific_token(Tok_EOS, Tok_Class_Punct); 04407 04408 TRACE (Func_Exit, "parse_nullify_stmt", NULL); 04409 04410 return; 04411 04412 } /* parse_nullify_stmt */ 04413 04414 04415 /******************************************************************************\ 04416 |* *| 04417 |* Description: *| 04418 |* Parse a RETURN statement. *| 04419 |* BNF : return-stmt is RETURN [scalar-int-expr] *| 04420 |* Alternate return specifiers are not allowed in FUNCTION subprograms. *| 04421 |* *| 04422 |* Input parameters: *| 04423 |* NONE *| 04424 |* *| 04425 |* Output parameters: *| 04426 |* NONE *| 04427 |* *| 04428 |* Returns: *| 04429 |* NONE *| 04430 |* *| 04431 \******************************************************************************/ 04432 04433 void parse_return_stmt (void) 04434 04435 { 04436 int ir_idx; 04437 opnd_type opnd; 04438 04439 04440 TRACE (Func_Entry, "parse_return_stmt", NULL); 04441 04442 /* Check if in an executable SUBROUTINE or FUNCTION block. */ 04443 04444 if (CURR_BLK_NO_EXEC || 04445 (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) != Function && 04446 ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) != Subroutine)) { 04447 iss_blk_stk_err(); 04448 } 04449 04450 if (cmd_line_flags.debug_lvl == Debug_Lvl_1) { /* -ez -G1 */ 04451 gen_debug_lbl_stmt(curr_stmt_sh_idx, Ldbg_Start_Epilogue, NULL_IDX); 04452 } 04453 04454 curr_stmt_category = Executable_Stmt_Cat; 04455 04456 NTR_IR_TBL(ir_idx); 04457 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 04458 04459 IR_OPR(ir_idx) = Return_Opr; 04460 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 04461 IR_LINE_NUM(ir_idx) = LA_CH_LINE; 04462 IR_COL_NUM(ir_idx) = LA_CH_COLUMN; 04463 04464 if (LA_CH_VALUE != EOS) { 04465 04466 /* Alternate return specifiers are obsolescent. */ 04467 04468 PRINTMSG(IR_LINE_NUM(ir_idx), 371, Comment, IR_COL_NUM(ir_idx)); 04469 04470 /* Check for alternate return specifier in a FUNCTION subprogram. */ 04471 04472 if (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) == Function) { 04473 PRINTMSG(IR_LINE_NUM(ir_idx), 370, Error, IR_COL_NUM(ir_idx)); 04474 } 04475 04476 /* Parse the expression. The Semantics Pass will verify that it's */ 04477 /* scalar and type integer. */ 04478 04479 if (parse_expr(&opnd)) { 04480 04481 COPY_OPND(IR_OPND_L(ir_idx), opnd); 04482 04483 if (LA_CH_VALUE != EOS) { 04484 04485 /* Have garbage at the end of the statement. */ 04486 04487 parse_err_flush(Find_EOS, EOS_STR); 04488 } 04489 } 04490 } 04491 04492 NEXT_LA_CH; 04493 04494 TRACE (Func_Exit, "parse_return_stmt", NULL); 04495 04496 return; 04497 04498 } /* parse_return_stmt */ 04499 04500 04501 /******************************************************************************\ 04502 |* *| 04503 |* Description: *| 04504 |* This function parses the SELECT CASE statement. *| 04505 |* *| 04506 |* Input parameters: *| 04507 |* NONE *| 04508 |* *| 04509 |* Output parameters: *| 04510 |* NONE *| 04511 |* *| 04512 |* Returns: *| 04513 |* NONE *| 04514 |* *| 04515 \******************************************************************************/ 04516 04517 void parse_select_stmt (void) 04518 04519 { 04520 opnd_type expr_opnd; 04521 int first_select_ir_idx; 04522 int second_select_ir_idx; 04523 04524 04525 TRACE (Func_Entry, "parse_select_stmt", NULL); 04526 04527 if (matched_specific_token(Tok_Kwd_Case, Tok_Class_Keyword) && 04528 LA_CH_VALUE == LPAREN) { 04529 NEXT_LA_CH; 04530 } 04531 else if (TOKEN_VALUE(token) == Tok_Kwd_Case) { 04532 parse_err_flush(Find_EOS, "("); 04533 goto EXIT; 04534 } 04535 else { 04536 parse_err_flush(Find_EOS, "CASE"); 04537 goto EXIT; 04538 } 04539 04540 if (CURR_BLK_NO_EXEC && iss_blk_stk_err()) { 04541 PUSH_BLK_STK (Select_Blk); 04542 CURR_BLK_ERR = TRUE; 04543 } 04544 else { 04545 PUSH_BLK_STK (Select_Blk); 04546 curr_stmt_category = Executable_Stmt_Cat; 04547 } 04548 04549 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 04550 CURR_BLK_NO_EXEC = TRUE; 04551 BLK_CASE_DEFAULT_LBL_FLD(blk_stk_idx) = NO_Tbl_Idx; 04552 LINK_TO_PARENT_BLK; 04553 04554 if (stmt_construct_idx != NULL_IDX) { 04555 CURR_BLK_NAME = stmt_construct_idx; 04556 ATL_CLASS(stmt_construct_idx) = Lbl_Construct; 04557 ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx; 04558 SH_ERR_FLG(curr_stmt_sh_idx) = 04559 SH_ERR_FLG(curr_stmt_sh_idx) || AT_DCL_ERR(stmt_construct_idx); 04560 stmt_construct_idx = NULL_IDX; 04561 } 04562 04563 /* Generate a dummy Select IR and attach it to the Select_Stmt SH. This */ 04564 /* dummy IR is needed because we need a place to temporarily hang the */ 04565 /* sorted CASE list in the Semantics Pass. This dummy IR is removed by */ 04566 /* the END SELECT code in the Semantics Pass. After the following two */ 04567 /* Select IR generations we have: */ 04568 /* */ 04569 /* Select_Stmt SH ---> Select IR */ 04570 /* -----------> (actual) Select IR */ 04571 /* -----------> sorted CASE list will go here */ 04572 04573 NTR_IR_TBL(first_select_ir_idx); 04574 SH_IR_IDX(curr_stmt_sh_idx) = first_select_ir_idx; 04575 IR_OPR(first_select_ir_idx) = Select_Opr; 04576 /* LRR - bhj used short typeless for type idx */ 04577 IR_TYPE_IDX(first_select_ir_idx) = TYPELESS_DEFAULT_TYPE; 04578 04579 if (parse_expr(&expr_opnd)) { 04580 NTR_IR_TBL(second_select_ir_idx); 04581 IR_OPR(second_select_ir_idx) = Select_Opr; 04582 /* LRR - bhj used short typeless for type idx */ 04583 IR_TYPE_IDX(second_select_ir_idx) = TYPELESS_DEFAULT_TYPE; 04584 IR_LINE_NUM(second_select_ir_idx) = stmt_start_line; 04585 IR_COL_NUM(second_select_ir_idx) = stmt_start_col; 04586 COPY_OPND(IR_OPND_L(second_select_ir_idx), expr_opnd); 04587 04588 IR_FLD_L(first_select_ir_idx) = IR_Tbl_Idx; 04589 IR_IDX_L(first_select_ir_idx) = second_select_ir_idx; 04590 04591 CURR_BLK_LABEL = gen_internal_lbl(stmt_start_line); 04592 AT_REFERENCED(CURR_BLK_LABEL) = Referenced; 04593 } 04594 04595 if (LA_CH_VALUE == RPAREN) { 04596 NEXT_LA_CH; 04597 } 04598 else { 04599 parse_err_flush(Find_EOS, ")"); 04600 } 04601 04602 if (LA_CH_VALUE != EOS) { 04603 parse_err_flush(Find_EOS, EOS_STR); 04604 } 04605 04606 CURR_BLK_ERR = SH_ERR_FLG(curr_stmt_sh_idx); 04607 04608 EXIT: 04609 04610 NEXT_LA_CH; 04611 04612 TRACE (Func_Exit, "parse_select_stmt", NULL); 04613 04614 return; 04615 04616 } /* parse_select_stmt */ 04617 04618 04619 /******************************************************************************\ 04620 |* *| 04621 |* Description: *| 04622 |* Parse the STOP statement or the PAUSE statement. *| 04623 |* BNF : *| 04624 |* pause_stmt is PAUSE [stop-code] *| 04625 |* stop_stmt is STOP [stop-code] *| 04626 |* stop_code is scalar-char-constant *| 04627 |* or digit [digit [digit [ digit [ digit ] ] ] ] *| 04628 |* *| 04629 |* NOTE: CFT77 allows an arbitrary character expression for the *| 04630 |* stop-code. CFT90 will be extended to support this. *| 04631 |* *| 04632 |* *| 04633 |* *| 04634 |* *| 04635 |* *| 04636 |* *| 04637 |* *| 04638 |* *| 04639 |* Input parameters: *| 04640 |* NONE *| 04641 |* *| 04642 |* Output parameters: *| 04643 |* NONE *| 04644 |* *| 04645 |* Returns: *| 04646 |* NONE *| 04647 |* *| 04648 \******************************************************************************/ 04649 04650 void parse_stop_pause_stmt (void) 04651 04652 { 04653 opnd_type opnd; 04654 int ir_idx; 04655 04656 04657 TRACE (Func_Entry, "parse_stop_pause_stmt", NULL); 04658 04659 if (cmd_line_flags.debug_lvl == Debug_Lvl_1) { /* -ez -G1 */ 04660 gen_debug_lbl_stmt(curr_stmt_sh_idx, Ldbg_Exit_Point, NULL_IDX); 04661 } 04662 04663 if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) { 04664 curr_stmt_category = Executable_Stmt_Cat; 04665 } 04666 04667 if (ATP_PURE(SCP_ATTR_IDX(curr_scp_idx)) || 04668 ATP_ELEMENTAL(SCP_ATTR_IDX(curr_scp_idx))) { 04669 PRINTMSG(TOKEN_LINE(token), 1262, Error, 04670 TOKEN_COLUMN(token), 04671 stmt_type_str[stmt_type], 04672 ATP_PURE(SCP_ATTR_IDX(curr_scp_idx)) ? "pure" : "elemental", 04673 AT_OBJ_NAME_PTR(SCP_ATTR_IDX(curr_scp_idx))); 04674 } 04675 04676 NTR_IR_TBL(ir_idx); 04677 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 04678 IR_LINE_NUM(ir_idx) = LA_CH_LINE; 04679 IR_COL_NUM(ir_idx) = LA_CH_COLUMN; 04680 04681 if (stmt_type == Stop_Stmt) { 04682 IR_OPR(ir_idx) = Stop_Opr; 04683 } 04684 else { 04685 IR_OPR(ir_idx) = Pause_Opr; 04686 04687 /* The PAUSE statement is a deleted feature. */ 04688 04689 PRINTMSG(TOKEN_LINE(token), 1568, Ansi, TOKEN_COLUMN(token), "PAUSE"); 04690 } 04691 04692 if (LA_CH_VALUE != EOS) { 04693 04694 if (LA_CH_CLASS == Ch_Class_Digit) { 04695 matched_specific_token(Tok_Const_Int, Tok_Class_Int_Spec); 04696 04697 if (LA_CH_VALUE != EOS) { 04698 /* Have garbage at the end of the statement. */ 04699 parse_err_flush(Find_EOS, EOS_STR); 04700 } 04701 else { 04702 IR_FLD_L(ir_idx) = CN_Tbl_Idx; 04703 IR_IDX_L(ir_idx) = TOKEN_CONST_TBL_IDX(token); 04704 IR_COL_NUM_L(ir_idx) = TOKEN_COLUMN(token); 04705 IR_LINE_NUM_L(ir_idx) = TOKEN_LINE(token); 04706 } 04707 } 04708 04709 /* Parse the expression. The Semantics Pass will verify rank and */ 04710 /* type. */ 04711 else if (parse_expr(&opnd)) { 04712 04713 COPY_OPND(IR_OPND_L(ir_idx), opnd); 04714 04715 if (LA_CH_VALUE != EOS) { 04716 /* Have garbage at the end of the statement. */ 04717 parse_err_flush(Find_EOS, EOS_STR); 04718 } 04719 } 04720 } 04721 04722 /* Get statement header for the RETURN which will be generated following */ 04723 /* the CALL to $STOP */ 04724 if (stmt_type == Stop_Stmt && 04725 ! cdir_switches.parallel_region && 04726 ! cdir_switches.doall_region && 04727 ! cdir_switches.guard) { 04728 04729 gen_sh(After, Return_Stmt, stmt_start_line, stmt_start_col, 04730 SH_ERR_FLG(curr_stmt_sh_idx), FALSE, TRUE); 04731 04732 NTR_IR_TBL(ir_idx); 04733 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 04734 SH_P2_SKIP_ME(curr_stmt_sh_idx) = TRUE; 04735 04736 IR_OPR(ir_idx) = Return_Opr; 04737 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 04738 IR_LINE_NUM(ir_idx) = stmt_start_line; 04739 IR_COL_NUM(ir_idx) = stmt_start_col; 04740 } 04741 04742 04743 NEXT_LA_CH; 04744 04745 TRACE (Func_Exit, "parse_stop_pause_stmt", NULL); 04746 04747 return; 04748 04749 } /* parse_stop_pause_stmt */ 04750 04751 04752 /******************************************************************************\ 04753 |* *| 04754 |* Description: *| 04755 |* BRIEF DESCRIPTION OF THIS FUNCTION'S PURPOSE *| 04756 |* *| 04757 |* Input parameters: *| 04758 |* NONE *| 04759 |* *| 04760 |* Output parameters: *| 04761 |* NONE *| 04762 |* *| 04763 |* Returns: *| 04764 |* NONE *| 04765 |* *| 04766 \******************************************************************************/ 04767 04768 void parse_where_stmt (void) 04769 04770 { 04771 int col; 04772 int ir_idx; 04773 int line; 04774 opnd_type opnd; 04775 int save_curr_stmt_sh_idx; 04776 04777 04778 TRACE (Func_Entry, "parse_where_stmt", NULL); 04779 04780 if (LA_CH_VALUE != LPAREN) { 04781 parse_err_flush(Find_EOS, "("); 04782 goto EXIT; 04783 } 04784 04785 NTR_IR_TBL(ir_idx); 04786 IR_OPR(ir_idx) = Where_Opr; 04787 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 04788 IR_LINE_NUM(ir_idx) = TOKEN_LINE(token); 04789 IR_COL_NUM(ir_idx) = TOKEN_COLUMN(token); 04790 04791 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 04792 04793 if (CURR_BLK == Where_Then_Blk || 04794 CURR_BLK == Where_Else_Blk || 04795 CURR_BLK == Where_Else_Mask_Blk) { 04796 04797 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = CURR_BLK_FIRST_SH_IDX; 04798 } 04799 04800 /* if this is a Where stmt, the right opnd will hold the assignment stmt, */ 04801 /* otherwise, it is a where construct stmt and the right opnd is null. */ 04802 04803 /* swallow ( */ 04804 NEXT_LA_CH; 04805 04806 parse_expr(&opnd); 04807 04808 if (LA_CH_VALUE != RPAREN) { 04809 if (! parse_err_flush(Find_Rparen, ")")) { 04810 goto EXIT; 04811 } 04812 } 04813 04814 /* swallow ) */ 04815 NEXT_LA_CH; 04816 04817 COPY_OPND(IR_OPND_L(ir_idx), opnd); 04818 04819 if (LA_CH_VALUE != EOS) { 04820 /* Have where_stmt */ 04821 04822 stmt_type = Where_Stmt; 04823 SH_STMT_TYPE(curr_stmt_sh_idx) = Where_Stmt; 04824 04825 if (cif_flags & MISC_RECS) { 04826 cif_stmt_type_rec(TRUE, CIF_Where_Stmt, statement_number); 04827 } 04828 04829 if (CURR_BLK_NO_EXEC && 04830 CURR_BLK != Forall_Blk && 04831 CURR_BLK != Where_Then_Blk && 04832 CURR_BLK != Where_Else_Blk && 04833 CURR_BLK != Where_Else_Mask_Blk) { 04834 iss_blk_stk_err(); 04835 parse_err_flush(Find_EOS, NULL); 04836 goto EXIT; 04837 } 04838 04839 /* We do not know if this will be an Assignment Statement */ 04840 /* or an Array_Assignment_Stmt so we need to generate a */ 04841 /* place holder for the statement number. We will carry */ 04842 /* it on a Statement_Num_Stmt following the Where_Stmt. */ 04843 /* It MUST be processed in where_stmt_semantics so as not */ 04844 /* to mess up cif statement processing. */ 04845 04846 INCREMENT_STATEMENT_NUMBER; 04847 04848 gen_sh(After, Statement_Num_Stmt, stmt_start_line, stmt_start_col, 04849 FALSE, FALSE, TRUE); 04850 SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = statement_number; 04851 curr_stmt_category = Executable_Stmt_Cat; 04852 save_curr_stmt_sh_idx = curr_stmt_sh_idx; 04853 line = LA_CH_LINE; 04854 col = LA_CH_COLUMN; 04855 in_action_stmt_of_if_where_or_forall = TRUE; 04856 04857 if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) { 04858 curr_stmt_sh_idx = ntr_sh_tbl(); 04859 04860 determine_stmt_type(); 04861 04862 if (stmt_type == Assignment_Stmt) { 04863 04864 (*stmt_parsers[Assignment_Stmt])(); 04865 04866 IR_FLD_R(ir_idx) = IR_Tbl_Idx; 04867 IR_IDX_R(ir_idx) = SH_IR_IDX(curr_stmt_sh_idx); 04868 04869 FREE_SH_NODE(curr_stmt_sh_idx); 04870 curr_stmt_sh_idx = save_curr_stmt_sh_idx; 04871 in_action_stmt_of_if_where_or_forall = FALSE; 04872 04873 goto NO_EOS; 04874 } 04875 else { 04876 04877 FREE_SH_NODE(curr_stmt_sh_idx); 04878 curr_stmt_sh_idx = save_curr_stmt_sh_idx; 04879 04880 PRINTMSG(line, 102, Error, col); 04881 parse_err_flush(Find_EOS, NULL); 04882 in_action_stmt_of_if_where_or_forall = FALSE; 04883 goto EXIT; 04884 } 04885 } 04886 else { 04887 PRINTMSG(line, 102, Error, col); 04888 parse_err_flush(Find_EOS, NULL); 04889 in_action_stmt_of_if_where_or_forall = FALSE; 04890 goto EXIT; 04891 } 04892 } 04893 else { 04894 /* else have where_construct_stmt */ 04895 04896 IR_OPR(ir_idx) = Where_Cnstrct_Opr; 04897 04898 if (cif_flags & MISC_RECS) { 04899 cif_stmt_type_rec(TRUE, CIF_Where_Construct, statement_number); 04900 } 04901 04902 if (! CURR_BLK_NO_EXEC || 04903 CURR_BLK == Forall_Blk || 04904 CURR_BLK == Where_Then_Blk || 04905 CURR_BLK == Where_Else_Blk || 04906 CURR_BLK == Where_Else_Mask_Blk) { 04907 PUSH_BLK_STK (Where_Then_Blk); 04908 } 04909 else { 04910 iss_blk_stk_err(); 04911 PUSH_BLK_STK (Where_Then_Blk); 04912 CURR_BLK_ERR = TRUE; 04913 } 04914 04915 if (stmt_construct_idx != NULL_IDX) { 04916 CURR_BLK_NAME = stmt_construct_idx; 04917 ATL_CLASS(stmt_construct_idx) = Lbl_Construct; 04918 ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx; 04919 SH_ERR_FLG(curr_stmt_sh_idx) = 04920 SH_ERR_FLG(curr_stmt_sh_idx) || AT_DCL_ERR(stmt_construct_idx); 04921 stmt_construct_idx = NULL_IDX; 04922 } 04923 04924 curr_stmt_category = Executable_Stmt_Cat; 04925 CURR_BLK_NO_EXEC = TRUE; 04926 CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx; 04927 } 04928 04929 EXIT: 04930 04931 NEXT_LA_CH; 04932 04933 NO_EOS: 04934 04935 TRACE (Func_Exit, "parse_where_stmt", NULL); 04936 04937 return; 04938 04939 } /* parse_where_stmt */ 04940 04941 04942 /******************************************************************************\ 04943 |* *| 04944 |* Description: *| 04945 |* This searches the blk_stk for the specified block and name. If not *| 04946 |* found, it returns NULL_IDX and makes sure blk_stk[NULL_IDX] is clear. *| 04947 |* *| 04948 |* Input parameters: *| 04949 |* blk_type -> The type of block being searched for. *| 04950 |* found_name -> TRUE if there is a name to match. The actual name is *| 04951 |* in token. *| 04952 |* *| 04953 |* Output parameters: *| 04954 |* NONE *| 04955 |* *| 04956 |* Returns: *| 04957 |* Index of the matched block. It will return NULL_IDX if there is no *| 04958 |* match, but it will also clear blk_stk[NULL_IDX] so that calling *| 04959 |* routines do not have to check for the NULL_IDX. *| 04960 |* *| 04961 \******************************************************************************/ 04962 04963 static int match_blk(blk_cntxt_type the_blk, 04964 boolean fnd_name) 04965 04966 { 04967 int blk_idx; 04968 04969 04970 TRACE (Func_Entry, "match_blk", NULL); 04971 04972 for (blk_idx = blk_stk_idx; blk_idx > NULL_IDX; blk_idx--) { 04973 04974 if (BLK_TYPE(blk_idx) == the_blk) { 04975 04976 if (!fnd_name || 04977 (BLK_NAME(blk_idx) != NULL_IDX && 04978 (compare_names(TOKEN_ID(token).words, 04979 TOKEN_LEN(token), 04980 AT_OBJ_NAME_LONG(BLK_NAME(blk_idx)), 04981 AT_NAME_LEN(BLK_NAME(blk_idx))) == 0))){ 04982 break; 04983 } 04984 } 04985 } 04986 04987 if (blk_idx == NULL_IDX) { 04988 CLEAR_TBL_NTRY(blk_stk, NULL_IDX); 04989 } 04990 04991 TRACE (Func_Exit, "match_blk", NULL); 04992 04993 return(blk_idx); 04994 04995 } /* match_blk */ 04996 04997 04998 /******************************************************************************\ 04999 |* *| 05000 |* Description: *| 05001 |* This procedure parses the label-list for the computed and assigned GO *| 05002 |* TO statements. *| 05003 |* *| 05004 |* Input parameters: *| 05005 |* ir_idx : index to the current IR entry *| 05006 |* *| 05007 |* Output parameters: *| 05008 |* NONE *| 05009 |* *| 05010 |* Returns: *| 05011 |* A boolean value that indicates whether or not the label-list was *| 05012 |* parsed correctly. If an error occurs, the statement is flushed to *| 05013 |* the EOS so the caller should discontinue parsing. *| 05014 |* *| 05015 \******************************************************************************/ 05016 05017 static boolean parse_label_list(int ir_idx) 05018 05019 { 05020 int lbl_attr_idx; 05021 int list_tail = NULL_IDX; 05022 int new_lbl; 05023 boolean parsed_correctly = TRUE; 05024 05025 05026 TRACE (Func_Entry, "parse_label_list", NULL); 05027 05028 /* The left paren has already been seen by the caller. Just absorb it. */ 05029 05030 NEXT_LA_CH; 05031 05032 /* Loop through the labels and commas in the list until the right paren */ 05033 /* is found. The list must not be empty. Save each label reference in */ 05034 /* a List entry. The List entries are linked in order of label appearance */ 05035 /* because the index expression of the computed GO TO selects them by */ 05036 /* ordinal position. */ 05037 05038 while (LA_CH_VALUE != EOS) { 05039 05040 if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) { 05041 05042 if ( ! TOKEN_ERR(token)) { 05043 lbl_attr_idx = check_label_ref(); 05044 05045 NTR_IR_LIST_TBL(new_lbl); 05046 05047 if (list_tail != NULL_IDX) { 05048 IL_NEXT_LIST_IDX(list_tail) = new_lbl; 05049 IL_PREV_LIST_IDX(new_lbl) = list_tail; 05050 list_tail = new_lbl; 05051 } 05052 else { 05053 IR_FLD_R(ir_idx) = IL_Tbl_Idx; 05054 IR_IDX_R(ir_idx) = new_lbl; 05055 list_tail = new_lbl; 05056 } 05057 05058 IL_LINE_NUM(new_lbl) = TOKEN_LINE(token); 05059 IL_COL_NUM(new_lbl) = TOKEN_COLUMN(token); 05060 IL_FLD(new_lbl) = AT_Tbl_Idx; 05061 IL_IDX(new_lbl) = lbl_attr_idx; 05062 AT_REFERENCED(lbl_attr_idx) = Referenced; 05063 05064 IR_LIST_CNT_R(ir_idx)++; 05065 } 05066 05067 if (LA_CH_VALUE == COMMA) { 05068 NEXT_LA_CH; 05069 } 05070 else if (LA_CH_VALUE == RPAREN) { 05071 NEXT_LA_CH; 05072 goto EXIT; 05073 } 05074 else { 05075 parse_err_flush(Find_EOS, ", or )"); 05076 parsed_correctly = FALSE; 05077 goto EXIT; 05078 } 05079 05080 } 05081 else { 05082 parse_err_flush(Find_EOS, "statement label"); 05083 parsed_correctly = FALSE; 05084 goto EXIT; 05085 } 05086 05087 } /* while */ 05088 05089 parse_err_flush(Find_EOS, "statement label"); 05090 parsed_correctly = FALSE; 05091 05092 EXIT: 05093 05094 TRACE (Func_Exit, "parse_label_list", NULL); 05095 05096 return(parsed_correctly); 05097 05098 } /* parse_label_list */ 05099 05100 05101 /******************************************************************************\ 05102 |* *| 05103 |* Description: *| 05104 |* Look for a final subscript opr on a reference tree in an *| 05105 |* ALLOCATE allocation object and change to a Alloc_Obj_Opr. *| 05106 |* Also check for stride in extent specs. *| 05107 |* *| 05108 |* Input parameters: *| 05109 |* opnd - root of subtree to check. *| 05110 |* *| 05111 |* Output parameters: *| 05112 |* opnd - checked tree. *| 05113 |* *| 05114 |* Returns: *| 05115 |* TRUE if no error with extent spec. *| 05116 |* *| 05117 \******************************************************************************/ 05118 05119 static boolean change_subscript(opnd_type *top_opnd) 05120 05121 { 05122 boolean allocate; 05123 int column; 05124 int ir_idx; 05125 int ir2_idx; 05126 int line; 05127 int list_idx; 05128 int list2_idx; 05129 int msg_num; 05130 boolean ok = TRUE; 05131 05132 05133 TRACE (Func_Entry, "change_subscript", NULL); 05134 05135 if (stmt_type == Deallocate_Stmt) { 05136 allocate = FALSE; 05137 msg_num = 428; 05138 } 05139 else { 05140 allocate = TRUE; 05141 msg_num = 201; 05142 } 05143 05144 if (OPND_FLD((*top_opnd)) == CN_Tbl_Idx) { 05145 05146 /* error .. can't have constant in allocate stmt */ 05147 05148 find_opnd_line_and_column(top_opnd, &line, &column); 05149 05150 PRINTMSG(line, msg_num, Error, column); 05151 ok = FALSE; 05152 } 05153 else if (OPND_FLD((*top_opnd)) == AT_Tbl_Idx) { 05154 05155 05156 NTR_IR_TBL(ir_idx); 05157 IR_OPR(ir_idx) = (allocate ? Alloc_Obj_Opr : Dealloc_Obj_Opr); 05158 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 05159 IR_LINE_NUM(ir_idx) = OPND_LINE_NUM((*top_opnd)); 05160 IR_COL_NUM(ir_idx) = OPND_COL_NUM((*top_opnd)); 05161 05162 COPY_OPND(IR_OPND_L(ir_idx), (*top_opnd)); 05163 05164 OPND_FLD((*top_opnd)) = IR_Tbl_Idx; 05165 OPND_IDX((*top_opnd)) = ir_idx; 05166 05167 } 05168 else if (OPND_FLD((*top_opnd)) == IR_Tbl_Idx) { 05169 ir_idx = OPND_IDX((*top_opnd)); 05170 05171 switch (IR_OPR(ir_idx)) { 05172 05173 case Subscript_Opr : 05174 05175 if (allocate) { 05176 IR_OPR(ir_idx) = Alloc_Obj_Opr; 05177 list_idx = IR_IDX_R(ir_idx); 05178 05179 while (list_idx != NULL_IDX) { 05180 05181 if (IL_FLD(list_idx) == IR_Tbl_Idx && 05182 IR_OPR(IL_IDX(list_idx)) == Triplet_Opr) { 05183 05184 ir_idx = IL_IDX(list_idx); 05185 #if 0 /*fzhao */ 05186 IL_FLD(list_idx) = IL_Tbl_Idx; 05187 IL_LIST_CNT(list_idx) = 2; 05188 IL_IDX(list_idx) = IR_IDX_L(ir_idx); 05189 #endif 05190 05191 /* list2_idx = IL_IDX(list_idx); */ 05192 /* list2_idx = IL_IDX(list_idx); fzhao */ 05193 05194 list2_idx = IR_IDX_L(ir_idx); 05195 list2_idx = IL_NEXT_LIST_IDX(list2_idx); 05196 05197 if (IL_FLD(IR_IDX_L(ir_idx)) == NO_Tbl_Idx) { 05198 /* bad allocate shape spec, no lower bound */ 05199 ok = FALSE; 05200 PRINTMSG(IR_LINE_NUM(ir_idx), 1558, Error, 05201 IR_COL_NUM(ir_idx), 05202 "lower bound"); 05203 } 05204 else if (IL_FLD(list2_idx) == NO_Tbl_Idx && 05205 ! IL_PE_SUBSCRIPT(list_idx)) { 05206 /* bad allocate shape spec, no upper bound */ 05207 ok = FALSE; 05208 PRINTMSG(IR_LINE_NUM(ir_idx), 1558, Error, 05209 IR_COL_NUM(ir_idx), 05210 "upper bound"); 05211 } 05212 else if (IL_FLD(IL_NEXT_LIST_IDX(list2_idx)) 05213 != NO_Tbl_Idx) { 05214 /* error .. stride is supplied */ 05215 ok = FALSE; 05216 find_opnd_line_and_column((opnd_type *)&IL_OPND( 05217 IL_NEXT_LIST_IDX(list2_idx)), 05218 &line, 05219 &column); 05220 PRINTMSG(line, 401, Error, column); } 05221 else { 05222 IL_FLD(IL_NEXT_LIST_IDX(list2_idx))=CN_Tbl_Idx; 05223 IL_IDX(IL_NEXT_LIST_IDX(list2_idx))=CN_INTEGER_ONE_IDX; 05224 } 05225 05226 /* FREE_IR_NODE(ir_idx); */ 05227 /* FREE_IR_NODE(ir_idx); fzhao */ 05228 05229 /* IL_NEXT_LIST_IDX(list2_idx) = NULL_IDX; */ 05230 /* IL_NEXT_LIST_IDX(list2_idx) = NULL_IDX; fzhao */ 05231 05232 } 05233 list_idx = IL_NEXT_LIST_IDX(list_idx); 05234 } 05235 } 05236 else { 05237 /* deallocate can't have subscript at end */ 05238 PRINTMSG(IR_LINE_NUM(ir_idx), 430, Error, 05239 IR_COL_NUM(ir_idx)); 05240 ok = FALSE; 05241 } 05242 break; 05243 05244 case Struct_Opr : 05245 05246 /* implies right opnd is AT */ 05247 NTR_IR_TBL(ir2_idx); 05248 05249 IR_OPR(ir2_idx) = (allocate ? Alloc_Obj_Opr : 05250 Dealloc_Obj_Opr); 05251 IR_TYPE_IDX(ir2_idx) = TYPELESS_DEFAULT_TYPE; 05252 IR_LINE_NUM(ir2_idx) = IR_LINE_NUM_R(ir_idx); 05253 IR_COL_NUM(ir2_idx) = IR_COL_NUM_R(ir_idx); 05254 05255 COPY_OPND(IR_OPND_L(ir2_idx), (*top_opnd)); 05256 05257 OPND_FLD((*top_opnd)) = IR_Tbl_Idx; 05258 OPND_IDX((*top_opnd)) = ir2_idx; 05259 05260 break; 05261 05262 case Substring_Opr : 05263 05264 PRINTMSG(IR_LINE_NUM(ir_idx), 405, Error, IR_COL_NUM(ir_idx)); 05265 ok = FALSE; 05266 break; 05267 05268 default : 05269 PRINTMSG(IR_LINE_NUM(ir_idx), msg_num, Error, IR_COL_NUM(ir_idx)); 05270 ok = FALSE; 05271 break; 05272 } 05273 } 05274 else { /* something weird */ 05275 find_opnd_line_and_column(top_opnd, &line, &column); 05276 PRINTMSG(line, 626, Internal, column, 05277 "CN_Tbl_Idx, AT_Tbl_Idx, or IR_Tbl_Idx", 05278 "change_subscript"); 05279 } 05280 05281 TRACE (Func_Exit, "change_subscript", NULL); 05282 05283 return(ok); 05284 05285 } /* change_subscript */ 05286 05287 05288 /******************************************************************************\ 05289 |* *| 05290 |* Description: *| 05291 |* Construct the name for an internal DO loop label in a token. *| 05292 |* *| 05293 |* Input parameters: *| 05294 |* blk_idx : the index of the Block Stack entry for which the label is *| 05295 |* to be generated *| 05296 |* lbl_pos : indicates if the name is being generated for the top, *| 05297 |* cycle, exit, or skip label *| 05298 |* *| 05299 |* Output parameters: *| 05300 |* NONE *| 05301 |* *| 05302 |* Returns: *| 05303 |* The index to the Attribute entry for the internal label, or NULL_IDX *| 05304 |* if the Attribute entry already exists. *| 05305 |* *| 05306 \******************************************************************************/ 05307 05308 int gen_loop_lbl_name(int blk_idx, 05309 lbl_pos_type lbl_pos) 05310 05311 { 05312 int attr_idx; 05313 char lbl_name[MAX_ID_LEN]; /* A max as reasonable as any other. */ 05314 char lbl_pos_name[4][8] = { "top", "cycle", "exit", "bot" }; 05315 token_type lbl_token; 05316 int name_idx; 05317 char num_buf[8]; 05318 05319 05320 TRACE (Func_Entry, "gen_loop_lbl_name", NULL); 05321 05322 if (BLK_LABEL(blk_idx) != NULL_IDX) { 05323 strcpy(lbl_name, AT_OBJ_NAME_PTR(BLK_LABEL(blk_idx))); 05324 } 05325 else { 05326 sprintf(num_buf, "%d", BLK_DEF_LINE(blk_idx)); 05327 strcpy(lbl_name, num_buf); 05328 strcat(lbl_name, "u"); 05329 } 05330 05331 strcat(lbl_name, lbl_pos_name[lbl_pos]); 05332 sprintf(num_buf, "%d", BLK_LOOP_NUM(blk_idx)); 05333 strcat(lbl_name, num_buf); 05334 05335 BACK: 05336 05337 CREATE_ID(TOKEN_ID(lbl_token), lbl_name, strlen(lbl_name)); 05338 TOKEN_LEN(lbl_token) = strlen(lbl_name); 05339 05340 attr_idx = srch_sym_tbl(TOKEN_STR(lbl_token), TOKEN_LEN(lbl_token), 05341 &name_idx); 05342 05343 if (attr_idx == NULL_IDX) { 05344 attr_idx = ntr_sym_tbl(&lbl_token, name_idx); 05345 AT_OBJ_CLASS(attr_idx) = Label; 05346 ATL_CLASS(attr_idx) = Lbl_LoopInternal; 05347 ATL_EXECUTABLE(attr_idx) = TRUE; 05348 05349 if (lbl_pos == Top_Lbl && 05350 (stmt_type == Do_Iterative_Stmt || stmt_type == Do_While_Stmt)) { 05351 ATL_TOP_OF_LOOP(attr_idx) = TRUE; 05352 } 05353 05354 if (cmd_line_flags.debug_lvl == Debug_Lvl_1) { /* -ez -G1 */ 05355 ATL_DEBUG_CLASS(attr_idx) = Ldbg_Loop_Lbl; 05356 } 05357 } 05358 else if (lbl_pos == Top_Lbl || lbl_pos == Skip_Lbl) { 05359 05360 sprintf(num_buf, "%d", BLK_FIRST_SH_IDX(blk_idx)); 05361 strcat(lbl_name, num_buf); 05362 goto BACK; 05363 } 05364 05365 TRACE (Func_Exit, "gen_loop_lbl_name", NULL); 05366 05367 return(attr_idx); 05368 05369 } /* gen_loop_lbl_name */ 05370 05371 05372 /******************************************************************************\ 05373 |* *| 05374 |* Description: *| 05375 |* Do all the processing necessary if a C*$* BLOCKABLE directive is in *| 05376 |* effect for this loop. *| 05377 |* *| 05378 |* Input parameters: *| 05379 |* NONE *| 05380 |* *| 05381 |* Output parameters: *| 05382 |* NONE *| 05383 |* *| 05384 |* Returns: *| 05385 |* NOTHING *| 05386 |* *| 05387 \******************************************************************************/ 05388 05389 static void process_blockable_dir(void) 05390 05391 { 05392 int blk_idx; 05393 int dir_il_idx; 05394 int i; 05395 int il_idx; 05396 int il_idx_2; 05397 int ir_idx; 05398 05399 05400 TRACE (Func_Entry, "process_blockable_dir", NULL); 05401 05402 /* If a C*$* BLOCKABLE directive was specified ahead of this loop, make */ 05403 /* sure the DO-variable for this (outer) loop is a member of the */ 05404 /* DO-variable list and, if so, capture some information about the */ 05405 /* directive. */ 05406 05407 if (cdir_switches.blockable_sh_idx != NULL_IDX) { 05408 BLK_BLOCKABLE_DIR_SH_IDX(blk_stk_idx) = cdir_switches.blockable_sh_idx; 05409 ir_idx = 05410 SH_IR_IDX(cdir_switches.blockable_sh_idx); 05411 BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx) = IR_LIST_CNT_L(ir_idx); 05412 cdir_switches.blockable_sh_idx = NULL_IDX; 05413 dir_il_idx = IR_IDX_L(ir_idx); 05414 05415 for (i = 1; i <= IR_LIST_CNT_L(ir_idx); ++i) { 05416 05417 if (IL_IDX(dir_il_idx) == OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) { 05418 break; 05419 } 05420 else { 05421 dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx); 05422 } 05423 } 05424 05425 if (i <= IR_LIST_CNT_L(ir_idx)) { 05426 NTR_IR_LIST_TBL(il_idx); 05427 IR_FLD_R(ir_idx) = IL_Tbl_Idx; 05428 IR_IDX_R(ir_idx) = il_idx; 05429 IR_LIST_CNT_R(ir_idx) = 1; 05430 05431 IL_LINE_NUM(il_idx) = TOKEN_LINE(token); 05432 IL_COL_NUM(il_idx) = TOKEN_COLUMN(token); 05433 IL_FLD(il_idx) = CN_Tbl_Idx; 05434 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, i); 05435 } 05436 else { 05437 PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token), 05438 "BLOCKABLE"); 05439 SH_ERR_FLG(BLK_BLOCKABLE_DIR_SH_IDX(blk_stk_idx)) = TRUE; 05440 BLK_BLOCKABLE_DIR_SH_IDX(blk_stk_idx) = NULL_IDX; 05441 BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx) = 0; 05442 } 05443 } 05444 else { 05445 05446 /* Try to find an interative DO Block Stack entry that is the subject */ 05447 /* of a BLOCKABLE directive so we know whether or not we should check */ 05448 /* to see if the current loop is perfectly nested. */ 05449 05450 for (blk_idx = blk_stk_idx - 1; blk_idx > 1; --blk_idx) { 05451 05452 if (BLK_TYPE(blk_idx) == Do_Blk && 05453 SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) { 05454 break; 05455 } 05456 } 05457 05458 if (blk_idx > 1 && BLK_BLOCKABLE_NUM_LCVS(blk_idx) > 1) { 05459 05460 /* If the current nest is subject to a BLOCKABLE directive, set up */ 05461 /* the current and parent Block Stack entries to reflect the new */ 05462 /* loop and make sure the DO-variable of this loop is in the */ 05463 /* DO-variable list of the BLOCKABLE directive. */ 05464 05465 if (BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx - 1) > 1) { 05466 BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx) = 05467 BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx - 1) - 1; 05468 05469 blk_idx = blk_stk_idx - 1; 05470 05471 while (BLK_BLOCKABLE_DIR_SH_IDX(blk_idx) == NULL_IDX) { 05472 --blk_idx; 05473 } 05474 05475 ir_idx = SH_IR_IDX(BLK_BLOCKABLE_DIR_SH_IDX(blk_idx)); 05476 dir_il_idx = IR_IDX_L(ir_idx); 05477 05478 for (i = 1; i <= IR_LIST_CNT_L(ir_idx); ++i) { 05479 05480 if (IL_IDX(dir_il_idx) == 05481 OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) { 05482 break; 05483 } 05484 else { 05485 dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx); 05486 } 05487 } 05488 05489 if (i <= IR_LIST_CNT_L(ir_idx)) { 05490 05491 /* We found the current DO-variable in the DO-variable list of */ 05492 /* the BLOCKABLE directive. Add its position to the position */ 05493 /* list. */ 05494 05495 il_idx = IR_IDX_R(ir_idx); 05496 05497 while (IL_NEXT_LIST_IDX(il_idx) != NULL_IDX) { 05498 il_idx = IL_NEXT_LIST_IDX(il_idx); 05499 } 05500 05501 NTR_IR_LIST_TBL(il_idx_2); 05502 IL_NEXT_LIST_IDX(il_idx) = il_idx_2; 05503 IL_PREV_LIST_IDX(il_idx_2) = il_idx; 05504 ++IR_LIST_CNT_R(ir_idx); 05505 IL_LINE_NUM(il_idx_2) = TOKEN_LINE(token); 05506 IL_COL_NUM(il_idx_2) = TOKEN_COLUMN(token); 05507 IL_FLD(il_idx_2) = CN_Tbl_Idx; 05508 IL_IDX(il_idx_2) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, i); 05509 } 05510 else { 05511 PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token), 05512 "BLOCKABLE"); 05513 BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx) = 0; 05514 05515 blk_idx = blk_stk_idx - 1; 05516 05517 for (blk_idx = blk_stk_idx; blk_idx > 1; --blk_idx) { 05518 BLK_BLOCKABLE_NUM_LCVS(blk_idx) = 0; 05519 05520 if (BLK_BLOCKABLE_DIR_SH_IDX(blk_idx) != NULL_IDX) { 05521 SH_ERR_FLG(BLK_BLOCKABLE_DIR_SH_IDX(blk_idx)) = TRUE; 05522 BLK_BLOCKABLE_DIR_SH_IDX(blk_idx) = NULL_IDX; 05523 } 05524 } 05525 } 05526 } 05527 } 05528 } 05529 05530 TRACE (Func_Exit, "process_blockable_dir", NULL); 05531 05532 return; 05533 05534 } /* process_blockable_dir */ 05535 05536 05537 /******************************************************************************\ 05538 |* *| 05539 |* Description: *| 05540 |* Do all the processing necessary if a C*$* INTERCHANGE directive *| 05541 |* is in effect for this loop. *| 05542 |* *| 05543 |* Input parameters: *| 05544 |* NONE *| 05545 |* *| 05546 |* Output parameters: *| 05547 |* NONE *| 05548 |* *| 05549 |* Returns: *| 05550 |* TRUE if the current DO statement immediately follows a preceding *| 05551 |* iterative DO statement. *| 05552 |* *| 05553 \******************************************************************************/ 05554 05555 static void process_interchange_dir(void) 05556 05557 { 05558 int blk_idx; 05559 int dir_il_idx; 05560 int i; 05561 int il_idx; 05562 int il_idx_2; 05563 int ir_idx; 05564 int sh_idx; 05565 05566 05567 TRACE (Func_Entry, "process_interchange_dir", NULL); 05568 05569 /* If a C*$* INTERCHANGE directive was specified ahead of this loop, make */ 05570 /* sure the DO-variable for this (outer) loop is a member of the */ 05571 /* DO-variable list and, if so, capture some information about the */ 05572 /* directive. */ 05573 05574 if (cdir_switches.interchange_sh_idx != NULL_IDX) { 05575 sh_idx = SH_PREV_IDX(BLK_FIRST_SH_IDX(blk_stk_idx)); 05576 05577 while (SH_COMPILER_GEN(sh_idx) || 05578 (SH_STMT_TYPE(sh_idx) == Directive_Stmt && 05579 IR_OPR(SH_IR_IDX(sh_idx)) != Interchange_Dir_Opr)) { 05580 sh_idx = SH_PREV_IDX(sh_idx); 05581 } 05582 05583 if (sh_idx != cdir_switches.interchange_sh_idx) { 05584 05585 /* Found a statement between the interchange dir and the do loop. */ 05586 05587 PRINTMSG(SH_GLB_LINE(sh_idx), 1381, Error, 0, "INTERCHANGE"); 05588 SH_ERR_FLG(cdir_switches.interchange_sh_idx) = TRUE; 05589 cdir_switches.interchange_sh_idx = NULL_IDX; 05590 } 05591 else { 05592 BLK_INTERCHANGE_DIR_SH_IDX(blk_stk_idx) = 05593 cdir_switches.interchange_sh_idx; 05594 ir_idx = SH_IR_IDX(cdir_switches.interchange_sh_idx); 05595 BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx) = IR_LIST_CNT_L(ir_idx); 05596 cdir_switches.interchange_sh_idx = NULL_IDX; 05597 dir_il_idx = IR_IDX_L(ir_idx); 05598 05599 for (i = 1; i <= IR_LIST_CNT_L(ir_idx); ++i) { 05600 05601 if (IL_IDX(dir_il_idx) == OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) { 05602 break; 05603 } 05604 else { 05605 dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx); 05606 } 05607 } 05608 05609 if (i <= IR_LIST_CNT_L(ir_idx)) { 05610 05611 /* Holds how many things are available in the list. */ 05612 05613 NTR_IR_LIST_TBL(il_idx); 05614 IR_FLD_R(ir_idx) = IL_Tbl_Idx; 05615 IR_IDX_R(ir_idx) = il_idx; 05616 IR_LIST_CNT_R(ir_idx) = 1; 05617 05618 IL_LINE_NUM(il_idx) = TOKEN_LINE(token); 05619 IL_COL_NUM(il_idx) = TOKEN_COLUMN(token); 05620 IL_FLD(il_idx) = CN_Tbl_Idx; 05621 IL_IDX(il_idx) = C_INT_TO_CN( CG_INTEGER_DEFAULT_TYPE, i); 05622 } 05623 else { 05624 05625 /* Didn't find the do var in the interchange do var list */ 05626 05627 PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token), 05628 "INTERCHANGE"); 05629 SH_ERR_FLG(BLK_INTERCHANGE_DIR_SH_IDX(blk_stk_idx)) = TRUE; 05630 BLK_INTERCHANGE_DIR_SH_IDX(blk_stk_idx) = NULL_IDX; 05631 BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx) = 0; 05632 } 05633 } 05634 } 05635 else { 05636 05637 /* Try to find an interative DO Block Stack entry that is the subject */ 05638 /* of an INTERCHANGE directive so we know whether or not we should */ 05639 /* check to see if the current loop is perfectly nested. */ 05640 05641 for (blk_idx = blk_stk_idx - 1; blk_idx > 1; --blk_idx) { 05642 05643 if (BLK_TYPE(blk_idx) == Do_Blk && 05644 SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) { 05645 break; 05646 } 05647 } 05648 05649 if (blk_idx > 1 && BLK_INTERCHANGE_NUM_LCVS(blk_idx) > 1) { 05650 05651 if (loop_top_is_perfectly_nested("INTERCHANGE")) { 05652 05653 /* The DO statement is perfectly nested within the containing DO */ 05654 /* loop. If the current nest is subject to an INTERCHANGE */ 05655 /* directive, set up the current and parent Block Stack entries */ 05656 /* to reflect the new loop and make sure the DO-variable of this */ 05657 /* loop is in the DO-variable list of the INTERCHANGE directive. */ 05658 05659 if (BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx - 1) > 1) { 05660 BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx) = 05661 BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx - 1) - 1; 05662 05663 blk_idx = blk_stk_idx - 1; 05664 05665 while (BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) == NULL_IDX) { 05666 --blk_idx; 05667 } 05668 05669 ir_idx = SH_IR_IDX(BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)); 05670 dir_il_idx = IR_IDX_L(ir_idx); 05671 05672 for (i = 1; i <= IR_LIST_CNT_L(ir_idx); ++i) { 05673 05674 if (IL_IDX(dir_il_idx) == 05675 OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) { 05676 break; 05677 } 05678 else { 05679 dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx); 05680 } 05681 } 05682 05683 if (i <= IR_LIST_CNT_L(ir_idx)) { 05684 05685 /* We found the current DO-variable in the DO-variable list */ 05686 /* of the INTERCHANGE directive. Add its position to the */ 05687 /* position list. */ 05688 05689 il_idx = IR_IDX_R(ir_idx); 05690 05691 while (IL_NEXT_LIST_IDX(il_idx) != NULL_IDX) { 05692 il_idx = IL_NEXT_LIST_IDX(il_idx); 05693 } 05694 05695 NTR_IR_LIST_TBL(il_idx_2); 05696 IL_NEXT_LIST_IDX(il_idx) = il_idx_2; 05697 IL_PREV_LIST_IDX(il_idx_2) = il_idx; 05698 ++IR_LIST_CNT_R(ir_idx); 05699 IL_LINE_NUM(il_idx_2) = TOKEN_LINE(token); 05700 IL_COL_NUM(il_idx_2) = TOKEN_COLUMN(token); 05701 IL_FLD(il_idx_2) = CN_Tbl_Idx; 05702 IL_IDX(il_idx_2) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, i); 05703 } 05704 else { 05705 PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token), 05706 "INTERCHANGE"); 05707 BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx) = 0; 05708 05709 blk_idx = blk_stk_idx - 1; 05710 05711 for (blk_idx = blk_stk_idx; blk_idx > 1; --blk_idx) { 05712 BLK_INTERCHANGE_NUM_LCVS(blk_idx) = 0; 05713 BLK_HAS_NESTED_LOOP(blk_idx) = FALSE; 05714 05715 if (BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) != NULL_IDX) { 05716 SH_ERR_FLG(BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)) = TRUE; 05717 BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) = 05718 NULL_IDX; 05719 } 05720 } 05721 } 05722 } 05723 } 05724 } 05725 } 05726 05727 TRACE (Func_Exit, "process_interchange_dir", NULL); 05728 05729 return; 05730 05731 } /* process_interchange_dir */ 05732 05733 # if defined(GENERATE_WHIRL) 05734 05735 /******************************************************************************\ 05736 |* *| 05737 |* Description: *| 05738 |* Do the processing to check for perfectly nested loops for PDO, *| 05739 |* DOACROSS, and PARALLEL DO directives. *| 05740 |* *| 05741 |* Input parameters: *| 05742 |* NONE *| 05743 |* *| 05744 |* Output parameters: *| 05745 |* NONE *| 05746 |* *| 05747 |* Returns: *| 05748 |* NOTHING *| 05749 |* *| 05750 \******************************************************************************/ 05751 05752 static void check_mp_dir_nesting(void) 05753 05754 { 05755 int blk_idx; 05756 int col; 05757 int dir_list_idx; 05758 int i; 05759 int line; 05760 int list_idx; 05761 int ir_idx; 05762 char str[80]; 05763 05764 05765 TRACE (Func_Entry, "check_mp_dir_nesting", NULL); 05766 05767 /* If an -mp directive was specified ahead of this loop, make */ 05768 /* sure the DO-variable for this (outer) loop is a member of the */ 05769 /* DO-variable list and, if so, capture some information about the */ 05770 /* directive. */ 05771 05772 if (cdir_switches.dir_nest_check_sh_idx != NULL_IDX) { 05773 BLK_DIR_NEST_CHECK_SH_IDX(blk_stk_idx) = 05774 cdir_switches.dir_nest_check_sh_idx; 05775 ir_idx = SH_IR_IDX(cdir_switches.dir_nest_check_sh_idx); 05776 05777 list_idx = IR_IDX_L(ir_idx); 05778 05779 for (i = 0; i < MP_DIR_NEST_IDX; i++) { 05780 list_idx = IL_NEXT_LIST_IDX(list_idx); 05781 } 05782 05783 # ifdef _DEBUG 05784 if (list_idx == NULL_IDX || 05785 IL_FLD(list_idx) != IL_Tbl_Idx) { 05786 PRINTMSG(SH_GLB_LINE(cdir_switches.dir_nest_check_sh_idx), 05787 626, Internal, 05788 SH_COL_NUM(cdir_switches.dir_nest_check_sh_idx), 05789 "IL_Tbl_Idx", "check_mp_dir_nesting"); 05790 } 05791 # endif 05792 05793 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx) = IL_LIST_CNT(list_idx); 05794 cdir_switches.dir_nest_check_sh_idx = NULL_IDX; 05795 dir_list_idx = IL_IDX(list_idx); 05796 05797 /* this must be the first do var in the NEST clause */ 05798 05799 if (IL_IDX(dir_list_idx) != OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) { 05800 05801 find_opnd_line_and_column(&IL_OPND(dir_list_idx), &line, &col); 05802 05803 PRINTMSG(line, 1416, Error, col); 05804 SH_ERR_FLG(BLK_DIR_NEST_CHECK_SH_IDX(blk_stk_idx)) = TRUE; 05805 BLK_DIR_NEST_CHECK_SH_IDX(blk_stk_idx) = NULL_IDX; 05806 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx) = 0; 05807 } 05808 } 05809 else { 05810 05811 for (blk_idx = blk_stk_idx - 1; blk_idx > 1; --blk_idx) { 05812 05813 if (BLK_TYPE(blk_idx) == Do_Blk && 05814 SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) { 05815 break; 05816 } 05817 } 05818 05819 if (blk_idx > 1 && BLK_DIR_NEST_CHECK_NUM_LCVS(blk_idx) > 1) { 05820 05821 blk_idx = blk_stk_idx - 1; 05822 05823 while (blk_idx > 1 && 05824 BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) == NULL_IDX) { 05825 --blk_idx; 05826 } 05827 05828 if (BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) != NULL_IDX) { 05829 switch (IR_OPR(SH_IR_IDX(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)))) { 05830 case Pdo_Par_Opr: 05831 strcpy(str, "PDO"); 05832 break; 05833 05834 case Parallel_Do_Par_Opr: 05835 strcpy(str, "PARALLEL DO"); 05836 break; 05837 05838 case Doacross_Dollar_Opr: 05839 strcpy(str, "DOACROSS"); 05840 break; 05841 05842 default: 05843 strcpy(str, "DO"); 05844 break; 05845 } 05846 } 05847 else { 05848 strcpy(str, "DO"); 05849 } 05850 05851 if (loop_top_is_perfectly_nested(str)) { 05852 05853 /* The DO statement is perfectly nested within the containing DO */ 05854 /* loop. Set up the current and parent Block Stack entries */ 05855 /* to reflect the new loop and make sure the DO-variable of this */ 05856 /* loop is in the proper position in the NEST clause. */ 05857 05858 if (BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx - 1) > 1) { 05859 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx) = 05860 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx - 1) - 1; 05861 05862 blk_idx = blk_stk_idx - 1; 05863 05864 while (blk_idx > 1 && 05865 BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) == NULL_IDX) { 05866 --blk_idx; 05867 } 05868 05869 # ifdef _DEBUG 05870 if (blk_idx <= 1 || 05871 BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) == NULL_IDX) { 05872 PRINTMSG(SH_GLB_LINE(cdir_switches.dir_nest_check_sh_idx), 05873 626, Internal, 05874 SH_COL_NUM(cdir_switches.dir_nest_check_sh_idx), 05875 "BLK_DIR_NEST_CHECK_SH_IDX", "check_mp_dir_nesting"); 05876 } 05877 # endif 05878 05879 ir_idx = SH_IR_IDX(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)); 05880 05881 /* Find the NEST clause */ 05882 05883 list_idx = IR_IDX_L(ir_idx); 05884 05885 for (i = 0; i < MP_DIR_NEST_IDX; i++) { 05886 list_idx = IL_NEXT_LIST_IDX(list_idx); 05887 } 05888 05889 # ifdef _DEBUG 05890 if (list_idx == NULL_IDX || 05891 IL_FLD(list_idx) != IL_Tbl_Idx) { 05892 PRINTMSG(SH_GLB_LINE(cdir_switches.dir_nest_check_sh_idx), 05893 626, Internal, 05894 SH_COL_NUM(cdir_switches.dir_nest_check_sh_idx), 05895 "IL_Tbl_Idx", "check_mp_dir_nesting"); 05896 } 05897 # endif 05898 05899 dir_list_idx = IL_IDX(list_idx); 05900 05901 for (i = 1; 05902 i < ((IL_LIST_CNT(list_idx) - 05903 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx)) + 1); 05904 i++) { 05905 05906 dir_list_idx = IL_NEXT_LIST_IDX(dir_list_idx); 05907 } 05908 05909 if (IL_IDX(dir_list_idx) != 05910 OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) { 05911 05912 find_opnd_line_and_column(&IL_OPND(dir_list_idx),&line,&col); 05913 05914 PRINTMSG(line, 1416, Error, col); 05915 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx) = 0; 05916 blk_idx = blk_stk_idx - 1; 05917 05918 for (blk_idx = blk_stk_idx; blk_idx > 1; --blk_idx) { 05919 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_idx) = 0; 05920 BLK_HAS_NESTED_LOOP(blk_idx) = FALSE; 05921 05922 if (BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) != NULL_IDX) { 05923 SH_ERR_FLG(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)) = TRUE; 05924 BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) = 05925 NULL_IDX; 05926 } 05927 } 05928 } 05929 } 05930 } 05931 } 05932 } 05933 05934 TRACE (Func_Exit, "check_mp_dir_nesting", NULL); 05935 05936 return; 05937 05938 } /* check_mp_dir_nesting */ 05939 05940 # endif 05941 05942 /******************************************************************************\ 05943 |* *| 05944 |* Description: *| 05945 |* Check to see if the current iterative DO statement immediately *| 05946 |* a preceding iterative DO statement. That is, check to see if the *| 05947 |* top of the current loop is perfectly nested within its containing *| 05948 |* iterative DO loop. *| 05949 |* *| 05950 |* Input parameters: *| 05951 |* NONE *| 05952 |* *| 05953 |* Output parameters: *| 05954 |* NONE *| 05955 |* *| 05956 |* Returns: *| 05957 |* TRUE if the current DO statement immediately follows a preceding *| 05958 |* iterative DO statement. *| 05959 |* *| 05960 \******************************************************************************/ 05961 05962 static boolean loop_top_is_perfectly_nested(char *str) 05963 05964 { 05965 int blk_idx; 05966 boolean perfectly_nested = FALSE; 05967 int sh_idx; 05968 05969 05970 TRACE (Func_Entry, "loop_top_is_perfectly_nested", NULL); 05971 05972 blk_idx = blk_stk_idx - 1; 05973 05974 if (BLK_TYPE(blk_idx) == Do_Blk && 05975 SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) { 05976 sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 05977 05978 while (SH_COMPILER_GEN(sh_idx)) { 05979 sh_idx = SH_PREV_IDX(sh_idx); 05980 } 05981 05982 if (SH_STMT_TYPE(sh_idx) == Do_Iterative_Stmt) { 05983 BLK_HAS_NESTED_LOOP(blk_idx) = TRUE; 05984 perfectly_nested = TRUE; 05985 } 05986 } 05987 else { 05988 sh_idx = BLK_FIRST_SH_IDX(blk_idx); 05989 } 05990 05991 if (! perfectly_nested) { 05992 PRINTMSG(SH_GLB_LINE(sh_idx), 1380, Error, SH_COL_NUM(sh_idx), str); 05993 05994 for (blk_idx = blk_stk_idx; blk_idx > 1; --blk_idx) { 05995 05996 if (BLK_TYPE(blk_idx) == Do_Blk) { 05997 BLK_INTERCHANGE_NUM_LCVS(blk_idx) = 0; 05998 BLK_DIR_NEST_CHECK_NUM_LCVS(blk_idx) = 0; 05999 BLK_HAS_NESTED_LOOP(blk_idx) = 0; 06000 06001 if (BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) != NULL_IDX) { 06002 SH_ERR_FLG(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)) = TRUE; 06003 BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) = NULL_IDX; 06004 } 06005 06006 if (BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) != NULL_IDX) { 06007 SH_ERR_FLG(BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)) = TRUE; 06008 BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) = NULL_IDX; 06009 break; 06010 } 06011 } 06012 } 06013 } 06014 06015 TRACE (Func_Exit, "loop_top_is_perfectly_nested", NULL); 06016 06017 return(perfectly_nested); 06018 06019 } /* loop_top_is_perfectly_nested */ 06020 06021 06022 /******************************************************************************\ 06023 |* *| 06024 |* Description: *| 06025 |* Create the endif opr for if processing. *| 06026 |* *| 06027 |* Input parameters: *| 06028 |* NONE *| 06029 |* *| 06030 |* Output parameters: *| 06031 |* NONE *| 06032 |* *| 06033 |* Returns: *| 06034 |* NOTHING *| 06035 |* *| 06036 \******************************************************************************/ 06037 06038 static void gen_if_ir(int if_stmt_lbl_idx, 06039 int if_stmt_sh_idx, 06040 int save_if_stmt_start_line, 06041 int save_if_stmt_start_col) 06042 06043 { 06044 int ir_idx; 06045 06046 06047 TRACE (Func_Entry, "gen_if_ir", NULL); 06048 06049 if (!SH_ERR_FLG(curr_stmt_sh_idx) && !SH_ERR_FLG(if_stmt_sh_idx)) { 06050 06051 # if defined(_HIGH_LEVEL_IF_FORM) 06052 06053 /* Generate an End_If_Stmt SH and mark it as compiler-generated */ 06054 /* (so that the IF stmt looks like a user IF construct so that */ 06055 /* all the IR generated to represent the <action-stmt> can be */ 06056 /* bracketed. No need to generate a fake Then_Stmt SH because */ 06057 /* the Semantics Pass just deletes it anyway. */ 06058 /* Do NOT pop the block stack entry. */ 06059 06060 gen_sh(After, End_If_Stmt, stmt_start_line, stmt_start_col, 06061 FALSE, /* Error flag. */ 06062 FALSE, /* Labeled. */ 06063 TRUE); /* Compiler-generated. */ 06064 SH_P2_SKIP_ME(curr_stmt_sh_idx) = TRUE; 06065 06066 NTR_IR_TBL(ir_idx); 06067 IR_OPR(ir_idx) = Endif_Opr; 06068 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 06069 IR_LINE_NUM(ir_idx) = stmt_start_line; 06070 IR_COL_NUM(ir_idx) = stmt_start_col; 06071 IR_FLD_L(ir_idx) = SH_Tbl_Idx; 06072 IR_IDX_L(ir_idx) = if_stmt_sh_idx; 06073 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 06074 # else 06075 stmt_start_line = save_if_stmt_start_line; 06076 stmt_start_col = save_if_stmt_start_col; 06077 06078 gen_sh(After, Continue_Stmt, stmt_start_line, stmt_start_col, 06079 FALSE, TRUE, TRUE); 06080 06081 NTR_IR_TBL(ir_idx); 06082 SH_IR_IDX(curr_stmt_sh_idx) = ir_idx; 06083 IR_OPR(ir_idx) = Label_Opr; 06084 06085 /* LRR - bhj put in short typeless for type idx */ 06086 06087 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 06088 IR_LINE_NUM(ir_idx) = stmt_start_line; 06089 IR_COL_NUM(ir_idx) = stmt_start_col; 06090 IR_FLD_L(ir_idx) = AT_Tbl_Idx; 06091 IR_IDX_L(ir_idx) = if_stmt_lbl_idx; 06092 IR_LINE_NUM_L(ir_idx) = stmt_start_line; 06093 IR_COL_NUM_L(ir_idx) = stmt_start_col; 06094 AT_DEFINED(if_stmt_lbl_idx) = TRUE; 06095 ATL_DEF_STMT_IDX(if_stmt_lbl_idx) = curr_stmt_sh_idx; 06096 06097 # endif 06098 } 06099 else if (SH_ERR_FLG(curr_stmt_sh_idx)) { 06100 SH_ERR_FLG(if_stmt_sh_idx) = TRUE; 06101 } 06102 TRACE (Func_Exit, "gen_if_ir", NULL); 06103 06104 return; 06105 }