Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cwh_types.cxx
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  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  dd-mmm-95 - Original Version
00042  *
00043  * Description: Handles the conversion of types to TYs. The
00044  *              entry points are *
00045  *
00046  *                fei_new_descriptor - new intrinsic/arraytype
00047  *                fei_array_dimen    - new bound for array type
00048  *                fei_next_type_idx  - new TY for derived type
00049  *                fei_user_type      - new derived type
00050  *                fei_member         - new component of derived type
00051  *                fei_new_dope_vector - new descriptor for deferred shape
00052  *                                      or pointer objects.
00053  *
00054  *              The TY is created, possibly in stages, then handed back
00055  *              to the interface which will store it and pass it back
00056  *              when a type is required.
00057  *
00058  * ====================================================================
00059  * ====================================================================
00060  */
00061 
00062 static char *source_file = __FILE__;
00063 
00064 #ifdef _KEEP_RCS_ID
00065 #endif /* _KEEP_RCS_ID */
00066 
00067 /* sgi includes */
00068 
00069 #include "defs.h"
00070 #include "glob.h"  
00071 #include "stab.h"
00072 #include "ttype.h"
00073 #include "strtab.h"
00074 #include "config_targ.h"
00075 #include "errors.h"
00076 #include "wn.h"
00077 #include "wn_util.h"
00078 
00079 /* Cray includes */
00080 
00081 #include "i_cvrt.h"
00082 
00083 /* conversion includes */
00084 
00085 #include "cwh_defines.h"
00086 #include "cwh_expr.h"
00087 #include "cwh_addr.h"
00088 #include "cwh_block.h"
00089 #include "cwh_preg.h" 
00090 #include "cwh_stab.h"
00091 #include "cwh_auxst.h"
00092 /* #include "cwh_stmt.h" */
00093 #include "cwh_types.h"
00094 #include "cwh_stk.h"
00095 #include "cwh_types.i"
00096 #include "sgi_cmd_line.h"
00097 
00098 /*#include "cwh_stats.h"  */
00099 
00100 #define BUMP_TY_COUNTER(x) 
00101 
00102 /*===================================================
00103  *
00104  * fei_descriptor
00105  *
00106  * This is the PDGCS call to make a new type.
00107  * Fill in the blanks of the PDGCS TYPE and return
00108  * it (space is allocated in caller). We only use 
00109  * the TY from the TYPE, via a cast for now. 
00110  * 
00111  * For an array, take the information set up in
00112  * decl_bounds, ty_dim1 & last_bitsize by calls to
00113  * fei_array_dimen and pass them to a utility routine.
00114  *
00115  ====================================================
00116 */
00117 
00118 TYPE
00119 fei_descriptor (INT32        flag_matrix,
00120                 INT32        table_type,
00121                 INTPTR       size,
00122                 INT32        basic_type,
00123                 INT32        aux_info,
00124                 INT32        alignment)
00125     
00126 {
00127   TYPE t     ;
00128   mUINT16 al ;
00129   BOOL  hosted ;
00130   TY_IDX ty_idx;
00131 
00132   hosted = test_flag(flag_matrix,FEI_DESCRIPTOR_HOSTED_TYPE) || in_hosted_dtype ;
00133 
00134   switch(table_type) {
00135   case Basic:
00136     al = bit_to_byte(size);      
00137     ty_idx = cwh_types_mk_basic_TY((BASIC_TYPE)basic_type,size,al) ; 
00138     break;
00139 
00140   case Array:
00141      Is_True((top_of_decl_bounds != ANULL),("Bad array info"));
00142     ty_idx = cwh_types_mk_array_TY(decl_bounds,
00143                                    top_of_decl_bounds + 1,
00144                                    ty_dim1,
00145                                    bit_to_byte(last_bitsize));
00146 
00147      if (test_flag(flag_matrix,FEI_ASSUMD_SHAPE_ARRAY))
00148             Set_TY_is_f90_assumed_shape(ty_idx);
00149 
00150      if (test_flag(flag_matrix,FEI_DEFERRED_SHAPE_ARRAY))
00151             Set_TY_is_f90_deferred_shape(ty_idx);
00152 
00153      if (test_flag(flag_matrix,FEI_ASSUMED_SIZE_ARRAY))
00154             Set_TY_is_f90_assumed_size(ty_idx);
00155 
00156      if (co_top_decl_bounds != ANULL)
00157             Set_TY_is_co_array(ty_idx);
00158 
00159    /*
00160     * move unique from "cwh_types_mk_array_TY" to here,
00161     * since we need the flags----fzhao
00162     */ 
00163       ty_idx = cwh_types_unique_TY(ty_idx);
00164 
00165   
00166     
00167     if (hosted)
00168       (void) cwh_types_mk_pointer_TY(ty_idx,TRUE);
00169 
00170     /* now generate a list of distribute pragmas, dont associate with
00171        the ST yet */
00172     if (decl_distributed_pragma_id!=WN_PRAGMA_UNDEFINED) {
00173       int i;
00174       WN *wn;
00175       decl_distribute_pragmas=WN_CreateBlock();
00176       for(i=top_of_decl_bounds; i>=0; i--) {
00177           /* from last to first */
00178         /* create a DISTRIBUTE or DISTRIBUTE_RESHAPE pragma for the dimension */
00179         /* use ST==NULL for now, we fill in this later */
00180         WN *lb,*ub,*st;
00181         wn = WN_CreatePragma(decl_distributed_pragma_id, (ST_IDX) NULL, 0, 0);
00182         WN_pragma_distr_type(wn) =decl_distribution[i];
00183         WN_pragma_index(wn) = top_of_decl_bounds-i;
00184         switch(decl_distribution[i]) {
00185           case DISTRIBUTE_CYCLIC_EXPR:
00186             WN_INSERT_BlockLast(decl_distribute_pragmas,wn);
00187             /* create an Xpragma with the value */
00188             wn = WN_CreateXpragma(decl_distributed_pragma_id, (ST_IDX) NULL, 1);
00189             WN_kid0(wn) = decl_cyclic_val[i].wn;
00190             WN_INSERT_BlockLast(decl_distribute_pragmas,wn);
00191             break;
00192           case DISTRIBUTE_CYCLIC_CONST:
00193             WN_pragma_preg(wn) = decl_cyclic_val[i].val;
00194             WN_INSERT_BlockLast(decl_distribute_pragmas,wn);
00195             break;
00196           default:
00197             WN_INSERT_BlockLast(decl_distribute_pragmas,wn);
00198             break;
00199         }
00200         /* generate an Xpragma for the array bound value for this dimension */
00201         lb = cwh_types_bound_WN(ty_idx,i,LOW);
00202         ub = cwh_types_bound_WN(ty_idx,i,UPPER);
00203         st = WN_Intconst(MTYPE_I4,1);
00204         wn = WN_CreateXpragma(decl_distributed_pragma_id, (ST_IDX) NULL, 1);
00205         WN_kid0(wn) = cwh_addr_extent(lb,ub,st);
00206         WN_INSERT_BlockLast(decl_distribute_pragmas,wn);
00207       } /* for each extent */
00208       /* now do a second pass if we have an ONTO clause */
00209       if (distribute_onto) {
00210         for(i=top_of_decl_bounds; i>=0; i--) {
00211           /* ONTO clause args only apply to each non-* distribution */
00212           if (decl_distribution[i]!=DISTRIBUTE_STAR) {
00213             /* make an Xpragma */
00214             wn = WN_CreateXpragma(WN_PRAGMA_ONTO, (ST_IDX) NULL, 1);
00215             WN_kid0(wn) = decl_onto[i];
00216             WN_INSERT_BlockLast(decl_distribute_pragmas,wn);
00217           }
00218         } /* for */
00219       }
00220     }
00221     top_of_decl_bounds = ANULL ;
00222     break ;
00223 
00224   case Func_tion:                  /* external, passed as arg */
00225     ty_idx = cwh_types_mk_procedure_TY(Be_Type_Tbl(MTYPE_V), 0,TRUE,FALSE);
00226     break ;
00227 
00228   default:
00229 
00230     DevWarn((" Unsupported type "));
00231   } 
00232 
00233   t.table_type = (TABLE_TYPE)table_type ;
00234   t.basic_type = (BASIC_TYPE)basic_type ;
00235 
00236   cwh_types_fill_type(flag_matrix,&t,ty_idx);
00237 
00238   return(t);
00239 }  
00240 
00241 
00242 void fei_init_global_vars()
00243 {
00244   top_of_decl_bounds = ANULL;
00245   co_top_decl_bounds = ANULL;
00246 }
00247 
00248 
00249 /*===================================================
00250  *
00251  * fei_array_dimen
00252  *
00253  * This is the PDGCS call to make a new array
00254  * dimension. The dimensions are processed in
00255  * order 1->rank of array, but the rank isn't known
00256  * here, so put each bound in decl_bounds[dim], and
00257  * create the TY in fei_descriptor.
00258  * 
00259  * If the bound isn't a constant, the FE puts it
00260  * into a temp, so the temp just has to be addressed.
00261  *
00262  * The result is returned but ignored. Save the 
00263  * TY associated with dim=1, as it's needed for
00264  * TY_etype of the TY_ARI.
00265  *
00266  ====================================================
00267  */
00268 extern INTPTR
00269 fei_array_dimen(INT32  flag_bits,
00270                 INT64  low_bound,
00271                 INT64  extent,
00272                 INT32  axis,
00273                 TYPE   span_type,
00274                 INT64  bitsize,
00275                 INT    distribution,
00276                 INT64  upper_bound)
00277 {
00278   ST * st;
00279   STB_pkt *b;
00280   WN  *wn ;
00281   BOOL hosted ;
00282   ST_IDX st_idx;
00283   ARB_HANDLE p;
00284   BOOL flow_dependent;
00285 
00286   hosted = test_flag(flag_bits,FEI_ARRAY_DIMEN_HOSTED_TYPE) || in_hosted_dtype ;
00287 
00288   top_of_decl_bounds = axis - 1 ;
00289 
00290   if (top_of_decl_bounds == 0) {
00291      decl_bounds = New_ARB();
00292      p = decl_bounds;
00293   } else {
00294      p = New_ARB();
00295   }
00296 
00297   flow_dependent = test_flag(flag_bits,FEI_ARRAY_DIMEN_FLOW_DEPENDENT);
00298 
00299   ARB_Init (p, 1, 1, 1);
00300 
00301   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_VARY_LB)) {
00302 
00303     b = cast_to_STB((UINTPS) low_bound) ;
00304     Is_True((b->form == is_ST),("Odd lbound"));
00305 
00306     st = cast_to_ST(b->item);
00307     Clear_ARB_const_lbnd(p);
00308     Set_ARB_lbnd_var(p, ST_st_idx(st));
00309 
00310     if (!hosted && !flow_dependent)
00311         cwh_types_copyin_pragma(st);
00312 
00313   } else {
00314   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_EMPTY_LB)) {
00315      Clear_ARB_const_lbnd(p);
00316      Set_ARB_empty_lbnd(p);
00317    } else {
00318 
00319     Set_ARB_const_lbnd(p);
00320     Set_ARB_lbnd_val (p, low_bound);
00321   }
00322  }
00323   
00324   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_VARY_UB)) {
00325 
00326     b = cast_to_STB((UINTPS) upper_bound) ;
00327     if (b != NULL) {
00328       Is_True((b->form == is_ST),("Odd extent"));
00329       
00330       st = cast_to_ST(b->item);
00331 
00332       Clear_ARB_const_ubnd(p);
00333       Set_ARB_ubnd_var(p, ST_st_idx(st));
00334 
00335       if (!hosted && !flow_dependent)
00336           cwh_types_copyin_pragma(st);
00337 
00338     }
00339    } else {
00340    if (test_flag(flag_bits,FEI_ARRAY_DIMEN_EMPTY_UB)) {
00341         Clear_ARB_const_ubnd(p);
00342      Set_ARB_empty_ubnd(p);
00343     }
00344    else {  /* constant ub */
00345     
00346     Set_ARB_const_ubnd(p);
00347     Set_ARB_ubnd_val (p, upper_bound);
00348   }
00349  }
00350 
00351 
00352   /* set pragma on extent, for MP/LNO, doesn't go into ARB */
00353 
00354   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_VARY_EXT)) {
00355 
00356     b = cast_to_STB((UINTPS) extent) ;
00357     if (b != NULL) {
00358       Is_True((b->form == is_ST),("Odd extent"));
00359       
00360       st = cast_to_ST(b->item);
00361 
00362       if (!hosted && !flow_dependent)
00363         cwh_types_copyin_pragma(st);
00364     }
00365   }
00366 
00367   /* update stride - the argument is the bitsize of the */
00368   /* current axis, but a TY has the size of an element  */
00369   /* so save the bitsize till next dimension. If stride */
00370   /* isn't constant bitsize becomes 0, and the TY tree  */
00371   /* seems to require the element size */
00372 
00373   if (axis == 1) {
00374      
00375      ty_dim1 = cast_to_TY(t_TY(span_type)) ;
00376      
00377      Set_ARB_const_stride(p);
00378      Set_ARB_stride_val(p, TY_size(Ty_Table[ty_dim1]));
00379      
00380   } else { 
00381      ARB_HANDLE q = p[-1];
00382      if (ARB_const_ubnd(p) && 
00383          ARB_const_lbnd(p) && 
00384          ARB_const_stride(q)) {
00385         
00386         Set_ARB_const_stride(p);
00387         Set_ARB_stride_val(p, bit_to_byte(last_bitsize));
00388         
00389      } else {
00390         
00391         Set_ARB_const_stride(p);
00392         Set_ARB_stride_val(p, ARB_stride_val(decl_bounds[0]));
00393      }
00394   }
00395   
00396   last_bitsize = bitsize ;
00397 
00398   if (axis == 1) {     /* initialize */
00399 
00400     distribute_onto=FALSE;
00401     decl_distributed_pragma_id=WN_PRAGMA_UNDEFINED;
00402     decl_distribute_pragmas =NULL;
00403   }
00404 
00405   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_ONTO_EXPR)) {
00406     distribute_onto=TRUE;
00407     /* get the WN for the constant */
00408     wn = cwh_expr_operand(NULL);
00409     Is_True( (WN_operator(wn)==OPR_INTCONST),("ONTO: expected integer constant"));
00410     Is_True( (distribution!=Star_Dist),("ONTO: unexpected for * distribution"));
00411     decl_onto[top_of_decl_bounds]=wn;
00412   }
00413 
00414   /* if this array is distributed, save the distribution information */
00415   switch(distribution) {
00416     case Block_Dist:
00417         decl_distribution[top_of_decl_bounds] = DISTRIBUTE_BLOCK;
00418         break;
00419     case Star_Dist:
00420         decl_distribution[top_of_decl_bounds]=DISTRIBUTE_STAR;
00421         break;
00422     case Cyclic_Dist:
00423         if (test_flag(flag_bits,FEI_ARRAY_DIMEN_DIST_EXPR)) {
00424           /* get the WN for the constant */
00425           wn = cwh_expr_operand(NULL);
00426           if(WN_operator(wn)==OPR_INTCONST) {
00427             decl_cyclic_val[top_of_decl_bounds].val=WN_const_val(wn);
00428             decl_distribution[top_of_decl_bounds]=DISTRIBUTE_CYCLIC_CONST;
00429           } else {
00430             /* this is a expression */
00431             decl_cyclic_val[top_of_decl_bounds].wn=wn;
00432             decl_distribution[top_of_decl_bounds]=DISTRIBUTE_CYCLIC_EXPR;
00433           } 
00434         } else {
00435           /* cyclic by itself is same as cyclic(1) */
00436           decl_cyclic_val[top_of_decl_bounds].val=1;
00437           decl_distribution[top_of_decl_bounds]=DISTRIBUTE_CYCLIC_CONST;
00438         }
00439         break;
00440   }
00441   
00442   if (distribution != No_Dist) {
00443     decl_distributed_pragma_id=test_flag(flag_bits,FEI_ARRAY_DIMEN_DIST_RESHAPE)?WN_PRAGMA_DISTRIBUTE_RESHAPE:WN_PRAGMA_DISTRIBUTE;
00444   }
00445 
00446   return(cast_to_int(&p));
00447 }
00448 
00449 
00450 //------------------------------------
00451 //----------------------------------
00452 extern INTPTR
00453 fei_co_array_dimen(INT32  flag_bits,
00454                 INT64  low_bound,
00455                 INT64  extent,
00456                 INT32  arraydims,
00457                 INT32  axis,
00458                 TYPE   span_type,
00459                 INT64  bitsize,
00460                 INT    distribution,
00461                 INT64  upper_bound)
00462 {
00463   ST * st;
00464   STB_pkt *b;
00465   WN  *wn ;
00466   BOOL hosted ;
00467   ST_IDX st_idx;
00468   ARB_HANDLE p;
00469   BOOL flow_dependent;
00470 
00471   hosted = test_flag(flag_bits,FEI_ARRAY_DIMEN_HOSTED_TYPE) || in_hosted_dtype ;
00472 
00473   top_of_decl_bounds = arraydims;
00474 
00475   if (top_of_decl_bounds == ANULL && axis == 1) { /*no array rank */
00476      decl_bounds = New_ARB();
00477      p = decl_bounds;
00478   } else {
00479      p = New_ARB();
00480   }
00481 
00482   co_top_decl_bounds = axis;
00483 
00484   flow_dependent = test_flag(flag_bits,FEI_ARRAY_DIMEN_FLOW_DEPENDENT);
00485 
00486   ARB_Init (p, 1, 1, 1);
00487 
00488   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_VARY_LB)) {
00489 
00490     b = cast_to_STB((UINTPS) low_bound) ;
00491     Is_True((b->form == is_ST),("Odd lbound"));
00492 
00493     st = cast_to_ST(b->item);
00494     Clear_ARB_const_lbnd(p);
00495     Set_ARB_lbnd_var(p, ST_st_idx(st));
00496 
00497     if (!hosted && !flow_dependent)
00498         cwh_types_copyin_pragma(st);
00499 
00500   } else {
00501   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_EMPTY_LB)) {
00502      Clear_ARB_const_lbnd(p);
00503      Set_ARB_empty_lbnd(p);
00504    } else {
00505 
00506     Set_ARB_const_lbnd(p);
00507     Set_ARB_lbnd_val (p, low_bound);
00508   }
00509  }
00510   
00511   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_VARY_UB)) {
00512 
00513     b = cast_to_STB((UINTPS) upper_bound) ;
00514     if (b != NULL) {
00515       Is_True((b->form == is_ST),("Odd extent"));
00516       
00517       st = cast_to_ST(b->item);
00518 
00519       Clear_ARB_const_ubnd(p);
00520       Set_ARB_ubnd_var(p, ST_st_idx(st));
00521 
00522       if (!hosted && !flow_dependent)
00523           cwh_types_copyin_pragma(st);
00524 
00525     }
00526    } else {
00527    if (test_flag(flag_bits,FEI_ARRAY_DIMEN_EMPTY_UB)) {
00528         Clear_ARB_const_ubnd(p);
00529      Set_ARB_empty_ubnd(p);
00530     }
00531    else {  /* constant ub */
00532     
00533     Set_ARB_const_ubnd(p);
00534     Set_ARB_ubnd_val (p, upper_bound);
00535   }
00536  }
00537 
00538 
00539   /* set pragma on extent, for MP/LNO, doesn't go into ARB */
00540 
00541   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_VARY_EXT)) {
00542 
00543     b = cast_to_STB((UINTPS) extent) ;
00544     if (b != NULL) {
00545       Is_True((b->form == is_ST),("Odd extent"));
00546       
00547       st = cast_to_ST(b->item);
00548 
00549       if (!hosted && !flow_dependent)
00550         cwh_types_copyin_pragma(st);
00551     }
00552   }
00553 
00554   /* update stride - the argument is the bitsize of the */
00555   /* current axis, but a TY has the size of an element  */
00556   /* so save the bitsize till next dimension. If stride */
00557   /* isn't constant bitsize becomes 0, and the TY tree  */
00558   /* seems to require the element size */
00559   if (axis == 1 && top_of_decl_bounds == ANULL) {
00560      
00561      ty_dim1 = cast_to_TY(t_TY(span_type)) ;
00562      
00563      Set_ARB_const_stride(p);
00564      Set_ARB_stride_val(p, TY_size(Ty_Table[ty_dim1]));
00565      
00566   } else { 
00567      ARB_HANDLE q = p[-1];
00568      if (ARB_const_ubnd(p) && 
00569          ARB_const_lbnd(p) && 
00570          ARB_const_stride(q)) {
00571         
00572         Set_ARB_const_stride(p);
00573         Set_ARB_stride_val(p, bit_to_byte(last_bitsize));
00574         
00575      } else {
00576         
00577         Set_ARB_const_stride(p);
00578         Set_ARB_stride_val(p, ARB_stride_val(decl_bounds[0]));
00579      }
00580   }
00581   
00582   last_bitsize = bitsize ;
00583 
00584   if (axis == 1 && top_of_decl_bounds == ANULL) {     /* initialize */
00585 
00586     distribute_onto=FALSE;
00587     decl_distributed_pragma_id=WN_PRAGMA_UNDEFINED;
00588     decl_distribute_pragmas =NULL;
00589   }
00590 
00591  if (top_of_decl_bounds == ANULL) 
00592         top_of_decl_bounds = axis-1;
00593  else
00594         top_of_decl_bounds = top_of_decl_bounds+(axis-1);
00595 
00596   if (test_flag(flag_bits,FEI_ARRAY_DIMEN_ONTO_EXPR)) {
00597     distribute_onto=TRUE;
00598     /* get the WN for the constant */
00599     wn = cwh_expr_operand(NULL);
00600     Is_True( (WN_operator(wn)==OPR_INTCONST),("ONTO: expected integer constant"));
00601     Is_True( (distribution!=Star_Dist),("ONTO: unexpected for * distribution"));
00602     decl_onto[top_of_decl_bounds]=wn;
00603   }
00604 
00605   /* if this array is distributed, save the distribution information */
00606   switch(distribution) {
00607     case Block_Dist:
00608         decl_distribution[top_of_decl_bounds] = DISTRIBUTE_BLOCK;
00609         break;
00610     case Star_Dist:
00611         decl_distribution[top_of_decl_bounds]=DISTRIBUTE_STAR;
00612         break;
00613     case Cyclic_Dist:
00614         if (test_flag(flag_bits,FEI_ARRAY_DIMEN_DIST_EXPR)) {
00615           /* get the WN for the constant */
00616           wn = cwh_expr_operand(NULL);
00617           if(WN_operator(wn)==OPR_INTCONST) {
00618             decl_cyclic_val[top_of_decl_bounds].val=WN_const_val(wn);
00619             decl_distribution[top_of_decl_bounds]=DISTRIBUTE_CYCLIC_CONST;
00620           } else {
00621             /* this is a expression */
00622             decl_cyclic_val[top_of_decl_bounds].wn=wn;
00623             decl_distribution[top_of_decl_bounds]=DISTRIBUTE_CYCLIC_EXPR;
00624           } 
00625         } else {
00626           /* cyclic by itself is same as cyclic(1) */
00627           decl_cyclic_val[top_of_decl_bounds].val=1;
00628           decl_distribution[top_of_decl_bounds]=DISTRIBUTE_CYCLIC_CONST;
00629         }
00630         break;
00631   }
00632   
00633   if (distribution != No_Dist) {
00634     decl_distributed_pragma_id=test_flag(flag_bits,FEI_ARRAY_DIMEN_DIST_RESHAPE)?WN_PRAGMA_DISTRIBUTE_RESHAPE:WN_PRAGMA_DISTRIBUTE;
00635   }
00636 
00637   return(cast_to_int(&p));
00638 }
00639 
00640 
00641 /*===================================================
00642  *
00643  * fei_next_type_idx
00644  *
00645  * get a new TY to hand to fei_user_type   
00646  *
00647  ====================================================
00648 */
00649 extern INT32
00650 fei_next_type_idx(INT32 flag, INT32 align)
00651 {
00652   TY_IDX ty_idx;
00653 
00654   if (!cwh_types_in_dtype())
00655     in_hosted_dtype =  test_flag(flag,FEI_NEXT_TYPE_IDX_HOSTED_TYPE);
00656 
00657   ty_idx = cwh_types_new_TY(in_hosted_dtype,
00658                             bit_to_byte(align)) ;
00659 
00660   BUMP_TY_COUNTER(c_TY_DTYPE);
00661 
00662   return(cast_to_int(ty_idx));
00663 }
00664 
00665 /*===================================================
00666  * fei_imported_type 
00667  * 
00668  ====================================================
00669 */
00670 extern INT32
00671 fei_imported_type(char  *name_string,
00672                   INTPTR modst_idx)
00673 {
00674       TY_IDX ty_idx;
00675       STB_pkt  *modp;
00676       ST *st;
00677 
00678       modp = cast_to_STB(modst_idx);
00679       st = cwh_stab_seen_derived_type_or_imported_var(cast_to_ST(modp->item),name_string);
00680       if (st) {
00681           ty_idx = ST_type(st);
00682           return (cast_to_int(ty_idx));
00683        } else
00684            return 0;
00685 } /* fei_imported_type */
00686 
00687 
00688 /*===================================================
00689  * fei_get_pdg_type
00690  * 
00691  ====================================================
00692 */
00693 
00694 extern TYPE 
00695 fei_get_pdg_type(INT32          ty_idx, 
00696                  INT32          table_type,
00697                  INT32          basic_type,
00698                  INT32          nbr_components)
00699 { 
00700   TYPE t ;
00701   dtype_t d ;
00702   INT32 i;
00703 
00704   TY& ty = Ty_Table[cast_to_TY(ty_idx)];
00705   t.table_type = (TABLE_TYPE)table_type ;
00706   t.basic_type = (BASIC_TYPE)basic_type ;
00707   cwh_types_fill_type(0,&t,(TY_IDX)ty_idx);
00708                                      
00709   for (i=0; i<nbr_components; i++) {
00710      FLD_HANDLE fld = New_FLD ();
00711      if (i == 0) {
00712         Set_TY_fld(ty, fld);
00713         d.dty_last = fld.Idx ();
00714      }
00715   }
00716 
00717   d.dty = ty_idx ;
00718   d.ncompos  = nbr_components ;
00719 //  d.seq      = (sequence != Seq_None);
00720 //  d.hosted   = in_hosted_dtype ;
00721                                                                                       
00722   cwh_types_push_dtype(d);
00723 
00724   return(t);
00725 }
00726 /*===================================================
00727  *
00728  * fei_user_type
00729  *
00730  * The definition of a new derived type. Create 
00731  * the STRUCT type, and add components with 
00732  * fei_new_member - the TY to fill is cr_ty_idx.
00733  *
00734  * This may be a derived type component of a
00735  * derived type, so a stack preserves the
00736  * parent derived type and makes the new
00737  * one current for fei_member.
00738  *
00739  * The alignments and offsets are provided by
00740  * fei_member, so make a default alignment here
00741  * and patch it up in fei_member.
00742  *
00743  ====================================================
00744 */
00745 /*ARGSUSED*/
00746 void
00747 fei_user_type(char         *name_string,
00748               INT32         nbr_components,
00749               INT64         size,
00750               INT32         sequence_arg,
00751               INT32         cr_ty_idx,
00752               INT32         align,
00753               INTPTR        modst_idx,
00754               INT32         definition)
00755     
00756 {
00757   TY_IDX ty_idx    ;
00758   TYPE t;
00759   dtype_t  d ;
00760   FORT_SEQUENCE sequence;
00761   INT32 i;
00762   ST *st, *currscp;
00763   STB_pkt  *modp;
00764   
00765 
00766  if (modst_idx)
00767    {
00768       modp = cast_to_STB(modst_idx);
00769       currscp = cast_to_ST(modp->item);
00770  } else 
00771      currscp = Scope_tab[CURRENT_SYMTAB].st;
00772 
00773  if (size==0)
00774        size =64; /*default shape array or pointer 
00775                    is 8bytes i.e 64 bits, */
00776   sequence = (FORT_SEQUENCE) sequence_arg;
00777 
00778   ty_idx = cast_to_TY(cr_ty_idx);
00779   TY& ty = Ty_Table[ty_idx];
00780 
00781   TY_Init (ty, bit_to_byte(size), KIND_STRUCT, MTYPE_M, Save_Str(name_string));
00782 
00783   if (sequence == Seq_Mixed ||
00784       sequence == Seq_Char  || 
00785       sequence == Seq_Numeric)
00786        Set_TY_is_sequence(ty);
00787 
00788   if (definition) {
00789      st = New_ST(GLOBAL_SYMTAB);
00790      ST_Init(st,
00791           Save_Str(name_string),
00792           CLASS_TYPE,
00793           SCLASS_UNKNOWN,
00794           EXPORT_LOCAL,
00795           ty_idx);
00796      Set_ST_base(st,currscp);
00797      cwh_auxst_add_item(currscp,st,l_TYMDLIST) ;
00798    }
00799 
00800   for (i=0; i<nbr_components; i++) {
00801      FLD_HANDLE fld = New_FLD ();
00802      if (i == 0) {
00803         Set_TY_fld(ty, fld);
00804         d.dty_last = fld.Idx ();
00805      }
00806   }
00807         
00808   /* this acts as a flag that stride_multipliers in 
00809    * dope vectors are in bytes, not words.
00810    */
00811   if (sequence ==  Seq_Char) {
00812      Set_TY_is_packed(ty);
00813     }
00814 
00815   d.dty = ty_idx ;
00816   d.ncompos  = nbr_components ;
00817   d.seq      = (sequence != Seq_None);
00818   d.hosted   = in_hosted_dtype ;
00819 
00820   cwh_types_push_dtype(d);
00821   
00822   return  ;
00823 
00824 }
00825 
00826 void fei_gen_st_for_type(char *name_string,
00827                          TYPE type_idx, 
00828                          INTPTR modst_idx)
00829 {
00830    ST * st, *modst;
00831    STB_pkt *p;
00832    TY_IDX ty_idx;
00833 
00834    if (modst_idx) {
00835           p = cast_to_STB(modst_idx);
00836           modst = cast_to_ST(p->item) ;
00837    } else 
00838       modst = Scope_tab[CURRENT_SYMTAB].st;
00839 
00840     st = cwh_stab_seen_derived_type_or_imported_var(modst,name_string);
00841 
00842     if (st)
00843          return;
00844 
00845     ty_idx = cast_to_TY(t_TY(type_idx)); 
00846     st = New_ST(GLOBAL_SYMTAB);
00847 
00848     ST_Init(st,
00849          Save_Str(name_string),
00850          CLASS_TYPE,
00851          SCLASS_UNKNOWN,
00852          EXPORT_LOCAL,
00853          ty_idx);
00854 
00855      Set_ST_base(st,modst);
00856      cwh_auxst_add_item(modst,st,l_TYMDLIST) ;
00857      return ;
00858 }
00859 /*===================================================
00860  *
00861  * fei_member
00862  *
00863  * Add the definition of a new component to the 
00864  * current derived type. If it's the last
00865  * component, enter the TY, otherwise push it
00866  * back on the stack
00867  *
00868  ====================================================
00869 */
00870 /*ARGSUSED*/
00871 INT32
00872 fei_member(char          *name_string,
00873            TYPE           member_type,
00874            INT64          offset,
00875            INT64          size,
00876            INT32          alignment,
00877            INT32          lineno,
00878            INT64          flag_bits,
00879            INT64          io_code)
00880 {
00881   dtype_t d ;
00882   TY_IDX ty_idx;
00883   TY_IDX tr_idx;
00884   BOOL p1   ;
00885   INT64  off;
00886   INT32 ret_val;
00887 
00888   ty_idx = cast_to_TY(t_TY(member_type));
00889   p1 = test_flag(flag_bits, FEI_OBJECT_DV_IS_PTR);
00890 
00891   /* does offset imply component is misaligned? */
00892 
00893   off = bit_to_byte(offset);
00894 
00895   Is_True((off%TY_align(ty_idx) == 0), ("Misalign"));
00896 
00897   if (p1) {
00898     Is_True(TY_is_f90_pointer(Ty_Table[ty_idx]),(" Missing f90ptr"));
00899   } else {
00900     Is_True(!TY_is_f90_pointer(Ty_Table[ty_idx]),(" extra f90ptr"));
00901   }
00902 
00903 
00904   d = cwh_types_pop_dtype();
00905 
00906   /* is enclosing derived type on more stringent alignment? */
00907 
00908   Is_True((TY_align(d.dty) >= TY_align(ty_idx)), ("Misalign, enclosing"));
00909 
00910   FLD_HANDLE fld (d.dty_last);
00911 
00912    if (p1) {
00913      tr_idx = Make_F90_Pointer_Type(ty_idx);
00914      Set_TY_is_f90_pointer(tr_idx);
00915     }
00916    else 
00917      tr_idx = ty_idx;
00918 
00919   FLD_Init (fld, Save_Str(name_string), tr_idx, off);
00920 
00921   if (p1)
00922    Set_FLD_is_pointer(fld);
00923 
00924   ret_val = d.dty_last;
00925 
00926   d.dty_last++;
00927 
00928   if (--d.ncompos == 0) {
00929   
00930     Set_FLD_last_field(fld);
00931 //    d.dty = cwh_types_unique_TY(d.dty);
00932 
00933     if (!cwh_types_in_dtype())
00934       in_hosted_dtype = FALSE ;
00935 
00936   } else 
00937     cwh_types_push_dtype(d);
00938 
00939   return (ret_val);
00940 }
00941 
00942 /*===================================================
00943  *
00944  * fei_dope_vector
00945  *
00946  * Build a dope vector TY for an array of the given
00947  * rank and scalar type.
00948  *
00949  ====================================================
00950  */
00951 extern TYPE 
00952 fei_dope_vector(INT32  num_dims,TYPE base_type, INT32 flag)
00953 {                                     
00954   TY_IDX ty_idx   ;
00955   TY_IDX ts_idx   ;
00956   TYPE  t    ;
00957   BOOL  b    ;
00958   
00959   ts_idx = cast_to_TY(t_TY(base_type));
00960   b  = test_flag(flag,FEI_DOPE_VECTOR_HOSTED_TYPE) || in_hosted_dtype;
00961   ty_idx = cwh_types_dope_TY(num_dims,ts_idx,b,test_flag(flag,FEI_DOPE_VECTOR_POINTER)) ;
00962 
00963   t.table_type = Basic ;
00964   t.basic_type = S_tructure ;
00965 
00966   cwh_types_fill_type(0,&t,ty_idx);
00967 
00968   return(t);
00969 }
00970 
00971 /*===================================================
00972  *
00973  * cwh_types_mk_basic_TY
00974  *
00975  * Given a PDGCS basic type, return a TY.
00976  *
00977  * Integer, real and complex variants are predefined
00978  * TYs, if they are aligned on a natural boundary, 
00979  * but logicals and characters aren't. The size
00980  * of a character type is a WN * which describes 
00981  * the len= type parameter. May be temp or constant.
00982  *
00983  * Basic types are entered in the global symbol 
00984  * table, except structures, which are entered
00985  * when all components have been seen (fei_member)
00986  *
00987  ====================================================
00988 */
00989 
00990 static TY_IDX
00991 cwh_types_mk_basic_TY (BASIC_TYPE    basic_type,
00992                        INTPTR        size,
00993                        mUINT16       alignment)
00994 {
00995   TY_IDX    ty_idx ;
00996   TYPE_ID   bt ;
00997   STB_pkt * p ;
00998   WN      * wn;
00999   static TY_IDX char_ptr_ty_idx = 0 ;
01000 
01001   ty_idx = 0 ;
01002 
01003   switch(basic_type) {
01004 
01005   case L_ogical:
01006     ty_idx = cwh_types_mk_logical_TY(size,alignment);
01007     break ;
01008 
01009   case Char_Fortran:
01010     p = cast_to_STB(size);
01011 
01012     switch (p->form) {
01013     case is_WN:
01014       wn = cast_to_WN(p->item);
01015       if (WNOPR(wn) == OPR_INTCONST)
01016         wn = bit_to_byte_WN(wn);
01017       ty_idx = cwh_types_mk_character_TY(wn,NULL,TRUE);
01018       break;
01019 
01020     case is_ST:
01021       ty_idx = cwh_types_mk_character_TY(NULL,cast_to_ST(p->item),FALSE);
01022       break;
01023 
01024     default:
01025       Is_True((0),("odd TY const"));
01026     }
01027     break ;
01028 
01029   case C_omplex:
01030     bt = Mtypes[align_index(size/2)][basic_index(basic_type)];   
01031     ty_idx = Be_Type_Tbl(bt);
01032     ty_idx = cwh_types_mk_misaligned_TY(ty_idx,alignment) ;
01033     break ;
01034 
01035   case S_tructure:
01036     ty_idx = cast_to_TY(size);
01037     break ;
01038 
01039   case CRI_Pointer_Char:
01040 
01041      /* We will make this a struct with two fields for now */
01042 
01043     if (char_ptr_ty_idx == 0 ) {
01044 
01045       FLD_HANDLE list = cwh_types_fld_util("base", Be_Type_Tbl(Pointer_Mtype),
01046                                            0,TRUE);
01047       FLD_HANDLE fld =  cwh_types_fld_util("len", Be_Type_Tbl(Pointer_Mtype),
01048                                            Pointer_Size,TRUE);
01049       Set_FLD_last_field(fld);
01050       char_ptr_ty_idx = cwh_types_mk_struct(2*Pointer_Size, Pointer_Size, list,
01051                                             ".char_pointer");
01052     }
01053     
01054     ty_idx = char_ptr_ty_idx ;
01055     break;
01056 
01057 
01058   case CRI_Pointer:
01059     ty_idx = Be_Type_Tbl(Pointer_Mtype);
01060     break ;
01061 
01062   case T_ypeless: 
01063 
01064     /* if large, Make a 1d array TY of unsigned bytes - make it global     */
01065     /* because it's probably for a pattern con which requires a global TY  */
01066     /* as the constant is inserted into Strtab                             */
01067     
01068     if (size == 8) {
01069        ty_idx = Be_Type_Tbl(MTYPE_U1);
01070     } else if (size==16) {
01071        ty_idx = Be_Type_Tbl(MTYPE_U2);
01072     } else if (size==32) {
01073        ty_idx = Be_Type_Tbl(MTYPE_U4);
01074     } else if (size==64) {
01075        ty_idx = Be_Type_Tbl(MTYPE_U8);
01076     } else {
01077       
01078       ty_idx = cwh_types_array_util(1,Be_Type_Tbl(MTYPE_U1),1,bit_to_byte(size),".typeless.",TRUE);
01079      
01080       ARB_HANDLE arb = TY_arb(ty_idx);
01081       Set_ARB_stride_val(arb, 1);
01082       Set_ARB_ubnd_val(arb, bit_to_byte(size) - 1);
01083       
01084       ty_idx = cwh_types_unique_TY(ty_idx);
01085     }
01086     break ;
01087 
01088   default:
01089     bt = Mtypes[align_index(size)][basic_index(basic_type)];     
01090     ty_idx = Be_Type_Tbl(bt);
01091     ty_idx = cwh_types_mk_misaligned_TY(ty_idx,alignment) ;
01092     break;
01093   }
01094   
01095   return(ty_idx);
01096 }
01097 
01098 /*===================================================
01099  *
01100  * cwh_types_mk_misaligned_TY
01101  *
01102  * If the alignment of the TY isn't small enough
01103  * a copy of the TY with the correct alignment will
01104  * be returned, otherwise the original TY.
01105  * 
01106  * alignment is # of bytes 1 - byte
01107  *                         2 - 16 bit
01108  *                         4 - 32 bit
01109  *                         8 - 64 bit
01110  *
01111  * and the 64 bit one is ignored. Works only for
01112  * basic types.
01113  *
01114  ====================================================
01115 */
01116 static TY_IDX
01117 cwh_types_mk_misaligned_TY(TY_IDX ty_idx, mUINT16 alignment)
01118 {
01119   TY_IDX tc_idx = ty_idx ;
01120   TY& ty = Ty_Table[ty_idx];
01121   
01122   if (TY_kind(ty) == KIND_SCALAR) {
01123     if (alignment <= 4) {
01124       if (alignment > 0) {
01125         if (TY_align(ty_idx) > alignment ) {
01126 
01127           tc_idx = unaligned_type [TY_mtype(ty)][alignment_to_align(alignment)];
01128 
01129           if (tc_idx == 0) {
01130 
01131             BUMP_TY_COUNTER(c_TY_MISC);
01132             tc_idx = cwh_types_new_TY ( TRUE , alignment);
01133             TY& tc = Ty_Table[tc_idx];
01134 
01135             TY_Init (tc, TY_size(ty), TY_kind(ty), TY_mtype(ty), Save_Str2(TY_name(ty),alstr[alignment_to_align(alignment)])); 
01136 
01137             Set_TY_flags(tc, TY_flags(ty));
01138 
01139             tc_idx = cwh_types_unique_TY(tc_idx);
01140 
01141             unaligned_type [TY_mtype(ty)][alignment_to_align(alignment)] = tc_idx ;
01142           }
01143         }
01144       }
01145     }
01146   }
01147   return tc_idx ;
01148 }
01149 
01150 /*===================================================
01151  *
01152  * cwh_types_form_misaligned_TY
01153  *
01154  * Given a TY and an alignment which is smaller
01155  * than its natural alignment, copy the TY but
01156  * enforce the alignment provided.
01157  * 
01158  * alignment is # of bytes ie: 1-8.
01159  *
01160  * In general derived types should have the correct
01161  * alignment set up in fei_member. If a dummy has to 
01162  * be misaligned though, it may be a derived type that
01163  * was aligned to a large value. eg: (F8,F8) Recursive
01164  * types can only arise via dope vectors, which are 
01165  * assumed to be correctly aligned.
01166  *
01167  * The assumption is that the TY is in the 
01168  * Current_Symtab, if not, then a new hosted 
01169  * flag is required. 
01170  *
01171  ====================================================
01172 */
01173 extern TY_IDX
01174 cwh_types_form_misaligned_TY(TY_IDX ty_idx, mUINT16 alignment)
01175 {
01176   TY_IDX  tr_idx ;
01177   TY_IDX  tt_idx ;
01178   INT num ;
01179   char *  const misstr = ".mis";
01180 
01181   TY& ty = Ty_Table[ty_idx];
01182 
01183   if (TY_align(ty_idx) <= alignment)
01184     return ty_idx ;
01185 
01186   switch(TY_kind(ty)) {
01187   case KIND_SCALAR:
01188     if (TY_is_logical(ty))
01189       tr_idx = cwh_types_mk_logical_TY(byte_to_bit(TY_size(ty)),alignment) ;
01190     else 
01191       tr_idx = cwh_types_mk_misaligned_TY(ty_idx,alignment) ;
01192     break ;
01193 
01194   case KIND_ARRAY:
01195    {
01196     tt_idx = cwh_types_form_misaligned_TY(TY_etype(ty),alignment);
01197     tr_idx = Copy_TY(ty_idx);  /* copies whole TY ***  */
01198     TY &tr = Ty_Table[tr_idx];
01199     Set_TY_etype(tr, tt_idx);
01200     Set_TY_align(tr_idx, alignment);
01201     Set_TY_name_idx(tr, Save_Str2(TY_name(tr),misstr));
01202     break;
01203    }
01204   case KIND_STRUCT:
01205     if (cwh_types_is_dope(ty_idx)) {
01206       tr_idx = ty_idx ;
01207 
01208     } else {
01209       FLD_ITER fld_iter = Make_fld_iter (TY_fld (ty));
01210       FLD_HANDLE c_fld;
01211       do {
01212         FLD_HANDLE p (fld_iter);
01213         FLD_HANDLE fld = New_FLD ();
01214         if (p == TY_fld (ty))
01215             c_fld = fld;
01216          FLD_Init (fld, 
01217                    Save_Str2(FLD_name(p),misstr), 
01218                    cwh_types_form_misaligned_TY(FLD_type(p), alignment),
01219                    FLD_ofst(p));
01220          Set_FLD_bofst(fld, FLD_bofst(p));
01221          Set_FLD_bsize(fld, FLD_bsize(p));
01222          Set_FLD_flags(fld, FLD_flags(p));
01223       } while (!FLD_last_field (fld_iter++));
01224 
01225       tr_idx = Copy_TY(ty_idx);
01226       TY &tr = Ty_Table[tr_idx];
01227       Set_TY_align(tr_idx, alignment);
01228       Set_TY_fld(tr, c_fld);
01229 
01230       Set_TY_name_idx(tr, Save_Str2(TY_name(ty),misstr));
01231     }
01232     break;
01233     
01234 
01235   case KIND_POINTER:
01236     tr_idx = ty_idx ;
01237     break ;
01238 
01239   default:
01240     Is_True((0),("Odd misalignment"));
01241     
01242   }
01243   
01244   return tr_idx;
01245 }
01246 
01247 /*===================================================
01248  *
01249  * cwh_types_mk_procedure_TY
01250  *
01251  * Given a TY for a return type, create a corresponding 
01252  * TY for an external procedure. Dummy arguments are 
01253  * not set up here, but an FTI of the correct size is
01254  * created. fei_object adds the dummies.Later : we omit
01255  * the TY parm list, as it doesn't seem to be needed.
01256  * Finally, we make sure we build hosted procedure types
01257  * in the right symbol table.
01258  *
01259  ====================================================
01260 */
01261 extern TY_IDX 
01262 cwh_types_mk_procedure_TY (TY_IDX ret_typ_idx, INT32 nparms, BOOL global, BOOL host)
01263 {
01264   TY_IDX ty_idx ;
01265   TYLIST tylist_idx;
01266 
01267   static TY_IDX basic_subroutine_TY_idx = 0 ;
01268   TY &ret_typ = Ty_Table[ret_typ_idx];
01269   
01270   if ( nparms == 0 )
01271     if (MTYPE_is_void(TY_mtype(ret_typ)))  
01272       if (basic_subroutine_TY_idx != 0) 
01273         return (basic_subroutine_TY_idx) ;
01274       else
01275         global = TRUE;
01276 
01277   BUMP_TY_COUNTER(c_TY_PROC) ;
01278   ty_idx  = cwh_types_new_TY (global,1) ;
01279   TY &ty = Ty_Table[ty_idx];
01280 
01281   TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, Save_Str(cwh_types_mk_anon_name(".proc.")));
01282 
01283   /* If nparms is > 0, we set the ret_type, but may change it
01284    * later for structs by value (don't have context yet. The 
01285    * TY_list is established in fei_proc_body. Hence don't match
01286    * TYs yet. (special case is void types, changed to structs).
01287    */
01288 
01289 /*  if (nparms == 0) {
01290  * When nparms>0 we have to set ret_typ_idx too,since this maybe happend 
01291  * When the PU is appear in interface blk 
01292  */
01293     (void) New_TYLIST (tylist_idx);
01294     Set_TY_tylist(ty, tylist_idx);
01295     Tylist_Table [tylist_idx] = ret_typ_idx;
01296     (void) New_TYLIST (tylist_idx);
01297     Tylist_Table [tylist_idx] = 0;
01298 /*  } */
01299 
01300   if (nparms == 0)
01301     if (MTYPE_is_void(TY_mtype(ret_typ)))
01302       basic_subroutine_TY_idx = ty_idx ;
01303   
01304   return (ty_idx);
01305   
01306 }
01307 
01308 /*===================================================
01309  *
01310  * cwh_types_mk_array_TY
01311  *
01312  * Create an array TY. The ARB information 
01313  * has been setup in the argument bounds,
01314  * the element TY in base, and the size of
01315  * the array in size. 
01316  * 
01317  * Allocate the TY and ARI nodes, copy & return.
01318  *
01319  * Ignore any first/last dimension stuff in the
01320  * bounds array.
01321  *
01322  * Note that the bounds pointed at by the ARB_HANDLE are in
01323  * Fortran order, and need to be reversed to C order
01324  *
01325  ====================================================
01326 */
01327 static TY_IDX
01328 cwh_types_mk_array_TY(ARB_HANDLE bounds,INT16 n,TY_IDX base_idx, INT64 size)
01329 {
01330   TY_IDX ty_idx   ;
01331   BOOL const_str = TRUE; 
01332   int     i;
01333 
01334 
01335   ty_idx = cwh_types_array_util(n,base_idx,TY_align(base_idx),0,".array.",FALSE);
01336   Set_TY_arb(ty_idx,bounds);
01337 
01338 
01339   // Step 1, reverse the bounds
01340   for (i = 0; i < n/2; i++) {
01341      ARB_swap(bounds[i],bounds[n-i-1]);
01342   }
01343 
01344   // Step 2, set the first, last and dimension bits
01345 if (co_top_decl_bounds != ANULL) {
01346   for (i = 0; i < co_top_decl_bounds ; i++) {
01347      Clear_ARB_first_dimen(bounds[i]);
01348      Clear_ARB_last_dimen(bounds[i]);
01349      Set_ARB_dimension(bounds[i],n-i);
01350      Set_ARB_co_dimension(bounds[i],co_top_decl_bounds);
01351      const_str = const_str && ARB_const_stride(bounds[i]);
01352   }
01353   for (i = co_top_decl_bounds; i < n ; i++) {
01354      Clear_ARB_first_dimen(bounds[i]);
01355      Clear_ARB_last_dimen(bounds[i]);
01356      Set_ARB_dimension(bounds[i],n-i);
01357      Set_ARB_co_dimension(bounds[i],co_top_decl_bounds);
01358      const_str = const_str && ARB_const_stride(bounds[i]);
01359   }
01360  } else
01361     {  for (i = 0; i < n ; i++) {
01362        Clear_ARB_first_dimen(bounds[i]);
01363        Clear_ARB_last_dimen(bounds[i]);
01364        Set_ARB_dimension(bounds[i],n-i);
01365        Set_ARB_co_dimension(bounds[i],0);
01366        const_str = const_str && ARB_const_stride(bounds[i]);
01367       }
01368   }
01369 
01370   Set_ARB_first_dimen(bounds[0]);
01371   Set_ARB_last_dimen(bounds[n-1]);
01372 
01373   if ( const_str && size!=0) 
01374         Set_TY_size(ty_idx, size);
01375   else 
01376         Set_TY_size(ty_idx, 8); //pointer get 8-bytes
01377 
01378 /*
01379  * move the function call "cwh_types_unique_TY" to fei_descriptor
01380  * Since here we don't get all the flags of type
01381  * may mix different kind of arrays such as a(1:*) a(1:1)
01382  * are same type arrays
01383  * ----fzhao
01384  */
01385 //  ty_idx = cwh_types_unique_TY(ty_idx);
01386 
01387 
01388   return (ty_idx);
01389 }
01390 
01391 /*===================================================
01392  *
01393  * cwh_types_mk_logical_TY
01394  *
01395  * Make a logical TY - use a single global one
01396  * for each kind (size) and alignment.
01397  *
01398  ====================================================
01399 */
01400 extern TY_IDX
01401 cwh_types_mk_logical_TY(INT32 size, mUINT16 alignment)
01402 {
01403 
01404   TYPE_ID  bt ;  
01405   TY_IDX   ty_idx ;
01406   INT16    i  ;
01407   char   * csz;
01408   char   * aln;
01409   INT32 size_in_bytes;
01410 
01411   i = align_index(size) ;
01412   
01413   Is_True((i < NUM_LOG_KINDS),("Odd logical type")) ;
01414   
01415   if (basic_logical_ty[i][alignment_to_align(alignment)] == 0) {
01416 
01417     csz = logstr[i];
01418     aln = "";
01419 
01420     bt  = Mtypes[align_index(size)][basic_index(L_ogical)];      
01421     ty_idx  = cwh_types_new_TY (TRUE,alignment) ; 
01422     
01423     BUMP_TY_COUNTER(c_TY_MISC);
01424 
01425     size_in_bytes = bit_to_byte(size);
01426 
01427     if (size_in_bytes != alignment)
01428         aln = alstr[alignment_to_align(alignment)];
01429 
01430     TY &ty = Ty_Table[ty_idx];
01431     
01432     TY_Init (ty, size_in_bytes, KIND_SCALAR, bt, Save_Str2(csz,aln));
01433 
01434     Set_TY_is_logical(ty);
01435 
01436     ty_idx = cwh_types_unique_TY(ty_idx);
01437 
01438     basic_logical_ty[i][alignment_to_align(alignment)] = ty_idx ;
01439 
01440   }
01441   return (basic_logical_ty[i][alignment_to_align(alignment)]);
01442 }
01443 
01444 /*===================================================
01445  *
01446  * cwh_types_mk_character_TY
01447  *
01448  * Make a character TY. The TY should be an array
01449  * of sz bytes, but the char*1 TY may have to be 
01450  * made first. The sz is in bytes. It may be an ST 
01451  * or a WN, with a flag to distinguish.
01452  *
01453  ====================================================
01454 */
01455 TY_IDX
01456 cwh_types_mk_character_TY(WN *sz_wn, ST *sz_st, BOOL sz_is_wn)
01457 {
01458   INT64 i    ;
01459   TY_IDX ty_idx   ;
01460   BOOL global;
01461   BOOL const_sz;
01462 
01463   static TY_IDX basic_character_ty_idx = 0;
01464 
01465   if (basic_character_ty_idx == 0) {
01466 
01467     BUMP_TY_COUNTER(c_TY_MISC)  ;
01468 
01469     ty_idx = cwh_types_new_TY (TRUE,1) ; 
01470     TY &ty = Ty_Table[ty_idx];
01471 
01472     TY_Init (ty, 1, KIND_SCALAR, MTYPE_U1, Save_Str(".character."));
01473     Set_TY_is_character(ty);
01474 
01475     ty_idx = cwh_types_unique_TY(ty_idx);
01476 
01477     basic_character_ty_idx = ty_idx ;
01478   }
01479    
01480   ty_idx = cwh_types_array_util(1,basic_character_ty_idx,1,0,".ch_str.",TRUE);
01481   TY& ty = Ty_Table[ty_idx];
01482 
01483   ARB_HANDLE arb = TY_arb(ty);
01484 
01485   Set_ARB_lbnd_val(arb, 1);
01486   Set_ARB_stride_val(arb, 1);
01487 
01488   /* could be an ST, or WN constant or WN expression */
01489 
01490   if (!sz_is_wn) {
01491 
01492     Clear_ARB_const_ubnd(arb);
01493     Set_TY_size(ty, 0);
01494     Set_ARB_ubnd_var(arb,ST_st_idx(sz_st));
01495 
01496   } else if (WNOPR(sz_wn) == OPR_INTCONST) {
01497 
01498     i = WN_const_val(sz_wn) ;
01499     Set_ARB_ubnd_val(arb,i) ;
01500     Set_TY_size(ty, i);
01501 
01502   } else {  /* expression into temp, & temp into ARB */
01503 
01504 #ifndef SOURCE_TO_SOURCE
01505      {
01506 
01507       ST *st = cwh_types_make_bounds_ST();
01508 
01509       Clear_ARB_const_ubnd(arb);
01510       Set_TY_size(ty, 0);
01511       cwh_addr_store_ST(st,0,0,sz_wn);
01512       Set_ARB_ubnd_var(arb, ST_st_idx(st));
01513    }  
01514 # endif
01515   }
01516 
01517   Set_TY_is_character(ty);
01518   ty_idx = cwh_types_unique_TY(ty_idx);
01519   return(ty_idx);
01520 }
01521 
01522 
01523 /*===================================================
01524  *
01525  * cwh_types_scalar_TY
01526  *
01527  * Given a TY, find its scalar ty, ie: the bottom
01528  * of any KIND_ARRAYs
01529  *
01530  ====================================================
01531 */
01532 extern TY_IDX
01533 cwh_types_scalar_TY(TY_IDX ty_idx)
01534 {
01535   TY_IDX rty_idx ;
01536  
01537   TY& ty = Ty_Table[ty_idx];
01538 
01539   switch(TY_kind(ty)) {
01540 
01541   case KIND_VOID:  
01542   case KIND_SCALAR:  
01543   case KIND_STRUCT:  
01544   case KIND_POINTER:  
01545   case KIND_FUNCTION:  
01546     rty_idx = ty_idx;
01547     break;
01548 
01549   case KIND_ARRAY:
01550     rty_idx = cwh_types_scalar_TY(TY_etype(ty)) ;
01551     break;
01552 
01553   default:
01554     DUMP_TY(ty_idx);
01555     Is_True((0),("Odd ty"));
01556     break;
01557   }
01558 
01559   return(rty_idx);
01560 }
01561 
01562 /*===================================================
01563  *
01564  * cwh_types_array_TY
01565  *
01566  * Given a TY, find its array ty, ie: the bottom
01567  * of any KIND_POINTERS to a KIND_ARRAY etc...
01568  * Given a scalar, just hand it back..
01569  *
01570  ====================================================
01571 */
01572 extern TY_IDX
01573 cwh_types_array_TY(TY_IDX ty_idx)
01574 {
01575   TY_IDX rty_idx ;
01576 
01577   TY& ty = Ty_Table[ty_idx];
01578 
01579   switch(TY_kind(ty)) {
01580   case KIND_ARRAY:
01581   case KIND_SCALAR:
01582   case KIND_STRUCT:
01583   case KIND_FUNCTION:
01584   case KIND_VOID:  
01585     rty_idx = ty_idx;
01586     break;
01587 
01588   case KIND_POINTER:  
01589     rty_idx = cwh_types_array_TY(TY_pointed(ty)) ;
01590     break;
01591 
01592   default:
01593     DUMP_TY(ty_idx);
01594     Is_True((0),("Odd array ty"));
01595     break;
01596   }
01597 
01598   return(rty_idx);
01599 }
01600 
01601 /*===================================================
01602  *
01603  * cwh_types_WN_TY
01604  *
01605  * Given a WN, find the TY of what it addresses. Not
01606  * general - used in figuring out TYs when building
01607  * addresses. If flag addr is TRUE, the pointer TY
01608  * for a load is passed back rather than deref'd.
01609  * eg: for a PARM node the TY of an LDA can be
01610  * plucked off as is.
01611  * 
01612  * Some logical operators would yield an integer 
01613  * TY (no TY_is_logical flag) without the special 
01614  * checking here.
01615  *
01616  ====================================================
01617 */
01618 
01619 extern TY_IDX
01620 cwh_types_WN_TY(WN * wn, BOOL addr)
01621 {
01622   TY_IDX ty_idx = 0 ;
01623   WN *kid;
01624   INT i;
01625 
01626   switch (WNOPR(wn)) {
01627   case OPR_ARRAY:
01628   case OPR_ARRSECTION:
01629   case OPR_ARRAYEXP:
01630   case OPR_MLOAD:
01631   case OPR_PARM:
01632     ty_idx = cwh_types_WN_TY(WN_kid0(wn),addr);
01633     break ;
01634 
01635   case OPR_INTCONST:
01636     if (addr) {
01637       ty_idx = Make_Pointer_Type(Be_Type_Tbl(MTYPE_V));
01638     } else {
01639       ty_idx = Be_Type_Tbl(WN_rtype(wn));
01640     }
01641     break;
01642 
01643   case OPR_INTRINSIC_OP:
01644     /* Special case so that we handle character transformationals correctly */
01645 
01646     if (MTYPE_is_pointer(WN_rtype(wn)) || WN_opcode(wn) == OPC_MINTRINSIC_OP) {
01647        ty_idx = cwh_types_WN_TY(WN_kid0(wn),addr);
01648     } else {
01649        ty_idx = Be_Type_Tbl(WN_rtype(wn));
01650     }
01651     break;
01652     
01653   case OPR_LDA:
01654   case OPR_ILOAD:
01655   case OPR_LDID:
01656    {
01657     ty_idx = WN_ty(wn) ;
01658     TY &ty = Ty_Table[ty_idx];
01659 
01660     if (! addr) 
01661       if (TY_kind(ty) == KIND_POINTER)
01662         ty_idx = TY_pointed(ty);
01663    }
01664    break;
01665 
01666   case OPR_CIOR:
01667   case OPR_CAND:
01668   case OPR_LIOR:
01669   case OPR_LAND:
01670   case OPR_LNOT:
01671   case OPR_EQ:
01672   case OPR_NE:
01673     ty_idx = cwh_types_WN_TY(WN_kid0(wn),addr);
01674     break;
01675 
01676   /* Special case for ADD */
01677   case OPR_ADD:
01678   case OPR_SUB:
01679     for (i=0; i <= 1; i++) {
01680        kid = WN_kid(wn,i);
01681        switch (WNOPR(kid)) {
01682         case OPR_ARRAY:
01683         case OPR_ARRSECTION:
01684         case OPR_ARRAYEXP:
01685         case OPR_LDA:
01686         case OPR_LDID:
01687         case OPR_ILOAD:
01688           ty_idx = cwh_types_WN_TY(kid,addr);
01689           return (ty_idx);
01690        }
01691     }
01692     /* Fall through */
01693 
01694   default:
01695     Is_True((OPCODE_is_expression(WN_opcode(wn))),(" Unexpected WN"));
01696 
01697     ty_idx = Be_Type_Tbl(WN_rtype(wn));
01698     break;
01699   }
01700 
01701   return (ty_idx) ;
01702 }
01703 
01704 /*===================================================
01705  *
01706  * cwh_types_ch_parm_ty
01707  *
01708  * Make a pointer to a character TY of the 
01709  * appropriate substring size - 
01710  *
01711  ====================================================
01712 */
01713 extern TY_IDX
01714 cwh_types_ch_parm_TY(WN *ln)
01715 {
01716   TY_IDX ty_idx ;
01717 
01718   ty_idx = cwh_types_mk_character_TY(ln,NULL,TRUE);
01719   ty_idx = Make_Pointer_Type( ty_idx);
01720   
01721   return(ty_idx);
01722 }
01723 
01724 /*===================================================
01725  *
01726  * cwh_types_is_character
01727  *
01728  * return T if this is a character TY
01729  *
01730  ====================================================
01731 */
01732 extern BOOL
01733 cwh_types_is_character(TY_IDX ty_idx)
01734 {
01735   TY_IDX ts_idx ;
01736 
01737   ts_idx = cwh_types_array_TY(ty_idx);
01738   ts_idx = cwh_types_scalar_TY(ts_idx);
01739 
01740   TY& ts = Ty_Table[ts_idx];
01741 
01742   return (TY_is_character(ts));
01743 }
01744 
01745 /*===================================================
01746  *
01747  * cwh_types_is_logical
01748  *
01749  * return T if this is a logical TY
01750  *
01751  ====================================================
01752 */
01753 extern BOOL
01754 cwh_types_is_logical(TY_IDX ty_idx)
01755 {
01756   TY_IDX ts_idx ;
01757 
01758   ts_idx = cwh_types_array_TY(ty_idx);
01759   ts_idx = cwh_types_scalar_TY(ts_idx);
01760 
01761   TY& ts = Ty_Table[ts_idx];
01762 
01763   return (TY_is_logical(ts));
01764 }
01765 
01766 /*===================================================
01767  *
01768  * cwh_types_is_character_function
01769  *
01770  * return T if this is a character function TY
01771  *
01772  ====================================================
01773 */
01774 extern BOOL
01775 cwh_types_is_character_function(TY_IDX ty_idx)
01776 {
01777   TY_IDX ts_idx ;
01778 
01779   ts_idx = cwh_types_array_TY(ty_idx);
01780   ts_idx = cwh_types_scalar_TY(ts_idx);
01781 
01782   TY& ts = Ty_Table[ts_idx];
01783 
01784   if (TY_kind(ts) != KIND_FUNCTION) return (FALSE);
01785 
01786   ts_idx = Tylist_Table[TY_tylist(ts)];
01787 
01788   ts_idx = cwh_types_scalar_TY(ts_idx);
01789 
01790   return (TY_is_character(Ty_Table[ts_idx]));
01791 }
01792 
01793 /*===================================================
01794  *
01795  * cwh_types_character_extra
01796  *
01797  * The length argument associated with a character
01798  * dummy is not explicit in the call. Make a 
01799  * temporary ST and hand it back.
01800  *
01801  ====================================================
01802 */
01803 extern ST *
01804 cwh_types_character_extra(ST *dummy)
01805 {
01806   TY_IDX ty_idx ;
01807   ST * st ;
01808 
01809   st = NULL;
01810 
01811   if (cwh_types_is_character(ST_type(dummy))) {
01812 
01813     ty_idx = Be_Type_Tbl(cwh_addr_char_len_typeid);
01814     st = cwh_types_formal_util(ty_idx);
01815     Set_ST_is_value_parm(st);
01816     Set_ST_is_temp_var(st);
01817   }
01818 
01819   return(st);
01820 }
01821 
01822 
01823 /*===================================================
01824  *
01825  * cwh_types_formal_util
01826  *
01827  * Make a formal of given TY & entr into the
01828  * symbol table. Used for character len type
01829  * parameters.
01830  *
01831  ====================================================
01832 */
01833 static ST *
01834 cwh_types_formal_util(TY_IDX ty_idx)
01835 {
01836   ST * st;
01837 
01838   st = New_ST(CURRENT_SYMTAB);
01839   cwh_auxst_clear(st);
01840   
01841   ST_Init(st, Save_Str(cwh_types_mk_anon_name(".len")), CLASS_VAR, SCLASS_FORMAL, EXPORT_LOCAL, ty_idx);
01842 
01843   return st ;
01844 }
01845 
01846 /*===================================================
01847  *
01848  * cwh_types_mk_struct
01849  *
01850  * Make a TY for a struct - utility routine
01851  * for generic structs. TY entered into symbol table.
01852  * FLDs are not created, but the head of the list of
01853  * flds should appear in 'list'. Will always return
01854  * a unique idx, because don't know if FLDs are
01855  * filled at this point.
01856  *
01857  ====================================================
01858 */
01859 static TY_IDX
01860 cwh_types_mk_struct(INT64 size, INT32 align, FLD_HANDLE list, char *name)
01861 {
01862   TY_IDX ty_idx ;
01863 
01864   BUMP_TY_COUNTER(c_TY_STRUCT) ;
01865 
01866   ty_idx = cwh_types_new_TY(TRUE,align) ;
01867   TY& ty = Ty_Table[ty_idx];
01868 
01869   TY_Init (ty, size, KIND_STRUCT, MTYPE_M, Save_Str(cwh_types_mk_anon_name(name)));
01870 
01871   Set_TY_fld(ty, list);
01872   return (ty_idx);
01873 
01874 }
01875 
01876 /*===================================================
01877  *
01878  * cwh_types_array_util
01879  *
01880  * Make a TY for an N-d array - utility routine
01881  * for filling in a few generic details. 
01882  *
01883  * Sets TY_AR_*_val to 0 and
01884  *      TY_AR_const_* to TRUE
01885  * 
01886  * alloc_arbs sets up the ARB information if TRUE, otherwise, it leaves it blank
01887  *
01888  ====================================================
01889 */
01890 extern TY_IDX
01891 cwh_types_array_util(INT16 rank, TY_IDX ety_idx, INT32 align, INT64 size, char * name, BOOL alloc_arbs)
01892 {
01893   TY_IDX  ty_idx ;
01894   INT16 i ;
01895 
01896   if (rank == 0)
01897     return (0);
01898 
01899   BUMP_TY_COUNTER(c_TY_ARRAY);
01900 
01901   ty_idx = cwh_types_new_TY(TRUE,align);
01902   TY &ty = Ty_Table[ty_idx];
01903   TY_Init (ty, size, KIND_ARRAY, MTYPE_UNKNOWN, Save_Str(cwh_types_mk_anon_name(name)));
01904 
01905   Set_TY_etype(ty, ety_idx);
01906 
01907   if (alloc_arbs) {
01908      for (i = 0 ; i < rank ; i++) {
01909         
01910         ARB_HANDLE arb = New_ARB();
01911         ARB_Init (arb, 1, 1, 1);
01912         
01913         if (i == 0) {
01914            Set_ARB_first_dimen(arb);
01915            Set_TY_arb (ty, arb);
01916         }
01917         
01918         Set_ARB_dimension (arb, rank - i );
01919         
01920         if (i == rank - 1)
01921            Set_ARB_last_dimen (arb);
01922         
01923         Set_ARB_const_lbnd (arb);
01924         Set_ARB_lbnd_val (arb, 0);
01925         
01926         Set_ARB_const_stride (arb);
01927         Set_ARB_stride_val (arb, 0);
01928         
01929         Set_ARB_const_ubnd (arb);
01930         Set_ARB_ubnd_val (arb, 0);
01931         
01932      }
01933   }
01934 
01935   return (ty_idx);
01936 }
01937 
01938 /*===================================================
01939  *
01940  * cwh_types_dim_struct_TY
01941  *
01942  * Make a struct TY for a set of dope bounds. Saves
01943  * duplication, cached in global symtab.
01944  *
01945  ====================================================
01946 */
01947 static TY_IDX
01948 cwh_types_dim_struct_TY(void)
01949 {
01950   INT16 i   ;
01951   
01952   static TY_IDX dim_TY_idx = 0;
01953   
01954   INT32 sz  ;
01955   
01956   if (dim_TY_idx == 0) {
01957 
01958     sz   = DOPE_bound_sz ;
01959 
01960     DOPE_bound_ty = Be_Type_Tbl(cwh_bound_int_typeid);
01961 
01962     FLD_HANDLE first;
01963     for (i=0; i < BOUND_NM; i++) {
01964        FLD_HANDLE fld = cwh_types_fld_util(bound_name[i],DOPE_bound_ty,(OFFSET_64)i*sz, TRUE);
01965        if (i == 0)
01966           first = fld;
01967        if (i == BOUND_NM - 1)
01968           Set_FLD_last_field(fld);
01969     }
01970 
01971     dim_TY_idx = cwh_types_mk_struct(DIM_SZ,Pointer_Size,first,".dope_bnd.");
01972   } 
01973 
01974   return(dim_TY_idx);
01975 }
01976 
01977 /*===================================================
01978  *
01979  * cwh_types_dim_TY
01980  *
01981  * Make an array TY for n dope bound structs. Saves
01982  * duplication, cached in global symtab.
01983  *
01984  ====================================================
01985 */
01986 static TY_IDX
01987 cwh_types_dim_TY(INT32 num_dims)
01988 {
01989   INT32 sz ;
01990   TY_IDX ta_idx  ;
01991   TY_IDX tb_idx  ;
01992   ARB_HANDLE arb;
01993 
01994   static TY_IDX tbl[MAX_ARY_DIMS+1] = {0,0,0,0,0,0,0,0};
01995 
01996   if (num_dims == 0) 
01997     return (0);
01998 
01999   if (tbl[num_dims] == 0) {
02000 
02001     tb_idx = cwh_types_dim_struct_TY() ;
02002     
02003     sz = num_dims * DIM_SZ ;
02004     ta_idx = cwh_types_array_util(1,tb_idx,Pointer_Size,sz,".dims.",TRUE) ;
02005    
02006     arb = TY_arb(ta_idx);
02007 
02008     Set_ARB_ubnd_val(arb, num_dims - 1);
02009     Set_ARB_stride_val(arb, DIM_SZ);
02010     
02011     ta_idx = cwh_types_unique_TY(ta_idx);
02012 
02013     tbl[num_dims] = ta_idx ;
02014   }
02015     
02016   return(tbl[num_dims]) ;
02017 }
02018 
02019 /*===================================================
02020  *
02021  * cwh_types_dope_TY
02022  *
02023  * Make an dope_vector TY for a scalar TY of base
02024  * and rank num_dims. NB - there should be flag in
02025  * the TY saying this is a dope struct, but there 
02026  * isn't yet. We use the name '.dope.' to recognize
02027  * a dope vector. See cwh_types_is_dope.
02028  *
02029  ====================================================
02030 */
02031 extern TY_IDX
02032 cwh_types_dope_TY(INT32 num_dims,TY_IDX base_idx, BOOL host, BOOL ptr)
02033 {
02034   TY_IDX ty_idx   ;
02035   TY_IDX ta_idx   ;
02036   TY_IDX  dope_invariant_ty;
02037   INT i;
02038 
02039   static BOOL    dims_ty_inited = FALSE;
02040   static TY_IDX  dims_ty[MAX_ARY_DIMS];
02041 
02042   // Create the dims part of the structure
02043   if (!dims_ty_inited) {
02044      for(i=0; i < MAX_ARY_DIMS; i++) {
02045         dims_ty[i] = 0;
02046      }
02047      dims_ty_inited = TRUE;
02048   }
02049   
02050   if (num_dims > 0 && dims_ty[num_dims-1] == 0) {
02051      dims_ty[num_dims-1] = cwh_types_dim_TY(num_dims);
02052   }
02053 
02054   // Create the invariant part of the structure
02055   dope_invariant_ty = cwh_types_mk_dope_invariant_TY();
02056 
02057   /* add address FLD, with type a pointer  */
02058   /* to an array of the basic type.        */
02059 
02060   FLD_HANDLE base_fld = cwh_types_fld_util(dope_name[0],
02061                                            Be_Type_Tbl(dope_btype[0]),
02062                                            (OFFSET_64)dope_offset[0],
02063                                            TRUE);
02064   
02065   /* create dope vector elements. */
02066   /* descriptors of the same rank (ie: same dims FLD)           */
02067 
02068   FLD_HANDLE fld = cwh_types_fld_util(".flds",
02069                                       dope_invariant_ty,
02070                                       (OFFSET_64)dope_offset[1],
02071                                       TRUE);
02072   
02073   if (num_dims != 0) {
02074      fld = cwh_types_fld_util(".dims.",
02075                                   dims_ty[num_dims-1],
02076                                   (OFFSET_64)DOPE_sz,
02077                                   TRUE);
02078   }
02079   
02080   Set_FLD_last_field(fld);
02081   
02082   ta_idx = cwh_types_array_util(num_dims,base_idx,Pointer_Size,0,".base.",TRUE);
02083   
02084   if (ta_idx != 0) 
02085     ta_idx = cwh_types_unique_TY(ta_idx);
02086   else
02087     ta_idx = base_idx ;
02088 
02089   /* If a pointer within a derived type, then the dope  */
02090   /* is created before the TY FLDs are complete. Ensure */
02091   /* don't get false match on lookup of pointer to TY   */
02092   /* when TY_flist == 0                              */
02093 
02094   TY& ta = Ty_Table[ta_idx];
02095 
02096   if ((TY_kind(ta) == KIND_STRUCT) && (TY_fld(ta).Is_Null ()))
02097     Set_FLD_type(base_fld, cwh_types_mk_unique_pointer_TY(ta_idx, host));
02098   else
02099     Set_FLD_type(base_fld, cwh_types_mk_pointer_TY(ta_idx, host));
02100   
02101   /* make dope vector TY */
02102   
02103   ty_idx = cwh_types_shared_dope(base_fld,num_dims,ptr);
02104   
02105   return(ty_idx);
02106 }
02107 
02108 /*===================================================
02109  *
02110  * cwh_types_mk_dope_invariant_TY
02111  *
02112  * Make the ty for the invariant part of a dope vector (i.e., 
02113  * the part containing everything but the base and the bounds)
02114  *
02115  ====================================================
02116 */
02117 static TY_IDX
02118 cwh_types_mk_dope_invariant_TY(void)
02119 {
02120   INT i ;
02121   OFFSET_64 first_offset;
02122   static TY_IDX invariant_ty=0;
02123   
02124   if (invariant_ty != 0) return (invariant_ty);
02125   
02126   // We need to create the TY.
02127   // Create the fields. We start with 1 to skip the 
02128   // base, and we offset the byte offset by the dope_offset of the first element
02129   // so that this part of the structure is 0 based.
02130 
02131   FLD_HANDLE first = cwh_types_fld_util(dope_name[1],
02132                                         Be_Type_Tbl(dope_btype[1]),
02133                                         (OFFSET_64) 0,
02134                                         TRUE);
02135   first_offset = dope_offset[1];
02136 
02137   FLD_HANDLE fld;
02138   for(i=2; i < DOPE_NM; i++) {
02139      fld = cwh_types_fld_util(dope_name[i],
02140                               Be_Type_Tbl(dope_btype[i]),
02141                               (OFFSET_64)dope_offset[i] - first_offset ,
02142                               TRUE);
02143      Set_FLD_bofst(fld, dope_bofst[i]);
02144      Set_FLD_bsize(fld, dope_bsize[i]);
02145      if (dope_bsize[i] != 0)
02146         Set_FLD_is_bit_field(fld);
02147   }
02148   Set_FLD_last_field(fld);
02149   
02150   // Create the TY
02151   invariant_ty = cwh_types_mk_struct(DOPE_sz - first_offset,
02152                                      Pointer_Size,first,(char *)dope_invariant_str); 
02153   return (invariant_ty);
02154 }
02155 
02156 /*===================================================
02157  *
02158  * cwh_types_shared_dope
02159  *
02160  * Given a dope vector's field list, base type
02161  * and pointer attribute, decide if we have a
02162  * dope vector we can use. If so use it. Pointers
02163  * and arrays have different dope vectors because
02164  * they have different TY flags.
02165  *
02166  * Dope vectors for scalar, intrinsic types are
02167  * always GLOBAL, and shared, one per rank.
02168  *
02169  ====================================================
02170 */
02171 static TY_IDX
02172 cwh_types_shared_dope(FLD_HANDLE fld, int ndims, BOOL is_ptr)
02173 {
02174   static TY_IDX intrn_dope[MAX_ARY_DIMS+1][NUM_DOPE_TYPES] ;
02175   static TY_IDX intrn_ptrs_dope[MAX_ARY_DIMS+1][NUM_DOPE_TYPES] ;
02176   TY_IDX *p  ;
02177   TY_IDX  dv_idx ;
02178   TY_IDX  tp_idx ;      
02179   TY_IDX  tb_idx ;      
02180   TYPE_ID bt ;      
02181 
02182   INT64 sz   ;
02183   INT32 al   ;
02184   
02185   /* get TY of object dope describes */
02186 
02187   dv_idx = 0 ;
02188 
02189   tp_idx = TY_pointed(Ty_Table[FLD_type(fld)]);
02190   tb_idx = cwh_types_scalar_TY(tp_idx); 
02191 
02192   TY& tb = Ty_Table[tb_idx];
02193 
02194   
02195   if (IS_SHARED_DOPE_BASE(tb)) {
02196     
02197     bt = TY_mtype(tb);
02198 
02199     if (TY_is_logical(tb))
02200         bt = LOGICAL_OFFSET(bt);
02201 
02202     if (is_ptr) 
02203       p = &intrn_ptrs_dope[ndims][bt];
02204     else
02205       p = &intrn_dope[ndims][bt];
02206     
02207     if (*p == 0) {
02208 
02209       sz = DOPE_sz + ndims * DIM_SZ ;
02210       al = Pointer_Size;
02211       *p = cwh_types_mk_struct(sz,al,fld,(char *)dope_str); 
02212 
02213       TY& ty = Ty_Table[*p];
02214 
02215       if (is_ptr) 
02216         Set_TY_is_f90_pointer(ty);
02217       else
02218         Clear_TY_is_f90_pointer(ty);
02219 
02220     } 
02221 
02222     BUMP_TY_COUNTER(c_TY_DOPE_INTRIN);
02223     dv_idx = *p;
02224     
02225   } else { /* either dtype component, or dtype */
02226 
02227     sz  = DOPE_sz + ndims * DIM_SZ ;
02228     al  = Pointer_Size;
02229     dv_idx  = cwh_types_mk_struct(sz,al,fld,(char *)dope_str); 
02230 
02231     TY&  dv = Ty_Table[dv_idx];
02232 
02233     if (is_ptr) 
02234       Set_TY_is_f90_pointer(dv);
02235     else
02236       Clear_TY_is_f90_pointer(dv);
02237   }
02238 
02239   return dv_idx ;
02240 }
02241 
02242 
02243 /*===================================================
02244  *
02245  * cwh_types_is_dope
02246  *
02247  * return TRUE if this is a dope TY. 
02248  *
02249  * better would be TY flag in stab.h, but this routine
02250  * is seldom used.
02251  *
02252  ====================================================
02253 */
02254 extern BOOL
02255 cwh_types_is_dope(TY_IDX ty)
02256 {
02257 
02258   while (TY_kind(ty) == KIND_POINTER) {
02259     ty = TY_pointed(ty);
02260   }
02261 
02262   if (strncmp(TY_name(ty),dope_str,DOPENM_LEN) == 0 )
02263     return TRUE;
02264 
02265   return FALSE ;
02266 }
02267 
02268 /*===================================================
02269  *
02270  * cwh_types_dope_rank
02271  *
02272  * Given a dope vector TY, return its rank.
02273  *
02274  ====================================================
02275 */
02276 extern INT32 
02277 cwh_types_dope_rank(TY_IDX ty_idx)
02278 {
02279   INT32 nd ;
02280 
02281   nd = 0 ;
02282 
02283   TY &ty = Ty_Table[ty_idx];
02284 
02285   FLD_HANDLE fl = TY_fld(ty);
02286 
02287   while(!FLD_last_field(fl)) 
02288      fl = FLD_next(fl);
02289 
02290   if (!fl.Is_Null ()) {
02291 
02292      if (FLD_ofst(fl) > dope_offset[DOPE_NM-1]) {
02293         ARB_HANDLE arb = TY_arb(FLD_type(fl));
02294         nd = 1 + ARB_ubnd_val(arb);
02295      }
02296   }
02297 
02298   return (nd);
02299 }
02300 
02301 /*===================================================
02302  *
02303  * cwh_types_dope_basic_TY
02304  *
02305  * Given a dope vector TY, return the array TY
02306  * of the info the dope describes.
02307  *
02308  ====================================================
02309 */
02310 extern TY_IDX
02311 cwh_types_dope_basic_TY(TY_IDX ty)
02312 {
02313   while (TY_kind(ty) == KIND_POINTER)
02314     ty = TY_pointed(ty);
02315 
02316   return (TY_pointed(FLD_type(TY_fld(Ty_Table[ty]))));
02317 }
02318 
02319 /*===================================================
02320  *
02321  * cwh_types_dope_dims_FLD
02322  *
02323  * Given a dope vector TY, return the dims FLD
02324  * - it describes the bounds struct.
02325  *
02326  ====================================================
02327 */
02328 extern FLD_HANDLE
02329 cwh_types_dope_dims_FLD(TY_IDX ty)
02330 {
02331   while (TY_kind(ty) == KIND_POINTER)
02332     ty = TY_pointed(ty);
02333 
02334   FLD_HANDLE fl = TY_fld(Ty_Table[ty]);
02335 
02336   while (!FLD_last_field(fl)) {
02337     fl = FLD_next(fl);
02338   }
02339 
02340   if (FLD_ofst(fl) <= dope_offset[DOPE_NM-1])
02341     fl = FLD_HANDLE ();
02342 
02343   return fl;
02344 }
02345 
02346 /*===================================================
02347  *
02348  * cwh_types_contains_dope
02349  *
02350  * Utility for functions returning structures.
02351  * Does the structure contain a dope vector. If so
02352  * return T. ( the consequence is that the struct
02353  * result must be passed by address, so the FE 
02354  * fills in the dope).
02355  *
02356  ====================================================
02357 */
02358 extern bool
02359 cwh_types_contains_dope(TY_IDX ty)
02360 {
02361   bool res = false;
02362 
02363   if (TY_kind(ty) == KIND_STRUCT) {
02364     res = cwh_types_is_dope(ty);
02365 
02366     if (!res) {
02367 
02368       FLD_ITER fld_iter = Make_fld_iter(TY_fld(ty));
02369 
02370       do {
02371 
02372         FLD_HANDLE p (fld_iter);
02373         res = cwh_types_contains_dope(FLD_type(p));
02374 
02375       } while (!res && !FLD_last_field(fld_iter++)) ;
02376     }
02377   }
02378 
02379   return res;
02380 }
02381 
02382 /*===================================================
02383  *
02384  * cwh_types_fld_util
02385  *
02386  * Utility to make a FLD which has the bofst and
02387  * bsize set to zero. Not entered into symtab.
02388  *
02389  ====================================================
02390 */
02391 static FLD_HANDLE
02392 cwh_types_fld_util(char* name_string, TY_IDX fld_ty,  OFFSET_64 offset, BOOL global)
02393 {
02394 
02395   FLD_HANDLE fld;
02396 
02397   if (fld_ty == 0)
02398     return(fld);
02399 
02400   fld = New_FLD ();
02401   FLD_Init (fld, Save_Str(name_string), fld_ty, offset);
02402   Set_FLD_bofst(fld, 0);
02403   Set_FLD_bsize(fld, 0);
02404 
02405   return(fld);
02406 }
02407 
02408 /*===================================================
02409  *
02410  * cwh_types_fld_dummy
02411  *
02412  * Make a FLD with an offset and type TY,
02413  * so type and offset information can be propagated 
02414  * on the stack. 
02415  *
02416  ====================================================
02417 */
02418 extern FLD_HANDLE
02419 cwh_types_fld_dummy(OFFSET_64 off,TY_IDX ty)
02420 {
02421   FLD_HANDLE fld ;
02422 
02423   fld = cwh_types_fld_util(".dummy.",ty,off,FALSE);
02424   return (fld);
02425 }
02426 
02427 /*===================================================
02428  *
02429  * cwh_types_array_temp_TY
02430  *
02431  * Given an OPC_ARRAYEXP and a TY of a scalar
02432  * element, make an array TY of the shape
02433  * described in the OPC_ARRAYEXP.
02434  *
02435  * The ARRAY node has the bounds in C order, but
02436  * they are translated to fortran order, because 
02437  * that's the way the utility routine expects them.
02438  *
02439  ====================================================
02440 */
02441 extern TY_IDX
02442 cwh_types_array_temp_TY(WN *ar, TY_IDX sc )
02443 {
02444   TY_IDX ty    ;
02445   WN  * wn    ;
02446   ARB_HANDLE  bound; 
02447   TYPE_ID   bt ;
02448   INT64 size;
02449   INT16 nd,i,j  ;  
02450 
02451 
02452   nd = WN_kid_count(ar) - 1;
02453   bt = cwh_bound_int_typeid ;
02454 
02455   /* setup bounds */
02456 
02457   for (i = 0 ; i < nd  ; i ++) {
02458 
02459     j = nd - i;
02460 
02461     ARB_HANDLE arb = New_ARB();
02462     ARB_Init (arb, 1, 1, 1);
02463     if (i == 0) {
02464        bound = arb;
02465     }
02466 
02467     Set_ARB_const_lbnd(arb);
02468     Set_ARB_lbnd_val(arb, 0);
02469     Clear_ARB_first_dimen(arb);
02470     Clear_ARB_last_dimen(arb);
02471 
02472     if (WNOPR(WN_kid(ar,j)) == OPR_INTCONST) {
02473 
02474       Set_ARB_const_ubnd(arb);
02475       Set_ARB_ubnd_val(arb, WN_const_val(WN_kid(ar,j)) -1);
02476 
02477     } else {
02478 
02479       WN *expr;
02480       ST *st;
02481 
02482       expr = cwh_expr_bincalc(OPR_SUB,
02483                               WN_COPY_Tree(WN_kid(ar,j)),
02484                               WN_Intconst(bt,1));
02485 
02486       Clear_ARB_const_ubnd(arb);
02487 
02488       st = cwh_types_make_bounds_ST();
02489       cwh_addr_store_ST(st,0,0,expr);
02490       Set_ARB_ubnd_var(arb, ST_st_idx(st));
02491 
02492     }
02493   }
02494 
02495   /* setup strides */
02496   
02497   if (TY_size(sc) != 0) {
02498 
02499     Set_ARB_const_stride(bound[0]);
02500     Set_ARB_stride_val(bound[0], TY_size(sc));
02501 
02502   } else {    /* must be character substring definition */
02503 
02504     ARB_HANDLE sc_arb = TY_arb(sc);
02505 
02506     Clear_ARB_const_stride(bound[0]);
02507     Set_ARB_stride_var(bound[0], ARB_ubnd_var(sc_arb));
02508   }
02509 
02510   for (i = 1 ; i < nd ; i ++) {
02511 
02512     ARB_HANDLE arb = bound[i-1];
02513 
02514     if (ARB_const_stride(arb)) {
02515       if (ARB_const_ubnd(arb)) {
02516 
02517         ARB_HANDLE arb2 = bound[i];
02518 
02519         Set_ARB_const_stride(arb2);
02520         Set_ARB_stride_val(arb2, ARB_stride_val(arb) * (ARB_ubnd_val(arb) + 1 ));
02521       } else {
02522  
02523         ST *st;
02524         WN *wn2;
02525        
02526         ARB_HANDLE arb2 = bound[i];
02527 
02528         Clear_ARB_const_stride(arb2);
02529 
02530         wn = WN_Intconst(cwh_bound_int_typeid,1 + ARB_const_ubnd(arb));
02531         wn2 = cwh_addr_load_ST(&St_Table[ARB_ubnd_var(arb)],0,0);
02532         wn = cwh_expr_bincalc(OPR_MPY, wn2, wn);
02533 
02534         st = cwh_types_make_bounds_ST();
02535         cwh_addr_store_ST(st,0,0,wn);
02536         Set_ARB_stride_var(arb2, ST_st_idx(st));
02537       }
02538     } else {
02539 
02540       ARB_HANDLE arb2 = bound[i];
02541       ST *st;
02542 
02543       Clear_ARB_const_stride(arb2);
02544 
02545       if (ARB_const_ubnd(arb)) {
02546         wn = cwh_expr_bincalc(OPR_ADD,
02547                               WN_Intconst(bt,ARB_ubnd_val(arb)),
02548                               WN_Intconst(bt,1));
02549       } else {
02550         WN *wn2 = cwh_addr_load_ST(&St_Table[ARB_ubnd_var(arb)],0,0);
02551         wn = cwh_expr_bincalc(OPR_ADD,wn2,WN_Intconst(bt,1));
02552       }
02553 
02554       wn = cwh_expr_bincalc(OPR_MPY,
02555                             wn,
02556                             cwh_addr_load_ST(&St_Table[ARB_stride_var(arb)], 0, 0)); 
02557       st = cwh_types_make_bounds_ST();
02558       cwh_addr_store_ST(st,0,0,wn);
02559       Set_ARB_stride_var(arb2, ST_st_idx(st));
02560     }
02561   }
02562 
02563   ARB_HANDLE last_arb = bound[nd-1];
02564  
02565   if (ARB_const_stride(last_arb) && ARB_const_ubnd(last_arb)
02566       && ARB_const_lbnd(last_arb)) {
02567      size = ARB_stride_val(last_arb)*(ARB_ubnd_val(last_arb) 
02568                                          - ARB_lbnd_val(last_arb)
02569                                          + 1);
02570   } else {
02571      size = 0;
02572   }
02573 
02574   Set_ARB_first_dimen(bound[0]);
02575   Set_ARB_last_dimen(last_arb);
02576 
02577   ty = cwh_types_mk_array_TY(bound,nd,sc,size);
02578   return(ty);
02579 }
02580 
02581 /*===================================================
02582  *
02583  * cwh_types_size_WN
02584  *
02585  * Given an array TY & an element size, return a WN with
02586  * the size of a TY of that shape and size.
02587  *
02588  ====================================================
02589 */
02590 extern WN * 
02591 cwh_types_size_WN(TY_IDX ty, WN *e_sz)
02592 {
02593   INT16 nd ;
02594   WN   *wn ;
02595   WN   *lb ;
02596   WN   *ub ;
02597   WN   *st ;
02598   WN   *wt ;
02599   INT  i;
02600 
02601   Is_True((TY_kind(ty) == KIND_ARRAY),("Odd size calc"));
02602 
02603   nd = ARB_dimension (TY_arb (ty));
02604   wn = e_sz;
02605 
02606   for (i = 0; i < nd ; i++) {
02607      lb = cwh_types_bound_WN(ty,i,LOW);
02608      ub = cwh_types_bound_WN(ty,i,UPPER);
02609      st = WN_Intconst(MTYPE_I4,1);
02610      wt = cwh_addr_extent(lb,ub,st);
02611      wn = cwh_expr_bincalc(OPR_MPY,wt,wn);
02612   }
02613   
02614   return(wn);
02615 }
02616 
02617 /*===================================================
02618  *
02619  * cwh_types_bound_WN
02620  *
02621  * Given an TY, index (0..n-1), and bound flag
02622  * return the bound value as  WN.
02623  *
02624  ====================================================
02625 */
02626 extern WN *
02627 cwh_types_bound_WN(TY_IDX ty, INT16 i, enum ty_bound_enum  b)
02628 {
02629   WN * wn ;
02630 
02631   ARB_HANDLE  arb = TY_arb(ty);
02632   INT16     nd = ARB_dimension(arb);
02633   arb = arb[nd-i-1];
02634   
02635   switch (b) {
02636   case LOW:
02637     if (ARB_const_lbnd(arb)) 
02638       wn = WN_Intconst(cwh_bound_int_typeid,ARB_lbnd_val(arb)) ;
02639     else
02640       wn = cwh_addr_load_ST(&St_Table[ARB_lbnd_var(arb)],0,0);
02641     break ;
02642 
02643   case UPPER:
02644     if (ARB_const_ubnd(arb)) 
02645       wn = WN_Intconst(cwh_bound_int_typeid,ARB_ubnd_val(arb)) ;
02646     else
02647       wn = cwh_addr_load_ST(&St_Table[ARB_ubnd_var(arb)],0,0);
02648     break ;
02649 
02650   case STRIDE:
02651     if (ARB_const_stride(arb)) 
02652       wn = WN_Intconst(cwh_bound_int_typeid,ARB_stride_val(arb)) ;
02653     else
02654       wn = cwh_addr_load_ST(&St_Table[ARB_stride_var(arb)],0,0);
02655     break ;
02656   }
02657 
02658   return (wn) ;
02659 }
02660 
02661 /*===================================================
02662  *
02663  * cwh_types_get_dope_info
02664  *
02665  * Get information about where in a dope vector things are
02666  * crayfield - field from the Cray dopevector defintion
02667  *              1.base_addr 
02668  *              2.el_len 
02669  *              3.assoc 
02670  *              4.ptr_alloc 
02671  *              5.p_or_a 
02672  *              6.contig 
02673  *              7.n_dim 
02674  *              8.typ_code 
02675  *              9.orig_base 
02676  *             10.orig_size 
02677  *
02678  * offset - byte offset of the word to read
02679  * rshift - number of bits to right-shift the field, or 0
02680  * mask   - bit mask to get the field, or 0
02681  * ty     - TYPE_ID to use for loads and operations on the field
02682  *
02683  ====================================================
02684 */
02685 extern void  
02686 cwh_types_get_dope_info(INT32 crayfield, INT32 *offset, INT32 *rshift, 
02687                                      INT64 *mask, TYPE_ID *ty)
02688 {
02689    INT real_field;
02690    INT shift;
02691    INT size;
02692    INT ty_size;
02693    
02694    /* Skip unused fields */
02695    if (crayfield >= 8) {
02696 //      real_field = crayfield + 1;
02697       real_field = crayfield;
02698    } else if (crayfield == 7) {
02699       real_field = crayfield;
02700    } else {
02701       real_field = crayfield - 1;
02702    }
02703 
02704    *offset = dope_offset[real_field];
02705    *ty = dope_btype[real_field];
02706    shift = dope_bofst[real_field];
02707    size = dope_bsize[real_field];
02708    ty_size = MTYPE_size_best(*ty);
02709    
02710    if (size != 0) {
02711       *mask = (1LL << size) - 1;
02712    } else {
02713       *mask = 0;
02714    }
02715    if (shift != 0 || size != 0) {
02716 # ifdef linux
02717       *rshift = shift;
02718 # else
02719       *rshift = ty_size - shift - size;
02720 # endif
02721    } else {
02722       *rshift = 0;
02723    } 
02724    return;
02725 }
02726 
02727 /*===================================================
02728  *
02729  * cwh_types_mk_pointer_TY
02730  *
02731  * Make a POINTER TY for the TY handed in.
02732  *
02733  ====================================================
02734 */
02735 extern TY_IDX
02736 cwh_types_mk_pointer_TY(TY_IDX ty_idx, BOOL host)
02737 {
02738   TY_IDX  tr_idx   ;
02739 
02740   tr_idx = Make_Pointer_Type(ty_idx);
02741 
02742   return(tr_idx);
02743 }
02744 
02745 /*===================================================
02746  *
02747  * cwh_types_mk_unique_pointer_TY
02748  *
02749  * Make a POINTER TY for the TY handed in. Don't look
02750  * up other pointers with Make_Pointer_TY
02751  *
02752  ====================================================
02753 */
02754 static TY_IDX
02755 cwh_types_mk_unique_pointer_TY(TY_IDX ty, BOOL host)
02756 {
02757   TY_IDX tp_idx;
02758 
02759   BUMP_TY_COUNTER(c_TY_UNIQ_POINTER) ;
02760 
02761   tp_idx = cwh_types_new_TY (TRUE,Pointer_Size);
02762   TY& tp = Ty_Table[tp_idx];
02763   TY_Init(tp, Pointer_Size, KIND_POINTER, Pointer_Mtype, Save_Str(cwh_types_mk_anon_name(".uniq_p.")));
02764 
02765   Set_TY_pointed(tp, ty);
02766 
02767   tp_idx = cwh_types_unique_TY(tp_idx);
02768 
02769   return tp_idx;
02770 }
02771 
02772 
02773 /*===================================================
02774  *
02775  * cwh_types_mk_common_TY
02776  *
02777  * Make a TY for a common block name. Don't
02778  * know the items in the common yet, so just
02779  * create the TY and return.
02780  *
02781  * If the alignment is 0, we choose a default
02782  * of 4. cwh_types_mk_element will bump it,
02783  * if an element requires a bigger alignment.
02784  *
02785  ====================================================
02786 */
02787 extern TY_IDX
02788 cwh_types_mk_common_TY(INT64 size, mUINT16 al )
02789 {
02790   TY_IDX ty    ;
02791   INT64 sz  ;
02792 
02793   if (al == 0) 
02794     al = 4;
02795   
02796   sz = bit_to_byte(size);
02797   ty = cwh_types_mk_struct(sz,al,FLD_HANDLE(),".common.");
02798                             
02799   return(ty);
02800 }
02801 
02802 
02803 extern TY_IDX
02804 cwh_types_mk_module_TY(INT64 size, mUINT16 al )
02805 {
02806   TY_IDX ty    ;
02807   INT64 sz  ;
02808 
02809   if (al == 0)
02810     al = 4;
02811  
02812   sz = bit_to_byte(size);
02813   ty = cwh_types_mk_struct(sz,al,FLD_HANDLE(),".module.");
02814 
02815   return(ty);
02816 }
02817 
02818 /*===================================================
02819  *
02820  * cwh_types_mk_equiv_TY
02821  *
02822  * Make a TY for an equivalence block name. Don't
02823  * know the items in the common yet, so just
02824  * create the TY and return
02825  *
02826  ====================================================
02827 */
02828 extern TY_IDX
02829 cwh_types_mk_equiv_TY(INT64 size)
02830 {
02831   TY_IDX ty    ;
02832   INT64 sz  ;
02833   
02834   sz = bit_to_byte(size);
02835   ty = cwh_types_mk_struct(sz,MAX_ALIGN,FLD_HANDLE(),".equiv.") ;
02836                             
02837   return ty ;
02838 }
02839 
02840 /*===================================================
02841  *
02842  * cwh_types_mk_namelist_TY
02843  *
02844  * Make a TY for a namelist. There are two parts -
02845  * an array of namelist item entries and a namelist 
02846  * name.
02847  *
02848  * The items themselves weem irrelevant. Why?
02849  *
02850  ====================================================
02851 */
02852 extern TY_IDX
02853 cwh_types_mk_namelist_TY(INT32 nitems)
02854 {
02855   TY_IDX ty   ;
02856   TY_IDX tn   ;
02857   TY_IDX te   ;
02858   TY_IDX ta_idx   ;
02859   WN *wn   ;
02860   FLD_HANDLE f1 ;
02861   FLD_HANDLE f2 ;
02862 
02863   /* array of namelist items */
02864 
02865   te = cwh_types_mk_namelist_item_TY();
02866   ta_idx = cwh_types_array_util(1,
02867                             te,
02868                             NL_Tables[ALIGN_Nlentry][NL_Table_Index],
02869                             TY_size(te),
02870                             ".NL_item_array.",
02871                             TRUE);
02872 
02873   TY& ta = Ty_Table[ta_idx];
02874 
02875   Set_TY_AR_ubnd_val(ta, 0, nitems - 1);
02876   Set_TY_AR_stride_val(ta, 0, TY_size(te));
02877 
02878   ta_idx = cwh_types_unique_TY(ta_idx);
02879 
02880 
02881 
02882   /* namelist name */
02883 
02884   wn = WN_Intconst(MTYPE_I4,NL_Name_Length) ;
02885   tn = cwh_types_mk_character_TY(wn,NULL,TRUE);
02886   f1 = cwh_types_fld_util(".NL_name.",tn,NL_Tables[OFFSET_Namelist_nlname][NL_Table_Index],TRUE);
02887 
02888   f2 = cwh_types_fld_util(".NL_vars.",ta_idx,NL_Tables[OFFSET_Namelist_nlvnames][NL_Table_Index],TRUE);
02889 
02890   Set_FLD_last_field(f2);
02891   
02892   ty = cwh_types_mk_struct(TY_size(tn) + TY_size(ta),
02893                            NL_Tables[ALIGN_Namelist][NL_Table_Index],
02894                            f1,
02895                            ".Namelist.");
02896   return ty ;
02897 }
02898 
02899 /*===================================================
02900  *
02901  * cwh_types_mk_namelist_item_TY
02902  *
02903  * Make a STRUCT for a namelist item
02904  *    item name
02905  *    item address ptr
02906  *    item type
02907  *    item dims?
02908  *
02909  *  Use one global TY for all items.
02910  *
02911  ====================================================
02912 */
02913 static TY_IDX
02914 cwh_types_mk_namelist_item_TY(void)
02915 {
02916   TY_IDX ty ;
02917   TY_IDX tp ;
02918   TY_IDX tc ;
02919   FLD_HANDLE f1 ;
02920   FLD_HANDLE f2 ;
02921   FLD_HANDLE f3 ;
02922   FLD_HANDLE f4 ;
02923   WN  * wn ;
02924 
02925   static TY_IDX gl_ty = 0 ;
02926 
02927   if (gl_ty == 0) {
02928 
02929     tp = Make_Pointer_Type(Be_Type_Tbl(MTYPE_V));
02930 
02931     ty = Be_Type_Tbl(MTYPE_I4); 
02932 
02933     wn = WN_Intconst(MTYPE_I4,NL_Name_Length) ;
02934 
02935     tc = cwh_types_mk_character_TY(wn,NULL,TRUE);
02936 
02937   
02938     f1 = cwh_types_fld_util("varname",tc,NL_Tables[OFFSET_Nlentry_varname][NL_Table_Index],TRUE);
02939     f2 = cwh_types_fld_util("varaddr",tp,NL_Tables[OFFSET_Nlentry_varaddr][NL_Table_Index],TRUE);
02940     f3 = cwh_types_fld_util("type",ty,NL_Tables[OFFSET_Nlentry_type][NL_Table_Index],TRUE);
02941     f4 = cwh_types_fld_util("dimp",tp,NL_Tables[OFFSET_Nlentry_dimp][NL_Table_Index],TRUE);
02942 
02943     Set_FLD_last_field(f4);
02944 
02945     WN_DELETE_Tree(wn);
02946     gl_ty = cwh_types_mk_struct(NL_Tables[SIZE_Nlentry][NL_Table_Index],
02947                                 NL_Tables[ALIGN_Nlentry][NL_Table_Index],
02948                                 f1,
02949                                 ".NL_item.");
02950   }
02951 
02952   return gl_ty ;                          
02953 }
02954 
02955 /*===================================================
02956  *
02957  * cwh_types_mk_element
02958  *
02959  * Make a FLD for a common block element or 
02960  * equivalence class. The ST of the common or is
02961  * equivalence is the first argument & the element 
02962  * the second. Set equivalence flags based on ST.
02963  *
02964  *
02965  ====================================================
02966 */
02967 extern void
02968 cwh_types_mk_element(ST *c, ST * st)
02969 {
02970   TY_IDX cbty ;
02971   FLD_HANDLE fld  ;
02972   FLD_HANDLE nfld ;
02973   FLD_HANDLE pfld ;
02974 
02975   cbty = ST_type(c);
02976   fld  = cwh_types_fld_util(ST_name(st),ST_type(st),ST_ofst(st),TRUE);
02977 
02978 
02979 
02980   if (ST_is_equivalenced(st))
02981   if (!(IS_COMMON(st)))
02982         Set_FLD_equivalence(fld);
02983 
02984   if (ST_sclass(st) == SCLASS_COMMON ||
02985       ST_sclass(st) == SCLASS_MODULE ) {  
02986     Set_FLD_st(fld, ST_st_idx(st)); 
02987     Is_True((ST_level(st) == 1),("Bad common st level"));
02988   }
02989 
02990 
02991 /*  Is_True((TY_align(ST_type(st))) <= TY_align(cbty),("Common align")); */
02992 
02993   if (TY_align(ST_type(st)) > TY_align(cbty)) {
02994       Set_TY_align(cbty, TY_align(ST_type(st)));
02995       Set_ST_type(*c,cbty);
02996   }
02997 
02998   if (TY_fld(Ty_Table[cbty]).Is_Null ()) {
02999     Set_TY_fld(Ty_Table[cbty], fld);
03000   } else {
03001     Clear_FLD_last_field(FLD_HANDLE (fld.Idx () - 1));
03002   }
03003   Set_FLD_last_field(fld);
03004 
03005 }
03006 
03007 /*===================================================
03008  *
03009  * cwh_types_mk_rslt_temp_TY
03010  *
03011  * Make a struct_ty for a struct-by-value temp for
03012  * a function result. This is so a result which
03013  * isn't 8 or 16 bytes won't write over adjacent
03014  * locations.
03015  *
03016  ====================================================
03017 */
03018 extern TY_IDX
03019 cwh_types_mk_result_temp_TY(void)
03020 {
03021   TY_IDX ty  ;
03022   FLD_HANDLE f1 ;
03023   FLD_HANDLE f2 ;
03024 
03025   f1 = cwh_types_fld_util("rt1", Be_Type_Tbl(MTYPE_I8),0,TRUE);
03026   f2 = cwh_types_fld_util("rt2", Be_Type_Tbl(MTYPE_I8),0,TRUE);
03027 
03028   Set_FLD_last_field(f2);
03029 
03030   ty = cwh_types_mk_struct(RESULT_SIZE, RESULT_ALIGN,f1,"res_temp");
03031 
03032   return ty;
03033 }
03034 /*===================================================
03035  *
03036  * cwh_types_fill_type
03037  *
03038  * Fill in the blanks of a PDGCS type
03039  *
03040  ====================================================
03041 */
03042 static void
03043 cwh_types_fill_type(INT32 flag_bits, TYPE *t, TY_IDX ty)
03044 {
03045 
03046   t->const_flag    = test_flag(flag_bits,FEI_DESCRIPTOR_CONST_C);
03047   t->volatile_flag = test_flag(flag_bits,FEI_DESCRIPTOR_VOLAT_C);
03048   t->signed_flag   = test_flag(flag_bits,FEI_DESCRIPTOR_SIGN_C);
03049   t->automatic     = test_flag(flag_bits,FEI_DESCRIPTOR_AUTO_F);
03050   t->restricted    = test_flag(flag_bits,FEI_DESCRIPTOR_RESTR_C);
03051   t->short_flag    = test_flag(flag_bits,FEI_DESCRIPTOR_SHORT_C);
03052   t->long_flag     = test_flag(flag_bits,FEI_DESCRIPTOR_LONG_C);
03053   t->bitfield      = test_flag(flag_bits,FEI_DESCRIPTOR_BITFLD_C);
03054   t->aux_info      = 0 ;
03055   t->shrd_pointee  = test_flag(flag_bits,FEI_DESCRIPTOR_SHRD_PTEE);
03056   t_TY((*t))       =  cast_to_uint(ty);
03057 
03058 }
03059 
03060 /*===================================================
03061  *
03062  * cwh_types_mk_anon_name
03063  *
03064  * Provide a name for an anonymous type. If a 
03065  * string (<40 bytes) is passed, then it's used as
03066  * the stem, otherwise a NULL uses the stem ".anon."
03067  *
03068  *
03069  ====================================================
03070 */
03071 
03072 extern char *
03073 cwh_types_mk_anon_name (char * nm)
03074 {
03075   static char anonymous_str [64] ;
03076   static INT32 anonymous_index = 0;
03077 
03078   INT32 len ;
03079 
03080   if (nm == NULL) {
03081     len = 6;
03082     strcpy(anonymous_str,".anon.");
03083 
03084   } else {
03085 
03086     len = strlen(nm);
03087     Is_True((len < 40),("name too long"));
03088     strcpy(anonymous_str,nm);
03089   }
03090 
03091 #if 0
03092 // In 7.3 numbering is suppressed, because TY_unique
03093 // uses the type name among the criteria for matching.
03094 // arguably it's not required, since TYs have an id in 
03095 // the dump..
03096 
03097   sprintf(&anonymous_str[len], "%d", ++ anonymous_index);
03098 #endif
03099 
03100   return(anonymous_str);
03101 }
03102 
03103 /*===================================================
03104  *
03105  * cwh_types_push_dtype
03106  *
03107  * Push the details of a derived type on a stack. Used
03108  * to preserve details of an enclosing derived type 
03109  * while processing an inner type.
03110  *
03111  ====================================================
03112 */
03113 static void
03114 cwh_types_push_dtype(dtype_t d)
03115 {
03116 
03117   dtype_top ++ ;
03118 
03119   if (dtype_top >= dtype_stk_size) {
03120      dtype_stk_size += STK_SIZE_CHANGE;
03121      dtype_stk = (dtype_t *) realloc(dtype_stk,sizeof(dtype_t)*dtype_stk_size);
03122   }
03123 
03124   dtype_stk[dtype_top].dty = d.dty ;
03125   dtype_stk[dtype_top].dty_last = d.dty_last; 
03126   dtype_stk[dtype_top].ncompos = d.ncompos ;
03127   dtype_stk[dtype_top].seq = d.seq;
03128   dtype_stk[dtype_top].hosted = d.hosted;
03129 
03130   return ;
03131 }
03132 
03133 /*===================================================
03134  *
03135  * cwh_types_pop_dtype
03136  *
03137  * Pop details of a derived type.
03138  *
03139  ====================================================
03140 */
03141 static dtype_t 
03142 cwh_types_pop_dtype(void)
03143 {
03144   dtype_t d ;
03145 
03146   Is_True((dtype_top >= 0),(" Dtype stack underflow"));
03147 
03148   d.dty      = dtype_stk[dtype_top].dty ;
03149   d.dty_last = dtype_stk[dtype_top].dty_last;
03150   d.ncompos  = dtype_stk[dtype_top].ncompos ;
03151   d.seq      = dtype_stk[dtype_top].seq ;
03152   d.hosted   = dtype_stk[dtype_top].hosted ;
03153 
03154   dtype_top --;
03155 
03156   return(d);
03157 }
03158 
03159 /*===================================================
03160  *
03161  * cwh_types_in_dtype
03162  *
03163  * Are we in a derived type? If so, honor offset
03164  * and alignments of dtype.
03165  *
03166  ====================================================
03167 */
03168 static BOOL
03169 cwh_types_in_dtype(void)
03170 {
03171   BOOL res = FALSE ;
03172 
03173   if (dtype_top >= 0 ) 
03174     res = TRUE ;
03175 
03176   return res ;
03177 }
03178 /*===================================================
03179  *
03180  * cwh_cray_type_from_TY
03181  *
03182  * return a Cray type from a TY - values
03183  * determined empirically from examination of FE output
03184  *
03185  ====================================================
03186 */
03187 extern INT64
03188 cwh_cray_type_from_TY(TY_IDX ty_idx)
03189 {
03190    TY_IDX base_ty_idx;
03191    INT64 rtype;
03192    f90_type_t  *f90_type_ptr;
03193 
03194    TY& ty = Ty_Table[ty_idx];
03195 
03196    rtype = 0;
03197    f90_type_ptr = (f90_type_t *)&rtype;
03198 
03199    if (TY_kind(ty) == KIND_ARRAY) {
03200       return (cwh_cray_type_from_TY(TY_etype(ty))); 
03201    } else if (TY_kind(ty) == KIND_SCALAR) {
03202       base_ty_idx = ty_idx;
03203    } else if (TY_kind(ty) == KIND_STRUCT) {
03204       f90_type_ptr->type = 8;           // DVTYPE_DERIVEDWORD
03205       return (rtype);
03206    } else {
03207       Is_True((0),("Do not know what to do with type"));
03208    }
03209 
03210    TY& base_ty = Ty_Table[base_ty_idx];
03211 
03212    if (TY_is_character(base_ty)) {
03213       f90_type_ptr->type = 6;           // DVTYPE_ASCII
03214       f90_type_ptr->int_len = 8;
03215       return (rtype);
03216    }
03217 
03218    rtype = cwh_cray_type_from_MTYPE(TY_mtype(base_ty));
03219    if (TY_is_logical(base_ty)) {
03220       f90_type_ptr->type = 5;           // DVTYPE_LOGICAL
03221    }
03222    
03223    return (rtype);
03224 }
03225 
03226 
03227 /*===================================================
03228  *
03229  * cwh_cray_type_from_MTYPE
03230  *
03231  * return a Cray type from an MTYPE. Note that there is no 
03232  * way to tell that we are dealing with a LOGICAL type here
03233  *
03234  ====================================================
03235 */
03236 extern INT64
03237 cwh_cray_type_from_MTYPE(TYPE_ID ty)
03238 {
03239    INT64 rtype;
03240    f90_type_t  *f90_type_ptr;
03241 
03242    rtype = 0;
03243    f90_type_ptr = (f90_type_t *)&rtype;
03244 
03245    switch (ty) {
03246     case MTYPE_I1: 
03247         f90_type_ptr->type = 2;
03248         f90_type_ptr->kind_or_star = 3;
03249         f90_type_ptr->int_len = 8;
03250         f90_type_ptr->dec_len = 1;
03251         return (rtype);
03252         // return (0x2300801);
03253 
03254     case MTYPE_I2: 
03255         f90_type_ptr->type = 2;
03256         f90_type_ptr->kind_or_star = 3;
03257         f90_type_ptr->int_len = 16;
03258         f90_type_ptr->dec_len = 2;
03259         return (rtype);
03260         // return (0x2301002);
03261 
03262     case MTYPE_I4: 
03263         f90_type_ptr->type = 2;
03264         f90_type_ptr->kind_or_star = 3;
03265         f90_type_ptr->int_len = 32;
03266         f90_type_ptr->dec_len = 4;
03267         return (rtype);
03268         // return (0x2302004);
03269 
03270     case MTYPE_I8: 
03271         f90_type_ptr->type = 2;
03272         f90_type_ptr->kind_or_star = 3;
03273         f90_type_ptr->int_len = 64;
03274         f90_type_ptr->dec_len = 8;
03275         return (rtype);
03276         // return (0x2304008);
03277 
03278     case MTYPE_F4: 
03279         f90_type_ptr->type = 3;
03280         f90_type_ptr->kind_or_star = 3;
03281         f90_type_ptr->int_len = 32;
03282         f90_type_ptr->dec_len = 4;
03283         return (rtype);
03284         // return (0x3302004);
03285 
03286     case MTYPE_F8: 
03287         f90_type_ptr->type = 3;
03288         f90_type_ptr->kind_or_star = 3;
03289         f90_type_ptr->int_len = 64;
03290         f90_type_ptr->dec_len = 8;
03291         return (rtype);
03292         // return (0x3304008);
03293 
03294     case MTYPE_FQ: 
03295         f90_type_ptr->type = 3;
03296         f90_type_ptr->kind_or_star = 3;
03297         f90_type_ptr->int_len = 128;
03298         f90_type_ptr->dec_len = 16;
03299         return (rtype);
03300         // return (0x3308010);
03301 
03302     case MTYPE_C4: 
03303         f90_type_ptr->type = 4;
03304         f90_type_ptr->kind_or_star = 3;
03305         f90_type_ptr->int_len = 64;
03306         f90_type_ptr->dec_len = 4;
03307         return (rtype);
03308         // return (0x4304004);
03309 
03310     case MTYPE_C8: 
03311         f90_type_ptr->type = 4;
03312         f90_type_ptr->kind_or_star = 3;
03313         f90_type_ptr->int_len = 128;
03314         f90_type_ptr->dec_len = 8;
03315         return (rtype);
03316         // return (0x4308008);
03317 
03318     case MTYPE_CQ: 
03319         f90_type_ptr->type = 4;
03320         f90_type_ptr->kind_or_star = 3;
03321         f90_type_ptr->int_len = 256;
03322         f90_type_ptr->dec_len = 16;
03323         return (rtype);
03324         // return (0x4310010);
03325    }
03326    Is_True(0,("Do not know what to do with type"));
03327 
03328    return(rtype);
03329 }
03330 
03331 /*================================================================
03332  * 
03333  * cwh_types_init_target
03334  *
03335  * Set up the target-specific variables.
03336  *
03337  *================================================================
03338  */
03339 extern void 
03340 cwh_types_init_target(void)
03341 {
03342    if (Pointer_Size == 4) {
03343       DOPE_bound_sz = 4;
03344       DOPE_dim_offset = 32;
03345       DOPE_sz = 32;
03346       dope_btype = dope_btype_32;
03347       dope_offset = dope_offset_32;
03348       NL_Table_Index = 0 ;
03349 
03350    } else {
03351       DOPE_bound_sz = 8;
03352       DOPE_dim_offset = 48;
03353       DOPE_sz = 48;
03354       dope_btype = dope_btype_64;
03355       dope_offset = dope_offset_64;
03356       NL_Table_Index = 1 ;
03357    }
03358    logical4_ty = cwh_types_mk_logical_TY(32,4);
03359 }
03360 
03361 /*===================================================
03362  *
03363  * The routines below are for making and marking the TY's 
03364  * on ILOADs, ISTOREs, MLOADs and MSTOREs which are through F90 
03365  * Pointers. These need to be marked so that the optimizer alias analysis can 
03366  * do its job.
03367  *
03368  *=====================================================
03369  */
03370 
03371 typedef struct {
03372    TY_IDX ty;
03373    TY_IDX f90_pointed;
03374 } type_pair_t;
03375 
03376 static type_pair_t * pairs;
03377 static INT num_type_pairs=0;
03378 static INT max_type_pairs=0;
03379 static INT pair_typenum=0;
03380 #define TYPE_ALLOC_CHUNK_SIZE 32
03381 
03382 static TY_IDX 
03383 cwh_types_find_f90_pointer_ty (TY_IDX ty)
03384 {
03385    INT i;
03386    for (i=0; i < num_type_pairs; i++) {
03387       if (pairs[i].ty == ty) {
03388          return(pairs[i].f90_pointed);
03389       }
03390    }
03391    return 0;
03392 }
03393 
03394 extern TY_IDX
03395 cwh_types_mk_f90_pointer_ty (TY_IDX ty)
03396 {
03397    static BOOL made_real_types=FALSE;
03398    static BOOL made_unsigned_types=FALSE;
03399    TY_IDX t_idx;
03400    char buf[32];
03401 
03402    t_idx = cwh_types_find_f90_pointer_ty (ty);
03403    if (t_idx) return (t_idx);
03404 
03405    num_type_pairs += 1;
03406    if (num_type_pairs > max_type_pairs) {
03407       /* Allocate another chunk in the pairs array */
03408       max_type_pairs += TYPE_ALLOC_CHUNK_SIZE;
03409       if (max_type_pairs==TYPE_ALLOC_CHUNK_SIZE) {
03410          pairs = (type_pair_t *) malloc(max_type_pairs * sizeof(type_pair_t));
03411       } else {
03412          pairs = (type_pair_t *) realloc(pairs,max_type_pairs * sizeof(type_pair_t));
03413       }
03414    }
03415    
03416    /* Make up the type */
03417 
03418    BUMP_TY_COUNTER(c_TY_f90_POINTER) ;
03419 
03420    sprintf ( buf, ".anon_f90pointer.%d",++pair_typenum);
03421 
03422    t_idx = cwh_types_new_TY ( TRUE, Pointer_Size);
03423    TY& t = Ty_Table[t_idx];
03424    TY_Init(t, Pointer_Size, KIND_POINTER, Pointer_Mtype, Save_Str (buf));
03425    Set_TY_pointed(t, ty);
03426    Set_TY_is_f90_pointer(t);
03427 
03428    t_idx = cwh_types_unique_TY(t_idx);
03429 
03430    pairs[num_type_pairs-1].ty = ty;
03431    pairs[num_type_pairs-1].f90_pointed = t_idx;
03432 
03433    /* If the ty is for a complex type, make up the corresponding real pointers.
03434     * They will probably be there, but just in case, we make them up.
03435     */
03436    if (!made_real_types && MTYPE_is_complex(TY_mtype(ty))) {
03437 
03438       made_real_types = TRUE;
03439       (void) cwh_types_mk_f90_pointer_ty (Be_Type_Tbl(MTYPE_F4));
03440       (void) cwh_types_mk_f90_pointer_ty (Be_Type_Tbl(MTYPE_F8));
03441       (void) cwh_types_mk_f90_pointer_ty (Be_Type_Tbl(MTYPE_FQ));
03442    }
03443 
03444    /* If the ty is for an MLOAD or MSTORE, make up the types for U1, U4 and U8 */
03445    if (!made_unsigned_types && MTYPE_is_m(TY_mtype(ty))) {
03446       made_unsigned_types = TRUE;
03447       (void) cwh_types_mk_f90_pointer_ty (Be_Type_Tbl(MTYPE_U8));
03448       (void) cwh_types_mk_f90_pointer_ty (Be_Type_Tbl(MTYPE_U4));
03449       (void) cwh_types_mk_f90_pointer_ty (Be_Type_Tbl(MTYPE_U1));
03450    }
03451        
03452    return t_idx;
03453 }
03454 
03455 /*================================================================
03456  *
03457  * cwh_types_new_TY
03458  *
03459  * Create a new TY of the given alignment. Update the id of the
03460  * last created, so it can be deallocated if a duplicate.
03461  *
03462  * ================================================================
03463  */
03464 static TY_IDX 
03465 cwh_types_new_TY(BOOL global, INT32 align) 
03466 {
03467   TY_IDX idx;
03468 
03469   TY& ty = New_TY(idx);
03470 
03471   Set_TY_align(idx,align);
03472 
03473   Last_TY_Created = idx;
03474 
03475   return idx ;
03476 }
03477 
03478 /*================================================================
03479  *
03480  * cwh_types_unique_TY
03481  *
03482  * check to see if a similar type has been created. 
03483  * Use it if so & delete input TY. It's expected to
03484  * be the last created. Alignment is handled
03485  *
03486  *  a) TY_is_unique updates just index ie: preserves flags
03487  *  b) Last_TY_Created is created with alignment.
03488  * 
03489  * Last_TY_Created is decremented, so can delete n-1, with luck,
03490  * if nested...
03491  *
03492  * ================================================================
03493  */
03494 TY_IDX 
03495 cwh_types_unique_TY(TY_IDX ty_idx) 
03496 {
03497   TY_IDX new_ty_idx;
03498 
03499   new_ty_idx = TY_is_unique(ty_idx);
03500 
03501   if (new_ty_idx != ty_idx) {
03502     if (ty_idx == Last_TY_Created) {
03503       Ty_tab.Delete_last();
03504       Last_TY_Created-- ;
03505     }
03506 
03507   }
03508   return new_ty_idx;
03509 }
03510 
03511 TY_IDX
03512 cwh_types_make_pointer_type(TY_IDX ty, BOOL f90_pointer) 
03513 {
03514    if (f90_pointer) {
03515       return Make_F90_Pointer_Type (ty);
03516    } else {
03517 
03518       return Make_Pointer_Type (ty);
03519    }
03520 }
03521 
03522 /*================================================================
03523  *
03524  * cwh_types_make_bounds_ST
03525  *
03526  * Makes a bounds ST for non-constant cases.
03527  *
03528  * ================================================================
03529  */
03530 static ST *
03531 cwh_types_make_bounds_ST(void)
03532 {
03533   ST * st; 
03534 
03535   TY_IDX bnd_ty = Be_Type_Tbl(cwh_bound_int_typeid);
03536 
03537   st = cwh_stab_temp_ST(bnd_ty,"bnd") ;
03538   return st;
03539 }
03540 
03541 /*================================================================
03542  *
03543  * cwh_types_copyin_pragma
03544  *
03545  * Makes a copyin xpragma for the bounds ST passed in. Assumes
03546  * not called for hosted ST (not reqd, & no hosted Preamble block yet...)
03547  * Note special case for character lengths, in cwh_addr_store_ST.
03548  *
03549  * ================================================================
03550  */
03551 extern void
03552 cwh_types_copyin_pragma(ST *st)
03553 {
03554   WN *pragma;
03555 
03556 #if 0
03557   if (enable_mp_processing || process_cri_mp_pragmas) {
03558 #endif
03559     if (ST_sym_class(st) == CLASS_VAR &&
03560         !ST_auxst_xpragma_copyin(st)) {
03561 
03562       pragma = WN_CreateXpragma ( WN_PRAGMA_COPYIN_BOUND, (ST_IDX) NULL, 1 );
03563       WN_kid0(pragma) = cwh_addr_load_ST(st,0,0);
03564       cwh_block_append_given_id(pragma,Preamble_Block,FALSE);
03565       Set_ST_auxst_xpragma_copyin(st,TRUE);
03566     }
03567 #if 0
03568   }
03569 #endif
03570 }
03571 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines