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