00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #ifdef _KEEP_RCS_ID
00057 static char *rcs_id = "$Source: /var/local/cvs/compilers/open64/osprey1.0/be/whirl2c/ty2c.cxx,v $ $Revision: 1.37 $";
00058 #endif
00059
00060 #include "whirl2c_common.h"
00061 #include "PUinfo.h"
00062 #include "ty2c.h"
00063 #include "tcon2c.h"
00064
00065 #if defined(__GNUC__) && (__GNUC__ >= 3)
00066
00067 # include <ext/hash_set>
00068 using __gnu_cxx::hash_set;
00069
00070 #else
00071 # include <set>
00072 #endif
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 typedef struct SCALAR_C_NAME
00085 {
00086 const char *real_name;
00087 const char *pseudo_name;
00088 } SCALAR_C_NAME;
00089
00090
00091
00092
00093
00094
00095 const char TY2C_Aligned_Block_Name[] = "__block";
00096
00097 #if defined(TARG_X8664)
00098 #define MTYPE_PREDEF MTYPE_V16F8
00099 #else
00100 #define MTYPE_PREDEF MTYPE_F16
00101 #endif
00102
00103 static char Name_Unknown_Type[] = "__UNKNOWN_TYPE";
00104 static const SCALAR_C_NAME Scalar_C_Names[MTYPE_LAST + 1] =
00105 {{"void", Name_Unknown_Type},
00106 {"char", "_BOOLEAN"},
00107 {"signed char", "_INT8"},
00108 {"signed short", "_INT16"},
00109 {"signed int", "_INT32"},
00110 {"signed long long", "_INT64"},
00111 {"unsigned char", "_UINT8"},
00112 {"unsigned short", "_UINT16"},
00113 {"unsigned int", "_UINT32"},
00114 {"unsigned long long", "_UINT64"},
00115 {"float", "_IEEE32"},
00116 {"double", "_IEEE64"},
00117 {Name_Unknown_Type, "_IEEE80"},
00118 {Name_Unknown_Type, "_IEEE128"},
00119 {Name_Unknown_Type, ""},
00120 {Name_Unknown_Type, ""},
00121 {Name_Unknown_Type, ""},
00122 {"_Complex float", "_COMPLEX32"},
00123 {"_Complex double", "_COMPLEX64"},
00124 {Name_Unknown_Type, ""},
00125 {Name_Unknown_Type, ""},
00126 {Name_Unknown_Type, ""},
00127 {Name_Unknown_Type, ""},
00128 {Name_Unknown_Type, ""},
00129 {"_Complex long double", "_COMPLEX80"},
00130 {Name_Unknown_Type, ""},
00131 {Name_Unknown_Type, ""},
00132 {Name_Unknown_Type, ""},
00133 #ifdef TARG_X8664
00134 {Name_Unknown_Type, "_CMPLX8[2]"},
00135 {Name_Unknown_Type, "_CMPLX16[1]"},
00136 {"signed char[16]", "_INT8[16]"},
00137 {"signed short[8]", "_INT16[8]"},
00138 {"signed int[4]", "_INT32[4]"},
00139 {"signed long long int[2]","_INT64[2]"},
00140 {"float[4]", "_IEEE32[4]"},
00141 {"double[2]", "_IEEE64[2]"},
00142 {Name_Unknown_Type, ""},
00143 {Name_Unknown_Type, ""},
00144 {Name_Unknown_Type, ""},
00145 {Name_Unknown_Type, ""},
00146 {Name_Unknown_Type, ""},
00147 {Name_Unknown_Type, ""},
00148 {Name_Unknown_Type, ""},
00149 {Name_Unknown_Type, ""},
00150 #elif defined(TARG_SL)
00151 {Name_Unknown_Type, ""},
00152 {Name_Unknown_Type, ""},
00153 {Name_Unknown_Type, ""},
00154 {Name_Unknown_Type, ""},
00155 {Name_Unknown_Type, ""},
00156 {Name_Unknown_Type, ""},
00157 {Name_Unknown_Type, ""},
00158 {Name_Unknown_Type, ""},
00159 {Name_Unknown_Type, ""},
00160 {Name_Unknown_Type, ""},
00161 {Name_Unknown_Type, ""},
00162 {Name_Unknown_Type, ""},
00163 {Name_Unknown_Type, ""},
00164 {Name_Unknown_Type, ""},
00165 {Name_Unknown_Type, ""},
00166 {Name_Unknown_Type, ""},
00167 {Name_Unknown_Type, ""},
00168 {Name_Unknown_Type, ""},
00169 {Name_Unknown_Type, ""},
00170 #endif
00171 };
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 const char Special_Void_TypeName[] = "void";
00182 const char Special_String_TypeName[] = "_STRING";
00183 const char Special_Quad_TypeName[] = "_QUAD";
00184 const char Special_Complex32_TypeName[] = "_COMPLEX32";
00185 const char Special_Complex64_TypeName[] = "_COMPLEX64";
00186 const char Special_ComplexQD_TypeName[] = "_COMPLEXQD";
00187
00188 const char *GET_SPECIAL_TYPENAME(TY_IDX mtype)
00189 {
00190 #if defined(TARG_SL)
00191 const char *Special_SL_Mem_TypeName[] = {
00192 "_sbuf1", "_sbuf2", "_sbuf4", "_sbuf8", "unsigned _sbuf1", "unsigned _sbuf2",
00193 "unsigned _sbuf4", "unsigned _sbuf8", "_sdram1", "_sdram2", "_sdram4", "_sdram8",
00194 "unsigned _sdram1", "unsigned _sdram2", "unsigned _sdram4", "unsigned _sdram8",
00195 "_vbuf1", "_vbuf2", "_vbuf4" };
00196
00197 if ((mtype >= MTYPE_SB1) || (mtype <= MTYPE_LAST)) {
00198 return Special_SL_Mem_TypeName[mtype - MTYPE_SB1];
00199 }
00200 #endif
00201 return
00202 ((mtype) == MTYPE_V? Special_Void_TypeName :
00203 ((mtype) == MTYPE_STR? Special_String_TypeName :
00204 ((mtype) == MTYPE_FQ? Special_Quad_TypeName :
00205 ((mtype) == MTYPE_C4? Special_Complex32_TypeName :
00206 ((mtype) == MTYPE_C8? Special_Complex64_TypeName :
00207 ((mtype) == MTYPE_CQ? Special_ComplexQD_TypeName :
00208 (const char *)NULL))))));
00209 }
00210
00211
00212
00213
00214
00215
00216 #define PTR_OR_ALIGNED_WITH_STRUCT(fld_ty, struct_align) true
00217
00218
00219
00220 static void TY2C_scalar(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00221 static void TY2C_array(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00222 static void TY2C_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00223 static void TY2C_function(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00224 static void TY2C_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00225 static void TY2C_void(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00226 static void TY2C_invalid(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context);
00227
00228
00229
00230
00231
00232
00233
00234 typedef void (*TY2C_HANDLER_FUNC)(TOKEN_BUFFER, TY_IDX, CONTEXT);
00235
00236 static const TY2C_HANDLER_FUNC
00237 TY2C_Handle[KIND_LAST] =
00238 {
00239 &TY2C_invalid,
00240 &TY2C_scalar,
00241 &TY2C_array,
00242 &TY2C_struct,
00243 &TY2C_pointer,
00244 &TY2C_function,
00245 &TY2C_void,
00246 };
00247
00248
00249
00250
00251
00252
00253
00254
00255 const char *TY2C_Complex_Realpart_Name = "realpart";
00256 const char *TY2C_Complex_Imagpart_Name = "imagpart";
00257 extern int compiling_upc_flag ;
00258
00259
00260
00261
00262 static void
00263 Write_Scalar_Typedef(FILE *ofile,
00264 const char *real_type,
00265 const char *new_name)
00266 {
00267 TOKEN_BUFFER tdef = New_Token_Buffer();
00268
00269 Append_Token_String(tdef, "typedef");
00270 Append_Token_String(tdef, real_type);
00271 Append_Token_String(tdef, new_name);
00272 Append_Token_Special(tdef, ';');
00273 Append_Indented_Newline(tdef, 1);
00274 Write_And_Reclaim_Tokens(ofile, NULL, &tdef);
00275 }
00276
00277
00278 static void
00279 Write_Typedef(FILE *ofile,
00280 TY_IDX ty,
00281 const char *type_name)
00282 {
00283 TOKEN_BUFFER tdef = New_Token_Buffer();
00284 CONTEXT context;
00285
00286 CONTEXT_reset(context);
00287
00288 Append_Token_String(tdef, type_name);
00289 TY2C_Handle[(TY_KIND)TY_kind(ty)](tdef, ty, context);
00290 Prepend_Token_String(tdef, "typedef");
00291 Append_Token_Special(tdef, ';');
00292 Append_Indented_Newline(tdef, 1);
00293
00294
00295 Prepend_Indented_Newline(tdef, 1);
00296 Write_And_Reclaim_Tokens(ofile, NULL, &tdef);
00297 }
00298
00299
00300 static void
00301 TY2C_prepend_qualifiers(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00302 {
00303 if (!CONTEXT_unqualified_ty2c(context))
00304 {
00305 if (TY_is_const(ty) && CONTEXT_const(context)) {
00306 Prepend_Token_String(decl_tokens, "const");
00307 }
00308 if (TY_is_volatile(ty))
00309 Prepend_Token_String(decl_tokens, "volatile");
00310 if (TY_is_restrict(ty)) {
00311 Prepend_Token_String(decl_tokens, "restrict");
00312 }
00313 }
00314 }
00315
00316
00317 static INT64
00318 get_field_gap(FLD_HANDLE this_fld, FLD_HANDLE next_fld, INT64 max_size,
00319 BOOL is_union)
00320 {
00321
00322
00323
00324
00325
00326
00327 INT64 field_gap = TY_size(FLD_type(this_fld));
00328
00329 if (!is_union &&
00330 !next_fld.Is_Null() &&
00331 field_gap != FLD_ofst(next_fld)-FLD_ofst(this_fld))
00332 {
00333 field_gap = FLD_ofst(next_fld) - FLD_ofst(this_fld);
00334 }
00335 if (field_gap > max_size || (!is_union && next_fld.Is_Null ()))
00336 {
00337 field_gap = max_size;
00338 }
00339 return field_gap;
00340 }
00341
00342
00343 static FLD_HANDLE
00344 skip_till_next_field(FLD_HANDLE this_fld,
00345 const INT64 struct_align,
00346 const INT64 struct_size,
00347 BOOL is_union)
00348 {
00349
00350
00351
00352
00353
00354
00355
00356 FLD_HANDLE next_fld = FLD_next(this_fld);
00357
00358 if (!is_union)
00359 {
00360
00361
00362
00363
00364
00365 while (!next_fld.Is_Null () &&
00366 (FLD_ofst(this_fld) >= FLD_ofst(next_fld) ||
00367 !PTR_OR_ALIGNED_WITH_STRUCT(FLD_type(next_fld), struct_align) ||
00368
00369
00370
00371 #if 0
00372 (!TY_Is_Pointer(FLD_type(next_fld)) &&
00373 FLD_ofst(next_fld) % TY_align(FLD_type(next_fld)) != 0) ||
00374 #endif
00375 (!is_union &&
00376 FLD_Is_Bitfield(next_fld,
00377 FLD_next(next_fld),
00378 struct_size - FLD_ofst(next_fld)))))
00379 {
00380 next_fld = FLD_next(next_fld);
00381 }
00382 }
00383 return next_fld;
00384 }
00385
00386
00387 static void
00388 TY2C_prepend_filler_field(TOKEN_BUFFER decl_tokens, INT64 byte_size)
00389 {
00390 return;
00391
00392
00393
00394 TOKEN_BUFFER field_tokens;
00395
00396 field_tokens = New_Token_Buffer();
00397 Append_Token_String(field_tokens,
00398 Scalar_C_Names[MTYPE_U1].pseudo_name);
00399 Append_Token_String(field_tokens, W2CF_Symtab_Unique_Name("fill"));
00400 Append_Token_Special(field_tokens, '[');
00401 TCON2C_translate(field_tokens, Host_To_Targ(MTYPE_I8, byte_size));
00402 Append_Token_Special(field_tokens, ']');
00403 Append_Token_Special(field_tokens, ';');
00404 Prepend_Indented_Newline(field_tokens, 1);
00405 Prepend_And_Reclaim_Token_List(decl_tokens, &field_tokens);
00406 }
00407
00408
00409 extern int debug_requested;
00410 static void
00411 TY2C_prepend_FLD_list(TOKEN_BUFFER decl_tokens,
00412 FLD_HANDLE fld,
00413 const BOOL is_union,
00414 const INT64 struct_align,
00415 const INT64 struct_size,
00416 CONTEXT context)
00417 {
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 TOKEN_BUFFER fld_tokens;
00429 INT64 fld_gap;
00430 const INT64 remaining_bytes = struct_size - FLD_ofst(fld);
00431
00432 FLD_HANDLE next_fld = skip_till_next_field(fld,
00433 struct_align,
00434 struct_size,
00435 is_union);
00436 fld_gap = get_field_gap(fld, next_fld, remaining_bytes, is_union);
00437
00438
00439
00440
00441
00442
00443 if (!next_fld.Is_Null ())
00444 {
00445 if (is_union)
00446 TY2C_prepend_FLD_list(decl_tokens,
00447 next_fld,
00448 TRUE,
00449 struct_align,
00450 struct_size,
00451 context);
00452 else
00453 TY2C_prepend_FLD_list(decl_tokens,
00454 next_fld,
00455 FALSE,
00456 struct_align,
00457 struct_size,
00458 context);
00459 }
00460
00461
00462
00463
00464
00465
00466 if (!PTR_OR_ALIGNED_WITH_STRUCT(FLD_type(fld), struct_align) ||
00467 (!is_union &&
00468 FLD_Is_Bitfield(fld, FLD_next(fld), remaining_bytes)))
00469 {
00470
00471 if (fld_gap > 0)
00472 TY2C_prepend_filler_field(decl_tokens, fld_gap);
00473 }
00474 else
00475 {
00476
00477
00478
00479 if (!is_union && fld_gap > TY_size(FLD_type(fld)))
00480 {
00481 TY2C_prepend_filler_field(decl_tokens,
00482 fld_gap - TY_size(FLD_type(fld)));
00483 }
00484
00485
00486 fld_tokens = New_Token_Buffer();
00487 Append_Token_String(fld_tokens, W2CF_Symtab_Nameof_Fld(fld));
00488 TY2C_translate(fld_tokens, FLD_type(fld), context);
00489 Append_Token_Special(fld_tokens, ';');
00490 Prepend_And_Reclaim_Token_List(decl_tokens, &fld_tokens);
00491 Prepend_Indented_Newline(decl_tokens, 1);
00492 }
00493 }
00494
00495
00496 static void
00497 TY2C_Prepend_Alignment_Type(TOKEN_BUFFER tokens, INT64 align)
00498 {
00499 CONTEXT c;
00500
00501 CONTEXT_reset(c);
00502 switch (align)
00503 {
00504 case 1:
00505 TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U1), c);
00506 break;
00507 case 2:
00508 TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U2), c);
00509 break;
00510 case 4:
00511 TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U4), c);
00512 break;
00513 case 8:
00514 TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_U8), c);
00515 break;
00516 case 16:
00517 TY2C_translate(tokens, Stab_Mtype_To_Ty(MTYPE_FQ), c);
00518 break;
00519 default:
00520 Is_True(FALSE,
00521 ("Unexpected alignment (%lld) in TY2C_Prepend_Alignment_Type()",
00522 align));
00523 }
00524 }
00525
00526
00527 static void
00528 TY2C_prototype_params(TOKEN_BUFFER decl_tokens,
00529 TYLIST_IDX params,
00530 CONTEXT context)
00531 {
00532 TOKEN_BUFFER param_tokens;
00533
00534 CONTEXT_set_const(context);
00535 if (Tylist_Table[params] == 0)
00536 {
00537 Append_Token_String(decl_tokens, "void");
00538 }
00539 else
00540 {
00541 while (Tylist_Table[params] != 0)
00542 {
00543 param_tokens = New_Token_Buffer();
00544 TY2C_translate(param_tokens, TYLIST_item(Tylist_Table[params]),
00545 context);
00546 Append_And_Reclaim_Token_List(decl_tokens, ¶m_tokens);
00547 params = TYLIST_next(params);
00548 if (Tylist_Table[params] != 0)
00549 Append_Token_Special(decl_tokens, ',');
00550 }
00551 }
00552 CONTEXT_reset_const(context);
00553 }
00554
00555
00556
00557
00558
00559 static void
00560 TY2C_scalar(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00561 {
00562 Is_True(TY_Is_String(ty) ||
00563 TY_mtype(ty) <= MTYPE_PREDEF, ("Illegal type in TY2C_scalar()"));
00564 Is_True(TY_mtype(ty) != MTYPE_UNKNOWN, ("Unknown type in TY2C_scalar()"));
00565
00566 if (TY_Is_String(ty))
00567 {
00568 Prepend_Token_String(decl_tokens,
00569 Scalar_C_Names[MTYPE_U1].pseudo_name);
00570 Append_Token_Special(decl_tokens, '[');
00571 Append_Token_Special(decl_tokens, ']');
00572 }
00573 else if (TY_is_logical(ty)) {
00574 Prepend_Token_String(decl_tokens, TY_name(ty));
00575 }
00576 else
00577 {
00578 Prepend_Token_String(decl_tokens,
00579 Scalar_C_Names[TY_mtype(ty)].pseudo_name);
00580 }
00581 TY2C_prepend_qualifiers(decl_tokens, ty, context);
00582 }
00583
00584
00585 static void
00586 TY2C_array(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00587 {
00588 if (Stab_Array_Has_Dynamic_Bounds(ty))
00589 {
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 if (CONTEXT_incomplete_ty2c(context))
00600 {
00601
00602
00603
00604
00605
00606 Append_Token_Special(decl_tokens, '[');
00607 Append_Token_Special(decl_tokens, ']');
00608
00609
00610
00611
00612 CONTEXT_reset_incomplete_ty2c(context);
00613 }
00614 else
00615 {
00616
00617
00618
00619 Prepend_Token_Special(decl_tokens, '*');
00620 if (TY_Is_Array_Or_Function(TY_AR_etype(ty)))
00621 WHIRL2C_parenthesize(decl_tokens);
00622
00623
00624 CONTEXT_set_incomplete_ty2c(context);
00625 }
00626 }
00627 else
00628 {
00629 INT32 dim;
00630 INT64 num_elts;
00631
00632
00633
00634
00635 for (dim = 0; dim < TY_AR_ndims(ty); dim++)
00636 {
00637 Append_Token_Special(decl_tokens, '[');
00638
00639
00640
00641
00642
00643
00644 num_elts = (TY_AR_ubnd_val(ty, dim) - TY_AR_lbnd_val(ty, dim) + 1);
00645
00646 if (num_elts > 0)
00647 TCON2C_translate(decl_tokens,
00648 Host_To_Targ(MTYPE_I8, num_elts));
00649
00650 Append_Token_Special(decl_tokens, ']');
00651 }
00652
00653
00654
00655
00656 CONTEXT_reset_incomplete_ty2c(context);
00657 }
00658
00659
00660 if (TY_kind(TY_AR_etype(ty)) == KIND_STRUCT) {
00661 CONTEXT_set_incomplete_ty2c(context);
00662 }
00663
00664
00665
00666
00667 TY2C_translate(decl_tokens, TY_AR_etype(ty), context);
00668 TY2C_prepend_qualifiers(decl_tokens, ty, context);
00669 }
00670
00671
00672 static void TY2C_complete_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context) {
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 CONTEXT fld_context;
00700 BOOL is_equivalenced = Stab_Is_Equivalenced_Struct(ty);
00701 BOOL is_anonymous = (strncmp (TY_name(ty), "T ", 2) == 0);
00702 BOOL do_write = FALSE;
00703 if (!TY_flist(Ty_Table[ty]).Is_Null ()) {
00704 do_write = TRUE;
00705 fld_context = context;
00706 CONTEXT_reset_unqualified_ty2c(fld_context);
00707 CONTEXT_reset_incomplete_ty2c(fld_context);
00708
00709 if (is_equivalenced)
00710 {
00711
00712
00713
00714
00715 Prepend_Token_Special(decl_tokens, '}');
00716 Prepend_Indented_Newline(decl_tokens, 1);
00717 Increment_Indentation();
00718 Prepend_Token_Special(decl_tokens, ';');
00719 Prepend_Token_String(decl_tokens, "__align");
00720 TY2C_Prepend_Alignment_Type(decl_tokens, TY_align(ty));
00721 Prepend_Indented_Newline(decl_tokens, 1);
00722 Prepend_Token_Special(decl_tokens, ';');
00723 Prepend_Token_String(decl_tokens, TY2C_Aligned_Block_Name);
00724 }
00725
00726
00727
00728
00729 Prepend_Token_Special(decl_tokens, '}');
00730 Prepend_Indented_Newline(decl_tokens, 1);
00731
00732
00733
00734
00735 if (TY_align(ty) == 1) {
00736 FLD_HANDLE first_fld = TY_flist(Ty_Table[ty]);
00737 if (!first_fld.Is_Null()) {
00738 Set_TY_align(ty, TY_align(FLD_type(first_fld)));
00739 }
00740 }
00741
00742
00743
00744
00745 Increment_Indentation();
00746 TY2C_prepend_FLD_list(decl_tokens,
00747 TY_flist(Ty_Table[ty]),
00748 TY_is_union(ty),
00749 TY_align(ty),
00750 TY_size(ty),
00751 fld_context);
00752 Decrement_Indentation();
00753
00754
00755 Prepend_Token_Special(decl_tokens, '{');
00756
00757 if (is_equivalenced)
00758 {
00759
00760
00761
00762 Prepend_Token_String(decl_tokens, TY_is_union(ty)? "union": "struct");
00763 Prepend_Indented_Newline(decl_tokens, 1);
00764 Decrement_Indentation();
00765 Prepend_Token_Special(decl_tokens, '{');
00766 }
00767 if (!is_anonymous) {
00768 Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00769 }
00770 } else if (TY_size(ty) == 1) {
00771
00772
00773
00774 Prepend_Token_Special(decl_tokens, '}');
00775 Prepend_Indented_Newline(decl_tokens, 1);
00776
00777 Prepend_Token_Special(decl_tokens, ';');
00778 Prepend_Token_String(decl_tokens, W2CF_Symtab_Unique_Name("dummy"));
00779 TY2C_translate(decl_tokens, Stab_Mtype_To_Ty(MTYPE_U1), context);
00780
00781 Increment_Indentation();
00782 Prepend_Indented_Newline(decl_tokens, 1);
00783 Prepend_Token_Special(decl_tokens, '{');
00784 Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00785 Decrement_Indentation();
00786 do_write = TRUE;
00787 } else if (TY_size(ty) == 0) {
00788
00789 if (!is_anonymous) {
00790 Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00791 do_write = TRUE;
00792 }
00793 }
00794
00795 if(do_write) {
00796 if (TY_is_union(ty) || is_equivalenced)
00797 Prepend_Token_String(decl_tokens, "union");
00798 else
00799 Prepend_Token_String(decl_tokens, "struct");
00800 }
00801 if (is_anonymous) {
00802 Prepend_Token_String(decl_tokens, "typedef ");
00803 Append_Token_String(decl_tokens, " ");
00804 Append_Token_String(decl_tokens, TY_name(ty) + 2);
00805 }
00806 }
00807
00808
00809
00810
00811
00812
00813
00814 static hash_set<TY_IDX> struct_ty;
00815
00816
00817
00818 static void TY2C_Output_Struct_Type(TY_IDX ty,
00819 INT lines_between_decls,
00820 CONTEXT context) {
00821
00822 if (struct_ty.find(ty) != struct_ty.end()) {
00823
00824 return;
00825 }
00826
00827 Set_TY_is_translated_to_c(ty);
00828 struct_ty.insert(ty);
00829
00830 TOKEN_BUFFER tmp_tokens = New_Token_Buffer();
00831 CONTEXT_reset_incomplete_ty2c(context);
00832 TY2C_complete_struct(tmp_tokens, ty, context);
00833 Append_Token_Special(tmp_tokens, ';');
00834 Append_Indented_Newline(tmp_tokens, lines_between_decls);
00835 Write_And_Reclaim_Tokens(W2C_File[W2C_DOTH_FILE],
00836 NULL,
00837 &tmp_tokens);
00838
00839 }
00840
00841
00842
00843
00844
00845
00846 static void
00847 TY2C_struct(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00848 {
00849
00850 if (!TY_is_translated_to_c(ty)) {
00851
00852 CONTEXT_reset_incomplete_ty2c (context);
00853 TY2C_Output_Struct_Type(ty, 1, context);
00854 }
00855
00856 BOOL is_anonymous = (strncmp(TY_name(ty), "T ", 2) == 0);
00857 if (!is_anonymous) {
00858
00859 Prepend_Token_String(decl_tokens, W2CF_Symtab_Nameof_Ty(ty));
00860
00861 BOOL is_equivalenced = Stab_Is_Equivalenced_Struct(ty);
00862 if (TY_is_union(ty) || is_equivalenced)
00863 Prepend_Token_String(decl_tokens, "union");
00864 else
00865 Prepend_Token_String(decl_tokens, "struct");
00866 } else {
00867 Prepend_Token_String(decl_tokens, TY_name(ty) + 2);
00868 }
00869
00870 TY2C_prepend_qualifiers(decl_tokens, ty, context);
00871 }
00872
00873
00874 static void
00875 TY2C_function(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00876 {
00877 TYLIST_IDX params = TY_parms(ty);
00878
00879
00880 CONTEXT_reset_unqualified_ty2c(context);
00881
00882
00883 CONTEXT_set_incomplete_ty2c(context);
00884
00885
00886 Append_Token_Special(decl_tokens, '(');
00887 if (TY_has_prototype(ty))
00888 {
00889 TY2C_prototype_params(decl_tokens, params, context);
00890 if (TY_is_varargs(ty))
00891 {
00892 Append_Token_Special(decl_tokens, ',');
00893 Append_Token_String(decl_tokens, "...");
00894 }
00895 }
00896 Append_Token_Special(decl_tokens, ')');
00897
00898
00899 TY2C_translate(decl_tokens, Func_Return_Type(ty), context);
00900 }
00901
00902
00903 static void
00904 TY2C_pointer(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00905 {
00906
00907
00908
00909
00910 TY2C_prepend_qualifiers(decl_tokens, ty, context);
00911
00912 Prepend_Token_Special(decl_tokens, '*');
00913
00914 if (TY_Is_Array_Or_Function(TY_pointed(ty)))
00915 WHIRL2C_parenthesize(decl_tokens);
00916
00917 CONTEXT_reset_unqualified_ty2c(context);
00918 CONTEXT_set_incomplete_ty2c(context);
00919 bool old_const = CONTEXT_const(context);
00920 CONTEXT_set_const(context);
00921 TY2C_translate(decl_tokens, TY_pointed(ty), context);
00922 if (!old_const) {
00923 CONTEXT_reset_const(context);
00924 }
00925 }
00926
00927
00928 static void
00929 TY2C_void(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00930 {
00931 Prepend_Token_String(decl_tokens, Special_Void_TypeName);
00932 TY2C_prepend_qualifiers(decl_tokens, ty, context);
00933 }
00934
00935
00936 static void
00937 TY2C_invalid(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00938 {
00939 Is_True(FALSE, ("Invalid TY kind (%d) for translation to C", TY_kind(ty)));
00940 }
00941
00942
00943
00944
00945
00946 void
00947 TY2C_initialize(CONTEXT context)
00948 {
00949
00950
00951
00952
00953 Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_STRING));
00954 Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_C4));
00955 Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_C8));
00956 Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_C10));
00957 Set_TY_is_translated_to_c(Be_Type_Tbl(MTYPE_CQ));
00958 }
00959
00960
00961 void
00962 TY2C_finalize(void)
00963 {
00964 return;
00965 }
00966
00967
00968 void
00969 TY2C_translate(TOKEN_BUFFER decl_tokens, TY_IDX ty, CONTEXT context)
00970 {
00971
00972
00973
00974 const char *special_name = GET_SPECIAL_TYPENAME(TY_mtype(ty));
00975
00976 if (special_name != NULL)
00977 {
00978 Prepend_Token_String(decl_tokens, special_name);
00979 TY2C_prepend_qualifiers(decl_tokens, ty, context);
00980 }
00981 else
00982 {
00983 Is_True((TY_KIND)TY_kind(ty) < KIND_LAST && TY_kind(ty) > KIND_INVALID,
00984 ("Unexpected TY_kind (%d) in TY2C_translate()", TY_kind(ty)));
00985 TY2C_Handle[(TY_KIND)TY_kind(ty)](decl_tokens, ty, context);
00986 }
00987 }
00988
00989
00990 void
00991 TY2C_translate_unqualified(TOKEN_BUFFER decl_tokens, TY_IDX ty)
00992 {
00993
00994
00995 CONTEXT context;
00996
00997 CONTEXT_reset(context);
00998 CONTEXT_set_unqualified_ty2c(context);
00999
01000 if (TY_kind(ty) == KIND_STRUCT) {
01001 CONTEXT_set_incomplete_ty2c(context);
01002 }
01003
01004 TY2C_translate(decl_tokens, ty, context);
01005 }
01006
01007
01008 TY2C_FLD_INFO
01009 TY2C_get_field_info(TY_IDX struct_ty,
01010 TY_IDX desired_ty,
01011 MTYPE desired_mty,
01012 INT64 desired_offset)
01013 {
01014
01015
01016
01017
01018
01019
01020
01021
01022 TY_IDX this_ty;
01023 FLD_HANDLE this_fld;
01024 FLD_HANDLE next_fld;
01025 TY2C_FLD_INFO this_fld_info;
01026 const INT64 struct_size = TY_size(struct_ty);
01027 const INT64 struct_align = TY_align(struct_ty);
01028 BOOL found_ty = FALSE, found_mty = FALSE;
01029
01030
01031 this_fld = TY_flist(Ty_Table[struct_ty]);
01032 if (!this_fld.Is_Null () && !TY_is_union(struct_ty))
01033 {
01034
01035
01036
01037
01038 for (next_fld = skip_till_next_field(this_fld,
01039 struct_align,
01040 struct_size,
01041 FALSE);
01042 !next_fld.Is_Null() && FLD_ofst(next_fld) <= desired_offset;
01043 next_fld = skip_till_next_field(next_fld,
01044 struct_align,
01045 struct_size,
01046 FALSE))
01047 {
01048 this_fld = next_fld;
01049 }
01050 }
01051 else if (!this_fld.Is_Null ())
01052 {
01053 next_fld = skip_till_next_field(this_fld,
01054 struct_align,
01055 struct_size,
01056 TRUE);
01057 }
01058
01059
01060
01061
01062
01063
01064 while (!found_ty && !this_fld.Is_Null () &&
01065 FLD_ofst(this_fld) <= desired_offset)
01066 {
01067 this_ty = FLD_type(this_fld);
01068
01069 if (!PTR_OR_ALIGNED_WITH_STRUCT(this_ty, struct_align) ||
01070 (!TY_is_union(struct_ty) &&
01071 FLD_Is_Bitfield(this_fld, FLD_next(this_fld),
01072 struct_size - FLD_ofst(this_fld))))
01073 {
01074
01075
01076
01077
01078
01079 }
01080 else if (desired_offset == FLD_ofst(this_fld) &&
01081 Stab_Identical_Types(desired_ty, this_ty,
01082 FALSE,
01083 TRUE,
01084 TRUE))
01085 {
01086
01087 this_fld_info.found_fld = this_fld;
01088 this_fld_info.select_tokens = New_Token_Buffer();
01089 Append_Token_String(this_fld_info.select_tokens,
01090 W2CF_Symtab_Nameof_Fld(this_fld));
01091 found_ty = TRUE;
01092 }
01093 else if (TY_Is_Structured(this_ty))
01094 {
01095
01096
01097
01098
01099 this_fld_info =
01100 TY2C_get_field_info(this_ty,
01101 desired_ty,
01102 desired_mty,
01103 desired_offset-FLD_ofst(this_fld));
01104 if (!this_fld_info.found_fld.Is_Null ())
01105 {
01106
01107 Prepend_Token_Special(this_fld_info.select_tokens, '.');
01108 Prepend_Token_String(this_fld_info.select_tokens,
01109 W2CF_Symtab_Nameof_Fld(this_fld));
01110 found_ty = TRUE;
01111 }
01112 }
01113 else if (desired_offset == FLD_ofst(this_fld) &&
01114 desired_mty == TY_mtype(this_ty))
01115 {
01116
01117
01118
01119 this_fld_info.found_fld = this_fld;
01120 found_mty = TRUE;
01121 }
01122 if (!found_ty)
01123 {
01124 this_fld = next_fld;
01125 if (!this_fld.Is_Null ())
01126 next_fld = skip_till_next_field(this_fld,
01127 struct_align,
01128 struct_size,
01129 TY_is_union(struct_ty));
01130 }
01131 }
01132
01133 if (!found_ty && found_mty)
01134 {
01135
01136
01137
01138 this_fld_info.select_tokens = New_Token_Buffer();
01139 Append_Token_String(this_fld_info.select_tokens,
01140 W2CF_Symtab_Nameof_Fld(this_fld_info.found_fld));
01141 }
01142 if (found_ty || found_mty)
01143 {
01144
01145
01146
01147
01148 if (Stab_Is_Equivalenced_Struct(struct_ty))
01149 {
01150 Prepend_Token_Special(this_fld_info.select_tokens, '.');
01151 Prepend_Token_String(this_fld_info.select_tokens,
01152 TY2C_Aligned_Block_Name);
01153 }
01154 }
01155 else if (!found_ty)
01156 {
01157 this_fld_info.found_fld = FLD_HANDLE(0);
01158 }
01159 return this_fld_info;
01160 }
01161
01162
01163 BOOL
01164 TY2C_builtin(TY_IDX ty)
01165 {
01166 const char *name = GET_SPECIAL_TYPENAME(TY_mtype(ty));
01167
01168 return (name != NULL ||
01169 (TY_mtype(ty) <= MTYPE_PREDEF &&
01170 (TY_mtype(ty) != MTYPE_UNKNOWN || TY_kind(ty) == KIND_INVALID) &&
01171 Scalar_C_Names[TY_mtype(ty)].pseudo_name != NULL));
01172 }