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
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #ifdef _KEEP_RCS_ID
00070 #endif
00071
00072 #include "whirl2c_common.h"
00073 #include "PUinfo.h"
00074 #include "tcon2c.h"
00075 #include "st2c.h"
00076 #include "ty2c.h"
00077 #include "init2c.h"
00078 #include "unparse_target.h"
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 #define ST2C_COMPATIBLE_COMMON_BLOCK_TYPES(ty1, ty2) \
00090 Stab_Identical_Types(ty1, ty2, FALSE, TRUE, FALSE)
00091
00092
00093
00094
00095
00096 static void ST2C_ignore(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00097
00098 static void ST2C_decl_error(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00099 static void ST2C_decl_var(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00100 static void ST2C_decl_func(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00101 static void ST2C_decl_const(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00102
00103 static void ST2C_use_error(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00104 static void ST2C_use_var(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00105 static void ST2C_use_func(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00106 static void ST2C_use_const(TOKEN_BUFFER tokens, const ST *st, CONTEXT context);
00107
00108
00109
00110
00111
00112 typedef void (*ST2C_HANDLER_FUNC)(TOKEN_BUFFER, const ST*, CONTEXT);
00113
00114 static const ST2C_HANDLER_FUNC ST2C_Decl_Handle[CLASS_COUNT] =
00115 {
00116 &ST2C_ignore,
00117 &ST2C_decl_var,
00118 &ST2C_decl_func,
00119 &ST2C_decl_const,
00120 &ST2C_decl_error,
00121 &ST2C_decl_error,
00122 &ST2C_decl_error
00123 };
00124
00125 static const ST2C_HANDLER_FUNC ST2C_Use_Handle[CLASS_COUNT] =
00126 {
00127 &ST2C_ignore,
00128 &ST2C_use_var,
00129 &ST2C_use_func,
00130 &ST2C_use_const,
00131 &ST2C_use_error,
00132 &ST2C_decl_error,
00133 &ST2C_decl_error
00134 };
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 #define COMMON_BLOCK_MEMBER_NAME(num) \
00150 Concat2_Strings("u", Number_as_String(num, "%lld"))
00151
00152 typedef struct Ty2c_List TY2C_LIST;
00153 struct Ty2c_List
00154 {
00155 SYMTAB_IDX symtab_id;
00156 TOKEN_BUFFER tokens;
00157 TY_IDX common_ty;
00158 TY2C_LIST *next;
00159 };
00160 #define TY2C_LIST_symtab_id(l) ((l)->symtab_id)
00161 #define TY2C_LIST_tokens(l) ((l)->tokens)
00162 #define TY2C_LIST_common_ty(l) ((l)->common_ty)
00163 #define TY2C_LIST_next(l) ((l)->next)
00164
00165 typedef struct Common_Block COMMON_BLOCK;
00166 struct Common_Block
00167 {
00168 const char *name;
00169 UINT64 hash_value;
00170 TOKEN_BUFFER initializer;
00171 TY2C_LIST *initialized;
00172 TY2C_LIST *variations;
00173 TY2C_LIST *last_variation;
00174 COMMON_BLOCK *next;
00175 };
00176 #define COMMON_BLOCK_name(cb) (cb)->name
00177 #define COMMON_BLOCK_hash_value(cb) (cb)->hash_value
00178 #define COMMON_BLOCK_initializer(cb) (cb)->initializer
00179 #define COMMON_BLOCK_initialized(cb) (cb)->initialized
00180 #define COMMON_BLOCK_variations(cb) (cb)->variations
00181 #define COMMON_BLOCK_last_variation(cb) (cb)->last_variation
00182 #define COMMON_BLOCK_next(cb) (cb)->next
00183
00184 #define COMMON_BLOCK_HASH_TABLE_SIZE 373
00185 static COMMON_BLOCK *Common_Block_Hash_Tbl[COMMON_BLOCK_HASH_TABLE_SIZE];
00186
00187
00188 #define TY2C_LIST_BLOCK_SIZE 16
00189 typedef struct Ty2c_List_Block TY2C_LIST_BLOCK;
00190 struct Ty2c_List_Block
00191 {
00192 TY2C_LIST element[TY2C_LIST_BLOCK_SIZE];
00193 TY2C_LIST_BLOCK *next;
00194 };
00195 #define TY2C_LIST_BLOCK_element(tb, n) &(tb)->element[n]
00196 #define TY2C_LIST_BLOCK_next(tb) (tb)->next
00197
00198 static TY2C_LIST_BLOCK *ST2C_Ty2c_List_Blocks = NULL;
00199 static TY2C_LIST *ST2C_Free_Ty2c_Lists = NULL;
00200
00201
00202 static BOOL
00203 In_Visible_Symtab(SYMTAB_IDX symtab, SYMTAB_IDX id)
00204 {
00205 SYMTAB_IDX tab;
00206
00207 for (tab = symtab; tab != 0 && tab != id; tab--);
00208 return tab != 0;
00209 }
00210
00211
00212 static COMMON_BLOCK *
00213 ST2C_Find_Common_Block(const char *name, UINT64 hash_value)
00214 {
00215
00216
00217
00218 COMMON_BLOCK *common;
00219 const UINT32 hash_idx = Name_Hash_Idx(hash_value,
00220 COMMON_BLOCK_HASH_TABLE_SIZE);
00221 Is_True((name != NULL && *name != '\0'),
00222 ("Expected non-empty name in ST2C_Find_Common_Block()"));
00223
00224 for (common = Common_Block_Hash_Tbl[hash_idx];
00225 (common != NULL &&
00226 (COMMON_BLOCK_hash_value(common) != hash_value ||
00227 strcmp(COMMON_BLOCK_name(common), name) != 0));
00228 common = COMMON_BLOCK_next(common));
00229
00230 return common;
00231 }
00232
00233
00234 static COMMON_BLOCK *
00235 ST2C_Get_Common_Block(const char *name, UINT64 hash_value)
00236 {
00237
00238
00239
00240 COMMON_BLOCK *common;
00241 const UINT32 hash_idx = Name_Hash_Idx(hash_value,
00242 COMMON_BLOCK_HASH_TABLE_SIZE);
00243
00244 common = ST2C_Find_Common_Block(name, hash_value);
00245 if (common == NULL)
00246 {
00247
00248 common = TYPE_ALLOC_N(COMMON_BLOCK, 1);
00249 COMMON_BLOCK_name(common) =
00250 strcpy(TYPE_ALLOC_N(char, strlen(name)+1), name);
00251 COMMON_BLOCK_hash_value(common) = hash_value;
00252 COMMON_BLOCK_initializer(common) = NULL;
00253 COMMON_BLOCK_initialized(common) = NULL;
00254 COMMON_BLOCK_variations(common) = NULL;
00255 COMMON_BLOCK_last_variation(common) = NULL;
00256 COMMON_BLOCK_next(common) = Common_Block_Hash_Tbl[hash_idx];
00257 Common_Block_Hash_Tbl[hash_idx] = common;
00258 }
00259 return common;
00260 }
00261
00262
00263 static TY2C_LIST *
00264 ST2C_Get_Common_Ty2c_List(COMMON_BLOCK *common,
00265 mUINT32 symtab_id,
00266 const ST *common_st,
00267 TY_IDX ty)
00268 {
00269
00270
00271
00272
00273
00274 INT ty2c_pos;
00275 TY2C_LIST *ty2c_list;
00276 TY2C_LIST_BLOCK *ty2c_list_block;
00277
00278 if (ST2C_Free_Ty2c_Lists == NULL)
00279 {
00280
00281 ty2c_list_block = TYPE_ALLOC_N(TY2C_LIST_BLOCK, 1);
00282 TY2C_LIST_BLOCK_next(ty2c_list_block) = ST2C_Ty2c_List_Blocks;
00283 ST2C_Ty2c_List_Blocks = ty2c_list_block;
00284
00285 ST2C_Free_Ty2c_Lists =
00286 TY2C_LIST_BLOCK_element(ST2C_Ty2c_List_Blocks, 0);
00287 for (ty2c_pos = 1; ty2c_pos < TY2C_LIST_BLOCK_SIZE; ty2c_pos++)
00288 TY2C_LIST_next(&ST2C_Free_Ty2c_Lists[ty2c_pos-1]) =
00289 &ST2C_Free_Ty2c_Lists[ty2c_pos];
00290 TY2C_LIST_next(&ST2C_Free_Ty2c_Lists[TY2C_LIST_BLOCK_SIZE-1]) = NULL;
00291 }
00292
00293
00294
00295
00296 for (ty2c_list = COMMON_BLOCK_variations(common);
00297 (ty2c_list != NULL &&
00298 !(In_Visible_Symtab(CURRENT_SYMTAB, TY2C_LIST_symtab_id(ty2c_list)) &&
00299 ST2C_COMPATIBLE_COMMON_BLOCK_TYPES(TY2C_LIST_common_ty(ty2c_list),
00300 ty)));
00301 ty2c_list = TY2C_LIST_next(ty2c_list));
00302
00303 if (ty2c_list == NULL)
00304 {
00305
00306
00307
00308
00309 CONTEXT context = INIT_CONTEXT;
00310 UINT indentation;
00311
00312 ty2c_list = ST2C_Free_Ty2c_Lists;
00313 ST2C_Free_Ty2c_Lists = TY2C_LIST_next(ST2C_Free_Ty2c_Lists);
00314
00315 TY2C_LIST_symtab_id(ty2c_list) = symtab_id;
00316 TY2C_LIST_common_ty(ty2c_list) = ty;
00317 TY2C_LIST_next(ty2c_list) = NULL;
00318
00319 indentation = Current_Indentation();
00320 Set_Current_Indentation(0);
00321 Increment_Indentation();
00322 TY2C_LIST_tokens(ty2c_list) = New_Token_Buffer();
00323 Reset_TY_is_translated_to_c(ty);
00324 STR_IDX name_idx = TY_name_idx(Ty_Table[ty]);
00325
00326
00327 TY2C_translate(TY2C_LIST_tokens(ty2c_list), ty, context);
00328
00329
00330 Append_Token_String(TY2C_LIST_tokens(ty2c_list),ST_name(common_st));
00331
00332
00333 Set_TY_is_translated_to_c(ty);
00334 Set_Current_Indentation(indentation);
00335
00336 if (COMMON_BLOCK_variations(common) == NULL)
00337 {
00338 COMMON_BLOCK_variations(common) = ty2c_list;
00339 COMMON_BLOCK_last_variation(common) = ty2c_list;
00340 }
00341 else
00342 {
00343 TY2C_LIST_next(COMMON_BLOCK_last_variation(common)) = ty2c_list;
00344 }
00345 if (ST_is_initialized(common_st))
00346 {
00347 INITO_IDX inito = Find_INITO_For_Symbol(common_st);
00348
00349 if (inito != 0 && ty != shared_ptr_idx && ty != pshared_ptr_idx)
00350 {
00351 Is_True(!COMMON_BLOCK_initialized(common),
00352 ("Common block (%s) is initialized twice",
00353 ST_name(common_st)));
00354
00355 COMMON_BLOCK_initialized(common) = ty2c_list;
00356 COMMON_BLOCK_initializer(common) = New_Token_Buffer();
00357 inito = Find_INITO_For_Symbol(common_st);
00358 Append_Token_Special(COMMON_BLOCK_initializer(common), '=');
00359 INITO2C_translate(COMMON_BLOCK_initializer(common), inito);
00360 }
00361 }
00362 }
00363 return ty2c_list;
00364
00365 }
00366
00367
00368 static void
00369 ST2C_Define_A_Common_Block(TOKEN_BUFFER tokens,
00370 COMMON_BLOCK *common,
00371 CONTEXT context)
00372 {
00373 TOKEN_BUFFER union_tokens;
00374 const char *variation_name;
00375 const char *base_name;
00376 INT ordinal;
00377 TY2C_LIST *ty2c_list;
00378
00379 base_name = WHIRL2C_make_valid_c_name(COMMON_BLOCK_name(common));
00380
00381
00382
00383
00384 union_tokens = New_Token_Buffer();
00385
00386 ordinal = 0;
00387 for (ty2c_list = COMMON_BLOCK_variations(common);
00388 ty2c_list != NULL;
00389 ty2c_list = TY2C_LIST_next(ty2c_list), ordinal++)
00390 {
00391 variation_name = COMMON_BLOCK_MEMBER_NAME(ordinal);
00392
00393
00394
00395 if (COMMON_BLOCK_initialized(common) == ty2c_list)
00396 {
00397
00398
00399
00400 Prepend_And_Reclaim_Token_List(union_tokens,
00401 &TY2C_LIST_tokens(ty2c_list));
00402 }
00403 else
00404 {
00405 Append_And_Reclaim_Token_List(union_tokens,
00406 &TY2C_LIST_tokens(ty2c_list));
00407
00408
00409
00410
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 if (COMMON_BLOCK_initialized(common) != NULL)
00428 {
00429 Append_And_Reclaim_Token_List(union_tokens,
00430 &COMMON_BLOCK_initializer(common));
00431 }
00432
00433 Append_Token_Special(union_tokens, ';');
00434 Append_And_Reclaim_Token_List(tokens, &union_tokens);
00435 }
00436
00437
00438 static const char *
00439 ST2C_Get_Common_Block_Name(const ST *st)
00440 {
00441 const char *base_name;
00442 INT ordinal;
00443 COMMON_BLOCK *common;
00444 TY2C_LIST *ty2c_list;
00445 TY2C_LIST *ty2c_list_iter;
00446
00447
00448 common =
00449 ST2C_Get_Common_Block(ST_name(st), Get_Hash_Value_For_Name(ST_name(st)));
00450 ty2c_list = ST2C_Get_Common_Ty2c_List(common,
00451 CURRENT_SYMTAB,
00452 st, ST_type(st));
00453 base_name = WHIRL2C_make_valid_c_name(COMMON_BLOCK_name(common));
00454
00455
00456
00457 return base_name;
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 }
00472
00473
00474
00475
00476
00477 static void
00478 ST2C_formal_ref_decl(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00479 {
00480 TOKEN_BUFFER decl_tokens = New_Token_Buffer();
00481
00482 Is_True(ST_sclass(st) == SCLASS_FORMAL_REF,
00483 ("Unexpected ST_sclass in ST2C_formal_ref_decl()"));
00484
00485 Append_Token_String(decl_tokens,
00486 W2CF_Symtab_Nameof_St(st));
00487 TY2C_translate(decl_tokens, Stab_Pointer_To(ST_type(st)), context);
00488
00489 Append_And_Reclaim_Token_List(tokens, &decl_tokens);
00490 }
00491
00492
00493 static void
00494 ST2C_basic_decl(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00495 {
00496 TOKEN_BUFFER decl_tokens = New_Token_Buffer();
00497
00498 Append_Token_String(decl_tokens,
00499 W2CF_Symtab_Nameof_St(st));
00500
00501
00502
00503
00504
00505 TY_IDX ty = ST_class(st) == CLASS_FUNC ? ST_pu_type(st) : ST_type(st);
00506 if (Compile_Upc) {
00507 if (TY_kind(ty) == KIND_STRUCT ||
00508 (TY_kind(ty) == KIND_FUNCTION &&
00509 TY_kind(W2X_Unparse_Target->Func_Return_Type(ty)) == KIND_STRUCT)) {
00510 CONTEXT_set_incomplete_ty2c(context);
00511 }
00512 }
00513
00514 TY2C_translate(decl_tokens,
00515 ST_sym_class(st) == CLASS_FUNC ? ST_pu_type(st) : ST_type(st),
00516 context);
00517
00518 if (!Stab_No_Linkage(st))
00519 {
00520
00521 if (ST_sym_class(st) == CLASS_FUNC &&
00522 PU_is_inline_function(Pu_Table[ST_pu(st)]))
00523 {
00524 Prepend_Token_String(decl_tokens, "__inline");
00525 } else if (ST_sym_class(st) == CLASS_FUNC &&
00526 ST_export(st) == EXPORT_LOCAL) {
00527
00528 Prepend_Token_String(decl_tokens, "static");
00529 } else if (ST_sclass(st) == SCLASS_FSTATIC ||
00530 ST_sclass(st) == SCLASS_PSTATIC ||
00531 ST_sclass(st) == SCLASS_CPLINIT ||
00532 ST_sclass(st) == SCLASS_EH_REGION ||
00533 ST_sclass(st) == SCLASS_EH_REGION_SUPP ||
00534 ST_sclass(st) == SCLASS_DISTR_ARRAY)
00535 {
00536 Prepend_Token_String(decl_tokens, "static");
00537 } else if (ST_sclass(st) == SCLASS_EXTERN ||
00538 ST_sclass(st) == SCLASS_TEXT)
00539 {
00540 Prepend_Token_String(decl_tokens, "extern");
00541 }
00542 }
00543
00544 Append_And_Reclaim_Token_List(tokens, &decl_tokens);
00545 }
00546
00547
00548 static void
00549 ST2C_Define_Preg(const char *name, TY_IDX ty, CONTEXT context)
00550 {
00551
00552
00553
00554 TOKEN_BUFFER decl_tokens = New_Token_Buffer();
00555 UINT current_indent = Current_Indentation();
00556
00557 Set_Current_Indentation(PUinfo_local_decls_indent);
00558 Append_Token_String(decl_tokens, name);
00559 TY2C_translate(decl_tokens, ty, context);
00560 Prepend_Token_String(decl_tokens, "register");
00561 Append_Token_Special(decl_tokens, ';');
00562 Append_Indented_Newline(decl_tokens, 1);
00563 Append_And_Reclaim_Token_List(PUinfo_local_decls, &decl_tokens);
00564 Set_Current_Indentation(current_indent);
00565 }
00566
00567
00568
00569
00570
00571 static void
00572 ST2C_ignore(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00573 {
00574 return;
00575 }
00576
00577
00578 static void
00579 ST2C_decl_error(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00580 {
00581 Is_True(FALSE,
00582 ("ST2C cannot declare this ST_sym_class (%d)", ST_sym_class(st)));
00583 }
00584
00585
00586 static void
00587 ST2C_decl_var(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00588 {
00589 INITO_IDX inito;
00590 Is_True(ST_sym_class(st)==CLASS_VAR, ("expected CLASS_VAR ST"));
00591 if (ST_is_initialized(st) && !Stab_No_Linkage(st))
00592 {
00593 ST2C_basic_decl(tokens, st, context);
00594 inito = Find_INITO_For_Symbol(st);
00595 if (inito != 0)
00596 {
00597 Append_Token_Special(tokens, '=');
00598 INITO2C_translate(tokens, inito);
00599 }
00600 }
00601 else if (ST_sclass(st) == SCLASS_FORMAL_REF)
00602 {
00603
00604
00605 ST2C_formal_ref_decl(tokens, st, context);
00606 }
00607 else
00608 {
00609
00610
00611
00612
00613 if (ST_sclass(st) == SCLASS_AUTO)
00614 CONTEXT_set_unqualified_ty2c(context);
00615 ST2C_basic_decl(tokens, st, context);
00616 }
00617 }
00618
00619
00620 static void
00621 ST2C_decl_func(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00622 {
00623 Is_True(ST_sym_class(st)==CLASS_FUNC, ("expected CLASS_FUNC ST"));
00624
00625
00626 ST2C_basic_decl(tokens, st, context);
00627
00628 }
00629
00630
00631 static void
00632 ST2C_decl_const(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00633 {
00634 Is_True(ST_sym_class(st)==CLASS_CONST, ("expected CLASS_CONST ST"));
00635
00636
00637
00638
00639
00640 # if 0
00641 ST2C_basic_decl(tokens, st, context);
00642 Append_Token_Special(tokens, '=');
00643 TCON2C_translate(tokens, STC_val(st));
00644 # endif
00645
00646 }
00647
00648
00649
00650
00651
00652
00653 static void
00654 ST2C_use_error(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00655 {
00656 Is_True(FALSE,
00657 ("ST2C cannot use an ST_sym_class (%d)", ST_sym_class(st)));
00658 }
00659
00660
00661 static void
00662 ST2C_use_var(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00663 {
00664 Is_True(ST_sym_class(st)==CLASS_VAR, ("expected CLASS_VAR ST"));
00665
00666
00667 if (Stab_Is_Common_Block(st) && !(Compile_Upc && ST_sclass(st) == SCLASS_DGLOBAL))
00668 {
00669
00670
00671
00672
00673 Append_Token_String(tokens, ST2C_Get_Common_Block_Name(st));
00674
00675 }
00676 else
00677 {
00678 Append_Token_String(tokens, W2CF_Symtab_Nameof_St(st));
00679
00680
00681
00682 if (!Stab_External_Def_Linkage(st))
00683 Set_BE_ST_w2fc_referenced(st);
00684 }
00685 }
00686
00687
00688 static void
00689 ST2C_use_func(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00690 {
00691 Is_True(ST_sym_class(st)==CLASS_FUNC, ("expected CLASS_FUNC ST"));
00692 Append_Token_String(tokens, W2CF_Symtab_Nameof_St(st));
00693 if (!Stab_External_Def_Linkage(st))
00694 Set_BE_ST_w2fc_referenced(st);
00695 }
00696
00697
00698 static void
00699 ST2C_use_const(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00700 {
00701 Is_True(ST_sym_class(st)==CLASS_CONST, ("expected CLASS_CONST ST"));
00702
00703 Append_Token_String(tokens, W2CF_Symtab_Nameof_St(st));
00704 }
00705
00706
00707
00708
00709
00710
00711 void
00712 ST2C_initialize(CONTEXT context)
00713 {
00714 return;
00715 }
00716
00717
00718 void
00719 ST2C_finalize(void)
00720 {
00721 INT hash_idx;
00722 COMMON_BLOCK *common;
00723 TY2C_LIST_BLOCK *ty2c_list_block;
00724 void *to_be_freed;
00725
00726
00727 for (hash_idx = 0; hash_idx < COMMON_BLOCK_HASH_TABLE_SIZE; hash_idx++)
00728 {
00729
00730 common = Common_Block_Hash_Tbl[hash_idx];
00731 while (common != NULL)
00732 {
00733 to_be_freed = (void *)COMMON_BLOCK_name(common);
00734 FREE(to_be_freed);
00735 to_be_freed = common;
00736 common = COMMON_BLOCK_next(common);
00737 FREE(to_be_freed);
00738 }
00739 Common_Block_Hash_Tbl[hash_idx] = NULL;
00740 }
00741
00742
00743 ty2c_list_block = ST2C_Ty2c_List_Blocks;
00744 while (ty2c_list_block != NULL)
00745 {
00746 to_be_freed = ty2c_list_block;
00747 ty2c_list_block = TY2C_LIST_BLOCK_next(ty2c_list_block);
00748 FREE(to_be_freed);
00749 }
00750 ST2C_Ty2c_List_Blocks = NULL;
00751
00752 }
00753
00754
00755 void
00756 ST2C_decl_translate(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00757 {
00758 ST2C_Decl_Handle[ST_sym_class(st)](tokens, st, context);
00759 }
00760
00761
00762 void
00763 ST2C_weakext_translate(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00764 {
00765 Is_True(ST_is_weak_symbol(st),
00766 ("Expected weak symbol in ST2C_weakext_translate()"));
00767
00768 ST2C_decl_translate(tokens, st, context);
00769 Append_Token_Special(tokens, ';');
00770 Append_Indented_Newline(tokens, 1);
00771 Append_Token_String(tokens, "#pragma");
00772 Append_Token_String(tokens, "weak");
00773 ST2C_use_translate(tokens, st, context);
00774
00775 if (ST_is_weak_symbol(st) &&
00776 Has_Base_Block(st) &&
00777 ST_sym_class(ST_base(st)) != CLASS_BLOCK)
00778 {
00779 Append_Token_Special(tokens, '=');
00780 ST2C_use_translate(tokens, ST_strong(st), context);
00781 }
00782 }
00783
00784
00785 void
00786 ST2C_use_translate(TOKEN_BUFFER tokens, const ST *st, CONTEXT context)
00787 {
00788 ST2C_Use_Handle[ST_sym_class(st)](tokens, st, context);
00789 }
00790
00791
00792 void
00793 ST2C_func_header(TOKEN_BUFFER tokens,
00794 const ST *st,
00795 ST **params,
00796 CONTEXT context)
00797 {
00798
00799
00800
00801
00802 TOKEN_BUFFER header_tokens = New_Token_Buffer();
00803 INT param, first_param;
00804 TY_IDX funtype = ST_pu_type(st);
00805 BOOL has_prototype = TY_has_prototype(funtype);
00806
00807 Is_True(TY_Is_Function(funtype),
00808 ("Non-function passed to ST2C_func_header"));
00809 Is_True((ST_sclass(st) == SCLASS_TEXT || ST_sclass(st) == SCLASS_EXTERN),
00810 ("Illegal ST_sclass for function"));
00811
00812
00813
00814
00815 first_param = (PUINFO_RETURN_TO_PARAM? 1 : 0);
00816
00817
00818 if (PU_is_mainpu(Pu_Table[ST_pu(st)]))
00819 Append_Token_String(header_tokens, "main");
00820 else
00821 Append_Token_String(header_tokens, W2CF_Symtab_Nameof_St(st));
00822
00823
00824 Append_Token_Special(header_tokens, '(');
00825
00826
00827 if (!has_prototype)
00828 {
00829 for (param = first_param; params[param] != NULL; param++)
00830 {
00831 Append_Token_String(header_tokens,
00832 W2CF_Symtab_Nameof_St(params[param]));
00833 if (params[param+1] != NULL)
00834 Append_Token_Special(header_tokens, ',');
00835 }
00836 Append_Token_Special(header_tokens, ')');
00837
00838
00839 if (Compile_Upc) {
00840 CONTEXT_set_incomplete_ty2c(context);
00841 }
00842 TY2C_translate(header_tokens, W2X_Unparse_Target->Func_Return_Type(funtype), context);
00843
00844
00845 Increment_Indentation();
00846 for (param = first_param; params[param] != NULL; param++)
00847 {
00848 Append_Indented_Newline(header_tokens, 1);
00849 ST2C_decl_translate(header_tokens, params[param], context);
00850 Append_Token_Special(header_tokens, ';');
00851 }
00852 Decrement_Indentation();
00853 }
00854 else
00855 {
00856
00857 TYLIST_IDX param_tylist = TY_parms(funtype);
00858 Increment_Indentation();
00859 for (param = first_param; params[param] != NULL; param++)
00860 {
00861 Append_Indented_Newline(header_tokens, 1);
00862 if (FALSE &&
00863 Tylist_Table[param_tylist] != TY_IDX_ZERO)
00864 {
00865
00866
00867 TY_IDX param_ty_idx = ST_type(params[param]);
00868 Set_ST_type(*params[param], Tylist_Table[param_tylist]);
00869 ST2C_decl_translate(header_tokens, params[param], context);
00870 Set_ST_type(*params[param], param_ty_idx);
00871 param_tylist = TYLIST_next(param_tylist);
00872 }
00873 else
00874 {
00875 ST2C_decl_translate(header_tokens, params[param], context);
00876 }
00877 if (params[param+1] != NULL)
00878 Append_Token_Special(header_tokens, ',');
00879 }
00880
00881
00882 if (TY_is_varargs(funtype))
00883 {
00884 Append_Token_Special(header_tokens, ',');
00885 Append_Token_String(header_tokens, "...");
00886 }
00887 Append_Token_Special(header_tokens, ')');
00888 Decrement_Indentation();
00889 TY2C_translate(header_tokens, W2X_Unparse_Target->Func_Return_Type(funtype), context);
00890 }
00891
00892 if (PU_is_inline_function(Pu_Table[ST_pu(st)]))
00893 Prepend_Token_String(header_tokens, "__inline");
00894 if (ST_sclass(st) == SCLASS_FSTATIC)
00895 Prepend_Token_String(header_tokens, "static");
00896
00897 Append_And_Reclaim_Token_List(tokens, &header_tokens);
00898 }
00899
00900
00901 void
00902 ST2C_Use_Preg(TOKEN_BUFFER tokens,
00903 TY_IDX preg_ty,
00904 PREG_IDX preg_idx,
00905 CONTEXT context)
00906 {
00907
00908
00909
00910 const char *preg_name;
00911
00912 preg_ty = PUinfo_Preg_Type(preg_ty, preg_idx);
00913 preg_name = W2CF_Symtab_Nameof_Preg(preg_ty, preg_idx);
00914
00915
00916 if (!PUinfo_Is_Preg_Declared(preg_ty, preg_idx))
00917 {
00918 ST2C_Define_Preg(preg_name, preg_ty, context);
00919 PUinfo_Set_Preg_Declared(preg_ty, preg_idx);
00920 }
00921
00922 Append_Token_String(tokens, preg_name);
00923 }
00924
00925
00926 void ST2C_Declare_Tempvar(TY_IDX ty, UINT idx)
00927 {
00928 TOKEN_BUFFER tmp_tokens = New_Token_Buffer();
00929 UINT current_indent = Current_Indentation();
00930 CONTEXT ty_context;
00931
00932 Set_Current_Indentation(PUinfo_local_decls_indent);
00933 Append_Token_String(
00934 tmp_tokens, W2CF_Symtab_Nameof_Tempvar(idx));
00935
00936
00937
00938
00939
00940 CONTEXT_reset(ty_context);
00941 CONTEXT_set_unqualified_ty2c(ty_context);
00942 TY2C_translate(tmp_tokens, ty, ty_context);
00943 Append_Token_Special(tmp_tokens, ';');
00944 Append_Indented_Newline(tmp_tokens, 1);
00945 Append_And_Reclaim_Token_List(PUinfo_local_decls, &tmp_tokens);
00946 Set_Current_Indentation(current_indent);
00947 }
00948
00949
00950 void
00951 ST2C_New_Common_Block(const ST *st)
00952 {
00953
00954
00955
00956
00957
00958 const char *name = ST_name(st);
00959 const UINT64 hash_value = Get_Hash_Value_For_Name(name);
00960 TY_IDX ty = ST_type(st);
00961 COMMON_BLOCK *common;
00962
00963 Is_True(Stab_Is_Common_Block(st),
00964 ("Expected common block in ST2C_New_Common_Block()"));
00965
00966
00967
00968
00969 common = ST2C_Get_Common_Block(name, hash_value);
00970 (void)ST2C_Get_Common_Ty2c_List(common, CURRENT_SYMTAB, st, ty);
00971
00972 Set_TY_is_translated_to_c(ty);
00973 }
00974
00975
00976 void
00977 ST2C_Define_Common_Blocks(TOKEN_BUFFER tokens, CONTEXT context)
00978 {
00979 INT hash_idx;
00980 COMMON_BLOCK *common;
00981
00982
00983 for (hash_idx = 0; hash_idx < COMMON_BLOCK_HASH_TABLE_SIZE; hash_idx++)
00984 {
00985
00986 for (common = Common_Block_Hash_Tbl[hash_idx];
00987 common != NULL;
00988 common = COMMON_BLOCK_next(common))
00989 {
00990 ST2C_Define_A_Common_Block(tokens, common, context);
00991 Append_Indented_Newline(tokens, 2);
00992 }
00993 }
00994 }
00995
00996
00997