Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
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(stmt_start_line, 1568, Ansi, stmt_start_col, "assign GOTO");
03591    }
03592    else {
03593 
03594       if (label_list_found) {
03595          parse_err_flush(Find_EOS, EOS_STR);
03596       }
03597       else {
03598          parse_err_flush(Find_EOS, ", or ( or EOS");
03599       }
03600   
03601    }
03602 
03603    if (cif_flags & MISC_RECS) {
03604       cif_stmt_type_rec(TRUE, CIF_Go_To_Assigned_Stmt, statement_number);
03605    }
03606 
03607 EXIT:
03608 
03609    NEXT_LA_CH;
03610 
03611    TRACE (Func_Exit, "parse_goto_stmt", NULL);
03612 
03613    return;
03614 
03615 }  /* parse_goto_stmt */
03616 
03617 
03618 /******************************************************************************\
03619 |*                                                                            *|
03620 |* Description:                                                               *|
03621 |*      This function parses all forms of statements beginning with the key-  *|
03622 |*      word IF:                                                              *|
03623 |*               [if-construct-name:] IF (scalar-logical-expr) THEN           *|
03624 |*               IF (scalar-logical-expr) action-stmt                         *|
03625 |*               IF (scalar-numeric-expr) label, label, label  {obsolescent}  *|
03626 |*               IF (scalar-logical-expr) label, label         {outmoded}     *|
03627 |*               IF (scalar-numeric-expr) label, label         {outmoded}     *|
03628 |*                                                                            *|
03629 |* Input parameters:                                                          *|
03630 |*      NONE                                                                  *|
03631 |*                                                                            *|
03632 |* Output parameters:                                                         *|
03633 |*      NONE                                                                  *|
03634 |*                                                                            *|
03635 |* Returns:                                                                   *|
03636 |*      NONE                                                                  *|
03637 |*                                                                            *|
03638 |* Algorithm notes:                                                           *|
03639 |*   This procedure is called recursively to process the action-stmt of a     *|
03640 |*   logical IF if the action-stmt is an arithmetic IF or one of the outmoded *|
03641 |*   IF forms (or, erroneously, another logical IF or IF construct).          *|
03642 |*                                                                            *|
03643 \******************************************************************************/
03644 
03645 void parse_if_stmt (void)
03646 
03647 {
03648    opnd_type    cond_expr;
03649    int          expr_start_line;
03650    int          expr_start_col;
03651    int          if_stmt_sh_idx;
03652    int          ir_idx;
03653    int          lbl_attr_idx;
03654    int          neg_il_idx;
03655    int          pos_il_idx;
03656    int          save_if_stmt_start_line;
03657    int          save_if_stmt_start_col;
03658    int          sh_idx;
03659    boolean      stmt_parsers_called;
03660    int          zero_il_idx;
03661 
03662 
03663    TRACE (Func_Entry, "parse_if_stmt", NULL);
03664 
03665    /* ----------------------------------------------------------------------- */
03666    /* Parse "(conditional-expr)".                                             */
03667    /* ----------------------------------------------------------------------- */
03668 
03669    if (LA_CH_VALUE == LPAREN) {
03670       NEXT_LA_CH;
03671 
03672       expr_start_line = LA_CH_LINE;
03673       expr_start_col  = LA_CH_COLUMN;
03674 
03675       parse_expr(&cond_expr);
03676 
03677       if (LA_CH_VALUE != RPAREN) {
03678 
03679          if ( ! parse_err_flush(Find_Rparen, ")") ) {
03680             parse_err_flush(Find_EOS, NULL);
03681             goto EXIT;
03682          }
03683       }
03684    }
03685    else {
03686       parse_err_flush(Find_EOS, "(");
03687       goto EXIT;
03688    }
03689 
03690    NEXT_LA_CH;
03691 
03692 
03693    /* ----------------------------------------------------------------------- */
03694    /* Now figure out what kind of IF we're parsing.                           */
03695    /* ----------------------------------------------------------------------- */
03696 
03697    if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) {
03698       
03699       if (TOKEN_VALUE(token) == Tok_Kwd_Then) {
03700  
03701          if (LA_CH_VALUE != EOS) {
03702 
03703             /* Identifier starting with THEN or bad character following THEN? */
03704 
03705             if (LA_CH_VALUE == USCORE  ||  LA_CH_CLASS == Ch_Class_Letter  ||
03706                 LA_CH_CLASS == Ch_Class_Digit) {
03707                reset_lex(TOKEN_BUF_IDX(token), TOKEN_STMT_NUM(token));
03708                MATCHED_TOKEN_CLASS(Tok_Class_Id);
03709                goto PARSE_LOGICAL_IF;
03710             }
03711             else if (LA_CH_VALUE == LPAREN  ||  LA_CH_VALUE == PERCENT  ||
03712                      LA_CH_VALUE == EQUAL) {
03713                goto PARSE_LOGICAL_IF;
03714             }
03715             else {
03716 
03717                /* Have THEN <bad-char>.  Let it go through so that a Block    */
03718                /* Stack entry will be created so a later END IF will have an  */
03719                /* entry to match.                                             */
03720  
03721                parse_err_flush(Find_EOS, EOS_STR); 
03722             }
03723          }
03724 
03725          /* ----------------------------------------------------------------- */
03726          /* IF THEN of an IF construct                                        */
03727          /* ----------------------------------------------------------------- */
03728 
03729          if (if_stmt_lbl_idx == NULL_IDX) {
03730   
03731             /* It's not the action-stmt of a logical IF (which would be an    */
03732             /* error).                                                        */
03733 
03734             if ( ! CURR_BLK_NO_EXEC  ||  ! iss_blk_stk_err() ) {
03735                curr_stmt_category = Executable_Stmt_Cat;
03736                PUSH_BLK_STK (If_Blk);
03737             }
03738             else {
03739                PUSH_BLK_STK (If_Blk);
03740                CURR_BLK_ERR = TRUE;
03741             }
03742 
03743             CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx;
03744             LINK_TO_PARENT_BLK;
03745 
03746             if (stmt_construct_idx != NULL_IDX) {
03747                CURR_BLK_NAME                        = stmt_construct_idx;
03748                ATL_CLASS(stmt_construct_idx)        = Lbl_Construct;
03749                ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx;
03750                SH_ERR_FLG(curr_stmt_sh_idx)         =
03751                   SH_ERR_FLG(curr_stmt_sh_idx) | AT_DCL_ERR(stmt_construct_idx);
03752                stmt_construct_idx                   = NULL_IDX;
03753             }
03754 
03755             /* Generate a Br_True IR to hold the conditional expression and   */
03756             /* branch-around label.  The .NOT. subtree is added by the        */
03757             /* Semantics Pass if the expression is OK.  The label's Attr entry*/
03758             /* fields are completed as a part of END IF processing.           */
03759 
03760             if ( ! SH_ERR_FLG(curr_stmt_sh_idx) ) {
03761                NTR_IR_TBL(ir_idx);
03762                SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
03763                IR_OPR(ir_idx)              = Br_True_Opr;
03764                IR_TYPE_IDX(ir_idx)         = LOGICAL_DEFAULT_TYPE;
03765                IR_LINE_NUM(ir_idx)         = expr_start_line;
03766                IR_COL_NUM(ir_idx)          = expr_start_col;
03767                COPY_OPND(IR_OPND_L(ir_idx), cond_expr);
03768 #if 0
03769                CURR_BLK_LABEL              = gen_internal_lbl(stmt_start_line);
03770                IR_LINE_NUM_R(ir_idx)       = expr_start_line;
03771                IR_COL_NUM_R(ir_idx)        = expr_start_col;
03772                IR_FLD_R(ir_idx)            = AT_Tbl_Idx;
03773                IR_IDX_R(ir_idx)            = CURR_BLK_LABEL;
03774 #endif
03775             }
03776 
03777             /* Generate a Then_Stmt SH and block stack entry.  This is needed */
03778             /* now to check the validity of label references.  It'll be       */
03779             /* thrown away by the Semantics Pass.                             */
03780 
03781             gen_sh(After, Then_Stmt, TOKEN_LINE(token), TOKEN_COLUMN(token),
03782                    SH_ERR_FLG(curr_stmt_sh_idx), FALSE, FALSE);
03783  
03784             PUSH_BLK_STK(If_Then_Blk);
03785             blk_stk[blk_stk_idx]              = blk_stk[blk_stk_idx - 1];
03786             CURR_BLK                          = If_Then_Blk;
03787             CURR_BLK_FIRST_SH_IDX             = curr_stmt_sh_idx;
03788             LINK_TO_PARENT_BLK;
03789 
03790             if (cif_flags & MISC_RECS) {
03791                cif_stmt_type_rec(TRUE, CIF_If_Construct, statement_number);
03792             }
03793          }
03794          else {
03795 
03796             /* The IF-THEN stmt of an IF construct can not be the action-stmt */
03797             /* of a logical IF.                                               */
03798      
03799             PRINTMSG(stmt_start_line, 365, Error, stmt_start_col);
03800          }
03801 
03802          goto EXIT;
03803 
03804       }
03805 
03806       /* -------------------------------------------------------------------- */
03807       /* Must be parsing a logical IF.                                        */
03808       /* Note that the identifier following the closing paren of the          */
03809       /* conditional expression might have started with the letters THEN      */
03810       /* (token scanning was reset above).                                    */
03811       /*--------------------------------------------------------------------- */
03812 
03813 PARSE_LOGICAL_IF:
03814 
03815       stmt_type                      = If_Stmt;
03816       SH_STMT_TYPE(curr_stmt_sh_idx) = If_Stmt;
03817       if_stmt_sh_idx                 = curr_stmt_sh_idx;
03818       save_if_stmt_start_line        = stmt_start_line;
03819       save_if_stmt_start_col         = stmt_start_col;
03820 
03821       if ( ! CURR_BLK_NO_EXEC  ||  ! iss_blk_stk_err() ) {
03822          curr_stmt_category = Executable_Stmt_Cat;
03823       }
03824 
03825       if (if_stmt_lbl_idx == NULL_IDX) {
03826          if_stmt_lbl_idx = gen_internal_lbl(stmt_start_line);
03827       }
03828       else {
03829          PRINTMSG(stmt_start_line, 365, Error, stmt_start_col);
03830          parse_err_flush(Find_EOS, NULL);
03831          NEXT_LA_CH;
03832          goto EXIT;
03833       }
03834 
03835       if (cif_flags & MISC_RECS) {
03836          cif_stmt_type_rec(TRUE, CIF_If_Logical_Stmt, statement_number);
03837       }
03838 
03839 
03840       /* If the IF stmt to this point is OK, generate the Br_True IR to hold  */
03841       /* the index to the conditional expression tree (temporarily) and the   */
03842       /* index of the compiler-generated branch-around label.  This label is  */
03843       /* not needed for the high-level form of the IF but it's presence is    */
03844       /* used as a flag to determine whether or not an IF stmt is being       */
03845       /* parsed.  It is better to just not perturb the code and let the       */
03846       /* Semantics Pass ignore this label when in high-level IF mode.         */
03847 
03848       if ( ! SH_ERR_FLG(curr_stmt_sh_idx) ) {
03849          NTR_IR_TBL(ir_idx);
03850          SH_IR_IDX(if_stmt_sh_idx)      = ir_idx;
03851          IR_OPR(ir_idx)                 = Br_True_Opr;
03852          IR_TYPE_IDX(ir_idx)            = LOGICAL_DEFAULT_TYPE;
03853          IR_LINE_NUM(ir_idx)            = expr_start_line;
03854          IR_COL_NUM(ir_idx)             = expr_start_col;
03855 
03856          COPY_OPND(IR_OPND_L(ir_idx), cond_expr);
03857          IR_LINE_NUM_R(ir_idx)          = expr_start_line;
03858          IR_COL_NUM_R(ir_idx)           = expr_start_col;
03859          IR_FLD_R(ir_idx)               = AT_Tbl_Idx;
03860          IR_IDX_R(ir_idx)               = if_stmt_lbl_idx;
03861          AT_REFERENCED(if_stmt_lbl_idx) = Referenced;
03862       }
03863 
03864 
03865       /* Now parse the action-stmt.                                           */
03866       /* determine_stmt_type fills in the stmt type, line number, column      */
03867       /* number, and whether or not the statement is labeled.                 */
03868 
03869       gen_sh(After, Null_Stmt, 0, 0, FALSE, FALSE, FALSE);
03870 
03871       SH_ACTION_STMT(curr_stmt_sh_idx)  = TRUE;
03872       stmt_parsers_called               = FALSE;
03873  
03874       determine_stmt_type();
03875 
03876       if (stmt_type == Where_Cstrct_Stmt ||
03877           stmt_type == End_Stmt ||
03878           stmt_type == Forall_Cstrct_Stmt) {
03879 
03880          /* Where_Cstrct_Stmt                                       */
03881          /* Procedure determine_stmt_type does not distinguish      */
03882          /* between a WHERE stmt and a WHERE construct so we must   */
03883          /* actually parse the WHERE to determine what it is.       */
03884 
03885          /* End_Stmt                                                */
03886          /* The stmt has to be parsed because determine_stmt_type   */
03887          /* can't tell a real END statement from an ENDFILE stmt.   */
03888 
03889          /* Forall_Cstrct_Stmt                                      */
03890          /* Procedure determine_stmt_type does not distinguish      */
03891          /* between a FORALL stmt and a FORALL construct so we      */
03892          /* must actually parse the FORALL to determine what it is. */
03893 
03894          INCREMENT_STATEMENT_NUMBER;
03895          stmt_parsers_called                    = TRUE;
03896          in_action_stmt_of_if_where_or_forall   = TRUE;
03897    
03898          (*stmt_parsers[stmt_type])();
03899 
03900          in_action_stmt_of_if_where_or_forall   = FALSE;
03901       }
03902 
03903       switch (stmt_type) {
03904          case Allocatable_Stmt:
03905          case Automatic_Stmt:
03906          case Common_Stmt:
03907          case Contains_Stmt:
03908          case Cpnt_Decl_Stmt:
03909          case Data_Stmt:
03910          case Derived_Type_Stmt:
03911          case Dimension_Stmt:
03912          case Directive_Stmt:
03913          case Equivalence_Stmt:
03914          case External_Stmt:
03915          case Format_Stmt:
03916          case Implicit_Stmt:
03917          case Implicit_None_Stmt:
03918          case Intent_Stmt:
03919          case Interface_Stmt:
03920          case Intrinsic_Stmt:
03921          case Module_Proc_Stmt:
03922          case Namelist_Stmt:
03923          case Optional_Stmt:
03924          case Parameter_Stmt:
03925          case Pointer_Stmt:
03926          case Private_Stmt:
03927          case Public_Stmt:
03928          case Save_Stmt:
03929          case Sequence_Stmt:
03930          case Stmt_Func_Stmt:
03931          case Target_Stmt:
03932          case Task_Common_Stmt:
03933          case Type_Decl_Stmt:
03934          case Use_Stmt:
03935          case Volatile_Stmt:
03936          case Blockdata_Stmt:
03937          case Elemental_Stmt:
03938          case Function_Stmt:
03939          case Module_Stmt:
03940          case Program_Stmt:
03941          case Pure_Stmt:
03942          case Recursive_Stmt:
03943          case Subroutine_Stmt:
03944 
03945             PRINTMSG(stmt_start_line, 365, Error, stmt_start_col);
03946             parse_err_flush(Find_EOS, NULL);
03947             NEXT_LA_CH;
03948             SH_ERR_FLG(if_stmt_sh_idx)  = TRUE;
03949             stmt_type                   = If_Stmt;
03950             break;
03951 
03952          case Where_Cstrct_Stmt:
03953          case Forall_Cstrct_Stmt:
03954 
03955             /* Pop the Block Stack (carefully) and mark all statement    */
03956             /* headers back to the IF statement header as being in error */
03957             /* so the Semantics Pass won't try to process them.          */
03958 
03959             if (CURR_BLK == Where_Then_Blk) {
03960                POP_BLK_STK;
03961             }
03962 
03963             sh_idx = curr_stmt_sh_idx;
03964 
03965             while (SH_STMT_TYPE(sh_idx) != If_Stmt) {
03966                SH_ERR_FLG(sh_idx)       = TRUE;
03967                sh_idx                   = SH_PREV_IDX(sh_idx);
03968             }
03969 
03970             /* Intentional fall through */
03971 
03972          case Case_Stmt:
03973          case Do_Iterative_Stmt:
03974          case Do_While_Stmt:
03975          case Do_Infinite_Stmt:
03976          case Else_Stmt:
03977          case Entry_Stmt:
03978          case Select_Stmt:
03979 
03980             PRINTMSG(stmt_start_line, 365, Error, stmt_start_col);
03981 
03982             if (stmt_type != Where_Cstrct_Stmt) {
03983                parse_err_flush(Find_EOS, NULL);
03984                NEXT_LA_CH;
03985             }
03986 
03987             SH_ERR_FLG(if_stmt_sh_idx)  = TRUE;
03988             stmt_type                   = If_Stmt;
03989             goto EXIT;
03990 
03991          case Allocate_Stmt:
03992          case Arith_If_Stmt:
03993          case Assign_Stmt:
03994          case Assignment_Stmt:
03995          case Backspace_Stmt:
03996          case Buffer_Stmt:
03997          case Call_Stmt:
03998          case Close_Stmt:
03999          case Continue_Stmt:
04000          case Cycle_Stmt:
04001          case Deallocate_Stmt:
04002          case Decode_Stmt:
04003          case Else_If_Stmt:
04004          case Else_Where_Stmt:
04005          case Encode_Stmt:
04006          case Exit_Stmt:
04007          case Goto_Stmt:
04008          case If_Cstrct_Stmt:
04009          case If_Stmt:
04010          case Inquire_Stmt:
04011          case Nullify_Stmt:
04012          case Open_Stmt:
04013          case Outmoded_If_Stmt:
04014          case Pause_Stmt:
04015          case Print_Stmt:
04016          case Read_Stmt:
04017          case Return_Stmt:
04018          case Rewind_Stmt:
04019          case Stop_Stmt:
04020          case Then_Stmt:
04021          case Write_Stmt:
04022          case Endfile_Stmt:
04023          case Where_Stmt:
04024          case Forall_Stmt:
04025 
04026 
04027             if (!stmt_parsers_called) {
04028 
04029                /* The action statement needs to have its statement */
04030                /* number be 1 greater than the if statement.       */
04031 
04032                INCREMENT_STATEMENT_NUMBER;
04033                in_action_stmt_of_if_where_or_forall     = TRUE;
04034    
04035                (*stmt_parsers[stmt_type])();
04036 
04037                in_action_stmt_of_if_where_or_forall     = FALSE;
04038             }
04039 
04040             /* If the IF portion and the action-stmt are OK, generate a      */
04041             /* CONTINUE stmt to define the branch-around label.  Otherwise,  */
04042             /* mark the If_Stmt SH in error if the action-stmt is bad.       */
04043             /* Note:  The Semantics Pass will fill in AT_DEF_LINE and        */
04044             /* AT_DEF_COL for the label with the info from the stmt          */
04045             /* following the compiler-generated CONTINUE statement.          */
04046    
04047             gen_if_ir(if_stmt_lbl_idx, 
04048                       if_stmt_sh_idx,
04049                       save_if_stmt_start_line,
04050                       save_if_stmt_start_col);
04051 
04052             stmt_type = If_Stmt;
04053             break;
04054 
04055          case End_Stmt:
04056          case End_Blockdata_Stmt:
04057          case End_Do_Stmt:
04058          case End_Function_Stmt:
04059          case End_If_Stmt:
04060          case End_Interface_Stmt:
04061          case End_Module_Stmt:
04062          case End_Program_Stmt:
04063          case End_Select_Stmt:
04064          case End_Subroutine_Stmt:
04065          case End_Type_Stmt:
04066          case End_Where_Stmt:
04067          case End_Forall_Stmt:
04068 
04069             PRINTMSG(stmt_start_line, 365, Error, stmt_start_col);
04070             SH_ERR_FLG(if_stmt_sh_idx)  = TRUE;
04071             stmt_type = If_Stmt;
04072             break;
04073 
04074          case Null_Stmt:
04075          case Type_Init_Stmt:
04076          case Label_Def:
04077          case Construct_Def:
04078          case Automatic_Base_Calc_Stmt:
04079          case Automatic_Base_Size_Stmt:
04080          case End_Parallel_Stmt:
04081          case End_Do_Parallel_Stmt:
04082          case End_Parallel_Case_Stmt:
04083          case Parallel_Case_Stmt:
04084          case End_Guard_Stmt:
04085          case Statement_Num_Stmt:
04086          case SGI_Section_Stmt:
04087          case SGI_End_Psection_Stmt:
04088          case SGI_End_Pdo_Stmt:
04089          case SGI_End_Parallel_Stmt:
04090          case SGI_End_Critical_Section_Stmt:
04091          case SGI_End_Single_Process_Stmt:
04092          case SGI_Region_End_Stmt:
04093          case Open_MP_Section_Stmt:
04094          case Open_MP_End_Parallel_Stmt:
04095          case Open_MP_End_Do_Stmt:
04096          case Open_MP_End_Parallel_Sections_Stmt:
04097          case Open_MP_End_Sections_Stmt:
04098          case Open_MP_End_Section_Stmt:
04099          case Open_MP_End_Single_Stmt:
04100          case Open_MP_End_Parallel_Do_Stmt:
04101          case Open_MP_End_Master_Stmt:
04102          case Open_MP_End_Critical_Stmt:
04103          case Open_MP_End_Ordered_Stmt:
04104      
04105 # if defined(_DEBUG)
04106                 
04107             /* ELSE IF and ELSE WHERE should never be seen because they    */
04108             /* should be classified as ELSE.                               */
04109             /* stmt_type = If_Cstrct_Stmt should never be seen because it  */
04110             /* will be caught above in IF construct processing.            */
04111             /* stmt_type = Then_Stmt should never be seen because THEN     */
04112             /* is not a beginning-of-stmt keyword.                         */
04113             /* None of the END stmt types except End_Stmt should be seen   */
04114             /* because they should all be classified as just END.          */
04115                    
04116             PRINTMSG(stmt_start_line, 366, Internal, stmt_start_col);
04117 # endif
04118             break;
04119 
04120       }  /* End switch (stmt_type)  */
04121 
04122       goto EXIT;   /* Get out so other IFs aren't deeply nested else's. */
04123 
04124    }     /* if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword))                       */
04125       
04126 
04127    /* ----------------------------------------------------------------------- */
04128    /* If the token following the right paren is a label, we are parsing an    */
04129    /* (obsolescent) arithmetic IF, an outmoded (CFT77 extension) indirect     */
04130    /* logical IF, or an outmoded (CFT77 extension) two-branch arithmetic IF.  */
04131    /* ----------------------------------------------------------------------- */
04132 
04133    if (LA_CH_CLASS == Ch_Class_Digit) {
04134 
04135       if ( ! CURR_BLK_NO_EXEC  ||  ! iss_blk_stk_err() ) {
04136          curr_stmt_category = Executable_Stmt_Cat;
04137       }
04138 
04139       stmt_type                      = Arith_If_Stmt;
04140       SH_STMT_TYPE(curr_stmt_sh_idx) = Arith_If_Stmt;
04141 
04142       /* Attach a Br_Aif_Opr IR entry to the SH to hold the conditional       */
04143       /* expression and the list of labels.                                   */
04144 
04145       NTR_IR_TBL(ir_idx);
04146       IR_OPR(ir_idx)      = Br_Aif_Opr;
04147       /* LRR - bhj put in Integer for type idx */
04148       IR_TYPE_IDX(ir_idx) = INTEGER_DEFAULT_TYPE;
04149       IR_LINE_NUM(ir_idx) = expr_start_line;
04150       IR_COL_NUM(ir_idx)  = expr_start_col;
04151       COPY_OPND(IR_OPND_L(ir_idx), cond_expr);
04152 
04153       SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
04154 
04155       /* MATCHED_TOKEN_CLASS is normally invoked as a function but we need    */
04156       /* not check its result because we already know the token starts with   */
04157       /* a digit.                                                             */
04158 
04159       MATCHED_TOKEN_CLASS(Tok_Class_Label);
04160 
04161       if (TOKEN_ERR(token)) {
04162          parse_err_flush(Find_EOS, NULL);
04163          goto EXIT;
04164       }
04165 
04166       /* Produce label list in the order:  zero-label, positive-label,        */
04167       /* negative-label.                                                      */
04168 
04169       lbl_attr_idx = check_label_ref();
04170 
04171       NTR_IR_LIST_TBL(neg_il_idx);
04172       IL_LINE_NUM(neg_il_idx) = TOKEN_LINE(token);
04173       IL_COL_NUM(neg_il_idx)  = TOKEN_COLUMN(token);
04174       IL_FLD(neg_il_idx)      = AT_Tbl_Idx;
04175       IL_IDX(neg_il_idx)      = lbl_attr_idx;
04176       AT_REFERENCED(lbl_attr_idx) = Referenced;
04177    
04178       IR_FLD_R(ir_idx) = IL_Tbl_Idx;
04179       IR_IDX_R(ir_idx) = neg_il_idx;
04180       ++IR_LIST_CNT_R(ir_idx);
04181 
04182       if (LA_CH_VALUE == COMMA) {
04183          NEXT_LA_CH;
04184 
04185          if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) {
04186 
04187             if (TOKEN_ERR(token)) {
04188                parse_err_flush(Find_EOS, NULL);
04189                goto EXIT;
04190             }
04191 
04192             lbl_attr_idx = check_label_ref();
04193 
04194             NTR_IR_LIST_TBL(zero_il_idx);
04195             IL_LINE_NUM(zero_il_idx) = TOKEN_LINE(token);
04196             IL_COL_NUM(zero_il_idx)  = TOKEN_COLUMN(token);
04197             IL_FLD(zero_il_idx)      = AT_Tbl_Idx;
04198             IL_IDX(zero_il_idx)      = lbl_attr_idx;
04199             AT_REFERENCED(lbl_attr_idx) = Referenced;
04200    
04201             IL_NEXT_LIST_IDX(zero_il_idx) = neg_il_idx;
04202             IL_PREV_LIST_IDX(neg_il_idx)  = zero_il_idx;
04203 
04204             IR_IDX_R(ir_idx) = zero_il_idx;
04205             ++IR_LIST_CNT_R(ir_idx);
04206 
04207             if (LA_CH_VALUE == COMMA) {
04208                NEXT_LA_CH;
04209 
04210                if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) {
04211 
04212                   if (TOKEN_ERR(token)) {
04213                      parse_err_flush(Find_EOS, NULL);
04214                      goto EXIT;
04215                   }
04216 
04217                   lbl_attr_idx = check_label_ref();
04218 
04219                   NTR_IR_LIST_TBL(pos_il_idx);
04220                   IL_LINE_NUM(pos_il_idx) = TOKEN_LINE(token);
04221                   IL_COL_NUM(pos_il_idx)  = TOKEN_COLUMN(token);
04222                   IL_FLD(pos_il_idx)      = AT_Tbl_Idx;
04223                   IL_IDX(pos_il_idx)      = lbl_attr_idx;
04224                   AT_REFERENCED(lbl_attr_idx) = Referenced;
04225    
04226                   IL_NEXT_LIST_IDX(zero_il_idx) = pos_il_idx;
04227                   IL_PREV_LIST_IDX(pos_il_idx)  = zero_il_idx;
04228                   IL_NEXT_LIST_IDX(pos_il_idx)  = neg_il_idx;
04229                   IL_PREV_LIST_IDX(neg_il_idx)  = pos_il_idx;
04230       
04231                   ++IR_LIST_CNT_R(ir_idx);
04232 
04233                   if (LA_CH_VALUE == EOS) {
04234                     
04235                      /* ----------------------------------------------------- */
04236                      /* Arithmetic IF.                                        */
04237                      /* ----------------------------------------------------- */
04238 
04239                      PRINTMSG(stmt_start_line, 112, Comment, stmt_start_col);
04240 
04241                      if (cif_flags & MISC_RECS) {
04242                         cif_stmt_type_rec(TRUE, 
04243                                           CIF_If_Arithmetic_Stmt, 
04244                                           statement_number);
04245                      }
04246                   }
04247                   else {
04248                      parse_err_flush(Find_EOS, EOS_STR);
04249                   }
04250                }
04251                else {
04252                   parse_err_flush(Find_EOS, "label");
04253                }
04254             }
04255             else {
04256             
04257                if (LA_CH_VALUE == EOS) {
04258 
04259                   /* -------------------------------------------------------- */
04260                   /* Outmoded indirect logical IF or outmoded two-branch      */
04261                   /* arithmetic IF.                                           */
04262                   /* -------------------------------------------------------- */
04263 
04264                   stmt_type                      = Outmoded_If_Stmt;
04265                   SH_STMT_TYPE(curr_stmt_sh_idx) = Outmoded_If_Stmt;
04266 
04267                   PRINTMSG(stmt_start_line, 406, Ansi, stmt_start_col);
04268 
04269                   if (cif_flags & MISC_RECS) {
04270                      gen_sh(Before, Statement_Num_Stmt, statement_number, 0,
04271                             FALSE, FALSE, TRUE);
04272                   }
04273                }
04274                else {
04275                   parse_err_flush(Find_EOS, ", or EOS");
04276                }
04277             }
04278          }
04279          else {
04280             parse_err_flush(Find_EOS, "label");
04281          }
04282       }
04283       else {
04284          parse_err_flush(Find_EOS, ",");
04285       }
04286    }
04287    else {
04288 
04289       /* Expecting the keyword THEN, beginning of an action-stmt, or a label. */
04290 
04291       PRINTMSG(LA_CH_LINE, 377, Error, LA_CH_COLUMN);
04292       parse_err_flush(Find_EOS, NULL);
04293    }
04294 
04295 EXIT:
04296 
04297    if (stmt_type == If_Stmt) {
04298       if_stmt_lbl_idx = NULL_IDX;
04299    }
04300    else {
04301             
04302       if (stmt_type == If_Cstrct_Stmt  &&  SH_ERR_FLG(curr_stmt_sh_idx)  && 
04303           stmt_label_idx != NULL_IDX) {
04304          AT_DCL_ERR(stmt_label_idx) = TRUE;
04305       }
04306 
04307       NEXT_LA_CH;
04308    }
04309    
04310    TRACE (Func_Exit, "parse_if_stmt", NULL);
04311 
04312    return;
04313 
04314 }  /* parse_if_stmt */
04315 
04316 
04317 /******************************************************************************\
04318 |*                                                                            *|
04319 |* Description:                                                               *|
04320 |*      BRIEF DESCRIPTION OF THIS FUNCTION'S PURPOSE                          *|
04321 |*                                                                            *|
04322 |* Input parameters:                                                          *|
04323 |*      NONE                                                                  *|
04324 |*                                                                            *|
04325 |* Output parameters:                                                         *|
04326 |*      NONE                                                                  *|
04327 |*                                                                            *|
04328 |* Returns:                                                                   *|
04329 |*      NONE                                                                  *|
04330 |*                                                                            *|
04331 \******************************************************************************/
04332 
04333 void parse_nullify_stmt (void)
04334 
04335 {
04336    int       ir_idx;
04337    int       list1_idx;
04338    int       list2_idx = NULL_IDX;
04339    int       num_items = 0;
04340    opnd_type opnd;
04341    boolean   parsed_ok = TRUE;
04342 
04343    TRACE (Func_Entry, "parse_nullify_stmt", NULL);
04344 
04345    if (LA_CH_VALUE != LPAREN) {
04346       parse_err_flush(Find_EOS, "(");
04347       goto EXIT;
04348    }
04349 
04350 
04351    if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) {
04352       curr_stmt_category = Executable_Stmt_Cat;
04353    }
04354 
04355    NTR_IR_TBL(ir_idx);
04356    SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
04357    IR_COL_NUM(ir_idx)          = TOKEN_COLUMN(token);
04358    IR_LINE_NUM(ir_idx)         = TOKEN_LINE(token);
04359    IR_OPR(ir_idx)              = Nullify_Opr;
04360    IR_TYPE_IDX(ir_idx)         = TYPELESS_DEFAULT_TYPE;
04361    IR_FLD_L(ir_idx)            = IL_Tbl_Idx;
04362 
04363    do {
04364       NEXT_LA_CH;
04365       num_items++;
04366    
04367       NTR_IR_LIST_TBL(list1_idx);
04368 
04369       if (list2_idx) {
04370          IL_NEXT_LIST_IDX(list2_idx) = list1_idx;
04371          IL_PREV_LIST_IDX(list1_idx) = list2_idx;
04372       }
04373       else {
04374          IR_IDX_L(ir_idx) = list1_idx;
04375       }
04376       list2_idx = list1_idx;
04377 
04378       if (MATCHED_TOKEN_CLASS(Tok_Class_Id)) {
04379          parsed_ok = parse_deref(&opnd, NULL_IDX) && parsed_ok;
04380          COPY_OPND(IL_OPND(list1_idx), opnd);
04381 
04382          mark_attr_defined(&opnd);
04383       }
04384       else {
04385          parsed_ok = FALSE;
04386          parse_err_flush(Find_Comma_Rparen, "IDENTIFIER");
04387       }
04388    }
04389    while (LA_CH_VALUE == COMMA);
04390 
04391    IR_LIST_CNT_L(ir_idx) = num_items;
04392 
04393    if (LA_CH_VALUE != RPAREN) {
04394       parse_err_flush(Find_EOS, ")");
04395    }
04396    else {
04397       NEXT_LA_CH;
04398    }
04399 
04400 EXIT:
04401    
04402    if (LA_CH_VALUE != EOS) {
04403       parse_err_flush(Find_EOS, EOS_STR);
04404    }
04405 
04406    matched_specific_token(Tok_EOS, Tok_Class_Punct);
04407 
04408    TRACE (Func_Exit, "parse_nullify_stmt", NULL);
04409 
04410    return;
04411 
04412 }  /* parse_nullify_stmt */
04413 
04414 
04415 /******************************************************************************\
04416 |*                                                                            *|
04417 |* Description:                                                               *|
04418 |*      Parse a RETURN statement.                                             *|
04419 |*      BNF : return-stmt     is RETURN [scalar-int-expr]                     *|
04420 |*      Alternate return specifiers are not allowed in FUNCTION subprograms.  *|
04421 |*                                                                            *|
04422 |* Input parameters:                                                          *|
04423 |*      NONE                                                                  *|
04424 |*                                                                            *|
04425 |* Output parameters:                                                         *|
04426 |*      NONE                                                                  *|
04427 |*                                                                            *|
04428 |* Returns:                                                                   *|
04429 |*      NONE                                                                  *|
04430 |*                                                                            *|
04431 \******************************************************************************/
04432 
04433 void parse_return_stmt (void)
04434 
04435 {
04436    int          ir_idx;
04437    opnd_type    opnd;
04438 
04439 
04440    TRACE (Func_Entry, "parse_return_stmt", NULL);
04441 
04442    /* Check if in an executable SUBROUTINE or FUNCTION block. */
04443 
04444    if (CURR_BLK_NO_EXEC || 
04445        (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) != Function &&
04446         ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) != Subroutine)) {
04447       iss_blk_stk_err();
04448    }
04449 
04450    if (cmd_line_flags.debug_lvl == Debug_Lvl_1) {  /* -ez  -G1 */
04451       gen_debug_lbl_stmt(curr_stmt_sh_idx, Ldbg_Start_Epilogue, NULL_IDX);
04452    }
04453 
04454    curr_stmt_category = Executable_Stmt_Cat;
04455 
04456    NTR_IR_TBL(ir_idx);
04457    SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
04458 
04459    IR_OPR(ir_idx)      = Return_Opr;
04460    IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE;
04461    IR_LINE_NUM(ir_idx) = LA_CH_LINE;
04462    IR_COL_NUM(ir_idx)  = LA_CH_COLUMN;
04463 
04464    if (LA_CH_VALUE != EOS) {
04465 
04466       /* Alternate return specifiers are obsolescent. */
04467 
04468       PRINTMSG(IR_LINE_NUM(ir_idx), 371, Comment, IR_COL_NUM(ir_idx));
04469 
04470       /* Check for alternate return specifier in a FUNCTION subprogram. */
04471 
04472       if (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) == Function) {
04473          PRINTMSG(IR_LINE_NUM(ir_idx), 370, Error, IR_COL_NUM(ir_idx));
04474       }
04475 
04476       /* Parse the expression.  The Semantics Pass will verify that it's  */
04477       /* scalar and type integer.                                         */
04478 
04479       if (parse_expr(&opnd)) {
04480 
04481          COPY_OPND(IR_OPND_L(ir_idx), opnd);
04482 
04483          if (LA_CH_VALUE != EOS) {
04484 
04485             /* Have garbage at the end of the statement. */
04486 
04487             parse_err_flush(Find_EOS, EOS_STR);
04488          }
04489       }
04490    }
04491 
04492    NEXT_LA_CH;
04493 
04494    TRACE (Func_Exit, "parse_return_stmt", NULL);
04495 
04496    return;
04497 
04498 }  /* parse_return_stmt */
04499 
04500 
04501 /******************************************************************************\
04502 |*                                                                            *|
04503 |* Description:                                                               *|
04504 |*      This function parses the SELECT CASE statement.                       *|
04505 |*                                                                            *|
04506 |* Input parameters:                                                          *|
04507 |*      NONE                                                                  *|
04508 |*                                                                            *|
04509 |* Output parameters:                                                         *|
04510 |*      NONE                                                                  *|
04511 |*                                                                            *|
04512 |* Returns:                                                                   *|
04513 |*      NONE                                                                  *|
04514 |*                                                                            *|
04515 \******************************************************************************/
04516 
04517 void parse_select_stmt (void)
04518 
04519 {
04520    opnd_type    expr_opnd;
04521    int          first_select_ir_idx;
04522    int          second_select_ir_idx;
04523 
04524 
04525    TRACE (Func_Entry, "parse_select_stmt", NULL);
04526 
04527    if (matched_specific_token(Tok_Kwd_Case, Tok_Class_Keyword) &&
04528        LA_CH_VALUE == LPAREN) {
04529       NEXT_LA_CH;
04530    }
04531    else if (TOKEN_VALUE(token) == Tok_Kwd_Case) {
04532       parse_err_flush(Find_EOS, "(");
04533       goto EXIT;
04534    }
04535    else {
04536       parse_err_flush(Find_EOS, "CASE");
04537       goto EXIT;
04538    }
04539 
04540    if (CURR_BLK_NO_EXEC  &&  iss_blk_stk_err()) {
04541       PUSH_BLK_STK (Select_Blk);
04542       CURR_BLK_ERR = TRUE;
04543    }
04544    else {
04545       PUSH_BLK_STK (Select_Blk);
04546       curr_stmt_category = Executable_Stmt_Cat;
04547    }
04548 
04549    CURR_BLK_FIRST_SH_IDX                 = curr_stmt_sh_idx;
04550    CURR_BLK_NO_EXEC                      = TRUE;
04551    BLK_CASE_DEFAULT_LBL_FLD(blk_stk_idx) = NO_Tbl_Idx;
04552    LINK_TO_PARENT_BLK;
04553 
04554    if (stmt_construct_idx != NULL_IDX) {
04555       CURR_BLK_NAME                        = stmt_construct_idx;
04556       ATL_CLASS(stmt_construct_idx)        = Lbl_Construct;
04557       ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx;
04558       SH_ERR_FLG(curr_stmt_sh_idx)         =
04559          SH_ERR_FLG(curr_stmt_sh_idx)  ||  AT_DCL_ERR(stmt_construct_idx);
04560       stmt_construct_idx                        = NULL_IDX;
04561    }
04562    
04563    /* Generate a dummy Select IR and attach it to the Select_Stmt SH.  This   */
04564    /* dummy IR is needed because we need a place to temporarily hang the      */
04565    /* sorted CASE list in the Semantics Pass.  This dummy IR is removed by    */
04566    /* the END SELECT code in the Semantics Pass.  After the following two     */
04567    /* Select IR generations we have:                                          */
04568    /*                                                                         */
04569    /*       Select_Stmt SH  ---> Select IR                                    */
04570    /*                              -----------> (actual) Select IR            */
04571    /*                              -----------> sorted CASE list will go here */
04572 
04573    NTR_IR_TBL(first_select_ir_idx);
04574    SH_IR_IDX(curr_stmt_sh_idx) = first_select_ir_idx;
04575    IR_OPR(first_select_ir_idx) = Select_Opr;
04576    /* LRR - bhj used short typeless for type idx */
04577    IR_TYPE_IDX(first_select_ir_idx) = TYPELESS_DEFAULT_TYPE;
04578 
04579    if (parse_expr(&expr_opnd)) {
04580       NTR_IR_TBL(second_select_ir_idx);
04581       IR_OPR(second_select_ir_idx)      = Select_Opr;
04582       /* LRR - bhj used short typeless for type idx */
04583       IR_TYPE_IDX(second_select_ir_idx) = TYPELESS_DEFAULT_TYPE;
04584       IR_LINE_NUM(second_select_ir_idx) = stmt_start_line;
04585       IR_COL_NUM(second_select_ir_idx)  = stmt_start_col;
04586       COPY_OPND(IR_OPND_L(second_select_ir_idx), expr_opnd);
04587      
04588       IR_FLD_L(first_select_ir_idx) = IR_Tbl_Idx;
04589       IR_IDX_L(first_select_ir_idx) = second_select_ir_idx;
04590 
04591       CURR_BLK_LABEL = gen_internal_lbl(stmt_start_line);
04592       AT_REFERENCED(CURR_BLK_LABEL) = Referenced;
04593    }
04594 
04595    if (LA_CH_VALUE == RPAREN) {
04596       NEXT_LA_CH;
04597    }
04598    else {
04599       parse_err_flush(Find_EOS, ")");
04600    }
04601 
04602    if (LA_CH_VALUE != EOS) {
04603       parse_err_flush(Find_EOS, EOS_STR);
04604    }
04605     
04606    CURR_BLK_ERR = SH_ERR_FLG(curr_stmt_sh_idx);
04607 
04608 EXIT:
04609 
04610    NEXT_LA_CH;
04611 
04612    TRACE (Func_Exit, "parse_select_stmt", NULL);
04613 
04614    return;
04615 
04616 }  /* parse_select_stmt */
04617 
04618 
04619 /******************************************************************************\
04620 |*                                                                            *|
04621 |* Description:                                                               *|
04622 |*      Parse the STOP statement or the PAUSE statement.                      *|
04623 |*      BNF :                                                                 *|
04624 |*            pause_stmt   is PAUSE [stop-code]                               *|
04625 |*            stop_stmt    is STOP [stop-code]                                *|
04626 |*            stop_code    is scalar-char-constant                            *|
04627 |*                         or digit [digit [digit [ digit [ digit ] ] ] ]     *|
04628 |*                                                                            *|
04629 |*      NOTE: CFT77 allows an arbitrary character expression for the          *|
04630 |*            stop-code.  CFT90 will be extended to support this.             *|
04631 |*                                                                            *|
04632 |*                                                                            *|
04633 |*                                                                            *|
04634 |*                                                                            *|
04635 |*                                                                            *|
04636 |*                                                                            *|
04637 |*                                                                            *|
04638 |*                                                                            *|
04639 |* Input parameters:                                                          *|
04640 |*      NONE                                                                  *|
04641 |*                                                                            *|
04642 |* Output parameters:                                                         *|
04643 |*      NONE                                                                  *|
04644 |*                                                                            *|
04645 |* Returns:                                                                   *|
04646 |*      NONE                                                                  *|
04647 |*                                                                            *|
04648 \******************************************************************************/
04649 
04650 void parse_stop_pause_stmt (void)
04651 
04652 {
04653    opnd_type    opnd;
04654    int          ir_idx;
04655 
04656 
04657    TRACE (Func_Entry, "parse_stop_pause_stmt", NULL);
04658 
04659    if (cmd_line_flags.debug_lvl == Debug_Lvl_1) {  /* -ez  -G1 */
04660       gen_debug_lbl_stmt(curr_stmt_sh_idx, Ldbg_Exit_Point, NULL_IDX);
04661    }
04662 
04663    if (!CURR_BLK_NO_EXEC || !iss_blk_stk_err()) {
04664       curr_stmt_category = Executable_Stmt_Cat;
04665    }
04666 
04667    if (ATP_PURE(SCP_ATTR_IDX(curr_scp_idx)) ||
04668        ATP_ELEMENTAL(SCP_ATTR_IDX(curr_scp_idx))) {
04669       PRINTMSG(TOKEN_LINE(token), 1262, Error,
04670                TOKEN_COLUMN(token),
04671                stmt_type_str[stmt_type],
04672                ATP_PURE(SCP_ATTR_IDX(curr_scp_idx)) ? "pure" : "elemental",
04673                AT_OBJ_NAME_PTR(SCP_ATTR_IDX(curr_scp_idx)));
04674    }
04675 
04676    NTR_IR_TBL(ir_idx);
04677    SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
04678    IR_LINE_NUM(ir_idx)         = LA_CH_LINE;
04679    IR_COL_NUM(ir_idx)          = LA_CH_COLUMN;
04680 
04681    if (stmt_type == Stop_Stmt) {
04682       IR_OPR(ir_idx) = Stop_Opr;
04683    }
04684    else {
04685       IR_OPR(ir_idx) = Pause_Opr;
04686 
04687       /* The PAUSE statement is a deleted feature. */
04688 
04689       PRINTMSG(TOKEN_LINE(token), 1568, Ansi, TOKEN_COLUMN(token), "PAUSE");
04690    }
04691 
04692    if (LA_CH_VALUE != EOS) {
04693 
04694       if (LA_CH_CLASS == Ch_Class_Digit) {
04695          matched_specific_token(Tok_Const_Int, Tok_Class_Int_Spec);
04696 
04697          if (LA_CH_VALUE != EOS) {
04698             /* Have garbage at the end of the statement. */
04699             parse_err_flush(Find_EOS, EOS_STR);
04700          }
04701          else {
04702             IR_FLD_L(ir_idx)      = CN_Tbl_Idx;
04703             IR_IDX_L(ir_idx)      = TOKEN_CONST_TBL_IDX(token);
04704             IR_COL_NUM_L(ir_idx)  = TOKEN_COLUMN(token);
04705             IR_LINE_NUM_L(ir_idx) = TOKEN_LINE(token);
04706          }
04707       }
04708 
04709       /* Parse the expression.  The Semantics Pass will verify rank and */
04710       /* type.                                                          */
04711       else if (parse_expr(&opnd)) {
04712 
04713          COPY_OPND(IR_OPND_L(ir_idx), opnd);
04714 
04715          if (LA_CH_VALUE != EOS) {
04716             /* Have garbage at the end of the statement. */
04717             parse_err_flush(Find_EOS, EOS_STR);
04718          }
04719       }
04720    }
04721 
04722    /* Get statement header for the RETURN which will be generated following */
04723    /* the CALL to $STOP                                                     */
04724    if (stmt_type == Stop_Stmt &&
04725        ! cdir_switches.parallel_region &&
04726        ! cdir_switches.doall_region &&
04727        ! cdir_switches.guard) {
04728 
04729       gen_sh(After, Return_Stmt, stmt_start_line, stmt_start_col,
04730              SH_ERR_FLG(curr_stmt_sh_idx), FALSE, TRUE);
04731 
04732       NTR_IR_TBL(ir_idx);
04733       SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
04734       SH_P2_SKIP_ME(curr_stmt_sh_idx) = TRUE;
04735 
04736       IR_OPR(ir_idx)      = Return_Opr;
04737       IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE;
04738       IR_LINE_NUM(ir_idx) = stmt_start_line;
04739       IR_COL_NUM(ir_idx)  = stmt_start_col;
04740    }
04741 
04742 
04743    NEXT_LA_CH;
04744 
04745    TRACE (Func_Exit, "parse_stop_pause_stmt", NULL);
04746 
04747    return;
04748 
04749 }  /* parse_stop_pause_stmt */
04750 
04751 
04752 /******************************************************************************\
04753 |*                                                                            *|
04754 |* Description:                                                               *|
04755 |*      BRIEF DESCRIPTION OF THIS FUNCTION'S PURPOSE                          *|
04756 |*                                                                            *|
04757 |* Input parameters:                                                          *|
04758 |*      NONE                                                                  *|
04759 |*                                                                            *|
04760 |* Output parameters:                                                         *|
04761 |*      NONE                                                                  *|
04762 |*                                                                            *|
04763 |* Returns:                                                                   *|
04764 |*      NONE                                                                  *|
04765 |*                                                                            *|
04766 \******************************************************************************/
04767 
04768 void parse_where_stmt (void)
04769 
04770 {
04771    int                  col;
04772    int                  ir_idx;
04773    int                  line;
04774    opnd_type            opnd;
04775    int                  save_curr_stmt_sh_idx;
04776 
04777 
04778    TRACE (Func_Entry, "parse_where_stmt", NULL);
04779 
04780    if (LA_CH_VALUE != LPAREN) {
04781       parse_err_flush(Find_EOS, "(");
04782       goto EXIT;
04783    }
04784 
04785    NTR_IR_TBL(ir_idx);
04786    IR_OPR(ir_idx)      = Where_Opr;
04787    IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE;
04788    IR_LINE_NUM(ir_idx) = TOKEN_LINE(token);
04789    IR_COL_NUM(ir_idx)  = TOKEN_COLUMN(token);
04790 
04791    SH_IR_IDX(curr_stmt_sh_idx) = ir_idx;
04792 
04793    if (CURR_BLK == Where_Then_Blk ||
04794        CURR_BLK == Where_Else_Blk ||
04795        CURR_BLK == Where_Else_Mask_Blk) {
04796 
04797       SH_PARENT_BLK_IDX(curr_stmt_sh_idx) = CURR_BLK_FIRST_SH_IDX;
04798    }
04799 
04800    /* if this is a Where stmt, the right opnd will hold the assignment stmt, */
04801    /* otherwise, it is a where construct stmt and the right opnd is null.    */
04802 
04803    /* swallow ( */
04804    NEXT_LA_CH;
04805 
04806    parse_expr(&opnd);
04807 
04808    if (LA_CH_VALUE != RPAREN) {
04809       if (! parse_err_flush(Find_Rparen, ")")) {
04810          goto EXIT;
04811       }
04812    }
04813 
04814    /* swallow ) */
04815    NEXT_LA_CH;
04816 
04817    COPY_OPND(IR_OPND_L(ir_idx), opnd);
04818 
04819    if (LA_CH_VALUE != EOS) {
04820       /* Have where_stmt */
04821 
04822       stmt_type = Where_Stmt;
04823       SH_STMT_TYPE(curr_stmt_sh_idx) = Where_Stmt;
04824 
04825       if (cif_flags & MISC_RECS) {
04826          cif_stmt_type_rec(TRUE, CIF_Where_Stmt, statement_number);
04827       }
04828 
04829       if (CURR_BLK_NO_EXEC &&  
04830           CURR_BLK != Forall_Blk &&
04831           CURR_BLK != Where_Then_Blk &&
04832           CURR_BLK != Where_Else_Blk &&
04833           CURR_BLK != Where_Else_Mask_Blk) {
04834          iss_blk_stk_err();
04835          parse_err_flush(Find_EOS, NULL);
04836          goto EXIT;
04837       }
04838 
04839       /* We do not know if this will be an Assignment Statement */
04840       /* or an Array_Assignment_Stmt so we need to generate a   */
04841       /* place holder for the statement number.  We will carry  */
04842       /* it on a Statement_Num_Stmt following the Where_Stmt.   */
04843       /* It MUST be processed in where_stmt_semantics so as not */
04844       /* to mess up cif statement processing.                   */
04845       
04846       INCREMENT_STATEMENT_NUMBER;
04847 
04848       gen_sh(After, Statement_Num_Stmt, stmt_start_line, stmt_start_col,
04849              FALSE, FALSE, TRUE);
04850       SH_PARENT_BLK_IDX(curr_stmt_sh_idx)       = statement_number;
04851       curr_stmt_category                        = Executable_Stmt_Cat;
04852       save_curr_stmt_sh_idx                     = curr_stmt_sh_idx;
04853       line                                      = LA_CH_LINE;
04854       col                                       = LA_CH_COLUMN;
04855       in_action_stmt_of_if_where_or_forall      = TRUE;
04856 
04857       if (MATCHED_TOKEN_CLASS(Tok_Class_Keyword)) {
04858          curr_stmt_sh_idx       = ntr_sh_tbl();
04859 
04860          determine_stmt_type();
04861 
04862          if (stmt_type == Assignment_Stmt) {
04863 
04864             (*stmt_parsers[Assignment_Stmt])();
04865 
04866             IR_FLD_R(ir_idx) = IR_Tbl_Idx;
04867             IR_IDX_R(ir_idx) = SH_IR_IDX(curr_stmt_sh_idx);
04868 
04869             FREE_SH_NODE(curr_stmt_sh_idx);
04870             curr_stmt_sh_idx = save_curr_stmt_sh_idx;
04871             in_action_stmt_of_if_where_or_forall        = FALSE;
04872 
04873             goto NO_EOS;
04874          }
04875          else {
04876 
04877             FREE_SH_NODE(curr_stmt_sh_idx);
04878             curr_stmt_sh_idx = save_curr_stmt_sh_idx;
04879 
04880             PRINTMSG(line, 102, Error, col);
04881             parse_err_flush(Find_EOS, NULL);
04882             in_action_stmt_of_if_where_or_forall        = FALSE;
04883             goto EXIT;
04884          }
04885       }
04886       else {
04887          PRINTMSG(line, 102, Error, col);
04888          parse_err_flush(Find_EOS, NULL);
04889          in_action_stmt_of_if_where_or_forall   = FALSE;
04890          goto EXIT;
04891       }
04892    }
04893    else {
04894       /* else have where_construct_stmt */
04895 
04896       IR_OPR(ir_idx) = Where_Cnstrct_Opr;
04897 
04898       if (cif_flags & MISC_RECS) {
04899          cif_stmt_type_rec(TRUE, CIF_Where_Construct, statement_number);
04900       }
04901 
04902       if (! CURR_BLK_NO_EXEC ||  
04903           CURR_BLK == Forall_Blk ||
04904           CURR_BLK == Where_Then_Blk ||
04905           CURR_BLK == Where_Else_Blk ||
04906           CURR_BLK == Where_Else_Mask_Blk) {
04907          PUSH_BLK_STK (Where_Then_Blk);
04908       }
04909       else {
04910          iss_blk_stk_err();
04911          PUSH_BLK_STK (Where_Then_Blk);
04912          CURR_BLK_ERR = TRUE;
04913       }
04914 
04915       if (stmt_construct_idx != NULL_IDX) {
04916          CURR_BLK_NAME                        = stmt_construct_idx;
04917          ATL_CLASS(stmt_construct_idx)        = Lbl_Construct;
04918          ATL_DEF_STMT_IDX(stmt_construct_idx) = curr_stmt_sh_idx;
04919          SH_ERR_FLG(curr_stmt_sh_idx)         =
04920             SH_ERR_FLG(curr_stmt_sh_idx)  ||  AT_DCL_ERR(stmt_construct_idx);
04921          stmt_construct_idx                        = NULL_IDX;
04922       }
04923 
04924       curr_stmt_category    = Executable_Stmt_Cat;
04925       CURR_BLK_NO_EXEC      = TRUE;
04926       CURR_BLK_FIRST_SH_IDX = curr_stmt_sh_idx;
04927    }
04928 
04929 EXIT:
04930 
04931    NEXT_LA_CH;
04932 
04933 NO_EOS:
04934    
04935    TRACE (Func_Exit, "parse_where_stmt", NULL);
04936    
04937    return;
04938 
04939 }  /* parse_where_stmt */
04940 
04941 
04942 /******************************************************************************\
04943 |*                                                                            *|
04944 |* Description:                                                               *|
04945 |*      This searches the blk_stk for the specified block and name.  If not   *|
04946 |*      found, it returns NULL_IDX and makes sure blk_stk[NULL_IDX] is clear. *|
04947 |*                                                                            *|
04948 |* Input parameters:                                                          *|
04949 |*      blk_type   -> The type of block being searched for.                   *|
04950 |*      found_name -> TRUE if there is a name to match.   The actual name is  *|
04951 |*                    in token.                                               *|
04952 |*                                                                            *|
04953 |* Output parameters:                                                         *|
04954 |*      NONE                                                                  *|
04955 |*                                                                            *|
04956 |* Returns:                                                                   *|
04957 |*      Index of the matched block.  It will return NULL_IDX if there is no   *|
04958 |*           match, but it will also clear blk_stk[NULL_IDX] so that calling  *|
04959 |*           routines do not have to check for the NULL_IDX.                  *|
04960 |*                                                                            *|
04961 \******************************************************************************/
04962 
04963 static int match_blk(blk_cntxt_type     the_blk,
04964                      boolean            fnd_name)
04965 
04966 {
04967    int           blk_idx;
04968 
04969 
04970    TRACE (Func_Entry, "match_blk", NULL);
04971 
04972    for (blk_idx = blk_stk_idx; blk_idx > NULL_IDX; blk_idx--) {
04973 
04974       if (BLK_TYPE(blk_idx) == the_blk) {
04975 
04976          if (!fnd_name || 
04977              (BLK_NAME(blk_idx) != NULL_IDX && 
04978                              (compare_names(TOKEN_ID(token).words,
04979                                         TOKEN_LEN(token),
04980                                         AT_OBJ_NAME_LONG(BLK_NAME(blk_idx)),
04981                                         AT_NAME_LEN(BLK_NAME(blk_idx))) == 0))){
04982             break;
04983          }
04984       }
04985    }
04986 
04987    if (blk_idx == NULL_IDX) {
04988       CLEAR_TBL_NTRY(blk_stk, NULL_IDX);
04989    }
04990 
04991    TRACE (Func_Exit, "match_blk", NULL);
04992 
04993    return(blk_idx);
04994 
04995 }  /* match_blk */
04996 
04997 
04998 /******************************************************************************\
04999 |*                                                                            *|
05000 |* Description:                                                               *|
05001 |*      This procedure parses the label-list for the computed and assigned GO *|
05002 |*      TO statements.                                                        *|
05003 |*                                                                            *|
05004 |* Input parameters:                                                          *|
05005 |*      ir_idx : index to the current IR entry                                *|
05006 |*                                                                            *|
05007 |* Output parameters:                                                         *|
05008 |*      NONE                                                                  *|
05009 |*                                                                            *|
05010 |* Returns:                                                                   *|
05011 |*      A boolean value that indicates whether or not the label-list was      *|
05012 |*      parsed correctly.  If an error occurs, the statement is flushed to    *|
05013 |*      the EOS so the caller should discontinue parsing.                     *|
05014 |*                                                                            *|
05015 \******************************************************************************/
05016 
05017 static boolean  parse_label_list(int           ir_idx)
05018 
05019 {
05020    int          lbl_attr_idx;
05021    int          list_tail               = NULL_IDX;
05022    int          new_lbl;
05023    boolean      parsed_correctly        = TRUE;
05024 
05025    
05026    TRACE (Func_Entry, "parse_label_list", NULL);
05027 
05028    /* The left paren has already been seen by the caller.  Just absorb it.    */
05029 
05030    NEXT_LA_CH;
05031 
05032    /* Loop through the labels and commas in the list until the right paren    */
05033    /* is found.  The list must not be empty.  Save each label reference in    */
05034    /* a List entry.  The List entries are linked in order of label appearance */
05035    /* because the index expression of the computed GO TO selects them by      */
05036    /* ordinal position.                                                       */
05037 
05038    while (LA_CH_VALUE != EOS) {
05039 
05040       if (MATCHED_TOKEN_CLASS(Tok_Class_Label)) {
05041 
05042          if ( ! TOKEN_ERR(token)) {
05043             lbl_attr_idx = check_label_ref();
05044 
05045             NTR_IR_LIST_TBL(new_lbl);
05046 
05047             if (list_tail != NULL_IDX) {
05048                IL_NEXT_LIST_IDX(list_tail) = new_lbl;
05049                IL_PREV_LIST_IDX(new_lbl)   = list_tail;
05050                list_tail                   = new_lbl;
05051             }
05052             else {
05053                IR_FLD_R(ir_idx) = IL_Tbl_Idx;
05054                IR_IDX_R(ir_idx) = new_lbl;
05055                list_tail        = new_lbl;
05056             }
05057 
05058             IL_LINE_NUM(new_lbl) = TOKEN_LINE(token);
05059             IL_COL_NUM(new_lbl)  = TOKEN_COLUMN(token);
05060             IL_FLD(new_lbl)      = AT_Tbl_Idx;
05061             IL_IDX(new_lbl)      = lbl_attr_idx;
05062             AT_REFERENCED(lbl_attr_idx) = Referenced;
05063 
05064             IR_LIST_CNT_R(ir_idx)++;
05065          }
05066 
05067          if (LA_CH_VALUE == COMMA) {
05068             NEXT_LA_CH;
05069          }
05070          else if (LA_CH_VALUE == RPAREN) {
05071                  NEXT_LA_CH;
05072                  goto EXIT;
05073               }
05074               else {
05075                  parse_err_flush(Find_EOS, ", or )");
05076                  parsed_correctly = FALSE;
05077                  goto EXIT;
05078               }
05079       
05080       }
05081       else {
05082          parse_err_flush(Find_EOS, "statement label");
05083          parsed_correctly = FALSE;
05084          goto EXIT;
05085       }
05086 
05087    }  /* while */
05088 
05089    parse_err_flush(Find_EOS, "statement label");
05090    parsed_correctly = FALSE;
05091 
05092 EXIT:
05093    
05094    TRACE (Func_Exit, "parse_label_list", NULL);
05095 
05096    return(parsed_correctly);
05097 
05098 }  /* parse_label_list */
05099 
05100 
05101 /******************************************************************************\
05102 |*                                                                            *|
05103 |* Description:                                                               *|
05104 |*      Look for a final subscript opr on a reference tree in an              *|
05105 |*      ALLOCATE allocation object and change to a Alloc_Obj_Opr.             *|
05106 |*      Also check for stride in extent specs.                                *|
05107 |*                                                                            *|
05108 |* Input parameters:                                                          *|
05109 |*      opnd - root of subtree to check.                                      *|
05110 |*                                                                            *|
05111 |* Output parameters:                                                         *|
05112 |*      opnd - checked tree.                                                  *|
05113 |*                                                                            *|
05114 |* Returns:                                                                   *|
05115 |*      TRUE if no error with extent spec.                                    *|
05116 |*                                                                            *|
05117 \******************************************************************************/
05118 
05119 static boolean change_subscript(opnd_type       *top_opnd)
05120 
05121 {
05122    boolean      allocate;
05123    int          column;
05124    int          ir_idx;
05125    int          ir2_idx;
05126    int          line;
05127    int          list_idx;
05128    int          list2_idx;
05129    int          msg_num;
05130    boolean      ok              = TRUE;
05131 
05132 
05133    TRACE (Func_Entry, "change_subscript", NULL);
05134 
05135    if (stmt_type == Deallocate_Stmt) {
05136       allocate = FALSE;
05137       msg_num  = 428;
05138    }
05139    else {
05140       allocate = TRUE;
05141       msg_num  = 201;
05142    }
05143 
05144    if (OPND_FLD((*top_opnd)) == CN_Tbl_Idx) {
05145 
05146       /* error .. can't have constant in allocate stmt */
05147 
05148       find_opnd_line_and_column(top_opnd, &line, &column);
05149 
05150       PRINTMSG(line, msg_num, Error, column);
05151       ok = FALSE;
05152    }
05153    else if (OPND_FLD((*top_opnd)) == AT_Tbl_Idx) {
05154 
05155 
05156       NTR_IR_TBL(ir_idx);
05157       IR_OPR(ir_idx)        = (allocate ? Alloc_Obj_Opr : Dealloc_Obj_Opr);
05158       IR_TYPE_IDX(ir_idx)   = TYPELESS_DEFAULT_TYPE;
05159       IR_LINE_NUM(ir_idx)   = OPND_LINE_NUM((*top_opnd));
05160       IR_COL_NUM(ir_idx)    = OPND_COL_NUM((*top_opnd));
05161 
05162       COPY_OPND(IR_OPND_L(ir_idx), (*top_opnd));
05163 
05164       OPND_FLD((*top_opnd)) = IR_Tbl_Idx;
05165       OPND_IDX((*top_opnd)) = ir_idx;
05166 
05167    }
05168    else if (OPND_FLD((*top_opnd)) == IR_Tbl_Idx) {
05169       ir_idx = OPND_IDX((*top_opnd));
05170    
05171       switch (IR_OPR(ir_idx)) {
05172 
05173          case Subscript_Opr :
05174 
05175             if (allocate) {
05176               IR_OPR(ir_idx) = Alloc_Obj_Opr; 
05177                list_idx = IR_IDX_R(ir_idx);
05178 
05179                while (list_idx != NULL_IDX) {
05180 
05181                   if (IL_FLD(list_idx) == IR_Tbl_Idx           &&
05182                       IR_OPR(IL_IDX(list_idx)) == Triplet_Opr) {
05183 
05184                      ir_idx                = IL_IDX(list_idx);
05185 #if 0 /*fzhao */
05186                      IL_FLD(list_idx)      = IL_Tbl_Idx;
05187                      IL_LIST_CNT(list_idx) = 2;
05188                      IL_IDX(list_idx)      = IR_IDX_L(ir_idx);
05189 #endif
05190 
05191 /*                     list2_idx             = IL_IDX(list_idx); */
05192 /*                     list2_idx             = IL_IDX(list_idx); fzhao */
05193 
05194                      list2_idx             = IR_IDX_L(ir_idx);  
05195                      list2_idx             = IL_NEXT_LIST_IDX(list2_idx);
05196 
05197                      if (IL_FLD(IR_IDX_L(ir_idx)) == NO_Tbl_Idx) {
05198                         /* bad allocate shape spec, no lower bound */
05199                         ok = FALSE;
05200                         PRINTMSG(IR_LINE_NUM(ir_idx), 1558, Error,
05201                                  IR_COL_NUM(ir_idx),
05202                                  "lower bound");
05203                      }
05204                      else if (IL_FLD(list2_idx) == NO_Tbl_Idx &&
05205                               ! IL_PE_SUBSCRIPT(list_idx)) {
05206                         /* bad allocate shape spec, no upper bound */
05207                         ok = FALSE;
05208                         PRINTMSG(IR_LINE_NUM(ir_idx), 1558, Error,
05209                                  IR_COL_NUM(ir_idx),
05210                                  "upper bound");
05211                      }
05212                      else if (IL_FLD(IL_NEXT_LIST_IDX(list2_idx)) 
05213                                                        != NO_Tbl_Idx) {
05214                         /* error .. stride is supplied */
05215                         ok = FALSE;
05216                         find_opnd_line_and_column((opnd_type *)&IL_OPND(
05217                                                    IL_NEXT_LIST_IDX(list2_idx)),
05218                                                    &line,
05219                                                    &column);
05220                         PRINTMSG(line, 401, Error, column); }
05221                             else {
05222                             IL_FLD(IL_NEXT_LIST_IDX(list2_idx))=CN_Tbl_Idx;
05223                             IL_IDX(IL_NEXT_LIST_IDX(list2_idx))=CN_INTEGER_ONE_IDX;
05224                      }
05225    
05226 /*                     FREE_IR_NODE(ir_idx); */
05227 /*                     FREE_IR_NODE(ir_idx); fzhao */
05228       
05229 /*                     IL_NEXT_LIST_IDX(list2_idx) = NULL_IDX; */
05230 /*                     IL_NEXT_LIST_IDX(list2_idx) = NULL_IDX; fzhao */
05231  
05232                   }
05233                   list_idx = IL_NEXT_LIST_IDX(list_idx);
05234                }
05235             }
05236             else {
05237                /* deallocate can't have subscript at end */
05238                PRINTMSG(IR_LINE_NUM(ir_idx), 430, Error,
05239                         IR_COL_NUM(ir_idx));
05240                ok = FALSE;
05241             }
05242             break;          
05243    
05244          case Struct_Opr    :
05245 
05246             /* implies right opnd is AT */
05247             NTR_IR_TBL(ir2_idx); 
05248 
05249             IR_OPR(ir2_idx)        = (allocate ? Alloc_Obj_Opr : 
05250                                                  Dealloc_Obj_Opr);
05251             IR_TYPE_IDX(ir2_idx)   = TYPELESS_DEFAULT_TYPE;
05252             IR_LINE_NUM(ir2_idx)   = IR_LINE_NUM_R(ir_idx);
05253             IR_COL_NUM(ir2_idx)    = IR_COL_NUM_R(ir_idx);
05254 
05255             COPY_OPND(IR_OPND_L(ir2_idx), (*top_opnd));
05256      
05257             OPND_FLD((*top_opnd))  = IR_Tbl_Idx;
05258             OPND_IDX((*top_opnd))  = ir2_idx;
05259 
05260             break;
05261             
05262          case Substring_Opr :
05263 
05264             PRINTMSG(IR_LINE_NUM(ir_idx), 405, Error, IR_COL_NUM(ir_idx));
05265             ok = FALSE;
05266             break;
05267 
05268          default            :
05269             PRINTMSG(IR_LINE_NUM(ir_idx), msg_num, Error, IR_COL_NUM(ir_idx));
05270             ok = FALSE;
05271             break;
05272       }
05273    }
05274    else { /* something weird */
05275       find_opnd_line_and_column(top_opnd, &line, &column);
05276       PRINTMSG(line, 626, Internal, column,
05277                "CN_Tbl_Idx, AT_Tbl_Idx, or IR_Tbl_Idx",
05278                "change_subscript");
05279    }
05280 
05281    TRACE (Func_Exit, "change_subscript", NULL);
05282 
05283    return(ok);
05284 
05285 }  /* change_subscript */
05286 
05287 
05288 /******************************************************************************\
05289 |*                                                                            *|
05290 |* Description:                                                               *|
05291 |*      Construct the name for an internal DO loop label in a token.          *|
05292 |*                                                                            *|
05293 |* Input parameters:                                                          *|
05294 |*      blk_idx : the index of the Block Stack entry for which the label is   *|
05295 |*                  to be generated                                           *|
05296 |*      lbl_pos : indicates if the name is being generated for the top,       *|
05297 |*                  cycle, exit, or skip label                                *|
05298 |*                                                                            *|
05299 |* Output parameters:                                                         *|
05300 |*      NONE                                                                  *|
05301 |*                                                                            *|
05302 |* Returns:                                                                   *|
05303 |*      The index to the Attribute entry for the internal label, or NULL_IDX  *|
05304 |*      if the Attribute entry already exists.                                *|
05305 |*                                                                            *|
05306 \******************************************************************************/
05307 
05308 int gen_loop_lbl_name(int               blk_idx,
05309                       lbl_pos_type      lbl_pos)
05310 
05311 {
05312    int          attr_idx;
05313    char         lbl_name[MAX_ID_LEN];   /* A max as reasonable as any other.  */
05314    char         lbl_pos_name[4][8] = { "top", "cycle", "exit", "bot" };
05315    token_type   lbl_token;
05316    int          name_idx;
05317    char         num_buf[8];
05318    
05319 
05320    TRACE (Func_Entry, "gen_loop_lbl_name", NULL);
05321 
05322    if (BLK_LABEL(blk_idx) != NULL_IDX) {
05323       strcpy(lbl_name, AT_OBJ_NAME_PTR(BLK_LABEL(blk_idx)));
05324    }
05325    else {
05326       sprintf(num_buf, "%d", BLK_DEF_LINE(blk_idx));
05327       strcpy(lbl_name, num_buf);
05328       strcat(lbl_name, "u");
05329    }
05330 
05331    strcat(lbl_name, lbl_pos_name[lbl_pos]);
05332    sprintf(num_buf, "%d", BLK_LOOP_NUM(blk_idx)); 
05333    strcat(lbl_name, num_buf);
05334 
05335 BACK:
05336 
05337    CREATE_ID(TOKEN_ID(lbl_token), lbl_name, strlen(lbl_name));
05338    TOKEN_LEN(lbl_token) = strlen(lbl_name);
05339 
05340    attr_idx = srch_sym_tbl(TOKEN_STR(lbl_token), TOKEN_LEN(lbl_token),
05341                            &name_idx);
05342 
05343    if (attr_idx == NULL_IDX) {
05344       attr_idx                  = ntr_sym_tbl(&lbl_token, name_idx);
05345       AT_OBJ_CLASS(attr_idx)    = Label;
05346       ATL_CLASS(attr_idx)       = Lbl_LoopInternal;
05347       ATL_EXECUTABLE(attr_idx)  = TRUE;
05348 
05349       if (lbl_pos == Top_Lbl  && 
05350           (stmt_type == Do_Iterative_Stmt  ||  stmt_type == Do_While_Stmt)) {
05351          ATL_TOP_OF_LOOP(attr_idx) = TRUE;
05352       }
05353         
05354       if (cmd_line_flags.debug_lvl == Debug_Lvl_1) {  /* -ez -G1 */
05355          ATL_DEBUG_CLASS(attr_idx) = Ldbg_Loop_Lbl;
05356       }
05357    }
05358    else if (lbl_pos == Top_Lbl  ||  lbl_pos == Skip_Lbl) {
05359 
05360       sprintf(num_buf, "%d", BLK_FIRST_SH_IDX(blk_idx));
05361       strcat(lbl_name, num_buf);
05362       goto BACK;
05363    }
05364 
05365    TRACE (Func_Exit, "gen_loop_lbl_name", NULL);
05366  
05367    return(attr_idx);
05368 
05369 }  /* gen_loop_lbl_name */
05370 
05371 
05372 /******************************************************************************\
05373 |*                                                                            *|
05374 |* Description:                                                               *|
05375 |*      Do all the processing necessary if a C*$* BLOCKABLE directive is in   *|
05376 |*      effect for this loop.                                                 *|
05377 |*                                                                            *|
05378 |* Input parameters:                                                          *|
05379 |*      NONE                                                                  *|
05380 |*                                                                            *|
05381 |* Output parameters:                                                         *|
05382 |*      NONE                                                                  *|
05383 |*                                                                            *|
05384 |* Returns:                                                                   *|
05385 |*      NOTHING                                                               *|
05386 |*                                                                            *|
05387 \******************************************************************************/
05388 
05389 static void process_blockable_dir(void)
05390 
05391 {
05392    int          blk_idx;
05393    int          dir_il_idx;
05394    int          i;
05395    int          il_idx;
05396    int          il_idx_2;
05397    int          ir_idx;
05398 
05399 
05400    TRACE (Func_Entry, "process_blockable_dir", NULL);
05401 
05402    /* If a C*$* BLOCKABLE directive was specified ahead of this loop, make    */
05403    /* sure the DO-variable for this (outer) loop is a member of the           */
05404    /* DO-variable list and, if so, capture some information about the         */
05405    /* directive.                                                              */
05406 
05407    if (cdir_switches.blockable_sh_idx != NULL_IDX) {
05408       BLK_BLOCKABLE_DIR_SH_IDX(blk_stk_idx) = cdir_switches.blockable_sh_idx;
05409       ir_idx                                =
05410          SH_IR_IDX(cdir_switches.blockable_sh_idx);
05411       BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx)   = IR_LIST_CNT_L(ir_idx);
05412       cdir_switches.blockable_sh_idx        = NULL_IDX;
05413       dir_il_idx                            = IR_IDX_L(ir_idx);
05414 
05415       for (i = 1;  i <= IR_LIST_CNT_L(ir_idx);  ++i) {
05416 
05417          if (IL_IDX(dir_il_idx) == OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) {
05418             break;
05419          }
05420          else {
05421             dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx);
05422          }
05423       }
05424 
05425       if (i <= IR_LIST_CNT_L(ir_idx)) {
05426          NTR_IR_LIST_TBL(il_idx);
05427          IR_FLD_R(ir_idx)      = IL_Tbl_Idx;
05428          IR_IDX_R(ir_idx)      = il_idx;
05429          IR_LIST_CNT_R(ir_idx) = 1;
05430 
05431          IL_LINE_NUM(il_idx) = TOKEN_LINE(token); 
05432          IL_COL_NUM(il_idx)  = TOKEN_COLUMN(token);
05433          IL_FLD(il_idx)      = CN_Tbl_Idx; 
05434          IL_IDX(il_idx)      = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, i);
05435       }
05436       else {
05437          PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token),
05438                   "BLOCKABLE");
05439          SH_ERR_FLG(BLK_BLOCKABLE_DIR_SH_IDX(blk_stk_idx)) = TRUE;
05440          BLK_BLOCKABLE_DIR_SH_IDX(blk_stk_idx)             = NULL_IDX;
05441          BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx)               = 0;
05442       }
05443    }
05444    else {
05445 
05446       /* Try to find an interative DO Block Stack entry that is the subject   */
05447       /* of a BLOCKABLE directive so we know whether or not we should check   */
05448       /* to see if the current loop is perfectly nested.                      */
05449 
05450       for (blk_idx = blk_stk_idx - 1;  blk_idx > 1;  --blk_idx) {
05451                
05452          if (BLK_TYPE(blk_idx) == Do_Blk  &&
05453              SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) {
05454             break;
05455          }
05456       }
05457 
05458       if (blk_idx > 1  &&  BLK_BLOCKABLE_NUM_LCVS(blk_idx) > 1) {
05459 
05460          /* If the current nest is subject to a BLOCKABLE directive, set up   */
05461          /* the current and parent Block Stack entries to reflect the new     */
05462          /* loop and make sure the DO-variable of this loop is in the         */
05463          /* DO-variable list of the BLOCKABLE directive.                      */
05464 
05465          if (BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx - 1) > 1) {
05466             BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx) =
05467                BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx - 1) - 1;
05468       
05469             blk_idx = blk_stk_idx - 1;
05470  
05471             while (BLK_BLOCKABLE_DIR_SH_IDX(blk_idx) == NULL_IDX) {
05472                --blk_idx; 
05473             }
05474 
05475             ir_idx     = SH_IR_IDX(BLK_BLOCKABLE_DIR_SH_IDX(blk_idx));
05476             dir_il_idx = IR_IDX_L(ir_idx);
05477 
05478             for (i = 1;  i <= IR_LIST_CNT_L(ir_idx);  ++i) {
05479 
05480                if (IL_IDX(dir_il_idx) ==
05481                       OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) {
05482                   break;
05483                }
05484                else {
05485                   dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx);
05486                }
05487             }
05488 
05489             if (i <= IR_LIST_CNT_L(ir_idx)) {
05490 
05491                /* We found the current DO-variable in the DO-variable list of */
05492                /* the BLOCKABLE directive.  Add its position to the position  */
05493                /* list.                                                       */
05494 
05495                il_idx = IR_IDX_R(ir_idx);
05496 
05497                while (IL_NEXT_LIST_IDX(il_idx) != NULL_IDX) {
05498                   il_idx = IL_NEXT_LIST_IDX(il_idx);
05499                }
05500 
05501                NTR_IR_LIST_TBL(il_idx_2);                  
05502                IL_NEXT_LIST_IDX(il_idx)   = il_idx_2;
05503                IL_PREV_LIST_IDX(il_idx_2) = il_idx;
05504                ++IR_LIST_CNT_R(ir_idx);
05505                IL_LINE_NUM(il_idx_2) = TOKEN_LINE(token);
05506                IL_COL_NUM(il_idx_2)  = TOKEN_COLUMN(token);
05507                IL_FLD(il_idx_2)      = CN_Tbl_Idx;
05508                IL_IDX(il_idx_2)      = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, i);
05509             } 
05510             else {
05511                PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token),
05512                         "BLOCKABLE");
05513                BLK_BLOCKABLE_NUM_LCVS(blk_stk_idx)   = 0;
05514 
05515                blk_idx = blk_stk_idx - 1;
05516 
05517                for (blk_idx = blk_stk_idx;  blk_idx > 1;  --blk_idx) {
05518                   BLK_BLOCKABLE_NUM_LCVS(blk_idx) = 0;
05519 
05520                   if (BLK_BLOCKABLE_DIR_SH_IDX(blk_idx) != NULL_IDX) {
05521                      SH_ERR_FLG(BLK_BLOCKABLE_DIR_SH_IDX(blk_idx)) = TRUE;
05522                      BLK_BLOCKABLE_DIR_SH_IDX(blk_idx)             = NULL_IDX;
05523                   }
05524                }
05525             }
05526          }
05527       }
05528    }
05529 
05530    TRACE (Func_Exit, "process_blockable_dir", NULL);
05531 
05532    return;  
05533 
05534 }  /* process_blockable_dir */
05535 
05536 
05537 /******************************************************************************\
05538 |*                                                                            *|
05539 |* Description:                                                               *|
05540 |*      Do all the processing necessary if a C*$* INTERCHANGE directive       *|
05541 |*      is in effect for this loop.                                           *|
05542 |*                                                                            *|
05543 |* Input parameters:                                                          *|
05544 |*      NONE                                                                  *|
05545 |*                                                                            *|
05546 |* Output parameters:                                                         *|
05547 |*      NONE                                                                  *|
05548 |*                                                                            *|
05549 |* Returns:                                                                   *|
05550 |*      TRUE if the current DO statement immediately follows a preceding      *|
05551 |*      iterative DO statement.                                               *|
05552 |*                                                                            *|
05553 \******************************************************************************/
05554 
05555 static void process_interchange_dir(void)
05556 
05557 {
05558    int          blk_idx;
05559    int          dir_il_idx;
05560    int          i;
05561    int          il_idx;
05562    int          il_idx_2;
05563    int          ir_idx;
05564    int          sh_idx;
05565 
05566 
05567    TRACE (Func_Entry, "process_interchange_dir", NULL);
05568 
05569    /* If a C*$* INTERCHANGE directive was specified ahead of this loop, make  */
05570    /* sure the DO-variable for this (outer) loop is a member of the           */
05571    /* DO-variable list and, if so, capture some information about the         */
05572    /* directive.                                                              */
05573 
05574    if (cdir_switches.interchange_sh_idx != NULL_IDX) {
05575       sh_idx = SH_PREV_IDX(BLK_FIRST_SH_IDX(blk_stk_idx));
05576 
05577       while (SH_COMPILER_GEN(sh_idx)  ||
05578              (SH_STMT_TYPE(sh_idx) == Directive_Stmt  &&
05579               IR_OPR(SH_IR_IDX(sh_idx)) != Interchange_Dir_Opr)) {
05580          sh_idx = SH_PREV_IDX(sh_idx);
05581       }
05582 
05583       if (sh_idx != cdir_switches.interchange_sh_idx) {
05584 
05585          /* Found a statement between the interchange dir and the do loop. */
05586  
05587          PRINTMSG(SH_GLB_LINE(sh_idx), 1381, Error, 0, "INTERCHANGE");
05588          SH_ERR_FLG(cdir_switches.interchange_sh_idx) = TRUE;
05589          cdir_switches.interchange_sh_idx             = NULL_IDX;
05590       }
05591       else { 
05592          BLK_INTERCHANGE_DIR_SH_IDX(blk_stk_idx) =
05593                                               cdir_switches.interchange_sh_idx;
05594          ir_idx  = SH_IR_IDX(cdir_switches.interchange_sh_idx);
05595          BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx) = IR_LIST_CNT_L(ir_idx);
05596          cdir_switches.interchange_sh_idx      = NULL_IDX;
05597          dir_il_idx                            = IR_IDX_L(ir_idx);
05598 
05599          for (i = 1;  i <= IR_LIST_CNT_L(ir_idx);  ++i) {
05600 
05601             if (IL_IDX(dir_il_idx) == OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) {
05602                break;
05603             }
05604             else {
05605                dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx);
05606             }
05607          }
05608 
05609          if (i <= IR_LIST_CNT_L(ir_idx)) {
05610 
05611             /* Holds how many things are available in the list. */
05612 
05613             NTR_IR_LIST_TBL(il_idx);
05614             IR_FLD_R(ir_idx)      = IL_Tbl_Idx;
05615             IR_IDX_R(ir_idx)      = il_idx;
05616             IR_LIST_CNT_R(ir_idx) = 1;
05617 
05618             IL_LINE_NUM(il_idx) = TOKEN_LINE(token); 
05619             IL_COL_NUM(il_idx)  = TOKEN_COLUMN(token);
05620             IL_FLD(il_idx)      = CN_Tbl_Idx; 
05621             IL_IDX(il_idx)      = C_INT_TO_CN( CG_INTEGER_DEFAULT_TYPE, i);
05622          }
05623          else {
05624 
05625             /* Didn't find the do var in the interchange do var list */
05626 
05627             PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token),
05628                      "INTERCHANGE");
05629             SH_ERR_FLG(BLK_INTERCHANGE_DIR_SH_IDX(blk_stk_idx)) = TRUE;
05630             BLK_INTERCHANGE_DIR_SH_IDX(blk_stk_idx) = NULL_IDX;
05631             BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx)   = 0;
05632          }
05633       }
05634    }
05635    else {
05636 
05637       /* Try to find an interative DO Block Stack entry that is the subject   */
05638       /* of an INTERCHANGE directive so we know whether or not we should      */
05639       /* check to see if the current loop is perfectly nested.                */
05640 
05641       for (blk_idx = blk_stk_idx - 1;  blk_idx > 1;  --blk_idx) {
05642                
05643          if (BLK_TYPE(blk_idx) == Do_Blk  &&
05644              SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) {
05645             break;
05646          }
05647       }
05648 
05649       if (blk_idx > 1  &&  BLK_INTERCHANGE_NUM_LCVS(blk_idx) > 1) {
05650 
05651          if (loop_top_is_perfectly_nested("INTERCHANGE")) {
05652    
05653             /* The DO statement is perfectly nested within the containing DO  */
05654             /* loop.  If the current nest is subject to an INTERCHANGE        */
05655             /* directive, set up the current and parent Block Stack entries   */
05656             /* to reflect the new loop and make sure the DO-variable of this  */
05657             /* loop is in the DO-variable list of the INTERCHANGE directive.  */
05658 
05659             if (BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx - 1) > 1) {
05660                BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx) =
05661                   BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx - 1) - 1;
05662          
05663                blk_idx = blk_stk_idx - 1;
05664  
05665                while (BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) == NULL_IDX) {
05666                   --blk_idx; 
05667                }
05668 
05669                ir_idx     = SH_IR_IDX(BLK_INTERCHANGE_DIR_SH_IDX(blk_idx));
05670                dir_il_idx = IR_IDX_L(ir_idx);
05671 
05672                for (i = 1;  i <= IR_LIST_CNT_L(ir_idx);  ++i) {
05673 
05674                   if (IL_IDX(dir_il_idx) ==
05675                          OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) {
05676                      break;
05677                   }
05678                   else {
05679                      dir_il_idx = IL_NEXT_LIST_IDX(dir_il_idx);
05680                   }
05681                }
05682 
05683                if (i <= IR_LIST_CNT_L(ir_idx)) {
05684 
05685                   /* We found the current DO-variable in the DO-variable list */
05686                   /* of the INTERCHANGE directive.  Add its position to the   */
05687                   /* position list.                                           */
05688 
05689                   il_idx = IR_IDX_R(ir_idx);
05690 
05691                   while (IL_NEXT_LIST_IDX(il_idx) != NULL_IDX) {
05692                      il_idx = IL_NEXT_LIST_IDX(il_idx);
05693                   }
05694 
05695                   NTR_IR_LIST_TBL(il_idx_2);                  
05696                   IL_NEXT_LIST_IDX(il_idx)   = il_idx_2;
05697                   IL_PREV_LIST_IDX(il_idx_2) = il_idx;
05698                   ++IR_LIST_CNT_R(ir_idx);
05699                   IL_LINE_NUM(il_idx_2) = TOKEN_LINE(token);
05700                   IL_COL_NUM(il_idx_2)  = TOKEN_COLUMN(token);
05701                   IL_FLD(il_idx_2)      = CN_Tbl_Idx;
05702                   IL_IDX(il_idx_2)   = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, i);
05703                } 
05704                else {
05705                   PRINTMSG(TOKEN_LINE(token), 1379, Error, TOKEN_COLUMN(token),
05706                            "INTERCHANGE");
05707                   BLK_INTERCHANGE_NUM_LCVS(blk_stk_idx)   = 0;
05708 
05709                   blk_idx = blk_stk_idx - 1;
05710 
05711                   for (blk_idx = blk_stk_idx;  blk_idx > 1;  --blk_idx) {
05712                      BLK_INTERCHANGE_NUM_LCVS(blk_idx) = 0;
05713                      BLK_HAS_NESTED_LOOP(blk_idx)      = FALSE;
05714 
05715                      if (BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) != NULL_IDX) {
05716                         SH_ERR_FLG(BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)) = TRUE;
05717                         BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)             =
05718                            NULL_IDX;
05719                      }
05720                   }
05721                }
05722             }
05723          }
05724       }
05725    }
05726 
05727    TRACE (Func_Exit, "process_interchange_dir", NULL);
05728 
05729    return;  
05730 
05731 }  /* process_interchange_dir */
05732 
05733 # if defined(GENERATE_WHIRL)
05734 
05735 /******************************************************************************\
05736 |*                                                                            *|
05737 |* Description:                                                               *|
05738 |*      Do the processing to check for perfectly nested loops for PDO,        *|
05739 |*      DOACROSS, and PARALLEL DO directives.                                 *|
05740 |*                                                                            *|
05741 |* Input parameters:                                                          *|
05742 |*      NONE                                                                  *|
05743 |*                                                                            *|
05744 |* Output parameters:                                                         *|
05745 |*      NONE                                                                  *|
05746 |*                                                                            *|
05747 |* Returns:                                                                   *|
05748 |*      NOTHING                                                               *|
05749 |*                                                                            *|
05750 \******************************************************************************/
05751 
05752 static void check_mp_dir_nesting(void)
05753 
05754 {
05755    int          blk_idx;
05756    int          col;
05757    int          dir_list_idx;
05758    int          i;
05759    int          line;
05760    int          list_idx;
05761    int          ir_idx;
05762    char         str[80];
05763 
05764 
05765    TRACE (Func_Entry, "check_mp_dir_nesting", NULL);
05766 
05767    /* If an -mp directive was specified ahead of this loop, make              */
05768    /* sure the DO-variable for this (outer) loop is a member of the           */
05769    /* DO-variable list and, if so, capture some information about the         */
05770    /* directive.                                                              */
05771 
05772    if (cdir_switches.dir_nest_check_sh_idx != NULL_IDX) {
05773       BLK_DIR_NEST_CHECK_SH_IDX(blk_stk_idx) = 
05774                                      cdir_switches.dir_nest_check_sh_idx;
05775       ir_idx = SH_IR_IDX(cdir_switches.dir_nest_check_sh_idx);
05776 
05777       list_idx = IR_IDX_L(ir_idx);
05778 
05779       for (i = 0; i < MP_DIR_NEST_IDX; i++) {
05780          list_idx = IL_NEXT_LIST_IDX(list_idx);
05781       }
05782 
05783 # ifdef _DEBUG
05784       if (list_idx == NULL_IDX ||
05785           IL_FLD(list_idx) != IL_Tbl_Idx) {
05786          PRINTMSG(SH_GLB_LINE(cdir_switches.dir_nest_check_sh_idx),
05787                   626, Internal, 
05788                   SH_COL_NUM(cdir_switches.dir_nest_check_sh_idx),
05789                   "IL_Tbl_Idx", "check_mp_dir_nesting");
05790       }
05791 # endif
05792 
05793       BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx) = IL_LIST_CNT(list_idx);
05794       cdir_switches.dir_nest_check_sh_idx         = NULL_IDX;
05795       dir_list_idx                             = IL_IDX(list_idx);
05796 
05797       /* this must be the first do var in the NEST clause */
05798 
05799       if (IL_IDX(dir_list_idx) != OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) {
05800              
05801          find_opnd_line_and_column(&IL_OPND(dir_list_idx), &line, &col);
05802 
05803          PRINTMSG(line, 1416, Error, col);
05804          SH_ERR_FLG(BLK_DIR_NEST_CHECK_SH_IDX(blk_stk_idx)) = TRUE;
05805          BLK_DIR_NEST_CHECK_SH_IDX(blk_stk_idx) = NULL_IDX;
05806          BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx)   = 0;
05807       }
05808    }
05809    else {
05810 
05811       for (blk_idx = blk_stk_idx - 1;  blk_idx > 1;  --blk_idx) {
05812                
05813          if (BLK_TYPE(blk_idx) == Do_Blk  &&
05814              SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) {
05815             break;
05816          }
05817       }
05818 
05819       if (blk_idx > 1  &&  BLK_DIR_NEST_CHECK_NUM_LCVS(blk_idx) > 1) {
05820 
05821          blk_idx = blk_stk_idx - 1;
05822 
05823          while (blk_idx > 1 &&
05824                 BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) == NULL_IDX) {
05825             --blk_idx;
05826          }
05827 
05828          if (BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) != NULL_IDX) {
05829             switch (IR_OPR(SH_IR_IDX(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)))) {
05830             case Pdo_Par_Opr:
05831                strcpy(str, "PDO");
05832                break;
05833 
05834             case Parallel_Do_Par_Opr:
05835                strcpy(str, "PARALLEL DO");
05836                break;
05837 
05838             case Doacross_Dollar_Opr:
05839                strcpy(str, "DOACROSS");
05840                break;
05841 
05842             default:
05843                strcpy(str, "DO");
05844                break;
05845             }
05846          }
05847          else {
05848             strcpy(str, "DO");
05849          }
05850 
05851          if (loop_top_is_perfectly_nested(str)) {
05852    
05853             /* The DO statement is perfectly nested within the containing DO  */
05854             /* loop. Set up the current and parent Block Stack entries   */
05855             /* to reflect the new loop and make sure the DO-variable of this  */
05856             /* loop is in the proper position in the NEST clause.  */
05857 
05858             if (BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx - 1) > 1) {
05859                BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx) =
05860                   BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx - 1) - 1;
05861          
05862                blk_idx = blk_stk_idx - 1;
05863  
05864                while (blk_idx > 1 &&
05865                       BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) == NULL_IDX) {
05866                   --blk_idx; 
05867                }
05868 
05869 # ifdef _DEBUG
05870                if (blk_idx <= 1 ||
05871                    BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) == NULL_IDX) {
05872                   PRINTMSG(SH_GLB_LINE(cdir_switches.dir_nest_check_sh_idx),
05873                            626, Internal,
05874                            SH_COL_NUM(cdir_switches.dir_nest_check_sh_idx),
05875                            "BLK_DIR_NEST_CHECK_SH_IDX", "check_mp_dir_nesting");
05876                }
05877 # endif
05878 
05879                ir_idx     = SH_IR_IDX(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx));
05880 
05881                /* Find the NEST clause */
05882 
05883                list_idx = IR_IDX_L(ir_idx);
05884 
05885                for (i = 0; i < MP_DIR_NEST_IDX; i++) {
05886                   list_idx = IL_NEXT_LIST_IDX(list_idx);
05887                }
05888 
05889 # ifdef _DEBUG
05890                if (list_idx == NULL_IDX ||
05891                    IL_FLD(list_idx) != IL_Tbl_Idx) {
05892                   PRINTMSG(SH_GLB_LINE(cdir_switches.dir_nest_check_sh_idx),
05893                            626, Internal,
05894                            SH_COL_NUM(cdir_switches.dir_nest_check_sh_idx),
05895                            "IL_Tbl_Idx", "check_mp_dir_nesting");
05896                }
05897 # endif
05898 
05899                dir_list_idx = IL_IDX(list_idx);
05900 
05901                for (i = 1;  
05902                     i < ((IL_LIST_CNT(list_idx) - 
05903                           BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx)) + 1);
05904                     i++) {
05905  
05906                   dir_list_idx = IL_NEXT_LIST_IDX(dir_list_idx);
05907                }
05908 
05909                if (IL_IDX(dir_list_idx) != 
05910                           OPND_IDX(BLK_DO_VAR_OPND(blk_stk_idx))) {
05911              
05912                   find_opnd_line_and_column(&IL_OPND(dir_list_idx),&line,&col);
05913 
05914                   PRINTMSG(line, 1416, Error, col);
05915                   BLK_DIR_NEST_CHECK_NUM_LCVS(blk_stk_idx)   = 0;
05916                   blk_idx = blk_stk_idx - 1;
05917 
05918                   for (blk_idx = blk_stk_idx;  blk_idx > 1;  --blk_idx) {
05919                      BLK_DIR_NEST_CHECK_NUM_LCVS(blk_idx) = 0;
05920                      BLK_HAS_NESTED_LOOP(blk_idx)      = FALSE;
05921 
05922                      if (BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) != NULL_IDX) {
05923                         SH_ERR_FLG(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)) = TRUE;
05924                         BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)             =
05925                            NULL_IDX;
05926                      }
05927                   }
05928                }
05929             }
05930          }
05931       }
05932    }
05933 
05934    TRACE (Func_Exit, "check_mp_dir_nesting", NULL);
05935 
05936    return;  
05937 
05938 }  /* check_mp_dir_nesting */
05939 
05940 # endif
05941 
05942 /******************************************************************************\
05943 |*                                                                            *|
05944 |* Description:                                                               *|
05945 |*      Check to see if the current iterative DO statement immediately        *|
05946 |*      a preceding iterative DO statement.  That is, check to see if the     *|
05947 |*      top of the current loop is perfectly nested within its containing     *|
05948 |*      iterative DO loop.                                                    *|
05949 |*                                                                            *|
05950 |* Input parameters:                                                          *|
05951 |*      NONE                                                                  *|
05952 |*                                                                            *|
05953 |* Output parameters:                                                         *|
05954 |*      NONE                                                                  *|
05955 |*                                                                            *|
05956 |* Returns:                                                                   *|
05957 |*      TRUE if the current DO statement immediately follows a preceding      *|
05958 |*      iterative DO statement.                                               *|
05959 |*                                                                            *|
05960 \******************************************************************************/
05961 
05962 static boolean loop_top_is_perfectly_nested(char *str)
05963 
05964 {
05965    int          blk_idx;
05966    boolean      perfectly_nested        = FALSE;
05967    int          sh_idx;
05968 
05969 
05970    TRACE (Func_Entry, "loop_top_is_perfectly_nested", NULL);
05971 
05972    blk_idx = blk_stk_idx - 1;
05973 
05974    if (BLK_TYPE(blk_idx) == Do_Blk  &&
05975        SH_STMT_TYPE(BLK_FIRST_SH_IDX(blk_idx)) == Do_Iterative_Stmt) {
05976       sh_idx = SH_PREV_IDX(curr_stmt_sh_idx);
05977 
05978       while (SH_COMPILER_GEN(sh_idx)) {
05979          sh_idx = SH_PREV_IDX(sh_idx);
05980       } 
05981 
05982       if (SH_STMT_TYPE(sh_idx) == Do_Iterative_Stmt) {
05983          BLK_HAS_NESTED_LOOP(blk_idx) = TRUE;
05984          perfectly_nested = TRUE;
05985       }
05986    }
05987    else {
05988       sh_idx = BLK_FIRST_SH_IDX(blk_idx);
05989    } 
05990 
05991    if (! perfectly_nested) {
05992       PRINTMSG(SH_GLB_LINE(sh_idx), 1380, Error, SH_COL_NUM(sh_idx), str);
05993 
05994       for (blk_idx = blk_stk_idx;  blk_idx > 1;  --blk_idx) {
05995 
05996          if (BLK_TYPE(blk_idx) == Do_Blk) {
05997             BLK_INTERCHANGE_NUM_LCVS(blk_idx) = 0;
05998             BLK_DIR_NEST_CHECK_NUM_LCVS(blk_idx) = 0;
05999             BLK_HAS_NESTED_LOOP(blk_idx)      = 0;
06000 
06001             if (BLK_DIR_NEST_CHECK_SH_IDX(blk_idx) != NULL_IDX) {
06002                SH_ERR_FLG(BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)) = TRUE;
06003                BLK_DIR_NEST_CHECK_SH_IDX(blk_idx)             = NULL_IDX;
06004             }
06005 
06006             if (BLK_INTERCHANGE_DIR_SH_IDX(blk_idx) != NULL_IDX) {
06007                SH_ERR_FLG(BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)) = TRUE;
06008                BLK_INTERCHANGE_DIR_SH_IDX(blk_idx)             = NULL_IDX;
06009                break;
06010             }
06011          }
06012       }
06013    }
06014 
06015    TRACE (Func_Exit, "loop_top_is_perfectly_nested", NULL);
06016 
06017    return(perfectly_nested);
06018 
06019 }  /* loop_top_is_perfectly_nested */
06020 
06021 
06022 /******************************************************************************\
06023 |*                                                                            *|
06024 |* Description:                                                               *|
06025 |*      Create the endif opr for if processing.                               *|
06026 |*                                                                            *|
06027 |* Input parameters:                                                          *|
06028 |*      NONE                                                                  *|
06029 |*                                                                            *|
06030 |* Output parameters:                                                         *|
06031 |*      NONE                                                                  *|
06032 |*                                                                            *|
06033 |* Returns:                                                                   *|
06034 |*      NOTHING                                                               *|
06035 |*                                                                            *|
06036 \******************************************************************************/
06037 
06038 static void gen_if_ir(int       if_stmt_lbl_idx,
06039                       int       if_stmt_sh_idx,
06040                       int       save_if_stmt_start_line,
06041                       int       save_if_stmt_start_col)
06042 
06043 {
06044    int          ir_idx;
06045 
06046 
06047    TRACE (Func_Entry, "gen_if_ir", NULL);
06048 
06049    if (!SH_ERR_FLG(curr_stmt_sh_idx)  && !SH_ERR_FLG(if_stmt_sh_idx)) {
06050 
06051 # if defined(_HIGH_LEVEL_IF_FORM)
06052 
06053       /* Generate an End_If_Stmt SH and mark it as compiler-generated  */
06054       /* (so that the IF stmt looks like a user IF construct so that   */
06055       /* all the IR generated to represent the <action-stmt> can be    */
06056       /* bracketed.  No need to generate a fake Then_Stmt SH because   */
06057       /* the Semantics Pass just deletes it anyway.                    */
06058       /* Do NOT pop the block stack entry.                             */
06059 
06060       gen_sh(After, End_If_Stmt, stmt_start_line, stmt_start_col,
06061              FALSE,                       /* Error flag.             */
06062              FALSE,                       /* Labeled.                */
06063              TRUE);                       /* Compiler-generated.     */
06064       SH_P2_SKIP_ME(curr_stmt_sh_idx) = TRUE;
06065 
06066       NTR_IR_TBL(ir_idx);
06067       IR_OPR(ir_idx)                    = Endif_Opr;
06068       IR_TYPE_IDX(ir_idx)               = TYPELESS_DEFAULT_TYPE;
06069       IR_LINE_NUM(ir_idx)               = stmt_start_line;
06070       IR_COL_NUM(ir_idx)                = stmt_start_col;
06071       IR_FLD_L(ir_idx)                  = SH_Tbl_Idx;
06072       IR_IDX_L(ir_idx)                  = if_stmt_sh_idx;
06073       SH_IR_IDX(curr_stmt_sh_idx)       = ir_idx;
06074 # else
06075       stmt_start_line = save_if_stmt_start_line;  
06076       stmt_start_col  = save_if_stmt_start_col;  
06077 
06078       gen_sh(After, Continue_Stmt, stmt_start_line, stmt_start_col,
06079              FALSE, TRUE, TRUE);
06080 
06081       NTR_IR_TBL(ir_idx);
06082       SH_IR_IDX(curr_stmt_sh_idx)       = ir_idx;
06083       IR_OPR(ir_idx)                    = Label_Opr;
06084 
06085       /* LRR - bhj put in short typeless for type idx */
06086 
06087       IR_TYPE_IDX(ir_idx)               = TYPELESS_DEFAULT_TYPE;
06088       IR_LINE_NUM(ir_idx)               = stmt_start_line;
06089       IR_COL_NUM(ir_idx)                = stmt_start_col;
06090       IR_FLD_L(ir_idx)                  = AT_Tbl_Idx;
06091       IR_IDX_L(ir_idx)                  = if_stmt_lbl_idx;
06092       IR_LINE_NUM_L(ir_idx)             = stmt_start_line;
06093       IR_COL_NUM_L(ir_idx)              = stmt_start_col;
06094       AT_DEFINED(if_stmt_lbl_idx)       = TRUE;
06095       ATL_DEF_STMT_IDX(if_stmt_lbl_idx) = curr_stmt_sh_idx;
06096 
06097 # endif
06098    }
06099    else if (SH_ERR_FLG(curr_stmt_sh_idx)) {
06100       SH_ERR_FLG(if_stmt_sh_idx) = TRUE;
06101    }
06102    TRACE (Func_Exit, "gen_if_ir", NULL);
06103 
06104    return;
06105 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines