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