OpenADFortTk (basic)
src/whirl2xaif/st2xaif.cxx
Go to the documentation of this file.
00001 // ##########################################################
00002 // # This file is part of OpenADFortTk.                     #
00003 // # The full COPYRIGHT notice can be found in the top      #
00004 // # level directory of the OpenADFortTk source tree.       #
00005 // # For more information visit                             #
00006 // # http://www.mcs.anl.gov/openad                          #
00007 // ##########################################################
00008 
00009 /* ====================================================================
00010  * ====================================================================
00011  *
00012  * Revision history:
00013  *  07-May-95 - Original Version
00014  *
00015  * Description: FIXME
00016  *
00017  *    See st2f.h for a description of the exported functions and 
00018  *    variables.  This module translates ST nodes into variable and
00019  *    function declarations (TranslateSTDecl), and gets the 
00020  *    lvalue for a variable or function when directly referenced in
00021  *    an expression (TranslateSTUse).  We provide a special 
00022  *    interface to deal with pseudo registers (pregs), but some 
00023  *    symbols must be handled by the context in which they appear,
00024  *    since this context uniquely determines the reference (e.g. 
00025  *    labels has label-numbers in the WN tree).
00026  *
00027  *    Possibly necessary TODO: sym_consts are only partially
00028  *    supported at the moment.
00029  *
00030  *    Fortran pointers are represented by two declarations, where
00031  *    one declares the pointer object (which is allocated memory)
00032  *    and one denotes the pointer dereference which also serves to
00033  *    specify the type of object to which is pointed:
00034  *
00035  *        INTEGER*4 a(12)
00036  *        POINTER(p, a)
00037  *
00038  *    Only "p" occurs in the WHIRL symbol table.  We have to derive
00039  *    "a" from "p" (with a name derived from "p").  The w2cf_symtab.h
00040  *    facilities coordinates this for us.
00041  *
00042  *    It is crucial that names with external linkage are generated 
00043  *    with the same name between compilation units.  For this reason
00044  *    we give file-scope variables precedence in name-ownership (i.e.
00045  *    they are entered first into the symbol-table).  If, despite this
00046  *    effort, there are clashes between names with static and external 
00047  *    linkage, the generated code may not be compilable or correctly
00048  *    executable.  TODO: Emit warning about this.
00049  * 
00050  * ====================================================================
00051  * ====================================================================
00052  */
00053 
00054 #include <ctype.h>
00055 #include <sstream> 
00056 #include <alloca.h>
00057 
00058 #include "Open64IRInterface/Open64BasicTypes.h"
00059 
00060 #include "wn2xaif.h"
00061 #include "st2xaif.h"
00062 #include "ty2xaif.h"
00063 #include "Args.h"
00064 
00065 #include "Open64IRInterface/SymTab.h"
00066 
00067 
00068 namespace whirl2xaif { 
00069 
00070 
00071 
00072   /*------- Fwd refs for miscellaneous utilities ------------------------*/
00073   /*---------------------------------------------------------------------*/
00074 
00075   static BOOL ST2F_Is_Dummy_Procedure(ST *st) ;
00076   static void ST2F_Declare_Return_Type(xml::ostream& xos,TY_IDX return_ty, 
00077                                        PUXlationContext& ctxt);
00078 
00079   // Symbol declarations and uses
00080 
00081   static void 
00082   xlate_ST_ignore(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00083 
00084   static void 
00085   xlate_STDecl_error(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00086   static void 
00087   xlate_STDecl_VAR(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00088   static void 
00089   xlate_STDecl_FUNC(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00090   static void 
00091   xlate_STDecl_CONST(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00092   static void 
00093   xlate_STDecl_PREG(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00094   static void 
00095   xlate_STDecl_BLOCK(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00096   static void 
00097   xlate_STDecl_NAME(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00098   static void 
00099   xlate_STDecl_TYPE(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00100 
00101   static void 
00102   xlate_STUse_error(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00103   static void 
00104   xlate_STUse_VAR(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00105   static void 
00106   xlate_STUse_CONST(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00107   static void 
00108   xlate_STUse_BLOCK(xml::ostream& xos, ST *st, PUXlationContext& ctxt);
00109 
00110   static FLD_HANDLE
00111   TY_Lookup_FLD(TY_IDX struct_ty, TY_IDX ref_ty, UINT64 ref_ofst, unsigned short eqInst=1);
00112 
00113   // ***************************************************************************
00114 
00115 
00116   // identical copy from xaif2whirl.cxx
00117   static FLD_HANDLE 
00118   TY_Lookup_FLD(TY_IDX struct_ty, TY_IDX ref_ty, UINT64 ref_ofst,unsigned short eqInst)
00119   {
00120     FLD_ITER fld_iter = Make_fld_iter(TY_fld(struct_ty));
00121     unsigned short foundInst=0;
00122     do {
00123       FLD_HANDLE fld(fld_iter);
00124       UINT64 ofst = FLD_ofst(fld);
00125       TY_IDX ty   = FLD_type(fld);
00126       if (ofst == ref_ofst) {
00127         ++foundInst;
00128         if (ref_ty == 0) {
00129           if (eqInst==foundInst)
00130             return fld;
00131         }
00132         else {
00133           if (Stab_Identical_Types(ref_ty, ty, FALSE /* check_quals */,
00134                                    FALSE /* check_scalars */, TRUE)) {
00135             return fld;
00136           }
00137         }
00138       }
00139     } while (!FLD_last_field(fld_iter++));
00140     return FLD_HANDLE(); // null field
00141   }
00142 
00143   std::string
00144   TCON2F_hollerith(TCON tvalue)
00145   {
00146     /* Translates the given Hollerith constant into Fortran representation.
00147      * A hollerith constant cannot be split into substrings.
00148      */
00149     const char *strbase;
00150     char       *str;
00151     INT32       strlen;
00152   
00153     FORTTK_ASSERT_WARN(TCON_ty(tvalue) == MTYPE_STR,
00154                        "Unexpected type " << MTYPE_name(TCON_ty(tvalue)));
00155   
00156     strlen = Targ_String_Length(tvalue);
00157     strbase = Targ_String_Address(tvalue);
00158     str = (char *) alloca(strlen + 16);
00159     sprintf(str, "%dH%s", strlen, strbase);
00160   
00161     return std::string(str);
00162   } /* TCON2F_hollerith */
00163 
00164    
00165   std::string
00166   TCON2F_translate(TCON tvalue, BOOL is_logical, TY_IDX object_ty)
00167   {
00168     // Note: It would be nice to simply use C++ stream formatting
00169     // instead of Targ_Print(..), but a TCON is a (complex) union whose
00170     // interpretation technically depends on the target.
00171 
00172     // Since Targ_Print(..) prints floating points with Fortran
00173     // exponents (i.e. the exponent of a double is preceeded by 'd'
00174     // instead of an 'e'), we massage its output.
00175 
00176     // FIXME: for now we use this hack to return a string
00177     std::ostringstream sstr;
00178     char* floatstr = NULL;
00179   
00180     if (is_logical && MTYPE_type_class(TCON_ty(tvalue)) & MTYPE_CLASS_INTEGER) {
00181       // Treat it as regular integral constant, unless it has value 0 or 1.
00182       if (Targ_To_Host(tvalue) == 0LL)
00183         sstr << "false";
00184       else if  (Targ_To_Host(tvalue) == 1LL)
00185         sstr << "true";
00186       else
00187         is_logical = FALSE;
00188     } else { /* Only integral values can be treated as boolean */
00189       is_logical = FALSE; 
00190     }
00191   
00192     if (!is_logical) {
00193       switch (TCON_ty(tvalue)) {
00194 
00195       case MTYPE_STR: {
00196         // To be entirely safe, we do not assume the string contains
00197         // NULL terminator.
00198         INT32 len = Targ_String_Length(tvalue);
00199         const char* str = Targ_String_Address(tvalue);      
00200         for (int i = 0; i < len; ++i)
00201           sstr << str[i];
00202       }
00203         break;
00204       
00205       case MTYPE_I1:
00206       case MTYPE_I2:
00207       case MTYPE_I4:
00208         sstr << Targ_Print("%1d", tvalue);
00209         break;
00210       
00211       case MTYPE_I8:
00212         sstr << Targ_Print("%1lld", tvalue);
00213         break;
00214       
00215       case MTYPE_U1:
00216       case MTYPE_U2:
00217       case MTYPE_U4:
00218         sstr << Targ_Print("%1u", tvalue);
00219         break;
00220       
00221       case MTYPE_U8:
00222         sstr << Targ_Print("%1llu", tvalue);
00223         break;
00224       
00225       case MTYPE_F4:
00226         floatstr = Targ_Print("%.10e", tvalue);
00227         break;
00228       
00229       case MTYPE_F8:
00230         floatstr = Targ_Print("%.20e", tvalue);
00231         break;
00232       
00233       case MTYPE_FQ:
00234         floatstr = Targ_Print(NULL, tvalue);
00235         break;
00236       
00237       case MTYPE_C4:
00238       case MTYPE_C8:
00239       case MTYPE_CQ:
00240         sstr << '(' << TCON2F_translate(Extract_Complex_Real(tvalue), FALSE)
00241              << ',' << TCON2F_translate(Extract_Complex_Imag(tvalue), FALSE)
00242              << ')';
00243         break;
00244       
00245       default:
00246         /* Only expression nodes should be handled here */
00247         FORTTK_DIE("Unexpected type " << MTYPE_name(TCON_ty(tvalue)));
00248         break;
00249       }
00250     }
00251 
00252     if (floatstr) {
00253       char* exp = NULL;
00254       if (exp = strchr(floatstr, 'd')) {
00255         *exp = 'e';
00256       }
00257       sstr << floatstr;
00258     }
00259   
00260     return sstr.str();
00261 
00262   } /* TCON2F_translate */
00263 
00264   std::string
00265   TCON2F_translate(TCON tvalue, BOOL is_logical)
00266   {
00267     return TCON2F_translate(tvalue, is_logical, (TY_IDX)NULL);
00268   } 
00269 
00270 
00271   // ***************************************************************************
00272 
00273   // usage: xlate_SymbolTables(xos, CURRENT_SYMTAB, symtab, ctxt);
00274 
00275   void 
00276   xlate_SymbolTables(xml::ostream& xos, SYMTAB_IDX symtab_lvl, 
00277                      fortTkSupport::ScalarizedRefTab_W2X* nonscalarsymtab, 
00278                      PUXlationContext& ctxt)
00279   {
00280     xos << xml::BegElem("xaif:SymbolTable") << xml::EndAttrs;
00281 
00282     xlate_SYMTAB(xos, symtab_lvl, ctxt);
00283     xlate_ScalarizedRefTab(xos, nonscalarsymtab, ctxt);
00284   
00285     xos << xml::EndElem;
00286   }
00287 
00288   void 
00289   xlate_ArrayBounds(xml::ostream& xos, 
00290                     TY_IDX ty_idx, 
00291                     PUXlationContext& ctxt) { 
00292     if (TY_kind(ty_idx) == KIND_ARRAY) {
00293       if (! TY_is_character(ty_idx) &&  ! TY_is_f90_assumed_size(ty_idx)) { 
00294         bool assumeBoundsAllConst=false;
00295         // figure out if all bounds are constant
00296         for (int i=0; i<TY_AR_ndims(ty_idx); i++) {
00297           if (TY_AR_const_lbnd(ty_idx,i) && TY_AR_const_ubnd(ty_idx,i)) {
00298             if (!assumeBoundsAllConst && i==0) { 
00299               assumeBoundsAllConst=true;
00300             }
00301           }
00302           else 
00303             if (assumeBoundsAllConst)
00304               assumeBoundsAllConst=false;
00305         }
00306         // only if all of them are constant we  
00307         // specify the dimensions in xaif.  
00308         // If they are not constant or only 
00309         // some are constant we don't bother and 
00310         // assume everything is variable
00311         if (assumeBoundsAllConst) { 
00312           for (int i=0; i<TY_AR_ndims(ty_idx); i++) {
00313             xos << xml::BegElem("xaif:DimensionBounds") 
00314                 << xml::Attr("lower", TY_AR_lbnd_val(ty_idx,i))
00315                 << xml::Attr("upper", TY_AR_ubnd_val(ty_idx,i))
00316                 << xml::EndElem;
00317           }
00318         }
00319       }
00320     } 
00321   } 
00322 
00323   // FIXME: move to xlateSYMTAB.cxx
00324   class xlate_ST_TAB {
00325   public:
00326     xlate_ST_TAB(xml::ostream& xos_, SYMTAB_IDX symtab_, PUXlationContext& ctxt_) 
00327       : xos(xos_), symtab(symtab_), ctxt(ctxt_)
00328     { } 
00329 
00330     // A function object applied to every entry of a ST_TAB
00331     void operator()(UINT32 idx, ST* st) const 
00332     { 
00333       TranslateSTDecl(xos, st, ctxt);
00334     }
00335   
00336   private:
00337     xml::ostream&   xos;
00338     SYMTAB_IDX      symtab;
00339     PUXlationContext& ctxt;  
00340   };
00341 
00342 
00343   // FIXME: move to xlateSYMTAB.cxx
00344   // xlate_SYMTAB: Translate a WHIRL SYMTAB (a collection of tables) to
00345   // an XAIF symbol table.  'symtab_lvl' is an index (lexical level) in
00346   // the current 'Scope_tab[]'.
00347   void 
00348   xlate_SYMTAB(xml::ostream& xos, SYMTAB_IDX symtab_lvl,
00349                PUXlationContext& ctxt)
00350   {
00351     // 'For_all' applies 'operator()' to every entry of St_Table.
00352     For_all(St_Table, symtab_lvl, xlate_ST_TAB(xos, symtab_lvl, ctxt));
00353   }
00354 
00355 #if 0
00356   void 
00357   xlate_PREGTAB(xml::ostream& xos, SYMTAB_IDX symtab_lvl,
00358                 PUXlationContext& ctxt)
00359   {
00360     // 'For_all' applies 'operator()' to every entry of Preg_Table.
00361     For_all(Preg_Table, symtab_lvl, xlate_PREG_TAB(xos, symtab_lvl, ctxt));
00362   }
00363 #endif
00364 
00365 
00366   void
00367   xlate_ScalarizedRefTab(xml::ostream& xos, 
00368                          fortTkSupport::ScalarizedRefTab_W2X* symtab, 
00369                          PUXlationContext& ctxt)
00370   {
00371     if (!symtab) { return; }
00372   
00373     for (fortTkSupport::ScalarizedRefTab_W2X::ScalarizedRefPoolTy::iterator it 
00374            = symtab->RefPoolBegin(); 
00375          it != symtab->RefPoolEnd(); ++it) {
00376       fortTkSupport::ScalarizedRef* sym = (*it);
00377     
00378       WN* wn = sym->getWN();
00379       TY_IDX ty = WN_GetRefObjType(wn);
00380       const char* ty_str = TranslateTYToSymType(ty);
00381       if (!ty_str) { ty_str = "***"; }
00382       if (WN_operator(wn)==OPR_ILOAD)
00383         ty=WN_Tree_Type(WN_kid0(wn));
00384       else
00385         ty = WN_Tree_Type(wn);
00386       bool isPointer = TY_Is_Pointer(ty) || TY_is_f90_pointer(ty);
00387       bool isFnPointer = isPointer && (TY_kind(TY_pointed(ty)) == KIND_FUNCTION);
00388       const char* shape_str = (isPointer && (!isFnPointer)) ? TranslateTYToSymShape(TY_pointed(ty))
00389                                         : TranslateTYToSymShape(ty);
00390     
00391       int active = (strcmp(ty_str, "real") == 0 // FIXME: see xlate_STDecl_VAR
00392                     || strcmp(ty_str, "complex") == 0) ? 1 : 0; 
00393 
00394       xos << xml::BegElem("xaif:Symbol") << xml::Attr("symbol_id", sym->getName().c_str());    
00395       if (isFnPointer) {
00396         xos << xml::Attr("kind", "pointer") << xml::Attr("type", ty_str);
00397       }
00398       else {
00399         xos << xml::Attr("kind", "variable") << xml::Attr("type", ty_str);
00400       }
00401       xos << xml::Attr("shape", shape_str) << WhirlIdAnnot(ctxt.findWNId(wn))
00402           << xml::Attr("active", active) << xml::EndElem;
00403     }
00404   }
00405 
00406 
00407   // ***************************************************************************
00408 
00409   typedef void (*XlateSTHandlerFunc)(xml::ostream&, ST*, PUXlationContext&);
00410 
00411   static const XlateSTHandlerFunc XlateSTDecl_HandlerTable[CLASS_COUNT] =
00412     {
00413       &xlate_ST_ignore,     /* CLASS_UNK    == 0 */
00414       &xlate_STDecl_VAR,    /* CLASS_VAR    == 1 */
00415       &xlate_STDecl_FUNC,   /* CLASS_FUNC   == 2 */
00416       &xlate_STDecl_CONST,  /* CLASS_CONST  == 3 */
00417       &xlate_STDecl_PREG,   /* CLASS_PREG   == 4 */
00418       &xlate_STDecl_BLOCK,  /* CLASS_BLOCK  == 5 */
00419       &xlate_STDecl_NAME,   /* CLASS_NAME   == 6 */
00420       &xlate_STDecl_error,  /* CLASS_MODULE == 7 */
00421       &xlate_STDecl_TYPE,   /* CLASS_TYPE   == 8 */
00422       &xlate_STDecl_CONST,  /* CLASS_PARAMETER  == 9 */
00423     };
00424 
00425   static const XlateSTHandlerFunc XlateSTUse_HandlerTable[CLASS_COUNT] =
00426     {
00427       &xlate_ST_ignore,     /* CLASS_UNK   == 0 */
00428       &xlate_STUse_VAR,     /* CLASS_VAR   == 1 */
00429       &xlate_STUse_error,   /* CLASS_FUNC  == 2 */
00430       &xlate_STUse_CONST,   /* CLASS_CONST == 3 */
00431       &xlate_STUse_error,   /* CLASS_PREG  == 4 */
00432       &xlate_STUse_BLOCK,   /* CLASS_BLOCK == 5 */
00433       &xlate_STUse_error,   /* CLASS_NAME  == 6 */
00434       &xlate_STDecl_error,  /* CLASS_MODULE == 7 */
00435       &xlate_STDecl_error,  /* CLASS_TYPE   == 8 */
00436       &xlate_STDecl_error,  /* CLASS_PARAMETER  == 9 */
00437     };
00438 
00439   // ***************************************************************************
00440 
00441   void 
00442   TranslateSTDecl(xml::ostream& xos, ST* st, PUXlationContext& ctxt)
00443   { 
00444     XlateSTDecl_HandlerTable[ST_sym_class(st)](xos, st, ctxt);
00445   } 
00446 
00447   void 
00448   TranslateSTUse(xml::ostream& xos, ST* st, PUXlationContext& ctxt)
00449   { 
00450     XlateSTUse_HandlerTable[ST_sym_class(st)](xos, st, ctxt);
00451   }
00452 
00453   static void 
00454   xlate_ST_ignore(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00455   {
00456   }
00457 
00458   static void 
00459   xlate_STDecl_error(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00460   {
00461     FORTTK_DIE("Unknown ST_CLASS " << ST_class(st));
00462   }
00463 
00464   static bool equivalencedToActive(ST* st,
00465                                    PUXlationContext& ctxt) { 
00466     // find the symbols we are equivalence to:
00467     //    std::cout << "JU: equivalencedToActive: looking at " << ST_name(st) << std::endl;  
00468     TY_IDX baseTypeIndex = ST_type(ST_base(st));
00469     mUINT64 offset = ST_ofst(st); // offset into base symbol
00470     // find field with correct offset or symbol
00471     FLD_HANDLE fld = TY_Lookup_FLD(baseTypeIndex, 0, offset);
00472     ST_IDX fldStIdx=FLD_st(fld);
00473     //    std::cout << "\tJU: equivalencedToActive: looking at fld " << 1 <<  ":" << fld.Idx() << ":" << FLD_name(fld) << ":" << offset;  
00474     if (!fldStIdx) { 
00475       //      std::cout << "\tJU: equivalencedToActive: no FLD st"  << std::endl;
00476       ;
00477     }
00478     else {  
00479       //      std::cout << "\tJU: equivalencedToActive: have FLD st"  << std::endl;
00480       ST* fldSt_p=ST_ptr(fldStIdx);
00481       if (ctxt.isActiveSym(fldSt_p)) 
00482         return true;
00483     } 
00484     // if not the first one retrieve other fields with the same offset
00485     unsigned short eqInst=2;
00486     fld = TY_Lookup_FLD(baseTypeIndex, 0, offset,eqInst);
00487     while (!fld.Is_Null()) { 
00488       ST_IDX fldStIdx=FLD_st(fld);
00489       if (!fldStIdx) {  // this happens e.g. for local variable equivalenced to common block variable  
00490         //      std::cout << "\tJU: equivalencedToActive: skipping fld " << eqInst <<  ":" << fld.Idx() << ":" << FLD_name(fld) << ":" << offset << std::endl;  
00491         ;
00492       }
00493       else { 
00494         ST* fldSt_p=ST_ptr(fldStIdx);
00495         //      std::cout << "\tJU: equivalencedToActive: looking at fld " << eqInst <<  ":" << fld.Idx() << ":" << ST_name(fldSt_p) << ":" << offset << std::endl;  
00496         if (ctxt.isActiveSym(fldSt_p)) 
00497           return true;
00498       } 
00499       fld = TY_Lookup_FLD(baseTypeIndex, 0, offset,++eqInst);
00500     }
00501     return false; 
00502   } 
00503 
00504   static bool equivalencedToActiveBlock(ST* st,
00505                                         PUXlationContext& ctxt) { 
00506     // find what we are equivalence to:
00507     TY_IDX baseTypeIndex = ST_type(ST_base(st));
00508     mUINT64 offset = ST_ofst(st); // offset into base symbol
00509     // find field with correct offset or symbol
00510     FLD_HANDLE fld = TY_Lookup_FLD(baseTypeIndex, 0, offset);
00511     ST_IDX fldStIdx=FLD_st(fld);
00512     //    std::cout << "\tJU: equivalencedToActiveBlock: looking at fld " << 1 <<  ":" << fld.Idx() << ":" << FLD_name(fld) << ":" << offset;  
00513     if (!fldStIdx) { 
00514       //      std::cout << "\tJU: equivalencedToActiveBlock: no FLD st"  << std::endl;
00515     }
00516     else {  
00517       //      std::cout << "\tJU: equivalencedToActiveBlock: have FLD st"  << std::endl;
00518       ST* fldSt_p=ST_ptr(fldStIdx);
00519       if (ctxt.isActiveSym(fldSt_p)) 
00520         return true;
00521     } 
00522     return false; 
00523   } 
00524 
00525   static bool activeInCommon(ST* st,
00526                              PUXlationContext& ctxt) { 
00527     // see if there is anything else 
00528     // active in this common block 
00529     TY_IDX tyIdx = ST_type(ST_base(st));
00530     TY& ty = Ty_Table[tyIdx];
00531     FLD_HANDLE fldlist=TY_flist(ty);
00532     FLD_ITER fld_iter = Make_fld_iter(fldlist);
00533     do {
00534       FLD_HANDLE fld (fld_iter);
00535       ST_IDX fldStIdx=FLD_st(fld);
00536       //      std::cout << "\tJU: activeInCommon: looking at fld " << 1 <<  ":" << fld.Idx() << ":" << FLD_name(fld) << ":" << FLD_ofst(fld);  
00537       if (!fldStIdx) { 
00538         //      std::cout << "\tJU: activeInCommon: no FLD st"  << std::endl;
00539         ;
00540       }
00541       else {  
00542         //      std::cout << "\tJU: activeInCommon: have FLD st"  << std::endl;
00543         ST* fldSt_p=ST_ptr(fldStIdx);
00544         if (ctxt.isActiveSym(fldSt_p)) 
00545           return true; 
00546       }
00547     } while (!FLD_last_field (fld_iter++)) ;
00548     return false;
00549   }
00550 
00551   static void 
00552   xlate_STDecl_VAR(xml::ostream& xos, ST *st, PUXlationContext& ctxt) {  
00553     FORTTK_ASSERT(ST_class(st) == CLASS_VAR, fortTkSupport::Diagnostics::UnexpectedInput);
00554     const char* st_name = ST_name(st);
00555     ST* base = ST_base(st);
00556     TY_IDX ty = ST_type(st);
00557     bool translatenow = false;
00558     if (Stab_Is_Common_Block(st)) {
00559       TY2F_Translate_Common(xos, st_name, ty); 
00560     } 
00561     else if (ST_sclass(st) == SCLASS_FORMAL && !ST_is_value_parm(st)) {
00562       // A procedure parameter (we expect a pointer TY to counteract the
00563       // Fortran call-by-reference semantics)
00564       FORTTK_ASSERT((TY_Is_Pointer(ty)|| TY_is_f90_pointer(ty)), "Unexpected type " << TY_kind(ty) << " for " << st_name);
00565     
00566       TY_IDX base_ty = TY_pointed(ty);
00567       if (TY_Is_Pointer(base_ty) && TY_ptr_as_array(Ty_Table[base_ty])) {
00568         /* FIXME: Handle ptr as array parameters */ 
00569         ty = Stab_Array_Of(TY_pointed(base_ty), 0/*size*/);
00570       } 
00571       else {
00572         ty = base_ty;
00573       }
00574       translatenow = true;
00575     } 
00576     else {
00577       translatenow = true;
00578     }
00579     if (translatenow) { // FIXME
00580       bool isPointer = TY_Is_Pointer(ty) || TY_is_f90_pointer(ty);
00581       bool isFnPointer = isPointer && (TY_kind(TY_pointed(ty)) == KIND_FUNCTION);
00582       const char* ty_str = (isPointer && (!isFnPointer)) ? TranslateTYToSymType(TY_pointed(ty))
00583                                      : TranslateTYToSymType(ty);
00584       if (!ty_str) { ty_str = "***"; }
00585       const char* shape_str = (isPointer && (!isFnPointer)) ? TranslateTYToSymShape(TY_pointed(ty))
00586                                         : TranslateTYToSymShape(ty);
00587       if (!shape_str) { shape_str = "***"; }
00588       int active = (ctxt.isActiveSym(st)) ? 1 : 0;
00589       if (Args::ourUniformCBactFlag && !active && Stab_Is_Valid_Base(st)) { 
00590         if (ST_is_equivalenced(st)) { 
00591           active=equivalencedToActive(st,ctxt);
00592         } 
00593         if (!active && Stab_Is_Equivalence_Block(ST_base(st))) {
00594           active=equivalencedToActiveBlock(st,ctxt);
00595         }
00596         if (!active && Stab_Is_Common_Block(ST_base(st))) {
00597           active=activeInCommon(st,ctxt);
00598         }
00599         if (active) { 
00600           if ((strcmp(ty_str, "integer") == 0
00601                ||
00602                strcmp(ty_str, "string") == 0)) { 
00603             static const char* txt1 = "cannot activate equivalenced of common block symbol >";
00604             static const char* txt2 = "< of type ";
00605             if (CURRENT_SYMTAB == GLOBAL_SYMTAB) {
00606               FORTTK_MSG(0, "warning: within global scope: " << txt1 << ST_name(st) << txt2 << ty_str);
00607             }
00608             else {
00609               ST_IDX pu_st = PU_Info_proc_sym(Current_PU_Info);
00610               FORTTK_MSG(0, "warning: within " << ST_name(pu_st) << ": " << txt1 << ST_name(st) << txt2  << ty_str);
00611             }
00612           }
00613           else {
00614             static const char* txt1 = "activating symbol >";
00615             static const char* txt2 = "< of type ";
00616             if (CURRENT_SYMTAB == GLOBAL_SYMTAB) {
00617               FORTTK_MSG(1, "within global scope: " << txt1 << ST_name(st) << txt2 << ty_str);
00618             }
00619             else {
00620               ST_IDX pu_st = PU_Info_proc_sym(Current_PU_Info);
00621               FORTTK_MSG(1, "within " << ST_name(pu_st) << ": " << txt1 << ST_name(st) << txt2  << ty_str);
00622             }
00623           }
00624         }
00625       } 
00626       if (Args::ourAllActiveFlag 
00627           && 
00628           !active 
00629           && 
00630           ((strcmp(ty_str, "real") == 0
00631             ||
00632             strcmp(ty_str, "complex") == 0))
00633           &&  
00634           !(ST_sclass(st) == SCLASS_PSTATIC 
00635             &&
00636             ST_is_initialized(st))
00637           ) {
00638         active=true;
00639       }
00640       if (active 
00641           && 
00642           (strcmp(ty_str, "integer") == 0
00643            ||
00644            strcmp(ty_str, "string") == 0)) {
00645         active = false;
00646         static const char* txt1 = "deactivating symbol >";
00647         static const char* txt2 = "< of type ";
00648         if (CURRENT_SYMTAB == GLOBAL_SYMTAB) {
00649           FORTTK_MSG(0, "warning: within global scope: " << txt1 << ST_name(st) << txt2 << ty_str);
00650         }
00651         else {
00652           ST_IDX pu_st = PU_Info_proc_sym(Current_PU_Info);
00653           FORTTK_MSG(0, "warning: within " << ST_name(pu_st) << ": " << txt1 << ST_name(st) << txt2  << ty_str);
00654         }
00655       }
00656       if (active 
00657           && 
00658           (ST_sclass(st) == SCLASS_PSTATIC 
00659             &&
00660            ST_is_initialized(st))) { 
00661         static const char* txt1 = "explicit initialization of active symbol >";
00662         static const char* txt2 = "< implies the active type may not use default initialization";
00663         if (CURRENT_SYMTAB == GLOBAL_SYMTAB) {
00664           FORTTK_MSG(0, "warning: within global scope: " << txt1 << ST_name(st) << txt2 );
00665         }
00666         else {
00667           ST_IDX pu_st = PU_Info_proc_sym(Current_PU_Info);
00668           FORTTK_MSG(0, "warning: within " << ST_name(pu_st) << ": " << txt1 << ST_name(st) << txt2 );
00669         }
00670       }
00671       fortTkSupport::SymId st_id = (fortTkSupport::SymId)ST_index(st);
00672 
00673       xos << xml::BegElem("xaif:Symbol") << AttrSymId(st);
00674       if (isFnPointer) {
00675         xos << xml::Attr("kind", "pointer");
00676       } 
00677       else {
00678         xos << xml::Attr("kind", "variable");
00679       }
00680       xos << xml::Attr("type", ty_str)
00681           << xml::Attr("feType",TranslateTYToMType(ty))
00682           << xml::Attr("shape", shape_str) 
00683           << SymIdAnnot(st_id)
00684           << xml::Attr("active", active);
00685       if (isPointer) {
00686         xos << xml::Attr("pointer", isPointer);
00687       }
00688       xos << xml::EndAttrs;
00689       xlate_ArrayBounds(xos, ty, ctxt);
00690       xos << xml::EndElem;
00691     }
00692   }
00693 
00694   static void 
00695   xlate_STDecl_FUNC(xml::ostream& xos, ST* st, PUXlationContext& ctxt)
00696   {
00697     // This only makes sense for "external" functions in Fortran,
00698     // while we should not do anything for other functions.
00699     FORTTK_ASSERT(ST_class(st) == CLASS_FUNC, fortTkSupport::Diagnostics::UnexpectedInput);
00700 
00701     fortTkSupport::SymId st_id = (fortTkSupport::SymId)ST_index(st);
00702     xos << xml::BegElem("xaif:Symbol") << AttrSymId(st)
00703         << xml::Attr("kind", "subroutine") << xml::Attr("type", "void")
00704         << SymIdAnnot(st_id) << xml::EndElem;
00705 
00706   }
00707 
00708   static void 
00709   xlate_STDecl_CONST(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00710   {
00711     //xos << BegComment << "const id=" << (UINT)ST_index(st) << EndComment;
00712   }
00713 
00714   static void 
00715   xlate_STDecl_PREG(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00716   {
00717     TY_IDX ty = ST_type(st);
00718     const char* ty_str = TranslateTYToSymType(ty);
00719     if (!ty_str) { 
00720       return; // skip [FIXME -- better hope this is not used!]
00721     }
00722   
00723     fortTkSupport::SymId st_id = (fortTkSupport::SymId)ST_index(st);
00724     xos << xml::BegElem("xaif:Symbol") << AttrSymId(st)
00725         << xml::Attr("kind", "variable") << xml::Attr("type", ty_str)
00726         << xml::Attr("shape", "scalar") << SymIdAnnot(st_id)
00727         << xml::Attr("active", 0) << xml::EndElem;
00728   }
00729 
00730   static void 
00731   xlate_STDecl_BLOCK(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00732   {
00733     //xos << BegComment << "block id=" << (UINT)ST_index(st) << EndComment;
00734   }
00735 
00736   static void 
00737   xlate_STDecl_NAME(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00738   {
00739     //xos << BegComment << "name id=" << (UINT)ST_index(st) << EndComment;
00740   }
00741 
00742   static void 
00743   xlate_STDecl_TYPE(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00744   {
00745     FORTTK_ASSERT(ST_class(st) == CLASS_TYPE, fortTkSupport::Diagnostics::UnexpectedInput);
00746 
00747     const char  *st_name = ST_name(st);
00748     TY_IDX       ty_rt = ST_type(st);
00749  
00750 #if 0 // FIXME 
00751     xos << BegComment << "type id=" << (UINT)ST_index(st) << EndComment; 
00752     TY2F_translate(xos, ST_type(st), 1, ctxt);
00753 #endif
00754   }
00755 
00756   // ***************************************************************************
00757   // 
00758   // ***************************************************************************
00759 
00760   static void 
00761   xlate_STUse_error(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00762   {
00763     FORTTK_DIE("Unknown ST_CLASS " << ST_class(st));
00764   }
00765 
00766   static void 
00767   xlate_STUse_VAR(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00768   {
00769     FORTTK_ASSERT(ST_class(st) == CLASS_VAR, fortTkSupport::Diagnostics::UnexpectedInput);
00770 
00771     // Note: for functions, check that st is a return var using
00772     //   ST_is_return_var(st)) (cf. whirl2f)
00773 
00774 #if 0 // FIXME xlate_SymRef moves from 'base' to 'field' (cannot reciprocate)
00775     if (Stab_Is_Based_At_Common_Or_Equivalence(st)) {
00776       /* Reference the corresponding field in the common block (we do this
00777        * only to ensure that the name referenced matches the one used for
00778        * the member of the common-block at the place of declaration).  Note
00779        * that will full splitting, the original common block can be found
00780        * at ST_full(ST_base(st)).
00781        */
00782       xlate_SymRef(xos, ST_base(st) /*base-symbol*/,
00783                    Stab_Pointer_To(ST_type(ST_base(st))), /*base-type*/
00784                    ST_type(st) /*object-type*/, 
00785                    ST_ofst(st) /*object-ofst*/, ctxt);
00786     }
00787     //else {
00788 #endif
00789   
00790     // FIXME: abstract
00791     ST_TAB* sttab = Scope_tab[ST_level(st)].st_tab;
00792    fortTkSupport::SymTabId scopeid = ctxt.findSymTabId(sttab);
00793   
00794     xos << xml::BegElem("xaif:SymbolReference") 
00795         << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId())
00796         << xml::Attr("scope_id", scopeid) << AttrSymId(st) << xml::EndElem;
00797   }
00798 
00799 
00800   static void 
00801   xlate_STUse_CONST(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00802   {
00803     FORTTK_ASSERT(ST_class(st) == CLASS_CONST, fortTkSupport::Diagnostics::UnexpectedInput);
00804   
00805     // A CLASS_CONST symbol never has a name, so just emit the value.
00806     TY_IDX ty_idx = ST_type(st);
00807     TY& ty = Ty_Table[ty_idx];
00808   
00809     std::string val;
00810     if (TY_mtype(ty) == MTYPE_STR && TY_align(ty_idx) > 1) {
00811       val = TCON2F_hollerith(STC_val(st)); // must be a hollerith constant
00812     } else {
00813       val = TCON2F_translate(STC_val(st), TY_is_logical(ty));
00814     }
00815   
00816     const char* ty_str = TranslateTYToSymType(ty_idx);
00817     if (!ty_str) { ty_str = "***"; }  
00818 
00819     xos << xml::BegElem("xaif:Constant") 
00820         << xml::Attr("vertex_id", ctxt.currentXlationContext().getNewVertexId()) 
00821         << xml::Attr("type", ty_str) 
00822         << xml::Attr("feType",TranslateTYToMType(ty_idx))
00823         << xml::Attr("value", val) << xml::EndElem;
00824   }
00825 
00826 
00827   static void 
00828   xlate_STUse_BLOCK(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00829   {
00830     /* with f90 at -O2, CLASS_BLOCK can appear on LDAs etc. in IO */
00831     /* put out something, so whirlbrowser doesn't fall over       */
00832     FORTTK_ASSERT(ST_class(st) == CLASS_BLOCK, fortTkSupport::Diagnostics::UnexpectedInput);
00833   
00834     xos << xml::BegElem("***use_block") << xml::Attr("id", ctxt.currentXlationContext().getNewVertexId()) 
00835         << xml::Attr("_type", -1) << xml::Attr("value", ST_name(st)) << xml::EndElem;
00836   } 
00837 
00838 
00839   // ***************************************************************************
00840   // 
00841   // ***************************************************************************
00842 
00843   /*------------------------ exported routines --------------------------*/
00844 
00845   void 
00846   ST2F_deref_translate(xml::ostream& xos, ST *st, PUXlationContext& ctxt)
00847   {
00848     FORTTK_ASSERT(ST_sym_class(st)==CLASS_VAR && 
00849                   TY_Is_Pointer(ST_type(st)) &&
00850                   !Stab_Is_Based_At_Common_Or_Equivalence(st), 
00851                   fortTkSupport::Diagnostics::UnexpectedInput << ST_class(st));
00852   
00853     /* reference to the pointer value; cf. W2CF_Symtab_Nameof_St_Pointee */
00854     xos << "{deref***} " << "deref_" << ST_name(st);
00855   }
00856 
00857 
00858   void 
00859   ST2F_Declare_Tempvar(TY_IDX ty, UINT idx)
00860   {
00861 #if 0 // FIXME
00862     xml::ostream& tmp_tokens = New_Token_Buffer();
00863     UINT         current_indent = 0; //FIXME Current_Indentation();
00864 
00865     Append_F77_Indented_Newline(PUinfo_local_decls, 1, NULL/*label*/);
00866     if (TY_Is_Pointer(ty))
00867       {
00868         /* Assume we never need to dereference the pointer, or else we
00869          * need to maintain a map from tmp_idx->pointee_idx (new temporary
00870          * for pointee_idx), so declare this temporary variable to be of
00871          * an integral type suitable for a pointer value.
00872          */
00873         ty = Stab_Mtype_To_Ty(Pointer_Mtype);
00874       }
00875     tmp_tokens << "tmp" << idx; /* name */
00876     TY2F_translate(tmp_tokens, ty);                                   /* type */
00877     if (ST_is_in_module(Scope_tab[Current_scope].st) &&
00878         !PU_is_nested_func(Pu_Table[ST_pu(Scope_tab[Current_scope].st)]))
00879       {
00880         Append_F77_Indented_Newline(tmp_tokens, 1, NULL/*label*/);
00881         Append_Token_String(tmp_tokens,"PRIVATE ");
00882         tmp_tokens << "tmp" << idx;
00883       }
00884 
00885     Append_And_Reclaim_Token_List(PUinfo_local_decls, &tmp_tokens);
00886     Set_Current_Indentation(current_indent);
00887 #endif
00888   } /* ST2F_Declare_Tempvar */
00889 
00890 
00891   static BOOL
00892   ST2F_Is_Dummy_Procedure(ST *st)
00893   {
00894     /* Does this ST represent a dummy procedure ? */
00895     BOOL dummy = FALSE;
00896     if (ST_sclass(st) == SCLASS_FORMAL && ST_is_value_parm(st)) {
00897       TY_IDX ty = ST_type(st);
00898       if (TY_kind(ty) == KIND_POINTER
00899           && TY_kind(TY_pointed(ty)) == KIND_FUNCTION) {
00900         dummy = TRUE;
00901       }
00902     }
00903     return dummy;
00904   }
00905 
00906 
00907   static void
00908   ST2F_Declare_Return_Type(xml::ostream& xos, TY_IDX return_ty, 
00909                            PUXlationContext& ctxt)
00910   {
00911     // The TY represents a dummy procedure or a function return type
00912     if ( (return_ty != (TY_IDX)0) && (TY_kind(return_ty) != KIND_VOID) ) {
00913       /* Use integral type for pointer returns */
00914       if (TY_Is_Pointer(return_ty))
00915         TY2F_translate(xos, Stab_Mtype_To_Ty(TY_mtype(return_ty)), ctxt);
00916       else
00917         TY2F_translate(xos, return_ty, ctxt);
00918     }
00919   }
00920 
00921 
00922 
00923 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines