p_ctl_flow.c

Go to the documentation of this file.
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(