Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ty2f.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  *  12-Apr-95 - Original Version
00042  *
00043  * Description:
00044  *
00045  *   Translates a TY entry to a Fortran type.
00046  *
00047  * ====================================================================
00048  * ====================================================================
00049  */
00050 #include <iostream>
00051 #include "whirl2f_common.h"
00052 #include "PUinfo.h"
00053 #include "wn2f.h"
00054 #include "ty2f.h"
00055 #include "st2f.h"
00056 #include "tcon2f.h"
00057 #include "wn2f_load_store.h"
00058 #include "ty_ftn.h"
00059 
00060 extern WN* PU_Body;
00061 extern BOOL Array_Bnd_Temp_Var;
00062 extern BOOL W2F_OpenAD; /* w2f_driver.h */
00063 
00064 #define NUMBER_OF_OPERATORS (OPERATOR_LAST + 1)
00065 
00066 //#define DBGPATH 1
00067 
00068 typedef WN2F_STATUS (*WN2F_HANDLER_FUNC)(TOKEN_BUFFER, WN*, WN2F_CONTEXT);
00069 extern WN2F_HANDLER_FUNC  WN2F_Handler[NUMBER_OF_OPERATORS];
00070 BOOL Use_Purple_Array_Bnds_Placeholder = FALSE;
00071 
00072 /* TY2F_Handler[] maps a TY_kind to a function that translates
00073  * a type of the given kind into Fortran.  Should the ordinal
00074  * numbering of the KIND change in "../common/com/stab.h", then
00075  * a corresponding change must be made here.
00076  */
00077 
00078 typedef void (*TY2F_HANDLER_FUNC)(TOKEN_BUFFER, TY_IDX);
00079 static void TY2F_invalid(TOKEN_BUFFER decl_tokens, TY_IDX ty);
00080 static void TY2F_scalar(TOKEN_BUFFER decl_tokens, TY_IDX ty);
00081 static void TY2F_array(TOKEN_BUFFER decl_tokens, TY_IDX ty);
00082 static void TY2F_array_for_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty);
00083 static void TY2F_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty);
00084 static void TY2F_2_struct(TOKEN_BUFFER decl_tokens,TY_IDX ty);
00085 static void TY2F_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty);
00086 static void TY2F_void(TOKEN_BUFFER decl_tokens, TY_IDX ty) ;
00087 static WN* find_stmt(ST* st,WN* wn);
00088 
00089 
00090 static const TY2F_HANDLER_FUNC 
00091    TY2F_Handler[KIND_LAST/*TY_KIND*/] =
00092 {
00093    &TY2F_invalid,   /* KIND_INVALID */
00094    &TY2F_scalar,    /* KIND_SCALAR */
00095    &TY2F_array,     /* KIND_ARRAY */
00096    &TY2F_struct,    /* KIND_STRUCT */
00097    &TY2F_pointer,   /* KIND_POINTER */
00098    &TY2F_invalid,   /* KIND_FUNCTION */
00099    &TY2F_void,      /* KIND_VOID */
00100 }; /* TY2F_Handler */
00101 
00102 /* detect parts of f90 dope vectors which should be output. Most are I4 boundaries */
00103 /* except the bofst >16 - just for num_dims */
00104 
00105 #define NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(f) \
00106   (!FLD_is_bit_field(f) || (FLD_is_bit_field(f) && (FLD_bofst(f) == 0) || FLD_bofst(f) > 16))
00107 
00108 /*---------------------- A few utility routines -----------------------*/
00109 /*---------------------------------------------------------------------*/
00110 
00111         
00112 void
00113 WN2F_Append_Purple_Xsym(TOKEN_BUFFER tokens, ST *st)
00114 {
00115    const char * const name   = W2F_Object_Name(st);
00116    mUINT32      const id     = ST_st_idx(st);
00117    ST_SCLASS    const sclass = ST_sclass(st);
00118    ST_EXPORT    const export_class = (ST_EXPORT) ST_export(st);
00119 
00120    Append_Token_String(tokens, name);
00121    Append_Token_Special(tokens, ',');
00122    Append_Token_String(tokens, Number_as_String(id, "%llu"));
00123    Append_Token_Special(tokens, ',');
00124    Append_Token_String(tokens, Number_as_String(sclass, "%lld"));
00125    Append_Token_Special(tokens, ',');
00126    Append_Token_String(tokens, Number_as_String(export_class, "%lld"));
00127    Append_Token_Special(tokens, ',');
00128    Append_Token_String(tokens, "0"); /* Flags */
00129 } /* WN2F_Append_Purple_Xsym */
00130 
00131 
00132 
00133 static void
00134 WN2F_tempvar_rhs(TOKEN_BUFFER tokens,
00135                  WN * wn)
00136 {
00137    WN2F_CONTEXT context= INIT_WN2F_CONTEXT;
00138    TOKEN_BUFFER rhs_tokens;
00139 
00140    /* The rhs */
00141    if (tokens) {
00142       rhs_tokens = New_Token_Buffer();
00143       WN2F_translate(rhs_tokens, WN_kid0(wn), context);
00144       Append_And_Reclaim_Token_List(tokens, &rhs_tokens);
00145    }
00146 }
00147 
00148 // GetTmpVarTransInfo: mfef90 may define array bound extents using
00149 // temporaries that cannot be directly translated into Fortran. E.g:
00150 // 't__1' below
00151 //    REAL(w2f__8) XXX(1 : t__1)
00152 // should be the formal parameter 'N'
00153 //    REAL(w2f__8) XXX(1 : N)
00154 // This routine finds the definition of 't__1'
00155 //    t__1 = N
00156 // so that 't__1' can be used instead of 'N'.
00157 static BOOL
00158 GetTmpVarTransInfo(TOKEN_BUFFER   decl_tokens,
00159                    ST_IDX         arbnd,
00160                    WN*            wn)
00161 {
00162    // Note: wn must be an OPR_BLOCK
00163 
00164    // Search through all the statements in 'wn' trying to find the
00165    // definition of the tempvar in 'arbnd'.
00166    const char* bndSymNm = ST_name(ST_ptr(arbnd));
00167   
00168    WN* foundStmt = NULL;
00169    for (WN* stmt = WN_first(wn); (stmt); stmt = WN_next(stmt)) {
00170       // mfef90 typically generates temporary-define statements like this
00171       bool isDefinedInSTID = 
00172         ((WN_operator(stmt) == OPR_STID) && 
00173          (strcmp(ST_name(WN_st(stmt)), bndSymNm) == 0));
00174       // whirl2xaif will generate statements like this
00175       bool isDefinedInISTORE =
00176         ((WN_operator(stmt) == OPR_ISTORE) && 
00177          (WN_operator(WN_kid1(stmt)) == OPR_LDA) &&
00178          (strcmp(ST_name(WN_st(WN_kid1(stmt))), bndSymNm) == 0));
00179       
00180       if (isDefinedInSTID || isDefinedInISTORE) {
00181          foundStmt = stmt;
00182          break;
00183       }
00184    }
00185    
00186    if (foundStmt) {
00187       WN2F_tempvar_rhs(decl_tokens, foundStmt);
00188       return TRUE;
00189    }
00190    else {
00191       return FALSE;
00192    }
00193 }
00194 
00195 static WN *
00196 find_stmt(ST * st, WN* wn)
00197 {
00198   WN *first_stmt = wn;
00199   WN *stmt = wn;
00200   ST *rst;
00201 
00202   while ((stmt !=NULL)&&((WN_operator(stmt)!=OPR_STID)
00203                            ||(WN_operator(stmt) ==OPR_STID)
00204                              &&strcmp(ST_name(WN_st(stmt)),ST_name(st))))
00205                                                                                                
00206    stmt = WN_next(stmt);
00207 
00208    if(stmt){
00209      rst = WN_st(WN_kid0(stmt));
00210      if(ST_is_temp_var(rst))
00211           stmt = find_stmt(rst,first_stmt);
00212      }
00213      
00214    if(stmt)
00215         return stmt;
00216    else return NULL;
00217 
00218 }    
00219 
00220 static void
00221 TY2F_Append_Array_Bnd_Ph(TOKEN_BUFFER decl_tokens, 
00222                          ST_IDX       arbnd,
00223                          BOOL         purple_assumed_size)
00224 {
00225    char ptr_string[128];
00226    const char * p = "%s";
00227    WN  * wn;
00228 
00229    if (purple_assumed_size)
00230      if ((ST_sclass(arbnd)==SCLASS_FORMAL)||
00231                 (ST_sclass(arbnd)==SCLASS_FORMAL_REF))
00232      {
00233       /* We are already within a placeholder for an assumed-sized array */
00234 
00235        p = "[%s]";
00236    
00237 
00238    sprintf(ptr_string, p, ST_name(ST_ptr(arbnd)));
00239    Append_Token_String(decl_tokens, ptr_string);
00240    } else
00241    Array_Bnd_Temp_Var=TRUE;
00242 
00243   if (!ST_is_temp_var(ST_ptr(arbnd)))
00244      Append_Token_String(decl_tokens, ST_name(arbnd));
00245   else{
00246    wn= PU_Body;
00247    if (!GetTmpVarTransInfo(decl_tokens,arbnd,wn)) {
00248           Append_Token_String(decl_tokens, "1");
00249 //          Append_Token_String(decl_tokens, ST_name(arbnd));
00250    }
00251   }
00252 } /* TY2F_Append_Array_Bnd_Ph */
00253 
00254 
00255 # if 0
00256 static void
00257 TY2F_Append_ARB(TOKEN_BUFFER decl_tokens, ARB_HANDLE arb, BOOL purple_assumed_size)
00258 {
00259    WN2F_CONTEXT context = INIT_WN2F_CONTEXT;
00260    
00261    /* All array acceses have been normalized to assume arrays with
00262     * bounds based at 1 (Fortran default), so we do the same thing here.
00263     * There is no need to emit the lower bound, since 1 is the default
00264     * anyway:
00265     *
00266     *   TCON2F_translate(decl_tokens, 
00267     *                    Host_To_Targ(MTYPE_I4, 1LL),
00268     *                    FALSE *is_logical*);
00269     *   Append_Token_Special(decl_tokens, ':');
00270     */
00271 
00272    /* Append the upper-bound */
00273    if (ARB_const_lbnd(arb) && /* Constant lower bound */
00274        ARB_const_ubnd(arb))   /* Constant upper bound */
00275    {
00276       if (ARB_ubnd_val(arb) - ARB_lbnd_val(arb) >= 0)
00277       {
00278          if ((ARB_ubnd_val(arb) -ARB_lbnd_val(arb)+ 1LL)>=INT_MAX )   
00279          TCON2F_translate(decl_tokens, 
00280                           Host_To_Targ(MTYPE_I8, 
00281                                        ARB_ubnd_val(arb) - 
00282                                        ARB_lbnd_val(arb) + 1LL),
00283                           FALSE /*is_logical*/);
00284           else
00285           TCON2F_translate(decl_tokens,
00286                           Host_To_Targ(MTYPE_I4,
00287                                        ARB_ubnd_val(arb) -
00288                                        ARB_lbnd_val(arb) + 1LL),
00289                           FALSE /*is_logical*/);
00290 
00291        }
00292       else
00293          Append_Token_Special(decl_tokens, '*');
00294          
00295    }
00296    else
00297    {
00298       /* We have some combination of non-constant bounds, so we try to
00299        * normalize these to account for index-expressions that have been
00300        * normalized to "1" based indices.
00301        */
00302       if ((!ARB_const_lbnd(arb) && ARB_lbnd_var(arb) == (ST_IDX) 0) ||
00303                (!ARB_const_ubnd(arb) && ARB_ubnd_var(arb) == (ST_IDX) 0))
00304       {
00305          Append_Token_Special(decl_tokens, ':');   
00306       }
00307       else if (ARB_const_ubnd(arb))
00308       {
00309          if ((ARB_ubnd_val(arb) + 1LL)>=INT_MAX )
00310 
00311          TCON2F_translate(decl_tokens, 
00312                           Host_To_Targ(MTYPE_I8,
00313                                        ARB_ubnd_val(arb) + 1LL),
00314                           FALSE /*is_logical*/);
00315          else
00316          TCON2F_translate(decl_tokens,
00317                           Host_To_Targ(MTYPE_I4,
00318                                        ARB_ubnd_val(arb) + 1LL),
00319                           FALSE /*is_logical*/);
00320 
00321          Append_Token_Special(decl_tokens, '-');
00322          Append_Token_Special(decl_tokens, '(');
00323          set_WN2F_CONTEXT_no_parenthesis(context);
00324          TY2F_Append_Array_Bnd_Ph(decl_tokens, 
00325                                   ARB_lbnd_var(arb), 
00326                                   purple_assumed_size);
00327          Append_Token_Special(decl_tokens, ')');
00328       }
00329       else 
00330       {
00331          if (strncmp(ST_name(ST_ptr(ARB_ubnd_var(arb))),"s$",2)==0) {
00332            TCON2F_translate(decl_tokens,
00333                              Host_To_Targ(MTYPE_I4,
00334                                           1LL),
00335                              FALSE /*is_logical*/);
00336 
00337            Append_Token_Special(decl_tokens,':');
00338            Append_Token_Special(decl_tokens,'*');}
00339 
00340          else 
00341          if (ARB_const_lbnd(arb)) {
00342 
00343          BOOL zero_lbnd = (ARB_lbnd_val(arb) - 1LL == 0LL);
00344 
00345          if (!zero_lbnd)
00346          {
00347             Append_Token_Special(decl_tokens, '(');
00348             set_WN2F_CONTEXT_no_parenthesis(context);
00349          }
00350          TY2F_Append_Array_Bnd_Ph(decl_tokens, 
00351                                   ARB_ubnd_var(arb), 
00352                                   purple_assumed_size);
00353          if (!zero_lbnd)
00354          {
00355             Append_Token_Special(decl_tokens, ')');
00356             Append_Token_Special(decl_tokens, '-');
00357             if ((ARB_lbnd_val(arb) - 1LL)>= INT_MAX)   
00358             TCON2F_translate(decl_tokens, 
00359                              Host_To_Targ(MTYPE_I8,
00360                                           ARB_lbnd_val(arb) - 1LL),
00361                              FALSE /*is_logical*/);
00362             else
00363             TCON2F_translate(decl_tokens,
00364                              Host_To_Targ(MTYPE_I4,
00365                                           ARB_lbnd_val(arb) - 1LL),
00366                              FALSE /*is_logical*/);
00367 
00368          }
00369       }
00370       else
00371       {
00372          set_WN2F_CONTEXT_no_parenthesis(context);
00373          Append_Token_String(decl_tokens, "1");
00374          Append_Token_Special(decl_tokens, '+');
00375          Append_Token_Special(decl_tokens, '(');
00376          TY2F_Append_Array_Bnd_Ph(decl_tokens,
00377                                   ARB_ubnd_var(arb), 
00378                                   purple_assumed_size);
00379          Append_Token_Special(decl_tokens, ')');
00380          Append_Token_Special(decl_tokens, '-');
00381          Append_Token_Special(decl_tokens, '(');
00382          TY2F_Append_Array_Bnd_Ph(decl_tokens,
00383                                   ARB_lbnd_var(arb), 
00384                                   purple_assumed_size);
00385          Append_Token_Special(decl_tokens, ')');
00386       }
00387     }
00388    } /* Constant bounds */
00389 } /* TY2F_Append_ARB */
00390 # endif
00391 
00392 
00393 static void
00394 TY2F_Append_ARB (TOKEN_BUFFER decl_tokens,ARB_HANDLE arb,BOOL purple_assumed_size)
00395   {
00396      WN2F_CONTEXT context = INIT_WN2F_CONTEXT;
00397 
00398        if (ARB_const_lbnd(arb))
00399               TCON2F_translate(decl_tokens,
00400                               Host_To_Targ(MTYPE_I4,
00401                                              ARB_lbnd_val(arb)),
00402                             FALSE /*is_logical*/);
00403        else if (ARB_lbnd_var(arb) != 0) {
00404            TY2F_Append_Array_Bnd_Ph(decl_tokens,
00405                                   ARB_lbnd_var(arb),
00406                                   purple_assumed_size);
00407             }
00408 
00409       Append_Token_Special(decl_tokens, ':');
00410       if (purple_assumed_size )
00411            Append_Token_Special(decl_tokens,'*');
00412       else     
00413        if (ARB_const_ubnd(arb))
00414            TCON2F_translate(decl_tokens,
00415                               Host_To_Targ(MTYPE_I4,
00416                                              ARB_ubnd_val(arb)),
00417                             FALSE /*is_logical*/); 
00418        else  if (ARB_ubnd_var(arb) != 0 ){
00419            TY2F_Append_Array_Bnd_Ph(decl_tokens,
00420                                   ARB_ubnd_var(arb),
00421                                   purple_assumed_size);
00422             }
00423           
00424 } 
00425 
00426 static void
00427 TY2F_Append_Assumed_Single_Dim(TOKEN_BUFFER decl_tokens,
00428                                ST          *st,
00429                                TY_IDX       element_ty)
00430 {
00431    /* Insert a purple placeholder to represent a one-dimensional array:
00432     *
00433     *  <#PRP_XSYM:ASSUMED_ARRAY name, id, sclass, exports, flags, 
00434     *                           1<>, element_size#>
00435     */
00436    Append_Token_String(decl_tokens, "<#PRP_XSYM:ASSUMED");
00437    WN2F_Append_Purple_Xsym(decl_tokens, st);
00438    Append_Token_Special(decl_tokens, ',');
00439    Append_Token_String(decl_tokens, Number_as_String(1, "%llu"));
00440    Append_Token_Special(decl_tokens, '<');
00441    Append_Token_Special(decl_tokens, '>');
00442    Append_Token_Special(decl_tokens, ',');
00443    Append_Token_String(decl_tokens, 
00444                        Number_as_String(TY_size(element_ty), "%llu"));
00445    Append_Token_String(decl_tokens, "#>");
00446 } /* TY2F_Append_Assumed_Single_Dim */
00447 
00448 static void
00449 TY2F_Purple_Ptr_As_Array(TOKEN_BUFFER decl_tokens, ST *st, TY_IDX element_ty)
00450 {
00451    if (TY_is_character(element_ty))
00452    {
00453       TOKEN_BUFFER tokens = New_Token_Buffer();
00454 
00455       Append_Token_String(tokens, "CHARACTER*(");
00456       TY2F_Append_Assumed_Single_Dim(tokens, st, element_ty);
00457       Append_Token_Special(tokens, ')');
00458       Prepend_And_Reclaim_Token_List(decl_tokens, &tokens);
00459    }
00460    else
00461    {
00462       Append_Token_Special(decl_tokens, '(');
00463       TY2F_Append_Assumed_Single_Dim(decl_tokens, st, element_ty);
00464       Append_Token_Special(decl_tokens, ')');
00465    }
00466 } /* TY2F_Purple_Ptr_As_Array */
00467 
00468 
00469 static void
00470 TY2F_Purple_Assumed_Sized_Array(TOKEN_BUFFER decl_tokens, ST *st, TY_IDX ty)
00471 {
00472    ASSERT_DBG_FATAL(TY_kind(ty) == KIND_ARRAY,
00473                     (DIAG_W2F_UNEXPECTED_TYPE_KIND,
00474                      TY_kind(ty), "TY2F_Purple_Assumed_Sized_Array"));
00475 
00476    if (TY_is_character(ty))
00477    {
00478       TOKEN_BUFFER tokens = New_Token_Buffer();
00479 
00480       Append_Token_String(tokens, "CHARACTER*(");
00481       TY2F_Append_Assumed_Single_Dim(tokens, st, TY_AR_etype(ty));
00482       Append_Token_Special(tokens, ')');
00483       Prepend_And_Reclaim_Token_List(decl_tokens, &tokens);
00484    }
00485    else
00486    {
00487       /* A regular assumed sized array, so insert a purple placeholder:
00488        *
00489        *  <#PRP_XSYM:ASSUMED_ARRAY name, id, sclass, exports, flags, 
00490        *                           num_bounds<bnds>, esize#>
00491        *
00492        * where "bnds" is a sequence of known bounds (B) or adjustable
00493        * bounds ([id]) for dimensions 0 -> (TY_AR_ndims(ty) - 2). Hence,
00494        * the number of comma-separated elements in bnds is one less than
00495        * num_bounds.
00496        */
00497 
00498       ARB_HANDLE  arb_base  = TY_arb(ty);
00499       INT32        dim  = ARB_dimension(arb_base) -1 ; 
00500 
00501       /* Prepend the element-type.
00502        */
00503       TY2F_translate(decl_tokens, TY_AR_etype(ty));
00504 
00505       /* Append a placeholder for the array bounds.
00506        */
00507       Append_Token_Special(decl_tokens, '(');
00508       Append_Token_String(decl_tokens, "<#PRP_XSYM:ASSUMED");
00509       WN2F_Append_Purple_Xsym(decl_tokens, st);
00510       Append_Token_Special(decl_tokens, ',');
00511       Append_Token_String(decl_tokens,
00512                           Number_as_String(TY_AR_ndims(ty), "%llu"));
00513       Append_Token_Special(decl_tokens, '<');
00514       
00515       while ( dim >= 0)
00516       {
00517         ARB_HANDLE arb = arb_base[dim];
00518         
00519         if (dim-- > 0) 
00520           Append_Token_Special(decl_tokens, ',');
00521 
00522         TY2F_Append_ARB(decl_tokens,arb,TRUE);
00523 
00524       } 
00525 
00526       Append_Token_Special(decl_tokens, '>');
00527       Append_Token_Special(decl_tokens, ',');
00528       Append_Token_String(decl_tokens, 
00529                           Number_as_String(TY_size(TY_AR_etype(ty)), "%llu"));
00530       Append_Token_String(decl_tokens, "#>");
00531       Append_Token_Special(decl_tokens, ')');
00532    }
00533 } /* TY2F_Purple_Assumed_Sized_Array */
00534 
00535 static BOOL
00536 TY2F_is_character(TY_IDX ty)
00537 {
00538   while (TY_kind(ty) == KIND_ARRAY)
00539     ty = TY_etype(ty);
00540 
00541   return TY_is_character(ty);
00542 }
00543 /*------ Utilities for accessing and declaring KIND_STRUCT FLDs ------
00544  *---------------------------------------------------------------------*/
00545 
00546 #define FLD_INFO_ALLOC_CHUNK 16
00547 static FLD_PATH_INFO *Free_Fld_Path_Info = NULL;
00548 
00549 
00550 static BOOL
00551 TY2F_Pointer_To_Dope(TY_IDX ty)
00552 {
00553   /* Is this a pointer to a dope vector base */
00554 
00555   return (strcmp(TY_name(TY_pointed(ty)),".base.") == 0) ;
00556 
00557 }
00558 static FLD_PATH_INFO *
00559 New_Fld_Path_Info(FLD_HANDLE fld)
00560 {
00561    /* Allocates a new FLD_PATH_INFO, reusing any that have earlier
00562     * been freed up.  Dynamic allocation occurs in chunks of 16
00563     * (FLD_INFO_ALLOC_CHUNK) FLD_PATH_INFOs at a time.
00564     */
00565    FLD_PATH_INFO *fld_info;
00566    
00567    if (Free_Fld_Path_Info != NULL)
00568    {
00569       fld_info = Free_Fld_Path_Info;
00570       Free_Fld_Path_Info = fld_info->next;
00571    }
00572    else
00573    {
00574       INT info_idx;
00575       
00576       /* Allocate a new chunk of path infos, and put all except the
00577        * first one on the free-list.
00578        */
00579       fld_info = TYPE_ALLOC_N(FLD_PATH_INFO, FLD_INFO_ALLOC_CHUNK);
00580       fld_info[FLD_INFO_ALLOC_CHUNK-1].next = Free_Fld_Path_Info;
00581       for (info_idx = FLD_INFO_ALLOC_CHUNK-2; info_idx > 0; info_idx--)
00582          fld_info[info_idx].next = &fld_info[info_idx+1];
00583       Free_Fld_Path_Info = &fld_info[1];
00584    }
00585 
00586    fld_info->next = NULL;
00587    fld_info->arr_elt = FALSE;
00588    fld_info->arr_ofst = 0;
00589    fld_info->arr_wn = NULL;
00590    fld_info->fld = fld;
00591    return fld_info;
00592 } /* New_Fld_Path_Info */
00593 
00594 static STAB_OFFSET
00595 TY2F_Fld_Size(FLD_HANDLE this_fld, mUINT64  max_size)
00596 {
00597   /* Returns the size of the field, taking into account the offset
00598    * to the next (non-equivalence) field and the maximum field-size
00599    * (based on the structure size).
00600    */
00601   
00602   mUINT64 fld_size = TY_size(FLD_type(this_fld));
00603 
00604   /* Restrict the fld_size to the max_size */
00605   if (fld_size > max_size)
00606     fld_size = max_size;
00607   
00608   /* If this_fld is an equivalence field, then just return the current
00609    * fld_size (cannot be any different), otherwise search for a non-
00610    * equivalent next_fld at a higher offset.
00611    * TODO: mfef90 & mfef77 set the flag slightly differently in COMMON.
00612    * this really works only for mfef77.
00613    */
00614 
00615   if (!FLD_equivalence(this_fld))
00616     {
00617       FLD_ITER fld_iter = Make_fld_iter(this_fld);
00618 
00619       if (!FLD_last_field (fld_iter)) 
00620       {
00621         ++fld_iter;
00622         BOOL found = FALSE;
00623         mUINT64 noffset = 0; 
00624 
00625         do
00626         {
00627            FLD_HANDLE next_fld (fld_iter);
00628 
00629            if (!FLD_is_bit_field(next_fld)) 
00630              if (!(FLD_equivalence(next_fld) || FLD_ofst(this_fld) >= FLD_ofst(next_fld)))
00631              {
00632                found  = TRUE;
00633                noffset =  FLD_ofst(next_fld) ;
00634                break ;
00635              }
00636          } while (!FLD_last_field (fld_iter ++ )) ;
00637 
00638         if (found) 
00639           if (fld_size > noffset - FLD_ofst(this_fld))
00640             fld_size = noffset - FLD_ofst(this_fld) ;
00641       }
00642     }
00643   return fld_size;
00644 } /* TY2F_Fld_Size */
00645 
00646 
00647 static FLD_PATH_INFO *
00648 Select_Best_Fld_Path(FLD_PATH_INFO *path1,
00649                      FLD_PATH_INFO *path2,
00650                      TY_IDX         desired_ty,
00651                      mUINT64        desired_offset)
00652 {
00653    /* PRECONDITION: Both paths must be non-NULL and lead to a field
00654     *    at the desired_offset.
00655     *
00656     * Try to find the best of two paths to a field.  This routine
00657     * will be called for EVERY field at every place where a struct,
00658     * union, or equivalence field is accessed, so efficiency is of
00659     * uttmost importance.  The best path is returned, while the other
00660     * on is freed up.
00661     */
00662    FLD_PATH_INFO *best_path;
00663    mUINT64        offs1, offs2;
00664    FLD_PATH_INFO *p1, *p2;
00665    TY_IDX         t1,  t2;
00666    
00667    ASSERT_DBG_FATAL(path1 != NULL && path2 != NULL,
00668                     (DIAG_W2F_UNEXPEXTED_NULL_PTR, 
00669                      "path1 or path2", "Select_Best_Fld_Path"));
00670    
00671    /* Find the last field on each path */
00672    offs1 = FLD_ofst(path1->fld) + path1->arr_ofst;
00673    for (p1 = path1; p1->next != NULL; p1 = p1->next)
00674       offs1 += FLD_ofst(p1->next->fld) + p1->next->arr_ofst;
00675    offs2 = FLD_ofst(path2->fld) + path2->arr_ofst;
00676    for (p2 = path2; p2->next != NULL; p2 = p2->next)
00677       offs2 += FLD_ofst(p2->next->fld) + p2->next->arr_ofst;
00678 
00679    ASSERT_DBG_FATAL(offs1 == desired_offset && offs2 == desired_offset,
00680                     (DIAG_W2F_UNEXPEXTED_OFFSET,
00681                      offs1, "Select_Best_Fld_Path"));
00682 
00683    /* Get the element type (either the field type or the type of an
00684     * array element.
00685     */
00686    if (p1->arr_elt)
00687       t1 = TY_AR_etype(FLD_type(p1->fld));
00688    else
00689       t1 = FLD_type(p1->fld);
00690    if (p2->arr_elt)
00691       t2 = TY_AR_etype(FLD_type(p2->fld));
00692    else
00693       t2 = FLD_type(p2->fld);
00694 
00695    /* Compare types, in order of increasing accuracy */
00696    if (TY_mtype(t1) == TY_mtype(desired_ty) &&
00697        TY_mtype(t2) != TY_mtype(desired_ty))
00698       best_path = path1;
00699    else if (TY_mtype(t2) == TY_mtype(desired_ty) &&
00700             TY_mtype(t1) != TY_mtype(desired_ty))
00701       best_path = path2;
00702    else if (Stab_Identical_Types(t1, desired_ty,
00703                                  FALSE,  /* check_quals */
00704                                  TRUE,   /* check_scalars */
00705                                  FALSE)) /* ptrs_as_scalars */
00706       best_path = path1; /* path2 cannot possibly be any better */
00707    else if (Stab_Identical_Types(t2, desired_ty,
00708                                  FALSE,  /* check_quals */
00709                                  TRUE,   /* check_scalars */
00710                                  FALSE)) /* ptrs_as_scalars */
00711       best_path = path2;
00712    else
00713       best_path = path1;
00714 
00715    /* Free up the path not chosen */
00716    if (best_path == path1)
00717       TY2F_Free_Fld_Path(path2);
00718    else
00719       TY2F_Free_Fld_Path(path1);
00720 
00721    return best_path;
00722 } /* Select_Best_Fld_Path */
00723 
00724 
00725 static FLD_PATH_INFO *
00726 Construct_Fld_Path(FLD_HANDLE   fld,
00727                    TY_IDX    struct_ty,
00728                    TY_IDX    desired_ty,
00729                    mUINT64   desired_offset,
00730                    mUINT64   max_fld_size)
00731 {
00732    /* Returns the field path through "fld" found to best match the 
00733     * given offset and type.  As a minimum requirement, the offset 
00734     * must be as desired and the type must have the desired size
00735     * and alignment (with some concessions allowed for substrings).
00736     * The path is terminate with a NULL next pointer.  When no 
00737     * field matches the desired type and offset, NULL is returned.
00738     */
00739    FLD_PATH_INFO    *fld_path;
00740    const mUINT64     fld_offset = FLD_ofst(fld);
00741    TY_IDX            fld_ty = FLD_type(fld);
00742    BOOL              is_array_elt = FALSE;
00743    STAB_OFFSET       ofst_in_fld = 0;
00744    
00745     if (TY_is_f90_pointer(fld_ty))
00746           fld_ty = TY_pointed(fld_ty);
00747 
00748 
00749    /* This field cannot be on the path to a field with the given
00750     * attributes, unless the desired_offset is somewhere within
00751     * the field.
00752     */
00753 #if DBGPATH
00754    printf (" Construct: fld %s, struct %s, desired %s , des off %d \n",
00755            FLD_name(fld),
00756            TY_name(struct_ty),
00757            TY_name(desired_ty),
00758            desired_offset);
00759 #endif
00760 
00761 
00762    if (desired_offset < fld_offset ||
00763        desired_offset >= (fld_offset + TY_size(fld_ty)))
00764    {
00765       /* This field cannot be on the path to a field with the given
00766        * attributes, since the desired_offset is nowhere within
00767        * the field.
00768        */
00769       fld_path = NULL;
00770 #if DBGPATH
00771       printf ("     found NULL\n");
00772 #endif
00773    }
00774    else if (TY_Is_Array(fld_ty) && TY_is_character(fld_ty) &&
00775             TY_Is_Array(desired_ty) && TY_is_character(desired_ty))
00776    {
00777 #if DBGPATH
00778       printf ("     found char substring\n");
00779 #endif
00780       /* A match is found! */
00781       ofst_in_fld = (desired_offset - fld_offset)/TY_size(TY_AR_etype(fld_ty));
00782       ofst_in_fld *= TY_size(TY_AR_etype(fld_ty));
00783       if ((ofst_in_fld + TY_size(desired_ty)) > TY_size(fld_ty))
00784       {
00785          fld_path = NULL; /* The string does not fit */
00786       }
00787       else
00788       {
00789          fld_path = New_Fld_Path_Info(fld);
00790          if (TY_size(fld_ty) != TY_size(desired_ty))
00791          {
00792             fld_path->arr_elt = TRUE;
00793             fld_path->arr_ofst = ofst_in_fld;
00794          } 
00795       }
00796    }
00797    else
00798    {
00799       /* See if the field we are looking for may be an array element */
00800 
00801       if(TY_kind(desired_ty)==KIND_POINTER)   
00802           desired_ty = TY_pointed(desired_ty);
00803       if (TY_kind(desired_ty)==KIND_ARRAY)
00804           desired_ty = TY_AR_etype(desired_ty);
00805 
00806       is_array_elt = (TY_Is_Array(fld_ty) &&
00807                       (TY_Is_Structured(TY_AR_etype(fld_ty))||
00808                        TY2F_is_character(fld_ty) ||
00809                        Stab_Identical_Types(TY_AR_etype(fld_ty), desired_ty,
00810                                             FALSE,   /* check_quals */
00811                                             FALSE,   /* check_scalars */
00812                                             TRUE))); /* ptrs_as_scalars */
00813 #if DBGPATH
00814       printf ("     is_array = %d, fld_ty %s \n",is_array_elt,TY_name(fld_ty));
00815 #endif
00816 
00817       if (is_array_elt)
00818       {
00819          fld_ty = TY_AR_etype(fld_ty);
00820          ofst_in_fld =
00821             ((desired_offset - fld_offset)/TY_size(fld_ty)) * TY_size(fld_ty);
00822       }
00823 
00824       if (TY_Is_Structured(fld_ty) &&
00825           !Stab_Identical_Types(fld_ty, desired_ty,
00826                                 FALSE,  /* check_quals */
00827                                 FALSE,  /* check_scalars */
00828                                 TRUE))  /* ptrs_as_scalars */
00829       {
00830 #if DBGPATH
00831         printf ("     recurse \n");
00832 #endif
00833          FLD_PATH_INFO *fld_path2 = 
00834             TY2F_Get_Fld_Path(fld_ty, desired_ty, 
00835                               desired_offset - (fld_offset+ofst_in_fld));
00836          
00837          /* If a matching path was found, attach "fld" to the path */
00838          if (fld_path2 != NULL)
00839          {
00840             if (TY_split(Ty_Table[fld_ty]))
00841                fld_path = fld_path2; /* A stransparent substructure */
00842             else
00843             {
00844                fld_path = New_Fld_Path_Info(fld);
00845                fld_path->arr_elt = is_array_elt;
00846                fld_path->arr_ofst = ofst_in_fld;
00847                fld_path->next = fld_path2;
00848             }
00849          }
00850          else
00851          {
00852             fld_path = NULL;
00853          }
00854       }
00855       else /* This may be a field we want to take into account */
00856       {
00857          const STAB_OFFSET fld_size = TY2F_Fld_Size(fld, max_fld_size);
00858 
00859          /* We only match a field with the expected size, offset
00860           * and alignment.
00861           */
00862        
00863          if (desired_offset != fld_offset+ofst_in_fld || /* unexpected ofst */
00864 //           fld_size < (TY_size(fld_ty)+ofst_in_fld) || /* unexpected size */
00865              TY_align(struct_ty) < TY_align(fld_ty))     /* unexpected align */
00866          {
00867 #if DBGPATH
00868             printf ("     account - miss\n");
00869 #endif
00870 
00871             fld_path = NULL;
00872          }
00873          else /* A match is found! */
00874          {
00875 #if DBGPATH
00876            printf ("     account - match\n");
00877 #endif
00878             fld_path = New_Fld_Path_Info(fld);
00879             fld_path->arr_elt = is_array_elt;
00880             fld_path->arr_ofst = ofst_in_fld;
00881          }/*if*/
00882       } /*if*/
00883    } /*if*/
00884 
00885    return fld_path;
00886 } /* Construct_Fld_Path */
00887 
00888 
00889 const char * 
00890 TY2F_Fld_Name(FLD_HANDLE fld, 
00891               BOOL       common_or_equivalence,
00892               BOOL       alt_return_name)
00893 {
00894    /* Since fields may be accessed in an unqualified manner in Fortran,
00895     * e.g. for common block members and equivalences, so we need to treat
00896     * them similar to the way we would treat regular objects.
00897     */
00898    const char *fld_name;
00899 
00900    if (common_or_equivalence && !alt_return_name)
00901       fld_name = W2CF_Symtab_Nameof_Fld(fld);
00902    else
00903    {
00904       fld_name = WHIRL2F_make_valid_name(FLD_name(fld),FALSE);
00905       if (fld_name == NULL || *fld_name == '\0')
00906          fld_name = W2CF_Symtab_Nameof_Fld(fld);
00907    }
00908    return fld_name;
00909 } /* TY2F_Fld_Name */
00910 
00911 
00912 /*------ Utilities for accessing and declaring KIND_STRUCTs ------
00913  *----------------------------------------------------------------*/
00914 
00915 /* Local buffer to hold Fortran STRUCTURE declarations, which
00916  * should be appended to this buffer in the order in which
00917  * they are encountered.
00918  */
00919 static TOKEN_BUFFER TY2F_Structure_Decls = NULL;
00920 
00921 
00922 static void
00923 TY2F_Equivalence(TOKEN_BUFFER tokens, 
00924                  const char  *equiv_name, 
00925                  const char  *fld_name)
00926 {
00927    /* Append one equivalence statement to the tokens buffer,
00928     * keeping in mind that the equiv_name is based at index 1.
00929     */
00930    Append_Token_String(tokens, "EQUIVALENCE");
00931    Append_Token_Special(tokens, '(');
00932    Append_Token_String(tokens, equiv_name); /* equiv_name at given offset */
00933    Append_Token_Special(tokens, ',');
00934    Append_Token_String(tokens, fld_name);   /* fld_name at offset zero */
00935    Append_Token_Special(tokens, ')');
00936 } /* TY2F_Equivalence */
00937 
00938 
00939 const char* findEquivFldNm(TY_IDX struct_ty,
00940                            mUINT64 ofst,
00941                            FLD_HANDLE*& equivFld){ 
00942   FLD_ITER fld_iter = Make_fld_iter(TY_fld(struct_ty));
00943   do {
00944     FLD_HANDLE fld(fld_iter);
00945     UINT64 fldOfst = FLD_ofst(fld);
00946 //     std::cout << "JU: looking at " << FLD_name(fld) << ":" << FLD_ofst(fld) << std::endl; 
00947     if (ofst == fldOfst) { // need to match the offset 
00948       if (FLD_st(fld)) {  // common block elemens being referenced in an equivalence have a FLD_st
00949         equivFld=&fld;
00950         return ST_name(ST_ptr(FLD_st(fld)));
00951       }
00952       if (FLD_last_field(fld)) { // for local variables there is always one last one
00953         equivFld=&fld;
00954         return FLD_name(fld);
00955       }
00956     }
00957   } while (!FLD_last_field(fld_iter++));
00958   ASSERT_FATAL(false, 
00959                (DIAG_W2F_UNEXPECTED_CONTEXT, 
00960                 "findEquivFldNm"));
00961 } 
00962 
00963 static void
00964 TY2F_Equivalence_FldList(TOKEN_BUFFER tokens, 
00965                          TY_IDX       struct_ty,
00966                          FLD_HANDLE   fldlist,
00967 //                          UINT         equiv_var_idx,
00968                          mUINT64      ofst) {
00969   FLD_ITER fld_iter = Make_fld_iter(fldlist);
00970   do {
00971     FLD_HANDLE fld (fld_iter);
00972     if (TY_split(Ty_Table[FLD_type(fld)])) {
00973       TY2F_Equivalence_FldList(tokens, 
00974                                struct_ty,
00975                                TY_flist(Ty_Table[FLD_type(fld)]),
00976 //                             equiv_var_idx,
00977                                ofst + FLD_ofst(fld));
00978     }
00979     else if (FLD_equivalence(fld) ) {
00980       Append_F77_Indented_Newline(tokens, 1, NULL/*label*/);
00981 //       std::cout << "JU: searching for " << FLD_name(fld) << ":" << FLD_ofst(fld) << std::endl; 
00982       FLD_HANDLE *equivFld_p(NULL);
00983       const char* equivVarNm=findEquivFldNm(struct_ty,FLD_ofst(fld),equivFld_p);
00984       if (*equivFld_p==fld) // search came up with the same field, skip this
00985         continue; 
00986       TY2F_Equivalence(tokens,
00987                        equivVarNm,
00988                        TY2F_Fld_Name(fld_iter, TRUE/*equiv*/, FALSE/*alt_ret*/));
00989     }
00990   } while (!FLD_last_field (fld_iter++)) ;
00991 } /* TY2F_Equivalence_FldList */
00992 
00993 
00994 static void
00995 TY2F_Equivalence_List(TOKEN_BUFFER tokens, 
00996                       const TY_IDX struct_ty)
00997 {
00998    /* Append a nameless EQUIVALENCE specification statement for
00999     * each equivalence field in the given struct.  Declare a 
01000     * dummy symbol as an array of INTEGER*1 elements to represent
01001     * the structure and each EQUIVALENCE specification will then 
01002     * equivalence a field to this dummy-symbol at the field offset.
01003     *
01004     * Group these declarations together by prepending each 
01005     * declaration (including the first one) with a newline.
01006     *
01007     * For COMMON blocks, it is also necessary to emit one element
01008     * that is not an equivalence!
01009     */
01010    TY_IDX     equiv_ty;
01011    UINT       equiv_var_idx;
01012 
01013 //    /* Declare an INTEGER*1 array (or CHARACTER string?) variable
01014 //     * to represent the whole equivalenced structure. Don't unlock
01015 //     * the tmpvar, or a similar equivalence group (ie: TY) will 
01016 //     * get the same temp.
01017 //     */
01018 
01019 //    equiv_ty = Stab_Array_Of(Stab_Mtype_To_Ty(MTYPE_I1), TY_size(struct_ty));
01020 //    equiv_var_idx = Stab_Lock_Tmpvar(equiv_ty, &ST2F_Declare_Tempvar);
01021 
01022    /* Relate every equivalence field to the temporary variable.
01023     */
01024    TY2F_Equivalence_FldList(tokens, 
01025                             struct_ty, 
01026                             TY_flist(Ty_Table[struct_ty]),
01027 //                             equiv_var_idx,
01028                             0 /* Initial offset */ );
01029 } /* TY2F_Equivalence_List */
01030 
01031 static void
01032 TY2F_Translate_Structure(TY_IDX ty)
01033 {
01034    TOKEN_BUFFER fld_tokens, struct_tokens;
01035    FLD_ITER     fld_iter;
01036    const UINT   current_indent = Current_Indentation();
01037    TY& ty_rt  = Ty_Table[ty];
01038    
01039    ASSERT_DBG_FATAL(TY_kind(ty_rt) == KIND_STRUCT, 
01040                     (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01041                      TY_kind(ty_rt), "TY2F_Translate_Structure"));
01042 
01043    /* Emit structure header */
01044    Set_Current_Indentation(PUinfo_local_decls_indent);
01045    struct_tokens = New_Token_Buffer();
01046 
01047    if (WN2F_F90_pu) {
01048       Append_Token_String(struct_tokens, "TYPE ");
01049       Append_Token_String(struct_tokens, W2CF_Symtab_Nameof_Ty(ty));
01050    } else {
01051       Append_Token_String(struct_tokens, "STRUCTURE");
01052       Append_Token_String(struct_tokens, 
01053                           Concat3_Strings("/", W2CF_Symtab_Nameof_Ty(ty), "/"));
01054    }
01055 
01056   if (TY_is_sequence(ty_rt)) {
01057      Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01058      Append_Token_String(struct_tokens,"SEQUENCE");
01059    }
01060 
01061    /* Emit structure body */
01062    Increment_Indentation();
01063    FLD_IDX flist = ty_rt.Fld();
01064 
01065    if (flist != 0) {
01066      fld_iter = Make_fld_iter(TY_flist(ty_rt));
01067      do
01068        {
01069          FLD_HANDLE fld (fld_iter);
01070 
01071          /* if it's a bitfield, then assume it's part of a dope vector & */
01072          /* just put out the name of the first bitfield in this I4       */
01073 
01074          if(NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(fld_iter))
01075            {
01076              /* See if this field starts a map or a union */
01077 
01078              Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01079              if (FLD_begin_union(fld))
01080                {
01081                  Append_Token_String(struct_tokens, "UNION");
01082                  Increment_Indentation();
01083                  Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01084                }
01085              else if (FLD_begin_map(fld))
01086                {
01087                  Append_Token_String(struct_tokens, "MAP");
01088                  Increment_Indentation();
01089                  Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01090                }
01091 
01092              /* Declare this field */
01093 
01094              fld_tokens = New_Token_Buffer();
01095              Append_Token_String(fld_tokens, 
01096                                  TY2F_Fld_Name(fld_iter,
01097                                                FALSE/*common*/, 
01098                                                FALSE/*alt_ret_name*/));
01099 
01100              if (FLD_is_pointer(fld)) {
01101                 Prepend_Token_String(fld_tokens,",POINTER::");
01102                 if (TY_kind( FLD_type(fld))==KIND_ARRAY)
01103                      TY2F_array_for_pointer(fld_tokens,FLD_type(fld));
01104                 else
01105                   TY2F_translate(fld_tokens, FLD_type(fld));
01106               }
01107              else 
01108                     TY2F_translate(fld_tokens, FLD_type(fld));
01109 
01110              Append_And_Reclaim_Token_List(struct_tokens, &fld_tokens);
01111 
01112              /* See if this field terminates a map or union */
01113              if (FLD_end_union(fld))
01114                {
01115                  Decrement_Indentation();
01116                  Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01117                  Append_Token_String(struct_tokens, "END UNION");
01118                }
01119              else if (FLD_end_map(fld))
01120                {
01121                  Decrement_Indentation();
01122                  Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01123                  Append_Token_String(struct_tokens, "END MAP");
01124                }
01125            }       
01126        } while (!FLD_last_field (fld_iter++)) ;
01127    }
01128    /* Emit structure tail */
01129    Decrement_Indentation();
01130 
01131    Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01132 
01133    if (WN2F_F90_pu) {
01134       Append_Token_String(struct_tokens, "END TYPE");
01135    } else {
01136       Append_Token_String(struct_tokens, "END STRUCTURE");
01137    }
01138 
01139    Append_F77_Indented_Newline(struct_tokens, 1, NULL/*label*/);
01140    
01141    if (TY2F_Structure_Decls == NULL)
01142        TY2F_Structure_Decls = New_Token_Buffer();
01143 
01144    Append_F77_Indented_Newline(TY2F_Structure_Decls, 1, NULL/*label*/);
01145 
01146    Set_Current_Indentation(current_indent);
01147    Append_And_Reclaim_Token_List(TY2F_Structure_Decls, &struct_tokens);
01148 
01149 
01150 } /* TY2F_Translate_Structure */
01151 
01152 
01153 static void
01154 TY2F_Translate_EquivCommon_PtrFld(TOKEN_BUFFER tokens, FLD_HANDLE fld)
01155 {
01156    /* Declare the pointee and the pointer field of the common/eqivalence
01157     * block.
01158     */
01159    TOKEN_BUFFER decl_tokens = New_Token_Buffer();
01160    const char  *pointee_name = W2CF_Symtab_Nameof_Fld_Pointee(fld);
01161    const char  *fld_name = TY2F_Fld_Name(fld, 
01162                                          TRUE/*comm,equiv*/, 
01163                                          FALSE/*alt_ret_name*/);
01164 
01165    Append_Token_String(decl_tokens, pointee_name);
01166    TY2F_translate(decl_tokens, TY_pointed(FLD_type(fld)));
01167    Append_F77_Indented_Newline(decl_tokens, 1, NULL/*label*/);
01168 
01169    /* Declare the pointer type */
01170    Append_Token_String(decl_tokens, "POINTER");
01171    Append_Token_Special(decl_tokens, '(');
01172    Append_Token_String(decl_tokens, fld_name);
01173    Append_Token_Special(decl_tokens, ',');
01174    Append_Token_String(decl_tokens, pointee_name);
01175    Append_Token_Special(decl_tokens, ')');
01176    Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01177 } /* TY2F_Translate_EquivCommon_PtrFld */
01178 
01179 static void
01180 TY2F_Declare_Common_Flds(TOKEN_BUFFER tokens,
01181                          FLD_HANDLE   fldlist, 
01182                          BOOL         alt_return, /* Alternate return points */
01183                          BOOL        *is_equiv)   /* out */
01184 {
01185   FLD_ITER fld_iter = Make_fld_iter(fldlist);
01186 
01187   /* Emit specification statements for every element of the
01188    * common block, including equivalences.
01189    */  
01190 
01191   do
01192     {
01193       Append_F77_Indented_Newline(tokens, 1, NULL/*label*/);
01194 
01195       FLD_HANDLE fld (fld_iter);
01196       TY_IDX ty = FLD_type(fld);
01197 
01198       /* Determine whether or not the common-block contains any
01199        * equivalences (must all be at the top level).
01200        */
01201 
01202       *is_equiv = *is_equiv || FLD_equivalence(fld);
01203       
01204       /* Declare as specified in the symbol table */
01205       if (TY_split(Ty_Table[ty]))
01206         {
01207           /* Treat a full split element as a transparent data-structure */
01208 
01209           TY2F_Declare_Common_Flds(tokens,
01210                                    TY_flist(Ty_Table[ty]),
01211                                    alt_return,
01212                                    is_equiv);
01213         }
01214       else if (TY_Is_Pointer(ty))
01215         {
01216           TY2F_Translate_EquivCommon_PtrFld(tokens, fld_iter);
01217         }
01218       else /* Non-pointer common field */
01219         {
01220           TOKEN_BUFFER decl_tokens = New_Token_Buffer();
01221           Append_Token_String(decl_tokens, 
01222                               TY2F_Fld_Name(fld_iter,
01223                                             TRUE/*common/equivalence*/, 
01224                                             alt_return/*alt_ret_name*/));
01225           TY2F_translate(decl_tokens, FLD_type(fld));
01226           Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01227         }
01228 
01229     } while (!FLD_last_field (fld_iter++)) ;
01230 //      Append_F77_Indented_Newline(tokens, 1, NULL/*label*/);
01231 } /* TY2F_Declare_Common_Flds */
01232 
01233 static void
01234 TY2F_List_Common_Flds(TOKEN_BUFFER tokens, FLD_HANDLE fldlist)
01235 {
01236   FLD_ITER fld_iter = Make_fld_iter(fldlist);
01237   
01238   bool needComma=false; // problem is we need to jump over fields flagged "equivalenced"
01239   do
01240     {
01241       FLD_HANDLE fld (fld_iter);
01242       TY & ty  = Ty_Table[FLD_type(fld)];       
01243 
01244       if (TY_split(ty))
01245         {
01246           /* Treat a full split element as a transparent data-structure */
01247 
01248           TY2F_List_Common_Flds(tokens, TY_flist(ty));
01249         }
01250       else if (!FLD_equivalence(fld))
01251       {
01252         Append_Token_String(tokens, 
01253                             TY2F_Fld_Name(fld_iter,
01254                                           TRUE/*common*/, 
01255                                           FALSE/*alt_ret_name*/));
01256         needComma=true;
01257       }
01258       
01259       if (!FLD_last_field(fld)) 
01260       {
01261         FLD_ITER  next_iter = fld_iter ;
01262         FLD_HANDLE next (++next_iter);
01263         if (!FLD_equivalence(next) && needComma) { 
01264           Append_Token_Special(tokens, ',');
01265           needComma=false;
01266         }
01267       }
01268 
01269     } while (!FLD_last_field (fld_iter++)) ;
01270 
01271 } /* TY2F_List_Common_Flds */
01272 
01273 /*------------- Hidden routines to declare variable types -------------*/
01274 /*---------------------------------------------------------------------*/
01275 
01276 static void
01277 TY2F_invalid(TOKEN_BUFFER decl_tokens, TY_IDX ty)
01278 {
01279    ASSERT_DBG_FATAL(FALSE, 
01280                     (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01281                      TY_kind(Ty_Table[ty]), 
01282                      "TY2F_invalid"));
01283    Prepend_Token_String(decl_tokens, "<TY2F_invalid>");
01284 } /* TY2F_invalid */
01285 
01286 static void
01287 TY2F_scalar(TOKEN_BUFFER decl_tokens, TY_IDX ty_idx)
01288 {
01289    const char *base_name;
01290    INT64 kind_type;
01291    const char * kind_spec;
01292    TY&   ty = Ty_Table[ty_idx];
01293    MTYPE mt = TY_mtype(ty);
01294 
01295    ASSERT_DBG_FATAL(TY_kind(ty) == KIND_SCALAR, 
01296                     (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01297                      TY_kind(ty), 
01298                      "TY2F_scalar"));
01299 
01300    // Special override for OpenAD types
01301    if (W2F_OpenAD) {
01302      const char* tyname = TY_name(ty);
01303      if (tyname && strncasecmp(tyname, W2F_activeType, strlen(W2F_activeType)) == 0) {
01304        const char* str = Concat3_Strings("TYPE (", tyname, ")");
01305        Prepend_Token_String(decl_tokens, str);
01306        return;
01307      }
01308    }
01309    
01310    // The general case
01311    kind_spec = "NULL";
01312    if (TY_is_character(ty))
01313    {
01314       base_name = "CHARACTER";
01315    }
01316    else if (TY_is_logical(ty))
01317    {
01318       base_name = "LOGICAL";
01319       switch(mt)
01320          {
01321            case MTYPE_I1:
01322             kind_spec = "(w2f__i1)";
01323              break;
01324 
01325            case MTYPE_I2:
01326             kind_spec = "(w2f__i2)";
01327              break;
01328 
01329            case MTYPE_I4:
01330             kind_spec = "(w2f__i4)";
01331              break;
01332 
01333            case MTYPE_I8:
01334             kind_spec = "(w2f__i8)";
01335              break;
01336       }
01337    }
01338    else {
01339      switch(mt) 
01340      {
01341        /* Strictly speaking unsigned integers not supported in Fortran,
01342         * but we are lenient and treat them as the signed equivalent.
01343         */
01344      case MTYPE_U1:
01345      case MTYPE_I1:
01346        base_name = "INTEGER";
01347        kind_spec = "(w2f__i1)"; 
01348        break;
01349        
01350      case MTYPE_U2:
01351      case MTYPE_I2:
01352        base_name = "INTEGER";
01353        kind_spec = "(w2f__i2)"; 
01354        break;
01355 
01356      case MTYPE_U4:
01357      case MTYPE_I4:
01358        base_name = "INTEGER";
01359        kind_spec = "(w2f__i4)"; 
01360        break;
01361 
01362      case MTYPE_U8:
01363      case MTYPE_I8:
01364        base_name = "INTEGER";
01365        kind_spec = "(w2f__i8)"; 
01366        break;
01367        
01368      case MTYPE_F4:
01369        kind_spec = "(w2f__4)"; 
01370        base_name = "REAL";
01371        break;
01372        
01373      case MTYPE_F8:
01374        kind_spec = "(w2f__8)";
01375        base_name = "REAL";
01376        break;
01377        
01378      case MTYPE_FQ:
01379        kind_spec = "(w2f__16)";
01380        base_name = "REAL";
01381        break;
01382        
01383      case MTYPE_C4:
01384        base_name = "COMPLEX";
01385        kind_spec = "(w2f__4)"; 
01386        break;
01387 
01388      case MTYPE_C8:
01389        base_name = "COMPLEX";
01390        kind_spec = "(w2f__8)";
01391        break;
01392 
01393      case MTYPE_CQ:
01394        base_name = "COMPLEX";
01395        kind_spec = "(w2f__16)";
01396        break;
01397        
01398      case MTYPE_M:
01399        base_name = "memory block";
01400        break;
01401        
01402      default:
01403        ASSERT_DBG_FATAL(FALSE,
01404                         (DIAG_W2F_UNEXPECTED_BTYPE, 
01405                          MTYPE_name(mt), 
01406                          "TY2F_scalar"));
01407      } /* switch(TY_btype(ty) */
01408    }
01409 
01410    if (TY_size(ty) > 0)
01411    {
01412       if (WN2F_F90_pu) {
01413          if (MTYPE_is_complex(mt)) {
01414             kind_type = TY_size(ty) / 2;
01415          } else {
01416             kind_type = TY_size(ty);
01417          }
01418 
01419          if (strcmp(kind_spec,"NULL") == 0) {
01420             kind_spec = 
01421               Concat3_Strings("(",Number_as_String(kind_type, "%lld"),")");
01422          }
01423          Prepend_Token_String(decl_tokens,
01424                               Concat2_Strings(base_name, kind_spec));
01425       } else {
01426          if (TY_is_character(ty)) {
01427             Prepend_Token_String(
01428                     decl_tokens,
01429                     Concat3_Strings(Concat2_Strings(base_name, "("),
01430                                     Number_as_String(TY_size(ty), "%lld"),
01431                                     ")"));
01432         }
01433         else {
01434            Prepend_Token_String(
01435                    decl_tokens, 
01436                    Concat3_Strings(base_name, "*", 
01437                                    Number_as_String(TY_size(ty), "%lld")));
01438         }
01439       }
01440    }
01441    else
01442    {
01443       if (mt == MTYPE_M) {
01444          Prepend_Token_String(decl_tokens, ".mblock.");
01445       }
01446       else
01447       {
01448          ASSERT_DBG_FATAL(TY_is_character(ty),
01449                           (DIAG_W2F_UNEXPECTED_TYPE_SIZE,
01450                            TY_size(ty),"TY2F_scalar"));
01451          Prepend_Token_String(decl_tokens, "CHARACTER*(*)");
01452       }
01453    }
01454 } /* TY2F_scalar */
01455 
01456 
01457 static void
01458 TY2F_array(TOKEN_BUFFER decl_tokens, TY_IDX ty_idx)
01459 {
01460   TY& ty = Ty_Table[ty_idx] ;
01461 
01462    ASSERT_DBG_FATAL(TY_kind(ty) == KIND_ARRAY,
01463                     (DIAG_W2F_UNEXPECTED_TYPE_KIND,
01464                      TY_kind(ty), "TY2F_array"));
01465 
01466    if (TY_is_character(ty))
01467    {
01468       /* A character string...
01469        */
01470       if (TY_size(ty) > 0) /* ... of known size */
01471          Prepend_Token_String(
01472             decl_tokens,
01473             Concat3_Strings("CHARACTER(",
01474                             Number_as_String(TY_size(ty), "%lld"),
01475                              ")"));
01476       else /* ... of unknown size */
01477          Prepend_Token_String(decl_tokens, "CHARACTER(*)");
01478    }
01479    else
01480    {
01481       /* A regular array, so prepend the element type and append
01482        * the index bounds.
01483        */
01484      ARB_HANDLE arb_base = TY_arb(ty);
01485      INT32       dim = ARB_dimension(arb_base) ;
01486      INT32       co_dim = ARB_co_dimension(arb_base);
01487      INT32       array_dim = dim-co_dim;
01488      INT32       revdim = 0;
01489 
01490       /* Do not permit pointers as elements of arrays, so just use
01491        * the corresponding integral type instead.  We do not expect
01492        * such pointers to be dereferenced anywhere.
01493        */
01494 
01495       if (TY_Is_Pointer(TY_AR_etype(ty)))
01496          TY2F_translate(decl_tokens,
01497                         Stab_Mtype_To_Ty(TY_mtype(TY_AR_etype(ty))));
01498       else  
01499          TY2F_translate(decl_tokens, TY_AR_etype(ty));
01500 
01501  if (ARB_co_dimension(arb_base)<=0){
01502      co_dim=0;
01503      array_dim = dim;
01504   }
01505 
01506 
01507     if (array_dim>0) {
01508       Append_Token_Special(decl_tokens, '(');
01509 
01510       while (array_dim > 0) 
01511       {
01512         ARB_HANDLE arb = arb_base[dim-1];
01513 
01514     if (TY_is_f90_deferred_shape(ty_idx)) 
01515          Append_Token_Special(decl_tokens, ':');
01516     else
01517     if (TY_is_f90_assumed_size(ty_idx) &&
01518              TY_AR_last_dimen(ty_idx,revdim))    
01519         TY2F_Append_ARB(decl_tokens, arb , TRUE);
01520     else
01521         TY2F_Append_ARB(decl_tokens, arb , FALSE);
01522 
01523 
01524     if (array_dim--> 1) 
01525       Append_Token_Special(decl_tokens, ',');
01526 
01527       --dim;
01528       ++revdim;
01529 
01530       } 
01531 
01532       Append_Token_Special(decl_tokens, ')');
01533  }
01534 
01535    dim = ARB_dimension(arb_base);
01536    array_dim = dim - co_dim;
01537    --dim;
01538 
01539    if (co_dim >0)
01540     {
01541       Append_Token_Special(decl_tokens, '[');
01542      while (co_dim >0 )
01543            {
01544         ARB_HANDLE arb = arb_base[dim-array_dim];
01545 
01546 //    if (TY_is_f90_assumed_size(ty_idx) &&
01547 //             TY_AR_last_dimen(ty_idx,revdim))
01548 //        TY2F_Append_ARB(decl_tokens, arb , TRUE);
01549 //    else
01550 //        TY2F_Append_ARB(decl_tokens, arb , FALSE);
01551 
01552     if (TY_is_f90_deferred_shape(ty))
01553        Append_Token_Special(decl_tokens,':');
01554     else
01555        if ( co_dim==1)
01556            TY2F_Append_ARB(decl_tokens, arb , TRUE);
01557        else
01558            TY2F_Append_ARB(decl_tokens, arb , FALSE);
01559 
01560 
01561       dim--;
01562 
01563     if (co_dim-- > 1)
01564       Append_Token_Special(decl_tokens, ',');
01565 
01566       ++revdim;
01567 
01568       }
01569 
01570       Append_Token_Special(decl_tokens, ']');
01571   }
01572 
01573    }
01574 } /* TY2F_array */
01575 
01576 
01577 static void
01578 TY2F_array_for_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty_idx)
01579 {
01580   TY& ty = Ty_Table[ty_idx] ;
01581 
01582    ASSERT_DBG_FATAL(TY_kind(ty) == KIND_ARRAY,
01583                     (DIAG_W2F_UNEXPECTED_TYPE_KIND,
01584                      TY_kind(ty), "TY2F_array"));
01585 
01586    if (TY_is_character(ty))
01587    {
01588       /* A character string...
01589        */
01590       if (TY_size(ty) > 0) /* ... of known size */
01591          Prepend_Token_String(
01592             decl_tokens,
01593             Concat2_Strings("CHARACTER*",
01594                             Number_as_String(TY_size(ty), "%lld")));
01595       else /* ... of unknown size */
01596          Prepend_Token_String(decl_tokens, "CHARACTER*(*)");
01597    }
01598    else
01599    {
01600       /* A regular array, so prepend the element type and append
01601        * the index bounds.
01602        */
01603      ARB_HANDLE arb_base = TY_arb(ty);
01604      INT32       dim = ARB_dimension(arb_base) ;
01605      INT32       co_dim = ARB_co_dimension(arb_base);
01606      INT32       array_dim = dim-co_dim;
01607      INT32       revdim = 0;
01608 
01609       /* Do not permit pointers as elements of arrays, so just use
01610        * the corresponding integral type instead.  We do not expect
01611        * such pointers to be dereferenced anywhere.
01612        */
01613       if (TY_Is_Pointer(TY_AR_etype(ty)))
01614          TY2F_translate(decl_tokens,
01615                         Stab_Mtype_To_Ty(TY_mtype(TY_AR_etype(ty))));
01616       else {
01617          TY2F_translate(decl_tokens, TY_AR_etype(ty));
01618        }
01619 
01620  if (ARB_co_dimension(arb_base)<=0){
01621      co_dim=0;
01622      array_dim = dim;
01623   }
01624 
01625     if (array_dim>0) {
01626       Append_Token_Special(decl_tokens, '(');
01627 
01628       while (array_dim > 0)
01629       {
01630         ARB_HANDLE arb = arb_base[dim-1];
01631 
01632          Append_Token_Special(decl_tokens, ':');
01633 
01634     if (array_dim--> 1)
01635       Append_Token_Special(decl_tokens, ',');
01636 
01637       --dim;
01638       ++revdim;
01639 
01640       }
01641 
01642       Append_Token_Special(decl_tokens, ')');
01643  }
01644 
01645    dim = ARB_dimension(arb_base);
01646    array_dim = dim - co_dim;
01647    --dim;
01648 
01649    if (co_dim >0)
01650     {
01651       Append_Token_Special(decl_tokens, '[');
01652      while (co_dim >0 )
01653            {
01654         ARB_HANDLE arb = arb_base[dim-array_dim];
01655 
01656 
01657        Append_Token_Special(decl_tokens,':');
01658 
01659       dim--;
01660 
01661     if (co_dim-- > 1)
01662       Append_Token_Special(decl_tokens, ',');
01663 
01664       ++revdim;
01665 
01666       }
01667 
01668       Append_Token_Special(decl_tokens, ']');
01669   }
01670 
01671    }
01672 } /* TY2F_array_for_pointer */
01673 
01674 
01675 
01676 
01677 static void
01678 TY2F_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty)
01679 {
01680   /* Structs are supported by VAX-Fortran and Fortran-90.  Note
01681    * that we here emit a RECORD declaration, while we expect
01682    * the STRUCTURE to have been declared through a call to
01683    * TY2F_Translate_Structure().
01684    */
01685   TY & ty_rt = Ty_Table[ty];
01686 
01687   ASSERT_DBG_FATAL(TY_kind(ty_rt) == KIND_STRUCT, 
01688                    (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01689                     TY_kind(ty_rt), "TY2F_struct"));
01690 
01691   if (!TY_is_translated_to_c(ty))
01692     {
01693       Set_TY_is_translated_to_c(ty); /* Really, translated to Fortran, not C */
01694       TY2F_Translate_Structure(ty);
01695     }
01696 
01697   if (!WN2F_F90_pu) {
01698     Prepend_Token_String(decl_tokens, 
01699                          Concat3_Strings("/", W2CF_Symtab_Nameof_Ty(ty), "/"));
01700     Prepend_Token_String(decl_tokens, "RECORD");
01701   } else {
01702     Prepend_Token_String(decl_tokens, 
01703                          Concat3_Strings("(", W2CF_Symtab_Nameof_Ty(ty), ")"));
01704     Prepend_Token_String(decl_tokens, "TYPE");
01705   }      
01706 } /* TY2F_struct */
01707 
01708 
01709 static void
01710 TY2F_2_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty)
01711 {
01712   /* Structs are supported by VAX-Fortran and Fortran-90.  Note
01713    * that we here emit a RECORD declaration, while we expect
01714    * the STRUCTURE to have been declared through a call to
01715    * TY2F_Translate_Structure().
01716    */
01717   TY & ty_rt = Ty_Table[ty];
01718 
01719   ASSERT_DBG_FATAL(TY_kind(ty_rt) == KIND_STRUCT, 
01720                    (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01721                     TY_kind(ty_rt), "TY2F_struct"));
01722 
01723   if (!TY_is_translated_to_c(ty))
01724     {
01725       Set_TY_is_translated_to_c(ty); /* Really, translated to Fortran, not C */
01726       TY2F_Translate_Structure(ty);
01727     }
01728 
01729 } /* TY2F_2_struct */
01730 
01731 
01732 static void
01733 TY2F_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty)
01734 {
01735    if (!WN2F_F90_pu) {
01736       /* Pointer types in Fortran can only occur in a Pointer specification
01737        * statement.  We do not expect this routine to be called, since we
01738        * expect pointer types to be handled by ST2F_decl_var().
01739        */
01740       ASSERT_DBG_WARN(FALSE, 
01741                       (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01742                        TY_kind(ty), "TY2F_pointer"));
01743       
01744       Append_Token_Special(decl_tokens, ')');
01745       Prepend_Token_Special(decl_tokens, '(');
01746       Prepend_Token_String(decl_tokens, "POINTER");
01747 
01748    } else {
01749 
01750       /* Is a dope vector base address? Put out an integer large enough */
01751       /* to hold an address for now. Don't really want POINTER because  */
01752       /* implies cray/f90 pointer instead of address slot               */
01753 
01754       if (TY2F_Pointer_To_Dope(ty))
01755       {
01756 #if 0
01757         Prepend_Token_String(decl_tokens,",POINTER ::");
01758 #endif
01759         TY2F_translate(decl_tokens,Be_Type_Tbl(Pointer_Mtype));
01760       } 
01761       else
01762       {
01763 
01764         /* avoid recursive type declarations */
01765 #if 0
01766         if (TY_kind(TY_pointed(ty)) == KIND_STRUCT)
01767         {
01768 /*
01769           Prepend_Token_String(decl_tokens,",POINTER ::");
01770           Prepend_Token_String(decl_tokens,W2CF_Symtab_Nameof_Ty(TY_pointed(ty)));
01771 */
01772          //this cause misunpared scalar pointer  
01773           TY2F_translate(decl_tokens,Be_Type_Tbl(Pointer_Mtype)); 
01774 
01775         } else 
01776 #endif
01777           TY2F_translate(decl_tokens,TY_pointed(ty)); 
01778 
01779       }
01780    }
01781 } /* TY2F_pointer */
01782 
01783 static void
01784 TY2F_void(TOKEN_BUFFER decl_tokens, TY_IDX ty_idx)
01785 {
01786   TY& ty = Ty_Table[ty_idx];
01787 
01788   ASSERT_DBG_FATAL(TY_kind(ty) == KIND_VOID, 
01789                     (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01790                      TY_kind(ty), 
01791                      "TY2F_void"));
01792 
01793    Prepend_F77_Indented_Newline(decl_tokens, 1, NULL/*label*/);
01794    Prepend_Token_String(decl_tokens, "! <Void Type>");
01795 } /* TY2F_void */
01796 
01797 /*------------------------ exported routines --------------------------*/
01798 /*---------------------------------------------------------------------*/
01799 
01800 void
01801 TY2F_translate(TOKEN_BUFFER tokens, TY_IDX ty,BOOL notyapp)
01802 {
01803    /* Dispatch the translation-task to the appropriate handler function.
01804     */
01805       if (!notyapp)
01806        TY2F_Handler[TY_kind(Ty_Table[ty])](tokens, ty);
01807       else
01808          TY2F_2_struct(tokens,ty);
01809 
01810 } /* TY2F_translate */
01811 
01812 void 
01813 TY2F_translate(TOKEN_BUFFER tokens,TY_IDX ty)
01814    {
01815       TY2F_translate(tokens,ty,0);
01816    }
01817 
01818 
01819 void 
01820 TY2F_Translate_Purple_Array(TOKEN_BUFFER tokens, ST *st, TY_IDX ty)
01821 {
01822    if (TY_Is_Pointer(ty) && TY_ptr_as_array(Ty_Table[ty]))
01823    {
01824       TY2F_Purple_Ptr_As_Array(tokens, st, TY_pointed(ty));
01825    }
01826    else if (Stab_Is_Assumed_Sized_Array(ty))
01827    {
01828       TY2F_Purple_Assumed_Sized_Array(tokens, st, ty);
01829    }
01830    else
01831    {
01832       /* Our regular translator inserts placeholders for adjstable bounds.
01833        */
01834       TY2F_translate(tokens, ty);
01835    }
01836 } /* TY2F_Translate_Purple_Array */
01837 
01838 
01839 
01840 static long
01841 GetLB(ARB_HANDLE arb)
01842 {
01843   long lbnd = 1;
01844   if (ARB_const_lbnd(arb)) {
01845     lbnd = ARB_lbnd_val(arb);
01846   }
01847   return lbnd;
01848 }
01849 
01850 
01851 void 
01852 TY2F_Translate_ArrayElt(TOKEN_BUFFER tokens, 
01853                         TY_IDX       arr_ty_idx,
01854                         STAB_OFFSET  arr_ofst)
01855 {
01856   TOKEN_BUFFER idx_tokens = New_Token_Buffer();
01857   INT32        dim;
01858   ARB_HANDLE   arb;
01859   
01860   ASSERT_FATAL(TY_Is_Array(arr_ty_idx), 
01861                (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01862                 TY_kind(arr_ty_idx), "TY2F_Translate_ArrayElt"));
01863   
01864   Append_Token_Special(tokens, '(');
01865   if (TY_Is_Character_String(arr_ty_idx))
01866     {
01867       /* Character strings can only be indexed using the substring notation
01868         */
01869       Append_Token_String(tokens, Number_as_String(arr_ofst+1, "%lld"));
01870       Append_Token_Special(tokens, ':');
01871       Append_Token_String(tokens, Number_as_String(arr_ofst+1, "%lld"));
01872     }
01873   else /* Regular array indexing */
01874     {
01875       /* Emit the indexing expressions for each dimension, taking note
01876        * that Fortran employs column-major array layout, meaning the 
01877        * leftmost indexing expression (dim==0) represents array elements
01878        * layed out in contiguous memory locations.
01879        */
01880 
01881       ARB_HANDLE arb_base = TY_arb(arr_ty_idx);
01882       dim = ARB_dimension(arb_base) - 1 ; 
01883 
01884       while ( dim >= 0)
01885       {
01886         ARB_HANDLE arb = arb_base[dim];
01887 
01888         if (arr_ofst == 0) {
01889           long lbnd = GetLB(arb);
01890           Prepend_Token_String(idx_tokens, Number_as_String(lbnd, "%ld"));
01891         }
01892         else if (ARB_const_stride(arb)) { /* Constant stride */
01893           long lbnd = GetLB(arb);
01894           long idx = arr_ofst/ARB_stride_val(arb) + lbnd;
01895           Prepend_Token_String(idx_tokens, Number_as_String(idx, "%ld"));
01896           arr_ofst -= (arr_ofst/ARB_stride_val(arb))*ARB_stride_val(arb);
01897         }
01898         else {
01899           Append_Token_String(idx_tokens, "*");
01900         }
01901         if (dim-- > 0)
01902           Prepend_Token_Special(idx_tokens, ',');
01903       }
01904       Append_And_Reclaim_Token_List(tokens, &idx_tokens);
01905     }
01906   Append_Token_Special(tokens, ')');
01907 } /* TY2F_Translate_ArrayElt */
01908 
01909 
01910 
01911 void
01912 TY2F_Translate_Common(TOKEN_BUFFER tokens, const char *name, TY_IDX ty_idx)
01913 {
01914   TY& ty = Ty_Table[ty_idx];
01915 
01916   BOOL  is_equiv = FALSE;
01917   
01918   ASSERT_DBG_FATAL(TY_kind(ty) == KIND_STRUCT, 
01919                    (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01920                     TY_kind(ty), "TY2F_Translate_Common"));
01921 
01922   /* Emit specification statements for every element of the
01923    * common block, including equivalences.
01924    */
01925   TOKEN_BUFFER decl_tokens = New_Token_Buffer();
01926 
01927 /* For named common block add "save" attribute---FMZ */
01928   if (name != NULL && *name != '\0'){
01929       Append_Token_String(decl_tokens,"SAVE");
01930       Append_Token_String(decl_tokens, Concat3_Strings("/", name, "/"));
01931       Append_F77_Indented_Newline(decl_tokens, 1, NULL/*label*/);
01932       Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01933    }
01934 
01935   decl_tokens = New_Token_Buffer();
01936   Append_Token_String(decl_tokens, "COMMON");
01937   if (name != NULL && *name != '\0')
01938     Append_Token_String(decl_tokens, Concat3_Strings("/", name, "/"));
01939   TY2F_List_Common_Flds(decl_tokens, TY_flist(ty));
01940   
01941 
01942   TY2F_Declare_Common_Flds(decl_tokens, // vars in common block type decl
01943                            TY_flist(ty),
01944                            FALSE, /*alt_return*/
01945                            &is_equiv);
01946   /* Emit the common block specification statement, excluding
01947    * equivalences, where the name is already in a valid form and 
01948    * can be emitted as is without a call to W2CF_Symtab_Nameof_Ty().
01949    */
01950 
01951 # if 0
01952 
01953   Append_Token_String(decl_tokens, "COMMON");
01954   if (name != NULL && *name != '\0')
01955     Append_Token_String(decl_tokens, Concat3_Strings("/", name, "/"));
01956   TY2F_List_Common_Flds(decl_tokens, TY_flist(ty));
01957 
01958 #endif
01959 
01960   /* Emit equivalences, if there are any */
01961 
01962   if (is_equiv)
01963     TY2F_Equivalence_List(decl_tokens, ty_idx /*struct_ty*/);
01964 
01965   Append_And_Reclaim_Token_List(tokens, &decl_tokens);
01966 
01967 } /* TY2F_Translate_Common */
01968 
01969 
01970 void
01971 TY2F_Translate_Equivalence(TOKEN_BUFFER tokens, TY_IDX ty_idx, BOOL alt_return)
01972 {
01973    /* When alt_return==TRUE, this represents an alternate return variable,
01974     * in which case we should declare the elements of the equivalence
01975     * with unmangled names and ignore the fact that they are in an
01976     * equivalence.  The first element in such an alternate return is
01977     * the function/subprogram return-variable, which we should never
01978     * declare.
01979     */
01980 
01981   TY& ty = Ty_Table[ty_idx];
01982 
01983   FLD_HANDLE first_fld;
01984   BOOL is_equiv;
01985    
01986    ASSERT_DBG_FATAL(TY_kind(ty) == KIND_STRUCT, 
01987                     (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
01988                      TY_kind(ty), "TY2F_Translate_Equivalence"));
01989 
01990    if (alt_return)
01991    {
01992       first_fld = FLD_next(TY_flist(ty)); /* skip func_entry return var */
01993    }
01994    else
01995    {
01996       first_fld = TY_flist(ty);
01997    }
01998 
01999 
02000 //    /* Emit specification statements for every element of the
02001 //     * equivalence block.
02002 //     */  
02003 //    TY2F_Declare_Common_Flds(tokens, 
02004 //                          first_fld,
02005 //                          alt_return,
02006 //                          &is_equiv);  /* Redundant in this call */
02007 
02008    if (!alt_return)
02009       TY2F_Equivalence_List(tokens, ty_idx /*struct_ty*/);
02010 
02011 } /* TY2F_Translate_Equivalence */
02012 
02013 void 
02014 TY2F_Prepend_Structures(TOKEN_BUFFER tokens)
02015 {
02016    if (TY2F_Structure_Decls != NULL)
02017       Prepend_And_Reclaim_Token_List(tokens, &TY2F_Structure_Decls);
02018 
02019 } /* TY2F_Prepend_Structures */
02020 
02021 
02022 FLD_PATH_INFO * 
02023 TY2F_Free_Fld_Path(FLD_PATH_INFO *fld_path)
02024 {
02025    FLD_PATH_INFO *free_list;
02026    
02027    if (fld_path != NULL)
02028    {
02029       free_list = Free_Fld_Path_Info;
02030       Free_Fld_Path_Info = fld_path;
02031       while (fld_path->next != NULL)
02032          fld_path = fld_path->next;
02033       fld_path->next = free_list;
02034    }
02035    return NULL;
02036 } /* TY2F_Free_Fld_Path */
02037 
02038 
02039 FLD_PATH_INFO * 
02040 TY2F_Get_Fld_Path(const TY_IDX struct_ty, 
02041                   const TY_IDX object_ty,
02042                   STAB_OFFSET offset)
02043 {
02044   FLD_PATH_INFO  *fld_path;
02045   FLD_PATH_INFO  *fld_path2 = NULL;
02046   TY & s_ty = Ty_Table[struct_ty] ;
02047   FLD_ITER fld_iter ;
02048   
02049   ASSERT_DBG_FATAL(TY_kind(s_ty) == KIND_STRUCT,
02050                    (DIAG_W2F_UNEXPECTED_TYPE_KIND, 
02051                     TY_kind(s_ty),
02052                     "TY2F_Get_Fld_Path"));
02053   
02054   /* Get the best matching field path into fld_path2 */
02055 
02056   fld_iter = Make_fld_iter(TY_flist(s_ty));
02057 
02058   do 
02059     {
02060       FLD_HANDLE fld (fld_iter);
02061 
02062       if (NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(fld_iter)) 
02063       {
02064         fld_path = Construct_Fld_Path(fld_iter,
02065                                       struct_ty,
02066                                       object_ty,
02067                                       offset,
02068                                       TY_size(s_ty));
02069         if (fld_path2 == NULL)
02070           fld_path2 = fld_path;
02071         else if (fld_path != NULL)
02072           fld_path2 = Select_Best_Fld_Path(fld_path2,
02073                                            fld_path,
02074                                            object_ty,
02075                                            offset);
02076       }
02077     } while (!FLD_last_field (fld_iter++)) ;
02078 
02079   /* POSTCONDITION: fld_path2 points to the best match found */
02080 
02081   return fld_path2;
02082 
02083 } /* TY2F_Get_Fld_Path */
02084 
02085 void
02086 TY2F_Translate_Fld_Path(TOKEN_BUFFER   tokens,
02087                         FLD_PATH_INFO *fld_path, 
02088                         BOOL           deref, 
02089                         BOOL           member_of_common, 
02090                         BOOL           alt_ret_name,
02091                         WN2F_CONTEXT   context)
02092 {
02093    /* Append the name of each field to the tokens, separated them
02094     * from each other by the field-selection operator ('.').  The
02095     * first name on the path may optionally be emitted in unclobbered 
02096     * form, as it may represent an alternate return point.
02097     */
02098    while (fld_path != NULL)
02099    {
02100       FLD_HANDLE f (fld_path->fld);
02101       if (deref && TY_Is_Pointer(FLD_type(f)))
02102          Append_Token_String(tokens, W2CF_Symtab_Nameof_Fld_Pointee(f));
02103       else
02104           Append_Token_String(tokens, 
02105                               TY2F_Fld_Name(f,
02106                                             member_of_common,
02107                                             alt_ret_name));
02108 
02109       member_of_common = FALSE; /* Can only be true first time around */
02110 
02111       /* if an array element, form the subscript list. If an OPC_ARRAY */
02112       /* provides the subscripts, use it o/w use offset                */
02113 
02114       if (fld_path->arr_elt) 
02115         {
02116           if (fld_path->arr_wn != NULL)
02117               WN2F_array_bounds(tokens,fld_path->arr_wn,FLD_type(f),context);     
02118           else 
02119               ;
02120 
02121 //   TY2F_Translate_ArrayElt(tokens,FLD_type(f),fld_path->arr_ofst);
02122 /* Looks like this stmt(above) is a bug.We don't need translate array_element here
02123  * since we already  get array information from an operator associated with this
02124  * processing
02125  */
02126         }
02127 
02128       /* Separate fields with the dot-notation. */
02129 
02130       fld_path = fld_path->next;
02131 
02132       if (fld_path != NULL)
02133       {
02134          TY2F_Fld_Separator(tokens) ;
02135          alt_ret_name = FALSE; /* Only applies to first field on the path */
02136       }
02137 
02138     } /* while */
02139 
02140 } /* TY2F_Translate_Fld_Path */
02141 
02142 
02143 
02144 extern void
02145 TY2F_Fld_Separator(TOKEN_BUFFER tokens)
02146 {
02147   /* puts out the appropriate structure component separator*/
02148 
02149   char p = '.' ;
02150 
02151   if (WN2F_F90_pu) 
02152        p =  '%';
02153 
02154   Append_Token_Special(tokens,p);
02155 }
02156 
02157 extern FLD_HANDLE
02158 TY2F_Last_Fld(FLD_PATH_INFO *fld_path)
02159 {
02160   FLD_HANDLE f = FLD_HANDLE () ;
02161 
02162   while (fld_path != NULL)
02163     {
02164       f = fld_path->fld;
02165       fld_path = fld_path->next ;
02166     }
02167 
02168   return f ;
02169 }
02170 
02171 extern FLD_PATH_INFO * 
02172 TY2F_Point_At_Path(FLD_PATH_INFO * path, STAB_OFFSET off)
02173 {
02174   /* given a fld path, return a pointer to */
02175   /* the slot at the given offset          */
02176 
02177 
02178   while (path != NULL )
02179   {
02180     if (FLD_ofst(path->fld) >= off)
02181       break ;
02182 
02183     path=path->next;
02184   }
02185   return path;
02186 }
02187 
02188 extern void
02189 TY2F_Dump_Fld_Path(FLD_PATH_INFO *fld_path)
02190 {
02191   printf ("path ::");
02192   while (fld_path != NULL)
02193     {
02194       FLD_HANDLE f = fld_path->fld;
02195 
02196       printf ("%s(#%d)",TY2F_Fld_Name(f,FALSE,FALSE),f.Idx ());
02197 
02198       if (fld_path->arr_elt)
02199         printf (" array");
02200 
02201       if (fld_path->arr_ofst)
02202         printf (" offset 0x%x",(mINT32) fld_path->arr_ofst);
02203 
02204       if (fld_path->arr_wn != NULL)
02205         printf (" tree 0x%p",fld_path->arr_wn);
02206 
02207       printf (" ::");
02208       fld_path = fld_path->next ;
02209     }
02210   printf ("\n");
02211 }
02212 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines