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 #include <values.h>
00055 #include <sys/types.h>
00056 #include <elf.h>
00057 #include "defs.h"
00058 #include "errors.h"
00059 extern "C" {
00060 #include "gnu_config.h"
00061 }
00062 #ifdef KEY // get HW_WIDE_INT for flags.h
00063 #include "gnu/hwint.h"
00064 #endif
00065 extern "C" {
00066 #include "gnu/flags.h"
00067 #include "gnu/system.h"
00068 #include "gnu/toplev.h"
00069 #include "gnu/tree.h"
00070 #include "cp-tree.h"
00071 #include "c-pragma.h"
00072 #ifdef KEY // get REAL_VALUE_TYPE
00073 #include "real.h"
00074 #endif // KEY
00075 }
00076 #undef TARGET_PENTIUM // hack around macro definition in gnu
00077 #include "glob.h"
00078 #include "wn.h"
00079 #include "wn_util.h"
00080 #include "symtab.h"
00081 #include "const.h"
00082 #include "pu_info.h"
00083 #include "ir_bwrite.h"
00084 #include "ir_reader.h"
00085 #include "wfe_decl.h"
00086 #include "wfe_misc.h"
00087 #include "wfe_dst.h"
00088 #include "tree_symtab.h"
00089 #include "wfe_expr.h"
00090 #include "wfe_stmt.h"
00091 #include "tree_cmp.h"
00092 #ifdef KEY
00093 #include "wfe_dst.h"
00094 #endif
00095 #include "targ_sim.h"
00096
00097 extern "C" void check_gnu_errors (int *, int *);
00098 #ifdef KEY
00099 extern void WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_ID, ST *);
00100 #ifdef Is_True_On
00101 extern "C" int flag_openmp;
00102 #endif
00103 extern "C" tree lookup_name (tree, int);
00104
00105 static tree WFE_get_thunk_target (tree decl);
00106 static void WFE_Handle_Named_Return_Value(tree fn);
00107
00108
00109
00110
00111 tree named_ret_obj_initializer;
00112 extern "C" BOOL pragma_implementation_seen, pragma_interface_seen;
00113
00114
00115 ST * Dummy_Exc_Ptr_Expr = NULL;
00116 #endif
00117
00118 static tree *deferred_function_stack;
00119 static INT32 deferred_function_i;
00120 static INT32 deferred_function_max;
00121
00122 static void
00123 Init_Deferred_Function_Stack()
00124 {
00125 deferred_function_max = 32;
00126 deferred_function_i = -1;
00127 deferred_function_stack =
00128 (tree *) malloc (sizeof (tree) * deferred_function_max);
00129 }
00130
00131 void
00132 Push_Deferred_Function (tree decl)
00133 {
00134
00135 for (INT32 i = deferred_function_i; i != -1; --i)
00136 if (deferred_function_stack [i] == decl)
00137 return;
00138
00139
00140 if (++deferred_function_i == deferred_function_max) {
00141 deferred_function_max = 2 * deferred_function_max;
00142 deferred_function_stack =
00143 (tree *) realloc (deferred_function_stack,
00144 deferred_function_max * sizeof(tree));
00145 }
00146
00147 deferred_function_stack[deferred_function_i] = decl;
00148 }
00149
00150 static tree
00151 Pop_Deferred_Function (void)
00152 {
00153 tree decl;
00154 decl = deferred_function_stack[deferred_function_i--];
00155
00156 return decl;
00157 }
00158
00159 static tree *deferred_decl_init_stack;
00160 static INT32 deferred_decl_init_i;
00161 static INT32 deferred_decl_init_max;
00162
00163 static void
00164 Init_Deferred_Decl_Init_Stack ()
00165 {
00166 deferred_decl_init_max = 32;
00167 deferred_decl_init_i = -1;
00168 deferred_decl_init_stack =
00169 (tree *) malloc (sizeof (tree) * deferred_decl_init_max);
00170 }
00171
00172 void
00173 Push_Deferred_Decl_Init (tree decl)
00174 {
00175 if (++deferred_decl_init_i == deferred_decl_init_max) {
00176 deferred_decl_init_max = 2 * deferred_decl_init_max;
00177 deferred_decl_init_stack =
00178 (tree *) realloc (deferred_decl_init_stack,
00179 deferred_decl_init_max * sizeof(tree));
00180 }
00181
00182 deferred_decl_init_stack[deferred_decl_init_i] = decl;
00183 }
00184
00185 static tree
00186 Pop_Deferred_Decl_Init (void)
00187 {
00188 tree decl;
00189 decl = deferred_decl_init_stack[deferred_decl_init_i--];
00190 return decl;
00191 }
00192
00193 extern PU_Info *PU_Tree_Root;
00194 static PU_Info *PU_Info_Table [258] = {0};
00195 static ST *Return_Address_ST [258] = {0};
00196 static BOOL map_mempool_initialized = FALSE;
00197 static MEM_POOL Map_Mem_Pool;
00198
00199 static tree curr_func_decl = NULL_TREE;
00200 #ifdef KEY
00201 static tree curr_namespace_decl = NULL_TREE;
00202 #endif
00203
00204 static int __ctors = 0;
00205 static int __dtors = 0;
00206
00207 static void Set_Current_Function_Decl(tree decl)
00208 {
00209 curr_func_decl = decl;
00210 }
00211
00212 tree Current_Function_Decl(void) {return curr_func_decl;}
00213
00214
00215
00216 #ifdef KEY
00217
00218
00219 static std::vector<WN*> curr_entry_wn;
00220 static void Push_Current_Entry_WN(WN *wn) { curr_entry_wn.push_back(wn); }
00221 static void Pop_Current_Entry_WN() { curr_entry_wn.pop_back(); }
00222 WN *Current_Entry_WN(void) { return curr_entry_wn.back(); }
00223
00224
00225
00226
00227 std::vector<tree> gxx_emitted_decls;
00228
00229 std::vector<tree> emit_typeinfos;
00230
00231 std::vector<tree> emit_decls;
00232
00233 std::vector<char *> gxx_emitted_asm;
00234
00235 std::vector<std::pair<tree, FLD_HANDLE> > defer_fields;
00236
00237 #include <stack>
00238
00239
00240
00241
00242
00243 std::stack<tree> mp_local_vars;
00244
00245
00246 class tsubst_var {
00247 tree orig;
00248 tree sub;
00249 tree func_decl;
00250 public:
00251 tsubst_var (tree o, tree s, tree f) : orig(o), sub(s), func_decl(f) {}
00252 tree equal (tree o, tree f) const {
00253 return (orig == o && func_decl == f) ? sub : NULL;
00254 }
00255 };
00256
00257 std::vector<tsubst_var> tsubst_map;
00258
00259 void
00260 template_substituted (tree orig, tree sub, tree func_decl) {
00261 tsubst_var in (orig, sub, func_decl);
00262 tsubst_map.push_back (in);
00263 }
00264
00265 tree
00266 get_substituted (tree orig, tree func_decl) {
00267 vector<tsubst_var>::const_iterator it = tsubst_map.begin();
00268
00269 for (; it != tsubst_map.end(); it++) {
00270 tree sub = (*it).equal (orig, func_decl);
00271 if (sub) return sub;
00272 }
00273 return NULL;
00274 }
00275
00276 void
00277 push_mp_local_vars (tree decl)
00278 {
00279 Is_True (flag_openmp, ("Should not reach here without -mp"));
00280 mp_local_vars.push (decl);
00281 }
00282
00283 tree
00284 pop_mp_local_vars (void)
00285 {
00286 Is_True (flag_openmp, ("Should not reach here without -mp"));
00287 if (mp_local_vars.empty()) return NULL;
00288 tree decl = mp_local_vars.top ();
00289 mp_local_vars.pop ();
00290 return decl;
00291 }
00292
00293 void
00294 gxx_emits_decl(tree t) {
00295 gxx_emitted_decls.push_back(t);
00296 }
00297
00298 void
00299 gxx_emits_typeinfos (tree t) {
00300 emit_typeinfos.push_back (t);
00301 }
00302
00303 void
00304 defer_decl (tree t) {
00305 emit_decls.push_back (t);
00306 }
00307
00308 void
00309 gxx_emits_asm (char *str) {
00310 gxx_emitted_asm.push_back (str);
00311 }
00312
00313 void
00314 defer_field (tree t, FLD_HANDLE fld) {
00315 defer_fields.push_back (std::make_pair(t, fld));
00316 }
00317
00318
00319 typedef struct {
00320 union {
00321 struct {
00322 tree context;
00323 tree fndecl;
00324 } member_func;
00325 } u1;
00326 int is_member_function : 1;
00327 } DST_defer_misc_info;
00328
00329
00330 std::vector<DST_defer_misc_info *> defer_DST_misc;
00331
00332 typedef struct {
00333 tree t;
00334 TY_IDX ttidx;
00335 TY_IDX idx;
00336 } DST_defer_type_info;
00337
00338
00339 std::vector<DST_defer_type_info *> defer_DST_types;
00340
00341 void
00342 defer_DST_type (tree t, TY_IDX ttidx, TY_IDX idx)
00343 {
00344 DST_defer_type_info *p =
00345 (DST_defer_type_info *) calloc(1, sizeof(DST_defer_type_info));
00346 p->t = t;
00347 p->ttidx = ttidx;
00348 p->idx = idx;
00349 defer_DST_types.push_back(p);
00350 }
00351
00352 void
00353 defer_DST_member_function (tree context, tree fndecl)
00354 {
00355 DST_defer_misc_info *p =
00356 (DST_defer_misc_info *) calloc(1, sizeof(DST_defer_misc_info));
00357 p->u1.member_func.context = context;
00358 p->u1.member_func.fndecl = fndecl;
00359 p->is_member_function = 1;
00360 defer_DST_misc.push_back (p);
00361 }
00362 #endif
00363
00364
00365 static int
00366 WFE_Expand_Function_Body (tree decl)
00367 {
00368 tree body;
00369
00370 #ifdef KEY
00371 if (expanded_decl(decl) == TRUE)
00372 return 0;
00373
00374
00375
00376
00377
00378
00379 if (
00380 !(TREE_PUBLIC(decl) && !DECL_COMDAT(decl)) &&
00381
00382 DECL_INLINE(decl) &&
00383 !flag_keep_inline_functions &&
00384
00385 DECL_COPY_CONSTRUCTOR_P(decl) &&
00386 DECL_COMPLETE_CONSTRUCTOR_P(decl) &&
00387
00388 DECL_ASSEMBLER_NAME(decl) &&
00389 !TREE_SYMBOL_REFERENCED_BY_WHIRL(DECL_ASSEMBLER_NAME(decl))) {
00390 return 0;
00391 }
00392
00393 expanded_decl(decl) = TRUE;
00394 #endif
00395
00396 (void) WFE_Start_Function(decl);
00397 Set_Current_Function_Decl(decl);
00398
00399 #ifdef KEY
00400 WFE_Handle_Named_Return_Value(decl);
00401
00402
00403
00404
00405
00406
00407 Push_Top_Level_Scope(decl);
00408 #endif
00409
00410 for (body = DECL_SAVED_TREE(decl); body; body = TREE_CHAIN(body))
00411 Mark_Scopes_And_Labels (body);
00412 #ifdef KEY // bug 11869
00413 Pop_Top_Level_Scope();
00414 #endif
00415
00416 for (body = DECL_SAVED_TREE(decl); body; body = TREE_CHAIN(body))
00417 WFE_Expand_Stmt(body);
00418
00419 WFE_Finish_Function();
00420 return 1;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 void WFE_Finish_Function(void);
00433
00434 static void
00435 WFE_Generate_Thunk (tree decl)
00436 {
00437 #ifdef KEY
00438 if (expanded_decl(decl) == TRUE)
00439 return;
00440 expanded_decl(decl) = TRUE;
00441 #endif
00442
00443 Is_True(decl != NULL &&
00444 TREE_CODE(decl) == FUNCTION_DECL &&
00445 DECL_THUNK_P(decl) &&
00446 TREE_CODE(CP_DECL_CONTEXT(decl)) != NAMESPACE_DECL,
00447 ("Argument to WFE_Generate_Thunk isn't a thunk"));
00448
00449 Is_True(DECL_INITIAL(decl) != NULL,
00450 ("Argument to WFE_Generate_Thunk has null DECL_INITIAL"));
00451
00452 ST *thunk_st = Get_ST (decl);
00453 #ifdef KEY
00454
00455 ST *func_st = Get_ST (TREE_OPERAND (WFE_get_thunk_target(decl), 0));
00456 #else
00457 ST *func_st = Get_ST (TREE_OPERAND (DECL_INITIAL(decl), 0));
00458 #endif // KEY
00459 TYPE_ID ret_mtype = TY_mtype (TY_ret_type (ST_pu_type (func_st)));
00460 WN *entry_wn = WFE_Start_Function (decl);
00461 INT32 nargs = WN_kid_count (entry_wn) - 3;
00462 INT32 i;
00463 ST *arg_st;
00464 TY_IDX arg_ty;
00465 TYPE_ID arg_mtype;
00466 WN *arg_wn;
00467 WN *wn;
00468 WN *call_wn;
00469
00470
00471 #ifdef KEY
00472
00473
00474 TY_IDX ret_ty_idx = Get_TY(TREE_TYPE(TREE_TYPE(decl)));
00475 if (TY_return_in_mem(ret_ty_idx))
00476 arg_st = WN_st (WN_kid1 (entry_wn));
00477 else
00478 #endif
00479 arg_st = WN_st (WN_kid0 (entry_wn));
00480 arg_ty = ST_type (arg_st);
00481 arg_mtype = TY_mtype (arg_ty);
00482
00483
00484
00485
00486
00487 wn = WN_Binary (OPR_ADD, arg_mtype,
00488 WN_Ldid (arg_mtype, 0, arg_st, arg_ty),
00489 WN_Intconst (arg_mtype, THUNK_DELTA(decl)));
00490 if (THUNK_VCALL_OFFSET(decl) != 0) {
00491 DevWarn ("Generating thunk with vcall adjustment at line %d\n", lineno);
00492 TY_IDX pdiff;
00493
00494
00495 switch (TY_mtype(Get_TY(ptrdiff_type_node))) {
00496 case MTYPE_I4:
00497 case MTYPE_U4:
00498 pdiff = MTYPE_To_TY(MTYPE_U4);
00499 break;
00500 case MTYPE_I8:
00501 case MTYPE_U8:
00502 pdiff = MTYPE_To_TY(MTYPE_U8);
00503 break;
00504 default:
00505 FmtAssert(FALSE, ("WFE_Generate_Thunk unexpected type"));
00506 }
00507
00508 TY_IDX p_pdiff = Make_Pointer_Type(pdiff, FALSE);
00509 TY_IDX pp_pdiff = Make_Pointer_Type(p_pdiff, FALSE);
00510
00511 WN* deref = WN_CreateIload(OPR_ILOAD,
00512 TY_mtype(p_pdiff), TY_mtype(pp_pdiff),
00513 0,
00514 p_pdiff, pp_pdiff,
00515 WN_Tas(TY_mtype(pp_pdiff), pp_pdiff,
00516 WN_COPY_Tree(wn)));
00517
00518
00519 FmtAssert(TREE_INT_CST_HIGH(THUNK_VCALL_OFFSET(decl)) == 0 ||
00520 TREE_INT_CST_HIGH(THUNK_VCALL_OFFSET(decl)) == ~0,
00521 ("WFE_Generate_Thunk unexpected integer size"));
00522 INT32 offset = TREE_INT_CST_LOW(THUNK_VCALL_OFFSET(decl));
00523 wn = WN_Binary (OPR_ADD, arg_mtype,
00524 wn,
00525 WN_CreateIload(OPR_ILOAD,
00526 TY_mtype(pdiff), TY_mtype(p_pdiff),
00527 offset, pdiff, p_pdiff, deref));
00528 }
00529 wn = WN_Stid (arg_mtype, 0, arg_st, arg_ty, wn);
00530 WFE_Stmt_Append (wn, Get_Srcpos());
00531
00532
00533 call_wn = WN_Create (OPR_CALL, ret_mtype, MTYPE_V, nargs);
00534 WN_st_idx (call_wn) = ST_st_idx (func_st);
00535 WN_Set_Call_Default_Flags (call_wn);
00536 WN_Set_Call_Replace_By_Jump (call_wn);
00537 for (i = 0; i < nargs; i++) {
00538 arg_st = WN_st (WN_kid (entry_wn, i));
00539 arg_ty = ST_type (arg_st);
00540 arg_mtype = TY_mtype (arg_ty);
00541 arg_wn = WN_Ldid (arg_mtype, 0, arg_st, arg_ty);
00542 arg_wn = WN_CreateParm (Mtype_comparison (arg_mtype), arg_wn,
00543 arg_ty, WN_PARM_BY_VALUE);
00544 WN_kid (call_wn, i) = arg_wn;
00545 }
00546
00547 if (ret_mtype == MTYPE_V) {
00548
00549 WFE_Stmt_Append (call_wn, Get_Srcpos());
00550 wn = WN_CreateReturn ();
00551 WFE_Stmt_Append (wn, Get_Srcpos());
00552 }
00553
00554 else {
00555
00556 WN *block_wn = WN_CreateBlock ();
00557 WN_INSERT_BlockLast (block_wn, call_wn);
00558 wn = WN_Ldid (ret_mtype, -1, Return_Val_Preg, Be_Type_Tbl (ret_mtype));
00559 wn = WN_CreateComma (OPR_COMMA, Mtype_comparison (ret_mtype), MTYPE_V,
00560 block_wn, wn);
00561 wn = WN_CreateReturn_Val (OPR_RETURN_VAL, ret_mtype, MTYPE_V, wn);
00562 WFE_Stmt_Append (wn, Get_Srcpos());
00563 }
00564
00565 Set_PU_is_thunk (Get_Current_PU ());
00566 WFE_Finish_Function ();
00567 }
00568
00569 static void process_local_classes()
00570 {
00571 for (int i = 0; i < local_classes->elements_used; ++i) {
00572 tree t = VARRAY_TREE(local_classes, i);
00573 if (t->common.code == RECORD_TYPE ||
00574 t->common.code == UNION_TYPE)
00575 Get_TY(t);
00576 }
00577 }
00578
00579 void WFE_Expand_Decl(tree decl)
00580 {
00581 Is_True(decl != NULL && TREE_CODE_CLASS(TREE_CODE(decl)) == 'd',
00582 ("Argument to WFE_Expand_Decl isn't a decl node"));
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 switch (TREE_CODE(decl)) {
00593
00594 case CONST_DECL:
00595 {
00596
00597 static BOOL once_is_enough=FALSE;
00598 if (!once_is_enough) {
00599 DevWarn("WFE_Expand_Decl: don't know what to do with CONST_DECL");
00600 once_is_enough = TRUE;
00601 }
00602 }
00603 break;
00604
00605 case FUNCTION_DECL:
00606 if (DECL_THUNK_P(decl) &&
00607 TREE_CODE(CP_DECL_CONTEXT(decl)) != NAMESPACE_DECL) {
00608 WFE_Generate_Thunk(decl);
00609 }
00610 #ifdef KEY
00611
00612 else if (DECL_ALIAS_TARGET(decl)) {
00613 WFE_Assemble_Alias(decl, DECL_ALIAS_TARGET(decl));
00614 return;
00615 }
00616 #endif
00617 else {
00618 tree body = DECL_SAVED_TREE(decl);
00619 if (body != NULL_TREE && !DECL_EXTERNAL(decl) &&
00620 #ifndef KEY
00621
00622
00623 (DECL_TEMPLATE_INFO(decl) == NULL ||
00624 DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(decl) ||
00625 DECL_TEMPLATE_INSTANTIATED(decl) ||
00626 DECL_TEMPLATE_SPECIALIZATION(decl)) &&
00627 #endif
00628 !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(decl) &&
00629 !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(decl)) {
00630
00631 #ifndef KEY // Don't call Get_ST we don't have a PU to attach the ST to
00632
00633
00634
00635 (void) Get_ST(decl);
00636 #endif
00637 if (!Enable_WFE_DFE) {
00638 if (CURRENT_SYMTAB != GLOBAL_SYMTAB ||
00639 DECL_FUNCTION_MEMBER_P(decl) ||
00640 strncmp (IDENTIFIER_POINTER(DECL_NAME(decl)), "__tcf", 5) == 0)
00641 Push_Deferred_Function (decl);
00642 else {
00643 WFE_Expand_Function_Body (decl);
00644 #ifndef KEY
00645 while (deferred_function_i != -1)
00646 WFE_Expand_Function_Body (Pop_Deferred_Function ());
00647 #endif
00648 }
00649 }
00650 }
00651 }
00652
00653 break;
00654
00655 case NAMESPACE_DECL: {
00656
00657
00658
00659
00660
00661
00662 if (DECL_NAMESPACE_ALIAS(decl))
00663 break;
00664 #ifdef KEY
00665 tree old_namespace_decl = curr_namespace_decl;
00666 curr_namespace_decl = decl;
00667 #endif
00668 tree subdecl;
00669 for (subdecl = cp_namespace_decls(decl);
00670 subdecl != NULL_TREE;
00671 subdecl = TREE_CHAIN(subdecl))
00672 WFE_Expand_Decl(subdecl);
00673 if (decl == global_namespace)
00674 process_local_classes();
00675 #ifndef KEY
00676 while (deferred_function_i != -1) {
00677
00678 WFE_Expand_Function_Body (Pop_Deferred_Function ());
00679 }
00680 #endif
00681 #ifdef KEY
00682 curr_namespace_decl = old_namespace_decl;
00683 #endif
00684 break;
00685 }
00686
00687 case TEMPLATE_DECL: {
00688 if (DECL_CONTEXT(decl) && TREE_CODE(DECL_CONTEXT(decl)) == RECORD_TYPE)
00689 Get_TY(DECL_CONTEXT(decl));
00690 tree gentemp = most_general_template(decl);
00691 for (tree t = DECL_TEMPLATE_SPECIALIZATIONS(gentemp);
00692 t; t = TREE_CHAIN(t))
00693 if (TREE_CODE(TREE_VALUE(t)) == FUNCTION_DECL &&
00694 !DECL_EXTERNAL(TREE_VALUE(t)) &&
00695 !uses_template_parms (TREE_VALUE(t)))
00696 WFE_Expand_Decl (TREE_VALUE(t));
00697 DECL_TEMPLATE_SPECIALIZATIONS(gentemp) = 0;
00698
00699 for (tree t = DECL_TEMPLATE_INSTANTIATIONS(gentemp);
00700 t; t = TREE_CHAIN(t)) {
00701 tree val = TREE_VALUE(t);
00702 if (TREE_CODE(val) == RECORD_TYPE &&
00703 !uses_template_parms(val))
00704 Get_TY(val);
00705 }
00706
00707 break;
00708 }
00709
00710 case TREE_VEC:
00711 break;
00712
00713 case TYPE_DECL: {
00714 #ifndef KEY // bug 7341: Generate types only on demand
00715 tree type = TREE_TYPE(decl);
00716 (void) Get_TY(type);
00717 #endif
00718 break;
00719 }
00720
00721 case VAR_DECL:
00722 #ifdef KEY
00723
00724
00725
00726
00727
00728
00729
00730
00731 if (DECL_ASSEMBLER_NAME_SET_P(decl) &&
00732 TREE_NOT_EMITTED_BY_GXX(decl) &&
00733 !TREE_SYMBOL_REFERENCED(DECL_ASSEMBLER_NAME(decl))) {
00734 expanded_decl(decl) = TRUE;
00735 return;
00736 }
00737
00738
00739 if (DECL_ALIAS_TARGET(decl)) {
00740 WFE_Assemble_Alias(decl, DECL_ALIAS_TARGET(decl));
00741 return;
00742 }
00743
00744 expanded_decl(decl) = TRUE;
00745 #endif
00746 (void) Get_ST(decl);
00747 if (DECL_INITIAL(decl) && !DECL_EXTERNAL(decl)) {
00748 tree init = DECL_INITIAL(decl);
00749 if (TREE_CODE(init) == ERROR_MARK)
00750 return;
00751
00752 if (TREE_CODE(init) == PTRMEM_CST) {
00753 init = cplus_expand_constant(init);
00754 DECL_INITIAL(decl) = init;
00755 }
00756
00757 if (TREE_CODE(init) == CONSTRUCTOR) {
00758 tree init_type = TREE_TYPE(init);
00759 if (TREE_CODE(init_type) != RECORD_TYPE &&
00760 TREE_CODE(init_type) != ARRAY_TYPE &&
00761 TREE_CODE(init_type) != UNION_TYPE
00762 #ifdef KEY
00763 && TREE_CODE(init_type) != VECTOR_TYPE
00764 #endif
00765 )
00766 return;
00767 }
00768
00769 WFE_Initialize_Decl(decl);
00770 }
00771 break;
00772
00773 #ifdef KEY
00774 case USING_DECL:
00775 break;
00776 #endif
00777
00778 default:
00779 Is_True(FALSE, ("Unexpected tree code"));
00780 break;
00781
00782 }
00783 }
00784
00785 static BOOL
00786 function_has_varargs(tree fndecl)
00787 {
00788 tree fntype = TREE_TYPE(fndecl);
00789 tree arglist = TYPE_ARG_TYPES(fntype);
00790
00791 #ifdef KEY // bug 9688: cannot be vararg if there is not a single argument
00792 if (arglist == NULL_TREE)
00793 return FALSE;
00794 #endif
00795
00796 while (arglist != NULL_TREE) {
00797 if (TREE_VALUE(arglist) == void_type_node)
00798 return FALSE;
00799 arglist = TREE_CHAIN(arglist);
00800 }
00801
00802 return TRUE;
00803 }
00804
00805 #ifdef KEY
00806
00807
00808 static void
00809 Setup_Entry_For_EH (void)
00810 {
00811 const int lbnd = 0;
00812 const int hbnd = 3;
00813
00814 ARB_HANDLE arb = New_ARB();
00815 ARB_Init (arb, lbnd, hbnd, 4);
00816 Set_ARB_flags (arb, ARB_flags(arb) | ARB_FIRST_DIMEN | ARB_LAST_DIMEN);
00817 STR_IDX str = Save_Str ("__EH_INFO_PER_PU__");
00818 TY_IDX ty;
00819 TY_Init (New_TY(ty), (hbnd+1) * 4 , KIND_ARRAY, MTYPE_M, str);
00820 Set_TY_arb (ty, arb);
00821 Set_TY_etype (ty, MTYPE_TO_TY_array[MTYPE_U4]);
00822 ST * etable = New_ST (CURRENT_SYMTAB);
00823 ST_Init (etable, str, CLASS_VAR, SCLASS_EH_REGION_SUPP, EXPORT_LOCAL, ty);
00824 Set_ST_is_initialized (*etable);
00825 Set_ST_one_per_pu (etable);
00826
00827 ST * exc_ptr_st = New_ST (CURRENT_SYMTAB);
00828 ST_Init (exc_ptr_st, Save_Str ("__Exc_Ptr__"), CLASS_VAR, SCLASS_AUTO,
00829 EXPORT_LOCAL, MTYPE_To_TY(Pointer_Mtype));
00830 Set_ST_one_per_pu (exc_ptr_st);
00831 INITV_IDX exc_ptr_iv = New_INITV();
00832 INITV_Set_VAL (Initv_Table[exc_ptr_iv], Enter_tcon (Host_To_Targ (MTYPE_U4,
00833 ST_st_idx (exc_ptr_st))), 1);
00834
00835 ST * filter_st = New_ST (CURRENT_SYMTAB);
00836 ST_Init (filter_st, Save_Str ("__Exc_Filter__"), CLASS_VAR, SCLASS_AUTO,
00837 EXPORT_LOCAL, MTYPE_To_TY(TARGET_64BIT ? MTYPE_U8 : MTYPE_U4));
00838 Set_ST_one_per_pu (filter_st);
00839 INITV_IDX filter_iv = New_INITV();
00840 INITV_Set_VAL (Initv_Table[filter_iv], Enter_tcon (Host_To_Targ (MTYPE_U4,
00841 ST_st_idx (filter_st))), 1);
00842 Set_INITV_next (exc_ptr_iv, filter_iv);
00843
00844 INITV_IDX tinfo = New_INITV();
00845 INITV_Set_VAL (Initv_Table[tinfo], Enter_tcon (Host_To_Targ (MTYPE_U4,
00846 0)), 1);
00847 Set_INITV_next (filter_iv, tinfo);
00848
00849 INITV_IDX eh_spec = New_INITV();
00850 INITV_Set_VAL (Initv_Table[eh_spec], Enter_tcon (Host_To_Targ (MTYPE_U4,
00851 0)), 1);
00852 Set_INITV_next (tinfo, eh_spec);
00853
00854 Set_PU_misc_info (Get_Current_PU(), New_INITO (ST_st_idx (etable), exc_ptr_iv));
00855 }
00856
00857
00858
00859 static void
00860 WFE_Assemble_Asm(char *asm_string)
00861 {
00862 ST *asm_st = New_ST(GLOBAL_SYMTAB);
00863 ST_Init(asm_st,
00864 Str_To_Index (Save_Str (asm_string),
00865 Global_Strtab),
00866 CLASS_NAME,
00867 SCLASS_UNKNOWN,
00868 EXPORT_LOCAL,
00869 (TY_IDX) 0);
00870
00871 Set_ST_asm_function_st(*asm_st);
00872
00873 WN *func_wn = WN_CreateEntry(0,
00874 asm_st,
00875 WN_CreateBlock(),
00876 NULL,
00877 NULL);
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887 #ifdef ASM_NEEDS_WN_MAP
00888
00889 if (Current_Map_Tab) {
00890 WN_MAP_TAB_Delete(Current_Map_Tab);
00891 Current_Map_Tab = NULL;
00892 }
00893
00894
00895 if (!map_mempool_initialized) {
00896 MEM_POOL_Initialize(&Map_Mem_Pool,"Map_Mem_Pool",FALSE);
00897 map_mempool_initialized = TRUE;
00898 } else {
00899 MEM_POOL_Pop(&Map_Mem_Pool);
00900 }
00901
00902 MEM_POOL_Push(&Map_Mem_Pool);
00903
00904 (void)WN_MAP_TAB_Create(&Map_Mem_Pool);
00905 #endif
00906
00907
00908
00909
00910
00911
00912 FmtAssert(CURRENT_SYMTAB == GLOBAL_SYMTAB,
00913 ("file-scope asm must be at global symtab scope."));
00914
00915 New_Scope (CURRENT_SYMTAB + 1, Malloc_Mem_Pool, TRUE);
00916
00917 if (Show_Progress) {
00918 fprintf (stderr, "Asm(%s)\n", ST_name (asm_st));
00919 fflush (stderr);
00920 }
00921 PU_Info *pu_info;
00922
00923 pu_info = TYPE_MEM_POOL_ALLOC(PU_Info, Malloc_Mem_Pool);
00924 PU_Info_init(pu_info);
00925
00926 Set_PU_Info_tree_ptr (pu_info, func_wn);
00927 PU_Info_maptab (pu_info) = Current_Map_Tab;
00928 PU_Info_proc_sym (pu_info) = ST_st_idx(asm_st);
00929 PU_Info_pu_dst (pu_info) = DST_Create_Subprogram (asm_st,0);
00930 PU_Info_cu_dst (pu_info) = DST_Get_Comp_Unit ();
00931
00932 Set_PU_Info_state(pu_info, WT_SYMTAB, Subsect_InMem);
00933 Set_PU_Info_state(pu_info, WT_TREE, Subsect_InMem);
00934 Set_PU_Info_state(pu_info, WT_PROC_SYM, Subsect_InMem);
00935
00936 Set_PU_Info_flags(pu_info, PU_IS_COMPILER_GENERATED);
00937
00938 if (PU_Info_Table [CURRENT_SYMTAB])
00939 PU_Info_next (PU_Info_Table [CURRENT_SYMTAB]) = pu_info;
00940 else
00941 PU_Tree_Root = pu_info;
00942
00943 PU_Info_Table [CURRENT_SYMTAB] = pu_info;
00944
00945
00946
00947
00948
00949 pu_info = PU_Info_Table [CURRENT_SYMTAB];
00950
00951 if (Current_Map_Tab) {
00952 WN_MAP_TAB_Delete(Current_Map_Tab);
00953 Current_Map_Tab = NULL;
00954 }
00955
00956 PU_IDX pu_idx;
00957 PU &pu = New_PU(pu_idx);
00958 PU_Init(pu, (TY_IDX) 0, CURRENT_SYMTAB);
00959 Set_PU_no_inline(pu);
00960 Set_PU_no_delete(pu);
00961 Set_ST_pu(*asm_st, pu_idx);
00962
00963 Write_PU_Info (pu_info);
00964
00965
00966 PU_Info_Table [CURRENT_SYMTAB+1] = NULL;
00967
00968 Delete_Scope(CURRENT_SYMTAB);
00969 --CURRENT_SYMTAB;
00970 }
00971 #endif
00972
00973 extern WN *
00974 WFE_Start_Function (tree fndecl)
00975 {
00976 Is_True(fndecl != NULL && TREE_CODE(fndecl) == FUNCTION_DECL,
00977 ("Bad argument to WFE_Start_Function"));
00978
00979 WN *entry_wn;
00980 BOOL thunk = DECL_THUNK_P(fndecl) &&
00981 TREE_CODE(CP_DECL_CONTEXT(fndecl)) != NAMESPACE_DECL;
00982
00983 #ifdef KEY
00984
00985
00986 add_deferred_DST_types();
00987
00988
00989 wfe_save_expr_stack_last = -1;
00990
00991
00992 wfe_save_expr_level = 1;
00993 wfe_last_save_expr_level = 1;
00994
00995
00996 WFE_unusable_label_idx = 0;
00997 WFE_last_label_idx = 0;
00998
00999 static tree prev_fndecl;
01000 if (CURRENT_SYMTAB != GLOBAL_SYMTAB) {
01001
01002
01003
01004
01005
01006
01007
01008
01009 func_PU_uplevel(prev_fndecl) = TRUE;
01010 }
01011 prev_fndecl = fndecl;
01012 #else
01013 if (CURRENT_SYMTAB != GLOBAL_SYMTAB)
01014 Set_PU_uplevel (Get_Current_PU ());
01015 #endif
01016
01017 #ifdef KEY
01018 try_block_seen = false;
01019 #endif
01020
01021
01022 if (Current_Map_Tab) {
01023 WN_MAP_TAB_Delete(Current_Map_Tab);
01024 Current_Map_Tab = NULL;
01025 }
01026
01027
01028 if (!map_mempool_initialized) {
01029 MEM_POOL_Initialize(&Map_Mem_Pool,"Map_Mem_Pool",FALSE);
01030 map_mempool_initialized = TRUE;
01031 } else {
01032 MEM_POOL_Pop(&Map_Mem_Pool);
01033 }
01034
01035 MEM_POOL_Push(&Map_Mem_Pool);
01036
01037
01038 (void)WN_MAP_TAB_Create(&Map_Mem_Pool);
01039
01040 New_Scope (CURRENT_SYMTAB + 1, Malloc_Mem_Pool, TRUE);
01041
01042 if (DECL_SOURCE_FILE (fndecl)) {
01043 lineno = DECL_SOURCE_LINE (fndecl);
01044 WFE_Set_Line_And_File (lineno, DECL_SOURCE_FILE (fndecl));
01045 }
01046
01047
01048 WN *vla_block = WN_CreateBlock ();
01049 WFE_Stmt_Push (vla_block, wfe_stmk_func_body, Get_Srcpos());
01050
01051 ST *func_st;
01052 #ifdef KEY
01053 static BOOL interface_only = (!pragma_implementation_seen || !pragma_interface_seen);
01054
01055
01056
01057
01058 ST_EXPORT eclass;
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 if (interface_only &&
01081 DECL_WEAK (fndecl) &&
01082 (DECL_DECLARED_INLINE_P (fndecl) ||
01083 (DECL_LANG_SPECIFIC (fndecl) &&
01084 DECL_IMPLICIT_INSTANTIATION (fndecl) &&
01085 DECL_NAMESPACE_SCOPE_P (fndecl))))
01086 eclass = EXPORT_INTERNAL;
01087 else if (DECL_WEAK(fndecl))
01088 eclass = EXPORT_PREEMPTIBLE;
01089 else if (!TREE_PUBLIC(fndecl))
01090 eclass = EXPORT_LOCAL;
01091 else if (DECL_INLINE(fndecl))
01092 eclass = EXPORT_PROTECTED;
01093 else
01094 eclass = EXPORT_PREEMPTIBLE;
01095 #else
01096 ST_EXPORT eclass = TREE_PUBLIC(fndecl) && !DECL_INLINE(fndecl)
01097 || DECL_WEAK(fndecl) ?
01098 EXPORT_PREEMPTIBLE :
01099 EXPORT_LOCAL;
01100 #endif
01101
01102 #ifndef GPLUSPLUS_FE
01103 if (DECL_INLINE (fndecl) && TREE_PUBLIC (fndecl)) {
01104 if (DECL_EXTERNAL (fndecl)) {
01105
01106 ST *oldst = DECL_ST (fndecl);
01107 DECL_ST (fndecl) = 0;
01108 func_st = Get_ST (fndecl);
01109 DECL_ST (fndecl) = oldst;
01110 }
01111 else {
01112
01113 func_st = Get_ST (fndecl);
01114 }
01115 }
01116 else
01117 #else
01118 func_st = Get_ST (fndecl);
01119 #endif
01120
01121 Set_ST_sclass (func_st, SCLASS_TEXT);
01122 Set_PU_lexical_level (Pu_Table [ST_pu (func_st)], CURRENT_SYMTAB);
01123 Set_PU_cxx_lang (Pu_Table [ST_pu (func_st)]);
01124
01125 #ifdef KEY
01126 if (lookup_attribute("used", DECL_ATTRIBUTES (fndecl)))
01127 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
01128
01129 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
01130 Set_PU_no_instrument (Pu_Table [ST_pu (func_st)]);
01131 if (DECL_DECLARED_INLINE_P(fndecl))
01132 Set_PU_is_marked_inline (Pu_Table [ST_pu (func_st)]);
01133 #endif
01134 if (DECL_INLINE(fndecl)) {
01135 Set_PU_is_inline_function (Pu_Table [ST_pu (func_st)]);
01136 wfe_invoke_inliner = TRUE;
01137 }
01138 Set_ST_export (func_st, eclass);
01139
01140 if (Show_Progress) {
01141 fprintf (stderr, "Compiling %s \n", ST_name (func_st));
01142 fflush (stderr);
01143 }
01144
01145 Scope_tab [Current_scope].st = func_st;
01146 #ifdef KEY
01147
01148
01149
01150 if (key_exceptions)
01151 Setup_Entry_For_EH ();
01152 else
01153 Dummy_Exc_Ptr_Expr = NULL;
01154
01155 if (func_PU_uplevel(fndecl))
01156 Set_PU_uplevel (Get_Current_PU ());
01157 #endif
01158
01159 INT num_args = 0;
01160 tree pdecl;
01161 #ifdef KEY
01162
01163 pdecl = thunk ? DECL_ARGUMENTS (TREE_OPERAND (WFE_get_thunk_target (fndecl), 0))
01164 : DECL_ARGUMENTS (fndecl);
01165 #else
01166 pdecl = thunk ? DECL_ARGUMENTS (TREE_OPERAND (DECL_INITIAL (fndecl), 0))
01167 : DECL_ARGUMENTS (fndecl);
01168 #endif
01169 for (;
01170 pdecl;
01171 pdecl = TREE_CHAIN (pdecl)) {
01172 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(pdecl));
01173 if (!WFE_Keep_Zero_Length_Structs &&
01174 TY_mtype (arg_ty_idx) == MTYPE_M &&
01175 TY_size (arg_ty_idx) == 0) {
01176
01177 }
01178 else
01179 ++num_args;
01180 }
01181
01182 #ifdef KEY
01183
01184
01185
01186 TY_IDX ret_ty_idx = Get_TY(TREE_TYPE(TREE_TYPE(fndecl)));
01187 if (TY_return_in_mem(ret_ty_idx)) {
01188 num_args++;
01189 }
01190 #endif
01191
01192 WN *body, *wn;
01193 body = WN_CreateBlock ( );
01194 entry_wn = WN_CreateEntry ( num_args, func_st, body, NULL, NULL );
01195
01196 INT i = 0;
01197
01198 #ifdef KEY
01199
01200 if (TY_return_in_mem(ret_ty_idx)) {
01201 ST *st = New_ST ();
01202 ST_Init (st, Save_Str2i(".arg", "", i), CLASS_VAR, SCLASS_FORMAL,
01203 EXPORT_LOCAL, Make_Pointer_Type(ret_ty_idx, FALSE));
01204 Set_ST_is_value_parm(st);
01205 WN_kid(entry_wn,i) = WN_CreateIdname ( 0, ST_st_idx(st) );
01206 ++i;
01207 }
01208 #endif
01209
01210 for (pdecl = thunk ?
01211 #ifdef KEY
01212 DECL_ARGUMENTS (TREE_OPERAND (WFE_get_thunk_target (fndecl), 0))
01213 #else
01214 DECL_ARGUMENTS (TREE_OPERAND (DECL_INITIAL (fndecl), 0))
01215 #endif
01216 : DECL_ARGUMENTS (fndecl);
01217 pdecl;
01218 pdecl = TREE_CHAIN (pdecl) )
01219 {
01220 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(pdecl));
01221 ST *st;
01222 if (thunk) {
01223 st = New_ST ();
01224 ST_Init (st, Save_Str2i(".arg", "", i), CLASS_VAR,
01225 SCLASS_FORMAL, EXPORT_LOCAL, arg_ty_idx);
01226 }
01227 else {
01228 #ifdef KEY
01229 tree passed_type = DECL_ARG_TYPE (pdecl);
01230 tree nominal_type = TREE_TYPE (pdecl);
01231
01232 if (passed_type != nominal_type &&
01233 POINTER_TYPE_P (passed_type) &&
01234 TREE_TYPE (passed_type) == nominal_type) {
01235
01236
01237 tree ptr_parm = build_decl(PARM_DECL, NULL_TREE, passed_type);
01238 DECL_ARG_TYPE(ptr_parm) = passed_type;
01239 st = Get_ST(ptr_parm);
01240
01241
01242
01243
01244 TREE_SET_CODE(pdecl, INDIRECT_REF);
01245 TREE_OPERAND(pdecl, 0) = ptr_parm;
01246 } else
01247 #endif
01248 {
01249 st = Get_ST(pdecl);
01250 if (DECL_ARTIFICIAL(pdecl) && DECL_NAME(pdecl) == this_identifier) {
01251 Set_ST_is_this_ptr (st);
01252 }
01253 }
01254 }
01255
01256 if (!WFE_Keep_Zero_Length_Structs &&
01257 TY_mtype (arg_ty_idx) == MTYPE_M &&
01258 TY_size (arg_ty_idx) == 0) {
01259
01260 }
01261 else {
01262 if (TY_mtype (arg_ty_idx) == MTYPE_F4 &&
01263 !TY_has_prototype (ST_pu_type (func_st)))
01264 Set_ST_promote_parm (st);
01265 WN_kid(entry_wn,i) = WN_CreateIdname ( 0, ST_st_idx(st) );
01266 ++i;
01267 }
01268 }
01269
01270 PU_Info *pu_info;
01271
01272 pu_info = TYPE_MEM_POOL_ALLOC(PU_Info, Malloc_Mem_Pool);
01273 PU_Info_init(pu_info);
01274
01275 Set_PU_Info_tree_ptr (pu_info, entry_wn);
01276 PU_Info_maptab (pu_info) = Current_Map_Tab;
01277 PU_Info_proc_sym (pu_info) = ST_st_idx(func_st);
01278 PU_Info_pu_dst (pu_info) = DST_Create_Subprogram (func_st,fndecl);
01279 PU_Info_cu_dst (pu_info) = DST_Get_Comp_Unit ();
01280
01281 Set_PU_Info_state(pu_info, WT_SYMTAB, Subsect_InMem);
01282 Set_PU_Info_state(pu_info, WT_TREE, Subsect_InMem);
01283 Set_PU_Info_state(pu_info, WT_PROC_SYM, Subsect_InMem);
01284
01285 Set_PU_Info_flags(pu_info, PU_IS_COMPILER_GENERATED);
01286
01287
01288 if (strcmp (ST_name (func_st), "main") == 0) {
01289 PU& pu = Pu_Table[ST_pu (St_Table [PU_Info_proc_sym (pu_info)])];
01290 Set_PU_is_mainpu (pu);
01291 Set_PU_no_inline (pu);
01292 }
01293
01294 if (PU_Info_Table [CURRENT_SYMTAB])
01295 PU_Info_next (PU_Info_Table [CURRENT_SYMTAB]) = pu_info;
01296
01297 else
01298 if (CURRENT_SYMTAB == GLOBAL_SYMTAB + 1)
01299 PU_Tree_Root = pu_info;
01300
01301 else
01302 PU_Info_child (PU_Info_Table [CURRENT_SYMTAB -1]) = pu_info;
01303
01304 PU_Info_Table [CURRENT_SYMTAB] = pu_info;
01305
01306 WFE_Stmt_Pop (wfe_stmk_func_body);
01307
01308 WFE_Stmt_Push (entry_wn, wfe_stmk_func_entry, Get_Srcpos());
01309 WFE_Stmt_Push (body, wfe_stmk_func_body, Get_Srcpos());
01310
01311 wn = WN_CreatePragma (WN_PRAGMA_PREAMBLE_END, (ST_IDX) NULL, 0, 0);
01312 WFE_Stmt_Append (wn, Get_Srcpos());
01313 WFE_Stmt_Append (vla_block, Get_Srcpos());
01314
01315 if (function_has_varargs(fndecl) && !thunk) {
01316
01317
01318
01319 PU& pu = Pu_Table[ST_pu (func_st)];
01320 TY_IDX ty_idx;
01321 TY &ty = New_TY (ty_idx);
01322 TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, STR_IDX_ZERO);
01323 Set_TY_align (ty_idx, 1);
01324 TYLIST tylist_idx;
01325 #ifdef KEY
01326
01327
01328 if (TY_return_in_mem(Get_TY(TREE_TYPE(TREE_TYPE(fndecl))))) {
01329 Set_TYLIST_type (New_TYLIST (tylist_idx), Be_Type_Tbl(MTYPE_V));
01330 } else
01331 #endif
01332 Set_TYLIST_type (New_TYLIST (tylist_idx),
01333 Get_TY(TREE_TYPE(TREE_TYPE(fndecl))));
01334 Set_TY_tylist (ty, tylist_idx);
01335 for (pdecl = DECL_ARGUMENTS (fndecl); pdecl; pdecl = TREE_CHAIN (pdecl) ) {
01336 #ifdef KEY
01337
01338
01339 ST *arg_st = TREE_CODE(pdecl) == INDIRECT_REF ?
01340 Get_ST(TREE_OPERAND(pdecl, 0)) : Get_ST(pdecl);
01341 #else
01342 ST *arg_st = Get_ST(pdecl);
01343 #endif
01344 Set_TYLIST_type (New_TYLIST (tylist_idx), ST_type(arg_st));
01345 }
01346 Set_TYLIST_type (New_TYLIST (tylist_idx), 0);
01347 Set_TY_is_varargs (ty_idx);
01348 Set_TY_has_prototype (ty_idx);
01349 Set_PU_prototype (pu, ty_idx);
01350
01351 tree fntype = TREE_TYPE(fndecl);
01352 if (TREE_CODE(fntype) == METHOD_TYPE) {
01353 TY_IDX base = Get_TY(TYPE_METHOD_BASETYPE(fntype));
01354 Set_PU_base_class(pu, base);
01355 }
01356 }
01357
01358 if (!thunk && DECL_GLOBAL_CTOR_P(fndecl)) {
01359 #ifndef KEY
01360
01361 if (GLOBAL_INIT_PRIORITY(fndecl) != DEFAULT_INIT_PRIORITY) {
01362 DevWarn("Discarding ctor priority %d (default %d) at line %d",
01363 GLOBAL_INIT_PRIORITY(fndecl),
01364 DEFAULT_INIT_PRIORITY,
01365 lineno);
01366 }
01367 #endif // !KEY
01368
01369 INITV_IDX initv = New_INITV ();
01370 INITV_Init_Symoff (initv, func_st, 0, 1);
01371 Set_ST_addr_saved (func_st);
01372 ST *init_st = New_ST (GLOBAL_SYMTAB);
01373 ST_Init (init_st, Save_Str2i ("__ctors", "_", ++__ctors),
01374 CLASS_VAR, SCLASS_FSTATIC,
01375 EXPORT_LOCAL, Make_Pointer_Type (ST_pu_type (func_st), FALSE));
01376 Set_ST_is_initialized (init_st);
01377 INITO_IDX inito = New_INITO (init_st, initv);
01378 ST_ATTR_IDX st_attr_idx;
01379 ST_ATTR& st_attr = New_ST_ATTR (GLOBAL_SYMTAB, st_attr_idx);
01380 ST_ATTR_Init (st_attr, ST_st_idx (init_st), ST_ATTR_SECTION_NAME,
01381 Save_Str (".ctors"));
01382 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
01383 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
01384 }
01385
01386 if (!thunk && DECL_GLOBAL_DTOR_P(fndecl)) {
01387 #ifndef KEY
01388
01389 if (GLOBAL_INIT_PRIORITY(fndecl) != DEFAULT_INIT_PRIORITY) {
01390 DevWarn("Discarding dtor priority %d (default %d) at line %d",
01391 GLOBAL_INIT_PRIORITY(fndecl),
01392 DEFAULT_INIT_PRIORITY,
01393 lineno);
01394 }
01395 #endif // !KEY
01396
01397 INITV_IDX initv = New_INITV ();
01398 INITV_Init_Symoff (initv, func_st, 0, 1);
01399 ST *init_st = New_ST (GLOBAL_SYMTAB);
01400 ST_Init (init_st, Save_Str2i ("__dtors", "_", ++__dtors),
01401 CLASS_VAR, SCLASS_FSTATIC,
01402 EXPORT_LOCAL, Make_Pointer_Type (ST_pu_type (func_st), FALSE));
01403 Set_ST_is_initialized (init_st);
01404 INITO_IDX inito = New_INITO (init_st, initv);
01405 ST_ATTR_IDX st_attr_idx;
01406 ST_ATTR& st_attr = New_ST_ATTR (GLOBAL_SYMTAB, st_attr_idx);
01407 ST_ATTR_Init (st_attr, ST_st_idx (init_st), ST_ATTR_SECTION_NAME,
01408 Save_Str (".dtors"));
01409 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
01410 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
01411 Set_ST_addr_saved (func_st);
01412 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
01413 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
01414 }
01415
01416 #ifdef KEY
01417
01418 Push_Current_Entry_WN(entry_wn);
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 if (!DECL_ONE_ONLY(fndecl)) {
01431 if (ST_is_weak_symbol(func_st) &&
01432 WEAK_WORKAROUND(func_st) == WEAK_WORKAROUND_made_weak) {
01433 Clear_ST_is_weak_symbol(func_st);
01434 }
01435 }
01436 #endif
01437
01438 return entry_wn;
01439 }
01440
01441 extern void
01442 WFE_Finish_Function (void)
01443 {
01444 WFE_Check_Undefined_Labels ();
01445 PU_Info *pu_info = PU_Info_Table [CURRENT_SYMTAB];
01446
01447 #ifdef KEY
01448 if (PU_lexical_level (Get_Current_PU()) > 2) {
01449
01450 DevWarn ("Encountered nested function");
01451 Set_PU_is_nested_func (Get_Current_PU ());
01452 }
01453 if (opt_regions)
01454 {
01455 Check_For_Call_Region ();
01456
01457
01458 Did_Not_Terminate_Region = FALSE;
01459 }
01460 #else
01461 if (CURRENT_SYMTAB > GLOBAL_SYMTAB + 1) {
01462
01463 DevWarn ("Encountered nested function");
01464 Set_PU_is_nested_func (Get_Current_PU ());
01465 }
01466 #endif
01467
01468
01469 WN * wn = WN_last (WFE_Stmt_Top ());
01470 if (wn == NULL || WN_operator (wn) != OPR_RETURN &&
01471 WN_operator (wn) != OPR_RETURN_VAL) {
01472 WFE_Stmt_Append (WN_CreateReturn (), Get_Srcpos ());
01473 }
01474
01475
01476 Do_Handlers ();
01477 #ifdef KEY
01478 if (flag_exceptions)
01479 #endif // KEY
01480 Do_EH_Cleanups ();
01481 #ifdef KEY
01482 if (key_exceptions)
01483 Do_EH_Tables ();
01484 #endif // KEY
01485
01486
01487 WFE_Stmt_Pop (wfe_stmk_func_body);
01488 WFE_Stmt_Pop (wfe_stmk_func_entry);
01489
01490
01491 if (Current_Map_Tab) {
01492 WN_MAP_TAB_Delete(Current_Map_Tab);
01493 Current_Map_Tab = NULL;
01494 }
01495
01496 Write_PU_Info (pu_info);
01497
01498 PU_Info_Table [CURRENT_SYMTAB+1] = NULL;
01499
01500 if (Return_Address_ST [CURRENT_SYMTAB]) {
01501 Set_PU_has_return_address (Get_Current_PU ());
01502 Set_PU_no_inline (Get_Current_PU ());
01503 #ifdef KEY
01504 if (PU_must_inline(Get_Current_PU())) {
01505 DevWarn("Disabling must_inline for PU %s",
01506 ST_name(Get_Current_PU_ST()));
01507 Clear_PU_must_inline(Get_Current_PU());
01508 }
01509 #endif
01510
01511 Return_Address_ST [CURRENT_SYMTAB] = NULL;
01512 }
01513
01514 #ifdef KEY
01515 try_block_seen = false;
01516
01517
01518 Pop_Current_Entry_WN();
01519 #endif
01520
01521 Delete_Scope (CURRENT_SYMTAB);
01522 --CURRENT_SYMTAB;
01523
01524
01525 }
01526
01527
01528
01529 static INITO_IDX aggregate_inito = 0;
01530 static INITV_IDX last_aggregate_initv = 0;
01531 static BOOL not_at_root = FALSE;
01532
01533 void
01534 WFE_Start_Aggregate_Init (tree decl)
01535 {
01536 if (TREE_STATIC(decl)) {
01537 ST *st = Get_ST(decl);
01538 Set_ST_is_initialized(st);
01539 if (ST_sclass(st) == SCLASS_UGLOBAL ||
01540 ST_sclass(st) == SCLASS_EXTERN ||
01541 ST_sclass(st) == SCLASS_COMMON)
01542 Set_ST_sclass(st, SCLASS_DGLOBAL);
01543 aggregate_inito = New_INITO (st);
01544 not_at_root = FALSE;
01545 last_aggregate_initv = 0;
01546 }
01547 }
01548
01549 void
01550 WFE_Add_Aggregate_Init_Padding (INT size)
01551 {
01552 if (aggregate_inito == 0) return;
01553 if (size < 0) return;
01554 INITV_IDX inv = New_INITV();
01555 INITV_Init_Pad (inv, size);
01556 if (last_aggregate_initv != 0)
01557 Set_INITV_next(last_aggregate_initv, inv);
01558 else if (! not_at_root)
01559 Set_INITO_val(aggregate_inito, inv);
01560 last_aggregate_initv = inv;
01561 }
01562
01563 void
01564 WFE_Add_Aggregate_Init_Integer (INT64 val, INT size)
01565 {
01566 if (aggregate_inito == 0) return;
01567 INITV_IDX inv = New_INITV();
01568 TYPE_ID mtype;
01569 if (size == 1) mtype = MTYPE_I1;
01570 else if (size == 2) mtype = MTYPE_I2;
01571 else if (size == 4) mtype = MTYPE_I4;
01572 else if (size == 8) mtype = MTYPE_I8;
01573 else FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Integer unexpected size"));
01574 INITV_Init_Integer (inv, mtype, val);
01575 if (last_aggregate_initv != 0)
01576 Set_INITV_next(last_aggregate_initv, inv);
01577 else if (! not_at_root)
01578 Set_INITO_val(aggregate_inito, inv);
01579 last_aggregate_initv = inv;
01580 }
01581
01582 float
01583 WFE_Convert_Internal_Real_to_IEEE_Single (REAL_VALUE_TYPE real)
01584 {
01585 INT32 retval;
01586
01587 Is_True (sizeof(INT32) == sizeof(float),
01588 ("The return value from REAL_VALUE_TO_TARGET_SINGLE() should be cast to"
01589 " a integer with the same size as float"));
01590 REAL_VALUE_TO_TARGET_SINGLE(real, retval);
01591 return *(float*)(void*)&retval;
01592 }
01593
01594 double
01595 WFE_Convert_Internal_Real_to_IEEE_Double (REAL_VALUE_TYPE real)
01596 {
01597 long buffer[4];
01598 int compact_buffer[8];
01599
01600 REAL_VALUE_TO_TARGET_DOUBLE (real, buffer);
01601 WFE_Convert_To_Host_Order(buffer);
01602 if (sizeof(long) > 4) {
01603 for (INT i = 0; i < sizeof(buffer)/sizeof(buffer[0]); i++)
01604 compact_buffer[i] = (int)buffer[i];
01605 return *(double*)(void*)&compact_buffer[0];
01606 }
01607 return *(double*)(void*)&buffer[0];
01608 }
01609
01610 long double
01611 WFE_Convert_Internal_Real_to_IEEE_Double_Extended (REAL_VALUE_TYPE real)
01612 {
01613 long buffer[4];
01614 int compact_buffer[8];
01615
01616 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, buffer);
01617 WFE_Convert_To_Host_Order(buffer);
01618 if (sizeof(long) > 4) {
01619 for (INT i = 0; i < sizeof(buffer)/sizeof(buffer[0]); i++)
01620 compact_buffer[i] = buffer[i];
01621 return *(long double*)(void*)&compact_buffer[0];
01622 }
01623 return *(long double*)(void*)&buffer[0];
01624 }
01625
01626 static void
01627 WFE_Add_Init_Block(void)
01628 {
01629 if (aggregate_inito == 0) return;
01630 INITV_IDX inv_blk = New_INITV();
01631 if (last_aggregate_initv != 0)
01632 Set_INITV_next(last_aggregate_initv, inv_blk);
01633 else if (! not_at_root)
01634 Set_INITO_val(aggregate_inito, inv_blk);
01635 last_aggregate_initv = inv_blk;
01636 }
01637
01638 #ifdef TARG_IA64
01639 void
01640 WFE_Add_Aggregate_Init_Real (REAL_VALUE_TYPE real, INT size)
01641 {
01642 if (aggregate_inito == 0) return;
01643 INITV_IDX inv = New_INITV();
01644 TCON tc;
01645
01646 switch (size) {
01647 case 4:
01648 tc = Host_To_Targ_Float_4 (MTYPE_F4,
01649 WFE_Convert_Internal_Real_to_IEEE_Single(real));
01650 break;
01651 case 8:
01652 tc = Host_To_Targ_Float (MTYPE_F8,
01653 WFE_Convert_Internal_Real_to_IEEE_Double(real));
01654 break;
01655 case 16:
01656 tc = Host_To_Targ_Float_10 (MTYPE_F10,
01657 WFE_Convert_Internal_Real_to_IEEE_Double_Extended(real));
01658 break;
01659 default:
01660 FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Real unexpected size"));
01661 break;
01662 }
01663 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), 1);
01664 if (last_aggregate_initv != 0)
01665 Set_INITV_next(last_aggregate_initv, inv);
01666 else if (! not_at_root)
01667 Set_INITO_val(aggregate_inito, inv);
01668 last_aggregate_initv = inv;
01669 }
01670 #else
01671 #ifdef KEY // kgccfe uses WFE_Add_Aggregrate_Init_Real instead of
01672
01673
01674
01675
01676 void
01677 WFE_Add_Aggregate_Init_Real (REAL_VALUE_TYPE real, INT size)
01678 {
01679 if (aggregate_inito == 0) return;
01680 INITV_IDX inv = New_INITV();
01681 TCON tc;
01682 int t1;
01683 #ifdef KEY
01684 long buffer [4];
01685 #else
01686
01687 int buffer [4];
01688 #endif // KEY
01689 INT32 rbuf_w[4];
01690 switch (size) {
01691 case 4:
01692 REAL_VALUE_TO_TARGET_SINGLE (real, t1);
01693 tc = Host_To_Targ_Float_4 (MTYPE_F4, *(float *) &t1);
01694 break;
01695 case 8:
01696 REAL_VALUE_TO_TARGET_DOUBLE (real, buffer);
01697 WFE_Convert_To_Host_Order(buffer);
01698 #if (SIZEOF_LONG != 4)
01699 for (int i = 0; i < 4; i++)
01700 rbuf_w[i] = buffer[i];
01701 tc = Host_To_Targ_Float (MTYPE_F8, *(double *) rbuf_w);
01702 #else
01703 tc = Host_To_Targ_Float (MTYPE_F8, *(double *) buffer);
01704 #endif
01705 break;
01706 #ifdef KEY
01707 case 12:
01708 case 16:
01709 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, buffer);
01710 WFE_Convert_To_Host_Order(buffer);
01711 #if (SIZEOF_LONG != 4)
01712 for (int i = 0; i < 4; i++)
01713 rbuf_w[i] = buffer[i];
01714 tc = Host_To_Targ_Quad (*(long double *) rbuf_w);
01715 #else
01716 tc = Host_To_Targ_Quad (*(long double *) buffer);
01717 #endif
01718 break;
01719 #endif
01720 default:
01721 FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Real unexpected size"));
01722 break;
01723 }
01724 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), 1);
01725 if (last_aggregate_initv != 0)
01726 Set_INITV_next(last_aggregate_initv, inv);
01727 else if (! not_at_root)
01728 Set_INITO_val(aggregate_inito, inv);
01729 last_aggregate_initv = inv;
01730 }
01731
01732 #else
01733
01734 void
01735 WFE_Add_Aggregate_Init_Double (double val, INT size)
01736 {
01737 if (aggregate_inito == 0) return;
01738 INITV_IDX inv = New_INITV();
01739 TYPE_ID mtype;
01740 if (size == 4) mtype = MTYPE_F4;
01741 else if (size == 8) mtype = MTYPE_F8;
01742 else FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Double unexpected size"));
01743 INITV_Init_Float (inv, mtype, val);
01744 if (last_aggregate_initv != 0)
01745 Set_INITV_next(last_aggregate_initv, inv);
01746 else if (! not_at_root)
01747 Set_INITO_val(aggregate_inito, inv);
01748 last_aggregate_initv = inv;
01749 }
01750 #endif // KEY
01751 #endif
01752 void
01753 WFE_Add_Aggregate_Init_Complex (REAL_VALUE_TYPE rval, REAL_VALUE_TYPE ival, INT size)
01754 {
01755 if (aggregate_inito == 0) return;
01756 INITV_IDX inv = New_INITV();
01757 TCON rtc;
01758 TCON itc;
01759
01760 switch (size) {
01761 case 8:
01762 rtc = Host_To_Targ_Float_4 (MTYPE_F4,
01763 WFE_Convert_Internal_Real_to_IEEE_Single (rval));
01764 itc = Host_To_Targ_Float_4 (MTYPE_F4,
01765 WFE_Convert_Internal_Real_to_IEEE_Single (ival));
01766 break;
01767 case 16:
01768 rtc = Host_To_Targ_Float (MTYPE_F8,
01769 WFE_Convert_Internal_Real_to_IEEE_Double (rval));
01770 itc = Host_To_Targ_Float (MTYPE_F8,
01771 WFE_Convert_Internal_Real_to_IEEE_Double (ival));
01772 break;
01773 case 32:
01774 rtc = Host_To_Targ_Quad (
01775 WFE_Convert_Internal_Real_to_IEEE_Double_Extended (rval));
01776 itc = Host_To_Targ_Quad (
01777 WFE_Convert_Internal_Real_to_IEEE_Double_Extended (ival));
01778 break;
01779 default:
01780 FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Complex unexpected size"));
01781 break;
01782 }
01783 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(rtc), 1);
01784 if (last_aggregate_initv != 0)
01785 Set_INITV_next(last_aggregate_initv, inv);
01786 else if (! not_at_root)
01787 Set_INITO_val(aggregate_inito, inv);
01788 last_aggregate_initv = inv;
01789 inv = New_INITV();
01790 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(itc), 1);
01791 Set_INITV_next(last_aggregate_initv, inv);
01792 last_aggregate_initv = inv;
01793 }
01794
01795 void
01796 WFE_Add_Aggregate_Init_String (char *s, INT size)
01797 {
01798 if (aggregate_inito == 0) return;
01799 INITV_IDX inv = New_INITV();
01800 INITV_Init_String (inv, s, size);
01801 if (last_aggregate_initv != 0)
01802 Set_INITV_next(last_aggregate_initv, inv);
01803 else if (! not_at_root)
01804 Set_INITO_val(aggregate_inito, inv);
01805 last_aggregate_initv = inv;
01806 }
01807
01808 void
01809 WFE_Add_Aggregate_Init_Symoff (ST *st, WN_OFFSET offset = 0)
01810 {
01811 if (aggregate_inito == 0) return;
01812 INITV_IDX inv = New_INITV();
01813 INITV_Init_Symoff (inv, st, offset);
01814 Set_ST_addr_saved (st);
01815 if (last_aggregate_initv != 0)
01816 Set_INITV_next(last_aggregate_initv, inv);
01817 else if (! not_at_root)
01818 Set_INITO_val(aggregate_inito, inv);
01819 last_aggregate_initv = inv;
01820 }
01821
01822 #ifdef TARG_IA64
01823 void
01824 WFE_Add_Aggregate_Init_Symiplt (ST *st, WN_OFFSET offset = 0)
01825 {
01826 if (aggregate_inito == 0) return;
01827 INITV_IDX inv = New_INITV();
01828 INITV_Init_Symiplt (inv, st, offset);
01829 Set_ST_addr_saved (st);
01830 if (last_aggregate_initv != 0)
01831 Set_INITV_next(last_aggregate_initv, inv);
01832 else if (! not_at_root)
01833 Set_INITO_val(aggregate_inito, inv);
01834 last_aggregate_initv = inv;
01835 }
01836 #endif
01837
01838 void
01839 WFE_Add_Aggregate_Init_Label (LABEL_IDX lab)
01840 {
01841 DevWarn ("taking address of a label at line %d", lineno);
01842 if (aggregate_inito == 0) return;
01843 INITV_IDX inv = New_INITV();
01844 INITV_Init_Label (inv, lab, 1);
01845 if (last_aggregate_initv != 0)
01846 Set_INITV_next(last_aggregate_initv, inv);
01847 else if (! not_at_root)
01848 Set_INITO_val(aggregate_inito, inv);
01849 last_aggregate_initv = inv;
01850 Set_LABEL_addr_saved (lab);
01851 }
01852
01853 void
01854 WFE_Add_Aggregate_Init_Address (tree init)
01855 {
01856 switch (TREE_CODE (init)) {
01857
01858 case VAR_DECL:
01859 case FUNCTION_DECL:
01860 {
01861 ST *st = Get_ST (init);
01862 WFE_Add_Aggregate_Init_Symoff (st);
01863 }
01864 break;
01865
01866 case STRING_CST:
01867 {
01868 #ifdef KEY
01869 TCON tcon = Host_To_Targ_String (MTYPE_STRING,
01870 const_cast<char*>TREE_STRING_POINTER(init),
01871 TREE_STRING_LENGTH(init));
01872 #else
01873 TCON tcon = Host_To_Targ_String (MTYPE_STRING,
01874 TREE_STRING_POINTER(init),
01875 TREE_STRING_LENGTH(init));
01876 #endif // KEY
01877 ST *const_st = New_Const_Sym (Enter_tcon (tcon),
01878 Get_TY(TREE_TYPE(init)));
01879 WFE_Add_Aggregate_Init_Symoff (const_st);
01880 }
01881 break;
01882
01883 case PLUS_EXPR:
01884 if ( TREE_CODE(TREE_OPERAND(init,0)) == ADDR_EXPR
01885 && TREE_CODE(TREE_OPERAND(init,1)) == INTEGER_CST)
01886 {
01887 tree addr_kid = TREE_OPERAND(TREE_OPERAND(init,0),0);
01888 FmtAssert(TREE_CODE(addr_kid) == VAR_DECL
01889 || TREE_CODE(addr_kid) == FUNCTION_DECL,
01890 ("expected decl under plus_expr"));
01891 WFE_Add_Aggregate_Init_Symoff ( Get_ST (addr_kid),
01892 Get_Integer_Value(TREE_OPERAND(init,1)) );
01893 }
01894 else
01895 {
01896 WN *init_wn = WFE_Expand_Expr (init);
01897 FmtAssert (WN_operator (init_wn) == OPR_LDA,
01898 ("expected decl under plus_expr"));
01899 WFE_Add_Aggregate_Init_Symoff (WN_st (init_wn),
01900 WN_offset (init_wn));
01901 WN_Delete (init_wn);
01902 }
01903 break;
01904
01905 case INTEGER_CST:
01906 WFE_Add_Aggregate_Init_Integer (Get_Integer_Value (init), Pointer_Size);
01907 break;
01908
01909 case LABEL_DECL:
01910 {
01911 LABEL_IDX label_idx = WFE_Get_LABEL (init, FALSE);
01912 WFE_Add_Aggregate_Init_Label (label_idx);
01913 }
01914 break;
01915
01916 default:
01917 {
01918 #ifndef KEY
01919 WN *init_wn = WFE_Expand_Expr (init);
01920 FmtAssert (WN_operator (init_wn) == OPR_LDA,
01921 ("expected operator encountered"));
01922 WFE_Add_Aggregate_Init_Symoff (WN_st (init_wn),
01923 WN_offset (init_wn));
01924 #else
01925 int tmp_aggr_inito = aggregate_inito;
01926 int tmp_last_aggregate_initv = last_aggregate_initv;
01927 WN *init_wn = WFE_Expand_Expr (init);
01928 aggregate_inito = tmp_aggr_inito;
01929 last_aggregate_initv = tmp_last_aggregate_initv;
01930 WFE_Add_Aggregate_Init_Symoff (WN_st(init_wn));
01931 aggregate_inito = 0;
01932 #endif
01933 WN_Delete (init_wn);
01934 }
01935 break;
01936 }
01937 }
01938
01939 void
01940 WFE_Finish_Aggregate_Init (void)
01941 {
01942 if (aggregate_inito == 0) return;
01943 ST *st = INITO_st(aggregate_inito);
01944 TY_IDX ty = ST_type(st);
01945 if (TY_size(ty) == 0 ||
01946 (TY_kind(ty) == KIND_ARRAY &&
01947 !ARB_const_ubnd (TY_arb(ty)) &&
01948 TY_size(ty) <= Get_INITO_Size(aggregate_inito))) {
01949
01950
01951 Set_TY_size(ty, Get_INITO_Size(aggregate_inito));
01952 if (TY_kind(ty) == KIND_ARRAY) {
01953 Set_ARB_const_ubnd (TY_arb(ty));
01954 Set_ARB_ubnd_val (TY_arb(ty),
01955 (TY_size(ty) / TY_size(TY_etype(ty))) - 1 );
01956 }
01957 }
01958 if (last_aggregate_initv == 0) {
01959 WFE_Add_Aggregate_Init_Padding (0);
01960 }
01961 aggregate_inito = 0;
01962 not_at_root = FALSE;
01963 }
01964
01965
01966 static BOOL
01967 Has_Non_Constant_Init_Value (tree init)
01968 {
01969 if (init == NULL) {
01970 return FALSE;
01971 }
01972 switch (TREE_CODE(init)) {
01973 case CONSTRUCTOR:
01974 if (!CONSTRUCTOR_ELTS(init))
01975 return TRUE;
01976 return Has_Non_Constant_Init_Value (CONSTRUCTOR_ELTS(init));
01977 case TREE_LIST:
01978 {
01979 tree p;
01980 for (p = init; p != NULL; p = TREE_CHAIN(p)) {
01981 if (Has_Non_Constant_Init_Value (TREE_VALUE(p))) {
01982 return TRUE;
01983 }
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994 }
01995 return FALSE;
01996 }
01997 case INTEGER_CST:
01998 case REAL_CST:
01999 case STRING_CST:
02000 return FALSE;
02001 case NOP_EXPR:
02002 if (TREE_CODE(TREE_OPERAND(init,0)) == ADDR_EXPR
02003 && TREE_CODE(TREE_OPERAND(TREE_OPERAND(init,0),0)) == STRING_CST)
02004 return FALSE;
02005 else
02006 return TRUE;
02007 case ADDR_EXPR: {
02008 tree t = TREE_OPERAND(init, 0);
02009 if (DECL_CONTEXT(t) == 0 ||
02010 TREE_CODE(DECL_CONTEXT(t)) == NAMESPACE_DECL)
02011 return FALSE;
02012 return TRUE;
02013 }
02014 default:
02015 return TRUE;
02016 }
02017 }
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028 static BOOL
02029 Use_Static_Init_For_Aggregate (ST *st, tree init)
02030 {
02031 return !Has_Non_Constant_Init_Value(init);
02032 }
02033
02034
02035 static void
02036 Add_Initv_For_Tree (tree val, UINT size)
02037 {
02038 switch (TREE_CODE(val)) {
02039 case INTEGER_CST:
02040 WFE_Add_Aggregate_Init_Integer (
02041 Get_Integer_Value(val), size);
02042 break;
02043 case REAL_CST:
02044 #ifdef KEY
02045 WFE_Add_Aggregate_Init_Real (
02046 TREE_REAL_CST(val), size);
02047 #else
02048 WFE_Add_Aggregate_Init_Double (
02049 TREE_REAL_CST(val), size);
02050 #endif
02051 break;
02052 case STRING_CST:
02053 #ifdef KEY
02054 WFE_Add_Aggregate_Init_String (
02055 const_cast<char*>TREE_STRING_POINTER(val), size);
02056 #else
02057 WFE_Add_Aggregate_Init_String (
02058 TREE_STRING_POINTER(val), size);
02059 #endif
02060 break;
02061 #if 0
02062 case PLUS_EXPR:
02063 if ( TREE_CODE(TREE_OPERAND(val,0)) == ADDR_EXPR
02064 && TREE_CODE(TREE_OPERAND(val,1)) == INTEGER_CST)
02065 {
02066 tree addr_kid = TREE_OPERAND(TREE_OPERAND(val,0),0);
02067 FmtAssert(TREE_CODE(addr_kid) == VAR_DECL
02068 || TREE_CODE(addr_kid) == FUNCTION_DECL,
02069 ("expected decl under plus_expr"));
02070 WFE_Add_Aggregate_Init_Symoff ( Get_ST (addr_kid),
02071 Get_Integer_Value(TREE_OPERAND(val,1)) );
02072 }
02073 else
02074 FmtAssert(FALSE, ("unexpected tree code %s",
02075 tree_code_name[TREE_CODE(val)]));
02076 break;
02077 #endif
02078 case NOP_EXPR:
02079 tree kid;
02080 kid = TREE_OPERAND(val,0);
02081 if (TREE_CODE(kid) == ADDR_EXPR
02082 && TREE_CODE(TREE_OPERAND(kid,0)) == STRING_CST)
02083 {
02084 kid = TREE_OPERAND(kid,0);
02085 WFE_Add_Aggregate_Init_Address (kid);
02086 break;
02087 }
02088 else
02089 if (TREE_CODE(kid) == INTEGER_CST) {
02090 WFE_Add_Aggregate_Init_Integer (
02091 Get_Integer_Value(kid), size);
02092 break;
02093 }
02094
02095 default:
02096 {
02097 WN *init_wn;
02098 init_wn = WFE_Expand_Expr (val);
02099 #ifdef KEY
02100 if (TREE_CODE(val) == PTRMEM_CST) {
02101 FmtAssert(WN_operator(init_wn) == OPR_INTCONST,
02102 ("Add_Initv_For_Tree: wrong wn after expanding PTRMEM_CST"));
02103 WFE_Add_Aggregate_Init_Integer(WN_const_val(init_wn),
02104 Pointer_Size);
02105
02106 break;
02107 }
02108 #endif
02109
02110 #ifdef TARG_IA64
02111 if (TREE_CODE(val) == FDESC_EXPR && WN_operator (init_wn) == OPR_LDA)
02112 {
02113 WFE_Add_Aggregate_Init_Symiplt (WN_st (init_wn),
02114 WN_offset (init_wn));
02115 WN_DELETE_Tree (init_wn);
02116 break;
02117 }
02118 #endif
02119
02120 if (WN_operator (init_wn) == OPR_LDA) {
02121 WFE_Add_Aggregate_Init_Symoff (WN_st (init_wn),
02122 WN_offset (init_wn));
02123 WN_DELETE_Tree (init_wn);
02124 break;
02125 }
02126 #ifdef KEY
02127 else if (WN_operator (init_wn) == OPR_LDA_LABEL) {
02128 tree label_decl =
02129 (TREE_CODE(TREE_OPERAND(val, 0)) == ADDR_EXPR)?
02130 TREE_OPERAND (TREE_OPERAND (val, 0), 0):
02131 TREE_OPERAND (val, 0);
02132 LABEL_IDX label_idx =
02133 WFE_Get_LABEL (label_decl, FALSE);
02134 WFE_Add_Aggregate_Init_Label (label_idx);
02135 WN_DELETE_Tree (init_wn);
02136 break;
02137 }
02138 #endif
02139
02140 if ((WN_opcode (init_wn) == OPC_I4U4CVT &&
02141 WN_opcode (WN_kid0 (init_wn)) == OPC_U4LDA) ||
02142 (WN_opcode (init_wn) == OPC_I8U8CVT &&
02143 WN_opcode (WN_kid0 (init_wn)) == OPC_U8LDA)) {
02144 WN *kid0 = WN_kid0(init_wn);
02145 WFE_Add_Aggregate_Init_Symoff (WN_st (kid0), WN_offset(kid0));
02146 WN_DELETE_Tree (init_wn);
02147 break;
02148 }
02149
02150
02151
02152 else if (WN_operator(init_wn) == OPR_ADD) {
02153 WN *kid0 = WN_kid0(init_wn);
02154 WN *kid1 = WN_kid1(init_wn);
02155 if (WN_operator(kid0) == OPR_LDA &&
02156 WN_operator(kid1) == OPR_INTCONST) {
02157 WFE_Add_Aggregate_Init_Symoff (WN_st (kid0),
02158 WN_offset(kid0) + WN_const_val(kid1));
02159 WN_DELETE_Tree (init_wn);
02160 break;
02161 }
02162 else if (WN_operator(kid1) == OPR_LDA &&
02163 WN_operator(kid0) == OPR_INTCONST) {
02164 WFE_Add_Aggregate_Init_Symoff (WN_st (kid1),
02165 WN_offset(kid1) + WN_const_val(kid0));
02166 WN_DELETE_Tree (init_wn);
02167 break;
02168 }
02169 }
02170 else if (WN_operator(init_wn) == OPR_SUB) {
02171 WN *kid0 = WN_kid0(init_wn);
02172 WN *kid1 = WN_kid1(init_wn);
02173 if (WN_operator(kid0) == OPR_LDA &&
02174 WN_operator(kid1) == OPR_INTCONST) {
02175 WFE_Add_Aggregate_Init_Symoff (WN_st (kid0),
02176 WN_offset(kid0) - WN_const_val(kid1));
02177 WN_DELETE_Tree (init_wn);
02178 break;
02179 }
02180 }
02181
02182
02183 else if (WN_operator(init_wn) == OPR_INTCONST) {
02184 WFE_Add_Aggregate_Init_Integer (WN_const_val(init_wn), size);
02185 break;
02186 }
02187 FmtAssert(FALSE, ("unexpected tree code %s",
02188 tree_code_name[TREE_CODE(val)]));
02189 }
02190 }
02191 }
02192
02193
02194
02195 class INITBUF {
02196 public:
02197 UINT64 ival;
02198
02199 INITBUF(void) {}
02200 INITBUF(UINT64 i): ival(i) {}
02201 ~INITBUF(void) {}
02202 mUINT8 Nth_byte(INT i) {
02203 INT rshft_amt = (Target_Byte_Sex == BIG_ENDIAN) ? 7-i : i;
02204 return (ival >> (rshft_amt * 8)) & 0xff;
02205 }
02206 };
02207
02208
02209
02210
02211 static void
02212 Add_Bitfield_Initv_For_Tree (tree val, FLD_HANDLE fld, INT &bytes)
02213 {
02214 FmtAssert(TREE_CODE(val) == INTEGER_CST,
02215 ("initialization value of bitfield expected to be integer, not %s",
02216 tree_code_name[TREE_CODE(val)]));
02217 INT bofst = FLD_bofst(fld);
02218 INT bsize = FLD_bsize(fld);
02219 if (bsize == 0)
02220 return;
02221
02222 INITBUF ib(Get_Integer_Value(val));
02223
02224 ib.ival = ib.ival << (64 - bsize);
02225
02226 if (Target_Byte_Sex == BIG_ENDIAN)
02227 ib.ival = ib.ival >> bofst;
02228 else ib.ival = ib.ival >> (64 - bofst - bsize);
02229
02230
02231 INT num_of_bytes = ((bofst + bsize - 1) >> 3) + 1;
02232
02233 INT bytes_out = bytes - FLD_ofst(fld);
02234 INT i;
02235 if (bytes_out > 0) {
02236
02237
02238 for (i = 0; i < bytes_out - 1; i++)
02239 FmtAssert(ib.Nth_byte(i) == 0,
02240 ("processing error in Add_Bitfield_Initv_For_Tree"));
02241 if (ib.Nth_byte(bytes_out-1) != 0) {
02242 if (INITV_kind(last_aggregate_initv) == INITVKIND_VAL) {
02243 TCON &tc = INITV_tc_val(last_aggregate_initv);
02244 mUINT8 last_ival = TCON_k0(tc);
02245 tc.vals.k0 = last_ival | ib.Nth_byte(bytes_out-1);
02246 }
02247 else {
02248 if (INITV_kind(last_aggregate_initv) == INITVKIND_ONE)
02249 INITV_Init_Integer(last_aggregate_initv, MTYPE_I1,
02250 1 | ib.Nth_byte(bytes_out-1));
02251 else {
02252 FmtAssert(INITV_kind(last_aggregate_initv) == INITVKIND_ZERO,
02253 ("processing error in static bit field initialization"));
02254 INITV_Init_Integer(last_aggregate_initv, MTYPE_I1,
02255 ib.Nth_byte(bytes_out-1));
02256 }
02257 }
02258 }
02259 }
02260
02261 for (i = bytes_out; i < num_of_bytes; i++)
02262 WFE_Add_Aggregate_Init_Integer(ib.Nth_byte(i), 1);
02263 bytes += num_of_bytes - bytes_out;
02264 }
02265
02266
02267
02268 static void
02269 Gen_Assign_Of_Init_Val (
02270 #ifdef NEW_INITIALIZER
02271 WN *target,
02272 #else
02273 ST *st,
02274 #endif
02275 tree init, UINT offset, UINT array_elem_offset,
02276 TY_IDX ty, BOOL is_bit_field, UINT field_id, FLD_HANDLE fld, INT &bytes)
02277 {
02278 #ifdef KEY
02279
02280
02281 if (TY_return_in_mem(ty) &&
02282 TREE_CODE(init) == CALL_EXPR) {
02283 #ifndef NEW_INITIALIZER
02284 WN *target = WN_Lda (Pointer_Mtype, 0, st, 0);
02285 bytes += TY_size(ty);
02286 #endif
02287 WFE_Expand_Expr (init, TRUE, 0, 0, 0, 0, FALSE, FALSE, target);
02288 return;
02289 }
02290 #endif
02291
02292 #ifdef NEW_INITIALIZER
02293 if (TY_return_in_mem(ty) &&
02294 TREE_CODE(init) == TARGET_EXPR) {
02295
02296
02297 Is_True ((WN_operator(target) == OPR_LDID ||
02298 WN_operator(target) == OPR_LDA),
02299 ("Bad operator for target") );
02300 if (WN_offset(target) != 0 || offset != 0) {
02301 TY_IDX targ_ty = WN_ty(target);
02302 ST* addr_st = Gen_Temp_Symbol (TY_mtype(targ_ty), "target");
02303 WN* wn = WN_Stid (TY_mtype(targ_ty), 0, addr_st, targ_ty,
02304 WN_Binary (OPR_ADD, Pointer_Mtype,
02305 WN_CopyNode(target),
02306 WN_Intconst(MTYPE_I4, offset) ) );
02307 WFE_Stmt_Append (wn, Get_Srcpos());
02308 target = WN_Ldid (TY_mtype(targ_ty), 0, addr_st, targ_ty);
02309 }
02310 WFE_Expand_Expr (init, TRUE, 0, 0, 0, 0, FALSE, FALSE, target);
02311 bytes += TY_size(ty);
02312 return;
02313 }
02314 #endif
02315
02316 WN *init_wn = WFE_Expand_Expr (init);
02317
02318
02319 if (!init_wn) {
02320 Is_True(TREE_CODE(init) == COND_EXPR,
02321 ("Must be COND_EXPR when init_wn equlas to NULL."));
02322 return;
02323 }
02324
02325 if (TREE_CODE(init) == STRING_CST && TY_kind(ty) == KIND_ARRAY)
02326 {
02327
02328
02329
02330 UINT size = TY_size(ty);
02331
02332
02333
02334
02335 UINT load_size = ( size > TREE_STRING_LENGTH(init) ) ?
02336 TREE_STRING_LENGTH(init) : size;
02337 TY_IDX ptr_ty = Make_Pointer_Type(ty);
02338 WN *load_wn = WN_CreateMload (0, ptr_ty, init_wn,
02339 #ifdef KEY
02340 WN_Intconst(MTYPE_I4, load_size));
02341 #else
02342 WN_Intconst(MTYPE_I4, size));
02343 #endif
02344 #ifdef NEW_INITIALIZER
02345 WN *addr_wn = target;
02346 #else
02347 WN *addr_wn = WN_Lda(Pointer_Mtype, 0, st);
02348 #endif
02349 WFE_Stmt_Append(
02350 WN_CreateMstore (offset, ptr_ty,
02351 load_wn,
02352 addr_wn,
02353 #ifdef KEY
02354 WN_Intconst(MTYPE_I4, load_size)),
02355 #else
02356 WN_Intconst(MTYPE_I4,size)),
02357 #endif
02358 Get_Srcpos());
02359 #ifdef KEY // bug 3247
02360 if (size - load_size > 0) {
02361 load_wn = WN_Intconst(MTYPE_U4, 0);
02362 #ifdef NEW_INITIALIZER
02363 addr_wn = target;
02364 #else
02365 addr_wn = WN_Lda(Pointer_Mtype, 0, st);
02366 #endif
02367 WFE_Stmt_Append(
02368 WN_CreateMstore (offset+load_size, ptr_ty,
02369 load_wn,
02370 addr_wn,
02371 WN_Intconst(MTYPE_I4,size-load_size)),
02372 Get_Srcpos());
02373 }
02374 #endif
02375 bytes += size;
02376 }
02377 else {
02378 TYPE_ID mtype = is_bit_field ? MTYPE_BS : TY_mtype(ty);
02379 if (is_bit_field) {
02380 offset = array_elem_offset;
02381 } else
02382 field_id = 0;
02383 WFE_Set_ST_Addr_Saved (init_wn);
02384 #ifdef NEW_INITIALIZER
02385
02386
02387 WN* wn = NULL;
02388 Is_True( (WN_operator(target) == OPR_LDID ||
02389 WN_operator(target) == OPR_LDA),
02390 ("Invalid operator for target"));
02391 if( WN_operator(target) == OPR_LDID ) {
02392 TY_IDX ptr_ty = Make_Pointer_Type(ty);
02393 wn = WN_Istore(mtype, offset, ptr_ty, target, init_wn, field_id);
02394 }
02395 else {
02396 ST *st = WN_st(target);
02397 wn = WN_Stid (mtype, WN_lda_offset(target) + offset, st,
02398 ty, init_wn, field_id);
02399 }
02400 #else
02401 WN *wn = WN_Stid (mtype, ST_ofst(st) + offset, st,
02402 ty, init_wn, field_id);
02403 #endif
02404 WFE_Stmt_Append(wn, Get_Srcpos());
02405 if (! is_bit_field)
02406 bytes += TY_size(ty);
02407 else {
02408 INT bofst = FLD_bofst(fld);
02409 INT bsize = FLD_bsize(fld);
02410
02411 INT num_of_bytes = ((bofst + bsize - 1) >> 3) + 1;
02412
02413 INT bytes_out = bytes - FLD_ofst(fld);
02414 bytes += num_of_bytes - bytes_out;
02415 }
02416 }
02417 }
02418
02419 UINT
02420 Traverse_Aggregate_Constructor (
02421 #ifdef NEW_INITIALIZER
02422 WN *target,
02423 #else
02424 ST *st,
02425 #endif
02426 tree init_list, tree type, BOOL gen_initv,
02427 UINT current_offset, UINT array_elem_offset, UINT field_id);
02428
02429 UINT
02430 Traverse_Aggregate_Struct (
02431 #ifdef NEW_INITIALIZER
02432 WN *target,
02433 #else
02434 ST *st,
02435 #endif
02436 tree init_list, tree type, BOOL gen_initv,
02437 UINT current_offset, UINT array_elem_offset, UINT field_id);
02438
02439
02440
02441
02442
02443 void
02444 Traverse_Aggregate_Pad (
02445 #ifdef NEW_INITIALIZER
02446 WN *target,
02447 #else
02448 ST *st,
02449 #endif
02450 BOOL gen_initv,
02451 UINT pad,
02452 UINT current_offset)
02453 {
02454 if (gen_initv) {
02455 WFE_Add_Aggregate_Init_Padding (pad);
02456 }
02457 else {
02458 WN *zero_wn = WN_Intconst(MTYPE_U4, 0);
02459 WN *pad_wn = WN_Intconst(MTYPE_U4, pad);
02460 #ifdef NEW_INITIALIZER
02461 WN *addr_wn = target;
02462 #else
02463 WN *addr_wn = WN_Lda(Pointer_Mtype, 0, st);
02464 #endif
02465 TY_IDX mstore_ty = Make_Pointer_Type(MTYPE_To_TY(MTYPE_U1));
02466 WFE_Stmt_Append (WN_CreateMstore (current_offset, mstore_ty,
02467 zero_wn, addr_wn, pad_wn),
02468 Get_Srcpos());
02469 }
02470 }
02471
02472
02473
02474
02475
02476
02477 void
02478 Traverse_Aggregate_Array (
02479 #ifdef NEW_INITIALIZER
02480 WN *target,
02481 #else
02482 ST *st,
02483 #endif
02484 tree init_list,
02485 tree type,
02486 BOOL gen_initv,
02487 UINT current_offset)
02488 {
02489 INT emitted_bytes = 0;
02490 INT pad;
02491 TY_IDX ty = Get_TY(type);
02492 TY_IDX ety = TY_etype (ty);
02493 UINT esize = TY_size (ety);
02494 tree init;
02495 tree next;
02496 tree init_value;
02497
02498 for (init = CONSTRUCTOR_ELTS(init_list);
02499 init;
02500 init = next) {
02501
02502
02503 next = TREE_CHAIN(init);
02504 init_value = TREE_VALUE (init);
02505
02506 if (TREE_CODE(init_value) == PTRMEM_CST) {
02507 init_value = cplus_expand_constant(TREE_VALUE(init));
02508 }
02509
02510 if (TREE_CODE(init_value) == CONSTRUCTOR) {
02511
02512
02513
02514 #ifdef NEW_INITIALIZER
02515 Traverse_Aggregate_Constructor (target, init_value, TREE_TYPE(type),
02516 #else
02517 Traverse_Aggregate_Constructor (st, init_value, TREE_TYPE(type),
02518 #endif
02519 gen_initv, current_offset, current_offset,
02520 0);
02521 emitted_bytes += esize;
02522 }
02523
02524 else {
02525
02526
02527 if (gen_initv) {
02528 if ((next != NULL) && (TREE_CODE (init_value) == FDESC_EXPR) &&
02529 (TREE_CODE (TREE_VALUE (next)) == FDESC_EXPR) &&
02530 (TREE_VALUE (init_value) == TREE_VALUE (TREE_VALUE (next))))
02531 {
02532 init = next;
02533 next = TREE_CHAIN(next);
02534 Add_Initv_For_Tree (TREE_VALUE(init), esize);
02535 emitted_bytes += (esize << 1);
02536 current_offset += (esize << 1);
02537 continue;
02538 }
02539 else
02540 {
02541 Add_Initv_For_Tree (TREE_VALUE(init), esize);
02542 emitted_bytes += esize;
02543 }
02544 }
02545 else
02546 #ifdef NEW_INITIALIZER
02547 Gen_Assign_Of_Init_Val (target, TREE_VALUE(init), current_offset, 0,
02548 #else
02549 Gen_Assign_Of_Init_Val (st, TREE_VALUE(init), current_offset, 0,
02550 #endif
02551 ety, FALSE, 0, FLD_HANDLE (), emitted_bytes);
02552 }
02553
02554 current_offset += esize;
02555 }
02556
02557
02558 pad = TY_size (ty) - emitted_bytes;
02559
02560 if (pad > 0)
02561 #ifdef NEW_INITIALIZER
02562 Traverse_Aggregate_Pad (target, gen_initv, pad, current_offset);
02563 #else
02564 Traverse_Aggregate_Pad (st, gen_initv, pad, current_offset);
02565 #endif
02566
02567 }
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577 UINT
02578 Traverse_Aggregate_Struct (
02579 #ifdef NEW_INITIALIZER
02580 WN *target,
02581 #else
02582 ST *st,
02583 #endif
02584 tree init_list,
02585 tree type,
02586 BOOL gen_initv,
02587 UINT current_offset,
02588 UINT array_elem_offset,
02589
02590
02591
02592
02593
02594 UINT field_id)
02595 {
02596 TY_IDX ty = Get_TY(type);
02597 tree field = TYPE_FIELDS(type);
02598 FLD_HANDLE fld = TY_fld (ty);
02599
02600 INT emitted_bytes = 0;
02601 INT current_offset_base = current_offset;
02602 INT pad;
02603 BOOL is_bit_field;
02604 tree init;
02605 TY_IDX fld_ty;
02606
02607
02608
02609
02610
02611 #ifndef KEY // g++'s class.c already laid out the base types. Bug 11622.
02612 if (TYPE_BINFO(type) &&
02613 BINFO_BASETYPES(TYPE_BINFO(type))) {
02614 tree basetypes = BINFO_BASETYPES(TYPE_BINFO(type));
02615 INT32 i;
02616 for (i = 0; i < TREE_VEC_LENGTH(basetypes); ++i) {
02617 tree binfo = TREE_VEC_ELT(basetypes, i);
02618 tree basetype = BINFO_TYPE(binfo);
02619 if (!is_empty_base_class(basetype) ||
02620 !TREE_VIA_VIRTUAL(binfo)) {
02621 ++field_id;
02622 fld = FLD_next (fld);
02623 field_id += TYPE_FIELD_IDS_USED(basetype);
02624 }
02625 }
02626 }
02627 #endif
02628
02629 while (field && TREE_CODE(field) != FIELD_DECL)
02630 field = next_real_or_virtual_field(type, field);
02631
02632 for (init = CONSTRUCTOR_ELTS(init_list);
02633 init;
02634 init = TREE_CHAIN(init)) {
02635
02636
02637 ++field_id;
02638
02639
02640
02641 if (field && TREE_PURPOSE(init) && TREE_CODE(TREE_PURPOSE(init)) == FIELD_DECL) {
02642 for (;;) {
02643 if (field == TREE_PURPOSE(init)) {
02644 break;
02645 }
02646 #ifdef KEY
02647
02648 if (DECL_NAME(field) &&
02649 DECL_NAME(field) == DECL_NAME(TREE_PURPOSE(init))) {
02650 break;
02651 }
02652 #endif
02653 ++field_id;
02654 fld = FLD_next (fld);
02655 field = next_real_or_virtual_field(type, field);
02656 while (field && TREE_CODE(field) != FIELD_DECL)
02657 field = next_real_or_virtual_field(type, field);
02658 }
02659 }
02660
02661
02662 pad = FLD_ofst (fld) - emitted_bytes;
02663
02664 if (pad > 0) {
02665 #ifdef NEW_INITIALIZER
02666 Traverse_Aggregate_Pad (target, gen_initv, pad, current_offset);
02667 #else
02668 Traverse_Aggregate_Pad (st, gen_initv, pad, current_offset);
02669 #endif
02670 current_offset += pad;
02671 emitted_bytes += pad;
02672 }
02673
02674 fld_ty = FLD_type(fld);
02675 if (TREE_CODE(TREE_VALUE(init)) == CONSTRUCTOR) {
02676
02677 tree element_type;
02678 element_type = TREE_TYPE(field);
02679 #ifdef NEW_INITIALIZER
02680 field_id = Traverse_Aggregate_Constructor (target, TREE_VALUE(init),
02681 #else
02682 field_id = Traverse_Aggregate_Constructor (st, TREE_VALUE(init),
02683 #endif
02684 element_type, gen_initv,
02685 current_offset,
02686 array_elem_offset, field_id);
02687 emitted_bytes += TY_size(fld_ty);
02688 }
02689 #ifdef KEY
02690
02691
02692
02693 else if (TYPE_PTRMEMFUNC_P(TREE_TYPE(field))) {
02694 tree element_type;
02695 element_type = TREE_TYPE(field);
02696 tree t = cplus_expand_constant(TREE_VALUE(init));
02697 #ifdef NEW_INITIALIZER
02698 field_id = Traverse_Aggregate_Constructor (target, t,
02699 #else
02700 field_id = Traverse_Aggregate_Constructor (st, t,
02701 #endif
02702 element_type, gen_initv,
02703 current_offset,
02704 array_elem_offset, field_id);
02705 emitted_bytes += TY_size(fld_ty);
02706 }
02707 #endif
02708 else {
02709
02710 is_bit_field = FLD_is_bit_field(fld);
02711 if (gen_initv) {
02712 if (! is_bit_field) {
02713 Add_Initv_For_Tree (TREE_VALUE(init), TY_size(fld_ty));
02714 emitted_bytes += TY_size(fld_ty);
02715 }
02716 else {
02717 Add_Bitfield_Initv_For_Tree (TREE_VALUE(init), fld, emitted_bytes);
02718
02719 }
02720 }
02721 else {
02722 #ifdef NEW_INITIALIZER
02723 Gen_Assign_Of_Init_Val (target, TREE_VALUE(init),
02724 #else
02725 Gen_Assign_Of_Init_Val (st, TREE_VALUE(init),
02726 #endif
02727 current_offset, array_elem_offset,
02728 is_bit_field ? ty : fld_ty,
02729 is_bit_field, field_id, fld, emitted_bytes);
02730
02731 }
02732 }
02733
02734
02735 current_offset = current_offset_base + emitted_bytes;
02736 fld = FLD_next(fld);
02737 field = next_real_or_virtual_field(type, field);
02738 while (field && TREE_CODE(field) != FIELD_DECL)
02739 field = next_real_or_virtual_field(type, field);
02740 }
02741
02742
02743
02744 while ( ! fld.Is_Null()) {
02745 ++field_id;
02746 fld = FLD_next(fld);
02747 field = next_real_or_virtual_field(type, field);
02748 while (field && TREE_CODE(field) != FIELD_DECL)
02749 field = next_real_or_virtual_field(type, field);
02750 }
02751
02752
02753
02754 pad = TY_size (ty) - emitted_bytes;
02755
02756 if (pad > 0)
02757 #ifdef NEW_INITIALIZER
02758 Traverse_Aggregate_Pad (target, gen_initv, pad, current_offset);
02759 #else
02760 Traverse_Aggregate_Pad (st, gen_initv, pad, current_offset);
02761 #endif
02762
02763 return field_id;
02764 }
02765
02766 #ifdef KEY
02767
02768
02769
02770 void
02771 Traverse_Aggregate_Vector (
02772 #ifdef NEW_INITIALIZER
02773 WN * target,
02774 #else
02775 ST * st,
02776 #endif
02777 tree init_list,
02778 BOOL gen_initv,
02779 UINT current_offset,
02780 BOOL vec_cst = FALSE)
02781 {
02782 tree init;
02783 INT emitted_bytes = 0;
02784
02785 if (vec_cst)
02786 init = TREE_VECTOR_CST_ELTS (init_list);
02787 else
02788 init = CONSTRUCTOR_ELTS (init_list);
02789
02790 for (;
02791 init;
02792 init = TREE_CHAIN(init))
02793 {
02794 tree unit_type = TREE_TYPE(TREE_VALUE(init));
02795 tree size = TYPE_SIZE (unit_type);
02796 Is_True (TREE_CODE (size) == INTEGER_CST,
02797 ("Traverse_Aggregate_Vector: Vector of variable-sized units?"));
02798 UINT esize = Get_Integer_Value(size) / BITSPERBYTE;
02799 if (gen_initv)
02800 {
02801 Add_Initv_For_Tree (TREE_VALUE(init), esize);
02802 emitted_bytes += esize;
02803 }
02804 else
02805 #ifdef NEW_INITIALIZER
02806 Gen_Assign_Of_Init_Val (target, TREE_VALUE(init),
02807 #else
02808 Gen_Assign_Of_Init_Val (st, TREE_VALUE(init),
02809 #endif
02810 current_offset, 0,
02811 Get_TY(unit_type),
02812 0, 0, FLD_HANDLE(), emitted_bytes);
02813 current_offset += esize;
02814 }
02815 }
02816
02817 void
02818 Traverse_Aggregate_Vector_Const (
02819 #ifdef NEW_INITIALIZER
02820 WN * target,
02821 #else
02822 ST * st,
02823 #endif
02824 tree init_list,
02825 BOOL gen_initv,
02826 UINT current_offset)
02827 {
02828 #ifdef NEW_INITIALIZER
02829 Traverse_Aggregate_Vector (target, init_list, gen_initv, current_offset, TRUE);
02830 #else
02831 Traverse_Aggregate_Vector (st, init_list, gen_initv, current_offset, TRUE);
02832 #endif
02833 }
02834 #endif
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846 UINT
02847 Traverse_Aggregate_Constructor (
02848 #ifdef NEW_INITIALIZER
02849 WN *target,
02850 #else
02851 ST *st,
02852 #endif
02853 tree init_list,
02854 tree type,
02855 BOOL gen_initv,
02856
02857 UINT current_offset,
02858 UINT array_elem_offset,
02859 UINT field_id)
02860 {
02861 TY_IDX ty = Get_TY(type);
02862
02863 INITV_IDX last_aggregate_initv_save;
02864
02865 if (gen_initv) {
02866
02867 WFE_Add_Init_Block();
02868 INITV_Init_Block(last_aggregate_initv, INITV_Next_Idx());
02869 not_at_root = TRUE;
02870 last_aggregate_initv_save = last_aggregate_initv;
02871 last_aggregate_initv = 0;
02872 }
02873
02874 if (TY_kind (ty) == KIND_STRUCT) {
02875
02876 #ifdef NEW_INITIALIZER
02877 field_id = Traverse_Aggregate_Struct (target, init_list, type, gen_initv,
02878 #else
02879 field_id = Traverse_Aggregate_Struct (st, init_list, type, gen_initv,
02880 #endif
02881 current_offset, array_elem_offset,
02882 field_id);
02883 }
02884
02885 else
02886 if (TY_kind (ty) == KIND_ARRAY) {
02887
02888 #ifdef NEW_INITIALIZER
02889 Traverse_Aggregate_Array (target, init_list, type, gen_initv, current_offset);
02890 #else
02891 Traverse_Aggregate_Array (st, init_list, type, gen_initv, current_offset);
02892 #endif
02893 }
02894
02895 #ifdef KEY // bug 9550
02896 else
02897 if (TY_kind (ty) == KIND_SCALAR && MTYPE_is_vector (TY_mtype (ty))) {
02898
02899 #ifdef NEW_INITIALIZER
02900 Traverse_Aggregate_Vector (target, init_list, gen_initv, current_offset);
02901 #else
02902 Traverse_Aggregate_Vector (st, init_list, gen_initv, current_offset);
02903 #endif
02904 }
02905 #endif
02906
02907 else
02908 Fail_FmtAssertion ("Traverse_Aggregate_Constructor: non STRUCT/ARRAY");
02909
02910 #ifdef KEY
02911 if (gen_initv && last_aggregate_initv == 0)
02912 INITV_Init_Block(last_aggregate_initv_save, INITV_IDX_ZERO);
02913 #endif
02914
02915
02916 last_aggregate_initv = last_aggregate_initv_save;
02917
02918 return field_id;
02919 }
02920
02921 static void
02922 Add_Inito_For_Tree (tree init, ST *st)
02923 {
02924 tree kid;
02925 last_aggregate_initv = 0;
02926 switch (TREE_CODE(init)) {
02927 case INTEGER_CST:
02928 UINT64 val;
02929 val = Get_Integer_Value (init);
02930 #ifdef TARG_SL
02931
02932 if (val == 0 && !ST_in_vbuf(st) && !ST_in_sbuf(st)) {
02933 #else
02934 if (val == 0 ) {
02935 #endif
02936 Set_ST_init_value_zero(st);
02937 if (ST_sclass(st) == SCLASS_DGLOBAL)
02938 Set_ST_sclass(st, SCLASS_UGLOBAL);
02939 return;
02940 }
02941 aggregate_inito = New_INITO (st);
02942 not_at_root = FALSE;
02943 WFE_Add_Aggregate_Init_Integer (val, TY_size(ST_type(st)));
02944 return;
02945 case REAL_CST:
02946 aggregate_inito = New_INITO (st);
02947 not_at_root = FALSE;
02948 #ifdef KEY
02949 WFE_Add_Aggregate_Init_Real (TREE_REAL_CST(init),
02950 TY_size(ST_type(st)));
02951 #else
02952 WFE_Add_Aggregate_Init_Double (TREE_REAL_CST(init),
02953 TY_size(ST_type(st)));
02954 #endif
02955 return;
02956 case COMPLEX_CST:
02957 aggregate_inito = New_INITO (st);
02958 not_at_root = FALSE;
02959 WFE_Add_Aggregate_Init_Complex (TREE_REAL_CST(TREE_REALPART(init)),
02960 TREE_REAL_CST(TREE_IMAGPART(init)),
02961 TY_size(ST_type(st)));
02962 return;
02963 case STRING_CST:
02964 aggregate_inito = New_INITO (st);
02965 not_at_root = FALSE;
02966 WFE_Add_Aggregate_Init_String (const_cast<char*>TREE_STRING_POINTER(init),
02967 #ifdef KEY
02968 TY_size(ST_type(st)) < TREE_STRING_LENGTH(init) ?
02969 TY_size(ST_type(st)) :
02970 #endif
02971 TREE_STRING_LENGTH(init));
02972 if (TY_size (ST_type(st)) > TREE_STRING_LENGTH(init))
02973 WFE_Add_Aggregate_Init_Padding ( TY_size (ST_type(st)) -
02974 TREE_STRING_LENGTH(init));
02975 return;
02976 case NOP_EXPR:
02977 Add_Inito_For_Tree (TREE_OPERAND(init,0), st);
02978 return;
02979 case ADDR_EXPR:
02980 kid = TREE_OPERAND(init,0);
02981 if (TREE_CODE(kid) == VAR_DECL ||
02982 TREE_CODE(kid) == FUNCTION_DECL ||
02983 TREE_CODE(kid) == STRING_CST) {
02984 aggregate_inito = New_INITO (st);
02985 not_at_root = FALSE;
02986 WFE_Add_Aggregate_Init_Address (kid);
02987 return;
02988 }
02989 case PLUS_EXPR:
02990 kid = TREE_OPERAND(init,0);
02991 if (TREE_CODE(kid) == ADDR_EXPR) {
02992
02993 Add_Inito_For_Tree (kid, st);
02994 kid = TREE_OPERAND(init,1);
02995 if (INITV_kind(last_aggregate_initv) == INITVKIND_SYMOFF
02996 && TREE_CODE(kid) == INTEGER_CST)
02997 {
02998 Set_INITV_ofst (last_aggregate_initv,
02999 Get_Integer_Value(kid));
03000 return;
03001 }
03002 }
03003 break;
03004 case MINUS_EXPR:
03005 kid = TREE_OPERAND(init,0);
03006 if (TREE_CODE(kid) == ADDR_EXPR) {
03007
03008 Add_Inito_For_Tree (kid, st);
03009 kid = TREE_OPERAND(init,1);
03010 if (INITV_kind(last_aggregate_initv) == INITVKIND_SYMOFF
03011 && TREE_CODE(kid) == INTEGER_CST)
03012 {
03013 Set_INITV_ofst (last_aggregate_initv,
03014 -Get_Integer_Value(kid));
03015 return;
03016 }
03017 }
03018 break;
03019 case CONSTRUCTOR:
03020 aggregate_inito = New_INITO (st);
03021 not_at_root = FALSE;
03022 last_aggregate_initv = 0;
03023 #ifdef NEW_INITIALIZER
03024 WN* target = WN_Lda (Pointer_Mtype, 0, st, 0);
03025 Traverse_Aggregate_Constructor (target, init, TREE_TYPE(init),
03026 #else
03027 Traverse_Aggregate_Constructor (st, init, TREE_TYPE(init),
03028 #endif
03029 TRUE , 0, 0, 0);
03030 return;
03031 }
03032
03033
03034 WN *init_wn = WFE_Expand_Expr (init);
03035 if (WN_operator(init_wn) == OPR_INTCONST) {
03036 aggregate_inito = New_INITO (st);
03037 not_at_root = FALSE;
03038 WFE_Add_Aggregate_Init_Integer (
03039 WN_const_val(init_wn), TY_size(ST_type(st)));
03040 return;
03041 }
03042 else
03043 if (WN_operator(init_wn) == OPR_LDA) {
03044 aggregate_inito = New_INITO (st);
03045 not_at_root = FALSE;
03046 WFE_Add_Aggregate_Init_Symoff (WN_st (init_wn), WN_offset (init_wn));
03047 return;
03048 }
03049 else
03050 if (WN_operator(init_wn) == OPR_ADD) {
03051 if (WN_operator(WN_kid0(init_wn)) == OPR_LDA &&
03052 WN_operator(WN_kid1(init_wn)) == OPR_INTCONST) {
03053 aggregate_inito = New_INITO (st);
03054 not_at_root = FALSE;
03055 WFE_Add_Aggregate_Init_Symoff (WN_st(WN_kid0(init_wn)),
03056 WN_offset(WN_kid0(init_wn)) + WN_const_val(WN_kid1(init_wn)));
03057 return;
03058 }
03059 #ifdef KEY
03060 else if (WN_operator(WN_kid0(init_wn)) == OPR_CVT) {
03061
03062 WN *tmp_wn = WN_kid0(WN_kid0(init_wn));
03063 if (WN_operator(tmp_wn) == OPR_LDA) {
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073 WN *tmp1_wn = WN_kid0(WN_kid1(init_wn));
03074 if (WN_operator(tmp1_wn) == OPR_LDA) {
03075 if (WN_st(tmp_wn) == WN_st(tmp1_wn)) {
03076 aggregate_inito = New_INITO (st);
03077 not_at_root = FALSE;
03078 WFE_Add_Aggregate_Init_Integer (WN_offset(tmp_wn) -
03079 WN_offset(tmp1_wn),
03080 TY_size(ST_type(st)));
03081 return;
03082 }
03083 }
03084 }
03085 }
03086 #endif
03087 }
03088 else
03089 if (WN_operator(init_wn) == OPR_SUB) {
03090 if (WN_operator(WN_kid0(init_wn)) == OPR_LDA &&
03091 WN_operator(WN_kid1(init_wn)) == OPR_INTCONST) {
03092 aggregate_inito = New_INITO (st);
03093 not_at_root = FALSE;
03094 WFE_Add_Aggregate_Init_Symoff (WN_st(WN_kid0(init_wn)),
03095 WN_offset(WN_kid0(init_wn)) - WN_const_val(WN_kid1(init_wn)));
03096 return;
03097 }
03098 }
03099 Fail_FmtAssertion ("unexpected static init tree for %s", ST_name(st));
03100 }
03101
03102
03103 extern ST *
03104 WFE_Generate_Temp_For_Initialized_Aggregate (tree init, char * name)
03105 {
03106 TY_IDX ty_idx = Get_TY(TREE_TYPE(init));
03107 ST *temp = New_ST (CURRENT_SYMTAB);
03108 ST_Init (temp,
03109 Save_Str2 (name, ".init"),
03110 CLASS_VAR, SCLASS_PSTATIC, EXPORT_LOCAL,
03111 ty_idx );
03112 if (TREE_CODE(init) == CONSTRUCTOR
03113 && ! Use_Static_Init_For_Aggregate (temp, init))
03114 {
03115
03116 Set_ST_sclass(temp, SCLASS_AUTO);
03117 #ifdef NEW_INITIALIZER
03118 WN* target = WN_Lda (Pointer_Mtype, 0, temp, 0);
03119 Traverse_Aggregate_Constructor (target, init, TREE_TYPE(init),
03120 #else
03121 Traverse_Aggregate_Constructor (temp, init, TREE_TYPE(init),
03122 #endif
03123 FALSE , 0, 0, 0);
03124 }
03125 else {
03126
03127 Set_ST_is_initialized(temp);
03128 aggregate_inito = New_INITO (temp);
03129 not_at_root = FALSE;
03130 last_aggregate_initv = 0;
03131 #ifdef NEW_INITIALIZER
03132 WN* target = WN_Lda (Pointer_Mtype, 0, temp, 0);
03133 Traverse_Aggregate_Constructor (target, init, TREE_TYPE(init),
03134 #else
03135 Traverse_Aggregate_Constructor (temp, init, TREE_TYPE(init),
03136 #endif
03137 TRUE , 0, 0, 0);
03138 WFE_Finish_Aggregate_Init ();
03139 }
03140 return temp;
03141 }
03142
03143 #ifdef NEW_INITIALIZER
03144 ST* WFE_Generate_Initialized_Aggregate (WN * target, tree init)
03145 {
03146 Is_True(TREE_CODE(init) == CONSTRUCTOR,
03147 ("wrong tree code for target"));
03148 Is_True((WN_operator(target) == OPR_LDID ||
03149 WN_operator(target) == OPR_LDA),
03150 ("Invalid target operator"));
03151 ST* target_st = WN_st(target);
03152
03153 if (TREE_CODE(init) == CONSTRUCTOR
03154 && ! Use_Static_Init_For_Aggregate (target_st, init))
03155 {
03156 Traverse_Aggregate_Constructor (target, init, TREE_TYPE(init),
03157 FALSE , 0, 0, 0);
03158 return target_st;
03159 }
03160 else {
03161
03162
03163 DevWarn ("Static initialize %s(%s)\n",
03164 ST_name(target_st), Sclass_Name(ST_sclass(target_st)));
03165 TY_IDX ty_idx = Get_TY(TREE_TYPE(init));
03166 ST *temp = New_ST (CURRENT_SYMTAB);
03167 ST_Init (temp,
03168 Save_Str2 (ST_name(target_st), ".init"),
03169 CLASS_VAR, SCLASS_PSTATIC, EXPORT_LOCAL,
03170 ty_idx );
03171
03172 Set_ST_is_initialized(temp);
03173 aggregate_inito = New_INITO (temp);
03174 not_at_root = FALSE;
03175 last_aggregate_initv = 0;
03176 WN* temp_target = WN_Lda (Pointer_Mtype, 0, temp, 0);
03177 Traverse_Aggregate_Constructor (temp_target, init, TREE_TYPE(init),
03178 TRUE , 0, 0, 0);
03179 WFE_Finish_Aggregate_Init ();
03180 return temp;
03181 }
03182 }
03183 #endif
03184
03185 static tree init_decl = NULL;
03186
03187 extern void
03188 WFE_Initialize_Decl (tree decl)
03189 {
03190 if (DECL_IGNORED_P(decl)) {
03191
03192
03193 return;
03194 }
03195 ST *st = Get_ST(decl);
03196 tree init = DECL_INITIAL(decl);
03197 if (init->common.code == VAR_DECL &&
03198 DECL_CONTEXT(init) &&
03199 TREE_CODE(DECL_CONTEXT(init)) == RECORD_TYPE)
03200 Get_TY(DECL_CONTEXT(init));
03201
03202 if (TREE_STATIC(decl) || DECL_CONTEXT(decl) == NULL)
03203 {
03204
03205 if (ST_sclass(st) == SCLASS_UGLOBAL && !ST_init_value_zero(st) ||
03206 ST_sclass(st) == SCLASS_EXTERN ||
03207 ST_sclass(st) == SCLASS_COMMON)
03208 Set_ST_sclass(st, SCLASS_DGLOBAL);
03209 if (!ST_is_initialized(st)) {
03210 Set_ST_is_initialized(st);
03211 if (init_decl) {
03212 Push_Deferred_Decl_Init (decl);
03213 return;
03214 }
03215 init_decl = decl;
03216 Add_Inito_For_Tree (init, st);
03217 while (deferred_decl_init_i >= 0) {
03218 init_decl = Pop_Deferred_Decl_Init ();
03219 Add_Inito_For_Tree (DECL_INITIAL(init_decl),
03220 Get_ST(init_decl));
03221 }
03222 init_decl = NULL;
03223 }
03224 if (TREE_READONLY(decl))
03225 Set_ST_is_const_var (st);
03226 }
03227 else {
03228
03229 if (TREE_CODE(init) == CONSTRUCTOR) {
03230
03231 if (Use_Static_Init_For_Aggregate (st, init)) {
03232
03233
03234 ST *copy = WFE_Generate_Temp_For_Initialized_Aggregate(
03235 init, ST_name(st));
03236 WN *init_wn = WN_CreateLdid (OPR_LDID, MTYPE_M, MTYPE_M,
03237 0, copy, ST_type(copy));
03238 WFE_Stmt_Append(
03239 WN_CreateStid (OPR_STID, MTYPE_V, MTYPE_M,
03240 0, st, ST_type(st), init_wn),
03241 Get_Srcpos());
03242 }
03243 else {
03244
03245 #ifdef NEW_INITIALIZER
03246 WN* target = WN_Lda(Pointer_Mtype, 0, st, 0);
03247 Traverse_Aggregate_Constructor (target, init, TREE_TYPE(init),
03248 #else
03249 Traverse_Aggregate_Constructor (st, init, TREE_TYPE(init),
03250 #endif
03251 FALSE , 0, 0, 0);
03252 }
03253 }
03254 else {
03255 INT emitted_bytes;
03256 #ifdef NEW_INITIALIZER
03257 WN* target = WN_Lda(Pointer_Mtype, 0, st, 0);
03258 Gen_Assign_Of_Init_Val (target, init,
03259 #else
03260 Gen_Assign_Of_Init_Val (st, init,
03261 #endif
03262 0 , 0 ,
03263 ST_type(st), FALSE, 0 ,
03264 FLD_HANDLE(), emitted_bytes);
03265 }
03266 }
03267 }
03268
03269 #ifdef KEY
03270
03271 extern void
03272 WFE_Initialize_Nested_Decl (tree decl)
03273 {
03274 if (DECL_IGNORED_P(decl)) {
03275
03276
03277 return;
03278 }
03279 ST *st = Get_ST(decl);
03280 tree init = DECL_INITIAL(decl);
03281
03282 if (TREE_STATIC(decl) || DECL_CONTEXT(decl) == NULL)
03283 {
03284
03285 if ((ST_sclass(st) == SCLASS_UGLOBAL &&
03286 !ST_init_value_zero(st)) ||
03287 ST_sclass(st) == SCLASS_EXTERN ||
03288 ST_sclass(st) == SCLASS_COMMON)
03289 Set_ST_sclass(st, SCLASS_DGLOBAL);
03290 if (!ST_is_initialized(st)) {
03291 Set_ST_is_initialized(st);
03292 Add_Inito_For_Tree (init, st);
03293 WFE_Finish_Aggregate_Init ();
03294 }
03295 if (TREE_READONLY(decl))
03296 Set_ST_is_const_var (st);
03297 }
03298 else {
03299
03300 if (TREE_CODE(init) == CONSTRUCTOR) {
03301
03302 if (Use_Static_Init_For_Aggregate (st, init)) {
03303
03304
03305 ST *copy = WFE_Generate_Temp_For_Initialized_Aggregate(
03306 init, ST_name(st));
03307 WN *init_wn = WN_CreateLdid (OPR_LDID, MTYPE_M, MTYPE_M,
03308 0, copy, ST_type(copy));
03309 WFE_Stmt_Append(
03310 WN_CreateStid (OPR_STID, MTYPE_V, MTYPE_M,
03311 0, st, ST_type(st), init_wn),
03312 Get_Srcpos());
03313 }
03314 else {
03315
03316 #ifdef NEW_INITIALIZER
03317 WN* target = WN_Lda(Pointer_Mtype, 0, st, 0);
03318 Traverse_Aggregate_Constructor (target, init,
03319 #else
03320 Traverse_Aggregate_Constructor (st, init,
03321 #endif
03322 TREE_TYPE(init),
03323 FALSE ,
03324 0, 0, 0);
03325 }
03326 return;
03327 }
03328 else {
03329 INT emitted_bytes;
03330 #ifdef NEW_INITIALIZER
03331 WN* target = WN_Lda(Pointer_Mtype, 0, st, 0);
03332 Gen_Assign_Of_Init_Val (target, init,
03333 #else
03334 Gen_Assign_Of_Init_Val (st, init,
03335 #endif
03336 0 , 0 ,
03337 ST_type(st), FALSE, 0 ,
03338 FLD_HANDLE(), emitted_bytes);
03339 }
03340 }
03341 }
03342 #endif
03343
03344 void
03345 WFE_Decl (tree decl)
03346 {
03347 #ifndef KEY
03348 if (DECL_INITIAL (decl) != 0) return;
03349 #endif
03350 if (DECL_IGNORED_P(decl)) return;
03351 if (TREE_CODE(decl) != VAR_DECL) return;
03352 #ifndef KEY
03353 if (DECL_CONTEXT(decl) != 0) return;
03354 if ( ! TREE_PUBLIC(decl)) return;
03355 #endif
03356 if ( ! TREE_STATIC(decl)) return;
03357
03358
03359 (void) Get_ST(decl);
03360 }
03361
03362 BOOL
03363 WFE_Assemble_Alias (tree decl, tree target)
03364 {
03365 DevWarn ("__attribute alias encountered at line %d", lineno);
03366 tree base_decl = NULL;
03367 #ifndef KEY
03368 base_decl = lookup_name (target, 0);
03369 FmtAssert (base_decl != NULL,
03370 ("undeclared base symbol %s not yet declared in __attribute__ alias is not currently implemented",
03371 IDENTIFIER_POINTER (target)));
03372 #else
03373
03374
03375
03376
03377
03378
03379
03380
03381 if (DECL_ALIAS_TARGET_DECL(decl)) {
03382
03383 base_decl = DECL_ALIAS_TARGET_DECL(decl);
03384 } else {
03385
03386 tree subdecl;
03387 for (subdecl = cp_namespace_decls(curr_namespace_decl);
03388 subdecl != NULL_TREE;
03389 subdecl = TREE_CHAIN(subdecl)) {
03390 if (DECL_ASSEMBLER_NAME_SET_P(subdecl) &&
03391 !strcmp(IDENTIFIER_POINTER(DECL_ASSEMBLER_NAME(subdecl)),
03392 IDENTIFIER_POINTER(target))) {
03393 base_decl = subdecl;
03394 break;
03395 }
03396 }
03397 if (base_decl == NULL) {
03398
03399
03400 if (DECL_WEAK(decl))
03401 return FALSE;
03402 Is_True(FALSE, ("WFE_Assemble_Alias: cannot find decl for alias target"));
03403 }
03404 DECL_ALIAS_TARGET_DECL(decl) = base_decl;
03405 }
03406
03407
03408
03409 if (!expanded_decl(base_decl))
03410 return FALSE;
03411 expanded_decl(decl) = TRUE;
03412 #endif // KEY
03413 ST *base_st = Get_ST (base_decl);
03414 ST *st = Get_ST (decl);
03415 if (ST_is_weak_symbol(st)) {
03416 Set_ST_sclass (st, SCLASS_EXTERN);
03417 Set_ST_strong_idx (*st, ST_st_idx (base_st));
03418 }
03419 else {
03420 Set_ST_base_idx (st, ST_st_idx (base_st));
03421 Set_ST_emit_symbol(st);
03422 Set_ST_sclass (st, ST_sclass (base_st));
03423 if (ST_is_initialized (base_st))
03424 Set_ST_is_initialized (st);
03425 #ifdef KEY
03426 if (ST_init_value_zero (base_st))
03427 Set_ST_init_value_zero (st);
03428 #endif
03429 }
03430 #ifdef KEY
03431 return TRUE;
03432 #endif
03433
03434
03435
03436
03437
03438
03439
03440 }
03441
03442 #if 0
03443 void
03444 WFE_Assemble_Constructor (char *name)
03445 {
03446 DevWarn ("__attribute__ ((constructor)) encountered at line %d", lineno);
03447 tree func_decl = lookup_name (get_identifier (name), 1);
03448 ST *func_st = Get_ST (func_decl);
03449 INITV_IDX initv = New_INITV ();
03450 INITV_Init_Symoff (initv, func_st, 0, 1);
03451 ST *init_st = New_ST (GLOBAL_SYMTAB);
03452 ST_Init (init_st, Save_Str2i ("__ctors", "_", ++__ctors),
03453 CLASS_VAR, SCLASS_FSTATIC,
03454 EXPORT_LOCAL, Make_Pointer_Type (ST_pu_type (func_st), FALSE));
03455 Set_ST_is_initialized (init_st);
03456 INITO_IDX inito = New_INITO (init_st, initv);
03457 ST_ATTR_IDX st_attr_idx;
03458 ST_ATTR& st_attr = New_ST_ATTR (GLOBAL_SYMTAB, st_attr_idx);
03459 ST_ATTR_Init (st_attr, ST_st_idx (init_st), ST_ATTR_SECTION_NAME,
03460 Save_Str (".ctors"));
03461 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
03462 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
03463 Set_ST_addr_saved (func_st);
03464 }
03465
03466 void
03467 WFE_Assemble_Destructor (char *name)
03468 {
03469 DevWarn ("__attribute__ ((destructor)) encountered at line %d", lineno);
03470 tree func_decl = lookup_name (get_identifier (name), 1);
03471 ST *func_st = Get_ST (func_decl);
03472 INITV_IDX initv = New_INITV ();
03473 INITV_Init_Symoff (initv, func_st, 0, 1);
03474 ST *init_st = New_ST (GLOBAL_SYMTAB);
03475 ST_Init (init_st, Save_Str2i ("__dtors", "_", ++__dtors),
03476 CLASS_VAR, SCLASS_FSTATIC,
03477 EXPORT_LOCAL, Make_Pointer_Type (ST_pu_type (func_st), FALSE));
03478 Set_ST_is_initialized (init_st);
03479 INITO_IDX inito = New_INITO (init_st, initv);
03480 ST_ATTR_IDX st_attr_idx;
03481 ST_ATTR& st_attr = New_ST_ATTR (GLOBAL_SYMTAB, st_attr_idx);
03482 ST_ATTR_Init (st_attr, ST_st_idx (init_st), ST_ATTR_SECTION_NAME,
03483 Save_Str (".dtors"));
03484 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
03485 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
03486 Set_ST_addr_saved (func_st);
03487 }
03488
03489 #endif
03490
03491 ST *
03492 WFE_Get_Return_Address_ST (int level)
03493 {
03494 ST *return_address_st = Return_Address_ST [CURRENT_SYMTAB - level];
03495 if (return_address_st == NULL) {
03496 return_address_st = New_ST (CURRENT_SYMTAB - level);
03497 ST_Init (return_address_st, Save_Str ("__return_address"), CLASS_VAR,
03498 (PUSH_RETURN_ADDRESS_ON_STACK ? SCLASS_FORMAL : SCLASS_AUTO),
03499 EXPORT_LOCAL, Make_Pointer_Type (Be_Type_Tbl (MTYPE_V), FALSE));
03500 Set_ST_is_return_var (return_address_st);
03501 Return_Address_ST [CURRENT_SYMTAB - level] = return_address_st;
03502 }
03503
03504 return return_address_st;
03505 }
03506
03507 ST *
03508 WFE_Alloca_0 (void)
03509 {
03510 WN *wn;
03511 TY_IDX ty_idx = Make_Pointer_Type (Be_Type_Tbl (MTYPE_V), FALSE);
03512 ST* alloca_st = Gen_Temp_Symbol (ty_idx, "__alloca");
03513 #ifdef KEY
03514 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, alloca_st);
03515 #endif
03516 wn = WN_CreateAlloca (WN_CreateIntconst (OPC_I4INTCONST, 0));
03517 wn = WN_Stid (Pointer_Mtype, 0, alloca_st, ty_idx, wn);
03518 WFE_Stmt_Append (wn, Get_Srcpos());
03519 Set_PU_has_alloca (Get_Current_PU ());
03520 return alloca_st;
03521 }
03522
03523 ST *
03524 WFE_Alloca_ST (tree decl)
03525 {
03526 ST *st = Create_ST_For_Tree (decl);
03527 ST *alloca_st = New_ST (CURRENT_SYMTAB);
03528 ST_Init (alloca_st, Save_Str (ST_name (st)),
03529 CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL,
03530 Make_Pointer_Type (ST_type (st), FALSE));
03531 Set_ST_is_temp_var (alloca_st);
03532 Set_ST_pt_to_unique_mem (alloca_st);
03533 Set_ST_base_idx (st, ST_st_idx (alloca_st));
03534 WN *swn = WFE_Expand_Expr (TYPE_SIZE(TREE_TYPE(decl)));
03535 WN *wn = WN_CreateAlloca (swn);
03536 wn = WN_Stid (Pointer_Mtype, 0, alloca_st, ST_type (alloca_st), wn);
03537 WFE_Stmt_Append (wn, Get_Srcpos());
03538 return st;
03539 }
03540
03541 #ifdef KEY
03542 void
03543 WFE_Dealloca (ST * alloca_st, vector<ST*> * vars)
03544 {
03545 int nkids = vars->size();
03546 Is_True (nkids > 0, ("No object allocated by alloca?"));
03547
03548 WN * wn = WN_CreateDealloca (nkids+1);
03549 WN_kid0 (wn) = WN_Ldid (Pointer_Mtype, 0, alloca_st, ST_type (alloca_st));
03550 nkids = 0;
03551
03552 while (! vars->empty())
03553 {
03554 ST * base_st = vars->back();
03555 WN_kid (wn, ++nkids) = WN_Ldid (Pointer_Mtype, 0, base_st, ST_type (base_st));
03556 vars->pop_back();
03557 }
03558 WFE_Stmt_Append (wn, Get_Srcpos());
03559 }
03560 #endif // KEY
03561
03562 #ifndef KEY // obsolete
03563 void
03564 WFE_Dealloca (ST *alloca_st, tree vars)
03565 {
03566 int nkids = 0;
03567 tree decl;
03568 WN *wn;
03569 ST *st;
03570 ST *base_st;
03571
03572 for (decl =vars; decl; decl = TREE_CHAIN (decl))
03573 if (TREE_CODE (decl) == VAR_DECL && DECL_ST (decl)) {
03574 st = DECL_ST (decl);
03575 base_st = ST_base (st);
03576 if (st != base_st)
03577 ++nkids;
03578 }
03579
03580 wn = WN_CreateDealloca (nkids+1);
03581 WN_kid0 (wn) = WN_Ldid (Pointer_Mtype, 0, alloca_st, ST_type (alloca_st));
03582 nkids = 0;
03583
03584 for (decl =vars; decl; decl = TREE_CHAIN (decl))
03585 if (TREE_CODE (decl) == VAR_DECL && DECL_ST (decl)) {
03586 st = DECL_ST (decl);
03587 base_st = ST_base (st);
03588 if (st != base_st)
03589 WN_kid (wn, ++nkids) = WN_Ldid (Pointer_Mtype, 0, base_st, ST_type (base_st));
03590 }
03591
03592 WFE_Stmt_Append (wn, Get_Srcpos());
03593 }
03594
03595 void
03596 WFE_Record_Asmspec_For_ST (tree decl, char *asmspec, int reg)
03597 {
03598 extern PREG_NUM Map_Reg_To_Preg [];
03599 PREG_NUM preg = Map_Reg_To_Preg [reg];
03600 FmtAssert (preg >= 0,
03601 ("mapping register %d to preg failed\n", reg));
03602 ST *st = Get_ST (decl);
03603 TY_IDX ty_idx = ST_type (st);
03604 Set_TY_is_volatile (ty_idx);
03605 Set_ST_type (st, ty_idx);
03606 Set_ST_assigned_to_dedicated_preg (st);
03607 ST_ATTR_IDX st_attr_idx;
03608 ST_ATTR& st_attr = New_ST_ATTR (CURRENT_SYMTAB, st_attr_idx);
03609 ST_ATTR_Init (st_attr, ST_st_idx (st), ST_ATTR_DEDICATED_REGISTER, preg);
03610 }
03611 #endif // KEY
03612
03613 void
03614 WFE_Resolve_Duplicate_Decls (tree olddecl, tree newdecl)
03615 {
03616 ST *st = DECL_ST(olddecl);
03617 tree newtype = TREE_TYPE(newdecl);
03618 tree newsize = TYPE_SIZE(newtype);
03619 TY_IDX ty = ST_type (st);
03620
03621 if (TREE_STATIC(olddecl) == FALSE &&
03622 TREE_STATIC(newdecl) == TRUE &&
03623 TREE_PUBLIC(olddecl) == TRUE &&
03624 TREE_PUBLIC(newdecl) == FALSE) {
03625 Set_ST_sclass (st, SCLASS_FSTATIC);
03626 Set_ST_export (st, EXPORT_LOCAL);
03627 }
03628
03629 if (newsize &&
03630 TREE_CODE(newsize) == INTEGER_CST &&
03631 TY_size (ty) <= Get_Integer_Value (newsize) / BITSPERBYTE) {
03632 UINT64 size = Get_Integer_Value (newsize) / BITSPERBYTE;
03633 Set_TY_size (ty, size);
03634 if (TY_kind (ty) == KIND_ARRAY) {
03635 Set_ARB_const_ubnd (TY_arb(ty));
03636 Set_ARB_ubnd_val (TY_arb(ty), (size / TY_size(TY_etype(ty))) - 1);
03637 }
03638 }
03639 }
03640
03641
03642 extern tree weak_decls;
03643
03644
03645
03646
03647
03648 void
03649 WFE_Add_Weak ()
03650 {
03651 tree decl = TREE_VALUE (weak_decls);
03652 if (decl) {
03653 ST *st = DECL_ST (decl);
03654 if (st)
03655 Set_ST_is_weak_symbol (st);
03656 }
03657 }
03658
03659
03660
03661
03662
03663
03664 void
03665 WFE_Weak_Finish ()
03666 {
03667 tree t;
03668 for (t = weak_decls; t; t = TREE_CHAIN (t)) {
03669 tree decl = TREE_VALUE (t);
03670 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
03671 if (! TREE_USED (decl))
03672 continue;
03673 else {
03674 ST *st = DECL_ST (decl);
03675
03676 if (!st)
03677 st = Get_ST (decl);
03678 if (st) {
03679 Set_ST_is_weak_symbol (st);
03680 }
03681 }
03682 }
03683 }
03684
03685
03686 void WFE_Process_Type_Decl (tree);
03687 void WFE_Process_Template_Decl (tree);
03688 void WFE_Process_Var_Decl (tree);
03689 void WFE_Process_Function_Decl (tree);
03690 void WFE_Process_Namespace_Decl (tree);
03691 void WFE_Process_Decl (tree);
03692
03693 void
03694 WFE_Process_Class_Decl (tree decl)
03695 {
03696
03697 if (cp_type_quals(decl) != TYPE_UNQUALIFIED)
03698 return;
03699
03700 if (TYPE_TY_IDX(decl))
03701 return;
03702
03703 TYPE_TY_IDX(decl) = MTYPE_B;
03704
03705 tree binfo = TYPE_BINFO(decl);
03706 tree basetypes = binfo ? BINFO_BASETYPES(binfo) : 0;
03707 INT32 i;
03708 if (basetypes)
03709 for (i = 0; i < TREE_VEC_LENGTH(basetypes); ++i)
03710 (void) WFE_Process_Class_Decl (BINFO_TYPE(TREE_VEC_ELT(basetypes, i)));
03711
03712 tree field;
03713 for (field = TYPE_FIELDS (decl);
03714 field != NULL_TREE;
03715 field = next_real_or_virtual_field (decl, field)) {
03716 if (TREE_CODE(field) == TYPE_DECL) {
03717 tree field_type = TREE_TYPE(field);
03718 if (field_type &&
03719 TREE_CODE(field_type) == RECORD_TYPE &&
03720 field_type != decl) {
03721 WFE_Process_Class_Decl (field_type);
03722 }
03723 }
03724 }
03725
03726 tree method = TYPE_METHODS(decl);
03727 while (method != NULL_TREE) {
03728 if (TREE_CODE(method) == FUNCTION_DECL) {
03729 tree body = DECL_SAVED_TREE(method);
03730 if (body != NULL_TREE && !DECL_EXTERNAL(method) &&
03731 !DECL_WEAK(method) &&
03732 !DECL_INLINE(method) &&
03733 DECL_ST(method) == NULL &&
03734 (DECL_TEMPLATE_INFO(method) == NULL ||
03735 DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(method) ||
03736 DECL_TEMPLATE_INSTANTIATED(method) ||
03737 DECL_TEMPLATE_SPECIALIZATION(method))) {
03738 WFE_Process_Function_Decl (method);
03739 }
03740 }
03741 method = TREE_CHAIN(method);
03742 }
03743 }
03744
03745 void
03746 WFE_Process_Type_Decl (tree decl)
03747 {
03748
03749 if (TREE_CODE(TREE_TYPE(decl)) == RECORD_TYPE &&
03750 cp_type_quals(decl) == TYPE_UNQUALIFIED) {
03751 WFE_Process_Class_Decl (TREE_TYPE(decl));
03752 }
03753 }
03754
03755 void
03756 WFE_Process_Template_Decl (tree decl)
03757 {
03758
03759 tree gentemp = most_general_template(decl);
03760 #if 0
03761 for (tree t = DECL_TEMPLATE_SPECIALIZATIONS(gentemp);
03762 t; t = TREE_CHAIN(t))
03763 if (TREE_CODE(TREE_VALUE(t)) == FUNCTION_DECL &&
03764 DECL_SAVED_TREE(TREE_VALUE(t)) &&
03765 !DECL_EXTERNAL(TREE_VALUE(t)) &&
03766 !uses_template_parms (TREE_VALUE(t)))
03767 st = Get_ST (TREE_VALUE(t));
03768 DECL_TEMPLATE_SPECIALIZATIONS(gentemp) = 0;
03769 #endif
03770 for (tree t = DECL_TEMPLATE_INSTANTIATIONS(gentemp);
03771 t; t = TREE_CHAIN(t)) {
03772 tree val = TREE_VALUE(t);
03773 if (TREE_CODE(val) == RECORD_TYPE &&
03774 !uses_template_parms(val))
03775 WFE_Process_Class_Decl (val);
03776 }
03777 }
03778
03779 #ifdef KEY
03780
03781 bool
03782 decl_is_needed_vtt (tree decl)
03783 {
03784 bool needed = false;
03785
03786
03787 if (DECL_NAME(decl) &&
03788 IDENTIFIER_POINTER(DECL_NAME(decl)) &&
03789 !strncmp("_ZTT", IDENTIFIER_POINTER(DECL_NAME(decl)), 4)) {
03790 needed = true;
03791 }
03792 return needed;
03793 }
03794 #endif
03795
03796 bool
03797 decl_is_needed_vtable (tree decl)
03798 {
03799 bool needed = false;
03800 if (DECL_NAME(decl) &&
03801 IDENTIFIER_POINTER(DECL_NAME(decl)) &&
03802 #ifdef KEY
03803 !strncmp("_ZTV", IDENTIFIER_POINTER(DECL_NAME(decl)), 4)
03804 #else
03805 !strncmp("__vt_", IDENTIFIER_POINTER(DECL_NAME(decl)), 5)
03806 #endif
03807 ) {
03808
03809 tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
03810
03811 for (; entries; entries = TREE_CHAIN (entries)) {
03812
03813 tree fnaddr;
03814 tree fn;
03815
03816 fnaddr = TREE_VALUE (entries);
03817
03818 #ifdef KEY
03819 if (TREE_CODE (fnaddr) == NOP_EXPR &&
03820 TREE_CODE (TREE_OPERAND (fnaddr, 0)) == ADDR_EXPR) {
03821 fn = TREE_OPERAND (TREE_OPERAND (fnaddr, 0), 0);
03822
03823 } else if (TREE_CODE (fnaddr) != ADDR_EXPR) {
03824
03825
03826 continue;
03827 } else
03828 fn = TREE_OPERAND (fnaddr, 0);
03829 #else
03830 if (TREE_CODE (fnaddr) != ADDR_EXPR)
03831
03832
03833 continue;
03834
03835 fn = TREE_OPERAND (fnaddr, 0);
03836 #endif
03837
03838 #ifdef KEY
03839
03840
03841 if (DECL_EMITTED_BY_GXX(fn)) {
03842 needed = TRUE;
03843 break;
03844 }
03845 #endif
03846
03847 if (!DECL_EXTERNAL(fn) &&
03848 !DECL_WEAK(fn)
03849 #ifndef KEY
03850 && !DECL_INLINE(fn)
03851 #endif
03852 ) {
03853 needed = TRUE;
03854 break;
03855 }
03856 }
03857 }
03858
03859 return needed;
03860 }
03861
03862 void
03863 WFE_Process_Var_Decl (tree decl)
03864 {
03865
03866 ST *st;
03867 if (TREE_PUBLIC(decl) &&
03868
03869 !DECL_EXTERNAL(decl) &&
03870 !DECL_ST(decl)) {
03871 if (!DECL_WEAK(decl)
03872 || decl_is_needed_vtable (decl)
03873 #ifdef KEY
03874 || decl_is_needed_vtt (decl)
03875 #endif
03876 ) {
03877 #ifdef KEY
03878 WFE_Expand_Decl(decl);
03879 #else
03880 DECL_ST(decl) = (ST *) 1;
03881 Push_Deferred_Function (decl);
03882 #endif
03883 }
03884 }
03885 }
03886
03887 void
03888 WFE_Process_Function_Decl (tree decl)
03889 {
03890
03891 tree body;
03892 ST *st;
03893 body = DECL_SAVED_TREE(decl);
03894 if (body != NULL_TREE && !DECL_EXTERNAL(decl) &&
03895 !DECL_ARTIFICIAL(decl) &&
03896 !DECL_INLINE(decl) &&
03897 DECL_ST(decl) == NULL &&
03898 (DECL_TEMPLATE_INFO(decl) == NULL ||
03899 DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(decl) ||
03900 DECL_TEMPLATE_INSTANTIATED(decl) ||
03901 DECL_TEMPLATE_SPECIALIZATION(decl))) {
03902 #ifdef KEY
03903 set_DECL_ST(decl, (ST *) 1);
03904 #else
03905 DECL_ST(decl) = (ST *) 1;
03906 #endif
03907 Push_Deferred_Function (decl);
03908 }
03909 }
03910
03911 void
03912 WFE_Process_Decl (tree decl)
03913 {
03914 switch (TREE_CODE (decl)) {
03915
03916 case NAMESPACE_DECL:
03917 WFE_Process_Namespace_Decl (decl);
03918 break;
03919
03920 case CONST_DECL:
03921 break;
03922
03923 case TYPE_DECL:
03924 WFE_Process_Type_Decl (decl);
03925 break;
03926
03927 case TEMPLATE_DECL:
03928 WFE_Process_Template_Decl (decl);
03929 break;
03930
03931 case VAR_DECL:
03932 WFE_Process_Var_Decl (decl);
03933 break;
03934
03935 case FUNCTION_DECL:
03936 WFE_Process_Function_Decl (decl);
03937 break;
03938
03939 default:
03940 break;
03941 }
03942 }
03943
03944 void
03945 WFE_Process_Namespace_Decl (tree namespace_decl)
03946 {
03947
03948 tree decl;
03949 if (!DECL_NAMESPACE_ALIAS(namespace_decl) && (namespace_decl != std_node)) {
03950 for (decl = cp_namespace_decls(namespace_decl);
03951 decl != NULL_TREE;
03952 decl = TREE_CHAIN(decl)) {
03953 WFE_Process_Decl(decl);
03954 }
03955 }
03956 }
03957
03958 extern "C"
03959 void
03960 WFE_Expand_Top_Level_Decl (tree top_level_decl)
03961 {
03962 int error_count, sorry_count;
03963 #ifdef KEY
03964 tree old_namespace_decl = curr_namespace_decl;
03965 curr_namespace_decl = top_level_decl;
03966 #endif
03967
03968 if (top_level_decl == global_namespace) {
03969 check_gnu_errors (&error_count, &sorry_count);
03970 if (error_count || sorry_count)
03971 return;
03972 Init_Deferred_Function_Stack();
03973 Init_Deferred_Decl_Init_Stack();
03974 }
03975
03976 if (!Enable_WFE_DFE) {
03977 #ifdef KEY
03978
03979
03980 std::vector<char *>::iterator asm_iter;
03981 for (asm_iter = gxx_emitted_asm.begin();
03982 asm_iter != gxx_emitted_asm.end();
03983 asm_iter++)
03984 WFE_Assemble_Asm (*asm_iter);
03985 #endif
03986
03987 WFE_Expand_Decl (top_level_decl);
03988
03989 #ifdef KEY
03990
03991
03992 std::vector<tree>::iterator it;
03993 int changed;
03994 do {
03995 changed = 0;
03996 for (it = gxx_emitted_decls.begin();
03997 it != gxx_emitted_decls.end();
03998 it++) {
03999 tree decl = *it;
04000 if (expanded_decl(decl) == TRUE)
04001 continue;
04002 if (TREE_CODE(decl) == FUNCTION_DECL) {
04003 if (DECL_THUNK_P(decl))
04004 WFE_Generate_Thunk(decl);
04005 else if (DECL_ALIAS_TARGET(decl))
04006 changed |= WFE_Assemble_Alias(decl, DECL_ALIAS_TARGET(decl));
04007 else
04008 changed |= WFE_Expand_Function_Body(decl);
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023 if (Debug_Level > 0) {
04024 tree context = DECL_CONTEXT(decl);
04025 if (context && TREE_CODE(context) == RECORD_TYPE) {
04026
04027
04028
04029
04030 BOOL skip = FALSE;
04031 if (IDENTIFIER_CTOR_OR_DTOR_P(DECL_NAME(decl)))
04032 skip = TRUE;
04033 else if (DECL_THUNK_P(decl)) {
04034
04035 tree addr = DECL_INITIAL_2(decl);
04036 Is_True(TREE_CODE(addr) == ADDR_EXPR &&
04037 TREE_CODE(TREE_OPERAND(addr, 0)) == FUNCTION_DECL,
04038 ("WFE_Expand_Top_Level_Decl: invalid thunk decl"));
04039 skip =
04040 IDENTIFIER_CTOR_OR_DTOR_P(DECL_NAME(TREE_OPERAND(addr, 0)));
04041 }
04042 if (!skip) {
04043 TY_IDX context_ty_idx = Get_TY(context);
04044
04045
04046 add_deferred_DST_types();
04047 DST_INFO_IDX context_dst_idx = TYPE_DST_IDX(context);
04048 DST_enter_member_function(context, context_dst_idx,
04049 context_ty_idx, decl);
04050 }
04051 }
04052 }
04053 } else if (TREE_CODE(decl) == VAR_DECL) {
04054 WFE_Process_Var_Decl (decl);
04055 } else if (TREE_CODE(decl) == NAMESPACE_DECL) {
04056 WFE_Expand_Decl (decl);
04057 } else {
04058 FmtAssert(FALSE, ("WFE_Expand_Top_Level_Decl: invalid node"));
04059 }
04060 }
04061 } while (changed);
04062
04063 for (it = emit_typeinfos.begin(); it != emit_typeinfos.end(); ++it) {
04064 tree decl = *it;
04065 if (expanded_decl (decl))
04066 continue;
04067 expanded_decl (decl) = TRUE;
04068 FmtAssert (TREE_CODE (decl) == VAR_DECL, ("Unexpected node in typeinfo"));
04069 WFE_Expand_Decl (decl);
04070 }
04071 #endif
04072
04073 } else {
04074
04075 WFE_Process_Namespace_Decl (top_level_decl);
04076
04077 tree decl;
04078 INT32 i;
04079 for (i = deferred_function_i; i >= 0; --i) {
04080 decl = deferred_function_stack [i];
04081 #ifdef KEY
04082 set_DECL_ST(decl, NULL);
04083 #else
04084 DECL_ST(decl) = NULL;
04085 #endif
04086 }
04087
04088 ST *st;
04089 for (i = deferred_function_i; i >= 0; --i) {
04090 decl = deferred_function_stack [i];
04091 st = Get_ST (decl);
04092
04093 }
04094
04095 while (deferred_function_i >= 0) {
04096 decl = Pop_Deferred_Function ();
04097 if (TREE_CODE(decl) == FUNCTION_DECL)
04098 if (DECL_THUNK_P(decl))
04099 WFE_Generate_Thunk(decl);
04100 else
04101 WFE_Expand_Function_Body (decl);
04102 else {
04103 st = DECL_ST(decl);
04104 if (ST_sclass(st) == SCLASS_EXTERN)
04105 Set_ST_sclass (st, SCLASS_UGLOBAL);
04106 WFE_Expand_Decl (decl);
04107 }
04108 }
04109 }
04110
04111 #ifdef KEY
04112 {
04113 int i;
04114
04115
04116 for (i = 0; i < emit_decls.size(); i++) {
04117 tree decl = emit_decls[i];
04118 if (TREE_CODE(decl) == VAR_DECL)
04119 WFE_Expand_Decl(decl);
04120 else if (TREE_CODE(decl) == RECORD_TYPE ||
04121 TREE_CODE(decl) == UNION_TYPE)
04122 Get_TY(decl);
04123 else
04124 Is_True(FALSE, ("WFE_Expand_Top_Level_Decl: unexpected tree type"));
04125 }
04126 }
04127
04128 {
04129
04130
04131 for (int i = 0; i < defer_fields.size(); i++) {
04132 tree field = defer_fields[i].first;
04133 FLD_HANDLE fld = defer_fields[i].second;
04134 Is_True(TREE_CODE(field) == FIELD_DECL,
04135 ("WFE_Expand_Top_Level_Decl: FIELD_DECL not found"));
04136
04137 Is_True(TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE,
04138 ("WFE_Expand_Top_Level_Decl: POINTER_TYPE not found"));
04139 TY_IDX fty_idx = Get_TY(TREE_TYPE(field));
04140 Set_FLD_type(fld, fty_idx);
04141 }
04142 }
04143
04144 {
04145
04146 int i;
04147
04148
04149 add_deferred_DST_types();
04150
04151
04152 for (i = 0; i < defer_DST_misc.size(); i++) {
04153 DST_defer_misc_info *p = defer_DST_misc[i];
04154 if (p->is_member_function) {
04155 tree context = p->u1.member_func.context;
04156 DST_INFO_IDX context_dst_idx = TYPE_DST_IDX(context);
04157 TY_IDX context_ty_idx = Get_TY(context);
04158 DST_enter_member_function(context, context_dst_idx, context_ty_idx,
04159 p->u1.member_func.fndecl);
04160 }
04161 }
04162
04163
04164
04165 add_deferred_DST_types();
04166 }
04167
04168 curr_namespace_decl = old_namespace_decl;
04169 #endif
04170 }
04171
04172 #ifdef KEY
04173
04174
04175
04176
04177 void
04178 add_deferred_DST_types()
04179 {
04180 static int last_type_index = -1;
04181 int i;
04182
04183 for (i = last_type_index + 1; i < defer_DST_types.size(); i++) {
04184 DST_defer_type_info *p = defer_DST_types[i];
04185 DST_INFO_IDX dst = Create_DST_type_For_Tree(p->t, p->ttidx, p->idx);
04186 TYPE_DST_IDX(p->t) = dst;
04187 }
04188 last_type_index = defer_DST_types.size() - 1;
04189 }
04190
04191
04192
04193
04194
04195
04196
04197 static tree
04198 WFE_get_thunk_target (tree decl)
04199 {
04200 if (TREE_CODE (DECL_INITIAL(decl)) == ADDR_EXPR) {
04201 return DECL_INITIAL(decl);
04202 } else {
04203 Is_True(DECL_INITIAL_2(decl) &&
04204 TREE_CODE(DECL_INITIAL_2(decl)) == ADDR_EXPR,
04205 ("ADDR_EXPR not found for thunk"));
04206 return DECL_INITIAL_2(decl);
04207 }
04208 }
04209
04210
04211
04212
04213 static void
04214 WFE_Handle_Named_Return_Value (tree fn)
04215 {
04216 named_ret_obj_initializer = NULL_TREE;
04217
04218
04219
04220
04221 tree named_ret_obj = DECL_NAMED_RETURN_OBJECT(fn);
04222 if (named_ret_obj == NULL_TREE)
04223 return;
04224
04225 FmtAssert(TREE_CODE(named_ret_obj) == VAR_DECL,
04226 ("WFE_Handle_Named_Return_Value: named return object not a VAR_DECL"));
04227
04228
04229
04230 Get_ST(named_ret_obj);
04231
04232
04233 TY_IDX ret_ty_idx = Get_TY(TREE_TYPE(TREE_TYPE(fn)));
04234 FmtAssert(TY_return_in_mem(ret_ty_idx),
04235 ("WFE_Handle_Named_Return_Value: nrv type not in mem"));
04236
04237
04238 WN *first_formal = WN_formal(Current_Entry_WN(), 0);
04239
04240
04241
04242
04243
04244 if (DECL_INITIAL(named_ret_obj)) {
04245 named_ret_obj_initializer = build(TARGET_EXPR, TREE_TYPE(named_ret_obj),
04246 named_ret_obj,
04247 DECL_INITIAL(named_ret_obj),
04248 NULL_TREE, NULL_TREE);
04249 TREE_SIDE_EFFECTS(named_ret_obj_initializer) = 1;
04250 }
04251
04252 tree ptr_var = build_decl(VAR_DECL, NULL_TREE,
04253 build_pointer_type(TREE_TYPE(TREE_TYPE(fn))));
04254 TREE_SET_CODE(named_ret_obj, INDIRECT_REF);
04255 TREE_OPERAND(named_ret_obj, 0) = ptr_var;
04256 set_DECL_ST(ptr_var, WN_st(first_formal));
04257
04258
04259
04260 if (Debug_Level >= 2) {
04261 DST_INFO_IDX info_idx = DECL_DST_IDX(named_ret_obj);
04262 DST_ATTR_IDX attr_idx = DST_INFO_attributes(DST_INFO_IDX_TO_PTR(info_idx));
04263 DST_VARIABLE *attr = DST_ATTR_IDX_TO_PTR(attr_idx, DST_VARIABLE);
04264 DST_ASSOC_INFO_fe_ptr(DST_VARIABLE_def_st(attr)) =
04265 (void *)ST_st_idx(WN_st(first_formal));
04266 DST_SET_deref(DST_INFO_flag( DST_INFO_IDX_TO_PTR(info_idx)));
04267 }
04268 }
04269 #endif