Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
s_data.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/s_data.c    5.7     09/02/99 17:06:53\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 "debug.m"
00050 # include "s_globals.m"
00051 
00052 # include "globals.h"
00053 # include "tokens.h"
00054 # include "sytb.h"
00055 # include "s_globals.h"
00056 # include "s_data.h"
00057 
00058 
00059 /******************************************************************\
00060 |* Function prototypes of static functions declared in this file. *|
00061 \******************************************************************/
00062 
00063 static  void    adjust_char_value_len (int, int, long64, long64);
00064 static  void    build_loop_tbl (int, boolean);
00065 static  boolean check_target_and_value (int, int);
00066 static  void    data_imp_do_semantics (int, int, boolean, boolean *);
00067 static  void    fold_all_subscripts (opnd_type *);
00068 static  void    gen_section_ref(int,long64,int,int,int,long64 *,long64 *,
00069                                 long64 *);
00070 static  boolean good_data_imp_do_expr(int);
00071 static  boolean imp_do_metamorphed (int);
00072 static  boolean init_whole_array(int, long64 *, int, int, boolean *);
00073 static  void    interpret_data_imp_do(int);
00074 static  void    object_semantics (opnd_type *, expr_mode_type, expr_arg_type *,
00075                                   boolean, boolean);
00076 static  boolean optimize_whole_array_init(int);
00077 static  void    process_data_imp_do_target(int, int, long64);
00078 static  void    section_semantics (int, opnd_type *, int *);
00079 static  void    set_global_value_variables (opnd_type *, opnd_type *, int);
00080 static  void    vv_subscript_semantics(int, int, expr_arg_type *);
00081 
00082 # if 0  /* Not used */
00083 static  int     reenter_const_as_hollerith(int, int, int, holler_type);
00084 # endif
00085 
00086 /******************************************************************************\
00087 |*                                                                            *|
00088 |* Description:                                                               *|
00089 |*      This procedure handles initialization of a whole array, as in:        *|
00090 |*                                                                            *|
00091 |*           INTEGER array(10,10)                                             *|
00092 |*           DATA array /45*0, 50*1, 5*2/                                     *|
00093 |*                                                                            *|
00094 |*      It does this by overlaying a single dimension compiler-generated      *|
00095 |*      array variable on the base array.  If the base array is a single      *|
00096 |*      dimension array, no overlay is made.                                  *|
00097 |*                                                                            *|
00098 |*      On the first call to this procedure for each whole array              *|
00099 |*      initialization, the size of the array is calculated, the c-g variable *|
00100 |*      is generated, and the IR is generated to assign the first (and        *|
00101 |*      possibly only) set of values to the array.  If the values are split   *|
00102 |*      up like the above example, successive calls to this procedure will    *|
00103 |*      generate IR representing each [rep-factor*]value.                     *|
00104 |*                                                                            *|
00105 |* Input parameters:                                                          *|
00106 |*      whole_sub_ir_idx : index of the Whole_Subscript IR                    *|
00107 |*      dup_count        : number of values available to be assigned to the   *|
00108 |*                           array on this pass through the array             *|
00109 |*      root_ir_idx      : if the Whole_Subscript IR is not the root IR of    *|
00110 |*                           the reference tree, root_ir_idx points to the    *|
00111 |*                           root IR                                          *|
00112 |*      init_ir_idx      : index of the Init IR                               *|
00113 |*                                                                            *|
00114 |* Output parameters:                                                         *|
00115 |*      optimized        : TRUE if the value list was converted to a single   *|
00116 |*                           typeless glob of bits                            *|
00117 |*                                                                            *|
00118 |* Returns:                                                                   *|
00119 |*      NONE                                                                  *|
00120 |*                                                                            *|
00121 |* Algorithm notes:                                                           *|
00122 |*      value_opnd is only used when the CRI extension is being processed     *|
00123 |*                                                                            *|
00124 \******************************************************************************/
00125 
00126 static boolean init_whole_array(int              whole_sub_ir_idx,
00127                                 long64          *dup_count,
00128                                 int              root_ir_idx,
00129                                 int              init_ir_idx,
00130                                 boolean         *optimized)
00131 
00132 {
00133    static       int                     attr_idx;
00134                 int                     bd_idx;
00135    static       long64                  curr_subscript;
00136                 int                     curr_subscript_idx;
00137                 int                     eq_idx;
00138                 int                     eq_tmp_idx;
00139                 boolean                 first_call;
00140                 int                     il_idx;
00141                 int                     ir_idx; 
00142                 size_offset_type        length;
00143                 boolean                 long_value;
00144                 boolean                 ok                      = TRUE;
00145                 opnd_type               opnd;
00146                 int                     overlay_attr_idx;
00147                 size_offset_type        result;
00148                 int                     var_attr_idx;
00149                 boolean                 word_size_target;
00150 
00151 # if defined(_SEPARATE_NONCOMMON_EQUIV_GROUPS)
00152                 int                     sb_idx;
00153 # endif
00154             
00155 
00156    TRACE(Func_Entry, "init_whole_array", NULL);
00157 
00158    if (obj_count == 0) {
00159       first_call = TRUE;
00160 
00161       /* If a single dimension array is being initialized, we can just use    */
00162       /* the array itself.  Otherwise, generate a single dimension temp array */
00163       /* and overlay it on the actual array because we can generate many      */
00164       /* fewer calls to PDGCS by using a single dimension array.  For example,*/
00165       /* the DATA statement    DATA ((array(i,j), i=1,10), j=1,10) /100*0/    */
00166       /* would generate 10 calls (one for each iteration of J) if left as a   */
00167       /* multidimension array because CCG only understands a single stride.   */
00168       /* But only a single call is generated if it is overlayed with a single */
00169       /* dimension array.                                                     */
00170       /* gen_compiler_tmp is used to generate an Attr with a temp name.  Since*/
00171       /* the base array Attr is just copied on top of it, any temp type can   */
00172       /* be used in the call.  gen_compiler_tmp must be used because the temp */
00173       /* counter used to create the name is local to it.                      */
00174 
00175       if (IR_FLD_L(whole_sub_ir_idx) == AT_Tbl_Idx) {
00176          attr_idx = IR_IDX_L(whole_sub_ir_idx);
00177       }
00178       else {
00179          attr_idx = IR_IDX_R(IR_IDX_L(whole_sub_ir_idx));
00180       }
00181 
00182       obj_count = CN_INT_TO_C(BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx)));
00183 
00184       if (BD_RANK(ATD_ARRAY_IDX(attr_idx)) == 1 ) {
00185          curr_subscript_idx = BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), 1);
00186          curr_subscript     = CN_INT_TO_C(curr_subscript_idx);
00187       }
00188       else { 
00189          AT_DEFINED(attr_idx) = TRUE;
00190 
00191          overlay_attr_idx = gen_compiler_tmp(IR_LINE_NUM_L(whole_sub_ir_idx), 
00192                                              IR_COL_NUM_L(whole_sub_ir_idx),
00193                                              Shared, TRUE);
00194 
00195          ATD_TYPE_IDX(overlay_attr_idx)         = ATD_TYPE_IDX(attr_idx);
00196          ATD_STOR_BLK_IDX(overlay_attr_idx)     = ATD_STOR_BLK_IDX(attr_idx);
00197          ATD_EQUIV(overlay_attr_idx)            = TRUE;
00198          AT_REFERENCED(overlay_attr_idx)        = Referenced;
00199          AT_SEMANTICS_DONE(overlay_attr_idx)    = TRUE;
00200 /*         AT_MODULE_OBJECT(overlay_attr_idx)     = AT_MODULE_OBJECT(attr_idx);June*/
00201          
00202          if (ATD_CLASS(attr_idx) != Struct_Component) {
00203 
00204             ATD_OFFSET_FLD(overlay_attr_idx)      = ATD_OFFSET_FLD(attr_idx);
00205             ATD_OFFSET_IDX(overlay_attr_idx)      = ATD_OFFSET_IDX(attr_idx);
00206             ATD_OFFSET_ASSIGNED(overlay_attr_idx) = 
00207                                                  ATD_OFFSET_ASSIGNED(attr_idx);
00208 
00209             /* The overlay tmp and the variable must have the same offset.    */
00210             /* Find the equivalence group for the variable and add the tmp to */
00211             /* the equivalence group.  To do this, create a new equivalence   */
00212             /* table entry, add it to the group and make ATD_OFFSET be the    */
00213             /* same for both.  (ATD_OFFSET can be set, even if ATD_OFFSET     */
00214             /* ASSIGNED is FALSE because this is the equivalence group        */
00215             /* offset).                                                       */
00216 
00217             if (ATD_EQUIV(attr_idx)) {
00218                eq_idx   = SCP_FIRST_EQUIV_GRP(curr_scp_idx);
00219 
00220                while (eq_idx != NULL_IDX) {
00221                   eq_tmp_idx    = eq_idx;
00222                   eq_idx        = EQ_NEXT_EQUIV_GRP(eq_idx);
00223 
00224                   while (eq_tmp_idx != NULL_IDX) {
00225 
00226                      if (EQ_ATTR_IDX(eq_tmp_idx) == attr_idx) { /* Found */
00227                         NTR_EQ_TBL(eq_idx);
00228                         COPY_TBL_NTRY(equiv_tbl, eq_idx, eq_tmp_idx);
00229                         EQ_NEXT_EQUIV_OBJ(eq_tmp_idx)   = eq_idx;
00230                         EQ_ATTR_IDX(eq_idx)             = overlay_attr_idx;
00231                         ATD_OFFSET_FLD(overlay_attr_idx)= 
00232                                                        ATD_OFFSET_FLD(attr_idx);
00233                         ATD_OFFSET_IDX(overlay_attr_idx)= 
00234                                                        ATD_OFFSET_IDX(attr_idx);
00235                         ATD_EQUIV(attr_idx)             = TRUE;
00236                         goto FOUND;
00237                      }
00238                      eq_tmp_idx = EQ_NEXT_EQUIV_OBJ(eq_tmp_idx);
00239                   }
00240                }
00241             }
00242 
00243             /* It is not in an equivalence group or it is not   */
00244             /* equivalenced, so make its own equivalence group. */
00245 
00246             NTR_EQ_TBL(eq_idx);
00247             NTR_EQ_TBL(eq_tmp_idx);
00248 
00249             EQ_NEXT_EQUIV_GRP(eq_idx)   = SCP_FIRST_EQUIV_GRP(curr_scp_idx);
00250             SCP_FIRST_EQUIV_GRP(curr_scp_idx)   = eq_idx;
00251             EQ_ATTR_IDX(eq_idx)                 = attr_idx;
00252             EQ_ATTR_IDX(eq_tmp_idx)             = overlay_attr_idx;
00253             EQ_NEXT_EQUIV_OBJ(eq_idx)           = eq_tmp_idx;
00254             ATD_EQUIV(attr_idx)                 = TRUE;
00255             ATD_VARIABLE_TMP_IDX(attr_idx)      = overlay_attr_idx;
00256             ATD_FLD(attr_idx)                   = AT_Tbl_Idx;
00257 
00258 # if defined(_SEPARATE_NONCOMMON_EQUIV_GROUPS)
00259 
00260             sb_idx      = ATD_STOR_BLK_IDX(attr_idx);
00261             if (sb_idx == NULL_IDX ||
00262 /*                (!SB_MODULE(sb_idx) && !SB_IS_COMMON(sb_idx))) {    */
00263 
00264 /* keep SB_MODULE variable keep similiar form with subroutine */
00265 
00266                  !SB_IS_COMMON(sb_idx)) {    
00267 
00268                if (SB_HOSTED_STATIC(sb_idx)) {
00269                   sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx));
00270                   SB_HOSTED_STATIC(sb_idx)      = TRUE;
00271                }
00272                else {
00273                   sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx));
00274                }
00275 
00276                ATD_STOR_BLK_IDX(attr_idx)               = sb_idx;
00277                ATD_STOR_BLK_IDX(overlay_attr_idx)       = sb_idx;
00278             }
00279 # endif
00280 
00281          }
00282          else {
00283 
00284             ATD_OFFSET_FLD(overlay_attr_idx) = ATD_OFFSET_FLD(attr_idx);
00285             ATD_OFFSET_IDX(overlay_attr_idx) = ATD_CPNT_OFFSET_IDX(attr_idx);
00286             ATD_OFFSET_ASSIGNED(overlay_attr_idx) = 
00287                                                  ATD_OFFSET_ASSIGNED(attr_idx);
00288 
00289             /* If the array being initialized is a structure component, we   */
00290             /* must calculate its offset within the structure here because   */
00291             /* the derived type definition could be shared by a number of    */
00292             /* structures.  (Different structures sharing it means the       */
00293             /* derived type could appear at different offsets within the     */
00294             /* different structures.)  Add its offset inside the structure   */
00295             /* to the variable's offset.  This is the offset for the overlay */
00296             /* tmp.  If this is in a common block, set ATD_OFFSET for the    */
00297             /* tmp to the component offset and then add it to an equivalence */
00298             /* group.  Equivalence processing for common blocks expects      */
00299             /* offsets for equivalence groups to be in ATD_OFFSET when       */
00300             /* ATD_OFFSET_ASSIGNED is FALSE.                                 */
00301 
00302             ir_idx              = IR_IDX_L(whole_sub_ir_idx);
00303 
00304             if (ATD_OFFSET_IDX(overlay_attr_idx) == NULL_IDX) {
00305                ATD_OFFSET_FLD(overlay_attr_idx) = CN_Tbl_Idx;
00306                ATD_OFFSET_IDX(overlay_attr_idx) = CN_INTEGER_ZERO_IDX;
00307             }
00308 
00309 # if defined(_DEBUG)
00310 
00311             /* Must be a constant length. */
00312 
00313             if (ATD_OFFSET_FLD(overlay_attr_idx) != CN_Tbl_Idx) {
00314                PRINTMSG(AT_DEF_LINE(overlay_attr_idx), 1201, Internal, 
00315                         AT_DEF_COLUMN(overlay_attr_idx),
00316                         AT_OBJ_NAME_PTR(overlay_attr_idx));
00317             }
00318 # endif
00319 
00320             result.fld = ATD_OFFSET_FLD(overlay_attr_idx);
00321             result.idx = ATD_OFFSET_IDX(overlay_attr_idx);
00322 
00323             while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) {     /* Must be Struct IR.*/
00324                ir_idx = IR_IDX_L(ir_idx);
00325                length.fld = ATD_OFFSET_FLD(IR_IDX_R(ir_idx));
00326                length.idx = ATD_CPNT_OFFSET_IDX(IR_IDX_R(ir_idx));
00327 
00328                if (!size_offset_binary_calc(&length,
00329                                             &result,
00330                                             Plus_Opr,
00331                                             &result)) {
00332                   break;
00333                }
00334             }
00335 
00336             if (result.fld == NO_Tbl_Idx) {
00337                ATD_OFFSET_FLD(overlay_attr_idx) = CN_Tbl_Idx;
00338                ATD_OFFSET_IDX(overlay_attr_idx) = ntr_const_tbl(result.type_idx,
00339                                                                FALSE,
00340                                                                result.constant);
00341             }
00342             else {
00343                ATD_OFFSET_FLD(overlay_attr_idx) = result.fld;
00344                ATD_OFFSET_IDX(overlay_attr_idx) = result.idx;
00345             }
00346 
00347             var_attr_idx = IR_IDX_L(ir_idx);
00348             ATD_OFFSET_ASSIGNED(overlay_attr_idx) = FALSE;
00349             ATD_DATA_INIT(overlay_attr_idx) = TRUE;
00350 
00351             ATD_STOR_BLK_IDX(overlay_attr_idx) = ATD_STOR_BLK_IDX(var_attr_idx);
00352 
00353             if (ATD_EQUIV(var_attr_idx)) {
00354                eq_idx = SCP_FIRST_EQUIV_GRP(curr_scp_idx);
00355 
00356                while (eq_idx != NULL_IDX) {
00357                   eq_tmp_idx = eq_idx;
00358                   eq_idx = EQ_NEXT_EQUIV_GRP(eq_idx);
00359 
00360                   while (eq_tmp_idx != NULL_IDX) {
00361 
00362                      if (EQ_ATTR_IDX(eq_tmp_idx) == var_attr_idx) {
00363 
00364                         if (ATD_OFFSET_IDX(var_attr_idx) == NULL_IDX) {
00365                            ATD_OFFSET_FLD(var_attr_idx) = CN_Tbl_Idx;
00366                            ATD_OFFSET_IDX(var_attr_idx) = CN_INTEGER_ZERO_IDX;
00367                         }
00368                         NTR_EQ_TBL(eq_idx);
00369                         COPY_TBL_NTRY(equiv_tbl, eq_idx, eq_tmp_idx);
00370                         EQ_NEXT_EQUIV_OBJ(eq_tmp_idx) = eq_idx;
00371                         EQ_ATTR_IDX(eq_idx) = overlay_attr_idx;
00372 
00373                         result.fld = EQ_OFFSET_FLD(eq_idx);
00374                         result.idx = EQ_OFFSET_IDX(eq_idx);
00375                         length.fld = ATD_OFFSET_FLD(overlay_attr_idx);
00376                         length.idx = ATD_OFFSET_IDX(overlay_attr_idx);
00377 
00378                         if (!size_offset_binary_calc(&result,
00379                                                      &length,
00380                                                      Plus_Opr,
00381                                                      &result)) {
00382                            break;
00383                         }
00384 
00385                         if (result.fld == NO_Tbl_Idx) {
00386                            EQ_OFFSET_FLD(eq_idx) = CN_Tbl_Idx;
00387                            EQ_OFFSET_IDX(eq_idx) = ntr_const_tbl(
00388                                                              result.type_idx,
00389                                                              FALSE,
00390                                                              result.constant);
00391                         }
00392                         else if (result.fld == CN_Tbl_Idx) {
00393                            EQ_OFFSET_FLD(eq_idx) = result.fld;
00394                            EQ_OFFSET_IDX(eq_idx) = result.idx;
00395                         }
00396 
00397                         result.fld = ATD_OFFSET_FLD(var_attr_idx);
00398                         result.idx = ATD_OFFSET_IDX(var_attr_idx);
00399                         
00400                         if (!size_offset_binary_calc(&length,
00401                                                      &result,
00402                                                      Plus_Opr,
00403                                                      &result)) {
00404                            break;
00405                         }
00406 
00407                         if (result.fld == NO_Tbl_Idx) {
00408                            ATD_OFFSET_FLD(overlay_attr_idx) = CN_Tbl_Idx;
00409                            ATD_OFFSET_IDX(overlay_attr_idx) = ntr_const_tbl(
00410                                                                result.type_idx,
00411                                                                FALSE,
00412                                                                result.constant);
00413                         }
00414                         else {
00415                            ATD_OFFSET_FLD(overlay_attr_idx) = result.fld;
00416                            ATD_OFFSET_IDX(overlay_attr_idx) = result.idx;
00417                         }
00418 
00419                         ATD_EQUIV(var_attr_idx) = TRUE;
00420                         goto FOUND;
00421                      }
00422                      eq_tmp_idx = EQ_NEXT_EQUIV_OBJ(eq_tmp_idx);
00423                   }
00424                }
00425             }
00426 
00427             /* It is not in an equivalence group or it is not   */
00428             /* equivalenced, so make its own equivalence group. */
00429 
00430             NTR_EQ_TBL(eq_idx);
00431             NTR_EQ_TBL(eq_tmp_idx);
00432 
00433             EQ_NEXT_EQUIV_GRP(eq_idx)   = SCP_FIRST_EQUIV_GRP(curr_scp_idx);
00434             SCP_FIRST_EQUIV_GRP(curr_scp_idx)= eq_idx;
00435             EQ_OFFSET_IDX(eq_tmp_idx)   = ATD_OFFSET_IDX(overlay_attr_idx);
00436             EQ_OFFSET_FLD(eq_tmp_idx)   = ATD_OFFSET_FLD(overlay_attr_idx);
00437             EQ_ATTR_IDX(eq_idx)         = var_attr_idx;
00438             EQ_ATTR_IDX(eq_tmp_idx)     = overlay_attr_idx;
00439             EQ_NEXT_EQUIV_OBJ(eq_idx)   = eq_tmp_idx;
00440             ATD_EQUIV(var_attr_idx)     = TRUE;
00441 
00442 # if defined(_SEPARATE_NONCOMMON_EQUIV_GROUPS)
00443 
00444             sb_idx = ATD_STOR_BLK_IDX(var_attr_idx);
00445 
00446             if (sb_idx == NULL_IDX ||
00447                 (!SB_MODULE(sb_idx) && !SB_IS_COMMON(sb_idx))) {
00448 
00449                if (SB_HOSTED_STATIC(sb_idx)) {
00450                   sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx));
00451                   SB_HOSTED_STATIC(sb_idx) = TRUE;
00452                }
00453                else {
00454                   sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx));
00455                }
00456 
00457                ATD_STOR_BLK_IDX(var_attr_idx) = sb_idx;
00458                ATD_STOR_BLK_IDX(overlay_attr_idx) = sb_idx;
00459             }
00460 # endif
00461 
00462             NTR_IR_LIST_TBL(il_idx);
00463             IL_IDX(il_idx) = overlay_attr_idx;
00464             IL_FLD(il_idx) = AT_Tbl_Idx;
00465             IL_LINE_NUM(il_idx) = stmt_start_line;
00466             IL_COL_NUM(il_idx) = stmt_start_col;
00467 
00468             if (ATD_FLD(var_attr_idx) == NO_Tbl_Idx) {
00469                ATD_FLD(var_attr_idx) = IL_Tbl_Idx;
00470                IL_LIST_CNT(il_idx) = 1;
00471             }
00472             else {
00473                IL_LIST_CNT(il_idx) = 1 +
00474                                 IL_LIST_CNT(ATD_VARIABLE_TMP_IDX(var_attr_idx));
00475                IL_NEXT_LIST_IDX(il_idx) = ATD_VARIABLE_TMP_IDX(var_attr_idx);
00476             }
00477             ATD_VARIABLE_TMP_IDX(var_attr_idx) = il_idx;
00478          }
00479 
00480 FOUND:;
00481 
00482          /* Create new bound entry as a one-dimension array. */
00483 
00484          bd_idx                 = reserve_array_ntry(1);
00485          BD_RESOLVED(bd_idx)    = TRUE;
00486          BD_LEN_FLD(bd_idx)     = CN_Tbl_Idx; 
00487          BD_LEN_IDX(bd_idx)     = BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx));
00488          BD_RANK(bd_idx)        = 1;
00489          BD_ARRAY_CLASS(bd_idx) = Explicit_Shape;
00490          BD_ARRAY_SIZE(bd_idx)  = Constant_Size;
00491          BD_LINE_NUM(bd_idx)    = IR_LINE_NUM_L(whole_sub_ir_idx);
00492          BD_COLUMN_NUM(bd_idx)  = IR_COL_NUM_L(whole_sub_ir_idx);
00493          BD_LB_FLD(bd_idx,1)    = CN_Tbl_Idx; 
00494          BD_LB_IDX(bd_idx,1)    = CN_INTEGER_ONE_IDX;
00495          BD_UB_FLD(bd_idx,1)    = CN_Tbl_Idx; 
00496          BD_UB_IDX(bd_idx,1)    = BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx));
00497          BD_XT_FLD(bd_idx,1)    = CN_Tbl_Idx; 
00498          BD_XT_IDX(bd_idx,1)    = BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx));
00499          BD_SM_FLD(bd_idx,1)    = CN_Tbl_Idx; 
00500          BD_SM_IDX(bd_idx,1)    = BD_SM_IDX(ATD_ARRAY_IDX(attr_idx),1);
00501 
00502          ATD_ARRAY_IDX(overlay_attr_idx) = ntr_array_in_bd_tbl(bd_idx);
00503 
00504          curr_subscript = 1;
00505          curr_subscript_idx = CN_INTEGER_ONE_IDX;
00506 
00507          attr_idx = overlay_attr_idx;
00508       }
00509    }
00510    else {
00511       first_call = FALSE;
00512       curr_subscript    += *dup_count;
00513       curr_subscript_idx = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
00514                                        curr_subscript);
00515    }
00516 
00517    word_size_target = FALSE;
00518 
00519    if (TYP_LINEAR(ATD_TYPE_IDX(attr_idx)) == INTEGER_DEFAULT_TYPE  ||
00520        TYP_LINEAR(ATD_TYPE_IDX(attr_idx)) == REAL_DEFAULT_TYPE) {
00521 
00522       if (storage_bit_size_tbl[TYP_LINEAR(ATD_TYPE_IDX(attr_idx))] ==
00523             TARGET_BITS_PER_WORD) {
00524          word_size_target = TRUE;
00525       }
00526    }
00527 
00528    long_value = FALSE;
00529 
00530    if (value_desc.type == Typeless) {
00531 
00532       if (TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) >
00533              TARGET_BITS_PER_WORD) {
00534          long_value = TRUE;
00535       }
00536    }
00537    else if (value_desc.type == Character) {
00538 
00539       if (CN_INT_TO_C(TYP_IDX(value_desc.type_idx)) > TARGET_CHARS_PER_WORD) {
00540          long_value = TRUE;
00541       }
00542    }
00543 
00544    if (word_size_target  &&  long_value) {
00545       PRINTMSG(OPND_LINE_NUM(value_opnd), 733, Error, OPND_COL_NUM(value_opnd));
00546    }
00547    else {
00548 
00549       /* If                                                                   */
00550       /*    (1) this is the first initialization action for this array,       */
00551       /*    (2) it is not a structure component (this restriction can be      */
00552       /*        adjusted with experience), and                                */
00553       /*    (3) it is not an array of structures (that is, it is an intrinsic */
00554       /*        type,                                                         */
00555       /* then see if the whole array init can be turned into the assignment   */
00556       /* of an array constructor value to the array.  If the value list is all*/
00557       /* individual values, this transformation changes the internal form from*/
00558       /* <n> individual assignments to a single assignment of one large       */
00559       /* typeless blob to the array.                                          */
00560 
00561       if (first_call                                      &&
00562            IR_FLD_L(IR_IDX_L(init_ir_idx)) == AT_Tbl_Idx  &&
00563            TYP_TYPE(ATD_TYPE_IDX(IR_IDX_L(IR_IDX_L(init_ir_idx)))) !=
00564               Structure) {
00565 
00566          if (ATD_CLASS(attr_idx) == Compiler_Tmp) {
00567             IR_IDX_L(IR_IDX_L(init_ir_idx)) = attr_idx;
00568          }
00569 
00570          if (TYP_TYPE(CN_TYPE_IDX(OPND_IDX(value_opnd))) == Character &&
00571              (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Integer ||
00572               TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Real)) {
00573             *optimized = FALSE;
00574          } 
00575          else {
00576             *optimized = optimize_whole_array_init(init_ir_idx);
00577          }
00578 
00579          if (SH_ERR_FLG(curr_stmt_sh_idx)) {
00580             ok = FALSE;
00581             goto EXIT;
00582          }
00583 
00584          if (*optimized) {
00585             goto EXIT;
00586          }
00587       }
00588       else {
00589          *optimized = FALSE;
00590       }
00591     }
00592 
00593 
00594    /* Make a copy of the reference IR tree.  Locate the Whole_Subscript IR    */
00595    /* and change it to a Subscript IR.  Use the IL to which the Triplet IR is */
00596    /* attached to indicate the element at which the initialization is to      */
00597    /* begin.  (The Triplet IR is abandoned.)                                  */
00598    /* LRR:  Should we go to the work to free up the space for the Triplet IR  */
00599    /*       and its ILs?                                                      */
00600 
00601    gen_opnd(&opnd, root_ir_idx, IR_Tbl_Idx, stmt_start_line, stmt_start_col);
00602    copy_subtree(&opnd, &opnd);
00603    ir_idx                = OPND_IDX(opnd);
00604    IR_FLD_L(init_ir_idx) = IR_Tbl_Idx;
00605    IR_IDX_L(init_ir_idx) = ir_idx;
00606 
00607    while (IR_OPR(ir_idx) != Whole_Subscript_Opr) {
00608       ir_idx = IR_IDX_L(ir_idx);
00609    } 
00610  
00611    IR_OPR(ir_idx)  = Subscript_Opr;
00612    IR_RANK(ir_idx) = 1;
00613 
00614 
00615    /* If attr_idx is pointing at a compiler temp, it means a multidimension   */
00616    /* array has been overlayed.  If the left operand of the Subscript IR is   */
00617    /* an Attr index, just update the index to point at the temp's Attr.       */
00618    /* If the left operand is another IR, it had better be a Struct IR.  It    */
00619    /* means the temp is overlaying a multidimensional structure component, so */
00620    /* replace the whole reference to the component with a reference to the    */
00621    /* temp's Attr.                                                            */
00622 
00623    if (ATD_CLASS(attr_idx) == Compiler_Tmp) {
00624 
00625       if (IR_FLD_L(ir_idx) == AT_Tbl_Idx) {
00626          IR_IDX_L(ir_idx) = attr_idx;
00627       }
00628       else {                                    /* Had better be a Struct IR. */
00629          IR_FLD_L(ir_idx) = AT_Tbl_Idx;    
00630          IR_IDX_L(ir_idx) = attr_idx;
00631          IR_LINE_NUM_L(ir_idx) = stmt_start_line;
00632          IR_COL_NUM_L(ir_idx)  = stmt_start_col;
00633       }
00634    }
00635 
00636    il_idx                   = IR_IDX_R(ir_idx);
00637    IL_NEXT_LIST_IDX(il_idx) = NULL_IDX;
00638    IR_LIST_CNT_R(ir_idx)    = 1;
00639 
00640    IL_FLD(il_idx) = CN_Tbl_Idx;
00641    IL_IDX(il_idx) = curr_subscript_idx;
00642    IL_LINE_NUM(il_idx) = stmt_start_line;
00643    IL_COL_NUM(il_idx)  = stmt_start_col;
00644    
00645 
00646 EXIT:
00647 
00648    TRACE(Func_Exit, "init_whole_array", NULL);
00649 
00650    return(ok);
00651 
00652 }  /* init_whole_array */
00653 
00654 
00655 
00656 /******************************************************************************\
00657 |*                                                                            *|
00658 |* Description:                                                               *|
00659 |*      Perform semantic checks for the DATA statement and generate IR for    *|
00660 |*      the PDGCS interface.                                                  *|
00661 |*                                                                            *|
00662 |* Input parameters:                                                          *|
00663 |*      NONE                                                                  *|
00664 |*                                                                            *|
00665 |* Output parameters:                                                         *|
00666 |*      NONE                                                                  *|
00667 |*                                                                            *|
00668 |* Returns:                                                                   *|
00669 |*      NONE                                                                  *|
00670 |*                                                                            *|
00671 \******************************************************************************/
00672 
00673 void data_stmt_semantics(void)
00674 {
00675    int                  array_ir_idx;
00676    int                  attr_idx;
00677    int                  column;
00678    boolean              compiler_gen_imp_do;
00679    int                  const_il_idx;
00680    int                  dim_item_idx;
00681    int                  dup_cnt_il_idx;
00682    opnd_type            dup_cnt_opnd;
00683    long64               dup_count;
00684    boolean              dup_count_calculated    = FALSE;
00685    boolean              first_obj               = TRUE;
00686    int                  first_triplet_idx;
00687    int                  i;
00688    int                  il_idx;
00689    int                  init_ir_idx;
00690    int                  ir_idx;
00691    size_offset_type     length;
00692    int                  line;
00693    boolean              metamorphed;
00694    expr_arg_type        obj_desc;
00695    opnd_type            obj_opnd;
00696    boolean              optimized;
00697    opnd_type            rep_factor_opnd;
00698    int                  root_ir_idx;
00699    long64               section_inc_value;
00700    long64               section_start_value     = 0;
00701    int                  stride_il_idx;
00702    size_offset_type     stride_in_bits;
00703    opnd_type            stride_opnd;
00704    int                  struct_ir_idx;
00705    /* int               substring_ir_idx; */
00706    int                  target_attr_idx;
00707    boolean              vv_sub_present;
00708 
00709 
00710    TRACE (Func_Entry, "data_stmt_semantics", NULL);
00711 
00712    OPND_IDX(rep_factor_opnd) = NULL_IDX;
00713    init_ir_idx               = SH_IR_IDX(curr_stmt_sh_idx);
00714    obj_il_idx                = IR_IDX_L(init_ir_idx);
00715    value_il_idx              = IR_IDX_R(init_ir_idx);
00716    metamorphed               = FALSE;
00717    obj_count                 = 0;
00718    rep_factor                = 0;
00719 
00720    while (obj_il_idx != NULL_IDX) {
00721 
00722       if (first_obj) {
00723          first_obj = FALSE;
00724       }
00725       else {
00726          gen_sh(After, Data_Stmt, IL_LINE_NUM(obj_il_idx), 
00727                 IL_COL_NUM(obj_il_idx), FALSE, FALSE, TRUE);
00728          
00729          NTR_IR_TBL(init_ir_idx);
00730          SH_IR_IDX(curr_stmt_sh_idx) = init_ir_idx;
00731          IR_OPR(init_ir_idx)         = Init_Opr;
00732          IR_TYPE_IDX(init_ir_idx)    = TYPELESS_DEFAULT_TYPE;
00733          IR_LINE_NUM(init_ir_idx)    = IL_LINE_NUM(obj_il_idx);
00734          IR_COL_NUM(init_ir_idx)     = IL_COL_NUM(obj_il_idx);
00735       }
00736 
00737 RESTART:
00738 
00739       if (obj_count == 0) {
00740          stride_opnd           = null_opnd;
00741          array_ir_idx          = NULL_IDX;
00742          struct_ir_idx         = NULL_IDX;
00743          /* substring_ir_idx   = NULL_IDX; */
00744          target_attr_idx       = NULL_IDX;
00745          obj_desc.rank         = 0;
00746          compiler_gen_imp_do   = FALSE;
00747          vv_sub_present        = FALSE;
00748 
00749          COPY_OPND(obj_opnd, IL_OPND(obj_il_idx));
00750 
00751          if (OPND_FLD(obj_opnd) == AT_Tbl_Idx  ||
00752              (OPND_FLD(obj_opnd) == IR_Tbl_Idx  &&  
00753               IR_OPR(OPND_IDX(obj_opnd)) != Implied_Do_Opr)) {
00754             object_semantics(&obj_opnd,
00755                               Data_Stmt_Target,
00756                              &obj_desc,
00757                               TRUE,
00758                               metamorphed);
00759 
00760             if (OPND_FLD(obj_opnd) == AT_Tbl_Idx) {
00761                root_ir_idx = NULL_IDX;
00762             }
00763             else {
00764                root_ir_idx = OPND_IDX(obj_opnd);
00765 
00766 /*
00767                if (IR_OPR(root_ir_idx) == Whole_Substring_Opr  ||
00768                    IR_OPR(root_ir_idx) == Substring_Opr) {
00769                   substring_ir_idx = root_ir_idx;
00770                }
00771 */
00772 
00773                /* Get to the Attr for the item actually being initialized.    */
00774 
00775                ir_idx = OPND_IDX(obj_opnd);
00776 
00777                while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) {
00778 
00779                   if (IR_OPR(ir_idx) == Struct_Opr) {
00780                      break;
00781                   }
00782                   else {
00783                     ir_idx = IR_IDX_L(ir_idx);
00784                   }
00785                }
00786 
00787                target_attr_idx = (IR_OPR(ir_idx) == Struct_Opr) ?
00788                                   IR_IDX_R(ir_idx) : IR_IDX_L(ir_idx);
00789             }
00790 
00791             if (! SH_ERR_FLG(curr_stmt_sh_idx)) {
00792                COPY_OPND(IR_OPND_L(init_ir_idx), obj_opnd);
00793             }
00794             else {
00795                goto EXIT;
00796             }
00797          }
00798       }
00799 
00800       /* We have to keep processing the DATA stmt even if there are no values */
00801       /* left (value_il_idx is NULL_IDX) to make sure that all remaining      */
00802       /* targets (including implied-DOs) are zero-sized (because zero-sized   */
00803       /* don't contribute any variables to the target list).                  */
00804       /* If rep_factor is not 0, it means part of the value was not used up   */
00805       /* a previous target.                                                   */
00806 
00807       if (rep_factor == 0) {
00808          set_global_value_variables(&rep_factor_opnd, 
00809                                     &dup_cnt_opnd,   
00810                                     target_attr_idx);
00811 
00812          if (SH_ERR_FLG(curr_stmt_sh_idx)) {
00813             goto EXIT;
00814          }
00815       }
00816 
00817       /* If the target item is a whole array or section, the "array" IR is    */
00818       /* the one that is of interest.  Otherwise, get down through possible   */
00819       /* Whole_Substring, Substring, or Struct IR to the Attr for the scalar  */
00820       /* item actually being initialized.  If the target is character, we'll  */
00821       /* deal with blank padding after the target is initially processed.     */
00822       
00823 PROCESS_THE_TARGET:
00824 
00825       /* NULL initializations are thrown out after semantics are done.  We    */
00826       /* initialize pointers to NULL by default, so we do not have to gen     */
00827       /* code to do it.  Just make sure the object is a pointer.              */
00828 
00829       if (obj_desc.rank > 0 && !obj_desc.pointer) {
00830 
00831          /* Find the IR (either Whole_Subscript or Section_Subscript) that    */
00832          /* produces the nonzero rank.                                        */
00833 
00834          if (array_ir_idx == NULL_IDX) {
00835             array_ir_idx = OPND_IDX(obj_opnd);
00836 
00837             while (IR_OPR(array_ir_idx) != Whole_Subscript_Opr  &&
00838                    IR_OPR(array_ir_idx) != Section_Subscript_Opr) {
00839 
00840 /*
00841                if (IR_OPR(array_ir_idx) == Substring_Opr ||
00842                    IR_OPR(array_ir_idx) == Whole_Substring_Opr) {
00843                   substring_ir_idx = array_ir_idx;
00844                }
00845 */
00846 
00847                if (IR_OPR(array_ir_idx) == Struct_Opr) {
00848                   struct_ir_idx = array_ir_idx;
00849                }
00850 
00851                array_ir_idx = IR_IDX_L(array_ir_idx);
00852             }
00853          }
00854 
00855          if (IR_OPR(array_ir_idx) == Whole_Subscript_Opr) {
00856 
00857             /* A zero-sized array contributes no variables to the list so     */
00858             /* just iterate to the next object if the array is zero-sized.    */
00859 
00860             if (IR_FLD_L(array_ir_idx) == AT_Tbl_Idx) {
00861                dim_item_idx = IR_IDX_L(array_ir_idx);
00862             }
00863             else {
00864 
00865                /* If there was no Struct IR ahead of the Whole_Subscript IR,  */
00866                /* it means we're processing a component that is an array.     */
00867                /* The Whole_Subscript IR must be pointing at a Struct IR.     */
00868                /* If there WAS a Struct IR ahead of the Whole_Subscript IR,   */
00869                /* it means we're processing a component out of each element   */
00870                /* of an array of structures.                                  */
00871 
00872                if (struct_ir_idx == NULL_IDX) {
00873                   dim_item_idx = IR_IDX_R(IR_IDX_L(array_ir_idx));
00874                }
00875                else {
00876                   ir_idx = IR_IDX_L(array_ir_idx);
00877 
00878                   while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) {
00879                      ir_idx = IR_IDX_L(ir_idx);
00880                   }
00881 
00882                   dim_item_idx = IR_IDX_L(ir_idx);
00883                }
00884 
00885             }
00886 
00887             if (compare_cn_and_value(BD_LEN_IDX(ATD_ARRAY_IDX(dim_item_idx)),
00888                                      0, Eq_Opr)) {
00889                SH_IR_IDX(curr_stmt_sh_idx) = NULL_IDX;
00890                obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx);
00891                continue;        /* the big obj_il_idx loop */
00892             }
00893 
00894             if (struct_ir_idx == NULL_IDX  ||
00895                 (struct_ir_idx != NULL_IDX  &&  obj_desc.rank == 1)) {
00896 
00897                if (init_whole_array(array_ir_idx,
00898                                     &dup_count,
00899                                     root_ir_idx,
00900                                     init_ir_idx,
00901                                     &optimized)) {
00902                   
00903                   if (optimized) {
00904                      obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx);
00905                      continue;  /* the big obj_il_idx loop */
00906                   }
00907                }
00908                else {
00909                   goto EXIT;
00910                }
00911             }
00912             else {
00913                IR_OPR(array_ir_idx) = Section_Subscript_Opr;
00914                goto PROCESS_THE_TARGET;
00915             }
00916          } 
00917          else {
00918 
00919             /* Process the Section_Subscript IR. */
00920 
00921             if (obj_count == 0) {
00922                il_idx = IR_IDX_R(array_ir_idx);
00923 
00924                for (i = 1;  i <= IR_LIST_CNT_R(array_ir_idx);  ++i) {
00925        
00926                   if (IL_VECTOR_SUBSCRIPT(il_idx)) {
00927                      vv_sub_present = TRUE;
00928                      break;
00929                   }
00930         
00931                   il_idx = IL_NEXT_LIST_IDX(il_idx);
00932                }
00933 
00934                /* If there is at least one vector valued subscript present,   */
00935                /* just turn the whole reference into a (perhaps nested) set   */
00936                /* of implied-DOs.  Then call data_imp_do_semantics to verify  */
00937                /* that all the values are assignment compatible with the      */
00938                /* target.                                                     */
00939 
00940                if (vv_sub_present) {
00941                   vv_subscript_semantics(init_ir_idx,
00942                                          array_ir_idx,
00943                                          &obj_desc);
00944 
00945                   data_imp_do_semantics(init_ir_idx,
00946                                         IR_IDX_L(init_ir_idx),
00947                                         TRUE,
00948                                         &metamorphed);
00949 
00950                   obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx);
00951                   continue;     /* the big obj_il_idx loop */
00952                }
00953                else {
00954                   section_semantics(array_ir_idx,
00955                                     &stride_opnd,
00956                                     &first_triplet_idx);
00957                }
00958             }
00959       
00960             if (SH_ERR_FLG(curr_stmt_sh_idx)) {
00961                goto EXIT;
00962             }
00963 
00964             if (obj_count != 0) {
00965                gen_section_ref( array_ir_idx,
00966                                 rep_factor,
00967                                 first_triplet_idx,
00968                                 root_ir_idx,
00969                                 init_ir_idx,
00970                                &dup_count,
00971                                &section_start_value,
00972                                &section_inc_value);
00973                dup_count_calculated = TRUE;
00974             }  
00975             else {
00976                SH_IR_IDX(curr_stmt_sh_idx) = NULL_IDX;
00977                obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx);
00978                continue;        /* the big obj_il_idx loop */
00979             }
00980          }
00981       }
00982       else {
00983 
00984          /* We are dealing with a scalar target or an implied-DO. */
00985 
00986          if (OPND_FLD(obj_opnd) == AT_Tbl_Idx) {
00987             obj_count = 1;
00988             target_attr_idx = OPND_IDX(obj_opnd);
00989          }
00990          else {
00991 
00992             /* OPND_FLD(obj_opnd) must be IR_Tbl_Idx. */
00993       
00994             if (IR_OPR(OPND_IDX(obj_opnd)) == Implied_Do_Opr) {
00995 
00996                data_imp_do_semantics(init_ir_idx,
00997                                      IL_IDX(obj_il_idx),
00998                                      compiler_gen_imp_do,
00999                                      &metamorphed);
01000 
01001                if (SH_ERR_FLG(curr_stmt_sh_idx)) {
01002                   goto EXIT;
01003                }
01004 
01005                if (metamorphed) {
01006                   IL_FLD(obj_il_idx) = IL_FLD(IR_IDX_L(init_ir_idx));
01007                   IL_IDX(obj_il_idx) = IL_IDX(IR_IDX_L(init_ir_idx));
01008                   goto RESTART; 
01009                }
01010 
01011                COPY_OPND(IR_OPND_L(init_ir_idx), obj_opnd);
01012                obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx);
01013 
01014                continue;        /* the big obj_il_idx loop */
01015             }
01016             else {
01017 
01018                /* Here if object is a character item (due to Whole_Substring */
01019                /* or Substring IR), an array element, or a structure         */
01020                /* component.                                                 */
01021 
01022                obj_count = 1;
01023 
01024 /* 
01025                if (OPND_FLD(obj_opnd) == IR_Tbl_Idx &&
01026                    (IR_OPR(OPND_IDX(obj_opnd)) == Substring_Opr ||
01027                     IR_OPR(OPND_IDX(obj_opnd)) == Whole_Substring_Opr)) {
01028 
01029                   substring_ir_idx = OPND_IDX(obj_opnd);
01030                }
01031 */
01032             }
01033          }
01034       } 
01035 
01036       /* Have we run out of values but not out of targets? */
01037 
01038       if (value_il_idx == NULL_IDX) {
01039          find_opnd_line_and_column(&obj_opnd, &line, &column);
01040          PRINTMSG(line, 667, Error, column);
01041          goto EXIT;
01042       } 
01043           
01044       /* Verify that the value is assignment compatible with the target. */
01045  
01046       if (! check_target_and_value(target_attr_idx, init_ir_idx)) {
01047          goto EXIT;
01048       }
01049 
01050       /* Generate the IL that holds the value. */
01051 
01052       NTR_IR_LIST_TBL(const_il_idx);
01053       IR_LIST_CNT_R(init_ir_idx) = 3;
01054       IR_FLD_R(init_ir_idx)      = IL_Tbl_Idx;
01055       IR_IDX_R(init_ir_idx)      = const_il_idx;
01056       COPY_OPND(IL_OPND(const_il_idx), value_opnd);
01057 
01058       /* Generate the IL that holds the repetition count. */
01059 
01060       NTR_IR_LIST_TBL(dup_cnt_il_idx);
01061       IL_PREV_LIST_IDX(dup_cnt_il_idx) = const_il_idx;
01062       IL_NEXT_LIST_IDX(const_il_idx)   = dup_cnt_il_idx;
01063    
01064       if (OPND_IDX(rep_factor_opnd) == NULL_IDX) {
01065          find_opnd_line_and_column(&value_opnd, &line, &column);
01066          IL_LINE_NUM(dup_cnt_il_idx) = line;
01067          IL_COL_NUM(dup_cnt_il_idx) = column;
01068          IL_FLD(dup_cnt_il_idx) = CN_Tbl_Idx;
01069          IL_IDX(dup_cnt_il_idx) = CN_INTEGER_ONE_IDX;
01070          dup_count = 1;
01071       }
01072       else {
01073 
01074          if (dup_count_calculated) {
01075             dup_count_calculated = FALSE;
01076          }
01077          else {
01078             dup_count = (obj_count <= rep_factor) ? obj_count : rep_factor;
01079          }
01080 
01081          OPND_IDX(dup_cnt_opnd) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
01082                                               dup_count);
01083          COPY_OPND(IL_OPND(dup_cnt_il_idx), dup_cnt_opnd);
01084       }
01085 
01086       /* Generate the IR that holds the stride value.  A single item has a    */
01087       /* stride of 0.                                                         */
01088 
01089       NTR_IR_LIST_TBL(stride_il_idx);
01090       IL_PREV_LIST_IDX(stride_il_idx) = dup_cnt_il_idx;
01091       IL_NEXT_LIST_IDX(dup_cnt_il_idx) = stride_il_idx;
01092    
01093       if (dup_count == 1  || 
01094           (OPND_IDX(stride_opnd) == NULL_IDX  &&  array_ir_idx == NULL_IDX)) {
01095          find_opnd_line_and_column(&obj_opnd, &line, &column);
01096          IL_LINE_NUM(stride_il_idx) = line;
01097          IL_COL_NUM(stride_il_idx) = column;
01098          IL_FLD(stride_il_idx) = CN_Tbl_Idx;
01099          IL_IDX(stride_il_idx) = CN_INTEGER_ZERO_IDX;
01100       }
01101       else {
01102 
01103          /* If the stride has not yet been computed, compute it in bits.      */
01104          /* Note:  OPND_FLD is used rather than OPND_IDX.  Section processing */
01105          /* sets OPND_IDX but leaves OPND_FLD as NO_Tbl_Idx to signal that    */
01106          /* the actual bit stride has not yet been calculated.                */
01107 
01108          if (OPND_FLD(stride_opnd) == NO_Tbl_Idx) {
01109 
01110             if (struct_ir_idx == NULL_IDX) {
01111                attr_idx = (IR_FLD_L(array_ir_idx) == AT_Tbl_Idx) ?
01112                           IR_IDX_L(array_ir_idx) :
01113                           IR_IDX_R(IR_IDX_L(array_ir_idx));
01114             }
01115             else {
01116                ir_idx = array_ir_idx;
01117 
01118                while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) {
01119                   ir_idx = IR_IDX_L(ir_idx);
01120                }
01121 
01122                attr_idx = IR_IDX_L(ir_idx);
01123             }
01124 
01125             stride_in_bits = stor_bit_size_of(attr_idx, FALSE, FALSE);
01126 
01127             if (OPND_IDX(stride_opnd) != NULL_IDX) {
01128                length.fld = CN_Tbl_Idx;
01129                length.idx = OPND_IDX(stride_opnd);
01130 
01131                size_offset_binary_calc(&stride_in_bits,
01132                                        &length,
01133                                        Mult_Opr,
01134                                        &stride_in_bits);
01135             }
01136 
01137             if (stride_in_bits.fld == NO_Tbl_Idx) {
01138                OPND_FLD(stride_opnd) = CN_Tbl_Idx;
01139                OPND_IDX(stride_opnd) = ntr_const_tbl(stride_in_bits.type_idx,
01140                                                      FALSE,
01141                                                      stride_in_bits.constant);
01142             }
01143             else {
01144                OPND_FLD(stride_opnd) = stride_in_bits.fld;
01145                OPND_IDX(stride_opnd) = stride_in_bits.idx;
01146             }
01147 
01148             OPND_LINE_NUM(stride_opnd) = stmt_start_line;
01149             OPND_COL_NUM(stride_opnd)  = stmt_start_col;
01150          }
01151 
01152          COPY_OPND(IL_OPND(stride_il_idx), stride_opnd);
01153       }
01154    
01155       /* If the item is type character, see if the initialization value needs */
01156       /* to be blank padded.                                                  */
01157 
01158       if (TYP_TYPE(ATD_TYPE_IDX(target_attr_idx)) == Character) {
01159          adjust_char_value_len(init_ir_idx,
01160                                array_ir_idx,
01161                                section_start_value,
01162                                section_inc_value);
01163       }
01164 
01165       /* If we have assigned values to all the (possibly expanded) objects    */
01166       /* represented by the current object IL, move ahead to the next object  */
01167       /* IL.  Similarly, if we've used up all the values represented by the   */
01168       /* current value IL, move ahead to the next value IL.                   */
01169 
01170       if ((obj_count -= dup_count) == 0) {
01171          obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx);
01172       }
01173 
01174       if ((rep_factor -= dup_count) == 0) {
01175          value_il_idx = IL_NEXT_LIST_IDX(value_il_idx);
01176          /* BHJ */
01177          if (value_il_idx != NULL_IDX) {
01178             IL_PREV_LIST_IDX(value_il_idx) = NULL_IDX;
01179          }
01180 
01181          if (value_il_idx == NULL_IDX  &&  obj_count != 0) {
01182 
01183             /* If obj_count != 0, it means we're still working on an array    */
01184             /* reference of some kind.  CF77 has an outmoded feature that     */
01185             /* allows the number of values in the constant list to be less    */
01186             /* than the number of targets as long as the last target is a     */
01187             /* whole array reference.  Do not extend this extension by        */
01188             /* considering it OK if the whole array reference is not the last */
01189             /* thing in the target list but everything following it is zero-  */
01190             /* sized.                                                         */
01191 
01192             if (OPND_FLD(obj_opnd) == IR_Tbl_Idx                   &&
01193                 IR_OPR(OPND_IDX(obj_opnd)) == Whole_Subscript_Opr  &&
01194                 IL_NEXT_LIST_IDX(obj_il_idx) == NULL_IDX) {
01195 
01196                if (IR_OPR(init_ir_idx) == Init_Opr) {
01197                   PRINTMSG(IR_LINE_NUM_L(OPND_IDX(obj_opnd)), 698, Ansi,
01198                            IR_COL_NUM_L(OPND_IDX(obj_opnd)));
01199                }
01200 
01201                break;
01202             }
01203             else {
01204                find_opnd_line_and_column(&obj_opnd, &line, &column);
01205                PRINTMSG(line, 667, Error, column);
01206                obj_il_idx = NULL_IDX;
01207             }
01208          } 
01209       }
01210 
01211    }  /* while (obj_il_idx != NULL_IDX) */
01212 
01213    if (value_il_idx != NULL_IDX) {
01214       PRINTMSG(IL_LINE_NUM(value_il_idx), 668, Error, IL_COL_NUM(value_il_idx));
01215    }
01216 
01217 EXIT:
01218   
01219    TRACE (Func_Exit, "data_stmt_semantics", NULL);
01220 
01221    return;
01222 
01223 }  /* data_stmt_semantics */
01224 
01225 
01226 /******************************************************************************\
01227 |*                                                                            *|
01228 |* Description:                                                               *|
01229 |*      This procedure performs semantic analysis on the current object.      *|
01230 |*                                                                            *|
01231 |* Input parameters:                                                          *|
01232 |*      obj_opnd         : the operand representing the object                *|
01233 |*      target_expr_mode : the expr_semantics mode in which the DATA should   *|
01234 |*                           be evaluated                                     *|
01235 |*      fold_subscripts  : TRUE if subscripts are to be folded (the target is *|
01236 |*                           NOT an implied-DO target; implied-DO targets are *|
01237 |*                           handled by the interface)                        *|
01238 |*      metamorphed      : TRUE if an implied-DO has been metamorphed into    *|
01239 |*                           a whole array or section ref initialization      *|
01240 |*                                                                            *|
01241 |* Output parameters:                                                         *|
01242 |*      obj_opnd : the updated operand                                        *|
01243 |*      obj_desc : the expression descriptor returned by expr_semantics       *|
01244 |*                                                                            *|
01245 |* Returns:                                                                   *|
01246 |*      NONE                                                                  *|
01247 |*                                                                            *|
01248 \******************************************************************************/
01249 
01250 static void object_semantics(opnd_type          *obj_opnd,
01251                              expr_mode_type      target_expr_mode,
01252                              expr_arg_type      *obj_desc,
01253                              boolean             fold_subscripts,
01254                              boolean             metamorphed)
01255 
01256 {
01257    int                  attr_idx;
01258    opnd_type            data_obj;
01259 
01260 
01261    TRACE (Func_Entry, "object_semantics", NULL);
01262 
01263    /* Get down to the Attr for the target.                                    */
01264    /* If there's something wrong with the target, just give up.               */
01265 
01266    COPY_OPND(data_obj, *obj_opnd);
01267 
01268    while (OPND_FLD(data_obj) == IR_Tbl_Idx) {
01269       COPY_OPND(data_obj, IR_OPND_L(OPND_IDX(data_obj)));
01270    } 
01271 
01272    if (AT_DCL_ERR(OPND_IDX(data_obj))) {
01273       SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 
01274       goto EXIT;
01275    }
01276 
01277    /* Evaluate the target.                                                    */
01278 
01279    expr_mode      = target_expr_mode;
01280    obj_desc->rank = 0;
01281 
01282    /* Add 100 to the "modification" value to signal the item is being         */
01283    /* initialized.                                                            */
01284 
01285    xref_state = (metamorphed) ? CIF_No_Usage_Rec : 
01286                                 (cif_usage_code_type)
01287                                      (CIF_Symbol_Modification + 100);
01288 
01289    if (expr_semantics(obj_opnd, obj_desc)) {
01290 
01291       COPY_OPND(data_obj, *obj_opnd);
01292 
01293       while (OPND_FLD(data_obj) == IR_Tbl_Idx) {
01294          COPY_OPND(data_obj, IR_OPND_L(OPND_IDX(data_obj)));
01295       } 
01296 
01297       attr_idx = OPND_IDX(data_obj);
01298 
01299       /* Constraint checks:                                                   */
01300       /* * A variable that is a member of blank common should not be          */
01301       /*   initialized.                                                       */
01302       /* * A variable that is a member of a named common block should only be */
01303       /*   initialized in a block data program unit.                          */
01304       /* * A variable that is a member of a task common block must not be     */
01305       /*   initialized.                                                       */
01306       /* * From a CF77 SPR:  If an object in a Block Data program unit is NOT */
01307       /*   in a common block (and is not equivalenced to an object in common) */
01308       /*   but IS initialized, issue a warning.                               */
01309       /* * F95 -> An item must not be specified in a DATA statement if it is  */
01310       /*   of a default initialized type.                                     */
01311 
01312       if (ATD_IN_COMMON(attr_idx)) {
01313 
01314          if (SB_BLK_TYPE(ATD_STOR_BLK_IDX(attr_idx)) == Common) {
01315 
01316             if (! metamorphed) {
01317 
01318                if (SB_BLANK_COMMON(ATD_STOR_BLK_IDX(attr_idx))) {
01319                   PRINTMSG(OPND_LINE_NUM(data_obj), 1109, Ansi,
01320                            OPND_COL_NUM(data_obj));
01321                }
01322                else if (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) != Blockdata) {
01323 
01324 # if defined(_ALLOW_DATA_INIT_OF_COMMON)
01325                   PRINTMSG(OPND_LINE_NUM(data_obj), 692, Ansi,
01326                            OPND_COL_NUM(data_obj));
01327 # else
01328                   PRINTMSG(OPND_LINE_NUM(data_obj), 1542, Warning,
01329                            OPND_COL_NUM(data_obj));
01330 # endif
01331                }
01332             }
01333          }
01334          else if (SB_BLK_TYPE(ATD_STOR_BLK_IDX(attr_idx)) == Task_Common) {
01335             PRINTMSG(OPND_LINE_NUM(data_obj), 851, Error,
01336                      OPND_COL_NUM(data_obj));
01337          }
01338       }
01339       else if (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) == Blockdata  &&
01340                !(ATD_EQUIV(attr_idx) &&
01341                  SB_IS_COMMON(ATD_STOR_BLK_IDX(attr_idx)))) {
01342          PRINTMSG(OPND_LINE_NUM(data_obj), 825, Warning,
01343                   OPND_COL_NUM(data_obj));
01344       }
01345 
01346 
01347       /* There is no way to initialize a CRI character pointer.               */
01348 
01349       if (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == CRI_Ch_Ptr) {
01350 # ifdef _EXTENDED_CRI_CHAR_POINTER
01351          transform_cri_ch_ptr(obj_opnd);
01352 # else
01353          PRINTMSG(OPND_LINE_NUM(data_obj), 695, Error, OPND_COL_NUM(data_obj));
01354 # endif
01355       } 
01356 
01357       if (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Structure &&
01358           ATT_DEFAULT_INITIALIZED(TYP_IDX(ATD_TYPE_IDX(attr_idx)))) {
01359          PRINTMSG(OPND_LINE_NUM(data_obj), 1589, Error, 
01360                   OPND_COL_NUM(data_obj),
01361                   AT_OBJ_NAME_PTR(attr_idx),
01362                   AT_OBJ_NAME_PTR(TYP_IDX(ATD_TYPE_IDX(attr_idx))));
01363       }
01364       
01365       /* If the target is subscripted, fold the subscript expressions that    */
01366       /* may have been too complicated for expr_semantics to have folded when */
01367       /* the target reference was evaluated.                                  */
01368       /* Note that object_semantics is only called for a scalar target or a   */
01369       /* a target of an implied-DO.  fold_all_subscripts is only called for a */
01370       /* scalar target.                                                       */
01371 
01372       if (OPND_FLD((*obj_opnd)) == IR_Tbl_Idx  &&  fold_subscripts) {
01373          fold_all_subscripts(obj_opnd);
01374       }
01375    }
01376 
01377 EXIT:
01378 
01379    expr_mode = Regular_Expr;
01380 
01381    TRACE (Func_Exit, "object_semantics", NULL);
01382  
01383    return;
01384 
01385 }  /* object_semantics */
01386 
01387 
01388 /******************************************************************************\
01389 |*                                                                            *|
01390 |* Description:                                                               *|
01391 |*      This procedure sets up rep_factor_opnd, value_desc, and advances      *|
01392 |*      value_il_idx in some situations.                                      *|
01393 |*                                                                            *|
01394 |* Input parameters:                                                          *|
01395 |*      NONE                                                                  *|
01396 |*                                                                            *|
01397 |* Output parameters:                                                         *|
01398 |*      rep_factor_opnd : the opnd representing the rep factor                *|
01399 |*      dup_cnt_opnd    : a copy of the rep factor opnd                       *|
01400 |*                                                                            *|
01401 |* Returns:                                                                   *|
01402 |*      NONE                                                                  *|
01403 |*                                                                            *|
01404 \******************************************************************************/
01405 
01406 static void set_global_value_variables(opnd_type           *rep_factor_opnd,
01407                                        opnd_type           *dup_cnt_opnd,
01408                                        int                 target_attr_idx)
01409 {
01410    expr_arg_type        expr_desc;
01411    int                  rep_count_ir_idx;
01412 
01413 
01414    TRACE (Func_Entry, "set_global_value_variables", NULL);
01415 
01416    /* Loop even though the rep factor is 0 because a value with a rep factor  */
01417    /* of 0 contributes no values to the list.                                 */
01418 
01419    while (rep_factor == 0  &&  value_il_idx != NULL_IDX) {
01420 
01421       if (IL_FLD(value_il_idx) == IR_Tbl_Idx  &&
01422           IR_OPR(IL_IDX(value_il_idx)) == Rep_Count_Opr) {
01423          rep_count_ir_idx = IL_IDX(value_il_idx);
01424          COPY_OPND(*rep_factor_opnd, IR_OPND_L(rep_count_ir_idx));
01425 
01426 # ifdef _DEBUG
01427 
01428          if (OPND_FLD((*rep_factor_opnd)) != CN_Tbl_Idx) {
01429             PRINTMSG(IR_LINE_NUM(rep_count_ir_idx), 626, Internal,
01430                      IR_COL_NUM(rep_count_ir_idx),
01431                      "CN_Tbl_Idx", "set_global_value_variables");
01432          }
01433 
01434 # endif
01435 
01436          expr_desc.type_idx       = CN_TYPE_IDX(OPND_IDX((*rep_factor_opnd)));
01437          expr_desc.type           = TYP_TYPE(expr_desc.type_idx);
01438          expr_desc.linear_type    = TYP_LINEAR(expr_desc.type_idx);
01439 
01440          rep_factor = CN_INT_TO_C(OPND_IDX((*rep_factor_opnd)));
01441 
01442          if (rep_factor > 0) {
01443             COPY_OPND(*dup_cnt_opnd, *rep_factor_opnd);
01444             COPY_OPND(value_opnd, IR_OPND_R(rep_count_ir_idx));
01445          }
01446          else if (rep_factor == 0) {
01447             OPND_IDX((*rep_factor_opnd)) = NULL_IDX;
01448 
01449             if (IL_PREV_LIST_IDX(value_il_idx) != NULL_IDX) {
01450                IL_NEXT_LIST_IDX(IL_PREV_LIST_IDX(value_il_idx)) =
01451                   IL_NEXT_LIST_IDX(value_il_idx);
01452             }
01453 
01454             if (IL_NEXT_LIST_IDX(value_il_idx) != NULL_IDX) {
01455                IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(value_il_idx)) =
01456                   IL_PREV_LIST_IDX(value_il_idx);
01457             }
01458 
01459             value_il_idx = IL_NEXT_LIST_IDX(value_il_idx);
01460             continue;
01461          }
01462          else {  /* Must be positive or zero */
01463             PRINTMSG(OPND_LINE_NUM((*rep_factor_opnd)), 679, Error,
01464                      OPND_COL_NUM((*rep_factor_opnd)));
01465             goto EXIT;
01466          }
01467       }
01468       else {
01469          COPY_OPND(value_opnd, IL_OPND(value_il_idx));
01470          rep_factor                   = 1;
01471          OPND_IDX((*rep_factor_opnd)) = NULL_IDX;
01472          rep_count_ir_idx             = NULL_IDX;
01473       }
01474 
01475    }  /* while (rep_factor == 0  &&  value_il_idx != NULL_IDX) */
01476 
01477    if (value_il_idx == NULL_IDX) {
01478       goto EXIT;
01479    }
01480 
01481 
01482    /* value_opnd contains either the value that was in the value list or the  */
01483    /* value to the right of the rep factor.                                   */
01484 
01485    if (OPND_FLD(value_opnd) == CN_Tbl_Idx) {
01486       value_desc.type_idx    = CN_TYPE_IDX(OPND_IDX(value_opnd));
01487       value_desc.type        = TYP_TYPE(value_desc.type_idx);
01488       value_desc.linear_type = TYP_LINEAR(value_desc.type_idx);
01489    }
01490    else if (OPND_FLD(value_opnd) == AT_Tbl_Idx               &&
01491             AT_OBJ_CLASS(OPND_IDX(value_opnd)) == Data_Obj   &&
01492             ATD_CLASS(OPND_IDX(value_opnd)) == Compiler_Tmp  &&
01493             ATD_FLD(OPND_IDX(value_opnd)) == CN_Tbl_Idx)  {
01494 
01495       value_desc.type_idx    = ATD_TYPE_IDX(OPND_IDX(value_opnd));
01496       value_desc.type        = TYP_TYPE(value_desc.type_idx);
01497       value_desc.linear_type = TYP_LINEAR(value_desc.type_idx);
01498 
01499       OPND_FLD(value_opnd) = CN_Tbl_Idx;
01500       OPND_IDX(value_opnd) = ATD_TMP_IDX(OPND_IDX(value_opnd));
01501 
01502       if (rep_count_ir_idx == NULL_IDX) {
01503          COPY_OPND(IL_OPND(value_il_idx), value_opnd);
01504       }
01505       else {
01506          COPY_OPND(IR_OPND_R(rep_count_ir_idx), value_opnd);
01507       }
01508    }
01509    else if (OPND_FLD(value_opnd) == IR_Tbl_Idx &&
01510             IR_OPR(OPND_IDX(value_opnd)) == Null_Intrinsic_Opr) {
01511       value_desc.type_idx    = ATD_TYPE_IDX(target_attr_idx);
01512       value_desc.type        = TYP_TYPE(ATD_TYPE_IDX(target_attr_idx));
01513       value_desc.linear_type = TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx));
01514    }
01515 
01516 # ifdef _DEBUG
01517 
01518    else {
01519       PRINTMSG(IR_LINE_NUM(rep_count_ir_idx), 626, Internal,
01520                IR_COL_NUM(rep_count_ir_idx),
01521                "CN_Tbl_Idx or AT_Tbl_Idx", "set_global_value_variables");
01522    }
01523 
01524 # endif
01525 
01526 
01527 EXIT:
01528 
01529    TRACE (Func_Exit, "set_global_value_variables", NULL);
01530 
01531    return;
01532 
01533 }  /* set_global_value_variables */
01534 
01535 
01536 
01537 /******************************************************************************\
01538 |*                                                                            *|
01539 |* Description:                                                               *|
01540 |*      This procedure sets up the loop_tbl and calculates the number of      *|
01541 |*      targets represented by the section reference.                         *|
01542 |*                                                                            *|
01543 |* Input parameters:                                                          *|
01544 |*      section_sub_ir_idx : the index of the Section_Subscript IR            *|
01545 |*                                                                            *|
01546 |* Output parameters:                                                         *|
01547 |*      stride_opnd       : set to the stride value from the first section    *|
01548 |*                          triplet                                           *|
01549 |*      first_triplet_idx : the index of the first loop_tbl entry that        *|
01550 |*                          represents a triplet section subscript            *|
01551 |*                                                                            *|
01552 |* Returns:                                                                   *|
01553 |*      NONE                                                                  *|
01554 |*                                                                            *|
01555 \******************************************************************************/
01556 
01557 static void section_semantics(int                section_sub_ir_idx,
01558                               opnd_type         *stride_opnd,
01559                               int               *first_triplet_idx)
01560 
01561 {
01562    long64               actual_stride;  
01563    int                  attr_idx;
01564    int                  bd_idx;
01565    long64               dcl_lb;
01566    long64               dcl_ub;
01567    int                  end_il_idx;
01568    boolean              error_found;
01569    expr_arg_type        expr_desc;
01570    opnd_type            expr_opnd;
01571    int                  i;
01572    int                  ignore_this_arg;
01573    int                  ignore_this_arg_too;
01574    int                  il_idx;
01575    int                  last_triplet_idx        = NULL_IDX;
01576    long64               num_iterations;
01577    int                  start_il_idx;
01578    int                  stride_il_idx;
01579 
01580 
01581    TRACE(Func_Entry, "section_semantics", NULL);
01582 
01583    obj_count          = 1;
01584    *first_triplet_idx = NULL_IDX;
01585 
01586    /* Capture the subscript info in the loop_tbl.                             */
01587 
01588    expr_desc             = init_exp_desc;
01589    expr_desc.type        = Integer;
01590    expr_desc.type_idx    = INTEGER_DEFAULT_TYPE;
01591    expr_desc.linear_type = INTEGER_DEFAULT_TYPE;
01592 
01593    il_idx = IR_IDX_R(section_sub_ir_idx);
01594 
01595    for (lt_idx = 1;  lt_idx <= IR_LIST_CNT_R(section_sub_ir_idx);  ++lt_idx) {
01596       loop_tbl[lt_idx].sibling_idx = NULL_IDX;
01597 
01598       if (IL_FLD(il_idx) == CN_Tbl_Idx) {
01599          loop_tbl[lt_idx].curr_value = CN_INT_TO_C(IL_IDX(il_idx));
01600       }
01601       else if (IL_FLD(il_idx) == IR_Tbl_Idx) {
01602 
01603          /* Had better be a Triplet IR.                                       */
01604 
01605          if (IR_OPR(IL_IDX(il_idx)) != Triplet_Opr) {
01606             PRINTMSG(IL_LINE_NUM(il_idx), 704, Internal, IL_COL_NUM(il_idx));
01607          }
01608 
01609          error_found = FALSE;
01610 
01611 
01612          /* Get the declared lower and upper bounds for this dimension.       */
01613          /* (Bound info might be associated with a structure component.)      */
01614          /* find_base_attr does NOT change the opnd.                          */
01615 
01616          attr_idx = find_base_attr(&IR_OPND_L(section_sub_ir_idx),
01617                                    &ignore_this_arg,
01618                                    &ignore_this_arg_too);
01619 
01620          dcl_lb = CN_INT_TO_C(BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), lt_idx));
01621          dcl_ub = CN_INT_TO_C(BD_UB_IDX(ATD_ARRAY_IDX(attr_idx), lt_idx));
01622 
01623 
01624          /* Capture the start value.                                          */
01625 
01626          start_il_idx = IR_IDX_L(IL_IDX(il_idx));
01627 
01628          if (IL_FLD(start_il_idx) == CN_Tbl_Idx) {
01629             /* Nuttin' to do.                                                 */
01630          }
01631          else if (IL_FLD(start_il_idx) == IR_Tbl_Idx) {
01632             COPY_OPND(expr_opnd, IL_OPND(start_il_idx));
01633 
01634             if (fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) {
01635                COPY_OPND(IL_OPND(start_il_idx), expr_opnd); 
01636             }
01637             else {
01638                PRINTMSG(IR_LINE_NUM(IL_IDX(start_il_idx)),
01639                         861,
01640                         Internal,
01641                         IR_COL_NUM(IL_IDX(start_il_idx)),
01642                         "section_semantics");
01643             }
01644          }
01645          else {
01646             PRINTMSG(IR_LINE_NUM(IL_IDX(start_il_idx)),
01647                      704,
01648                      Internal,
01649                      IR_COL_NUM(IL_IDX(start_il_idx)));
01650          }
01651 
01652          loop_tbl[lt_idx].start_value = CN_INT_TO_C(IL_IDX(start_il_idx));
01653          loop_tbl[lt_idx].curr_value = loop_tbl[lt_idx].start_value;
01654 
01655 
01656          /* Capture the end value.                                            */
01657 
01658          end_il_idx = IL_NEXT_LIST_IDX(start_il_idx);
01659 
01660          if (IL_FLD(end_il_idx) == CN_Tbl_Idx) {
01661             /* Nuttin' to do.                                                 */
01662          }
01663          else if (IL_FLD(end_il_idx) == IR_Tbl_Idx) {
01664             COPY_OPND(expr_opnd, IL_OPND(end_il_idx));
01665 
01666             if (fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) {
01667                COPY_OPND(IL_OPND(end_il_idx), expr_opnd); 
01668             }
01669             else {
01670                PRINTMSG(IR_LINE_NUM(IL_IDX(end_il_idx)),
01671                         861,
01672                         Internal,
01673                         IR_COL_NUM(IL_IDX(end_il_idx)),
01674                         "section_semantics");
01675             }
01676          }
01677          else {
01678             PRINTMSG(IR_LINE_NUM(IL_IDX(end_il_idx)),
01679                      704,
01680                      Internal,
01681                      IR_COL_NUM(IL_IDX(end_il_idx)));
01682          }
01683 
01684          loop_tbl[lt_idx].end_value = CN_INT_TO_C(IL_IDX(end_il_idx));
01685 
01686 
01687          /* Capture the stride value.                                         */
01688               
01689          stride_il_idx = IL_NEXT_LIST_IDX(end_il_idx);
01690 
01691          if (IL_FLD(stride_il_idx) == CN_Tbl_Idx) {
01692             /* Nuttin' to do.                                                 */
01693          }
01694          else if (IL_FLD(stride_il_idx) == IR_Tbl_Idx) {
01695             COPY_OPND(expr_opnd, IL_OPND(stride_il_idx));
01696 
01697             if (fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) {
01698                COPY_OPND(IL_OPND(stride_il_idx), expr_opnd); 
01699             }
01700             else {
01701                PRINTMSG(IR_LINE_NUM(IL_IDX(stride_il_idx)),
01702                         861,
01703                         Internal,
01704                         IR_COL_NUM(IL_IDX(stride_il_idx)),
01705                         "section_semantics");
01706             }
01707          }
01708          else {
01709             PRINTMSG(IR_LINE_NUM(IL_IDX(stride_il_idx)),
01710                      704,
01711                      Internal,
01712                      IR_COL_NUM(IL_IDX(stride_il_idx)));
01713          }
01714 
01715          loop_tbl[lt_idx].inc_value = CN_INT_TO_C(IL_IDX(stride_il_idx));
01716    
01717 
01718          /* Check on the values of the start, end, and stride values.         */
01719 
01720          if (loop_tbl[lt_idx].inc_value > 0) {
01721             
01722             if (loop_tbl[lt_idx].start_value < dcl_lb) {
01723 
01724                /* The start value of the section subscript triplet is less    */
01725                /* than the declared lower bound.                              */
01726 
01727                PRINTMSG(IL_LINE_NUM(start_il_idx),
01728                         841,
01729                         Error,
01730                         IL_COL_NUM(start_il_idx)); 
01731                error_found = TRUE;
01732             }
01733 
01734             if (loop_tbl[lt_idx].start_value > dcl_ub) {
01735 
01736                /* The start value of the section subscript triplet is greater */
01737                /* than the declared upper bound.                              */
01738 
01739                PRINTMSG(IL_LINE_NUM(start_il_idx),
01740                         849,
01741                         Error,
01742                         IL_COL_NUM(start_il_idx)); 
01743                error_found = TRUE;
01744             }
01745 
01746             num_iterations =
01747                (loop_tbl[lt_idx].end_value - loop_tbl[lt_idx].start_value +
01748                 loop_tbl[lt_idx].inc_value) /
01749                loop_tbl[lt_idx].inc_value;
01750 
01751             if (num_iterations > 0) {
01752                obj_count *= num_iterations;
01753 
01754                if ((loop_tbl[lt_idx].start_value +
01755                    (num_iterations - 1)*loop_tbl[lt_idx].inc_value) > dcl_ub) {
01756 
01757                   /* The section subscript triplet produces a subscript value */
01758                   /* greater than the declared upper bound.                   */
01759 
01760                   PRINTMSG(IL_LINE_NUM(start_il_idx),
01761                            905,
01762                            Error,
01763                            IL_COL_NUM(start_il_idx)); 
01764                   error_found = TRUE;
01765                }
01766             }
01767             else {
01768                obj_count = 0;
01769             }
01770          }
01771          else if (loop_tbl[lt_idx].inc_value < 0) {
01772             
01773             if (loop_tbl[lt_idx].start_value > dcl_ub) {
01774 
01775                /* The start value of the section subscript triplet is greater */
01776                /* than the declared upper bound.                              */
01777 
01778                PRINTMSG(IL_LINE_NUM(start_il_idx),
01779                         849,
01780                         Error,
01781                         IL_COL_NUM(start_il_idx)); 
01782                error_found = TRUE;
01783             }
01784 
01785             if (loop_tbl[lt_idx].start_value < dcl_lb) {
01786 
01787                /* The start value of the section subscript triplet is less    */
01788                /* than the declared lower bound.                              */
01789 
01790                PRINTMSG(IL_LINE_NUM(start_il_idx),
01791                         841,
01792                         Error,
01793                         IL_COL_NUM(start_il_idx)); 
01794                error_found = TRUE;
01795             }
01796 
01797             num_iterations =
01798                (loop_tbl[lt_idx].end_value - loop_tbl[lt_idx].start_value +
01799                 loop_tbl[lt_idx].inc_value) /
01800                loop_tbl[lt_idx].inc_value;
01801   
01802             if (num_iterations > 0) {
01803                obj_count *= num_iterations;
01804 
01805                if ((loop_tbl[lt_idx].start_value +
01806                    (num_iterations - 1)*loop_tbl[lt_idx].inc_value) < dcl_lb) {
01807 
01808                   /* The section subscript triplet produces an end value less */
01809                   /* than the declared lower bound.                           */
01810 
01811                   PRINTMSG(IL_LINE_NUM(start_il_idx),
01812                            997,
01813                            Error,
01814                            IL_COL_NUM(start_il_idx)); 
01815                   error_found = TRUE;
01816                }
01817             }
01818             else { 
01819                obj_count = 0;
01820             }
01821          }
01822          else {
01823 
01824             /* The stride value of the section subscript must be nonzero.     */
01825 
01826             PRINTMSG(IL_LINE_NUM(stride_il_idx),
01827                      998,
01828                      Error,
01829                      IL_COL_NUM(stride_il_idx)); 
01830             error_found = TRUE;
01831          }
01832            
01833          if (! error_found) {
01834 
01835             /* Save information about the first triplet subscript because this*/
01836             /* is the only one we can use as a "loop" (the CRI back-end only  */
01837             /* accepts a single stride value).                                */
01838             /* Note:  OPND_FLD is set to NO_Tbl_Idx to indicate that the      */
01839             /* stride was calculated by section processing.  See the code in  */
01840             /* data_stmt_semantics that generates the stride IL.              */
01841                    
01842             if (*first_triplet_idx == NULL_IDX) {
01843                *first_triplet_idx = lt_idx;
01844                COPY_OPND(*stride_opnd, IL_OPND(stride_il_idx));
01845                OPND_FLD((*stride_opnd)) = NO_Tbl_Idx;
01846 
01847                if (lt_idx != 1) {
01848                   actual_stride = CN_INT_TO_C(IL_IDX(stride_il_idx));
01849                   bd_idx = ATD_ARRAY_IDX(IR_IDX_L(section_sub_ir_idx));
01850 
01851                   for (i = 1;  i < lt_idx;  ++i) {
01852                      actual_stride *= CN_INT_TO_C(BD_XT_IDX(bd_idx, i));
01853                   }
01854 
01855                   OPND_IDX((*stride_opnd)) =C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
01856                                                         actual_stride);
01857                }
01858             }
01859             else {
01860                loop_tbl[last_triplet_idx].sibling_idx = lt_idx;
01861             }
01862 
01863             last_triplet_idx = lt_idx;
01864          }
01865       }
01866 
01867       il_idx = IL_NEXT_LIST_IDX(il_idx);
01868 
01869    }  /* for loop */
01870 
01871    TRACE(Func_Exit, "section_semantics", NULL);
01872 
01873    return;
01874 
01875 }  /* section_semantics */
01876 
01877 
01878 /******************************************************************************\
01879 |*                                                                            *|
01880 |* Description:                                                               *|
01881 |*      This procedure generates the Subscript IR to represent where          *|
01882 |*      initialization is to begin for a piece of an array section.           *|
01883 |*                                                                            *|
01884 |* Input parameters:                                                          *|
01885 |*      section_sub_ir_idx : The index to the original Section_Subscript IR   *|
01886 |*                           that represents the section reference as seen in *|
01887 |*                           the user program.                                *|
01888 |*      value_count        : The number of values available to be used to     *|
01889 |*                           initialize the section (or portion of it).       *|
01890 |*      first_triplet_idx  : The index into the loop_tbl of the first section *|
01891 |*                           subscript.                                       *|
01892 |*      root_ir_idx        : NULL_IDX if the Section_Subscript IR is the root *|
01893 |*                           IR; otherwise, index of the root IR.             *|
01894 |*      init_ir_idx        : Index of the Init IR.                            *|
01895 |*                                                                            *|
01896 |* Output parameters:                                                         *|
01897 |*      dup_count           : The number of elements that can be initialized  *|
01898 |*                            on this pass through the section.  The maximum  *|
01899 |*                            number is the extent of the first section       *|
01900 |*                            subscript.                                      *|
01901 |*      section_start_value : If the target needs to be blank padded, an      *|
01902 |*                            implied-DO is needed.  This value is needed as  *|
01903 |*                            the implied-DO start value.                     *|
01904 |*      section_inc_value   : If the target needs to be blank padded, an      *|
01905 |*                            implied-DO is needed.  This value is needed as  *|
01906 |*                            the implied-DO inc value.                       *|
01907 |*                                                                            *|
01908 |* Returns:                                                                   *|
01909 |*      NONE                                                                  *|
01910 |*                                                                            *|
01911 \******************************************************************************/
01912 
01913 static void     gen_section_ref(int               section_sub_ir_idx,
01914                                 long64            value_count,
01915                                 int               first_triplet_idx,
01916                                 int               root_ir_idx,
01917                                 int               init_ir_idx,
01918                                 long64           *dup_count,
01919                                 long64           *section_start_value,
01920                                 long64           *section_inc_value) 
01921 
01922 {
01923    int          i;
01924    int          il_idx;
01925    int          last_il_idx;
01926    long64       local_obj_count;
01927    int          ir_idx;
01928    opnd_type    opnd;
01929  
01930 
01931    TRACE(Func_Entry, "gen_section_ref", NULL);
01932 
01933    /* Make a copy of the reference IR tree.  Locate the Section_Subscript IR  */
01934    /* and change it to a Subscript IR.  Use one of the ILs attached to the    */
01935    /* Triplet IR to indicate the element at which the initialization is to    */
01936    /* begin.                                                                  */
01937 
01938    gen_opnd(&opnd, root_ir_idx, IR_Tbl_Idx, stmt_start_line, stmt_start_col);
01939    copy_subtree(&opnd, &opnd);
01940    ir_idx                = OPND_IDX(opnd);
01941    IR_FLD_L(init_ir_idx) = IR_Tbl_Idx;
01942    IR_IDX_L(init_ir_idx) = ir_idx;
01943 
01944    while (IR_OPR(ir_idx) != Section_Subscript_Opr) {
01945       ir_idx = IR_IDX_L(ir_idx);
01946    }
01947 
01948    IR_OPR(ir_idx)  = Subscript_Opr;
01949    IR_RANK(ir_idx) = 1;
01950 
01951    NTR_IR_LIST_TBL(il_idx);
01952    IR_FLD_R(ir_idx) = IL_Tbl_Idx;
01953    IR_IDX_R(ir_idx) = il_idx;
01954    IL_FLD(il_idx)   = CN_Tbl_Idx;
01955    IL_IDX(il_idx)   = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
01956                                   loop_tbl[1].curr_value);
01957    IL_LINE_NUM(il_idx) = stmt_start_line;
01958    IL_COL_NUM(il_idx)  = stmt_start_col;
01959 
01960    last_il_idx      = il_idx;
01961 
01962    for (i = 2;  i <= IR_LIST_CNT_R(section_sub_ir_idx);  ++i) {
01963       NTR_IR_LIST_TBL(il_idx);
01964       IL_NEXT_LIST_IDX(last_il_idx) = il_idx;
01965       IL_PREV_LIST_IDX(il_idx) = last_il_idx;
01966       last_il_idx              = il_idx;
01967       IL_FLD(il_idx)           = CN_Tbl_Idx;
01968       IL_IDX(il_idx)           = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
01969                                              loop_tbl[i].curr_value);
01970       IL_LINE_NUM(il_idx) = stmt_start_line;
01971       IL_COL_NUM(il_idx)  = stmt_start_col;
01972    }
01973 
01974    /* Before loop_tbl[first_triplet_idx].curr_value gets updated, capture it  */
01975    /* to pass it out.  It will be needed if the target needs to be blank      */
01976    /* padded.                                                                 */
01977 
01978    *section_start_value = loop_tbl[first_triplet_idx].curr_value;
01979    *section_inc_value   = loop_tbl[first_triplet_idx].inc_value;
01980 
01981    /* Calculate the number of elements to be initialized.  The maximum that   */
01982    /* can be initialized at one time is the extent of the first section       */
01983    /* subscript.                                                              */
01984 
01985    local_obj_count = (loop_tbl[first_triplet_idx].end_value -
01986                       loop_tbl[first_triplet_idx].curr_value +
01987                       loop_tbl[first_triplet_idx].inc_value) /
01988                      loop_tbl[first_triplet_idx].inc_value;
01989 
01990    /* If the number of values available exceeds the number of elements        */
01991    /* available, it means we'll use up all (remaining) elements of the first  */
01992    /* triplet so we need to reset the triplet to its start value and increment*/
01993    /* triplets to the right as necessary.                                     */
01994    /* If the number of elements exceeds the number of values, just increment  */
01995    /* the leftmost triplet so it's ready on the next pass through this        */
01996    /* procedure.                                                              */
01997 
01998    if (local_obj_count <= value_count) {
01999       *dup_count = local_obj_count;
02000 
02001       if (obj_count != local_obj_count) {
02002          loop_tbl[first_triplet_idx].curr_value = 
02003             loop_tbl[first_triplet_idx].start_value;
02004          lt_idx = loop_tbl[first_triplet_idx].sibling_idx;
02005 
02006          while (lt_idx != NULL_IDX) {
02007             loop_tbl[lt_idx].curr_value += loop_tbl[lt_idx].inc_value;
02008             
02009             if ((loop_tbl[lt_idx].inc_value > 0  &&
02010                  loop_tbl[lt_idx].curr_value <= loop_tbl[lt_idx].end_value)  ||
02011                 (loop_tbl[lt_idx].inc_value < 0  &&
02012                  loop_tbl[lt_idx].curr_value >= loop_tbl[lt_idx].end_value)) {
02013                break;
02014             }
02015 
02016             loop_tbl[lt_idx].curr_value = loop_tbl[lt_idx].start_value;
02017             lt_idx                      = loop_tbl[lt_idx].sibling_idx;
02018          }
02019                 
02020       }
02021    }
02022    else {
02023       *dup_count = value_count;
02024       loop_tbl[first_triplet_idx].curr_value +=
02025          value_count * loop_tbl[first_triplet_idx].inc_value;
02026    }
02027       
02028    TRACE(Func_Exit, "gen_section_ref", NULL);
02029 
02030    return;
02031 
02032 }  /* gen_section_ref */
02033 
02034 
02035 /******************************************************************************\
02036 |*                                                                            *|
02037 |* Description:                                                               *|
02038 |*      This procedure generates implied-DOs to represent a section           *|
02039 |*      initialization when at least one subscript is a vector valued         *|
02040 |*      subscript.                                                            *|
02041 |*                                                                            *|
02042 |* Input parameters:                                                          *|
02043 |*      init_ir_idx     : index of the Init IR                                *|
02044 |*      array_ir_idx    : index of the Section_Subscript IR                   *|
02045 |*      obj_desc        : expression descriptor for the target                *|
02046 |*                                                                            *|
02047 |* Output parameters:                                                         *|
02048 |*      NONE                                                                  *|
02049 |*                                                                            *|
02050 |* Returns:                                                                   *|
02051 |*      NONE                                                                  *|
02052 |*                                                                            *|
02053 \******************************************************************************/
02054 
02055 static void     vv_subscript_semantics(int               init_ir_idx,
02056                                        int               array_ir_idx,
02057                                        expr_arg_type    *obj_desc)
02058 {
02059    int                  do_var_il_idx;
02060    int                  end_il_idx;
02061    int                  i;
02062    int                  il_idx;
02063    int                  imp_do_ir_idx;
02064    int                  inc_il_idx;
02065    expr_arg_type        shape_desc;
02066    int                  shape_idx;
02067    opnd_type            shape_opnd;
02068    int                  start_il_idx;
02069    int                  subscript_il_idx;
02070    int                  tmp_idx;
02071    int                  triplet_ir_idx;
02072 
02073 
02074    TRACE (Func_Entry, "vv_subscript_semantics", NULL);
02075 
02076    /* Loop through the subscripts of the Section_Subscript IR to find out     */
02077    /* which ones represent vector valued subscripts and which ones represent  */
02078    /* triplet subscripts or constants (if any).                               */
02079 
02080    shape_idx        = -1;
02081    subscript_il_idx = IR_IDX_R(array_ir_idx);
02082 
02083    for (i = 1;  i <= IR_LIST_CNT_R(array_ir_idx);  ++i) {
02084       
02085       switch (IL_FLD(subscript_il_idx)) {
02086 
02087          case CN_Tbl_Idx:
02088             break;
02089 
02090          case IR_Tbl_Idx:
02091 
02092             /* Since the subscript is represented by IR, it must be a vector  */
02093             /* valued subscript (possibly an expression like (V + 1) where V  */
02094             /* is a vector), or it must be a Triplet IR.                      */
02095             /*                                                                */
02096             /* Generate an Implied_Do IR and its left operand IL.  As we move */
02097             /* "left" to "right" through the subscript list, we are building  */
02098             /* up inner to outer loops so the Implied_Do IR is always         */
02099             /* attached to the left operand of the Init IR.  Whatever was     */
02100             /* formerly attached to the left operand of the Init IR then      */
02101             /* becomes the object of the new implied-DO.                      */
02102 
02103             ++shape_idx;
02104 
02105             NTR_IR_TBL(imp_do_ir_idx);
02106             IR_OPR(imp_do_ir_idx)      = Implied_Do_Opr;
02107             IR_TYPE_IDX(imp_do_ir_idx) = TYPELESS_DEFAULT_TYPE;
02108             IR_LINE_NUM(imp_do_ir_idx) = IR_LINE_NUM(init_ir_idx); 
02109             IR_COL_NUM(imp_do_ir_idx)  = IR_COL_NUM(init_ir_idx); 
02110 
02111             NTR_IR_LIST_TBL(il_idx);
02112             IR_LIST_CNT_L(imp_do_ir_idx) = 1;
02113             IR_FLD_L(imp_do_ir_idx)      = IL_Tbl_Idx;
02114             IR_IDX_L(imp_do_ir_idx)      = il_idx;
02115 
02116             COPY_OPND(IL_OPND(il_idx), IR_OPND_L(init_ir_idx));
02117 
02118             IR_IDX_L(init_ir_idx) = imp_do_ir_idx; 
02119             
02120             /* If this is a Triplet IR, save its index.  Its index will be    */
02121             /* used later to get at the ILs attached to it.                   */
02122 
02123             if (IR_OPR(IL_IDX(subscript_il_idx)) == Triplet_Opr) {
02124                triplet_ir_idx = IL_IDX(subscript_il_idx);
02125             }
02126          
02127             /* Generate an integer temp to serve as the DO variable of the    */
02128             /* implied-DO.  Generate the IL for the DO variable (the temp)    */
02129             /* and attach the IL to the right operand of the Implied_Do IR.   */
02130             /* If the subscript is a vector valued subscript, go into the     */
02131             /* expression descriptor and generate the implied-DO's start,     */
02132             /* end, and inc values from the shape of the current subscript    */
02133             /* (start and inc are always 1).  If the subscript is a triplet,  */
02134             /* let the start, end, and inc values be the values that were     */
02135             /* attached to the Triplet IR.                                    */
02136 
02137             tmp_idx = gen_compiler_tmp(IR_LINE_NUM(imp_do_ir_idx),
02138                                        IR_COL_NUM(imp_do_ir_idx),
02139                                        Priv, TRUE);
02140             AT_SEMANTICS_DONE(tmp_idx) = TRUE;
02141             ATD_TYPE_IDX(tmp_idx)      = INTEGER_DEFAULT_TYPE;
02142             ATD_STOR_BLK_IDX(tmp_idx)  = SCP_SB_STACK_IDX(curr_scp_idx);
02143             ATD_LCV_IS_CONST(tmp_idx)  = TRUE;
02144 
02145             /* clear the referenced field so that this tmp does */
02146             /* not get sent to mif. BHJ                         */
02147 
02148             AT_REFERENCED(tmp_idx)     = Not_Referenced;
02149 
02150             NTR_IR_LIST_TBL(do_var_il_idx);
02151             IL_LINE_NUM(do_var_il_idx)      = IR_LINE_NUM(imp_do_ir_idx);
02152             IL_COL_NUM(do_var_il_idx)       = IR_COL_NUM(imp_do_ir_idx);
02153             IL_FLD(do_var_il_idx)           = AT_Tbl_Idx;
02154             IL_IDX(do_var_il_idx)           = tmp_idx;
02155 
02156             if (IL_VECTOR_SUBSCRIPT(subscript_il_idx)) {
02157                NTR_IR_LIST_TBL(start_il_idx);
02158                IL_NEXT_LIST_IDX(do_var_il_idx) = start_il_idx;
02159                IL_PREV_LIST_IDX(start_il_idx)  = do_var_il_idx;
02160                IL_LINE_NUM(start_il_idx)       = IR_LINE_NUM(init_ir_idx);
02161                IL_COL_NUM(start_il_idx)        = IR_COL_NUM(init_ir_idx);
02162                IL_FLD(start_il_idx)            = CN_Tbl_Idx;
02163                IL_IDX(start_il_idx)            = CN_INTEGER_ONE_IDX;
02164  
02165                NTR_IR_LIST_TBL(end_il_idx);
02166                IL_NEXT_LIST_IDX(start_il_idx) = end_il_idx;
02167                IL_PREV_LIST_IDX(end_il_idx)   = start_il_idx;
02168 
02169                if (obj_desc->shape[shape_idx].fld != CN_Tbl_Idx) {
02170                   COPY_OPND(shape_opnd, obj_desc->shape[shape_idx]);
02171 
02172                   shape_desc             = init_exp_desc;
02173                   shape_desc.type        = Integer;
02174                   shape_desc.type_idx    = INTEGER_DEFAULT_TYPE;
02175                   shape_desc.linear_type = INTEGER_DEFAULT_TYPE;
02176                  
02177                   if (fold_aggragate_expression(&shape_opnd, 
02178                                                 &shape_desc,
02179                                                  TRUE)) {
02180                      COPY_OPND(IL_OPND(end_il_idx), shape_opnd);
02181                   }
02182                   else {
02183                      PRINTMSG(obj_desc->shape[shape_idx].line_num,
02184                               861, 
02185                               Internal,
02186                               obj_desc->shape[shape_idx].col_num,
02187                               "vv_subscript_semantics");
02188                   }
02189                }
02190                else {
02191                   IL_LINE_NUM(end_il_idx) = IR_LINE_NUM(init_ir_idx);
02192                   IL_COL_NUM(end_il_idx)  = IR_COL_NUM(init_ir_idx);
02193                   IL_FLD(end_il_idx)      = CN_Tbl_Idx;
02194                   IL_IDX(end_il_idx)      = obj_desc->shape[shape_idx].idx;
02195                } 
02196  
02197                NTR_IR_LIST_TBL(inc_il_idx);
02198                IL_NEXT_LIST_IDX(end_il_idx) = inc_il_idx;
02199                IL_PREV_LIST_IDX(inc_il_idx) = end_il_idx;
02200                IL_LINE_NUM(inc_il_idx)      = IR_LINE_NUM(init_ir_idx);
02201                IL_COL_NUM(inc_il_idx)       = IR_COL_NUM(init_ir_idx);
02202                IL_FLD(inc_il_idx)           = CN_Tbl_Idx;
02203                IL_IDX(inc_il_idx)           = CN_INTEGER_ONE_IDX;
02204 
02205                /* Generate a special 5th IL to point at the vector valued     */
02206                /* subscript tree so that the PDGCS interface can get each     */
02207                /* value in the vector.                                        */
02208 
02209                NTR_IR_LIST_TBL(il_idx);
02210                IL_NEXT_LIST_IDX(inc_il_idx) = il_idx;
02211                IL_PREV_LIST_IDX(il_idx)     = inc_il_idx;
02212                COPY_OPND(IL_OPND(il_idx), IL_OPND(subscript_il_idx));
02213 
02214                IR_LIST_CNT_R(imp_do_ir_idx) = 5;
02215             }
02216             else {
02217                IL_NEXT_LIST_IDX(do_var_il_idx) = IR_IDX_L(triplet_ir_idx);
02218                IR_LIST_CNT_R(imp_do_ir_idx)    = 4;
02219             }
02220 
02221             IR_FLD_R(imp_do_ir_idx) = IL_Tbl_Idx;
02222             IR_IDX_R(imp_do_ir_idx) = do_var_il_idx;
02223 
02224             IL_FLD(subscript_il_idx) = AT_Tbl_Idx;
02225             IL_IDX(subscript_il_idx) = tmp_idx;
02226             IL_LINE_NUM(subscript_il_idx) = IR_LINE_NUM(init_ir_idx);
02227             IL_COL_NUM(subscript_il_idx)  = IR_COL_NUM(init_ir_idx);
02228             
02229             break;
02230 
02231          default:
02232             PRINTMSG(IR_LINE_NUM(init_ir_idx), 179, Internal, 
02233                      IR_COL_NUM(init_ir_idx), "vv_section_semantics");
02234       }  
02235 
02236       subscript_il_idx = IL_NEXT_LIST_IDX(subscript_il_idx);
02237    }
02238    
02239    TRACE (Func_Exit, "vv_subscript_semantics", NULL);
02240 
02241    return;
02242 
02243 }  /* vv_subscript_semantics */
02244 
02245 
02246 /******************************************************************************\
02247 |*                                                                            *|
02248 |* Description:                                                               *|
02249 |*      This procedure handles the optimized initialization of a whole        *|
02250 |*      array, as in:                                                         *|
02251 |*                                                                            *|
02252 |*           INTEGER array(500)                                               *|
02253 |*           DATA array / <500 individual values> /                           *|
02254 |*                                                                            *|
02255 |*      It does this by overlaying a single dimension compiler-generated      *|
02256 |*      array variable on the base array.  If the base array is a single      *|
02257 |*      dimension array, no overlay is made.                                  *|
02258 |*                                                                            *|
02259 |* Input parameters:                                                          *|
02260 |*      init_ir_idx      : index of the Init IR                               *|
02261 |*                                                                            *|
02262 |* Output parameters:                                                         *|
02263 |*      optimized        : a flag passed back to the caller indicating        *|
02264 |*                         whether or not we were able to transform the       *|
02265 |*                         initialization                                     *|
02266 |* Returns:                                                                   *|
02267 |*      NONE                                                                  *|
02268 |*                                                                            *|
02269 \******************************************************************************/
02270 
02271 static boolean optimize_whole_array_init(int    init_ir_idx)
02272 {
02273    int                  attr_idx;
02274    int                  i;
02275    opnd_type            ignore_this_opnd;
02276    int                  ir_idx;
02277    expr_arg_type        loc_exp_desc;
02278    opnd_type            opnd;
02279    boolean              optimized       = TRUE;
02280    opnd_type            rep_factor_opnd;
02281    boolean              save_insert_subs_ok;
02282    opnd_type            save_left_opnd;
02283    long64               save_rep_factor;
02284    opnd_type            save_right_opnd;
02285    expr_arg_type        save_value_desc;
02286    int                  save_value_il_idx;
02287    opnd_type            save_value_opnd;
02288 
02289 
02290    TRACE(Func_Entry, "optimize_whole_array_init", NULL);
02291 
02292    if (value_il_idx == NULL_IDX) {
02293       optimized = FALSE;
02294       goto EXIT;
02295    }
02296 
02297    COPY_OPND(save_left_opnd, IR_OPND_L(init_ir_idx));
02298    COPY_OPND(save_right_opnd, IR_OPND_R(init_ir_idx));
02299    COPY_OPND(save_value_opnd, value_opnd);
02300    save_value_il_idx = value_il_idx;
02301    save_value_desc = value_desc;
02302    save_rep_factor = rep_factor;
02303 
02304    IR_LIST_CNT_R(init_ir_idx) = 0;
02305 
02306    if (IR_FLD_R(init_ir_idx) == NO_Tbl_Idx) {
02307       IR_FLD_R(init_ir_idx) = IL_Tbl_Idx;
02308       IR_IDX_R(init_ir_idx) = value_il_idx;
02309    }
02310 
02311    COPY_OPND(opnd, IR_OPND_L(init_ir_idx));
02312 
02313    while (OPND_FLD(opnd) == IR_Tbl_Idx) {
02314 
02315       if (IR_OPR(OPND_IDX(opnd)) == Substring_Opr ||
02316           IR_OPR(OPND_IDX(opnd)) == Whole_Substring_Opr) {
02317          break;
02318       }
02319 
02320       COPY_OPND(opnd, IR_OPND_L(OPND_IDX(opnd)));
02321    }
02322 
02323    attr_idx = IR_IDX_L(IR_IDX_L(init_ir_idx));
02324 
02325    for (i = 1;  i <= obj_count;  ++i) {
02326  
02327      /* Someday we have to duplicate some of the main line DATA code to eat   */
02328      /* up as values as we need and leave the Rep_Count IR in shape for the   */
02329      /* next target if there are any values left in it.                       */
02330      /* For now, if we see an IR index, we assume it's a Rep_Count IR, we     */
02331      /* restore everything to what it was when we came in, and we give up.    */
02332      if (IL_FLD(value_il_idx) == IR_Tbl_Idx) {
02333         optimized = FALSE;
02334         COPY_OPND(IR_OPND_L(init_ir_idx), save_left_opnd);
02335         COPY_OPND(IR_OPND_R(init_ir_idx), save_right_opnd);
02336         COPY_OPND(value_opnd, save_value_opnd);
02337         value_il_idx = save_value_il_idx;
02338         value_desc = save_value_desc;
02339         rep_factor = save_rep_factor;
02340         goto EXIT;
02341      }
02342 
02343      if (check_target_and_value(attr_idx, init_ir_idx)) {
02344         --rep_factor;
02345 
02346         if (rep_factor == 0) {
02347            ++IR_LIST_CNT_R(init_ir_idx);
02348            value_il_idx = IL_NEXT_LIST_IDX(value_il_idx);
02349         
02350            if (value_il_idx == NULL_IDX) {
02351               break;
02352            }
02353            else {
02354               set_global_value_variables(&rep_factor_opnd, 
02355                                          &ignore_this_opnd,
02356                                          attr_idx);
02357 
02358               if (SH_ERR_FLG(curr_stmt_sh_idx)) {
02359                  goto EXIT;
02360               }
02361            }
02362         }
02363      }
02364      else {
02365         goto EXIT;
02366      }
02367    }
02368 
02369    if (value_il_idx != NULL_IDX) {
02370       IL_NEXT_LIST_IDX(IL_PREV_LIST_IDX(value_il_idx)) = NULL_IDX;
02371       IL_PREV_LIST_IDX(value_il_idx) = NULL_IDX;
02372    }
02373  
02374 
02375    /* CF77 (and thus our little compiler) has an outmoded feature that allows */
02376    /* the number of values in the constant list to be less than the number of */
02377    /* target elements as long as the target array is the last item in the     */
02378    /* DATA target list.                                                       */
02379 
02380    if (IR_LIST_CNT_R(init_ir_idx) < obj_count) {
02381 
02382       if (IL_NEXT_LIST_IDX(obj_il_idx) == NULL_IDX) {
02383          PRINTMSG(IR_LINE_NUM_L(init_ir_idx), 698, Ansi,
02384                   IR_COL_NUM_L(init_ir_idx));
02385       }
02386       else {
02387          PRINTMSG(IR_LINE_NUM_L(init_ir_idx), 667, Error, 
02388                   IR_COL_NUM_L(init_ir_idx));
02389          optimized  = FALSE;   
02390          obj_il_idx = NULL_IDX;
02391          goto EXIT;
02392       }
02393    }
02394 
02395 
02396    /* Convert the value list to an array constructor.                         */
02397    /* target_array_idx, target_type_idx, and insert_subs_ok are global        */
02398    /* variables used by array constructor code.                               */
02399 
02400    OPND_FLD(init_target_opnd) = AT_Tbl_Idx;
02401    OPND_IDX(init_target_opnd) = attr_idx;
02402    OPND_LINE_NUM(init_target_opnd) = stmt_start_line;
02403    OPND_COL_NUM(init_target_opnd) = stmt_start_col;
02404 
02405    target_array_idx             = ATD_ARRAY_IDX(attr_idx);
02406    target_type_idx              = ATD_TYPE_IDX(attr_idx);
02407    check_type_conversion        = TRUE;
02408    save_insert_subs_ok          = insert_subs_ok;
02409    insert_subs_ok               = FALSE;
02410 
02411    NTR_IR_TBL(ir_idx);
02412    IR_OPR(ir_idx)      = Constant_Array_Construct_Opr;
02413    IR_LINE_NUM(ir_idx) = stmt_start_line;
02414    IR_COL_NUM(ir_idx)  = stmt_start_col;
02415    IR_TYPE_IDX(ir_idx) = target_type_idx;
02416 
02417    COPY_OPND(IR_OPND_R(ir_idx), IR_OPND_R(init_ir_idx));
02418 
02419    OPND_IDX(opnd) = ir_idx;
02420    OPND_FLD(opnd) = IR_Tbl_Idx;
02421 
02422    loc_exp_desc              = init_exp_desc;
02423    loc_exp_desc.type_idx     = target_type_idx;
02424    loc_exp_desc.type         = TYP_TYPE(target_type_idx);
02425    loc_exp_desc.linear_type  = TYP_LINEAR(target_type_idx);
02426    loc_exp_desc.rank         = 1;
02427 
02428    if (IR_LIST_CNT_R(init_ir_idx) == obj_count) {
02429       loc_exp_desc.shape[0].fld = BD_XT_FLD(target_array_idx, 1);
02430       loc_exp_desc.shape[0].idx = BD_XT_IDX(target_array_idx, 1);
02431    }
02432    else {
02433       loc_exp_desc.shape[0].fld = CN_Tbl_Idx;
02434       loc_exp_desc.shape[0].idx = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
02435                                               IR_LIST_CNT_R(init_ir_idx));
02436    }
02437 
02438    loc_exp_desc.constructor_size_level = Simple_Expr_Size;
02439 
02440    create_constructor_constant(&opnd, &loc_exp_desc);
02441 
02442    init_target_opnd = null_opnd;
02443    target_array_idx             = NULL_IDX;
02444    insert_subs_ok               = save_insert_subs_ok;
02445 
02446    remove_sh(curr_stmt_sh_idx);
02447    curr_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx);
02448 
02449    obj_count = 0;
02450 
02451 EXIT:
02452 
02453    TRACE(Func_Exit, "optimize_whole_array_init", NULL);
02454 
02455    return(optimized);
02456 
02457 }  /* optimize_whole_array_init */
02458 
02459 
02460 /******************************************************************************\
02461 |*                                                                            *|
02462 |* Description:                                                               *|
02463 |*      This procedure drives the processing of a DATA implied-DO and nested  *|
02464 |*      loops, if any exist.                                                  *|
02465 |*                                                                            *|
02466 |* Input parameters:                                                          *|
02467 |*      init_ir_idx  : the index of the current Init IR                       *|
02468 |*      imp_do_idx   : the index of the current Implied_Do IR                 *|
02469 |*      compiler_gen_imp_do : TRUE if the compiler produced this implied-DO   *|
02470 |*                                                                            *|
02471 |* Output parameters:                                                         *|
02472 |*      metamorphed : TRUE if the implied-DO underwent metamorphosis into a   *|
02473 |*                    whole array or array section initialization.            *|
02474 |*                                                                            *|
02475 |* Returns:                                                                   *|
02476 |*      NONE                                                                  *|
02477 |*                                                                            *|
02478 \******************************************************************************/
02479 
02480 static void data_imp_do_semantics(int                 init_ir_idx,
02481                                   int                 imp_do_idx,
02482                                   boolean             compiler_gen_imp_do,
02483                                   boolean            *metamorphed)
02484 
02485 {
02486    int           il_idx;
02487    int           local_rep_count_ir_idx;
02488    long64        local_rep_factor;
02489    int           local_value_il_idx;
02490    int           rep_count_ir_idx;
02491    boolean       save_runtime_bounds;
02492 
02493 
02494    TRACE (Func_Entry, "data_imp_do_semantics", NULL);
02495    save_runtime_bounds = cdir_switches.bounds;
02496    cdir_switches.bounds = TRUE;
02497 
02498    *metamorphed = FALSE;
02499 
02500 
02501    /* The expression descriptor for each implied-DO expression must be saved  */
02502    /* if the expression is truly an expression (involving IR).  There is a    */
02503    /* dynamic table where copies of the expression descriptors can be saved.  */
02504    /* The table is reset to "empty" after each statement.  Capture its base   */
02505    /* now.  Entries will be added to it by build_loop_tbl.                    */
02506 
02507    arg_info_list_base = arg_info_list_top;
02508 
02509 
02510    /* Build the loop_tbl entry for this loop level.                           */
02511 
02512    last_lt_idx     = NULL_IDX;
02513    curr_parent_idx = NULL_IDX;
02514 
02515    build_loop_tbl(imp_do_idx, compiler_gen_imp_do);
02516 
02517    if (SH_ERR_FLG(curr_stmt_sh_idx)) {
02518       goto EXIT;
02519    }
02520 
02521 
02522    /* See if the implied-DO can be metamorphed into a much more efficient     */
02523    /* whole array or array section initialization (it must be the only or     */
02524    /* last item in the original DATA statement; see imp_do_metamorphed for    */
02525    /* further explanation).                                                   */
02526 
02527    if (IL_NEXT_LIST_IDX(obj_il_idx) == NULL_IDX) {
02528 
02529       if (imp_do_metamorphed(init_ir_idx)) {
02530          *metamorphed = TRUE;
02531          goto EXIT;
02532       }
02533    }
02534 
02535       
02536    /* First, if the current value is a rep-factor/value pair and a            */
02537    /* previous target has used some of the values, make sure that the current */
02538    /* value of *rep_factor is represented by the Rep_Count IR because the     */
02539    /* implied-DO could use the Rep_Count IR directly.                         */
02540 
02541    if (IL_FLD(value_il_idx) == IR_Tbl_Idx  &&
02542        rep_factor != CN_INT_TO_C(IR_IDX_L(IL_IDX(value_il_idx)))) {
02543 
02544       IR_IDX_L(IL_IDX(value_il_idx)) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
02545                                                    rep_factor);
02546    }
02547 
02548    /* Now match the targets against the values.  If the implied-DO is part of */
02549    /* a DATA statement that contains other targets, split out the values that */
02550    /* will be assigned to the implied-DO target(s).                           */
02551    /* The rep factor and value for the first value have already been          */
02552    /* processed by data_stmt_semantics so they are ready for use.             */
02553 
02554    IR_LIST_CNT_R(init_ir_idx) = 1;
02555    IR_FLD_R(init_ir_idx) = IL_Tbl_Idx;
02556    IR_IDX_R(init_ir_idx) = value_il_idx;
02557 
02558    lt_idx = 1;
02559 
02560    interpret_data_imp_do(init_ir_idx);
02561 
02562    if (SH_ERR_FLG(curr_stmt_sh_idx)) {
02563       goto EXIT;
02564    }
02565 
02566    if (rep_factor == 0) {
02567 
02568       /* BHJ, LRR what is this ? */
02569 
02570       if (value_il_idx != NULL_IDX) {
02571          IL_NEXT_LIST_IDX(IL_PREV_LIST_IDX(value_il_idx)) = NULL_IDX;
02572       }
02573    }
02574    else if (IL_FLD(value_il_idx) == IR_Tbl_Idx) {
02575 
02576       /* A single value has a rep_factor of 1.  The above test is asking if   */
02577       /* there was originally a user-specified rep factor.                    */
02578       /* Since the rep_factor has not been counted down to 0, there are some  */
02579       /* values left over.  If the number of values used is greater than 1,   */
02580       /* make of copy of the original Rep_Count IR and attach it to the       */
02581       /* implied-DO's value chain to represent the number of values used.     */
02582       /* Otherwise, if the number of values used is 1, just copy the value    */
02583       /* from the original value IL.                                          */
02584 
02585       rep_count_ir_idx = IL_IDX(value_il_idx);
02586 
02587       local_rep_factor = CN_INT_TO_C(IR_IDX_L(rep_count_ir_idx)) - rep_factor; 
02588 
02589       local_value_il_idx = IL_PREV_LIST_IDX(value_il_idx);
02590 
02591       NTR_IR_LIST_TBL(il_idx);
02592 
02593       if (IR_LIST_CNT_R(init_ir_idx) == 1) {
02594          IR_IDX_R(init_ir_idx) = il_idx;
02595       }
02596       else {
02597          IL_NEXT_LIST_IDX(local_value_il_idx) = il_idx;
02598          IL_PREV_LIST_IDX(il_idx) = local_value_il_idx;
02599       }
02600 
02601       local_value_il_idx = il_idx;
02602 
02603       if (local_rep_factor > 1) {
02604          NTR_IR_TBL(local_rep_count_ir_idx);
02605          IR_TYPE_IDX(local_rep_count_ir_idx) = TYPELESS_DEFAULT_TYPE;
02606          IL_FLD(local_value_il_idx) = IR_Tbl_Idx;
02607          IL_IDX(local_value_il_idx) = local_rep_count_ir_idx;
02608          COPY_TBL_NTRY(ir_tbl, local_rep_count_ir_idx, rep_count_ir_idx);
02609 
02610          IR_IDX_L(local_rep_count_ir_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
02611                                                         local_rep_factor);
02612          COPY_OPND(IR_OPND_R(local_rep_count_ir_idx), value_opnd);
02613       }
02614       else {
02615          COPY_OPND(IL_OPND(local_value_il_idx), value_opnd);
02616       }
02617 
02618       /* If rep_factor is now 1, make the original value IL point directly at */
02619       /* the value (abandon the original Rep_Count IR).  Otherwise, replace   */
02620       /* the left operand (rep factor) of the original Rep_Count IR with the  */
02621       /* new rep_factor value.                                                */
02622 
02623       if (rep_factor == 1) {
02624          COPY_OPND(IL_OPND(value_il_idx), IR_OPND_R(rep_count_ir_idx));
02625       }
02626       else {
02627          IR_IDX_L(rep_count_ir_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
02628                                                   rep_factor);
02629       }
02630    }
02631 
02632 EXIT:
02633 
02634    cdir_switches.bounds = save_runtime_bounds;
02635 
02636    TRACE (Func_Exit, "data_imp_do_semantics", NULL);
02637 
02638    return;
02639 
02640 }  /* data_imp_do_semantics */
02641 
02642 
02643 /******************************************************************************\
02644 |*                                                                            *|
02645 |* Description:                                                               *|
02646 |*      This procedure fills in the loop_tbl that represents the implied-DO   *|
02647 |*      loops.                                                                *|
02648 |*                                                                            *|
02649 |* Input parameters:                                                          *|
02650 |*      imp_do_idx          : the index of the current Implied_Do IR.         *|
02651 |*      compiler_gen_imp_do : TRUE if the compiler generated the implied-DO   *|
02652 |*                                                                            *|
02653 |* Output parameters:                                                         *|
02654 |*      NONE                                                                  *|
02655 |*                                                                            *|
02656 |* Returns:                                                                   *|
02657 |*      NONE                                                                  *|
02658 |*                                                                            *|
02659 |* Algorithm note:                                                            *|
02660 |*      This procedure is recursive.                                          *|
02661 |*                                                                            *|
02662 \******************************************************************************/
02663 
02664 static void build_loop_tbl(int          imp_do_idx,
02665                            boolean      compiler_gen_imp_do)
02666 
02667 {
02668    int                  attr_idx;
02669    int                  column;
02670    int                  do_var_tmp_idx;
02671    expr_arg_type        expr_desc;
02672    int                  il_idx;
02673    int                  lcv_col;
02674    int                  lcv_line;
02675    int                  line;
02676    opnd_type            opnd;
02677    boolean              save_in_implied_do;
02678    boolean              save_imp_do_lcv;
02679    int                  search_idx;
02680    boolean              semantics_ok;
02681    int                  target_idx;
02682    int                  temp_ir_idx;
02683 
02684 
02685    TRACE (Func_Entry, "build_loop_tbl", NULL);
02686    
02687    if (++last_lt_idx > LOOP_TBL_SIZE) {
02688       PRINTMSG(IR_LINE_NUM(imp_do_idx), 237, Internal, IR_COL_NUM(imp_do_idx),
02689                "DATA implied-DO loop_tbl");
02690    }
02691 
02692    lt_idx = last_lt_idx;
02693 
02694    /* Initialize fields of the current table entry.  If we're at the outermost*/
02695    /* loop, indicate there is no parent.  Otherwise, "link" the current       */
02696    /* table entry to its parent (and sibling, if it exists).                  */
02697    /* NOTE:  curr_value is used by this procedure to locate the last sibling  */
02698    /*        in a sibling chain so we don't have to search to the end to      */
02699    /*        attach a subsequent sibling.                                     */
02700    /*
02701   -------------------------------------------------------------------------
02702   | lcv_idx                  |        | target_list             | num_   8|
02703   |                       24 |      8 |                      24 | targets |
02704   |-----------------------------------------------------------------------|
02705   | start_idx                | start_ | start_expr_desc_idx     | parent_ |
02706   |                       24 | fld  8 |                         | idx    8|
02707   |-----------------------------------------------------------------------|
02708   | end_idx                  | end_   | end_expr_desc_idx       |sibling_ |
02709   |                       24 | fld  8 |                         |idx     8|
02710   |-----------------------------------------------------------------------|
02711   | inc_idx                  | inc_   | inc_expr_desc_idx       |offspring|
02712   |                       24 | fld  8 |                         |_idx    8|
02713   |-----------------------------------------------------------------------|
02714   |                                start_value                            |
02715   |-----------------------------------------------------------------------|
02716   |                                 end_value                             |
02717   |-----------------------------------------------------------------------|
02718   |                                 inc_value                             |
02719   |-----------------------------------------------------------------------|
02720   |                                 curr_value                            |
02721   -------------------------------------------------------------------------
02722 
02723 */
02724 
02725    loop_tbl[lt_idx].num_targets   = 0;
02726    loop_tbl[lt_idx].sibling_idx   = NULL_IDX;
02727    loop_tbl[lt_idx].offspring_idx = NULL_IDX;
02728    loop_tbl[lt_idx].target_list   = NULL_IDX;
02729    loop_tbl[lt_idx].curr_value    = NULL_IDX;
02730   
02731    if (curr_parent_idx == NULL_IDX) {
02732       loop_tbl[lt_idx].parent_idx = NULL_IDX;
02733    }
02734    else {
02735       loop_tbl[lt_idx].parent_idx = curr_parent_idx;
02736        
02737       if (loop_tbl[curr_parent_idx].offspring_idx == NULL_IDX) {
02738          loop_tbl[curr_parent_idx].offspring_idx = lt_idx;
02739       }
02740       else {
02741          loop_tbl[loop_tbl[curr_parent_idx].curr_value].sibling_idx = lt_idx;
02742       }
02743 
02744       loop_tbl[curr_parent_idx].curr_value = lt_idx;
02745    }
02746 
02747    attr_idx = NULL_IDX;
02748 
02749 
02750    /* Capture the start value.  If it's a constant, get it's value.  If it's  */
02751    /* an Attr index it should be a loop control variable of an outer loop.    */
02752    /* Search back through the parent table entries to find the loop control   */
02753    /* variable and get its current value.  If it's an expression, point to    */
02754    /* the expression tree.                                                    */
02755    /* Note:  expr_sem is called rather than expr_semantics so that subobjects */
02756    /*        of named constants will not be folded.  If the expression is a   */
02757    /*        tree when it comes back from expr_sem, we need to check it to    */
02758    /*        see if it contains any subobjects of named constants.            */
02759 
02760    il_idx = IL_NEXT_LIST_IDX(IR_IDX_R(imp_do_idx));
02761 
02762    if (compiler_gen_imp_do) {
02763       loop_tbl[lt_idx].start_value = CN_INT_TO_C(IL_IDX(il_idx));
02764    }
02765    else {
02766       COPY_OPND(opnd, IL_OPND(il_idx));
02767       expr_mode      = Restricted_Imp_Do_Expr;
02768       expr_desc.rank = 0;
02769       xref_state     = CIF_Symbol_Reference;
02770 
02771       if (! expr_sem(&opnd, &expr_desc)) {
02772 
02773          /* It is possible for expr_sem to return a value of false without    */
02774          /* issuing an error message.                                         */
02775 
02776          SH_ERR_FLG(curr_stmt_sh_idx) = TRUE;
02777          goto EXIT;
02778       }
02779 
02780       if (expr_desc.linear_type == Short_Typeless_Const) {
02781          OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd),
02782                                                  INTEGER_DEFAULT_TYPE,
02783                                                  OPND_LINE_NUM(opnd),
02784                                                  OPND_COL_NUM(opnd));
02785          expr_desc.type_idx = INTEGER_DEFAULT_TYPE;
02786          expr_desc.type = Integer;
02787          expr_desc.linear_type = INTEGER_DEFAULT_TYPE;
02788       }
02789 
02790    
02791       if (expr_desc.rank == 0  &&
02792           expr_desc.type == Integer) {
02793          COPY_OPND(IL_OPND(il_idx), opnd);
02794          loop_tbl[lt_idx].start_fld = IL_FLD(il_idx);
02795          loop_tbl[lt_idx].start_idx = IL_IDX(il_idx);
02796    
02797          switch (loop_tbl[lt_idx].start_fld) {
02798 
02799             case CN_Tbl_Idx:
02800                loop_tbl[lt_idx].start_value = CN_INT_TO_C(IL_IDX(il_idx));
02801                break;
02802    
02803             case AT_Tbl_Idx:
02804                search_idx = loop_tbl[lt_idx].parent_idx;
02805    
02806                while (search_idx != NULL_IDX) {
02807 
02808                   if (loop_tbl[search_idx].lcv_idx == IL_IDX(il_idx)) {
02809                      loop_tbl[lt_idx].start_idx = search_idx;
02810                      break;
02811                   }
02812                   else {
02813                      search_idx = loop_tbl[search_idx].parent_idx;
02814                   }
02815      
02816                }
02817 
02818                if (search_idx == NULL_IDX) {
02819                   PRINTMSG(IL_LINE_NUM(il_idx), 658, Error, IL_COL_NUM(il_idx),
02820                            AT_OBJ_NAME_PTR(IL_IDX(il_idx)));
02821                   goto EXIT;
02822                }
02823 
02824                break;
02825 
02826             case IR_Tbl_Idx:
02827                if (good_data_imp_do_expr(loop_tbl[lt_idx].start_idx)) {
02828                   arg_info_list_top = arg_info_list_base + 1;
02829 
02830                   loop_tbl[lt_idx].start_expr_desc_idx = arg_info_list_top;
02831    
02832                   if (arg_info_list_top > arg_info_list_size) {
02833                      enlarge_info_list_table();
02834                   }
02835 
02836                   arg_info_list[arg_info_list_top]    = init_arg_info;
02837                   arg_info_list[arg_info_list_top].ed = expr_desc;
02838                }
02839 
02840                break; 
02841   
02842             default:
02843                PRINTMSG(IR_LINE_NUM(imp_do_idx), 179, Internal,
02844                         IR_COL_NUM(imp_do_idx), "build_loop_tbl");
02845          }    
02846       }
02847       else {
02848          PRINTMSG(IL_LINE_NUM(il_idx), 936, Error, IL_COL_NUM(il_idx));
02849       }
02850    }
02851 
02852 
02853    /* Capture the end value.  The processing is the same as for the start     */
02854    /* value.                                                                  */
02855 
02856    il_idx = IL_NEXT_LIST_IDX(il_idx);
02857 
02858    if (compiler_gen_imp_do) {
02859       loop_tbl[lt_idx].end_value = CN_INT_TO_C(IL_IDX(il_idx));
02860    }
02861    else {
02862       COPY_OPND(opnd, IL_OPND(il_idx));
02863       expr_desc.rank = 0;
02864       xref_state = CIF_Symbol_Reference;
02865 
02866       if (! expr_sem(&opnd, &expr_desc)) {
02867          SH_ERR_FLG(curr_stmt_sh_idx) = TRUE;
02868          goto EXIT;
02869       }
02870 
02871       if (expr_desc.linear_type == Short_Typeless_Const) {
02872          OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd),
02873                                                  INTEGER_DEFAULT_TYPE,
02874                                                  OPND_LINE_NUM(opnd),
02875                                                  OPND_COL_NUM(opnd));
02876          expr_desc.type_idx = INTEGER_DEFAULT_TYPE;
02877          expr_desc.type = Integer;
02878          expr_desc.linear_type = INTEGER_DEFAULT_TYPE;
02879       }
02880 
02881       if (expr_desc.rank == 0  &&
02882           expr_desc.type == Integer) {
02883 
02884          COPY_OPND(IL_OPND(il_idx), opnd);
02885          loop_tbl[lt_idx].end_fld = IL_FLD(il_idx);
02886          loop_tbl[lt_idx].end_idx = IL_IDX(il_idx);
02887    
02888          switch (loop_tbl[lt_idx].end_fld) {
02889 
02890             case CN_Tbl_Idx:
02891                loop_tbl[lt_idx].end_value = CN_INT_TO_C(IL_IDX(il_idx));
02892                break;
02893    
02894             case AT_Tbl_Idx:
02895                search_idx = loop_tbl[lt_idx].parent_idx;
02896 
02897                while (search_idx != NULL_IDX) {
02898          
02899                   if (loop_tbl[search_idx].lcv_idx == IL_IDX(il_idx)) {
02900                      loop_tbl[lt_idx].end_idx   = search_idx;
02901                      break;
02902                   }
02903                   else {
02904                      search_idx = loop_tbl[search_idx].parent_idx;
02905                   }
02906      
02907                }
02908 
02909                if (search_idx == NULL_IDX) {
02910                   PRINTMSG(IL_LINE_NUM(il_idx), 658, Error, IL_COL_NUM(il_idx),
02911                            AT_OBJ_NAME_PTR(IL_IDX(il_idx)));
02912                   goto EXIT;
02913                }
02914 
02915                break;
02916 
02917             case IR_Tbl_Idx:
02918                if (good_data_imp_do_expr(loop_tbl[lt_idx].end_idx)) {
02919                   arg_info_list_top = arg_info_list_base + 1;
02920 
02921                   loop_tbl[lt_idx].end_expr_desc_idx = arg_info_list_top;
02922   
02923                   if (arg_info_list_top > arg_info_list_size) {
02924                      enlarge_info_list_table();
02925                   }
02926 
02927                   arg_info_list[arg_info_list_top]    = init_arg_info;
02928                   arg_info_list[arg_info_list_top].ed = expr_desc;
02929                }
02930 
02931                break; 
02932   
02933             default:
02934                PRINTMSG(IR_LINE_NUM(imp_do_idx), 179, Internal,
02935                         IR_COL_NUM(imp_do_idx), "build_loop_tbl");
02936          }
02937       }
02938       else {
02939          PRINTMSG(IL_LINE_NUM(il_idx), 936, Error, IL_COL_NUM(il_idx));
02940       }
02941    }
02942 
02943 
02944    /* If no increment value was supplied, use 1.  Otherwise, capture the      */
02945    /* value in the same way the start and end values were captured.           */
02946    /* Generate an IL to represent the value 1 for the interface's convenience.*/
02947 
02948    if (IL_NEXT_LIST_IDX(il_idx) == NULL_IDX) {
02949       loop_tbl[lt_idx].inc_fld = CN_Tbl_Idx;
02950       loop_tbl[lt_idx].inc_idx = CN_INTEGER_ONE_IDX;
02951       loop_tbl[lt_idx].inc_value = CN_INT_TO_C(CN_INTEGER_ONE_IDX);
02952 
02953       NTR_IR_LIST_TBL(IL_NEXT_LIST_IDX(il_idx));
02954       IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(il_idx)) = il_idx; 
02955       il_idx = IL_NEXT_LIST_IDX(il_idx);
02956       IL_LINE_NUM(il_idx) = IL_LINE_NUM(IL_PREV_LIST_IDX(il_idx));
02957       IL_COL_NUM(il_idx) = IL_COL_NUM(IL_PREV_LIST_IDX(il_idx));
02958       IL_FLD(il_idx) = CN_Tbl_Idx; 
02959       IL_IDX(il_idx) = CN_INTEGER_ONE_IDX;
02960       ++IR_LIST_CNT_R(imp_do_idx);
02961    }
02962    else if (compiler_gen_imp_do) {
02963       il_idx = IL_NEXT_LIST_IDX(il_idx);
02964       loop_tbl[lt_idx].inc_value = CN_INT_TO_C(IL_IDX(il_idx));
02965    }
02966    else {
02967       il_idx = IL_NEXT_LIST_IDX(il_idx);
02968       COPY_OPND(opnd, IL_OPND(il_idx));
02969       expr_desc.rank = 0;
02970       xref_state = CIF_Symbol_Reference;
02971 
02972       if (! expr_sem(&opnd, &expr_desc)) {
02973          SH_ERR_FLG(curr_stmt_sh_idx) = TRUE;
02974          goto EXIT;
02975       }
02976 
02977       if (expr_desc.linear_type == Short_Typeless_Const) {
02978          OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd),
02979                                                  INTEGER_DEFAULT_TYPE,
02980                                                  OPND_LINE_NUM(opnd),
02981                                                  OPND_COL_NUM(opnd));
02982          expr_desc.type_idx = INTEGER_DEFAULT_TYPE;
02983          expr_desc.type = Integer;
02984          expr_desc.linear_type = INTEGER_DEFAULT_TYPE;
02985       }
02986 
02987       if (expr_desc.rank == 0  &&
02988           expr_desc.type == Integer) {
02989 
02990          COPY_OPND(IL_OPND(il_idx), opnd);
02991          loop_tbl[lt_idx].inc_fld = IL_FLD(il_idx);
02992          loop_tbl[lt_idx].inc_idx = IL_IDX(il_idx);
02993    
02994          switch (loop_tbl[lt_idx].inc_fld) {
02995 
02996             case CN_Tbl_Idx:
02997                if (fold_relationals(IL_IDX(il_idx),
02998                                     CN_INTEGER_ZERO_IDX,
02999                                     Eq_Opr)) {
03000                   PRINTMSG(IL_LINE_NUM(il_idx), 1084, Error, 
03001                            IL_COL_NUM(il_idx));
03002                }
03003                else {
03004                   loop_tbl[lt_idx].inc_value = CN_INT_TO_C(IL_IDX(il_idx));
03005                }
03006 
03007                break;
03008    
03009             case AT_Tbl_Idx:
03010                search_idx = loop_tbl[lt_idx].parent_idx;
03011 
03012                while (search_idx != NULL_IDX) {
03013             
03014                   if (loop_tbl[search_idx].lcv_idx == IL_IDX(il_idx)) {
03015                      loop_tbl[lt_idx].inc_idx = search_idx;
03016                      break;
03017                   }
03018                   else {
03019                      search_idx = loop_tbl[search_idx].parent_idx;
03020                   }
03021      
03022                }
03023 
03024                if (search_idx == NULL_IDX) {
03025                   PRINTMSG(IL_LINE_NUM(il_idx), 658, Error, IL_COL_NUM(il_idx),
03026                            AT_OBJ_NAME_PTR(IL_IDX(il_idx)));
03027                   goto EXIT;
03028                }
03029       
03030                break;
03031 
03032             case IR_Tbl_Idx:
03033                if (good_data_imp_do_expr(loop_tbl[lt_idx].inc_idx)) {
03034                   arg_info_list_top = arg_info_list_base + 1;
03035 
03036                   loop_tbl[lt_idx].inc_expr_desc_idx = arg_info_list_top;
03037 
03038                   if (arg_info_list_top > arg_info_list_size) {
03039                      enlarge_info_list_table();
03040                   }
03041 
03042                   arg_info_list[arg_info_list_top]    = init_arg_info;
03043                   arg_info_list[arg_info_list_top].ed = expr_desc;
03044                }
03045 
03046                break; 
03047   
03048             default:
03049                PRINTMSG(IR_LINE_NUM(imp_do_idx), 179, Internal,
03050                         IR_COL_NUM(imp_do_idx), "build_loop_tbl");
03051          }
03052       }
03053       else {
03054          PRINTMSG(IL_LINE_NUM(il_idx), 936, Error, IL_COL_NUM(il_idx));
03055       }
03056    }
03057 
03058 
03059    /* Resolve the loop control variable.  If an Attr for the same name exists */
03060    /* at an outer level, apply the semantic checks to that Attr; else use the */
03061    /* implied-DO local Attr.  Verify that the entity is a data object of type */
03062    /* integer and that it does not have the same name as a named constant.    */
03063 
03064    il_idx = IR_IDX_R(imp_do_idx);
03065 
03066    if (compiler_gen_imp_do) {
03067       loop_tbl[lt_idx].lcv_idx = IL_IDX(il_idx);
03068    }
03069    else {
03070       COPY_OPND(opnd, IL_OPND(il_idx));
03071       expr_desc.rank = 0;
03072       expr_mode = Regular_Expr;
03073       xref_state = CIF_No_Usage_Rec;
03074       save_in_implied_do = in_implied_do;
03075       in_implied_do = FALSE;
03076      
03077       lcv_line = OPND_LINE_NUM(opnd);
03078       lcv_col = OPND_COL_NUM(opnd);
03079       attr_idx = find_base_attr(&opnd, &lcv_line, &lcv_col);
03080 
03081       if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
03082          save_imp_do_lcv = ATD_IMP_DO_LCV(attr_idx);
03083          ATD_IMP_DO_LCV(attr_idx) = TRUE;
03084       }
03085 
03086       semantics_ok = expr_semantics(&opnd, &expr_desc);
03087 
03088       COPY_OPND(IL_OPND(il_idx), opnd);
03089       in_implied_do = save_in_implied_do;
03090 
03091       if (AT_OBJ_CLASS(attr_idx) == Data_Obj) {
03092          ATD_IMP_DO_LCV(attr_idx) = save_imp_do_lcv;
03093       }
03094 
03095       if (expr_desc.reference) {
03096 
03097          if (expr_desc.type != Integer) {
03098             find_opnd_line_and_column(&opnd, &line, &column);
03099             PRINTMSG(line, 675, Error, column);
03100             semantics_ok = FALSE;
03101          }
03102 
03103          if (OPND_FLD(opnd) == IR_Tbl_Idx  &&
03104              IR_OPR(OPND_IDX(opnd)) == Whole_Subscript_Opr) {
03105             COPY_OPND(opnd, IR_OPND_L(OPND_IDX(opnd)));
03106          }
03107 
03108          if (OPND_FLD(opnd) == IR_Tbl_Idx  &&
03109              IR_OPR(OPND_IDX(opnd)) == Dv_Deref_Opr) {
03110             COPY_OPND(opnd, IR_OPND_L(OPND_IDX(opnd)));
03111          }
03112 
03113          /* The implied-DO variable must be an unqualified name.              */
03114 
03115          if (semantics_ok  &&  OPND_FLD(opnd) != AT_Tbl_Idx) {
03116             find_opnd_line_and_column(&opnd, &line, &column);
03117             PRINTMSG(line, 199, Error, column);
03118             semantics_ok = FALSE;
03119          }
03120          else {
03121             attr_idx = OPND_IDX(opnd);
03122          }
03123 
03124          if (semantics_ok  &&  expr_desc.rank != 0) {
03125             find_opnd_line_and_column(&opnd, &line, &column);
03126             PRINTMSG(line, 837, Ansi, column);
03127          }
03128       }
03129       else {
03130 
03131          /* The implied-DO variable must be a variable (as opposed to an      */
03132          /* expression or a constant, for instance).                          */
03133 
03134          find_opnd_line_and_column(&opnd, &line, &column);
03135          PRINTMSG(line, 675, Error, column);
03136          semantics_ok = FALSE;
03137       }
03138 
03139       if (semantics_ok) {
03140          find_opnd_line_and_column(&opnd, &line, &column);
03141 
03142          if (AT_ATTR_LINK(attr_idx)) {
03143             PRINTMSG(line, 533, Error, column,
03144                      AT_OBJ_NAME_PTR(attr_idx));
03145             semantics_ok = FALSE;
03146          }
03147          else {
03148             do_var_tmp_idx = gen_compiler_tmp(line, column, Priv, TRUE);
03149             AT_SEMANTICS_DONE(do_var_tmp_idx) = TRUE;
03150             ATD_TYPE_IDX(do_var_tmp_idx) = ATD_TYPE_IDX(attr_idx);
03151             ATD_STOR_BLK_IDX(do_var_tmp_idx) = SCP_SB_STACK_IDX(curr_scp_idx);
03152 
03153             AT_ATTR_LINK(attr_idx) = do_var_tmp_idx;
03154             AT_IGNORE_ATTR_LINK(attr_idx) = TRUE;
03155 
03156             ATD_IMP_DO_LCV(do_var_tmp_idx) = TRUE;
03157             ATD_LCV_IS_CONST(do_var_tmp_idx) = TRUE;
03158             ATD_TMP_NEEDS_CIF(do_var_tmp_idx) = TRUE;
03159 
03160             /* change name to original name */
03161             AT_NAME_IDX(do_var_tmp_idx) = AT_NAME_IDX(attr_idx);
03162             AT_NAME_LEN(do_var_tmp_idx) = AT_NAME_LEN(attr_idx);
03163 
03164             /* clear the referenced field so that this tmp does */
03165             /* not get sent to mif.  BHJ                        */
03166 
03167             AT_REFERENCED(do_var_tmp_idx) = Not_Referenced;
03168 
03169             IL_FLD(il_idx) = AT_Tbl_Idx;
03170             IL_IDX(il_idx) = do_var_tmp_idx;
03171             IL_LINE_NUM(il_idx) = line;
03172             IL_COL_NUM(il_idx) = column;
03173 
03174             loop_tbl[lt_idx].lcv_idx = do_var_tmp_idx;
03175 
03176             /* issue a usage rec if needed */
03177             if ((cif_flags & XREF_RECS) != 0) {
03178                cif_usage_rec(do_var_tmp_idx, AT_Tbl_Idx, line, column,
03179                              CIF_Symbol_Modification);
03180             }
03181 
03182          }
03183       }
03184    }
03185 
03186 
03187    if (SH_ERR_FLG(curr_stmt_sh_idx)) {
03188       goto EXIT;
03189    }
03190 
03191    /* Count the number of target variables at this level of implied-DO.       */
03192    /* Example:   DATA ((tgt(i,j), i=1,10), a1(j), a2(j), j=1,3,2)             */
03193    /* The inner loop has one target and the outer has two.                    */
03194 
03195    in_implied_do = TRUE;
03196    target_idx = IR_IDX_L(imp_do_idx);
03197    loop_tbl[lt_idx].target_list = target_idx;
03198 
03199    while (target_idx != NULL_IDX) {
03200       ++loop_tbl[lt_idx].num_targets;
03201       
03202       if (IL_FLD(target_idx) == IR_Tbl_Idx  &&
03203           IR_OPR(IL_IDX(target_idx)) == Implied_Do_Opr) {
03204          curr_parent_idx = lt_idx;
03205          build_loop_tbl(IL_IDX(target_idx), compiler_gen_imp_do);
03206       }
03207       else if (! compiler_gen_imp_do) {
03208          COPY_OPND(opnd, IL_OPND(target_idx));
03209          object_semantics(&opnd,
03210                            Restricted_Imp_Do_Target,
03211                           &expr_desc,
03212                            FALSE,
03213                            FALSE);
03214 
03215          if (! SH_ERR_FLG(curr_stmt_sh_idx)) {
03216 
03217             /* An implied-DO target can only be an array element or a scalar  */
03218             /* structure component reference (note that there is no rule      */
03219             /* that the component reference must have an interior subscript   */
03220             /* list).                                                         */
03221 
03222             if (expr_desc.rank != 0  ||  OPND_FLD(opnd) != IR_Tbl_Idx) {
03223                find_opnd_line_and_column(&opnd, &line, &column);
03224                PRINTMSG(line, 709, Error, column);
03225                goto EXIT;
03226             }
03227 
03228             /* The Whole_Substring or Substring IR is annoyingly at the top   */
03229             /* of the reference tree so they must be skipped over to really   */
03230             /* tell what kind of reference we have.                           */
03231 
03232             temp_ir_idx = OPND_IDX(opnd);
03233 
03234             if (IR_OPR(temp_ir_idx) == Whole_Substring_Opr  ||
03235                 IR_OPR(temp_ir_idx) == Substring_Opr) {
03236                temp_ir_idx = IR_IDX_L(temp_ir_idx);
03237             }
03238  
03239             if (IR_OPR(temp_ir_idx) != Subscript_Opr  &&
03240                 IR_OPR(temp_ir_idx) != Struct_Opr) { 
03241                find_opnd_line_and_column(&opnd, &line, &column);
03242                PRINTMSG(line, 709, Error, column);
03243                goto EXIT;
03244             }
03245       
03246             COPY_OPND(IL_OPND(target_idx), opnd);
03247          }
03248       }
03249 
03250       target_idx = IL_NEXT_LIST_IDX(target_idx);
03251    }
03252 
03253 
03254    /* Pop out to the containing implied-DO, if there is one. */
03255 
03256    lt_idx = curr_parent_idx;
03257    
03258    if (curr_parent_idx != NULL_IDX) {
03259       curr_parent_idx = loop_tbl[lt_idx].parent_idx;
03260    }
03261 
03262 
03263 EXIT:
03264 
03265 
03266    /* This implied-DO is done so clear the AT_ATTR_LINK field of the */
03267    /* implied-DO variable so no processing will go on to the temp.   */
03268 
03269    if (semantics_ok  &&  attr_idx != NULL_IDX) {
03270       AT_ATTR_LINK(attr_idx) = NULL_IDX;
03271       AT_IGNORE_ATTR_LINK(attr_idx) = FALSE;
03272    }
03273 
03274    in_implied_do = save_in_implied_do;
03275    expr_mode = Regular_Expr;
03276 
03277    TRACE (Func_Exit, "build_loop_tbl", NULL);
03278   
03279    return;
03280 
03281 }  /* build_loop_tbl */
03282 
03283 
03284 /******************************************************************************\
03285 |*                                                                            *|
03286 |* Description:                                                               *|
03287 |*      This procedure checks to see that an IR tree returned from expr_sem   *|
03288 |*      for a DATA implied-DO loop control expression does not contain a      *|
03289 |*      subobject of a named constant.                                        *|
03290 |*                                                                            *|
03291 |* Input parameters:                                                          *|
03292 |*      ir_do_idx : the index of the IR tree                                  *|
03293 |*                                                                            *|
03294 |* Output parameters:                                                         *|
03295 |*      NONE                                                                  *|
03296 |*                                                                            *|
03297 |* Returns:                                                                   *|
03298 |*      TRUE if the expression does not contain a subobject designator        *|
03299 |*                                                                            *|
03300 \******************************************************************************/
03301 
03302 static boolean good_data_imp_do_expr(int          ir_idx)
03303 
03304 {
03305    boolean      result  = TRUE;
03306 
03307 
03308    TRACE (Func_Entry, "good_data_imp_do_expr", NULL);
03309 
03310    switch (IR_OPR(ir_idx)) {
03311 
03312       case Power_Opr:
03313       case Mult_Opr:
03314       case Div_Opr:
03315       case Uplus_Opr:
03316       case Uminus_Opr:
03317       case Plus_Opr:
03318       case Minus_Opr:
03319       case Paren_Opr:
03320       case Cvrt_Opr:
03321       case Cvrt_Unsigned_Opr:
03322          if (IR_FLD_L(ir_idx) == IR_Tbl_Idx) {
03323      
03324             if (! good_data_imp_do_expr(IR_IDX_L(ir_idx))) {
03325                result = FALSE;
03326             }
03327          }
03328 
03329          if (IR_FLD_R(ir_idx) == IR_Tbl_Idx) {
03330      
03331             if (! good_data_imp_do_expr(IR_IDX_R(ir_idx))) {
03332                result = FALSE;
03333             }
03334          }
03335 
03336          break;
03337 
03338       case Struct_Opr:
03339       case Subscript_Opr:
03340          PRINTMSG(IR_LINE_NUM(ir_idx), 1081, Error, IR_COL_NUM(ir_idx));
03341          result = FALSE;
03342          break;
03343 
03344       default:
03345          PRINTMSG(IR_LINE_NUM(ir_idx), 179, Internal, 0,
03346                   "good_data_imp_do_expr");
03347    }
03348 
03349    TRACE (Func_Exit, "good_data_imp_do_expr", NULL);
03350 
03351    return(result);
03352 
03353 }  /* good_data_imp_do_expr */
03354   
03355 
03356 /******************************************************************************\
03357 |*                                                                            *|
03358 |* Description:                                                               *|
03359 |*      Due to the characteristics of the PDGCS interface for implied-DOs,    *|
03360 |*      implied-DOs that initialize many array elements can take an           *|
03361 |*      excruciatingly long time to complete.  On the other hand, whole array *|
03362 |*      and array section initialization forms run significantly faster.  So  *|
03363 |*      this procedure is called to snoop through an implied-DO to see if it  *|
03364 |*      can undergo metamorphosis from a nasty, crawling implied-DO           *|
03365 |*      caterpillar to a lovely, dainty whole array butterfly or at least to  *|
03366 |*      a less elegant (but yet winged) array section moth.  In order for the *|
03367 |*      metamorphosis to take place, a number of environmental conditions     *|
03368 |*      must be met:                                                          *|
03369 |*                                                                            *|
03370 |*        1. The innermost loop can only have a single target and all outer   *|
03371 |*           loops can only be used to drive the innermost loop.  That is,    *|
03372 |*           a loop of the form:                                              *|
03373 |*                                                                            *|
03374 |*                DATA ((arr(i,j), i = 1, 10), j = 1, 10) /.../               *|
03375 |*                                                                            *|
03376 |*           can undergo metamorphosis but a loop of either of the following  *|
03377 |*           forms can not:                                                   *|
03378 |*                                                                            *|
03379 |*                DATA ((a1(i,j), a2(i,j), i = 1, 10), j = 1, 10) /.../       *|
03380 |*                DATA ((a1(i,j), i = 1, 10), a2(j), j = 1, 10)   /.../       *|
03381 |*                                                                            *|
03382 |*        2. The target must be of numeric or logical type.  All of the loops *|
03383 |*           that cause the compiler problems at this point are FORTRAN 77    *|
03384 |*           implied-DOs.  We don't need to worry yet about a program that    *|
03385 |*           tries to initialize a large number of elements of a large array  *|
03386 |*           of structures.  Likely if people start using arrays of           *|
03387 |*           structures, they will also use other Fortran 90 initialization   *|
03388 |*           concepts such as whole array initialization or initialization on *|
03389 |*           the type declaration statement.                                  *|
03390 |*                                                                            *|
03391 |*        3. The target must be a simple array element reference.  Again, all *|
03392 |*           of the problem implied-DOs are 77-style loops.  Therefore, we    *|
03393 |*           should not have to worry about initialization of a structure     *|
03394 |*           component that is a large array or initializing an array         *|
03395 |*           constructed by taking one component from each element of an      *|
03396 |*           array of structures.  This rule eliminates having to dig through *|
03397 |*           an arbitrarily complex structure reference tree to find the      *|
03398 |*           entity that's actually being initialized.                        *|
03399 |*                                                                            *|
03400 |*        4. Each subscript in the array element reference must be an         *|
03401 |*           implied-DO variable or a constant.  An expression prevents       *|
03402 |*           metamorphosis because it can't be translated into a whole array  *|
03403 |*           initialization and sometimes not even into an array section      *|
03404 |*           section initialization.  It's too much work to allow in SOME     *|
03405 |*           expressions because it's too much work to see if they are        *|
03406 |*           satisfactory.  For example, the first implied-DO below can be    *|
03407 |*           metamorphed but the second can not:                              *|
03408 |*                                                                            *|
03409 |*                DATA (arr(i + 1), i = 1, 10)   /.../                        *|
03410 |*                DATA ((arr(i + j, j), i = 1, 10), j = 1, 10)   /.../        *|
03411 |*                                                                            *|
03412 |*        5. Each subscript that is an implied-DO variable must be in the     *|
03413 |*           same order as the loop nest.  That is, the subscripts that are   *|
03414 |*           variables must vary the fastest from the left to the right (from *|
03415 |*           the innermost loop to the outermost) because this is the way     *|
03416 |*           whole array and section subscripting works.  For example, the    *|
03417 |*           first implied-DO below can be metamorphed but the second can     *|
03418 |*           not:                                                             *|
03419 |*                                                                            *|
03420 |*                DATA ((arr(i,2,j), i = 1, 10), j = 1, 10)   /.../           *|
03421 |*                DATA ((arr(j,i), i = 1, 10), j = 1, 10)     /.../           *|
03422 |*                                                                            *|
03423 |*        6. Every loop control expression of every loop in the nest must be  *|
03424 |*           constant.  Again, due to the way subscripting works in a whole   *|
03425 |*           array or section reference, a loop control expression can not    *|
03426 |*           involve an implied-DO variable from an outer loop.               *|
03427 |*                                                                            *|
03428 |*        7. No value in the value list can be a long Hollerith or character  *|
03429 |*           constant.  We don't do whole array initializations or array      *|
03430 |*           section initializations when the values are character forms so   *|
03431 |*           we can't change an implied-DO into either one.  And it's too     *|
03432 |*           darn much work to sift through the values matching them to see   *|
03433 |*           that the character values do or do not get assigned to the       *|
03434 |*           implied-DO target so we take the easier route of quitting if a   *|
03435 |*           character value shows up anywhere in the value list.             *|
03436 |*                                                                            *|
03437 |*        8. The number of array elements being initialized must be equal to  *|
03438 |*           the number of values in the value list.  The Cray version of     *|
03439 |*           this compiler has an extension whereby when a whole array is     *|
03440 |*           being initialized, if it is the only array or the last array in  *|
03441 |*           the object list, the number of values can be less than the       *|
03442 |*           of array elements.  If we do not make the count comparison in    *|
03443 |*           this rule and change an implied-DO into a whole array init, we   *|
03444 |*           could lose the count mismatch diagnostic and would thereby allow *|
03445 |*           an otherwise invalid implied-DO through.                         *|
03446 |*                                                                            *|
03447 |*      If all the above requirements are met then if each loop range matches *|
03448 |*      the declared bounds of the target array, the implied-DO caterpillar   *|
03449 |*      will undergo metamorphosis to a whole array butterfly; otherwise, it  *|
03450 |*      will become an array section moth.                                    *|
03451 |*                                                                            *|
03452 |* Input parameters:                                                          *|
03453 |*      init_ir_idx : The index of the Init IR that heads the implied-DO.     *|
03454 |*                                                                            *|
03455 |* Output parameters:                                                         *|
03456 |*      NONE                                                                  *|
03457 |*                                                                            *|
03458 |* Returns:                                                                   *|
03459 |*      TRUE if the implied-DO underwent metamorphosis.                       *|
03460 |*                                                                            *|
03461 \******************************************************************************/
03462 
03463 static boolean imp_do_metamorphed(int   init_ir_idx)
03464 {
03465    int                  attr_idx;
03466    expr_arg_type        expr_desc;
03467    opnd_type            expr_opnd;
03468    int                  i;
03469    int                  il_idx;
03470    int                  ir_idx;
03471    int                  iter_count_ir_idx;
03472    int                  local_lt_idx;
03473    boolean              loops_match_bounds;
03474    boolean              metamorphed;
03475    int                  num_elements_idx;
03476    long                 num_single_values;
03477    int                  num_single_values_idx;
03478    int                  num_values_idx;
03479    int                  result_type_idx;
03480    long_type            result_value[MAX_WORDS_FOR_NUMERIC];
03481    int                  subscript_ir_idx;
03482    int                  triplet_ir_idx;
03483    int                  t1_il_idx;
03484    int                  t2_il_idx;
03485 
03486 
03487    TRACE (Func_Entry, "imp_do_metamorphed", NULL);
03488 
03489    metamorphed           = FALSE;
03490    num_elements_idx      = CN_INTEGER_ONE_IDX;
03491    num_values_idx        = CN_INTEGER_ZERO_IDX;
03492    num_single_values     = 0;
03493    num_single_values_idx = CN_INTEGER_ZERO_IDX;
03494 
03495 
03496    /* 1. The innermost loop can only have a single target and all outer loops */
03497    /*    can only be used to drive the innermost loop (therefore, each loop   */
03498    /*    in the nest can only have a single target).                          */
03499 
03500    for (i = 1;  i <= last_lt_idx;  ++i) {
03501 
03502       if (loop_tbl[i].num_targets != 1) {
03503          goto EXIT;
03504       }
03505    }
03506 
03507 
03508    /* 2. The target must be of numeric or logical type.                       */
03509    /*                                                                         */
03510    /* 3. The target must be a simple array element reference.                 */
03511 
03512    subscript_ir_idx = IL_IDX(loop_tbl[last_lt_idx].target_list);
03513 
03514    if (IR_OPR(subscript_ir_idx) != Subscript_Opr  ||
03515        IR_FLD_L(subscript_ir_idx) != AT_Tbl_Idx) {
03516       goto EXIT;
03517    }
03518 
03519    attr_idx = IR_IDX_L(subscript_ir_idx);
03520 
03521    if (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Integer  &&
03522        TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Real     &&
03523        TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Complex  &&
03524        TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Logical) {
03525       goto EXIT;
03526    }
03527 
03528 
03529    /* 4. Each subscript in the array element reference must be an implied-DO  */
03530    /*    variable or a constant.                                              */
03531    /*                                                                         */
03532    /* 5. Each subscript that is an implied-DO variable must be in the same    */
03533    /*    order as the loop nest.                                              */
03534    /*                                                                         */
03535    /* 6. Every loop control expression of every loop in the nest must be      */
03536    /*    constant.                                                            */
03537 
03538    loops_match_bounds = TRUE;
03539    local_lt_idx       = last_lt_idx;
03540    il_idx             = IR_IDX_R(subscript_ir_idx);
03541 
03542 
03543    for (i = 1;  i <= IR_LIST_CNT_R(subscript_ir_idx);  ++i) {
03544    
03545       if (IL_FLD(il_idx) == AT_Tbl_Idx) {
03546       
03547          if (IL_IDX(il_idx) != loop_tbl[local_lt_idx].lcv_idx) {
03548             goto EXIT;
03549          }
03550 
03551          if (loop_tbl[local_lt_idx].start_fld == CN_Tbl_Idx  &&
03552              loop_tbl[local_lt_idx].end_fld   == CN_Tbl_Idx  &&
03553              loop_tbl[local_lt_idx].inc_fld   == CN_Tbl_Idx) {
03554 
03555             if (fold_relationals(loop_tbl[local_lt_idx].start_idx,
03556                                  BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), i),
03557                                  Ne_Opr)  ||
03558                 fold_relationals(loop_tbl[local_lt_idx].end_idx,
03559                                  BD_UB_IDX(ATD_ARRAY_IDX(attr_idx), i),
03560                                  Ne_Opr)  ||
03561                 fold_relationals(loop_tbl[local_lt_idx].inc_idx,
03562                                  CN_INTEGER_ONE_IDX,
03563                                  Ne_Opr)) {
03564                loops_match_bounds = FALSE;
03565             }
03566 
03567 
03568             /* Build an IR tree to calculate the number of times the loop     */
03569             /* will execute.                                                  */
03570 
03571             NTR_IR_TBL(iter_count_ir_idx);
03572             IR_OPR(iter_count_ir_idx)      = Minus_Opr;
03573             IR_TYPE_IDX(iter_count_ir_idx) = INTEGER_DEFAULT_TYPE;
03574             IR_LINE_NUM(iter_count_ir_idx) = stmt_start_line;
03575             IR_COL_NUM(iter_count_ir_idx)  = stmt_start_col;
03576             IR_FLD_L(iter_count_ir_idx)    = CN_Tbl_Idx;
03577             IR_IDX_L(iter_count_ir_idx)    = loop_tbl[local_lt_idx].end_idx;
03578             IR_LINE_NUM_L(iter_count_ir_idx) = stmt_start_line;
03579             IR_COL_NUM_L(iter_count_ir_idx)  = stmt_start_col;
03580             IR_FLD_R(iter_count_ir_idx)    = CN_Tbl_Idx;
03581             IR_IDX_R(iter_count_ir_idx)    = loop_tbl[local_lt_idx].start_idx;
03582             IR_LINE_NUM_R(iter_count_ir_idx) = stmt_start_line;
03583             IR_COL_NUM_R(iter_count_ir_idx)  = stmt_start_col;
03584 
03585             NTR_IR_TBL(ir_idx);
03586             IR_OPR(ir_idx)      = Plus_Opr;
03587             IR_TYPE_IDX(ir_idx) = INTEGER_DEFAULT_TYPE;
03588             IR_LINE_NUM(ir_idx) = stmt_start_line;
03589             IR_COL_NUM(ir_idx)  = stmt_start_col;
03590             IR_FLD_L(ir_idx)    = IR_Tbl_Idx;
03591             IR_IDX_L(ir_idx)    = iter_count_ir_idx;
03592             IR_FLD_R(ir_idx)    = CN_Tbl_Idx;
03593             IR_IDX_R(ir_idx)    = loop_tbl[local_lt_idx].inc_idx;
03594             IR_LINE_NUM_R(ir_idx) = stmt_start_line;
03595             IR_COL_NUM_R(ir_idx)  = stmt_start_col;
03596 
03597             NTR_IR_TBL(iter_count_ir_idx);
03598             IR_OPR(iter_count_ir_idx)      = Div_Opr;
03599             IR_TYPE_IDX(iter_count_ir_idx) = INTEGER_DEFAULT_TYPE;
03600             IR_LINE_NUM(iter_count_ir_idx) = stmt_start_line;
03601             IR_COL_NUM(iter_count_ir_idx)  = stmt_start_col;
03602             IR_FLD_L(iter_count_ir_idx)    = IR_Tbl_Idx;
03603             IR_IDX_L(iter_count_ir_idx)    = ir_idx;
03604             IR_FLD_R(iter_count_ir_idx)    = CN_Tbl_Idx;
03605             IR_IDX_R(iter_count_ir_idx)    = loop_tbl[local_lt_idx].inc_idx;
03606             IR_LINE_NUM_R(iter_count_ir_idx) = stmt_start_line;
03607             IR_COL_NUM_R(iter_count_ir_idx)  = stmt_start_col;
03608 
03609             OPND_FLD(expr_opnd) = IR_Tbl_Idx;
03610             OPND_IDX(expr_opnd) = iter_count_ir_idx;
03611 
03612             if (! expr_semantics(&expr_opnd, &expr_desc)) {
03613                PRINTMSG(IR_LINE_NUM(init_ir_idx), 857, Internal,
03614                         IR_COL_NUM(init_ir_idx));
03615             }
03616 
03617 
03618             /* Add in this loop's iteration count to the total.               */
03619  
03620             result_type_idx = INTEGER_DEFAULT_TYPE;
03621 
03622             if (folder_driver( (char *) &CN_CONST(num_elements_idx),
03623                                CN_TYPE_IDX(num_elements_idx),
03624                                (char *) &CN_CONST(OPND_IDX(expr_opnd)),
03625                                expr_desc.type_idx,
03626                                result_value,
03627                               &result_type_idx,
03628                                IR_LINE_NUM(init_ir_idx),
03629                                IR_COL_NUM(init_ir_idx),
03630                                2,
03631                                Mult_Opr)) {
03632                num_elements_idx = ntr_const_tbl(INTEGER_DEFAULT_TYPE,
03633                                                 FALSE,
03634                                                 result_value);
03635             }
03636             else {
03637                PRINTMSG(IR_LINE_NUM(init_ir_idx), 1024, Internal,
03638                         IR_COL_NUM(init_ir_idx));
03639             }
03640 
03641             --local_lt_idx;
03642          }
03643          else {
03644             goto EXIT;
03645          }
03646       }
03647       else if (IL_FLD(il_idx) == CN_Tbl_Idx) {
03648          loops_match_bounds = FALSE;
03649       }
03650       else {
03651          goto EXIT;
03652       }
03653 
03654       il_idx = IL_NEXT_LIST_IDX(il_idx);
03655    }
03656 
03657 
03658    /* 7. No value in the value list can be a long Hollerith or a character    */
03659    /*    constant.                                                            */
03660    /*                                                                         */
03661    /* The value can be a stand-alone value or it can be the object of a rep   */
03662    /* factor (the right operand of a Rep_Count IR).                           */
03663 
03664    il_idx = value_il_idx;
03665 
03666    while (il_idx != NULL_IDX) {
03667 
03668       if (IL_FLD(il_idx) == CN_Tbl_Idx) {
03669  
03670          if (TYP_TYPE(CN_TYPE_IDX(IL_IDX(il_idx))) != Character  &&
03671              TYP_LINEAR(CN_TYPE_IDX(IL_IDX(il_idx))) != Long_Typeless) {
03672             ++num_single_values;
03673          }
03674          else {
03675             goto EXIT;
03676          }
03677       }
03678       else if (IL_FLD(il_idx) == IR_Tbl_Idx) {
03679          ir_idx = IL_IDX(il_idx);
03680 
03681          if (IR_OPR(ir_idx) == Rep_Count_Opr) {
03682          
03683             if (IR_FLD_R(ir_idx) == CN_Tbl_Idx  &&
03684                 (TYP_TYPE(CN_TYPE_IDX(IR_IDX_R(ir_idx))) == Character  ||
03685                  TYP_LINEAR(CN_TYPE_IDX(IR_IDX_R(ir_idx))) == Long_Typeless)) {
03686                goto EXIT;
03687             }
03688 
03689             /* Add the repetition count to the total number of values.        */
03690  
03691             result_type_idx = INTEGER_DEFAULT_TYPE;
03692 
03693             if (folder_driver( (char *) &CN_CONST(num_values_idx),
03694                                CN_TYPE_IDX(num_values_idx),
03695                                (char *) &CN_CONST(IR_IDX_L(ir_idx)),
03696                                CN_TYPE_IDX(IR_IDX_L(ir_idx)),
03697                                result_value,
03698                               &result_type_idx,
03699                                IR_LINE_NUM(ir_idx),
03700                                IR_COL_NUM(ir_idx),
03701                                2,
03702                                Plus_Opr)) {
03703                num_values_idx = ntr_const_tbl(INTEGER_DEFAULT_TYPE,
03704                                               FALSE,
03705                                               result_value);
03706             }
03707             else {
03708                PRINTMSG(IL_LINE_NUM(il_idx), 1024, Internal,
03709                         IL_COL_NUM(il_idx));
03710             }
03711          }
03712          else {
03713 
03714             /* Assume it is a unary + or - operator.                          */
03715 
03716             if (TYP_TYPE(CN_TYPE_IDX(IR_IDX_L(ir_idx))) != Character  &&
03717                 TYP_LINEAR(CN_TYPE_IDX(IR_IDX_L(ir_idx))) != Long_Typeless) {
03718                ++num_single_values;
03719             }
03720             else {
03721                goto EXIT;
03722             }
03723          }
03724       }
03725 
03726       il_idx = IL_NEXT_LIST_IDX(il_idx);
03727    }
03728 
03729  
03730    /* 8. The number of array elements being initialized must be equal to the  */
03731    /*    the number of values in the value list.                              */
03732 
03733    num_single_values_idx = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
03734                                        num_single_values);
03735 
03736    if (num_single_values_idx != CN_INTEGER_ZERO_IDX  &&
03737        num_values_idx != CN_INTEGER_ZERO_IDX) {
03738  
03739       result_type_idx = INTEGER_DEFAULT_TYPE;
03740 
03741       if (folder_driver( (char *) &CN_CONST(num_single_values_idx),
03742                          CG_INTEGER_DEFAULT_TYPE,
03743                          (char *) &CN_CONST(num_values_idx),
03744                          CN_TYPE_IDX(num_values_idx),
03745                          result_value,
03746                          &result_type_idx,
03747                          IR_LINE_NUM(init_ir_idx),
03748                          IR_COL_NUM(init_ir_idx),
03749                          2,
03750                          Plus_Opr)) {
03751 
03752          num_values_idx = ntr_const_tbl(INTEGER_DEFAULT_TYPE,
03753                                         FALSE,
03754                                         result_value);
03755       }
03756       else {
03757          PRINTMSG(IR_LINE_NUM(init_ir_idx), 1024, Internal,
03758                   IR_COL_NUM(init_ir_idx));
03759       }
03760    }
03761 
03762    if (fold_relationals(num_values_idx, CN_INTEGER_ZERO_IDX, Eq_Opr)) {
03763       num_values_idx = num_single_values_idx;
03764    }
03765 
03766    if (fold_relationals(num_elements_idx, num_values_idx, Ne_Opr)) {
03767       goto EXIT;
03768    }
03769 
03770    
03771    /* If control gets here, all the rules have been met so the implied-DO can */
03772    /* be metamorphed.                                                         */
03773 
03774    metamorphed = TRUE;
03775 
03776    PRINTMSG(IR_LINE_NUM(init_ir_idx), 1021, Note, IR_COL_NUM(init_ir_idx));
03777 
03778    if (loops_match_bounds) {
03779 
03780       /* The loop can be transformed into a whole array initialization.       */
03781       /* If the implied-DO is the first item or the only item in the list,    */
03782       /* the Init IR's left operand will be pointing at the IL that in turn   */
03783       /* points at the implied-DO IR tree.  To fake out data_stmt_semantics,  */
03784       /* put the array name in the IL attached to the Init IR.                */
03785       /* If the implied-DO is NOT the first or the only item in the list, a   */
03786       /* new, empty Init IR was generated by data_stmt_semantics.  To fake    */
03787       /* out data_stmt_semantics, attach an IL to the Init IR's left operand  */
03788       /* and put the array name in the IL.                                    */
03789 
03790       if (IR_FLD_L(init_ir_idx) == NO_Tbl_Idx) {
03791          NTR_IR_LIST_TBL(IR_IDX_L(init_ir_idx));
03792          IR_LIST_CNT_L(init_ir_idx) = 1;
03793          IR_FLD_L(init_ir_idx)      = IL_Tbl_Idx;
03794 
03795       }
03796 
03797       IL_FLD(IR_IDX_L(init_ir_idx)) = AT_Tbl_Idx;
03798       IL_IDX(IR_IDX_L(init_ir_idx)) = attr_idx;
03799       IL_LINE_NUM(IR_IDX_L(init_ir_idx)) = IR_LINE_NUM(init_ir_idx);
03800       IL_COL_NUM(IR_IDX_L(init_ir_idx))  = IR_COL_NUM(init_ir_idx);
03801    }
03802    else {
03803 
03804       /* The loop can be transformed into an array section initialization.    */
03805       /* To fake out data_stmt_semantics, change the Subscript IR that's the  */
03806       /* target of the implied-DO into a section reference and attach it to   */
03807       /* the IL attached to the Init IR.                                      */
03808 
03809       IL_FLD(IR_IDX_L(init_ir_idx)) = IR_Tbl_Idx;
03810       IL_IDX(IR_IDX_L(init_ir_idx)) = subscript_ir_idx;
03811 
03812       local_lt_idx = last_lt_idx;
03813       il_idx       = IR_IDX_R(subscript_ir_idx);
03814 
03815       for (i = 1;  i <= IR_LIST_CNT_R(subscript_ir_idx);  ++i) {
03816 
03817          if (IL_FLD(il_idx) == AT_Tbl_Idx) {
03818             NTR_IR_TBL(triplet_ir_idx);
03819             IL_FLD(il_idx) = IR_Tbl_Idx;
03820             IL_IDX(il_idx) = triplet_ir_idx;
03821 
03822             IR_OPR(triplet_ir_idx)      = Triplet_Opr;
03823             IR_TYPE_IDX(triplet_ir_idx) = TYPELESS_DEFAULT_TYPE;
03824             IR_LINE_NUM(triplet_ir_idx) = IL_LINE_NUM(il_idx);
03825             IR_COL_NUM(triplet_ir_idx)  = IL_COL_NUM(il_idx);
03826             
03827             NTR_IR_LIST_TBL(t1_il_idx);
03828 
03829             IR_LIST_CNT_L(triplet_ir_idx) = 1;
03830             IR_FLD_L(triplet_ir_idx)      = IL_Tbl_Idx;
03831             IR_IDX_L(triplet_ir_idx)      = t1_il_idx;
03832 
03833             IL_LINE_NUM(t1_il_idx) = IL_LINE_NUM(il_idx);
03834             IL_COL_NUM(t1_il_idx)  = IL_COL_NUM(il_idx);
03835             IL_FLD(t1_il_idx)      = CN_Tbl_Idx;
03836             IL_IDX(t1_il_idx)      = loop_tbl[local_lt_idx].start_idx;
03837 
03838             NTR_IR_LIST_TBL(t2_il_idx);
03839 
03840             ++IR_LIST_CNT_L(triplet_ir_idx);
03841             IL_NEXT_LIST_IDX(t1_il_idx) = t2_il_idx;
03842             IL_PREV_LIST_IDX(t2_il_idx) = t1_il_idx;
03843 
03844             IL_LINE_NUM(t2_il_idx) = IL_LINE_NUM(il_idx);
03845             IL_COL_NUM(t2_il_idx)  = IL_COL_NUM(il_idx);
03846             IL_FLD(t2_il_idx)      = CN_Tbl_Idx;
03847             IL_IDX(t2_il_idx)      = loop_tbl[local_lt_idx].end_idx;
03848 
03849             t1_il_idx = t2_il_idx;
03850 
03851             NTR_IR_LIST_TBL(t2_il_idx);
03852 
03853             ++IR_LIST_CNT_L(triplet_ir_idx);
03854             IL_NEXT_LIST_IDX(t1_il_idx) = t2_il_idx;
03855             IL_PREV_LIST_IDX(t2_il_idx) = t1_il_idx;
03856 
03857             IL_LINE_NUM(t2_il_idx) = IL_LINE_NUM(il_idx);
03858             IL_COL_NUM(t2_il_idx)  = IL_COL_NUM(il_idx);
03859             IL_FLD(t2_il_idx)      = CN_Tbl_Idx;
03860             IL_IDX(t2_il_idx)      = loop_tbl[local_lt_idx].inc_idx;
03861 
03862             --local_lt_idx;
03863          }
03864 
03865          il_idx = IL_NEXT_LIST_IDX(il_idx);
03866       }
03867    }
03868 
03869 EXIT:
03870 
03871    TRACE (Func_Exit, "imp_do_metamorphed", NULL);
03872 
03873    return(metamorphed);
03874 
03875 }  /* imp_do_metamorphed */
03876 
03877 
03878 /******************************************************************************\
03879 |*                                                                            *|
03880 |* Description:                                                               *|
03881 |*   Interpret the DATA implied-DO to match its targets and values.           *|
03882 |*                                                                            *|
03883 |* Input parameters:                                                          *|
03884 |*      init_ir_idx : the index to the current Init IR                        *|
03885 |*                                                                            *|
03886 |* Output parameters:                                                         *|
03887 |*      NONE                                                                  *|
03888 |*                                                                            *|
03889 |* Returns:                                                                   *|
03890 |*      NONE                                                                  *|
03891 |*                                                                            *|
03892 \******************************************************************************/
03893 
03894 static void interpret_data_imp_do(int    init_ir_idx)
03895 {
03896 
03897    expr_arg_type        expr_desc;
03898    opnd_type            expr_opnd;
03899    boolean              first_offspring_imp_do;
03900    int                  i;
03901    long_type            loc_value[MAX_WORDS_FOR_NUMERIC];
03902    long64               num_iterations;
03903    int                  sister_idx;
03904    int                  target_il_idx;
03905 
03906 
03907    TRACE (Func_Entry, "interpret_data_imp_do", NULL);
03908 
03909 
03910    /* Save the guts of the lcv_idx attr.   Store them in a Constant entry     */
03911    /* pointed to by ATD_TMP_IDX(lcv_idx).                                     */
03912 
03913    GET_LCV_CONST(loop_tbl[lt_idx].lcv_idx, loc_value[0],  /* target const */
03914            num_host_wds[TYP_LINEAR(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx))]);
03915 
03916    ATD_FLD(loop_tbl[lt_idx].lcv_idx) = CN_Tbl_Idx;
03917    ATD_TMP_IDX(loop_tbl[lt_idx].lcv_idx) = 
03918                  ntr_const_tbl(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx),
03919                                FALSE,
03920                                loc_value);
03921 
03922 
03923    OPND_FLD(expr_opnd) = IR_Tbl_Idx;
03924 
03925    if (loop_tbl[lt_idx].start_fld == AT_Tbl_Idx) {
03926       loop_tbl[lt_idx].start_value =
03927          loop_tbl[loop_tbl[lt_idx].start_idx].curr_value;
03928    }
03929    else if (loop_tbl[lt_idx].start_fld == IR_Tbl_Idx) {
03930       OPND_IDX(expr_opnd) = loop_tbl[lt_idx].start_idx;
03931      
03932       expr_desc = arg_info_list[loop_tbl[lt_idx].start_expr_desc_idx].ed;
03933      
03934       if (! fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) {
03935          goto EXIT;
03936       }
03937 
03938       loop_tbl[lt_idx].start_value = CN_INT_TO_C(OPND_IDX(expr_opnd));
03939    }
03940 
03941    if (loop_tbl[lt_idx].end_fld == AT_Tbl_Idx) {
03942       loop_tbl[lt_idx].end_value =
03943          loop_tbl[loop_tbl[lt_idx].end_idx].curr_value;
03944    }
03945    else if (loop_tbl[lt_idx].end_fld == IR_Tbl_Idx) {
03946       OPND_IDX(expr_opnd) = loop_tbl[lt_idx].end_idx;
03947 
03948       expr_desc = arg_info_list[loop_tbl[lt_idx].end_expr_desc_idx].ed;
03949      
03950       if (! fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) {
03951          goto EXIT;
03952       }
03953 
03954       loop_tbl[lt_idx].end_value = CN_INT_TO_C(OPND_IDX(expr_opnd));
03955    }
03956 
03957    if (loop_tbl[lt_idx].inc_fld == AT_Tbl_Idx) {
03958       loop_tbl[lt_idx].inc_value =
03959          loop_tbl[loop_tbl[lt_idx].inc_idx].curr_value;
03960    }
03961    else if (loop_tbl[lt_idx].inc_fld == IR_Tbl_Idx) {
03962       OPND_IDX(expr_opnd) = loop_tbl[lt_idx].inc_idx;
03963      
03964       expr_desc = arg_info_list[loop_tbl[lt_idx].inc_expr_desc_idx].ed;
03965      
03966       if (! fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) {
03967          goto EXIT;
03968       }
03969 
03970       loop_tbl[lt_idx].inc_value = CN_INT_TO_C(OPND_IDX(expr_opnd));
03971    }
03972 
03973    num_iterations =
03974       (loop_tbl[lt_idx].end_value - loop_tbl[lt_idx].start_value +
03975        loop_tbl[lt_idx].inc_value) /
03976       loop_tbl[lt_idx].inc_value;
03977 
03978    if (num_iterations < 0) {
03979       num_iterations = 0;
03980    }
03981 
03982    if (num_iterations == 0) {
03983       goto EXIT;
03984    }
03985 
03986    for (loop_tbl[lt_idx].curr_value = loop_tbl[lt_idx].start_value;
03987         (loop_tbl[lt_idx].inc_value > 0) ?
03988            loop_tbl[lt_idx].curr_value <= loop_tbl[lt_idx].end_value :
03989            loop_tbl[lt_idx].curr_value >= loop_tbl[lt_idx].end_value;
03990         loop_tbl[lt_idx].curr_value += loop_tbl[lt_idx].inc_value) {
03991 
03992       C_TO_F_INT(loc_value, 
03993                  loop_tbl[lt_idx].curr_value,
03994                  TYP_LINEAR(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx)));
03995 
03996       SET_LCV_CONST(loop_tbl[lt_idx].lcv_idx, 
03997                     (loc_value[0]),
03998                     num_host_wds[TYP_LINEAR(ATD_TYPE_IDX(
03999                                           loop_tbl[lt_idx].lcv_idx))]);
04000 
04001       target_il_idx          = loop_tbl[lt_idx].target_list;
04002       first_offspring_imp_do = TRUE;
04003 
04004       for (i = 1;  i <= loop_tbl[lt_idx].num_targets;  ++i) {
04005       
04006          if (IR_OPR(IL_IDX(target_il_idx)) == Implied_Do_Opr) {
04007 
04008             /* If this is the first offspring that is an implied-DO, get the  */
04009             /* lt_idx from the offspring_idx field of the current loop_tbl    */
04010             /* entry and save the index to its sibling (which might be 0).    */
04011             /* Otherwise, use the saved sibling index to get to the next      */
04012             /* child of this implied-DO.                                      */
04013 
04014             if (first_offspring_imp_do) {
04015                lt_idx     = loop_tbl[lt_idx].offspring_idx; 
04016                sister_idx = loop_tbl[lt_idx].sibling_idx;
04017                first_offspring_imp_do = FALSE;
04018             }
04019             else {
04020                lt_idx     = sister_idx;
04021                sister_idx = loop_tbl[lt_idx].sibling_idx;
04022             }
04023 
04024 
04025             interpret_data_imp_do(init_ir_idx);
04026 
04027             if (SH_ERR_FLG(curr_stmt_sh_idx)) {
04028                goto EXIT;
04029             }
04030          }
04031          else {
04032 
04033             process_data_imp_do_target(init_ir_idx,
04034                                        target_il_idx,
04035                                        num_iterations);
04036 
04037             if (SH_ERR_FLG(curr_stmt_sh_idx)) {
04038                goto EXIT;
04039             }
04040 
04041             if (loop_tbl[lt_idx].num_targets == 1) {
04042                goto EXIT;
04043             }
04044          }
04045     
04046          target_il_idx = IL_NEXT_LIST_IDX(target_il_idx);
04047       }
04048    } 
04049 
04050 EXIT:
04051 
04052    /* Restore the guts of the LCV temp Attr.                                  */
04053 
04054    SET_LCV_CONST(loop_tbl[lt_idx].lcv_idx, 
04055                  CN_CONST(ATD_TMP_IDX(loop_tbl[lt_idx].lcv_idx)),
04056             num_host_wds[TYP_LINEAR(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx))]);
04057 
04058    lt_idx = loop_tbl[lt_idx].parent_idx;
04059 
04060    TRACE (Func_Exit, "interpret_data_imp_do", NULL);
04061 
04062    return;
04063 
04064 }  /* interpret_data_imp_do */
04065 
04066 
04067 /******************************************************************************\
04068 |*                                                                            *|
04069 |* Description:                                                               *|
04070 |*   See enormously long description below.                                   *|
04071 |*                                                                            *|
04072 |*                                                                            *|
04073 |* Input parameters:                                                          *|
04074 |*      init_ir_idx    : the index of the Init IR                             *|
04075 |*      target_il_idx  : IL index of current target                           *|
04076 |*      num_iterations : the number of times the current implied-DO will be   *|
04077 |*                      executed                                              *|
04078 |*                                                                            *|
04079 |* Output parameters:                                                         *|
04080 |*      NONE                                                                  *|
04081 |*                                                                            *|
04082 |* Returns:                                                                   *|
04083 |*      NONE                                                                  *|
04084 |*                                                                            *|
04085 \******************************************************************************/
04086 
04087 /******************************************************************************\
04088                                  N O T E S
04089 
04090   Among the basic design tenets of DATA processing are the following which 
04091   directly relate to the relationship between the Semantics Pass and the 
04092   (PDGCS) Interface:
04093 
04094     * The Interface expects each implied-DO target to have a corresponding 
04095       value.  This means that the Semantics Pass must ensure that the *number*
04096       of targets matches the number of values.
04097 
04098     * The Interface should not have to contend with DATA statement semantics
04099       (error checking).  This means that the Semantics Pass must ensure that
04100       the *type* of each value is suitable for assignment to the corresponding
04101       target.
04102 
04103   Normally, this is relatively straightforward because this relationship   
04104   (expectations) between the Interface and the Semantics Pass reflects the 
04105   standard.  However, CF77 has an extension that allows a long string (either
04106   a Hollerith or character literal constant) to be assigned piecemeal to 
04107   targets of an implied-DO or array initialization.  This procedure
04108   (process_data_imp_do_target) exists to match a target with a value (in some
04109   cases match a number of targets with a number of values) and to ensure that
04110   the target(s) and value(s) are assignment compatible.  (CF77 only allows
04111   initialization of multiple word-length items with long string constants.
04112   This means, for example, that double precision and complex items can *not*
04113   be initialized with a long string.  And CF77 only allows initialization of
04114   word-length targets with word-length (or less) values, so, for example, a
04115   double precision variable can not be initialized with a character/Hollerith
04116   constant.  CF90 relaxes the latter rule in 2.0 and beyond because programs
04117   exist that are intended to be run on 32-bit machines and that initialize
04118   multi-word numeric items with Hollerith strings.  However, CF90 will *not*
04119   enhance the "long string" extension to work with multi-word targets.  And
04120   since CF77 does not support array section notation in DATA statements, CF90
04121   does *not* support initialization of array sections with long strings.  And
04122   finally, since CF77 does not support initialization on type declaration
04123   statements, CF90 does *not* support the "long string" extension in that
04124   context either.
04125 
04126   Since a long string can be split up among arbitrary implied-DO targets,
04127   a number of the bookkeeping variables like value_count are
04128   static, wither by being global to this file or static in this procedure.
04129   For whole array initialization, the long string is *not* split across 
04130   multiple targets.  This means you can *not* do the following:
04131 
04132        integer i(2), k(2)
04133        data i, k  /'abcdef123456ABCDEF654321'/
04134 
04135   The long string is broken down into word-size pieces and each piece is
04136   reentered into the Constant Table.  Note that the last piece may be less
04137   than a word in length.  If the implied-DO does not finish off the long
04138   string, the remainder is set up as the next value (for the target 
04139   following the implied-DO) by data_imp_do_semantics (when the (outermost)
04140   implied-DO is completely finished).  This is not done for whole array 
04141   initialization.  That is, the "remainder" is not passed on to another 
04142   variable.  The value must break down into the number of values required by
04143   the target array (except if the array is the last thing in the list, in
04144   which case another CRI extension is invoked whereby the last array in the
04145   list need not be completely initialized).
04146 
04147   The following general rule was deduced from CF77 by running variations on a
04148   number of programs:
04149 
04150        A long string can be utilized by any combination of numeric targets
04151        at any level of nesting.  The string can slop over onto an 
04152        initialization following the implied-DO.  The initialization rules
04153        for the item following the implied-DO are then in effect.
04154 
04155   There is a minor difference between the CF77 and CF90 implementations of
04156   the "long string" extension.  In an initialization of the form:
04157 
04158             INTEGER array(3)
04159             DATA (array(i), i = 1, 3), k  /2 * 16H1234567887654321/
04160 
04161   CF77 issues an error message saying that there are too few values because
04162   it does not use whatever is left over in the string when the implied-DO
04163   completes IF THERE IS A REP FACTOR PRESENT.  If the example was written as:
04164 
04165             INTEGER array(2)
04166             DATA (array(i), i = 1, 2), k  /24H1234567887654321zzzzzzzz/
04167 
04168   CF77 WOULD use the remaining part of the string as the value to be assigned
04169   to K.  CF90 always uses all of the string in a consistent manner.
04170 
04171 
04172   This procedure has two basic processing sections:
04173 
04174     * If the current implied-DO (which may be an inner implied-DO of a 
04175       nested set) has only a single target (a typical case so it's worth
04176       the optimization), control remains in this procedure for all of the
04177       iterations of the current implied-DO.  That is, this routine will 
04178       continue advancing through the values until the current implied-DO
04179       runs out of targets.  For example,
04180 
04181            CHARACTER*8  array(4096)
04182            DATA (array(i), i = 1, 4096)
04183           &     /1000*'a', 1000*'b', 1000*'c', 1000*'d', 96*' '/
04184 
04185       This procedure will process the entire value list for the implied-DO
04186       before it returns to interpret_data_imp_do.  This is also true for 
04187       the inner loop of an example of the form:
04188 
04189            INTEGER  k1(10,10), k2(10)
04190            DATA ((k1(i,j), i = 1, 10), k2(j), j = 1, 10) /500*0, 500*1/
04191 
04192       That is, 10 values will be processed for K1 then control will return.
04193       When this procedure is entered again, a single value will be processed
04194       for K2.  And when the procedure is entered for the third time, another
04195       10 values will be processed for K1 and so on.
04196 
04197     * Otherwise, the current implied-DO has more than one target.  "More 
04198       than one target" means a single implied-DO loop has multiple array
04199       element targets or an implied-DO contains at least one nested 
04200       implied-DO.  For these cases, this procedure is called once for each
04201       target (which is why the case above that checks for a single target
04202       exists:  to reduce the number of calls to this procedure).  
04203 
04204 \******************************************************************************/
04205 static void process_data_imp_do_target(int      init_ir_idx,
04206                                        int      target_il_idx,
04207                                        long64   num_iterations)
04208 {
04209            opnd_type    ignore_this_opnd;
04210            int          il_idx;
04211            boolean      long_value;
04212            int          ir_idx;
04213            opnd_type    rep_factor_opnd;
04214            int          target_attr_idx;
04215            boolean      word_size_target;
04216 
04217 
04218    TRACE (Func_Entry, "process_data_imp_do_target", NULL);
04219 
04220    ir_idx = IL_IDX(target_il_idx);
04221 
04222    if (IR_OPR(ir_idx) == Whole_Substring_Opr  ||
04223        IR_OPR(ir_idx) == Substring_Opr) {
04224       ir_idx = IR_IDX_L(ir_idx);
04225    }
04226   
04227    /* Section_Subscript_Opr gets into the act if this is a compiler-gen'd     */
04228    /* implied-DO to represent an array initialization where the array has at  */
04229    /* one vector valued subscript.                                            */
04230  
04231    if (IR_OPR(ir_idx) == Subscript_Opr  ||
04232        IR_OPR(ir_idx) == Section_Subscript_Opr) {
04233        
04234       /* Subscript must be pointing at Attr entry or Struct IR.               */
04235 
04236       target_attr_idx = (IR_FLD_L(ir_idx) == AT_Tbl_Idx) ?
04237                         IR_IDX_L(ir_idx) : IR_IDX_R(IR_IDX_L(ir_idx));
04238    }
04239    else {
04240       target_attr_idx = IR_IDX_R(ir_idx);            /* Must be Struct IR. */
04241    }
04242 
04243    if (loop_tbl[lt_idx].num_targets == 1) {
04244 
04245       /* Implied-DO contains a single target.  Process all iterations of this */
04246       /* implied-DO.                                                          */
04247 
04248       obj_count = num_iterations * loop_tbl[lt_idx].num_targets;
04249 
04250       while (obj_count > 0) {
04251 
04252          if (rep_factor == 0) {
04253             set_global_value_variables(&rep_factor_opnd, 
04254                                        &ignore_this_opnd, 
04255                                        target_attr_idx);
04256 
04257             if (SH_ERR_FLG(curr_stmt_sh_idx)) {
04258                goto EXIT;
04259             }
04260 
04261             ++IR_LIST_CNT_R(init_ir_idx);
04262          }
04263 
04264             word_size_target = FALSE;
04265 
04266             if (TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)) ==
04267                    INTEGER_DEFAULT_TYPE                         ||
04268                 TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)) ==
04269                    REAL_DEFAULT_TYPE) {
04270 
04271                if (storage_bit_size_tbl[
04272                       TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx))] ==
04273                          TARGET_BITS_PER_WORD) {
04274                   word_size_target = TRUE;
04275                }
04276             }
04277 
04278             long_value = FALSE;
04279 
04280             if (value_desc.type == Typeless) {
04281                if (TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) >
04282                       TARGET_BITS_PER_WORD) {
04283                   long_value = TRUE;
04284                }
04285             }
04286             else if (value_desc.type == Character) {
04287 
04288                if (CN_INT_TO_C(TYP_IDX(value_desc.type_idx)) >
04289                       TARGET_CHARS_PER_WORD) {
04290                   long_value = TRUE;
04291                }
04292             }
04293 
04294             if (word_size_target  &&  long_value) { 
04295                PRINTMSG(OPND_LINE_NUM(value_opnd), 733, Error,
04296                         OPND_COL_NUM(value_opnd));
04297 
04298                --IR_LIST_CNT_R(init_ir_idx);
04299 
04300 
04301                /* Hollerith constants are always a word multiple in length.   */
04302                /*  They are padded on the right or on the left with blanks    */
04303                /* or nulls, depending on the Hollerith specifier.             */
04304 
04305                if (TYP_TYPE(CN_TYPE_IDX(OPND_IDX(value_opnd))) == Typeless) {
04306                   ls_word_len =
04307                      TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) /
04308                      TARGET_BITS_PER_WORD;
04309                }
04310                else {
04311                   ls_word_len =
04312                      CN_INT_TO_C(TYP_IDX(CN_TYPE_IDX(OPND_IDX(value_opnd)))) /
04313                      TARGET_CHARS_PER_WORD;
04314 
04315                   if ((long)
04316                       CN_INT_TO_C(TYP_IDX(CN_TYPE_IDX(OPND_IDX(value_opnd)))) %
04317                          TARGET_CHARS_PER_WORD) {
04318                      ++ls_word_len;
04319                   }
04320                }
04321             }
04322 
04323             check_target_and_value(target_attr_idx, init_ir_idx);
04324 
04325             if (SH_ERR_FLG(curr_stmt_sh_idx)) {
04326                goto EXIT;
04327             }
04328 
04329             if (obj_count == rep_factor) {
04330                obj_count  = 0;
04331                rep_factor = 0;
04332 
04333                if (IL_FLD(value_il_idx) == CN_Tbl_Idx) {
04334                   IL_IDX(value_il_idx) = OPND_IDX(value_opnd);
04335                }
04336                else {
04337                   IR_IDX_R(IL_IDX(value_il_idx)) = OPND_IDX(value_opnd);
04338                }
04339 
04340                value_il_idx = IL_NEXT_LIST_IDX(value_il_idx);
04341             }
04342             else if (obj_count > rep_factor) {
04343                obj_count  -= rep_factor;
04344                rep_factor  = 0;
04345 
04346                if (IL_FLD(value_il_idx) == CN_Tbl_Idx) {
04347                   IL_IDX(value_il_idx) = OPND_IDX(value_opnd);
04348                }
04349                else {
04350                   IR_IDX_R(IL_IDX(value_il_idx)) = OPND_IDX(value_opnd);
04351                }
04352 
04353                value_il_idx = IL_NEXT_LIST_IDX(value_il_idx);
04354 
04355                if (value_il_idx == NULL_IDX) {
04356                   PRINTMSG(IR_LINE_NUM(init_ir_idx), 667, Error,
04357                            IR_COL_NUM(init_ir_idx));
04358                   goto EXIT;
04359                }
04360             }
04361             else {
04362 
04363                /* This case (where there are values left over) is taken care  */
04364                /* of upon return to data_imp_do_semantics.                    */
04365 
04366                rep_factor -= obj_count;
04367                obj_count   = 0;
04368             }
04369       }
04370    }
04371    else {
04372     
04373       /* Implied-DO has more than one target.  Process only the current       */
04374       /* target.                                                              */
04375 
04376       if (rep_factor == 0) {
04377          set_global_value_variables(&rep_factor_opnd, 
04378                                     &ignore_this_opnd, 
04379                                     target_attr_idx);
04380 
04381          if (SH_ERR_FLG(curr_stmt_sh_idx)) {
04382             goto EXIT;
04383          }
04384 
04385          ++IR_LIST_CNT_R(init_ir_idx);
04386       }
04387 
04388       /* CRI extension:  (same as described above)                            */
04389       if ((TYP_TYPE(ATD_TYPE_IDX(target_attr_idx)) == Integer  ||
04390            TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)) == REAL_DEFAULT_TYPE) &&
04391            (value_desc.linear_type == Long_Typeless || 
04392             (CN_HOLLERITH_TYPE(OPND_IDX(value_opnd)) != Not_Hollerith &&
04393              TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) >
04394                                                     TARGET_BITS_PER_WORD) ||
04395            (value_desc.type == Character  &&
04396             CN_INT_TO_C(TYP_IDX(value_desc.type_idx)) > 
04397                                           TARGET_CHARS_PER_WORD))){
04398 
04399          PRINTMSG(OPND_LINE_NUM(value_opnd), 
04400                   733, Error,
04401                   OPND_COL_NUM(value_opnd));
04402       }
04403 
04404       check_target_and_value(target_attr_idx, init_ir_idx);
04405 
04406       if (rep_factor == 1) {
04407          rep_factor   = 0;
04408          value_il_idx = IL_NEXT_LIST_IDX(value_il_idx);
04409       }
04410       else {                                        /* rep_factor must be > 1 */
04411          --rep_factor;
04412       }
04413    }
04414 
04415 EXIT:
04416 
04417    /* In order to get an IR display, restore the correct value in             */
04418    /* IR_LIST_CNT_R (because it was set to 1 earlier and in the normal case   */
04419    /* will be incremented as each value IL is used).                          */
04420 
04421    if (SH_ERR_FLG(curr_stmt_sh_idx)) {
04422       il_idx = IR_IDX_R(init_ir_idx);
04423       IR_LIST_CNT_R(init_ir_idx) = 1;
04424 
04425       while (IL_NEXT_LIST_IDX(il_idx) != NULL_IDX) {
04426          il_idx = IL_NEXT_LIST_IDX(il_idx);
04427          ++IR_LIST_CNT_R(init_ir_idx);
04428       }
04429    }
04430 
04431    TRACE (Func_Exit, "process_data_imp_do_target", NULL);
04432 
04433    return;
04434 
04435 }  /* process_data_imp_do_target */
04436 
04437 
04438 /******************************************************************************\
04439 |*                                                                            *|
04440 |* Description:                                                               *|
04441 |*      Verify that the target and value are assignment compatible.  If the   *|
04442 |*      target is type character and the value is shorter than the target,    *|
04443 |*      calculate the number of padding blanks needed.                        *|
04444 |*                                                                            *|
04445 |*      This routine is extern'd (in globals.h) so that the implied-DO code   *|
04446 |*      in the PDGCS interface can call it.                                   *|
04447 |*                                                                            *|
04448 |* Input parameters:                                                          *|
04449 |*      attr_idx : the target's Attr table index                              *|
04450 |*                                                                            *|
04451 |* Output parameters:                                                         *|
04452 |*      NONE                                                                  *|
04453 |*                                                                            *|
04454 |* Returns:                                                                   *|
04455 |*      TRUE if the target and value are compatible.                          *|
04456 |*                                                                            *|
04457 \******************************************************************************/
04458 
04459 static boolean check_target_and_value(int       attr_idx,
04460                                       int       init_ir_idx)
04461 
04462 {
04463    long_type    another_constant[MAX_WORDS_FOR_NUMERIC];
04464    int          column;
04465    int          line;
04466    boolean      result                  = TRUE;
04467    int          type_idx;
04468 
04469 
04470    TRACE (Func_Entry, "check_target_and_value", NULL);
04471 
04472    if (value_desc.linear_type == Long_Typeless) { 
04473       PRINTMSG(OPND_LINE_NUM(value_opnd), 1133, Error,
04474                OPND_COL_NUM(value_opnd));
04475       result = FALSE;
04476       goto EXIT;
04477    }
04478 
04479    if (check_asg_semantics(ATD_TYPE_IDX(attr_idx),
04480                            value_desc.type_idx,
04481                            OPND_LINE_NUM(value_opnd),
04482                            OPND_COL_NUM(value_opnd))) {
04483 
04484       if ((ATD_POINTER(attr_idx) &&
04485            (OPND_FLD(value_opnd) != IR_Tbl_Idx ||
04486             IR_OPR(OPND_IDX(value_opnd)) != Null_Intrinsic_Opr)) ||
04487 
04488           (!ATD_POINTER(attr_idx) &&
04489            OPND_FLD(value_opnd) == IR_Tbl_Idx &&
04490            IR_OPR(OPND_IDX(value_opnd)) == Null_Intrinsic_Opr)) {
04491          find_opnd_line_and_column(&value_opnd, &line, &column);
04492          PRINTMSG(line, 1559, Error, column);
04493       }
04494 
04495       if (ATD_POINTER(attr_idx) &&
04496           OPND_FLD(value_opnd) == IR_Tbl_Idx &&
04497           IR_OPR(OPND_IDX(value_opnd)) == Null_Intrinsic_Opr) {
04498          IR_OPR(init_ir_idx) = Null_Opr;
04499       }
04500 
04501       if (CN_BOZ_CONSTANT(OPND_IDX(value_opnd))  &&
04502           TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Integer) {
04503 
04504          PRINTMSG(OPND_LINE_NUM(value_opnd), 729, Ansi,
04505                   OPND_COL_NUM(value_opnd), 
04506                   AT_OBJ_NAME_PTR(attr_idx));
04507       }
04508 
04509       if ((TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Character  &&  
04510            value_desc.type == Character) ||
04511           value_desc.linear_type == Short_Typeless_Const) {
04512 
04513          /* Cast the typeless or character (boolean) constant to the */
04514          /* type of the target.                                      */
04515 
04516          OPND_IDX(value_opnd) = cast_typeless_constant(OPND_IDX(value_opnd),
04517                                                     ATD_TYPE_IDX(attr_idx),
04518                                                     OPND_LINE_NUM(value_opnd),
04519                                                     OPND_COL_NUM(value_opnd));
04520          value_desc.type        = TYP_TYPE(ATD_TYPE_IDX(attr_idx));
04521          value_desc.type_idx    = ATD_TYPE_IDX(attr_idx);
04522          value_desc.linear_type = TYP_LINEAR(ATD_TYPE_IDX(attr_idx));
04523       }
04524       else if (TYP_LINEAR(value_desc.type_idx) != 
04525                               TYP_LINEAR(ATD_TYPE_IDX(attr_idx))   &&
04526                TYP_TYPE(value_desc.type_idx) != Character          &&
04527                TYP_TYPE(value_desc.type_idx) != Typeless           &&
04528                TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != CRI_Ptr         &&
04529                TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != CRI_Parcel_Ptr  &&
04530                TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != CRI_Ch_Ptr) {
04531 
04532          /* PDGCS does not like it if the value is not the same size as the   */
04533          /* target; for example, the value is a double precision constant and */
04534          /* the target is a single precision variable.  So explicitly convert */
04535          /* the value to the type and kind type parameter of the target for   */
04536          /* all combinations to be consistent.                                */
04537 
04538          type_idx = ATD_TYPE_IDX(attr_idx);
04539 
04540          if (folder_driver( (char *) &CN_CONST(OPND_IDX(value_opnd)),
04541                             value_desc.type_idx,
04542                             NULL,
04543                             NULL_IDX,
04544                             another_constant,
04545                            &type_idx,
04546                             OPND_LINE_NUM(value_opnd),
04547                             OPND_COL_NUM(value_opnd),
04548                             1,
04549                             Cvrt_Opr)) {
04550 
04551             value_desc.type_idx    = type_idx;
04552             value_desc.linear_type = TYP_LINEAR(type_idx);
04553             value_desc.type        = TYP_TYPE(type_idx);
04554             OPND_IDX(value_opnd)   = ntr_const_tbl(ATD_TYPE_IDX(attr_idx),
04555                                                    FALSE,
04556                                                    another_constant);
04557          }
04558       }
04559    }
04560    else {
04561       find_opnd_line_and_column(&value_opnd, &line, &column);
04562       PRINTMSG(line, 97, Error, column, AT_OBJ_NAME_PTR(attr_idx));
04563       result = FALSE;
04564    }
04565 
04566 EXIT:
04567 
04568    TRACE (Func_Exit, "check_target_and_value", NULL);
04569 
04570    return(result);
04571 
04572 }  /* check_target_and_value" */
04573 
04574 
04575 /******************************************************************************\
04576 |*                                                                            *|
04577 |* Description:                                                               *|
04578 |*      Make sure the character-valued initialization value is the same       *|
04579 |*      length as the target.  If necessary, generate a secondary DATA stmt   *|
04580 |*      to blank pad the initialization value.                                *|
04581 |*                                                                            *|
04582 |* Input parameters:                                                          *|
04583 |*      init_ir_idx         : the index of the Init IR                        *|
04584 |*      array_ir_idx        : contains an IR index only if the target is an   *|
04585 |*                            array                                           *|
04586 |*      section_start_value : if the target is a section, this is the current *|
04587 |*                            value of the first section triplet subscript    *|
04588 |*      section_inc_value   : if the target is a section, this is inc value   *|
04589 |*                            in the first section triplet subscript          *|
04590 |*                                                                            *|
04591 |* Output parameters:                                                         *|
04592 |*      NONE                                                                  *|
04593 |*                                                                            *|
04594 |* Returns:                                                                   *|
04595 |*      NONE                                                                  *|
04596 |*                                                                            *|
04597 \******************************************************************************/
04598 
04599 static void adjust_char_value_len(int           init_ir_idx,
04600                                   int           array_ir_idx,
04601                                   long64        section_start_value,
04602                                   long64        section_inc_value)
04603 {
04604 
04605    int          end_il_idx;
04606    long64       i;
04607    int          il_idx;
04608    int          imp_do_ir_idx;
04609    int          inc_il_idx;
04610    int          ir_idx;
04611    int          new_init_ir_idx;
04612    int          new_str_idx;
04613    char        *new_str_ptr;
04614    long64       numeric_value;
04615    char        *old_str_ptr;
04616    opnd_type    opnd;
04617    int          original_end_il_idx;
04618    long64       original_end_val;
04619    long64       original_start_val;
04620    long64       rep_count;
04621    int          rep_count_il_idx;
04622    int          rep_count_ir_idx;
04623    int          start_il_idx;
04624    int          substring_ir_idx;
04625    long64       target_length;
04626    int          temp_idx;
04627    int          type_idx;
04628    int          value_idx;
04629    long64       value_length;
04630 
04631 
04632    /* -------------------  Problematic code warning  ------------------------ */
04633    /*                                                                         */
04634    /* By design, each entry in the Constant Table must start on a word        */
04635    /* boundary.  The following declaration pushes the single character        */
04636    /* value to the LEFT end of the word.  Some architectures may prefer it    */
04637    /* to be on the right end so someone may later have to ifdef the following */
04638    /* declaration to work on those other architectures.        LRR            */
04639    /*                                                                         */
04640    /* -------------------  Problematic code warning  ------------------------ */
04641 
04642 
04643   
04644 # if defined(_HOST_LITTLE_ENDIAN)
04645    long_type    single_blank    = (long_type)' ';
04646 #else
04647    long_type    single_blank    = (long_type)' ' << 
04648                                        (sizeof(long_type)*CHAR_BIT - CHAR_BIT);
04649 # endif
04650 
04651 
04652    TRACE (Func_Entry, "adjust_char_value_len", NULL);
04653 
04654    substring_ir_idx    = IR_IDX_L(init_ir_idx);
04655    il_idx              = IR_IDX_R(substring_ir_idx);
04656    original_start_val  = CN_INT_TO_C(IL_IDX(il_idx));
04657    original_end_il_idx = IL_NEXT_LIST_IDX(il_idx);
04658    original_end_val    = CN_INT_TO_C(IL_IDX(original_end_il_idx));
04659    target_length       = original_end_val - original_start_val + 1;
04660 
04661    if (target_length > 0) {
04662       value_idx    = IL_IDX(IR_IDX_R(init_ir_idx));
04663       value_length = CN_INT_TO_C(TYP_IDX(CN_TYPE_IDX(value_idx)));
04664 
04665       if (target_length == value_length) {
04666          goto EXIT;
04667       }
04668 
04669       if (target_length < value_length) {
04670 
04671          /* Need to replace the initialization value with a shorter length    */
04672          /* string to match the length of the target.                         */
04673          
04674          CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX);
04675          TYP_TYPE(TYP_WORK_IDX)       = Character;
04676          TYP_LINEAR(TYP_WORK_IDX)     = CHARACTER_DEFAULT_TYPE;
04677          TYP_CHAR_CLASS(TYP_WORK_IDX) = Const_Len_Char;
04678          TYP_FLD(TYP_WORK_IDX)        = CN_Tbl_Idx;
04679          TYP_IDX(TYP_WORK_IDX)        = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04680                                                     target_length);
04681          type_idx                     = ntr_type_tbl();
04682 
04683          /* Call ntr_const_tbl with NULL for the incoming constant so it will */
04684          /* just allocate the amount of space needed.  Copy the original      */
04685          /* string to the new string by hand.                                 */
04686          /* Replace the value's Constant table index with the Constant table  */
04687          /* index of the shortened string.                                    */
04688 
04689          new_str_idx = ntr_const_tbl(type_idx, TRUE, NULL);
04690          new_str_ptr = (char *) &CN_CONST(new_str_idx);  /* KAYKAY */
04691          old_str_ptr = (char *) &CN_CONST(value_idx);
04692 
04693          for (i = 0;  i < target_length;  i++) {
04694             new_str_ptr[i] = old_str_ptr[i];
04695          }
04696 
04697          while (target_length % TARGET_BYTES_PER_WORD != 0) {
04698             new_str_ptr[target_length] = ' ';
04699             target_length++;
04700          }
04701 
04702          IL_IDX(IR_IDX_R(init_ir_idx)) = new_str_idx;
04703       }
04704       else {
04705 
04706          /* Future optimizations:                                             */
04707          /*  - If the target is a scalar and the value is "small", reenter    */
04708          /*    the constant with blank padding rather than generating the     */
04709          /*    implied-DO to do the blank padding.                            */
04710          /*  - If the value is a zero-length constant, no tree duplication    */
04711          /*    needs to be done.                                              */
04712          /*                                                                   */
04713          /* Must do blank padding.  There are two ways to do this:            */
04714          /*   (a) generate a new value (char constant) that is the same       */
04715          /*       length as the target and is blank padded, or                */
04716          /*   (b) generate an implied-DO to do the blank padding.  For the    */
04717          /*       array case, the implied-DO makes a second pass through the  */
04718          /*       array (after the value is assigned to each element via      */
04719          /*       whole array or section initialization) adding the blanks.   */
04720          /* It is a design trade-off for array initialization between eating  */
04721          /* up time by running through an implied-DO in the interface vs.     */
04722          /* potentially eating up a lot of CN table space if a number of new  */
04723          /* character constants need to be built.  The "if" stmt below        */
04724          /* controls when we'll switch from the implied-DO method to the new  */
04725          /* constant method.  As it stands now, there is both an array element*/
04726          /* count threshhold and an array element length threshhold.  As we   */
04727          /* learn more about trade-offs between the implied-DO method and the */
04728          /* new constant method, the threshholds can easily be changed.  They */
04729          /* are currently set to switch to the new constant method if at      */
04730          /* least 100 array elements are being initialized where the length   */
04731          /* of each element is no more than 256 characters.  The numbers were */
04732          /* essentially chosen at random but with an eye to performance on    */
04733          /* both Crays and workstations.                                      */
04734       
04735          rep_count_il_idx = IL_NEXT_LIST_IDX(IR_IDX_R(init_ir_idx));
04736          rep_count        = CN_INT_TO_C(IL_IDX(rep_count_il_idx));
04737 
04738          if (array_ir_idx != NULL_IDX  &&  rep_count >= 100  &&
04739              target_length <= 256) {
04740 
04741             CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX);
04742             TYP_TYPE(TYP_WORK_IDX)      = Character;
04743             TYP_LINEAR(TYP_WORK_IDX)    = CHARACTER_DEFAULT_TYPE;
04744             TYP_CHAR_CLASS(TYP_WORK_IDX)= Const_Len_Char;
04745             TYP_FLD(TYP_WORK_IDX)       = CN_Tbl_Idx;
04746             TYP_IDX(TYP_WORK_IDX)       = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04747                                                       target_length);
04748             type_idx                    = ntr_type_tbl();
04749 
04750             /* Call ntr_const_tbl with NULL for the incoming constant so it   */
04751             /* will just allocate the amount of space needed.  Copy the       */
04752             /* original string to the new string by hand and blank pad the    */
04753             /* new string by hand.                                            */
04754             /* Replace the value's Constant table index with the Constant     */
04755             /* table index of the padded string.                              */
04756 
04757             new_str_idx = ntr_const_tbl(type_idx, TRUE, NULL);
04758             new_str_ptr = (char *) &CN_CONST(new_str_idx);
04759             old_str_ptr = (char *) &CN_CONST(value_idx);
04760 
04761             for (i = 0;  i < value_length;  i++) {
04762                new_str_ptr[i] = old_str_ptr[i];
04763             }
04764 
04765             for (i = value_length;  i < target_length;  i++) {
04766                new_str_ptr[i] = ' ';
04767             }
04768 
04769             while (target_length % TARGET_BYTES_PER_WORD != 0) {
04770                new_str_ptr[target_length] = ' ';
04771                target_length++;
04772             }
04773 
04774             IL_IDX(IR_IDX_R(init_ir_idx)) = new_str_idx;
04775          }
04776          else {
04777 
04778             /* Use the implied-DO method.                                     */
04779             /*   - Generate a DATA stmt SH following the current SH.          */
04780             /*   - Change the substring operator to Substring_Opr in case it  */
04781             /*     was originally Whole_Substring_Opr.                        */
04782             /*   - If a single target is being initialized, the original      */
04783             /*     initialization IR tree can be duplicated and altered to do */
04784             /*     blank padding.  Otherwise, the padding must be done by     */
04785             /*     generating implied-DO IR.                                  */
04786 
04787             gen_sh(After, Data_Stmt,
04788                    IR_LINE_NUM(init_ir_idx), IR_COL_NUM(init_ir_idx),
04789                    FALSE, FALSE, TRUE);
04790 
04791             if (rep_count == 1) {
04792                gen_opnd(&opnd, init_ir_idx, IR_Tbl_Idx, 
04793                         IR_LINE_NUM(init_ir_idx),
04794                         IR_COL_NUM(init_ir_idx));
04795 
04796                copy_subtree(&opnd, &opnd);
04797                new_init_ir_idx = OPND_IDX(opnd);
04798                SH_IR_IDX(curr_stmt_sh_idx) = new_init_ir_idx;
04799 
04800                substring_ir_idx            = IR_IDX_L(new_init_ir_idx);
04801                IR_OPR(substring_ir_idx)    = Substring_Opr;
04802 
04803                /* In the new tree, replace the value's Constant table index   */
04804                /* with the Constant table index of a single blank.            */
04805 
04806                il_idx         = IR_IDX_R(new_init_ir_idx);
04807                IL_IDX(il_idx) = ntr_const_tbl(CHARACTER_DEFAULT_TYPE,
04808                                               FALSE,
04809                                               (long_type *) &single_blank);
04810 
04811                /* In the new tree, update the rep count.                      */
04812 
04813                il_idx         = IL_NEXT_LIST_IDX(il_idx);
04814                numeric_value  = target_length - value_length;
04815                IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04816                                             numeric_value);
04817 
04818                /* In the new tree, set the stride to 8 (bits).                */
04819 
04820                il_idx         = IL_NEXT_LIST_IDX(il_idx);
04821                numeric_value  = 8;
04822                IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04823                                             numeric_value);
04824 
04825                /* Pick up common processing below the implied-DO code.        */
04826             }
04827             else {
04828 
04829                /* Generate a new Init IR and set up the value list attached   */
04830                /* to it to represent the blank padding.  The value list is a  */
04831                /* single IL.  The IL points at a Rep_Count IR whose left      */
04832                /* operand is the number of array elements to initialize.      */
04833                /* Its right operand points at another Rep_Count IR that       */
04834                /* represents the number of padding blanks needed.             */
04835 
04836                NTR_IR_TBL(new_init_ir_idx);
04837                SH_IR_IDX(curr_stmt_sh_idx)  = new_init_ir_idx;
04838                IR_OPR(new_init_ir_idx)      = Init_Opr;
04839                IR_TYPE_IDX(new_init_ir_idx) = TYPELESS_DEFAULT_TYPE;
04840                IR_LINE_NUM(new_init_ir_idx) = IR_LINE_NUM(init_ir_idx);
04841                IR_COL_NUM(new_init_ir_idx)  = IR_COL_NUM(init_ir_idx);
04842 
04843                NTR_IR_LIST_TBL(il_idx);
04844                IR_LIST_CNT_R(new_init_ir_idx) = 1;
04845                IR_FLD_R(new_init_ir_idx)      = IL_Tbl_Idx;
04846                IR_IDX_R(new_init_ir_idx)      = il_idx;
04847 
04848                NTR_IR_TBL(rep_count_ir_idx);
04849                IL_FLD(il_idx)                = IR_Tbl_Idx;
04850                IL_IDX(il_idx)                = rep_count_ir_idx;
04851                IR_OPR(rep_count_ir_idx)      = Rep_Count_Opr;
04852                IR_TYPE_IDX(rep_count_ir_idx) = TYPELESS_DEFAULT_TYPE;
04853                IR_LINE_NUM(rep_count_ir_idx) = IR_LINE_NUM(init_ir_idx);
04854                IR_COL_NUM(rep_count_ir_idx)  = IR_COL_NUM(init_ir_idx);
04855 
04856                COPY_OPND(IR_OPND_L(rep_count_ir_idx),
04857                          IL_OPND(rep_count_il_idx));
04858    
04859                NTR_IR_TBL(ir_idx);
04860                IR_FLD_R(rep_count_ir_idx) = IR_Tbl_Idx;
04861                IR_IDX_R(rep_count_ir_idx) = ir_idx;
04862                IR_OPR(ir_idx)             = Rep_Count_Opr;
04863                IR_TYPE_IDX(ir_idx)        = TYPELESS_DEFAULT_TYPE;
04864                IR_LINE_NUM(ir_idx)        = IR_LINE_NUM(init_ir_idx);
04865                IR_COL_NUM(ir_idx)         = IR_COL_NUM(init_ir_idx);
04866 
04867                IR_FLD_L(ir_idx)   = CN_Tbl_Idx;
04868                numeric_value      = target_length - value_length;
04869                IR_IDX_L(ir_idx)   = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04870                                                 numeric_value);
04871                IR_LINE_NUM_L(ir_idx)      = IR_LINE_NUM(init_ir_idx);
04872                IR_COL_NUM_L(ir_idx)       = IR_COL_NUM(init_ir_idx);
04873 
04874                IR_FLD_R(ir_idx) = CN_Tbl_Idx;
04875                IR_IDX_R(ir_idx) = ntr_const_tbl(CHARACTER_DEFAULT_TYPE,
04876                                                 FALSE,
04877                                                 (long_type *) &single_blank);
04878                IR_LINE_NUM_R(ir_idx)      = IR_LINE_NUM(init_ir_idx);
04879                IR_COL_NUM_R(ir_idx)       = IR_COL_NUM(init_ir_idx);
04880 
04881                /* Generate an implied-DO to loop through the target array     */
04882                /* elements.                                                   */
04883 
04884                NTR_IR_TBL(imp_do_ir_idx);
04885                IR_FLD_L(new_init_ir_idx)    = IR_Tbl_Idx;
04886                IR_IDX_L(new_init_ir_idx)    = imp_do_ir_idx;
04887                IR_OPR(imp_do_ir_idx)        = Implied_Do_Opr;
04888                IR_TYPE_IDX(imp_do_ir_idx)   = TYPELESS_DEFAULT_TYPE;
04889                IR_LINE_NUM(imp_do_ir_idx)   = IR_LINE_NUM(init_ir_idx);
04890                IR_COL_NUM(imp_do_ir_idx)    = IR_COL_NUM(init_ir_idx);
04891 
04892                /* The 4 IL's attached to the right opnd of the implied-DO IR  */
04893                /* are:                                                        */
04894                /*    - implied-DO variable : a temp                           */
04895                /*    - start value         : the value from the IL attached to*/
04896                /*                            the Subscript IR in the original */
04897                /*                            tree                             */
04898                /*    - end value           : start value + rep count (of array*/
04899                /*                            elements) - 1                    */
04900                /*    - increment value     : 1                                */
04901 
04902                temp_idx = gen_compiler_tmp(IR_LINE_NUM(init_ir_idx),
04903                                            IR_COL_NUM(init_ir_idx),
04904                                            Priv, TRUE);
04905                AT_SEMANTICS_DONE(temp_idx) = TRUE;
04906                ATD_TYPE_IDX(temp_idx)      = INTEGER_DEFAULT_TYPE;
04907                ATD_STOR_BLK_IDX(temp_idx)  = SCP_SB_STACK_IDX(curr_scp_idx);
04908                ATD_LCV_IS_CONST(temp_idx)  = TRUE;
04909 
04910                /* clear the referenced field so that this tmp does */
04911                /* not get sent to mif. BHJ                         */
04912 
04913                AT_REFERENCED(temp_idx)     = Not_Referenced;
04914 
04915 
04916                NTR_IR_LIST_TBL(il_idx);
04917                IR_LIST_CNT_R(imp_do_ir_idx) = 1;
04918                IR_FLD_R(imp_do_ir_idx)      = IL_Tbl_Idx;
04919                IR_IDX_R(imp_do_ir_idx)      = il_idx;
04920                IL_FLD(il_idx)               = AT_Tbl_Idx;
04921                IL_IDX(il_idx)               = temp_idx;
04922                IL_LINE_NUM(il_idx)          = stmt_start_line;
04923                IL_COL_NUM(il_idx)           = stmt_start_col;
04924 
04925                /* Produce the ILs that will hold the implied-DO start, end,   */
04926                /* and increment values.  They get filled differently depending*/
04927                /* on whether the implied-DO is being generated due to a whole */
04928                /* array or a section initialization.                          */
04929 
04930                NTR_IR_LIST_TBL(start_il_idx);
04931                IR_LIST_CNT_R(imp_do_ir_idx)   = 2;
04932                IL_NEXT_LIST_IDX(il_idx)       = start_il_idx;
04933                IL_PREV_LIST_IDX(start_il_idx) = il_idx;
04934 
04935                NTR_IR_LIST_TBL(end_il_idx);
04936                IR_LIST_CNT_R(imp_do_ir_idx)   = 3;
04937                IL_NEXT_LIST_IDX(start_il_idx) = end_il_idx;
04938                IL_PREV_LIST_IDX(end_il_idx)   = start_il_idx;
04939 
04940                NTR_IR_LIST_TBL(inc_il_idx);
04941                IR_LIST_CNT_R(imp_do_ir_idx) = 4;
04942                IL_NEXT_LIST_IDX(end_il_idx) = inc_il_idx;
04943                IL_PREV_LIST_IDX(inc_il_idx) = end_il_idx;
04944 
04945                if (section_start_value == 0) {
04946                   ir_idx = IR_IDX_L(substring_ir_idx);
04947 
04948                   while (IR_OPR(ir_idx) != Subscript_Opr) {
04949                      ir_idx = IR_IDX_L(ir_idx);
04950                   }
04951 
04952                   COPY_OPND(IL_OPND(start_il_idx), IL_OPND(IR_IDX_R(ir_idx)));
04953 
04954                   numeric_value = CN_INT_TO_C(IL_IDX(start_il_idx))+rep_count-1;
04955             
04956                   IL_FLD(end_il_idx) = CN_Tbl_Idx;
04957                   IL_IDX(end_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04958                                                    numeric_value);
04959                   IL_LINE_NUM(end_il_idx)          = stmt_start_line;
04960                   IL_COL_NUM(end_il_idx)           = stmt_start_col;
04961 
04962                   IL_FLD(inc_il_idx) = CN_Tbl_Idx;
04963                   IL_IDX(inc_il_idx) = CN_INTEGER_ONE_IDX;
04964                   IL_LINE_NUM(inc_il_idx)          = stmt_start_line;
04965                   IL_COL_NUM(inc_il_idx)           = stmt_start_col;
04966                }
04967                else {
04968 
04969                   /* We're processing a section reference.                    */
04970                   /* section_start_value and section_inc_value are used for   */
04971                   /* the loop start and inc values.  The loop end value is    */
04972                   /* calculated.                                              */
04973 
04974                   IL_FLD(start_il_idx) = CN_Tbl_Idx;
04975                   IL_IDX(start_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04976                                                      section_start_value);
04977                   IL_LINE_NUM(start_il_idx)          = stmt_start_line;
04978                   IL_COL_NUM(start_il_idx)           = stmt_start_col;
04979 
04980                   numeric_value =
04981                      section_start_value + (rep_count - 1)*section_inc_value;
04982 
04983                   IL_FLD(end_il_idx) = CN_Tbl_Idx;
04984                   IL_IDX(end_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04985                                                    numeric_value);
04986                   IL_LINE_NUM(end_il_idx)          = stmt_start_line;
04987                   IL_COL_NUM(end_il_idx)           = stmt_start_col;
04988 
04989                   IL_FLD(inc_il_idx) = CN_Tbl_Idx;
04990                   IL_IDX(inc_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
04991                                                    section_inc_value);
04992                   IL_LINE_NUM(inc_il_idx)          = stmt_start_line;
04993                   IL_COL_NUM(inc_il_idx)           = stmt_start_col;
04994                }
04995 
04996                /* Make a copy of the original reference IR tree and attach it */
04997                /* to the left operand of the implied-DO IR via an IL.         */
04998     
04999                NTR_IR_LIST_TBL(il_idx);
05000                IR_LIST_CNT_L(imp_do_ir_idx) = 1;
05001                IR_FLD_L(imp_do_ir_idx)      = IL_Tbl_Idx;
05002                IR_IDX_L(imp_do_ir_idx)      = il_idx;
05003 
05004                copy_subtree(&IR_OPND_L(init_ir_idx), &opnd);
05005                COPY_OPND(IL_OPND(il_idx), opnd);
05006 
05007                substring_ir_idx         = IL_IDX(il_idx); 
05008                IR_OPR(substring_ir_idx) = Substring_Opr;
05009             }
05010          
05011             IR_OPR(IR_IDX_L(init_ir_idx)) = Substring_Opr;
05012   
05013             /* In the original tree, replace the substring end value.         */
05014   
05015             numeric_value               = original_start_val + value_length - 1;
05016             IL_IDX(original_end_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
05017                                                       numeric_value); 
05018 
05019             /* In the original tree, update the substring length to be the    */
05020             /* length of the initialization value.                            */
05021 
05022             il_idx         = IL_NEXT_LIST_IDX(original_end_il_idx);
05023             IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
05024                                          value_length);
05025 
05026             /* In the new tree, update the substring start value, end value   */
05027             /* (end value == start value), and length.                        */
05028 
05029             ++numeric_value;
05030   
05031             il_idx         = IR_IDX_R(substring_ir_idx);
05032             IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE,
05033                                          numeric_value);
05034 
05035             il_idx         = IL_NEXT_LIST_IDX(il_idx);
05036             IL_IDX(il_idx) = IL_IDX(IL_PREV_LIST_IDX(il_idx));
05037 
05038             il_idx         = IL_NEXT_LIST_IDX(il_idx);
05039             IL_IDX(il_idx) = CN_INTEGER_ONE_IDX;
05040  
05041             if (rep_count > 1) {
05042 
05043                /* An implied-DO IR was generated.  Change the target's        */
05044                /* subscript to point at the implied-DO temp.                  */
05045 
05046                ir_idx = IR_IDX_L(substring_ir_idx);
05047   
05048                while (IR_OPR(ir_idx) != Subscript_Opr) {
05049                   ir_idx = IR_IDX_L(ir_idx);
05050                }
05051   
05052                IL_FLD(IR_IDX_R(ir_idx)) = AT_Tbl_Idx;
05053                IL_IDX(IR_IDX_R(ir_idx)) = temp_idx;
05054                IL_LINE_NUM(IR_IDX_R(ir_idx)) = stmt_start_line;
05055                IL_COL_NUM(IR_IDX_R(ir_idx)) = stmt_start_col;
05056                
05057             }
05058          }
05059       }
05060    }
05061    else {
05062 
05063       /* Future optimization:  If the target is zero-length, can we just eat  */
05064       /* the current value and eliminate the DATA SH and IR?                  */
05065 
05066    }
05067 
05068 EXIT:
05069 
05070    TRACE (Func_Exit, "adjust_char_value_len", NULL);
05071 
05072    return;
05073 
05074 }  /* adjust_char_value_len */
05075 
05076 
05077 /******************************************************************************\
05078 |*                                                                            *|
05079 |* Description:                                                               *|
05080 |*      Climb the DATA target reference tree to find all subscript expressions*|
05081 |*      that were too complicated for expr_semantics to fold.  Fold them now. *|
05082 |*                                                                            *|
05083 |* Input parameters:                                                          *|
05084 |*      NONE                                                                  *|
05085 |*                                                                            *|
05086 |* Output parameters:                                                         *|
05087 |*      NONE                                                                  *|
05088 |*                                                                            *|
05089 |* Returns:                                                                   *|
05090 |*      NONE                                                                  *|
05091 |*                                                                            *|
05092 \******************************************************************************/
05093 
05094 static void fold_all_subscripts(opnd_type       *opnd)
05095 {
05096    int                  attr_idx;
05097    expr_arg_type        expr_desc;
05098    int                  i;
05099    int                  il_idx;
05100    int                  ir_idx;
05101    opnd_type            local_opnd;
05102    opnd_type            my_opnd;
05103 
05104    
05105    TRACE (Func_Entry, "fold_all_subscripts", NULL);
05106 
05107    COPY_OPND(local_opnd, (*opnd));
05108 
05109    expr_desc             = init_exp_desc;
05110    expr_desc.type        = Integer;
05111    expr_desc.type_idx    = INTEGER_DEFAULT_TYPE;
05112    expr_desc.linear_type = INTEGER_DEFAULT_TYPE;
05113 
05114    while (OPND_FLD(local_opnd) == IR_Tbl_Idx) {
05115 
05116       ir_idx = OPND_IDX(local_opnd);
05117 
05118       switch (IR_OPR(ir_idx)) {
05119 
05120          case Subscript_Opr:
05121         
05122             attr_idx = (IR_FLD_L(ir_idx) == AT_Tbl_Idx) ?
05123                           IR_IDX_L(ir_idx) :
05124                           IR_IDX_R(IR_IDX_L(ir_idx));
05125 
05126             il_idx = IR_IDX_R(ir_idx);
05127 
05128             for (i = 1;  i <= IR_LIST_CNT_R(ir_idx);  ++i) {
05129 
05130 # ifdef COARRAY_FORTRAN
05131                if (IL_PE_SUBSCRIPT(il_idx)) {
05132                   continue;
05133                }
05134 # endif
05135 
05136                if (IL_FLD(il_idx) == IR_Tbl_Idx) {
05137                   COPY_OPND(my_opnd, IL_OPND(il_idx));
05138                   fold_all_subscripts(&my_opnd);
05139 
05140                   if (IL_FLD(il_idx) == IR_Tbl_Idx) {
05141 
05142                      if (fold_aggragate_expression(&my_opnd,
05143                                                    &expr_desc,
05144                                                     TRUE)) {
05145                         COPY_OPND(IL_OPND(il_idx), my_opnd);
05146                      }
05147                      else {
05148                         PRINTMSG(IR_LINE_NUM(IL_IDX(il_idx)),
05149                                  861,
05150                                  Internal,
05151                                  IR_COL_NUM(IL_IDX(il_idx)),
05152                                  "object semantics");
05153                      }
05154                   }
05155                }
05156 
05157                if (fold_relationals(IL_IDX(il_idx),
05158                                     BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), i),
05159                                     Lt_Opr)) {
05160                   PRINTMSG(IL_LINE_NUM(il_idx),
05161                            831,
05162                            Error,
05163                            IL_COL_NUM(il_idx));
05164                }
05165 
05166                if (fold_relationals(IL_IDX(il_idx),
05167                                     BD_UB_IDX(ATD_ARRAY_IDX(attr_idx), i),
05168                                     Gt_Opr)) {
05169                   PRINTMSG(IL_LINE_NUM(il_idx),
05170                            996,
05171                            Error,
05172                            IL_COL_NUM(il_idx));
05173                }
05174 
05175                il_idx = IL_NEXT_LIST_IDX(il_idx);
05176             }
05177    
05178             COPY_OPND(local_opnd, IR_OPND_L(ir_idx));
05179          
05180             break;
05181 
05182          case Struct_Opr:
05183          case Whole_Substring_Opr:
05184          case Substring_Opr:
05185             COPY_OPND(local_opnd, IR_OPND_L(ir_idx));
05186             break;
05187 
05188          default:
05189             goto EXIT;
05190       }
05191    }
05192 
05193 EXIT:
05194 
05195    TRACE (Func_Exit, "fold_all_subscripts", NULL);
05196 
05197    return;
05198 
05199 }  /* fold_all_subscripts */
05200 
05201 
05202 /******************************************************************************\
05203 |*                                                                            *|
05204 |* Description:                                                               *|
05205 |*      When a long hollerith is broken up between data targets, the rest of  *|
05206 |*      the constant is entered back into the constant table. It must be      *|
05207 |*      entered as hollerith, so this wrapper routine is needed.              *|
05208 |*                                                                            *|
05209 |* Input parameters:                                                          *|
05210 |*      NONE                                                                  *|
05211 |*                                                                            *|
05212 |* Output parameters:                                                         *|
05213 |*      NONE                                                                  *|
05214 |*                                                                            *|
05215 |* Returns:                                                                   *|
05216 |*      NOTHING                                                               *|
05217 |*                                                                            *|
05218 \******************************************************************************/
05219 # if 0
05220 
05221 static int reenter_const_as_hollerith(int               value_idx,
05222                                       int               offset,
05223                                       int               type_idx,
05224                                       holler_type       hollerith_type)
05225 
05226 {
05227    int          cn_idx;
05228    long64       i;
05229    long64       words;
05230 
05231    TRACE (Func_Entry, "reenter_const_as_hollerith", NULL);
05232 
05233    cn_idx = ntr_const_tbl(type_idx, 
05234                           (TYP_TYPE(type_idx) == Character ? TRUE : FALSE), 
05235                           NULL);
05236 
05237    if (TYP_TYPE(type_idx) == Typeless) {
05238       words = TARGET_BITS_TO_WORDS(TYP_BIT_LEN(type_idx));
05239    }
05240    else if (TYP_TYPE(type_idx) == Character) {
05241       words = TARGET_BYTES_TO_WORDS(CN_INT_TO_C(TYP_IDX(type_idx)));
05242    }
05243 
05244    for (i = 0; i < words; i++) {
05245       CP_CONSTANT(CN_POOL_IDX(cn_idx) + i) = 
05246                           CP_CONSTANT(CN_POOL_IDX(value_idx) + offset + i);
05247    }
05248 
05249    CN_HOLLERITH_TYPE(cn_idx) = hollerith_type;
05250 
05251    TRACE (Func_Exit, "reenter_const_as_hollerith", NULL);
05252 
05253    return(cn_idx);
05254 
05255 }  /* reenter_const_as_hollerith */
05256 
05257 # endif
05258 
05259 
05260 /******************************************************************************\
05261 |*                                                                            *|
05262 |* Description:                                                               *|
05263 |*      This procedure performs semantic analysis on the data-stmt-repeat     *|
05264 |*                                                                            *|
05265 |* Input parameters:                                                          *|
05266 |*      repeat_ir_idx   -> IR index of parsed repeat.                         *|
05267 |*                                                                            *|
05268 |* Output parameters:                                                         *|
05269 |*      NONE                                                                  *|
05270 |*                                                                            *|
05271 |* Returns:                                                                   *|
05272 |*      NONE                                                                  *|
05273 |*                                                                            *|
05274 \******************************************************************************/
05275 
05276 void    data_repeat_semantics(int       repeat_ir_idx)
05277 
05278 {
05279    int                  column;
05280    expr_arg_type        expr_desc;
05281    int                  line;
05282    int                  ok              = TRUE;
05283    opnd_type            opnd;
05284    int                  save_attr       = NULL_IDX;
05285    expr_mode_type       save_expr_mode  = expr_mode;
05286 
05287 
05288    TRACE (Func_Entry, "data_repeat_semantics", NULL);
05289 
05290    COPY_OPND(opnd, IR_OPND_L(repeat_ir_idx));
05291 
05292    expr_desc.rank       = 0;
05293    xref_state           = CIF_Symbol_Reference;
05294 
05295    /* Any subscripts must be initialization expressions */
05296 
05297    expr_mode            = Initialization_Expr;
05298 
05299    switch (OPND_FLD(opnd)) {
05300 
05301    case IR_Tbl_Idx:
05302 
05303       if (IR_OPR(OPND_IDX(opnd)) == Paren_Opr) {
05304 
05305          if (IR_FLD_L(OPND_IDX(opnd)) == AT_Tbl_Idx &&
05306              AT_OBJ_CLASS(IR_IDX_L(OPND_IDX(opnd))) == Data_Obj) {
05307             save_attr                    = IR_IDX_L(OPND_IDX(opnd));
05308             ATD_PARENT_OBJECT(save_attr) = TRUE;
05309          }
05310       }
05311       break;
05312 
05313    case AT_Tbl_Idx:
05314 
05315       if (AT_OBJ_CLASS(OPND_IDX(opnd)) == Data_Obj) {
05316          save_attr                      = OPND_IDX(opnd);
05317          ATD_PARENT_OBJECT(save_attr)   = TRUE;
05318       }
05319    }
05320 
05321 
05322    if (expr_semantics(&opnd, &expr_desc)) {
05323       find_opnd_line_and_column(&opnd, &line, &column);
05324 
05325       /* If the rep factor is represented by an Attr table entry, */
05326       /* the only thing it can be is a scalar named constant.     */
05327 
05328       switch (OPND_FLD(opnd)) {
05329       case CN_Tbl_Idx:    /* Great - ok */
05330          break;
05331 
05332       case AT_Tbl_Idx:
05333          ok = FALSE;
05334          PRINTMSG(line, 677, Error, column); /* Must be a constant */
05335          break;
05336 
05337       default:
05338          ok = FALSE;
05339          PRINTMSG(line, 678, Error, column); /* Must be a int scalar constant */
05340          break;
05341       }
05342 
05343       if (!ok) {
05344 
05345          /* Intentionally blank */
05346      
05347       }
05348       else if (expr_desc.type != Integer && expr_desc.type != Typeless) {
05349          PRINTMSG(line, 678, Error, column);
05350       }
05351       else if (expr_desc.linear_type == Long_Typeless) {
05352          PRINTMSG(line, 1133, Error, column);
05353       }
05354       else if (expr_desc.rank > 0) {
05355          PRINTMSG(line, 678, Error, column);
05356       }
05357       else if (expr_desc.linear_type == Short_Typeless_Const) {
05358          OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd),
05359                                                  INTEGER_DEFAULT_TYPE,
05360                                                  line,
05361                                                  column);
05362       }
05363    }
05364 
05365    COPY_OPND(IR_OPND_L(repeat_ir_idx), opnd);
05366 
05367    expr_mode = save_expr_mode;
05368 
05369    if (save_attr != NULL_IDX) {
05370       ATD_PARENT_OBJECT(save_attr)      = FALSE;
05371    }
05372 
05373    TRACE (Func_Exit, "data_repeat_semantics", NULL);
05374 
05375    return;
05376 
05377 }  /* data_repeat_semantics */
05378 
05379 
05380 /******************************************************************************\
05381 |*                                                                            *|
05382 |* Description:                                                               *|
05383 |*      This procedure performs semantic analysis on the data-stmt-constant   *|
05384 |*                                                                            *|
05385 |* Input parameters:                                                          *|
05386 |*      const_ir_idx    -> IR index of parsed constant.                       *|
05387 |*                                                                            *|
05388 |* Output parameters:                                                         *|
05389 |*      NONE                                                                  *|
05390 |*                                                                            *|
05391 |* Returns:                                                                   *|
05392 |*      NONE                                                                  *|
05393 |*                                                                            *|
05394 \******************************************************************************/
05395 
05396 void    constant_value_semantics(opnd_type      *opnd,
05397                                  int             uopr_ir_idx)
05398 
05399 {
05400    int                  boz_const_col_num;
05401    int                  boz_const_line_num      = 0;
05402    int                  column;
05403    expr_arg_type        expr_desc;
05404    boolean              have_null               = FALSE;
05405    int                  line;
05406    int                  save_attr               = NULL_IDX;
05407    expr_mode_type       save_expr_mode          = expr_mode;
05408 
05409 
05410    TRACE (Func_Entry, "constant_value_semantics", NULL);
05411 
05412    switch (OPND_FLD((*opnd))) {
05413    case IR_Tbl_Idx:
05414       find_opnd_line_and_column(opnd, &line, &column);
05415 
05416       if (IR_OPR(OPND_IDX((*opnd))) == Call_Opr &&
05417           AT_IS_INTRIN(IR_IDX_L(OPND_IDX((*opnd)))) &&
05418           strcmp(AT_OBJ_NAME_PTR(IR_IDX_L(OPND_IDX((*opnd)))), "NULL") == 0) {
05419          have_null = TRUE;
05420 
05421          if (IR_IDX_R(OPND_IDX((*opnd))) != NULL_IDX) { /* MOLD is specified */
05422             PRINTMSG(line, 1573, Error, column);
05423             IR_OPND_R(OPND_IDX((*opnd))) = null_opnd;  /* Clear the argument */
05424          }
05425       }
05426 
05427       if (IR_OPR(OPND_IDX((*opnd))) == Paren_Opr) {
05428 
05429          if (IR_FLD_L(OPND_IDX((*opnd))) == AT_Tbl_Idx &&
05430              AT_OBJ_CLASS(IR_IDX_L(OPND_IDX((*opnd)))) == Data_Obj) {
05431             save_attr                    = IR_IDX_L(OPND_IDX((*opnd)));
05432             ATD_PARENT_OBJECT(save_attr) = TRUE;
05433          }
05434       }
05435 
05436       if (uopr_ir_idx != NULL_IDX) {
05437 
05438          /* expr_semantics treats a unary minus on a BOZ constant as */
05439          /* an expression which means the column pointer comes back  */
05440          /* pointing to the minus sign rather than to the BOZ        */
05441          /* constant.  Save the line and column here and use them in */
05442          /* the result opnd below.                                   */
05443 
05444          boz_const_line_num = line;
05445          boz_const_col_num  = column;
05446 
05447          COPY_OPND(IR_OPND_L(uopr_ir_idx), (*opnd));
05448          OPND_FLD((*opnd)) = IR_Tbl_Idx;
05449          OPND_IDX((*opnd)) = uopr_ir_idx;
05450       }
05451       break;
05452 
05453    case AT_Tbl_Idx:
05454 
05455       if (AT_OBJ_CLASS(OPND_IDX((*opnd))) == Data_Obj) {
05456          save_attr                      = OPND_IDX((*opnd));
05457          ATD_PARENT_OBJECT(save_attr)   = TRUE;
05458       }
05459 
05460       if (uopr_ir_idx != NULL_IDX) {
05461          PRINTMSG(IR_LINE_NUM(uopr_ir_idx), 958, Error,
05462                   IR_COL_NUM(uopr_ir_idx));
05463       }
05464       break;
05465 
05466    case CN_Tbl_Idx:
05467 
05468       if (uopr_ir_idx != NULL_IDX) {
05469 
05470          if (CN_BOZ_CONSTANT(OPND_IDX((*opnd)))) {
05471             PRINTMSG(IR_LINE_NUM(uopr_ir_idx), 957, Ansi,
05472                      IR_COL_NUM(uopr_ir_idx));
05473          }
05474          else if (TYP_TYPE(CN_TYPE_IDX(OPND_IDX((*opnd)))) != Integer  &&
05475                   TYP_TYPE(CN_TYPE_IDX(OPND_IDX((*opnd)))) != Real  &&
05476                   ! CN_BOOLEAN_CONSTANT(OPND_IDX((*opnd)))) {
05477 
05478             /* A sign is only permitted for integer or real literal constants */
05479 
05480             PRINTMSG(IR_LINE_NUM(uopr_ir_idx), 958, Error,
05481                      IR_COL_NUM(uopr_ir_idx));
05482          }
05483          COPY_OPND(IR_OPND_L(uopr_ir_idx), (*opnd));
05484          OPND_FLD((*opnd)) = IR_Tbl_Idx;
05485          OPND_IDX((*opnd)) = uopr_ir_idx;
05486       }
05487       break;
05488    }   /* end switch */
05489 
05490    /* Any subscripts must be initialization expressions */
05491 
05492    expr_desc.rank = 0;
05493    expr_mode      = Initialization_Expr;
05494    xref_state     = CIF_Symbol_Reference;
05495 
05496    /* set comp_gen_expr to TRUE. This forces the fold of REAL   */
05497    /* constant expressions. When -Oieeeconform is specified,    */
05498    /* the folding of Real and Complex expressions is prevented. */
05499 
05500    comp_gen_expr = TRUE;
05501 
05502    if (expr_semantics(opnd, &expr_desc)) {
05503       find_opnd_line_and_column(opnd, &line, &column);
05504 
05505       switch (OPND_FLD((*opnd))) {
05506       case CN_Tbl_Idx:
05507 
05508          if (boz_const_line_num != 0) {
05509             OPND_LINE_NUM((*opnd)) = boz_const_line_num;
05510             OPND_COL_NUM((*opnd))  = boz_const_col_num;
05511             line                 = boz_const_line_num;
05512             column               = boz_const_col_num;
05513          }
05514 
05515          break;
05516 
05517       case AT_Tbl_Idx:
05518 
05519          if (AT_OBJ_CLASS(OPND_IDX((*opnd))) == Data_Obj   &&
05520              ATD_CLASS(OPND_IDX((*opnd))) == Compiler_Tmp  &&
05521              ATD_FLD(OPND_IDX((*opnd))) == CN_Tbl_Idx)  {
05522 
05523             if (!expr_desc.constant) {
05524                PRINTMSG(line, 906, Error, column);
05525                *opnd = null_opnd;
05526             }
05527          }
05528          else {
05529             PRINTMSG(line, 1101, Error, column);
05530          }
05531          break;
05532 
05533       case IR_Tbl_Idx:
05534 
05535          if (!have_null) {
05536             PRINTMSG(line, 1648, Error, column);
05537             *opnd = null_opnd;
05538          }
05539          break;
05540 
05541       }  /* End switch */
05542    }
05543 
05544    if (save_attr != NULL_IDX) {
05545       ATD_PARENT_OBJECT(save_attr)      = FALSE;
05546    }
05547 
05548    /* reset comp_gen_expr to FALSE. end of */
05549    /* compiler generated expression        */
05550 
05551    comp_gen_expr        = FALSE;
05552    expr_mode            = save_expr_mode;
05553 
05554    TRACE (Func_Exit, "constant_value_semantics", NULL);
05555 
05556    return;
05557 
05558 }  /* constant_value_semantics */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines