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 * 07-Oct-94 - Original Version 00042 * 00043 * Description: 00044 * 00045 * Translates initializers (INITOs) to C. Exports the 00046 * function: 00047 * 00048 * INITO2C_translate() 00049 * 00050 * ==================================================================== 00051 * ==================================================================== 00052 */ 00053 #ifdef _KEEP_RCS_ID 00054 #endif /* _KEEP_RCS_ID */ 00055 00056 #include "whirl2c_common.h" 00057 #include "st2c.h" 00058 #include "ty2c.h" 00059 #include "tcon2c.h" 00060 #include "init2c.h" 00061 00062 00063 /* Hidden Utility functions */ 00064 /*--------------------------*/ 00065 00066 #define INITV_repeat(x) \ 00067 ((INITV_kind(Initv_Table[x]) == INITVKIND_ZERO || \ 00068 INITV_kind(Initv_Table[x]) == INITVKIND_ONE || \ 00069 INITV_kind(Initv_Table[x]) == INITVKIND_VAL) ? \ 00070 INITV_repeat2(Initv_Table[x]) : INITV_repeat1(Initv_Table[x])) 00071 00072 inline TCON 00073 TCON_For_Initv(INITV_IDX initv) 00074 { 00075 TCON tcon; 00076 00077 switch (INITV_kind(initv)) 00078 { 00079 case INITVKIND_ZERO: 00080 tcon = Host_To_Targ(INITV_mtype(Initv_Table[initv]), 0); 00081 break; 00082 case INITVKIND_ONE: 00083 tcon = Host_To_Targ(INITV_mtype(Initv_Table[initv]), 1); 00084 break; 00085 case INITVKIND_VAL: 00086 tcon = INITV_tc_val(Initv_Table[initv]); 00087 break; 00088 default: 00089 Is_True(FALSE, ("Unexpected initv kind in TCON_For_Initv()")); 00090 break; 00091 } 00092 return tcon; 00093 } /* TCON_For_Initv */ 00094 00095 static void 00096 INIT2C_Next_Initv(INITV_IDX *inv, INT *inv_repeat) 00097 { 00098 /* Get the next initializer. 00099 */ 00100 (*inv_repeat)--; 00101 if (*inv_repeat <= 0) 00102 { 00103 *inv = INITV_next(*inv); 00104 *inv_repeat = (*inv != 0) ? INITV_repeat(*inv) : 0; 00105 } 00106 } /* INIT2C_Next_Initv */ 00107 00108 00109 static void 00110 INITV2C_translate(TOKEN_BUFFER tokens, 00111 TY_IDX ty, 00112 INITV_IDX initv); /* Defined below */ 00113 00114 static void 00115 INITV2C_symoff(TOKEN_BUFFER tokens, 00116 TY_IDX ty, 00117 INITV_IDX initv) 00118 { 00119 /* Translate a INITVKIND_SYMOFF to C, ignoring repeats, where 00120 * the data location being initialized is typed as "ty". 00121 */ 00122 TOKEN_BUFFER tmp_tokens; 00123 CONTEXT dummy_context; 00124 BOOL use_implicit_array_addressing, casted_address; 00125 ST_IDX initv_st = INITV_st(Initv_Table[initv]); 00126 TY_IDX sym_ty = (ST_class(initv_st) == CLASS_FUNC) ? 00127 ST_pu_type(initv_st) : ST_type(initv_st); 00128 TY2C_FLD_INFO fld_info; 00129 fld_info.select_tokens = NULL; 00130 fld_info.found_fld = FLD_HANDLE(); 00131 Is_True(TY_Is_Pointer_Or_Scalar(ty)||TY_Is_Array(ty) 00132 || TY_Is_Struct(ty) , 00133 ("Unexpected lhs type in INITV2C_symoff()")); 00134 Is_True(ST_sym_class(St_Table[initv_st]) != CLASS_PREG, 00135 ("Unexpected st class in INITV2C_symoff()")); 00136 /* See if we can use implicit array addressing (only relevant for 00137 * zero offset). 00138 */ 00139 use_implicit_array_addressing = 00140 (TY_Is_Pointer(ty) && 00141 TY_Is_Array(sym_ty) && 00142 Stab_Identical_Types(TY_pointed(ty), 00143 TY_AR_etype(sym_ty), 00144 FALSE, /*check_quals*/ 00145 TRUE, /*check_scalars*/ 00146 FALSE)); /*ptrs_as_scalars*/ 00147 00148 /* When using implicit_array_addressing, the symbol we address 00149 * is an element of the array. 00150 */ 00151 if (use_implicit_array_addressing) 00152 sym_ty = TY_AR_etype(sym_ty); 00153 00154 /* Generate a type cast to a non-pointer or incompatible pointer 00155 * type. 00156 */ 00157 casted_address = (!use_implicit_array_addressing && 00158 (!TY_Is_Pointer(ty) || 00159 !Stab_Identical_Types(TY_pointed(ty), 00160 sym_ty, 00161 FALSE, /*check_quals*/ 00162 TRUE, /*check_scalars*/ 00163 FALSE))); /*ptrs_as_scalars*/ 00164 00165 /* Since this function is used to dumpout the constant string 00166 * we don't need to add the prefix of type to each element. 00167 *--------fzhao 00168 */ 00169 # if 0 00170 if (casted_address) 00171 { 00172 tmp_tokens = New_Token_Buffer(); 00173 TY2C_translate_unqualified(tmp_tokens, ty); 00174 WHIRL2C_parenthesize(tmp_tokens); 00175 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00176 } 00177 #endif 00178 00179 /* Get the address expression */ 00180 tmp_tokens = New_Token_Buffer(); 00181 CONTEXT_reset(dummy_context); 00182 if (INITV_ofst(Initv_Table[initv]) == 0) 00183 { 00184 if (ST_sym_class(St_Table[initv_st]) == CLASS_CONST) 00185 { 00186 TCON2C_translate(tmp_tokens, STC_val(&St_Table[initv_st])); 00187 } 00188 else 00189 { 00190 if (!use_implicit_array_addressing) 00191 Append_Token_Special(tmp_tokens, '&'); 00192 ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context); 00193 } 00194 } 00195 else if (INITV_ofst(Initv_Table[initv]) % TY_size(sym_ty) == 0) 00196 { 00197 /* Use indexing expression to do the address calculation */ 00198 ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context); 00199 Prepend_Token_Special(tmp_tokens, '&'); 00200 00201 Append_Token_Special(tmp_tokens, '['); 00202 Append_Token_String(tmp_tokens, 00203 Number_as_String(INITV_ofst(Initv_Table[initv])/TY_size(sym_ty), "%lld")); 00204 Append_Token_Special(tmp_tokens, ']'); 00205 } 00206 else /* Need to use byte or struct offsets */ 00207 { 00208 /* We fall into this case for struct selection and 00209 * more complex expression, such as "a[17].field3[21]". 00210 */ 00211 ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context); 00212 Prepend_Token_Special(tmp_tokens, '&'); 00213 00214 if (TY_Is_Struct(sym_ty) && TY_Is_Pointer(ty)) 00215 { 00216 /* Try to use field selection */ 00217 fld_info = TY2C_get_field_info(sym_ty, 00218 TY_pointed(ty), 00219 MTYPE_V, /* Only find field of ty */ 00220 INITV_ofst(Initv_Table[initv])); 00221 if (!fld_info.found_fld.Is_Null ()) 00222 { 00223 Append_Token_Special(tmp_tokens, '.'); 00224 Append_And_Reclaim_Token_List(tmp_tokens, &fld_info.select_tokens); 00225 } 00226 } 00227 00228 if (fld_info.found_fld.Is_Null ()) 00229 { 00230 /* Cast to a (char*), do offset calculation, and cast to (void*) */ 00231 Prepend_Token_Special(tmp_tokens, ')'); 00232 Prepend_Token_Special(tmp_tokens, '*'); 00233 Prepend_Token_String(tmp_tokens, "char"); 00234 Prepend_Token_Special(tmp_tokens, '('); 00235 Append_Token_Special(tmp_tokens, '+'); 00236 Append_Token_String(tmp_tokens, 00237 Number_as_String(INITV_ofst(Initv_Table[initv]), 00238 "%lld")); 00239 WHIRL2C_parenthesize(tmp_tokens); 00240 if (!casted_address) 00241 { 00242 WHIRL2C_parenthesize(tmp_tokens); 00243 Prepend_Token_Special(tmp_tokens, ')'); 00244 Prepend_Token_Special(tmp_tokens, '*'); 00245 Prepend_Token_String(tmp_tokens, "void"); 00246 Prepend_Token_Special(tmp_tokens, '('); 00247 } 00248 } 00249 } 00250 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00251 } /* INITV2C_symoff */ 00252 00253 static void 00254 INITV2C_symoff_help(TOKEN_BUFFER tokens, 00255 TY_IDX ty, 00256 INITV_IDX initv) 00257 { 00258 TCON tcon; 00259 INITV_IDX next_initv; 00260 00261 if (TY_Is_Structured(ty)) { 00262 Append_Token_Special(tokens,'{'); 00263 INITV2C_symoff(tokens, ty, initv); 00264 next_initv = INITV_next(initv); 00265 while(next_initv !=0){ 00266 if(INITV_kind (next_initv)== INITVKIND_VAL){ 00267 Append_Token_Special(tokens,','); 00268 tcon = TCON_For_Initv(next_initv); 00269 TCON2C_translate(tokens, tcon); 00270 } 00271 else 00272 if(INITV_kind (next_initv)== INITVKIND_SYMOFF){ 00273 Append_Token_Special(tokens,','); 00274 INITV2C_symoff(tokens, ty, next_initv); 00275 00276 } 00277 00278 next_initv = INITV_next(next_initv); 00279 } 00280 Append_Token_Special(tokens,'}'); 00281 } 00282 else if (TY_Is_Array(ty)) { 00283 Append_Token_Special(tokens,'{'); 00284 INITV2C_symoff(tokens, ty, initv); 00285 next_initv = INITV_next(initv); 00286 while(next_initv !=0){ 00287 if(INITV_kind (next_initv)== INITVKIND_VAL){ 00288 Append_Token_Special(tokens,','); 00289 tcon = TCON_For_Initv(next_initv); 00290 TCON2C_translate(tokens, tcon); 00291 } else 00292 if(INITV_kind (next_initv)== INITVKIND_SYMOFF){ 00293 Append_Token_Special(tokens,','); 00294 INITV2C_symoff(tokens, ty, next_initv); 00295 00296 } 00297 00298 next_initv = INITV_next(next_initv); 00299 } 00300 Append_Token_Special(tokens,'}'); 00301 } 00302 else 00303 00304 INITV2C_symoff(tokens, ty, initv); 00305 00306 } 00307 00308 00309 00310 static void 00311 INITV2C_val(TOKEN_BUFFER tokens, 00312 TY_IDX ty, 00313 INITV_IDX initv) 00314 { 00315 /* Translate an INITVKIND_ZERO, INITVKIND_ONE, or INITVKIND_VAL to C, 00316 * ignoring repeats, where the data location being initialized is 00317 * typed as "ty". 00318 */ 00319 TOKEN_BUFFER tmp_tokens; 00320 TCON tcon = TCON_For_Initv(initv); 00321 INITV_IDX next_initv; 00322 00323 // "struct" and "union" variables appeared in the Tcons if declared as "static" variables 00324 // and "array" variable too---fzhao 00325 00326 Is_True(TY_Is_Pointer_Or_Scalar(ty) || TY_Is_Array_Of_Chars(ty) || 00327 TY_Is_Structured(ty)|| TY_Is_Array(ty), 00328 ("Unexpected lhs type in INITV2C_val()")); 00329 00330 /* Make sure the types are assignment compatible, by casting pointer 00331 * constants when necessary. No casting is necessary for NULL 00332 * pointers. 00333 */ 00334 if (TY_Is_Pointer(ty) && Targ_To_Host(tcon) != 0LL) 00335 { 00336 tmp_tokens = New_Token_Buffer(); 00337 TY2C_translate_unqualified(tmp_tokens, ty); 00338 WHIRL2C_parenthesize(tmp_tokens); 00339 Append_And_Reclaim_Token_List(tokens, &tmp_tokens); 00340 } 00341 00342 00343 /* Translate the constant value */ 00344 00345 /* If the type is struct,then there might be more than 00346 one constant values in this INITO table entry,dumpout 00347 all the values-----fzhao 00348 */ 00349 if (TY_Is_Structured(ty)) { 00350 Append_Token_Special(tokens,'{'); 00351 TCON2C_translate(tokens, tcon); 00352 next_initv = INITV_next(initv); 00353 while(next_initv !=0){ 00354 if(INITV_kind (next_initv)== INITVKIND_VAL) { 00355 Append_Token_Special(tokens,','); 00356 tcon = TCON_For_Initv(next_initv); 00357 TCON2C_translate(tokens, tcon); 00358 } 00359 next_initv = INITV_next(next_initv); 00360 } 00361 Append_Token_Special(tokens,'}'); 00362 } 00363 else if (TY_Is_Array(ty)) { 00364 Append_Token_Special(tokens,'{'); 00365 TCON2C_translate(tokens, tcon); 00366 next_initv = INITV_next(initv); 00367 while(next_initv !=0){ 00368 if(INITV_kind (next_initv)== INITVKIND_VAL) { 00369 Append_Token_Special(tokens,','); 00370 tcon = TCON_For_Initv(next_initv); 00371 TCON2C_translate(tokens, tcon); 00372 } 00373 next_initv = INITV_next(next_initv); 00374 } 00375 Append_Token_Special(tokens,'}'); 00376 } 00377 else 00378 TCON2C_translate(tokens, tcon); 00379 00380 } /* INITV2C_val */ 00381 00382 00383 static void 00384 INITV2C_array_dimension(TOKEN_BUFFER tokens, 00385 TY_IDX etype, 00386 INITV_IDX next_initv, 00387 INT this_dim, /* one based dimension */ 00388 INT num_dims) 00389 { 00390 INITV_IDX inv; 00391 INT repeat; 00392 00393 /* The front-end may generate multi-dimensional arrays for arrays 00394 * of arrays. 00395 * 00396 * Walk through the list of (comma separated) initializers 00397 * for the aggregate initializer, ignoring padding. 00398 */ 00399 Append_Token_Special(tokens, '{'); 00400 for (inv = next_initv; inv != 0; inv = INITV_next(inv)) 00401 { 00402 /* Handle repetitions */ 00403 for (repeat = INITV_repeat(inv); repeat > 0; repeat--) 00404 { 00405 if (INITV_kind(Initv_Table[inv]) != INITVKIND_PAD) 00406 { 00407 /* Avoid preceeding the first initializer with a comma */ 00408 if (inv != next_initv || repeat < INITV_repeat(inv)) 00409 Append_Token_Special(tokens, ','); 00410 00411 if (this_dim < num_dims && 00412 INITV_kind(Initv_Table[inv]) == INITVKIND_BLOCK) 00413 INITV2C_array_dimension(tokens, 00414 etype, 00415 INITV_blk(inv), 00416 this_dim+1, 00417 num_dims); 00418 else 00419 INITV2C_translate(tokens, etype, inv); 00420 } /* if */ 00421 } /* for */ 00422 } /* for */ 00423 Append_Token_Special(tokens, '}'); 00424 } /* INITV2C_array_dimension */ 00425 00426 00427 static void 00428 INITV2C_block_array(TOKEN_BUFFER tokens, 00429 TY_IDX ty, 00430 INITV_IDX initv) 00431 { 00432 /* Translate a INITVKIND_BLOCK for an array to C, where the 00433 * location being initialized is typed as "ty" (KIND_ARRAY). 00434 */ 00435 INITV_IDX first_inv = INITV_blk(initv); 00436 TY_IDX etype = TY_AR_etype(ty); 00437 INT ndims = TY_AR_ndims(ty); 00438 00439 if (!TY_Is_Array(etype) && !TY_Is_String(etype) && 00440 INITV_kind(Initv_Table[first_inv]) == INITVKIND_VAL && 00441 TCON_ty(INITV_tc_val(Initv_Table[first_inv])) == MTYPE_STRING) 00442 { 00443 Is_True((TY_size(ty) == 00444 Targ_String_Length(INITV_tc_val(Initv_Table[first_inv]))) || 00445 (INITV_next(first_inv) != 0 && 00446 INITV_kind(Initv_Table[INITV_next(first_inv)]) == INITVKIND_PAD), 00447 ("Expected padding to follow incomplete string initializer")); 00448 INITV2C_translate(tokens, ty, first_inv); 00449 } 00450 else /* Not incomplete string initializer */ 00451 { 00452 if (first_inv != 0 && 00453 INITV_kind(Initv_Table[first_inv]) == INITVKIND_PAD && 00454 INITV_next(first_inv) == 0) 00455 { 00456 /* Handle the special case of just having padding as an 00457 * initializer. 00458 */ 00459 Append_Token_Special(tokens, '{'); 00460 Append_Token_String(tokens, "0L"); 00461 Append_Token_Special(tokens, '}'); 00462 } 00463 else 00464 { 00465 INITV2C_array_dimension(tokens, etype, first_inv, 1, ndims); 00466 } /* if */ 00467 } /* if */ 00468 } /* INITV2C_block_array */ 00469 00470 00471 static void 00472 INITV2C_struct_fill(TOKEN_BUFFER tokens, 00473 INITV_IDX *current_inv, 00474 INT *inv_repeat, 00475 INT64 *current_offset, 00476 INT64 desired_offset) 00477 { 00478 /* Using the inv sequence of initializers, initialize 00479 * a byte-array with bytes up to the desired offset. 00480 * Thus, the number of bytes initialized will be limited 00481 * by the inv list and the "desired_offset-current_offset". 00482 * Padding will be viewed as zero initializers. Update 00483 * the current_inv, the inv_repeat, and the current_offset. 00484 */ 00485 union Tcon_Bytes 00486 { 00487 struct 00488 { 00489 UINT32 u1; 00490 UINT32 u2; 00491 UINT32 u3; 00492 UINT32 u4; 00493 UINT32 u5; 00494 UINT32 u6; 00495 UINT32 u7; 00496 UINT32 u8; 00497 } val; 00498 mUINT8 byte[32]; 00499 } tcon_bytes; 00500 00501 INT pad_byte; 00502 INT tcon_size; 00503 TCON tcon; 00504 00505 Is_True(*current_inv != 0 && *current_offset < desired_offset, 00506 ("Incorrect call to INITV2C_struct_fill()")); 00507 00508 Append_Token_Special(tokens, '{'); 00509 while (*current_offset < desired_offset && *current_inv != 0) 00510 { 00511 /* Expect only padding and integral val INITVs */ 00512 switch (INITV_kind(Initv_Table[*current_inv])) 00513 { 00514 case INITVKIND_UNK: 00515 Is_True(FALSE, ("Unknown initv kind in INITV2C_struct_fill()")); 00516 break; 00517 00518 case INITVKIND_SYMOFF: 00519 Is_True(FALSE, ("SYMOFF initv kind in INITV2C_struct_fill()")); 00520 break; 00521 00522 case INITVKIND_ZERO: 00523 case INITVKIND_ONE: 00524 case INITVKIND_VAL: 00525 tcon = TCON_For_Initv(*current_inv); 00526 tcon_size = TY_size(Stab_Mtype_To_Ty(TCON_ty(tcon))); 00527 if (tcon_size < sizeof(tcon.vals.uval.u0)) 00528 { 00529 /* Shift the relevant bytes into the appropriate position */ 00530 tcon_bytes.val.u1 = 00531 (tcon.vals.uval.u0 << 00532 8*(sizeof(tcon.vals.uval.u0) - tcon_size)); 00533 } 00534 else 00535 { 00536 /* Assign all eight 32 bits words of the tcon value to 00537 * tcon_bytes. 00538 */ 00539 tcon_bytes.val.u1 = tcon.vals.uval.u0; 00540 tcon_bytes.val.u2 = tcon.vals.uval.u1; 00541 tcon_bytes.val.u3 = tcon.vals.uval.u2; 00542 tcon_bytes.val.u4 = tcon.vals.uval.u3; 00543 tcon_bytes.val.u5 = tcon.cmplxval.ival.v0; 00544 tcon_bytes.val.u6 = tcon.cmplxval.ival.v1; 00545 tcon_bytes.val.u7 = tcon.cmplxval.ival.v2; 00546 tcon_bytes.val.u8 = tcon.cmplxval.ival.v3; 00547 } 00548 00549 /* The tcon bytes of relevance are now in tcon_bytes */ 00550 for (pad_byte = 0; pad_byte < tcon_size; pad_byte++) 00551 { 00552 if (pad_byte > 0) 00553 Append_Token_Special(tokens, ','); 00554 Append_Token_String(tokens, 00555 Number_as_String(tcon_bytes.byte[pad_byte], "%llu")); 00556 } 00557 *current_offset += tcon_size; 00558 break; 00559 00560 case INITVKIND_BLOCK: 00561 Is_True(FALSE, ("BLOCK initv kind in INITV2C_struct_fill()")); 00562 break; 00563 00564 case INITVKIND_PAD: 00565 /* View padding as zero initialized */ 00566 for (pad_byte = INITV_pad(Initv_Table[*current_inv]); 00567 pad_byte > 0; 00568 pad_byte--) 00569 { 00570 Append_Token_String(tokens, "0"); 00571 if (pad_byte > 1) 00572 Append_Token_Special(tokens, ','); 00573 } 00574 *current_offset += INITV_pad(Initv_Table[*current_inv]); 00575 break; 00576 00577 default: 00578 Is_True(FALSE, ("Unexpected initv kind in INITV2C_struct_fill()")); 00579 break; 00580 00581 } /* switch */ 00582 00583 INIT2C_Next_Initv(current_inv, inv_repeat); 00584 00585 /* Seperate the last filler byte emitted from the next one 00586 * with a comma. 00587 */ 00588 if (*current_offset < desired_offset && *current_inv != 0) 00589 Append_Token_Special(tokens, ','); 00590 00591 } /*while*/ 00592 Append_Token_Special(tokens, '}'); 00593 } /* INITV2C_struct_fill */ 00594 00595 00596 static void 00597 INITV2C_block_struct(TOKEN_BUFFER tokens, 00598 TY_IDX ty, 00599 INITV_IDX initv) 00600 { 00601 /* Translate a INITVKIND_BLOCK for a struct to C, where the 00602 * location being initialized is typed as "ty" (KIND_STRUCT). 00603 */ 00604 INITV_IDX inv, first_inv = INITV_blk(initv); 00605 INT inv_repeat; 00606 INT64 local_offset; 00607 FLD_HANDLE fld; 00608 TY2C_FLD_INFO fld_info; 00609 BOOL a_field_is_initialized = FALSE; 00610 00611 /* Walk through the list of (comma separated) initializers 00612 * for the aggregate initializer, ignoring padding. 00613 */ 00614 Append_Token_Special(tokens, '{'); 00615 if (first_inv != 0 && 00616 INITV_kind(Initv_Table[first_inv]) == INITVKIND_PAD && 00617 INITV_next(first_inv) == 0) 00618 { 00619 /* Handle the special case of just having padding as an 00620 * initializer. 00621 */ 00622 Append_Token_String(tokens, "0L"); 00623 } 00624 else 00625 { 00626 /* Walk through the list of structure fields, initializing 00627 * field separating padding, but leaving padding at the end 00628 * of a struct uninitialized. 00629 */ 00630 local_offset = 0; 00631 inv = first_inv; 00632 inv_repeat = (inv != 0) ? INITV_repeat(inv) : 0; 00633 for (fld = TY_flist(Ty_Table[ty]); 00634 !fld.Is_Null () && inv != 0; 00635 fld = FLD_next(fld)) 00636 { 00637 if (FLD_ofst(fld) >= local_offset) 00638 { 00639 /* This field does not overlap any previous fields. 00640 */ 00641 fld_info = TY2C_get_field_info(ty, 00642 FLD_type(fld), 00643 MTYPE_V, 00644 FLD_ofst(fld)); 00645 if (!fld_info.found_fld.Is_Null ()) 00646 { 00647 /* This field is declared in the C output. 00648 */ 00649 Reclaim_Token_Buffer(&fld_info.select_tokens); 00650 if (FLD_ofst(fld) > local_offset) 00651 { 00652 /* Insert padding before this field. 00653 */ 00654 if (a_field_is_initialized) 00655 Append_Token_Special(tokens, ','); 00656 else 00657 a_field_is_initialized = TRUE; 00658 INITV2C_struct_fill(tokens, 00659 &inv, &inv_repeat, 00660 &local_offset, FLD_ofst(fld)); 00661 } 00662 if (inv != 0) 00663 { 00664 /* An initializer exists for this field. 00665 */ 00666 if (a_field_is_initialized) 00667 Append_Token_Special(tokens, ','); 00668 else 00669 a_field_is_initialized = TRUE; 00670 00671 /* Work around a Fortran bug! TODO: Rewrite this to 00672 * be more similar to whirl2f and to work for all cases. 00673 */ 00674 if (PU_src_lang(CURRENT_SYMTAB) == PU_F77_LANG && 00675 (INITV_kind(Initv_Table[inv]) == INITVKIND_ZERO || 00676 INITV_kind(Initv_Table[inv]) == INITVKIND_ONE || 00677 INITV_kind(Initv_Table[inv]) == INITVKIND_VAL)) 00678 { 00679 INT fld_size = TY_size(Ty_Table[FLD_type(fld)]); 00680 TY_IDX inv_ty; 00681 00682 if (TY_Is_Array(FLD_type(fld)) || 00683 TY_Is_Structured(FLD_type(fld))) 00684 { 00685 Append_Token_Special(tokens, '{'); 00686 } 00687 00688 while (inv != 0 && 00689 fld_size > 0 && 00690 (INITV_kind(Initv_Table[inv]) == INITVKIND_ZERO || 00691 INITV_kind(Initv_Table[inv]) == INITVKIND_ONE || 00692 INITV_kind(Initv_Table[inv]) == INITVKIND_VAL)) 00693 { 00694 inv_ty = Stab_Mtype_To_Ty(TCON_ty(TCON_For_Initv(inv))); 00695 INITV2C_translate(tokens, inv_ty, inv); 00696 fld_size -= TY_size(inv_ty); 00697 INIT2C_Next_Initv(&inv, &inv_repeat); 00698 if (fld_size > 0) 00699 Append_Token_Special(tokens, ','); 00700 } 00701 if (TY_Is_Array(FLD_type(fld)) || 00702 TY_Is_Structured(FLD_type(fld))) 00703 { 00704 Append_Token_Special(tokens, '}'); 00705 } 00706 } 00707 else 00708 { 00709 INITV2C_translate(tokens, FLD_type(fld), inv); 00710 INIT2C_Next_Initv(&inv, &inv_repeat); 00711 } 00712 00713 local_offset += TY_size(FLD_type(fld)); 00714 } /*if*/ 00715 } /*if*/ 00716 } /*if*/ 00717 } /*for*/ 00718 00719 /* Explicitly apply any outstanding initializer. We can here 00720 * Assert that (fld!=0 xor inv!=0). 00721 */ 00722 if (local_offset < TY_size(ty) && inv != 0) 00723 { 00724 if (a_field_is_initialized) 00725 Append_Token_Special(tokens, ','); 00726 INITV2C_struct_fill(tokens, 00727 &inv, &inv_repeat, 00728 &local_offset, TY_size(ty)); 00729 } /*if*/ 00730 } /*if*/ 00731 Append_Token_Special(tokens, '}'); 00732 } /* INITV2C_block_struct */ 00733 00734 00735 static void 00736 INITV2C_block_union(TOKEN_BUFFER tokens, 00737 TY_IDX ty, 00738 INITV_IDX initv) 00739 { 00740 /* Translate a INITVKIND_BLOCK for a union to C, where the 00741 * location being initialized is typed as "ty" (KIND_STRUCT). 00742 */ 00743 INITV_IDX first_inv = INITV_blk(initv); 00744 INITV_IDX next_inv = INITV_next(first_inv); 00745 00746 /* Make sure only one element of the union is initialized; allow a 00747 * second initializer for the union only if it is for padding. 00748 */ 00749 Is_True((next_inv == 0 || 00750 (INITV_kind(Initv_Table[next_inv]) == INITVKIND_PAD && 00751 INITV_next(next_inv) == 0)), 00752 ("Expected an initializer only for the first element of a union")); 00753 00754 /* Initialize the first element of the union */ 00755 Append_Token_Special(tokens, '{'); 00756 INITV2C_translate(tokens, FLD_type(TY_flist(Ty_Table[ty])), 00757 first_inv); 00758 Append_Token_Special(tokens, '}'); 00759 } /* INITV2C_block_union */ 00760 00761 00762 static void 00763 INITV2C_translate(TOKEN_BUFFER tokens, 00764 TY_IDX ty, 00765 INITV_IDX initv) 00766 { 00767 switch (INITV_kind(Initv_Table[initv])) 00768 { 00769 case INITVKIND_UNK: 00770 Is_True(FALSE, ("Unknown initv kind in INITV2C_translate()")); 00771 break; 00772 00773 case INITVKIND_SYMOFF: 00774 INITV2C_symoff_help(tokens, ty, initv); 00775 break; 00776 00777 case INITVKIND_ZERO: 00778 case INITVKIND_ONE: 00779 case INITVKIND_VAL: 00780 /* May be a scalar or a string initializer */ 00781 INITV2C_val(tokens, ty, initv); 00782 break; 00783 00784 case INITVKIND_BLOCK: 00785 /* Expect an array, a union or a struct ty. Assert on 00786 * anything else! Note that a string may occur as a 00787 * block initializer when it has padding. 00788 */ 00789 if (TY_Is_Array(ty)) 00790 INITV2C_block_array(tokens, ty, initv); 00791 else if (TY_Is_Union(ty)) 00792 INITV2C_block_union(tokens, ty, initv); 00793 else if (TY_Is_Struct(ty)) 00794 INITV2C_block_struct(tokens, ty, initv); 00795 else 00796 Is_True(FALSE, ("Unexpected aggregate type in INITV2C_translate()")); 00797 break; 00798 00799 case INITVKIND_PAD: 00800 /* Simply ignore padding */ 00801 break; 00802 00803 default: 00804 Is_True(FALSE, ("Unexpected initv kind in INITV2C_translate()")); 00805 break; 00806 00807 } /* switch */ 00808 } /* INITV2C_translate */ 00809 00810 00811 void 00812 INITO2C_translate(TOKEN_BUFFER tokens, INITO_IDX inito) 00813 { 00814 /* There is one INITO denoting the object initializer. The INITO 00815 * points to the object it references (ST*), and the INITO_ofst 00816 * attribute (offset in data section) has no significance for 00817 * the translation to C. 00818 */ 00819 00820 if (Stab_Is_Common_Block(INITO_st(inito)) || 00821 Stab_Is_Equivalence_Block(INITO_st(inito))) 00822 { 00823 if ( !TY_Is_Structured(ST_type(INITO_st(inito))) ) 00824 Append_Token_Special(tokens, '{'); 00825 INITV2C_translate(tokens, ST_type(INITO_st(inito)), INITO_val(inito)); 00826 if ( !TY_Is_Structured(ST_type(INITO_st(inito))) ) 00827 Append_Token_Special(tokens, '}'); 00828 } 00829 else{ 00830 INITV2C_translate(tokens, ST_type(INITO_st(inito)), INITO_val(inito)); 00831 00832 } 00833 } /* INITO2C_translate */