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