ty2xaif.cxx

Go to the documentation of this file.
00001 // -*-Mode: C++;-*-
00002 // $Header: /Volumes/cvsrep/developer/OpenADFortTk/src/whirl2xaif/ty2xaif.cxx,v 1.27 2006/05/12 16:12:23 utke Exp $
00003 
00004 // * BeginCopyright *********************************************************
00005 /*
00006   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00007 
00008   This program is free software; you can redistribute it and/or modify it
00009   under the terms of version 2 of the GNU General Public License as
00010   published by the Free Software Foundation.
00011 
00012   This program is distributed in the hope that it would be useful, but
00013   WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00015 
00016   Further, this software is distributed without any warranty that it is
00017   free of the rightful claim of any third person regarding infringement 
00018   or the like.  Any license provided herein, whether implied or 
00019   otherwise, applies only to this software file.  Patent licenses, if 
00020   any, provided herein do not apply to combinations of this program with 
00021   other software, or any other product whatsoever.  
00022 
00023   You should have received a copy of the GNU General Public License along
00024   with this program; if not, write the Free Software Foundation, Inc., 59
00025   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00026 
00027   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00028   Mountain View, CA 94043, or:
00029 
00030   http://www.sgi.com
00031 
00032   For further information regarding this notice, see:
00033 
00034   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00035 */
00036 // *********************************************************** EndCopyright *
00037 
00038 
00039 #include <sstream> //FIXME
00040 
00041 
00042 #include "Open64IRInterface/Open64BasicTypes.h"
00043 
00044 
00045 #include "wn2xaif.h"
00046 #include "wn2xaif_mem.h"
00047 #include "st2xaif.h"
00048 #include "ty2xaif.h"
00049 
00050 // ************************** Forward Declarations ***************************
00051 
00052 namespace whirl2xaif { 
00053 
00054   // ************************** Forward Declarations ***************************
00055 
00056   extern WN* PU_Body;
00057   extern BOOL Array_Bnd_Temp_Var;
00058 
00059   /* TY2F_Handler[] maps a TY_kind to a function that translates
00060    * a type of the given kind into Fortran.  Should the ordinal
00061    * numbering of the KIND change in "../common/com/stab.h", then
00062    * a corresponding change must be made here.
00063    */
00064 
00065   typedef void (*TY2F_HANDLER_FUNC)(xml::ostream&, TY_IDX, PUXlationContext& ctxt);
00066 
00067   static void 
00068   TY2F_invalid(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00069   static void 
00070   TY2F_scalar(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00071   static void 
00072   TY2F_array(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00073   static void 
00074   TY2F_array_for_pointer(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00075   static void 
00076   TY2F_struct(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00077   static void 
00078   TY2F_2_struct(xml::ostream& xos,TY_IDX ty, PUXlationContext& ctxt);
00079   static void 
00080   TY2F_pointer(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00081   static void 
00082   TY2F_void(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt);
00083 
00084   // ***************************************************************************
00085 
00086   static const TY2F_HANDLER_FUNC TY2F_Handler[KIND_LAST/*TY_KIND*/] = {
00087     &TY2F_invalid,   /* KIND_INVALID */
00088     &TY2F_scalar,    /* KIND_SCALAR */
00089     &TY2F_array,     /* KIND_ARRAY */
00090     &TY2F_struct,    /* KIND_STRUCT */
00091     &TY2F_pointer,   /* KIND_POINTER */
00092     &TY2F_invalid,   /* KIND_FUNCTION */
00093     &TY2F_void,      /* KIND_VOID */
00094   }; /* TY2F_Handler */
00095 
00096   /* detect parts of f90 dope vectors which should be output. Most are
00097      I4 boundaries except the bofst >16 - just for num_dims */
00098 #define NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(f)                         \
00099   (!FLD_is_bit_field(f) || (FLD_is_bit_field(f) && (FLD_bofst(f) == 0) || FLD_bofst(f) > 16))
00100 
00101   // ***************************************************************************
00102 
00103   void
00104   TY2F_translate(xml::ostream& xos, TY_IDX ty, BOOL notyapp, PUXlationContext& ctxt)
00105   {
00106     // Dispatch the translation-task to the appropriate handler function.
00107     if (!notyapp)
00108       TY2F_Handler[TY_kind(Ty_Table[ty])](xos, ty, ctxt);
00109     else
00110       TY2F_2_struct(xos, ty, ctxt);
00111   }
00112 
00113   void 
00114   TY2F_translate(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt)
00115   {
00116     TY2F_translate(xos, ty, 0, ctxt);
00117   }
00118 
00119 
00120   /*---------------------- A few utility routines -----------------------*/
00121   /*---------------------------------------------------------------------*/
00122 
00123   // static void
00124   // WN2F_tempvar_rhs(xml::ostream& xos, WN * wn)
00125   // {
00126   //   /* The rhs */
00127   //   PUXlationContext ctxt;
00128   //   whirl2xaif::TranslateWN(xos, WN_kid0(wn), ctxt);
00129   // }
00130 
00131   // static void
00132   // GetTmpVarTransInfo(xml::ostream& xos, ST_IDX arbnd, WN* wn)
00133   // {
00134   //   WN * stmt;
00135   //   stmt = WN_first(wn);
00136   //   while ((stmt !=NULL)
00137   //     && ((WN_operator(stmt)!=OPR_STID) || (WN_operator(stmt) ==OPR_STID)
00138   //         && strcmp(ST_name(WN_st(stmt)), ST_name(ST_ptr(arbnd)))))
00139   //     stmt = WN_next(stmt);
00140   //   if (stmt != NULL)
00141   //     WN2F_tempvar_rhs(xos, stmt);
00142   // }
00143 
00144   static std::string
00145   TY2F_Append_Array_Bnd_Ph(ST_IDX arbnd)
00146   {
00147     // FIXME: 
00148     std::ostringstream xos_abdstr;
00149     xml::ostream xos_abd(xos_abdstr.rdbuf());
00150 
00151 #if 0 // FIXME
00152     WN* wn = PU_Body; // FIXME--Yuck!!!
00153     GetTmpVarTransInfo(xos_abd, arbnd, wn);
00154 #endif
00155   
00156     return xos_abdstr.str();
00157   } 
00158 
00159   static void
00160   TY2F_Append_ARB(xml::ostream& xos, ARB_HANDLE arb, TY_IDX ty_idx, 
00161                   PUXlationContext& ctxt)
00162   {  
00163     if (TY_is_f90_deferred_shape(ty_idx)) {
00164 
00165       xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00166           << xml::Attr("name", "shape") << xml::Attr("value", ':') << xml::EndElem;
00167     
00168     } else {
00169 
00170       std::string lb, ub;
00171       if (ARB_const_lbnd(arb)) {
00172         lb = TCON2F_translate(Host_To_Targ(MTYPE_I4, ARB_lbnd_val(arb)), 
00173                               FALSE /*is_logical*/);
00174       } else if (ARB_lbnd_var(arb) != 0) {
00175         lb = TY2F_Append_Array_Bnd_Ph(ARB_lbnd_var(arb));
00176       }
00177     
00178       if (ARB_const_ubnd(arb)) {
00179         ub = TCON2F_translate(Host_To_Targ(MTYPE_I4, ARB_ubnd_val(arb)),
00180                               FALSE /*is_logical*/); 
00181       } else if (ARB_ubnd_var(arb) != 0) {
00182         ub = TY2F_Append_Array_Bnd_Ph(ARB_ubnd_var(arb));
00183       }
00184 
00185       xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00186           << xml::Attr("name", "lb") << xml::Attr("value", lb) << xml::EndElem;
00187       xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00188           << xml::Attr("name", "ub") << xml::Attr("value", ub) << xml::EndElem;
00189 
00190     }
00191   } 
00192 
00193   static BOOL
00194   TY2F_is_character(TY_IDX ty)
00195   {
00196     while (TY_kind(ty) == KIND_ARRAY)
00197       ty = TY_etype(ty);
00198 
00199     return TY_is_character(ty);
00200   }
00201   /*------ Utilities for accessing and declaring KIND_STRUCT FLDs ------
00202    *---------------------------------------------------------------------*/
00203 
00204 #define FLD_INFO_ALLOC_CHUNK 16
00205   static FLD_PATH_INFO *Free_Fld_Path_Info = NULL;
00206 
00207 
00208   static BOOL
00209   TY2F_Pointer_To_Dope(TY_IDX ty)
00210   {
00211     /* Is this a pointer to a dope vector base */
00212     return (strcmp(TY_name(TY_pointed(ty)),".base.") == 0) ;
00213   }
00214 
00215   static FLD_PATH_INFO *
00216   New_Fld_Path_Info(FLD_HANDLE fld)
00217   {
00218     /* Allocates a new FLD_PATH_INFO, reusing any that have earlier
00219      * been freed up.  Dynamic allocation occurs in chunks of 16
00220      * (FLD_INFO_ALLOC_CHUNK) FLD_PATH_INFOs at a time.
00221      */
00222     FLD_PATH_INFO *fld_info;
00223    
00224     if (Free_Fld_Path_Info != NULL)
00225       {
00226         fld_info = Free_Fld_Path_Info;
00227         Free_Fld_Path_Info = fld_info->next;
00228       }
00229     else
00230       {
00231         INT info_idx;
00232       
00233         /* Allocate a new chunk of path infos, and put all except the
00234          * first one on the free-list.
00235          */
00236         fld_info = TYPE_MEM_POOL_ALLOC_N(FLD_PATH_INFO, Malloc_Mem_Pool, 
00237                                          FLD_INFO_ALLOC_CHUNK);
00238         fld_info[FLD_INFO_ALLOC_CHUNK-1].next = Free_Fld_Path_Info;
00239         for (info_idx = FLD_INFO_ALLOC_CHUNK-2; info_idx > 0; info_idx--)
00240           fld_info[info_idx].next = &fld_info[info_idx+1];
00241         Free_Fld_Path_Info = &fld_info[1];
00242       }
00243 
00244     fld_info->next = NULL;
00245     fld_info->arr_elt = FALSE;
00246     fld_info->arr_ofst = 0;
00247     fld_info->arr_wn = NULL;
00248     fld_info->fld = fld;
00249     return fld_info;
00250   } /* New_Fld_Path_Info */
00251 
00252   static STAB_OFFSET
00253   TY2F_Fld_Size(FLD_HANDLE this_fld, mUINT64  max_size)
00254   {
00255     /* Returns the size of the field, taking into account the offset
00256      * to the next (non-equivalence) field and the maximum field-size
00257      * (based on the structure size).
00258      */
00259   
00260     mUINT64 fld_size = TY_size(FLD_type(this_fld));
00261 
00262     /* Restrict the fld_size to the max_size */
00263     if (fld_size > max_size)
00264       fld_size = max_size;
00265   
00266     /* If this_fld is an equivalence field, then just return the current
00267      * fld_size (cannot be any different), otherwise search for a non-
00268      * equivalent next_fld at a higher offset.
00269      * TODO: mfef90 & mfef77 set the flag slightly differently in COMMON.
00270      * this really works only for mfef77.
00271      */
00272 
00273     if (!FLD_equivalence(this_fld))
00274       {
00275         FLD_ITER fld_iter = Make_fld_iter(this_fld);
00276 
00277         if (!FLD_last_field (fld_iter)) 
00278           {
00279             ++fld_iter;
00280             BOOL found = FALSE;
00281             mUINT64 noffset = 0; 
00282 
00283             do
00284               {
00285                 FLD_HANDLE next_fld (fld_iter);
00286 
00287                 if (!FLD_is_bit_field(next_fld)) 
00288                   if (!(FLD_equivalence(next_fld) || FLD_ofst(this_fld) >= FLD_ofst(next_fld)))
00289                     {
00290                       found  = TRUE;
00291                       noffset =  FLD_ofst(next_fld) ;
00292                       break ;
00293                     }
00294               } while (!FLD_last_field (fld_iter ++ )) ;
00295 
00296             if (found) 
00297               if (fld_size > noffset - FLD_ofst(this_fld))
00298                 fld_size = noffset - FLD_ofst(this_fld) ;
00299           }
00300       }
00301     return fld_size;
00302   } /* TY2F_Fld_Size */
00303 
00304 
00305   static FLD_PATH_INFO *
00306   Select_Best_Fld_Path(FLD_PATH_INFO *path1,
00307                        FLD_PATH_INFO *path2,
00308                        TY_IDX         desired_ty,
00309                        mUINT64        desired_offset)
00310   {
00311     /* PRECONDITION: Both paths must be non-NULL and lead to a field
00312      *    at the desired_offset.
00313      *
00314      * Try to find the best of two paths to a field.  This routine
00315      * will be called for EVERY field at every place where a struct,
00316      * union, or equivalence field is accessed, so efficiency is of
00317      * uttmost importance.  The best path is returned, while the other
00318      * on is freed up.
00319      */
00320     FORTTK_ASSERT(path1 && path2, fortTkSupport::Diagnostics::UnexpectedInput);
00321    
00322     FLD_PATH_INFO *best_path;
00323     mUINT64        offs1, offs2;
00324     FLD_PATH_INFO *p1, *p2;
00325     TY_IDX         t1,  t2;
00326    
00327     /* Find the last field on each path */
00328     offs1 = FLD_ofst(path1->fld) + path1->arr_ofst;
00329     for (p1 = path1; p1->next != NULL; p1 = p1->next)
00330       offs1 += FLD_ofst(p1->next->fld) + p1->next->arr_ofst;
00331     offs2 = FLD_ofst(path2->fld) + path2->arr_ofst;
00332     for (p2 = path2; p2->next != NULL; p2 = p2->next)
00333       offs2 += FLD_ofst(p2->next->fld) + p2->next->arr_ofst;
00334 
00335     FORTTK_ASSERT(offs1 == desired_offset && offs2 == desired_offset,
00336                   "Unexpected offset");
00337 
00338     /* Get the element type (either the field type or the type of an
00339      * array element.
00340      */
00341     if (p1->arr_elt)
00342       t1 = TY_AR_etype(FLD_type(p1->fld));
00343     else
00344       t1 = FLD_type(p1->fld);
00345     if (p2->arr_elt)
00346       t2 = TY_AR_etype(FLD_type(p2->fld));
00347     else
00348       t2 = FLD_type(p2->fld);
00349 
00350     /* Compare types, in order of increasing accuracy */
00351     if (TY_mtype(t1) == TY_mtype(desired_ty) &&
00352         TY_mtype(t2) != TY_mtype(desired_ty))
00353       best_path = path1;
00354     else if (TY_mtype(t2) == TY_mtype(desired_ty) &&
00355              TY_mtype(t1) != TY_mtype(desired_ty))
00356       best_path = path2;
00357     else if (Stab_Identical_Types(t1, desired_ty,
00358                                   FALSE,  /* check_quals */
00359                                   TRUE,   /* check_scalars */
00360                                   FALSE)) /* ptrs_as_scalars */
00361       best_path = path1; /* path2 cannot possibly be any better */
00362     else if (Stab_Identical_Types(t2, desired_ty,
00363                                   FALSE,  /* check_quals */
00364                                   TRUE,   /* check_scalars */
00365                                   FALSE)) /* ptrs_as_scalars */
00366       best_path = path2;
00367     else
00368       best_path = path1;
00369 
00370     /* Free up the path not chosen */
00371     if (best_path == path1)
00372       TY2F_Free_Fld_Path(path2);
00373     else
00374       TY2F_Free_Fld_Path(path1);
00375 
00376     return best_path;
00377   } /* Select_Best_Fld_Path */
00378 
00379 
00380   static FLD_PATH_INFO *
00381   Construct_Fld_Path(FLD_HANDLE   fld,
00382                      TY_IDX    struct_ty,
00383                      TY_IDX    desired_ty,
00384                      mUINT64   desired_offset,
00385                      mUINT64   max_fld_size)
00386   {
00387     /* Returns the field path through "fld" found to best match the 
00388      * given offset and type.  As a minimum requirement, the offset 
00389      * must be as desired and the type must have the desired size
00390      * and alignment (with some concessions allowed for substrings).
00391      * The path is terminate with a NULL next pointer.  When no 
00392      * field matches the desired type and offset, NULL is returned.
00393      */
00394     FLD_PATH_INFO    *fld_path;
00395     const mUINT64     fld_offset = FLD_ofst(fld);
00396     TY_IDX            fld_ty = FLD_type(fld);
00397     BOOL              is_array_elt = FALSE;
00398     STAB_OFFSET       ofst_in_fld = 0;
00399   
00400     if (TY_is_f90_pointer(fld_ty))
00401       fld_ty = TY_pointed(fld_ty);
00402   
00403   
00404     /* This field cannot be on the path to a field with the given
00405      * attributes, unless the desired_offset is somewhere within
00406      * the field.
00407      */
00408 #if DBGPATH
00409     printf (" Construct: fld %s, struct %s, desired %s , des off %d \n",
00410             FLD_name(fld), TY_name(struct_ty), TY_name(desired_ty),
00411             desired_offset);
00412 #endif
00413 
00414     if (desired_offset < fld_offset ||
00415         desired_offset >= (fld_offset + TY_size(fld_ty))) {
00416       /* This field cannot be on the path to a field with the given
00417        * attributes, since the desired_offset is nowhere within
00418        * the field.
00419        */
00420       fld_path = NULL;
00421 #if DBGPATH
00422       printf ("     found NULL\n");
00423 #endif
00424     } else if (TY_Is_Array(fld_ty) && TY_is_character(fld_ty) &&
00425                TY_Is_Array(desired_ty) && TY_is_character(desired_ty)) {
00426 #if DBGPATH
00427       printf ("     found char substring\n");
00428 #endif
00429       /* A match is found! */
00430       ofst_in_fld = (desired_offset - fld_offset)/TY_size(TY_AR_etype(fld_ty));
00431       ofst_in_fld *= TY_size(TY_AR_etype(fld_ty));
00432       if ((ofst_in_fld + TY_size(desired_ty)) > TY_size(fld_ty)) {
00433         fld_path = NULL; /* The string does not fit */
00434       } else {
00435         fld_path = New_Fld_Path_Info(fld);
00436         if (TY_size(fld_ty) != TY_size(desired_ty)) {
00437           fld_path->arr_elt = TRUE;
00438           fld_path->arr_ofst = ofst_in_fld;
00439         } 
00440       }
00441     } else {
00442       /* See if the field we are looking for may be an array element */
00443     
00444       if (TY_kind(desired_ty)==KIND_POINTER)   
00445         desired_ty = TY_pointed(desired_ty);
00446       if (TY_kind(desired_ty)==KIND_ARRAY)
00447         desired_ty = TY_AR_etype(desired_ty);
00448 
00449       is_array_elt = (TY_Is_Array(fld_ty) &&
00450                       (TY_Is_Structured(TY_AR_etype(fld_ty))||
00451                        TY2F_is_character(fld_ty) ||
00452                        Stab_Identical_Types(TY_AR_etype(fld_ty), desired_ty,
00453                                             FALSE,   /* check_quals */
00454                                             FALSE,   /* check_scalars */
00455                                             TRUE))); /* ptrs_as_scalars */
00456 #if DBGPATH
00457       printf ("     is_array = %d, fld_ty %s \n",is_array_elt,TY_name(fld_ty));
00458 #endif
00459 
00460       if (is_array_elt) {
00461         fld_ty = TY_AR_etype(fld_ty);
00462         ofst_in_fld =
00463           ((desired_offset - fld_offset)/TY_size(fld_ty)) * TY_size(fld_ty);
00464       }
00465     
00466       if (TY_Is_Structured(fld_ty) &&
00467           !Stab_Identical_Types(fld_ty, desired_ty,
00468                                 FALSE,  /* check_quals */
00469                                 FALSE,  /* check_scalars */
00470                                 TRUE)) {  /* ptrs_as_scalars */
00471 #if DBGPATH
00472         printf ("     recurse \n");
00473 #endif
00474         FLD_PATH_INFO *fld_path2 = 
00475           TY2F_Get_Fld_Path(fld_ty, desired_ty, 
00476                             desired_offset - (fld_offset+ofst_in_fld));
00477       
00478         /* If a matching path was found, attach "fld" to the path */
00479         if (fld_path2 != NULL) {
00480           if (TY_split(Ty_Table[fld_ty]))
00481             fld_path = fld_path2; /* A stransparent substructure */
00482           else {
00483             fld_path = New_Fld_Path_Info(fld);
00484             fld_path->arr_elt = is_array_elt;
00485             fld_path->arr_ofst = ofst_in_fld;
00486             fld_path->next = fld_path2;
00487           }
00488         } else {
00489           fld_path = NULL;
00490         }
00491       } else { /* This may be a field we want to take into account */
00492         const STAB_OFFSET fld_size = TY2F_Fld_Size(fld, max_fld_size);
00493 
00494         /* We only match a field with the expected size, offset
00495          * and alignment.
00496          */
00497         if (desired_offset != fld_offset+ofst_in_fld || /* unexpected ofst */
00498             // fld_size < (TY_size(fld_ty)+ofst_in_fld) || /* unexpected size */
00499             TY_align(struct_ty) < TY_align(fld_ty)) {   /* unexpected align */
00500 #if DBGPATH
00501           printf ("     account - miss\n");
00502 #endif
00503         
00504           fld_path = NULL;
00505         } else { /* A match is found! */
00506 #if DBGPATH
00507           printf ("     account - match\n");
00508 #endif
00509           fld_path = New_Fld_Path_Info(fld);
00510           fld_path->arr_elt = is_array_elt;
00511           fld_path->arr_ofst = ofst_in_fld;
00512         }/*if*/
00513       } /*if*/
00514     } /*if*/
00515   
00516     return fld_path;
00517   } /* Construct_Fld_Path */
00518 
00519 
00520   static const char * 
00521   TY2F_Fld_Name(FLD_HANDLE fld, 
00522                 BOOL       common_or_equivalence,
00523                 BOOL       alt_return_name)
00524   {
00525     /* Since fields may be accessed in an unqualified manner in Fortran,
00526      * e.g. for common block members and equivalences, so we need to treat
00527      * them similar to the way we would treat regular objects.
00528      */
00529     const char *fld_name = NULL;
00530 
00531     if (common_or_equivalence && !alt_return_name) {
00532       fld_name = FLD_name(fld);
00533     } else {
00534       fld_name = FLD_name(fld);
00535     }
00536     if (fld_name == NULL || *fld_name == '\0') { fld_name = "anon-fld"; }
00537 
00538     return fld_name;
00539   } /* TY2F_Fld_Name */
00540 
00541 
00542   /*------ Utilities for accessing and declaring KIND_STRUCTs ------
00543    *----------------------------------------------------------------*/
00544 
00545   static void
00546   TY2F_Equivalence(xml::ostream& xos, 
00547                    const char  *equiv_name, 
00548                    const char  *fld_name,
00549                    STAB_OFFSET  fld_ofst)
00550   {
00551     /* Append one equivalence statement to the tokens buffer,
00552      * keeping in mind that the equiv_name is based at index 1. */
00553     xos << "EQUIVALENCE(" << equiv_name; /* equiv_name at given offset */
00554     xos << "(" << Num2Str(fld_ofst, "%lld") << "),";
00555     xos << fld_name << ")";  /* fld_name at offset zero */
00556   } /* TY2F_Equivalence */
00557 
00558 
00559   static void
00560   TY2F_Equivalence_FldList(xml::ostream& xos, 
00561                            FLD_HANDLE   fldlist,
00562                            UINT         equiv_var_idx,
00563                            mUINT64      ofst,
00564                            BOOL        *common_block_equivalenced)
00565   {
00566     FLD_ITER fld_iter = Make_fld_iter(fldlist);
00567 
00568     do {
00569       FLD_HANDLE fld (fld_iter);
00570 
00571       if (TY_split(Ty_Table[FLD_type(fld)]))
00572         {
00573           TY2F_Equivalence_FldList(xos, 
00574                                    TY_flist(Ty_Table[FLD_type(fld)]),
00575                                    equiv_var_idx,
00576                                    ofst + FLD_ofst(fld),
00577                                    common_block_equivalenced);
00578         }
00579       else if (FLD_equivalence(fld) || !*common_block_equivalenced)
00580         {
00581           xos << std::endl;
00582           const char* tmpvar = StrCat("tmp", Num2Str(equiv_var_idx, "%d"));
00583           TY2F_Equivalence(xos, tmpvar, TY2F_Fld_Name(fld_iter, TRUE/*equiv*/,
00584                                                       FALSE/*alt_ret*/),
00585                            ofst + FLD_ofst(fld));
00586           if (!FLD_equivalence(fld))
00587             *common_block_equivalenced = TRUE;
00588         }
00589 
00590     }
00591     while (!FLD_last_field (fld_iter++)) ;
00592 
00593   } /* TY2F_Equivalence_FldList */
00594 
00595 
00596   static void
00597   TY2F_Equivalence_List(xml::ostream& xos, 
00598                         const TY_IDX struct_ty)
00599   {
00600     /* Append a nameless EQUIVALENCE specification statement for
00601      * each equivalence field in the given struct.  Declare a 
00602      * dummy symbol as an array of INTEGER*1 elements to represent
00603      * the structure and each EQUIVALENCE specification will then 
00604      * equivalence a field to this dummy-symbol at the field offset.
00605      *
00606      * Group these declarations together by prepending each 
00607      * declaration (including the first one) with a newline.
00608      *
00609      * For COMMON blocks, it is also necessary to emit one element
00610      * that is not an equivalence!
00611      */
00612     TY_IDX     equiv_ty;
00613     UINT       equiv_var_idx;
00614     BOOL       common_block_equivalenced = FALSE;
00615 
00616     /* Declare an INTEGER*1 array (or CHARACTER string?) variable
00617      * to represent the whole equivalenced structure. Don't unlock
00618      * the tmpvar, or a similar equivalence group (ie: TY) will 
00619      * get the same temp.
00620      */
00621     equiv_ty = Stab_Array_Of(Stab_Mtype_To_Ty(MTYPE_I1), TY_size(struct_ty));
00622     equiv_var_idx = Stab_Lock_Tmpvar(equiv_ty, &ST2F_Declare_Tempvar);
00623 
00624     /* Relate every equivalence field to the temporary variable.
00625      */
00626     TY2F_Equivalence_FldList(xos, 
00627                              TY_flist(Ty_Table[struct_ty]),
00628                              equiv_var_idx,
00629                              0, /* Initial offset */
00630                              &common_block_equivalenced);
00631 
00632   } /* TY2F_Equivalence_List */
00633 
00634   // static void
00635   // TY2F_Translate_Structure(xml::ostream& xos, TY_IDX ty)
00636   // {
00637   //   FORTTK_ASSERT(TY_kind(ty) == KIND_STRUCT, "Unexpected type " << TY_kind(ty));
00638 
00639   //   FLD_ITER     fld_iter;
00640   //   TY& ty_rt  = Ty_Table[ty];
00641 
00642   //   PUXlationContext ctxt;// FIXME
00643 
00644   //   xos << std::endl;
00645   
00646   //   /* Emit structure header */
00647   //   xos << "TYPE " << TY_name(ty);
00648   
00649   //   if (TY_is_sequence(ty_rt)) {
00650   //     xos << std::endl << "SEQUENCE ";
00651   //   }
00652   
00653   //   /* Emit structure body */
00654   //   FLD_IDX flist = ty_rt.Fld();
00655   
00656   //   if (flist != 0) {
00657   //     fld_iter = Make_fld_iter(TY_flist(ty_rt));
00658   //     do {
00659   //       FLD_HANDLE fld (fld_iter);
00660       
00661   //       /* if it's a bitfield, then assume it's part of a dope vector & */
00662   //       /* just put out the name of the first bitfield in this I4       */
00663   //       if (NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(fld_iter)) {
00664   //    /* See if this field starts a map or a union */
00665         
00666   //    xos << std::endl;
00667   //    if (FLD_begin_union(fld)) {
00668   //      xos << "  UNION" << std::endl;
00669   //    } else if (FLD_begin_map(fld)) {
00670   //      xos << "  MAP" << std::endl;
00671   //    }
00672         
00673   //    /* Declare this field */
00674   //    if (FLD_is_pointer(fld)) {
00675   //      xos << ",POINTER::";
00676   //    }
00677 
00678   //    xos << TY2F_Fld_Name(fld_iter, FALSE/*common*/, FALSE/*alt_ret_name*/);
00679         
00680   //    if (FLD_is_pointer(fld) && (TY_kind(FLD_type(fld)) == KIND_ARRAY)) {
00681   //      TY2F_array_for_pointer(xos, FLD_type(fld), ctxt);
00682   //    } else {
00683   //      TY2F_translate(xos, FLD_type(fld), ctxt);
00684   //    }
00685         
00686   //    /* See if this field terminates a map or union */
00687   //    if (FLD_end_union(fld)) {
00688   //      xos << std::endl << "END UNION";
00689   //    } else if (FLD_end_map(fld)) {
00690   //      xos << std::endl << "END MAP";
00691   //    }
00692   //       }       
00693   //     } while (!FLD_last_field (fld_iter++)) ;
00694   //   }
00695   
00696   //   /* Emit structure tail */
00697   //   xos << std::endl;
00698   //   xos << "END TYPE" << std::endl;
00699   // }
00700 
00701 
00702   static void
00703   TY2F_Translate_EquivCommon_PtrFld(xml::ostream& xos, FLD_HANDLE fld)
00704   {
00705     assert(0);
00706   }
00707 
00708   static void
00709   TY2F_Declare_Common_Flds(xml::ostream& xos,
00710                            FLD_HANDLE   fldlist, 
00711                            BOOL         alt_return, /* Alternate return points */
00712                            BOOL        *is_equiv)   /* out */
00713   {
00714     assert(0);
00715   } 
00716 
00717   static void
00718   TY2F_List_Common_Flds(xml::ostream& xos, FLD_HANDLE fldlist)
00719   {
00720     FLD_ITER fld_iter = Make_fld_iter(fldlist);
00721 
00722     do {
00723       FLD_HANDLE fld (fld_iter);
00724       TY & ty  = Ty_Table[FLD_type(fld)];       
00725     
00726       if (TY_split(ty)) {
00727         /* Treat a full split element as a transparent data-structure */
00728         TY2F_List_Common_Flds(xos, TY_flist(ty));
00729       } else if (!FLD_equivalence(fld)) {
00730         xos << TY2F_Fld_Name(fld_iter, TRUE/*common*/, FALSE/*alt_ret_name*/);
00731       }
00732     
00733       if (!FLD_last_field(fld)) {
00734         FLD_ITER  next_iter = fld_iter ;
00735         FLD_HANDLE next (++next_iter);
00736         if (!FLD_equivalence(next))
00737           xos << ',';
00738       }
00739     
00740     } while (!FLD_last_field (fld_iter++)) ;
00741 
00742   } /* TY2F_List_Common_Flds */
00743 
00744   /*------------- Hidden routines to declare variable types -------------*/
00745   /*---------------------------------------------------------------------*/
00746 
00747   static void
00748   TY2F_invalid(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt)
00749   {
00750     FORTTK_DIE(fortTkSupport::Diagnostics::UnexpectedInput << TY_kind(Ty_Table[ty]));
00751   }
00752 
00753   static void
00754   TY2F_scalar(xml::ostream& xos, TY_IDX ty_idx, PUXlationContext& ctxt)
00755   {
00756     FORTTK_ASSERT(TY_kind(ty_idx) == KIND_SCALAR, fortTkSupport::Diagnostics::UnexpectedInput);
00757   
00758     TY&   ty = Ty_Table[ty_idx];
00759     MTYPE mt = TY_mtype(ty);
00760 
00761     const char* type_str;
00762     if (TY_is_character(ty)) {
00763       type_str = "CHARACTER";
00764     } else if (TY_is_logical(ty)) {
00765       type_str = "LOGICAL";
00766     } else {
00767       switch(mt) {
00768       case MTYPE_U1: // Strictly speaking unsigned integers not supported
00769       case MTYPE_U2: // in Fortran, but we are lenient and treat them
00770       case MTYPE_U4: // as the signed equivalent.
00771       case MTYPE_U8:
00772       
00773       case MTYPE_I1:
00774       case MTYPE_I2:
00775       case MTYPE_I4:
00776       case MTYPE_I8:
00777         type_str = "INTEGER";
00778         break;
00779       
00780       case MTYPE_F4:
00781       case MTYPE_F8:
00782       case MTYPE_FQ:
00783         type_str = "REAL";
00784         break;
00785       
00786       case MTYPE_C4:
00787       case MTYPE_C8:
00788       case MTYPE_CQ:
00789         type_str = "COMPLEX";
00790         break;
00791       
00792       case MTYPE_M:
00793         type_str = "memory block";
00794         break;
00795       
00796       default:
00797         FORTTK_DIE("Unexpected type " << MTYPE_name(mt));
00798       }
00799     }
00800   
00801     const char* size_str;
00802     INT64 size;
00803     if (TY_size(ty) > 0) {
00804       if (ctxt.isF90() && MTYPE_is_complex(mt)) {
00805         size = TY_size(ty) / 2; 
00806       } else {
00807         size = TY_size(ty);
00808       }
00809       size_str = Num2Str(size, "%lld");
00810     } else {
00811       if (mt == MTYPE_M) {
00812         size_str = ".mblock.";
00813       } else {
00814         FORTTK_ASSERT(TY_is_character(ty), 
00815                       "Unexpected type size " << TY_size(ty));
00816         size_str = "*";
00817       }
00818     }
00819 
00820     const char* str = StrCat(type_str, size_str);
00821 
00822     xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00823         << xml::Attr("name", "type") << xml::Attr("value", str) << xml::EndElem;
00824 
00825     xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00826         << xml::Attr("name", "whirltype") << xml::Attr("value", TY_name(ty)) << xml::EndElem;
00827   }
00828 
00829   static void
00830   TY2F_array(xml::ostream& xos, TY_IDX ty_idx, PUXlationContext& ctxt)
00831   {
00832     TY& ty = Ty_Table[ty_idx];
00833 
00834     FORTTK_ASSERT(TY_kind(ty) == KIND_ARRAY, fortTkSupport::Diagnostics::UnexpectedInput);
00835 
00836     xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00837         << xml::Attr("name", "whirlkind") << xml::Attr("value", "array") << xml::EndElem;
00838 
00839 
00840     if (TY_is_character(ty)) { // FIXME
00841       // A character string... 
00842       if (TY_size(ty) > 0) /* ... of known size */
00843         xos << "CHARACTER*" << Num2Str(TY_size(ty), "%lld");
00844       else /* ... of unknown size */
00845         xos << "CHARACTER*(*)";
00846 
00847     } else {
00848       // A regular array, so prepend the element type and append
00849       // the index bounds.
00850       ARB_HANDLE arb_base = TY_arb(ty);
00851       INT32 dim = ARB_dimension(arb_base) ;
00852       INT32 co_dim = ARB_co_dimension(arb_base);
00853       INT32 array_dim = dim - co_dim;
00854       INT32 revdim = 0;
00855 
00856       if (ARB_co_dimension(arb_base) <= 0) {
00857         co_dim = 0;
00858         array_dim = dim;
00859       }
00860 
00861       // 1. Translate element type
00862       xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00863           << xml::Attr("name", "ArrayElementType");
00864 
00865       // Do not permit pointers as elements of arrays, so just use
00866       // the corresponding integral type instead.  We do not expect
00867       // such pointers to be dereferenced anywhere. (FIXME)
00868       if (TY_Is_Pointer(TY_AR_etype(ty)))
00869         TY2F_translate(xos, Stab_Mtype_To_Ty(TY_mtype(TY_AR_etype(ty))), ctxt);
00870       else
00871         TY2F_translate(xos, TY_AR_etype(ty), ctxt);
00872     
00873       xos << xml::EndElem;
00874 
00875       // 2. Translate dimension attributes
00876       while (array_dim > 0) {
00877       
00878         xos << xml::BegElem("xaif:Property") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00879             << xml::Attr("name", "ArrayDimensionAttr") << xml::Attr("dim", dim);
00880       
00881         ARB_HANDLE arb = arb_base[dim-1];
00882         TY2F_Append_ARB(xos, arb, ty_idx, ctxt);
00883       
00884         xos << xml::EndElem;
00885       
00886         array_dim--;
00887         dim--;
00888         revdim++;
00889       } 
00890 
00891       // 3. What is this???
00892       dim = ARB_dimension(arb_base);
00893       array_dim = dim - co_dim;
00894       --dim;
00895     
00896       if (co_dim > 0) {
00897         xos << '[';
00898         while (co_dim > 0) {
00899           ARB_HANDLE arb = arb_base[dim-array_dim];
00900         
00901 
00902           if (TY_is_f90_deferred_shape(ty))
00903             TY2F_Append_ARB(xos, arb, ty_idx, ctxt);
00904           else {
00905             if (co_dim == 1)
00906               TY2F_Append_ARB(xos, arb, ty_idx, ctxt); // TRUE
00907             else
00908               TY2F_Append_ARB(xos, arb, ty_idx, ctxt); // FALSE
00909           }
00910         
00911           dim--;
00912 
00913           if (co_dim > 1)
00914             xos << ',';
00915 
00916           co_dim--;
00917           ++revdim;
00918         }
00919         xos << ']';
00920       }
00921 
00922     }
00923   } /* TY2F_array */
00924 
00925 
00926   static void
00927   TY2F_array_for_pointer(xml::ostream& xos, TY_IDX ty_idx, PUXlationContext& ctxt)
00928   {
00929     TY& ty = Ty_Table[ty_idx] ;
00930 
00931     FORTTK_ASSERT(TY_kind(ty) == KIND_ARRAY, fortTkSupport::Diagnostics::UnexpectedInput);
00932   
00933     if (TY_is_character(ty)) {
00934       /* A character string...
00935        */
00936       if (TY_size(ty) > 0) /* ... of known size */
00937         xos << "CHARACTER*" << Num2Str(TY_size(ty), "%lld");
00938       else /* ... of unknown size */
00939         xos << "CHARACTER*(*)";
00940     } else {
00941       /* A regular array, so prepend the element type and append
00942        * the index bounds.
00943        */
00944       ARB_HANDLE arb_base = TY_arb(ty);
00945       INT32       dim = ARB_dimension(arb_base) ;
00946       INT32       co_dim = ARB_co_dimension(arb_base);
00947       INT32       array_dim = dim-co_dim;
00948       INT32       revdim = 0;
00949     
00950       /* Do not permit pointers as elements of arrays, so just use
00951        * the corresponding integral type instead.  We do not expect
00952        * such pointers to be dereferenced anywhere.
00953        */
00954       if (TY_Is_Pointer(TY_AR_etype(ty)))
00955         TY2F_translate(xos, Stab_Mtype_To_Ty(TY_mtype(TY_AR_etype(ty))), ctxt);
00956       else
00957         TY2F_translate(xos, TY_AR_etype(ty), ctxt);
00958     
00959       if (ARB_co_dimension(arb_base)<=0) {
00960         co_dim=0;
00961         array_dim = dim;
00962       }
00963     
00964       if (array_dim>0) {
00965         xos << "(";
00966       
00967         while (array_dim > 0) {
00968           ARB_HANDLE arb = arb_base[dim-1];
00969           xos << ':';
00970           if (array_dim-- > 1)
00971             xos << ',';
00972         
00973           --dim;
00974           ++revdim;
00975         }
00976       
00977         xos << ')';
00978       }
00979     
00980       dim = ARB_dimension(arb_base);
00981       array_dim = dim - co_dim;
00982       --dim;
00983     
00984       if (co_dim > 0) {
00985         xos << '[';
00986         while (co_dim > 0) {
00987           ARB_HANDLE arb = arb_base[dim-array_dim];
00988           xos << ':';
00989           dim--;
00990 
00991           if (co_dim-- > 1)
00992             xos << ',';
00993         
00994           ++revdim;
00995         }
00996         xos << ']';
00997       }
00998     }
00999   } /* TY2F_array_for_pointer */
01000 
01001 
01002   static void
01003   TY2F_struct(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt)
01004   {
01005     /* Structs are supported by VAX-Fortran and Fortran-90.  Note
01006      * that we here emit a RECORD declaration, while we expect
01007      * the STRUCTURE to have been declared through a call to
01008      * TY2F_Translate_Structure().
01009      */
01010     TY& ty_rt = Ty_Table[ty];
01011     FORTTK_ASSERT(TY_kind(ty_rt) == KIND_STRUCT, fortTkSupport::Diagnostics::UnexpectedInput);
01012   
01013     xos << "(" << TY_name(ty) << ")" << "TYPE";
01014   
01015 #if 0 // see Open64 stab_attr.cxx; if needed simulate thru PUXlationContext
01016     if (!TY_is_translated_to_c(ty)) {
01017       TY2F_Translate_Structure(xos, ty);
01018       Set_TY_is_translated_to_c(ty); /* Really, translated to Fortran, not C */
01019     }
01020 #endif
01021   }
01022 
01023 
01024   static void
01025   TY2F_2_struct(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt)
01026   {
01027     /* Structs are supported by VAX-Fortran and Fortran-90.  Note
01028      * that we here emit a RECORD declaration, while we expect
01029      * the STRUCTURE to have been declared through a call to
01030      * TY2F_Translate_Structure().
01031      */
01032     TY & ty_rt = Ty_Table[ty];
01033     FORTTK_ASSERT(TY_kind(ty_rt) == KIND_STRUCT, fortTkSupport::Diagnostics::UnexpectedInput);
01034 
01035 #if 0 // see Open64 stab_attr.cxx; if needed simulate thru PUXlationContext
01036     if (!TY_is_translated_to_c(ty)) {
01037       TY2F_Translate_Structure(xos, ty);
01038       Set_TY_is_translated_to_c(ty); /* Really, translated to Fortran, not C */
01039     }
01040 #endif
01041   }
01042 
01043 
01044   static void
01045   TY2F_pointer(xml::ostream& xos, TY_IDX ty, PUXlationContext& ctxt)
01046   {
01047     /* Is a dope vector base address? Put out an integer large enough */
01048     /* to hold an address for now. Don't really want POINTER because  */
01049     /* implies cray/f90 pointer instead of address slot               */
01050   
01051     if (TY2F_Pointer_To_Dope(ty)) {
01052 #if 0
01053       Prepend_Token_String(xos,",POINTER ::");
01054 #endif
01055       TY2F_translate(xos,Be_Type_Tbl(Pointer_Mtype), ctxt);
01056     } else {
01057       /* avoid recursive type declarations */
01058       if (TY_kind(TY_pointed(ty)) == KIND_STRUCT) {
01059 #if 0
01060         Prepend_Token_String(xos,",POINTER ::");
01061         Prepend_Token_String(xos, TY_name(TY_pointed(ty)));
01062 #endif
01063         TY2F_translate(xos,Be_Type_Tbl(Pointer_Mtype), ctxt);
01064       
01065       } else
01066         TY2F_translate(xos,TY_pointed(ty), ctxt);
01067     }
01068   } /* TY2F_pointer */
01069 
01070   static void
01071   TY2F_void(xml::ostream& xos, TY_IDX ty_idx, PUXlationContext& ctxt)
01072   {
01073     TY& ty = Ty_Table[ty_idx];
01074     FORTTK_ASSERT(TY_kind(ty) == KIND_VOID, fortTkSupport::Diagnostics::UnexpectedInput);
01075     xos << std::endl << "! <Void Type>";
01076   }
01077 
01078   /*------------------------ exported routines --------------------------*/
01079   /*---------------------------------------------------------------------*/
01080 
01081 
01082   // JU: I don't think the conditions under which this method is called
01083   // in the rest of the code are ever satisfied. 
01084   void 
01085   TY2F_Translate_ArrayElt(xml::ostream& xos, 
01086                           TY_IDX       arr_ty_idx,
01087                           STAB_OFFSET  arr_ofst)
01088   {  
01089     assert(0);
01090   }
01091 
01092 
01093   void
01094   TY2F_Translate_Common(xml::ostream& xos, const char *name, TY_IDX ty_idx)
01095   {
01096     TY& ty = Ty_Table[ty_idx];
01097     BOOL is_equiv = FALSE;
01098   
01099     FORTTK_ASSERT(TY_kind(ty) == KIND_STRUCT, 
01100                   fortTkSupport::Diagnostics::UnexpectedInput << TY_kind(ty));
01101 
01102     // Emit specification statements for every element of the common
01103     // block, including equivalences.
01104     xos << xml::BegComment << "COMMON";
01105     if (name != NULL && *name != '\0') { xos << " name = " << name; }
01106     xos << xml::EndComment;
01107 
01108 #if 0 // FIXME
01109     TY2F_List_Common_Flds(xos, TY_flist(ty));
01110   
01111     // variables in common block type declaration
01112     TY2F_Declare_Common_Flds(xos, TY_flist(ty), FALSE /*alt_return*/, &is_equiv);
01113   
01114     // Emit equivalences, if there are any
01115     if (is_equiv)
01116       TY2F_Equivalence_List(xos, ty_idx /*struct_ty*/);
01117 #endif
01118   }
01119 
01120 
01121   void
01122   TY2F_Translate_Equivalence(xml::ostream& xos, TY_IDX ty_idx, BOOL alt_return)
01123   {
01124     /* When alt_return==TRUE, this represents an alternate return variable,
01125      * in which case we should declare the elements of the equivalence
01126      * with unmangled names and ignore the fact that they are in an
01127      * equivalence.  The first element in such an alternate return is
01128      * the function/subprogram return-variable, which we should never
01129      * declare.
01130      */
01131     TY& ty = Ty_Table[ty_idx];
01132 
01133     FLD_HANDLE first_fld;
01134     BOOL is_equiv;
01135    
01136     FORTTK_ASSERT(TY_kind(ty) == KIND_STRUCT, 
01137                   fortTkSupport::Diagnostics::UnexpectedInput << TY_kind(ty));
01138 
01139     if (alt_return) {
01140       first_fld = FLD_next(TY_flist(ty)); /* skip func_entry return var */
01141     } else {
01142       first_fld = TY_flist(ty);
01143     }
01144 
01145     /* Emit specification statements for every element of the
01146      * equivalence block.
01147      */  
01148     TY2F_Declare_Common_Flds(xos, first_fld, alt_return,
01149                              &is_equiv);  /* Redundant in this call */
01150 
01151     if (!alt_return)
01152       TY2F_Equivalence_List(xos, ty_idx /*struct_ty*/);
01153 
01154   } /* TY2F_Translate_Equivalence */
01155 
01156 
01157   FLD_PATH_INFO * 
01158   TY2F_Free_Fld_Path(FLD_PATH_INFO *fld_path)
01159   {
01160     FLD_PATH_INFO *free_list;
01161    
01162     if (fld_path != NULL) {
01163       free_list = Free_Fld_Path_Info;
01164       Free_Fld_Path_Info = fld_path;
01165       while (fld_path->next != NULL)
01166         fld_path = fld_path->next;
01167       fld_path->next = free_list;
01168     }
01169     return NULL;
01170   } /* TY2F_Free_Fld_Path */
01171 
01172 
01173   FLD_PATH_INFO * 
01174   TY2F_Get_Fld_Path(const TY_IDX struct_ty, const TY_IDX object_ty, 
01175                     STAB_OFFSET offset)
01176   {
01177     FLD_PATH_INFO* fld_path;
01178     FLD_PATH_INFO* fld_path2 = NULL;
01179     TY& s_ty = Ty_Table[struct_ty];
01180     FLD_ITER fld_iter;
01181 
01182     FORTTK_ASSERT(TY_kind(s_ty) == KIND_STRUCT, 
01183                   fortTkSupport::Diagnostics::UnexpectedInput << TY_kind(s_ty));
01184   
01185     /* Get the best matching field path into fld_path2 */
01186     fld_iter = Make_fld_iter(TY_flist(s_ty));
01187   
01188     do {
01189       FLD_HANDLE fld (fld_iter);
01190     
01191       if (NOT_BITFIELD_OR_IS_FIRST_OF_BITFIELD(fld_iter)) {
01192         fld_path = Construct_Fld_Path(fld_iter, struct_ty, object_ty,
01193                                       offset, TY_size(s_ty));
01194         if (fld_path2 == NULL)
01195           fld_path2 = fld_path;
01196         else if (fld_path != NULL)
01197           fld_path2 = Select_Best_Fld_Path(fld_path2, fld_path, object_ty,
01198                                            offset);
01199       }
01200     } while (!FLD_last_field (fld_iter++));
01201   
01202     /* POSTCONDITION: fld_path2 points to the best match found */
01203     return fld_path2;
01204   }
01205 
01206   void
01207   TY2F_Translate_Fld_Path(xml::ostream&   xos,
01208                           FLD_PATH_INFO *fld_path, 
01209                           BOOL           deref, 
01210                           BOOL           member_of_common, 
01211                           BOOL           alt_ret_name,
01212                           PUXlationContext& ctxt)
01213   {
01214     /* Append the name of each field to the tokens, separated them
01215      * from each other by the field-selection operator ('.').  The
01216      * first name on the path may optionally be emitted in unclobbered 
01217      * form, as it may represent an alternate return point.
01218      */
01219     while (fld_path != NULL) {
01220       FLD_HANDLE f (fld_path->fld);
01221       const char* str = TY2F_Fld_Name(f, member_of_common, alt_ret_name);
01222       if (deref && TY_Is_Pointer(FLD_type(f))) {
01223         str = StrCat("deref_", str); // W2CF_Symtab_Nameof_Fld_Pointee(f);
01224       }
01225       xos << xml::BegElem("TYFLD") << xml::Attr("***name", str) << xml::EndElem;
01226 
01227       member_of_common = FALSE; /* Can only be true first time around */
01228     
01229       /* if an array element, form the subscript list. If an OPC_ARRAY */
01230       /* provides the subscripts, use it o/w use offset                */
01231       if (fld_path->arr_elt) {
01232         if (fld_path->arr_wn != NULL)
01233           WN2F_array_bounds(xos, fld_path->arr_wn, FLD_type(f), ctxt);
01234       }
01235     
01236       /* Separate fields with the dot-notation. */
01237       fld_path = fld_path->next;
01238       if (fld_path != NULL) {
01239         TY2F_Fld_Separator(xos) ;
01240         alt_ret_name = FALSE; /* Only applies to first field on the path */
01241       }
01242     } /* while */
01243   
01244   } /* TY2F_Translate_Fld_Path */
01245 
01246 
01247   extern void
01248   TY2F_Fld_Separator(xml::ostream& xos)
01249   {
01250     /* puts out the appropriate structure component separator*/
01251     xos << '%';
01252   }
01253 
01254   extern FLD_HANDLE
01255   TY2F_Last_Fld(FLD_PATH_INFO *fld_path)
01256   {
01257     FLD_HANDLE f = FLD_HANDLE () ;
01258 
01259     while (fld_path != NULL) {
01260       f = fld_path->fld;
01261       fld_path = fld_path->next ;
01262     }
01263   
01264     return f;
01265   }
01266 
01267   extern FLD_PATH_INFO * 
01268   TY2F_Point_At_Path(FLD_PATH_INFO * path, STAB_OFFSET off)
01269   {
01270     /* given a fld path, return a pointer to */
01271     /* the slot at the given offset          */
01272     while (path != NULL) {
01273       if ((INT64)FLD_ofst(path->fld) >= off)
01274         break ;    
01275       path=path->next;
01276     }
01277     return path;
01278   }
01279 
01280   extern void
01281   TY2F_Dump_Fld_Path(FLD_PATH_INFO *fld_path)
01282   {
01283     printf ("path ::");
01284     while (fld_path != NULL) {
01285       FLD_HANDLE f = fld_path->fld;
01286     
01287       printf ("%s(#%d)",TY2F_Fld_Name(f,FALSE,FALSE),f.Idx ());
01288     
01289       if (fld_path->arr_elt)
01290         printf (" array");
01291     
01292       if (fld_path->arr_ofst)
01293         printf (" offset 0x%x",(mINT32) fld_path->arr_ofst);
01294     
01295       if (fld_path->arr_wn != NULL)
01296         printf (" tree 0x%p",fld_path->arr_wn);
01297     
01298       printf (" ::");
01299       fld_path = fld_path->next ;
01300     }
01301     printf ("\n");
01302   }
01303 
01304 
01305   // ***************************************************************************
01306   //
01307   // ***************************************************************************
01308 
01309 
01310   const char*
01311   TranslateTYToSymType(TY_IDX ty_idx)
01312   {
01313     TY& ty = Ty_Table[ty_idx];
01314     const char* str = NULL;
01315 
01316     if (TY_kind(ty) == KIND_SCALAR) {
01317       MTYPE mt = TY_mtype(ty);
01318       if (TY_is_character(ty)) {
01319         str = "char"; 
01320       } 
01321       else if (TY_is_logical(ty)) {
01322         str = "bool"; 
01323       } 
01324       else if (MTYPE_is_integral(mt)) {
01325         str = "integer"; 
01326       } 
01327       else if (MTYPE_is_complex(mt)) { /* must come before 'float' */
01328         str = "complex";
01329       } 
01330       else if (MTYPE_is_float(mt)) { 
01331         str = "real"; 
01332       }
01333     } 
01334     else if (TY_kind(ty) == KIND_ARRAY) {
01335       if (TY_is_character(ty)) { 
01336         str = "string"; 
01337       } 
01338       else {
01339         // Do not permit pointers as elements of arrays, so just use
01340         // the corresponding integral type instead.  We do not expect
01341         // such pointers to be dereferenced anywhere. (FIXME)
01342         TY_IDX ety_idx = TY_AR_etype(ty);
01343         if (TY_Is_Pointer(ety_idx)) {
01344           ety_idx = Stab_Mtype_To_Ty(TY_mtype(ety_idx));
01345         } 
01346         str = TranslateTYToSymType(ety_idx);
01347       }
01348     } 
01349     else if (TY_kind(ty) == KIND_STRUCT 
01350              || 
01351              TY_kind(ty) == KIND_INVALID) {
01352       // the latter applies to symbols that are f90 interface names
01353       str = "opaque";
01354     }  
01355     else if (TY_kind(ty) == KIND_FUNCTION) {
01356       str = "void";
01357     } 
01358     else if (TY_kind(ty) == KIND_POINTER) { 
01359       str = "opaque";
01360     } 
01361     else 
01362       FORTTK_DIE("whirl2xaif::TranslateTYToSymType: no logic to handle type of kind " << TY_kind(ty));
01363     return str;
01364   }
01365 
01366   const char*
01367   TranslateTYToMType(TY_IDX ty_idx) {
01368     TY& ty_r = Ty_Table[ty_idx];
01369     if (TY_kind(ty_r) == KIND_SCALAR) {
01370       return Mtype_Name(TY_mtype(ty_r));
01371     } 
01372     else if (TY_kind(ty_r) == KIND_ARRAY) {
01373       if (TY_is_character(ty_r)) { 
01374         return Mtype_Name(TY_mtype(ty_r));
01375       } 
01376       else {
01377         // Do not permit pointers as elements of arrays, so just use
01378         // the corresponding integral type instead.  We do not expect
01379         // such pointers to be dereferenced anywhere. (FIXME)
01380         TY_IDX ety_idx = TY_AR_etype(ty_r);
01381         if (TY_Is_Pointer(ety_idx)) {
01382           ety_idx = Stab_Mtype_To_Ty(TY_mtype(ety_idx));
01383         } 
01384         return TranslateTYToMType(ety_idx);
01385       }
01386     } 
01387     else if (TY_kind(ty_r) == KIND_STRUCT 
01388              || 
01389              TY_kind(ty_r) == KIND_INVALID
01390              ||
01391              TY_kind(ty_r) == KIND_FUNCTION
01392              ||
01393              TY_kind(ty_r) == KIND_POINTER) { 
01394         return Mtype_Name(TY_mtype(ty_r));
01395     } 
01396     else 
01397       FORTTK_DIE("whirl2xaif::TranslateTYToMType: no logic to handle type of kind " << TY_kind(ty_r));
01398     return "";
01399   }
01400 
01401   const char*
01402   TranslateTYToSymShape(TY_IDX ty_idx)
01403   {
01404     TY& ty = Ty_Table[ty_idx];
01405     const char* str = NULL;
01406   
01407     if (TY_kind(ty) == KIND_SCALAR) {
01408       str = "scalar";
01409     } 
01410     else if (TY_kind(ty) == KIND_ARRAY) {
01411     
01412       ARB_HANDLE arb_base = TY_arb(ty);
01413       INT32 dim = ARB_dimension(arb_base);
01414       // ARB_co_dimension(arb_base) <= 0 FIXME
01415 
01416       if (TY_is_character(ty)) { 
01417         str = "scalar"; 
01418       } 
01419       else {
01420         switch (dim) {
01421         case 1:  str = "vector"; break;
01422         case 2:  str = "matrix"; break;
01423         case 3:  str = "three_tensor"; break;
01424         case 4:  str = "four_tensor"; break;
01425         case 5:  str = "five_tensor"; break;
01426         case 6:  str = "six_tensor"; break;
01427         case 7:  str = "seven_tensor"; break;
01428         default: 
01429           FORTTK_DIE("Invalid array dimension: " << dim);
01430         }
01431       }
01432 
01433     } 
01434     else if (TY_kind(ty) == KIND_STRUCT
01435              || 
01436              TY_kind(ty) == KIND_INVALID) {
01437       // the latter applies to symbols that are f90 interface names
01438       str = "scalar"; // FIXME
01439     }  
01440   
01441     return str;
01442   }
01443 
01444 }

Generated on Fri Jul 24 04:29:12 2009 for OpenADFortTk (extended to Open64) by  doxygen 1.5.7.1