|
OpenADFortTk (basic)
|
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 }