1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1985-1998 by Symantec 6 * Copyright (C) 2000-2021 by The D Language Foundation, All Rights Reserved 7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 8 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 9 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/cc.d, backend/_cc.d) 10 */ 11 12 module dmd.backend.cc; 13 14 // Online documentation: https://dlang.org/phobos/dmd_backend_cc.html 15 16 import dmd.backend.barray; 17 import dmd.backend.cdef; // host and target compiler definition 18 import dmd.backend.code_x86; 19 import dmd.backend.dlist; 20 import dmd.backend.dt; 21 import dmd.backend.el; 22 import dmd.backend.symtab; 23 import dmd.backend.type; 24 25 extern (C++): 26 @nogc: 27 nothrow: 28 29 enum GENOBJ = 1; // generating .obj file 30 31 uint mskl(uint i) { return 1 << i; } // convert int to mask 32 33 // Warnings 34 enum WM 35 { 36 WM_no_inline = 1, //function '%s' is too complicated to inline 37 WM_assignment = 2, //possible unintended assignment 38 WM_nestcomment = 3, //comments do not nest 39 WM_assignthis = 4, //assignment to 'this' is obsolete, use X::operator new/delete 40 WM_notagname = 5, //no tag name for struct or enum 41 WM_valuenotused = 6, //value of expression is not used 42 WM_extra_semi = 7, //possible extraneous ';' 43 WM_large_auto = 8, //very large automatic 44 WM_obsolete_del = 9, //use delete[] rather than delete[expr], expr ignored 45 WM_obsolete_inc = 10, //using operator++() (or --) instead of missing operator++(int) 46 WM_init2tmp = 11, //non-const reference initialized to temporary 47 WM_used_b4_set = 12, //variable '%s' used before set 48 WM_bad_op = 13, //Illegal type/size of operands for the %s instruction 49 WM_386_op = 14, //Reference to '%s' caused a 386 instruction to be generated 50 WM_ret_auto = 15, //returning address of automatic '%s' 51 WM_ds_ne_dgroup = 16, //DS is not equal to DGROUP 52 WM_unknown_pragma = 17, //unrecognized pragma 53 WM_implied_ret = 18, //implied return at closing '}' does not return value 54 WM_num_args = 19, //%d actual arguments expected for %s, had %d 55 WM_before_pch = 20, //symbols or macros defined before #include of precompiled header 56 WM_pch_first = 21, //precompiled header must be first #include when -H is used 57 WM_pch_config = 22, 58 WM_divby0 = 23, 59 WM_badnumber = 24, 60 WM_ccast = 25, 61 WM_obsolete = 26, 62 63 // Posix 64 WM_skip_attribute = 27, // skip GNUC attribute specification 65 WM_warning_message = 28, // preprocessor warning message 66 WM_bad_vastart = 29, // args for builtin va_start bad 67 WM_undefined_inline = 30, // static inline not expanded or defined 68 } 69 70 static if (MEMMODELS == 1) 71 { 72 enum LARGEDATA = 0; // don't want 48 bit pointers 73 enum LARGECODE = 0; 74 } 75 else 76 { 77 bool LARGEDATA() { return (config.memmodel & 6) != 0; } 78 bool LARGECODE() { return (config.memmodel & 5) != 0; } 79 } 80 81 version (SPP) 82 { 83 enum COMPILER = "Preprocessor"; 84 enum ACTIVITY = "preprocessing..."; 85 } 86 else version (HTOD) 87 { 88 enum COMPILER = ".h to D Migration Tool"; 89 enum ACTIVITY = "migrating..."; 90 } 91 else version (SCPP) 92 { 93 enum COMPILER = "C/C++ Compiler"; 94 enum ACTIVITY = "compiling..."; 95 } 96 97 //#ifdef DEBUG 98 //# define debug(a) (a) 99 //# define debugx(a) (a) 100 //# define debug_assert assert 101 //#else 102 //# define debug(a) 103 //# define debugx(a) 104 //# define debug_assert(e) 105 //#endif 106 107 /*************************** 108 * Print out debugging information. 109 */ 110 111 //#ifdef DEBUG 112 //#define debugmes(s) (debugw && dbg_printf(s)) 113 //#define cmes(s) (debugc && dbg_printf(s)) 114 //#define cmes2(s,b) (debugc && dbg_printf((s),(b))) 115 //#define cmes3(s,b,c) (debugc && dbg_printf((s),(b),(c))) 116 //#else 117 //#define debugmes(s) 118 //#define cmes(s) 119 //#define cmes2(s,b) 120 //#define cmes3(s,b,c) 121 //#endif 122 123 124 //#define arraysize(array) (sizeof(array) / sizeof(array[0])) 125 126 enum IDMAX = 900; // identifier max (excluding terminating 0) 127 enum IDOHD = 4+1+int.sizeof*3; // max amount of overhead to ID added by 128 enum STRMAX = 65_000; // max length of string (determined by 129 // max ph size) 130 131 //enum SC; 132 struct Thunk 133 { Symbol *sfunc; 134 Symbol *sthunk; 135 targ_size_t d; 136 targ_size_t d2; 137 int i; 138 } 139 140 141 version (MARS) 142 struct token_t; 143 else 144 import dtoken : token_t; 145 146 //struct param_t; 147 //struct block; 148 //struct Classsym; 149 //struct Nspacesym; 150 //struct Outbuffer; 151 //struct Aliassym; 152 //struct dt_t; 153 //typedef struct TYPE type; 154 //typedef struct Symbol symbol; 155 alias Funcsym = Symbol; 156 //#if !MARS 157 //typedef struct MACRO macro_t; 158 version (MARS) 159 struct blklst; 160 else 161 import parser : blklst; 162 //#endif 163 //typedef list_t symlist_t; /* list of pointers to Symbols */ 164 alias symlist_t = list_t; 165 alias vec_t = size_t*; 166 alias enum_TK = ubyte; 167 168 __gshared Config config; 169 170 uint CPP() { return config.flags3 & CFG3cpp; } 171 172 173 /////////// Position in source file 174 175 struct Srcpos 176 { 177 nothrow: 178 uint Slinnum; // 0 means no info available 179 uint Scharnum; 180 version (SCPP) 181 { 182 Sfile **Sfilptr; // file 183 short Sfilnum; // file number 184 } 185 version (SPP) 186 { 187 Sfile **Sfilptr; // file 188 short Sfilnum; // file number 189 } 190 version (HTOD) 191 { 192 Sfile **Sfilptr; // file 193 short Sfilnum; // file number 194 } 195 196 version (MARS) 197 { 198 const(char)* Sfilename; 199 200 const(char*) name() const { return Sfilename; } 201 202 static Srcpos create(const(char)* filename, uint linnum, int charnum) 203 { 204 // Cannot have constructor because Srcpos is used in a union 205 Srcpos sp; 206 sp.Sfilename = filename; 207 sp.Slinnum = linnum; 208 sp.Scharnum = charnum; 209 return sp; 210 } 211 212 /******* 213 * Set fields of Srcpos 214 * Params: 215 * filename = file name 216 * linnum = line number 217 * charnum = character number 218 */ 219 void set(const(char)* filename, uint linnum, int charnum) pure 220 { 221 Sfilename = filename; 222 Slinnum = linnum; 223 Scharnum = charnum; 224 } 225 } 226 227 void print(const(char)* func) const { Srcpos_print(this, func); } 228 } 229 230 version (SCPP) 231 { 232 static Sfile srcpos_sfile(Srcpos p) { return **(p).Sfilptr; } 233 static char* srcpos_name(Srcpos p) { return srcpos_sfile(p).SFname; } 234 } 235 version (SPP) 236 { 237 static Sfile srcpos_sfile(Srcpos p) { return **(p).Sfilptr; } 238 static char* srcpos_name(Srcpos p) { return srcpos_sfile(p).SFname; } 239 } 240 version (HTOD) 241 { 242 static Sfile srcpos_sfile(Srcpos p) { return **(p).Sfilptr; } 243 static char* srcpos_name(Srcpos p) { return srcpos_sfile(p).SFname; } 244 } 245 246 void Srcpos_print(ref const Srcpos srcpos, const(char)* func); 247 248 //#include "token.h" 249 250 alias stflags_t = uint; 251 enum 252 { 253 PFLpreprocessor = 1, // in preprocessor 254 PFLmasm = 2, // in Microsoft-style inline assembler 255 PFLbasm = 4, // in Borland-style inline assembler 256 PFLsemi = 8, // ';' means start of comment 257 // PFLautogen = 0x10, // automatically generate HX ph file 258 PFLmftemp = 0x20, // if expanding member function template 259 PFLextdef = 0x40, // we had an external def 260 PFLhxwrote = 0x80, // already generated HX ph file 261 PFLhxdone = 0x100, // done with HX ph file 262 263 // if TX86 264 PFLhxread = 0x200, // have read in an HX ph file 265 PFLhxgen = 0x400, // need to generate HX ph file 266 PFLphread = 0x800, // read a ph file 267 PFLcomdef = 0x1000, // had a common block 268 PFLmacdef = 0x2000, // defined a macro in the source code 269 PFLsymdef = 0x4000, // declared a global Symbol in the source 270 PFLinclude = 0x8000, // read a .h file 271 PFLmfc = 0x10000, // something will affect MFC compatibility 272 } 273 274 alias sthflags_t = char; 275 enum 276 { 277 FLAG_INPLACE = 0, // in place hydration 278 FLAG_HX = 1, // HX file hydration 279 FLAG_SYM = 2, // .SYM file hydration 280 } 281 282 /********************************** 283 * Current 'state' of the compiler. 284 * Used to gather together most global variables. 285 * This struct is saved/restored during function body parsing. 286 */ 287 288 struct Pstate 289 { 290 ubyte STinopeq; // if in n2_createopeq() 291 ubyte STinarglist; // if !=0, then '>' is the end of a template 292 // argument list, not an operator 293 ubyte STinsizeof; // !=0 if in a sizeof expression. Useful to 294 // prevent <array of> being converted to 295 // <pointer to>. 296 ubyte STintemplate; // if !=0, then expanding a function template 297 // (do not expand template Symbols) 298 ubyte STdeferDefaultArg; // defer parsing of default arg for parameter 299 ubyte STnoexpand; // if !=0, don't expand template symbols 300 ubyte STignoretal; // if !=0 ignore template argument list 301 ubyte STexplicitInstantiation; // if !=0, then template explicit instantiation 302 ubyte STexplicitSpecialization; // if !=0, then template explicit specialization 303 ubyte STinconstexp; // if !=0, then parsing a constant expression 304 ubyte STisaddr; // is this a possible pointer to member expression? 305 uint STinexp; // if !=0, then in an expression 306 307 static if (NTEXCEPTIONS) 308 { 309 ubyte STinfilter; // if !=0 then in exception filter 310 ubyte STinexcept; // if !=0 then in exception handler 311 block *STbfilter; // current exception filter 312 } 313 314 version (MARS) 315 { 316 } 317 else 318 { 319 int STinitseg; // segment for static constructor function pointer 320 } 321 Funcsym *STfuncsym_p; // if inside a function, then this is the 322 // function Symbol. 323 324 stflags_t STflags; 325 326 version (MARS) 327 { 328 } 329 else 330 { 331 int STinparamlist; // if != 0, then parser is in 332 // function parameter list 333 int STingargs; // in template argument list 334 list_t STincalias; // list of include aliases 335 list_t STsysincalias; // list of system include aliases 336 } 337 338 // should probably be inside #if HYDRATE, but unclear for the dmc source 339 sthflags_t SThflag; // FLAG_XXXX: hydration flag 340 341 Classsym *STclasssym; // if in the scope of this class 342 symlist_t STclasslist; // list of classes that have deferred inline 343 // functions to parse 344 Classsym *STstag; // returned by struct_searchmember() and with_search() 345 SYMIDX STmarksi; // to determine if temporaries are created 346 ubyte STnoparse; // add to classlist instead of parsing 347 ubyte STdeferparse; // defer member func parse 348 SC STgclass; // default function storage class 349 int STdefertemps; // defer allocation of temps 350 int STdeferaccesscheck; // defer access check for members (BUG: it 351 // never does get done later) 352 int STnewtypeid; // parsing new-type-id 353 int STdefaultargumentexpression; // parsing default argument expression 354 block *STbtry; // current try block 355 block *STgotolist; // threaded goto scoping list 356 int STtdbtimestamp; // timestamp of tdb file 357 Symbol *STlastfunc; // last function symbol parsed by ext_def() 358 359 // For "point of definition" vs "point of instantiation" template name lookup 360 uint STsequence; // sequence number (Ssequence) of next Symbol 361 uint STmaxsequence; // won't find Symbols with STsequence larger 362 // than STmaxsequence 363 } 364 365 void funcsym_p(Funcsym* fp) { pstate.STfuncsym_p = fp; } 366 Funcsym* funcsym_p() { return pstate.STfuncsym_p; } 367 368 stflags_t preprocessor() { return pstate.STflags & PFLpreprocessor; } 369 stflags_t inline_asm() { return pstate.STflags & (PFLmasm | PFLbasm); } 370 371 extern __gshared Pstate pstate; 372 373 /**************************** 374 * Global variables. 375 */ 376 377 struct Cstate 378 { 379 blklst* CSfilblk; // current source file we are parsing 380 Symbol* CSlinkage; // table of forward referenced linkage pragmas 381 list_t CSlist_freelist; // free list for list package 382 symtab_t* CSpsymtab; // pointer to current Symbol table 383 //#if MEMORYHX 384 // void **CSphx; // pointer to HX data block 385 //#endif 386 char* modname; // module unique identifier 387 } 388 389 extern __gshared Cstate cstate; 390 391 /* Bits for sytab[] that give characteristics of storage classes */ 392 enum 393 { 394 SCEXP = 1, // valid inside expressions 395 SCKEP = 2, // Symbol should be kept even when function is done 396 SCSCT = 4, // storage class is valid for use in static ctor 397 SCSS = 8, // storage class is on the stack 398 SCRD = 0x10, // we can do reaching definitions on these 399 } 400 401 // Determine if Symbol has a Ssymnum associated with it. 402 // (That is, it is allocated on the stack or has live variable analysis 403 // done on it, so it is stack and register variables.) 404 //char symbol_isintab(Symbol *s) { return sytab[s.Sclass] & SCSS; } 405 406 //version (Windows) 407 alias enum_SC = char; 408 //else 409 // alias SC enum_SC; 410 411 412 /****************************************** 413 * Basic blocks: 414 * Basic blocks are a linked list of all the basic blocks 415 * in a function. startblock heads the list. 416 */ 417 418 alias ClassDeclaration_ = void*; 419 alias Declaration_ = void*; 420 alias Module_ = void*; 421 422 struct Blockx 423 { 424 version (MARS) 425 { 426 block* startblock; 427 block* curblock; 428 Funcsym* funcsym; 429 Symbol* context; // eh frame context variable 430 int scope_index; // current scope index 431 int next_index; // value for next scope index 432 uint flags; // value to OR into Bflags 433 block* tryblock; // current enclosing try block 434 elem* init; // static initializer 435 ClassDeclaration_ classdec; 436 Declaration_ member; // member we're compiling for 437 Module_ _module; // module we're in 438 } 439 } 440 441 alias bflags_t = ushort; 442 enum 443 { 444 BFLvisited = 1, // set if block is visited 445 BFLmark = 2, // set if block is visited 446 BFLjmpoptdone = 4, // set when no more jump optimizations 447 // are possible for this block 448 BFLnostackopt = 8, // set when stack elimination should not 449 // be done 450 // NTEXCEPTIONS 451 BFLehcode = 0x10, // BC_filter: need to load exception code 452 BFLunwind = 0x1000, // do local_unwind following block (unused) 453 454 BFLnomerg = 0x20, // do not merge with other blocks 455 BFLprolog = 0x80, // generate function prolog 456 BFLepilog = 0x100, // generate function epilog 457 BFLrefparam = 0x200, // referenced parameter 458 BFLreflocal = 0x400, // referenced local 459 BFLoutsideprolog = 0x800, // outside function prolog/epilog 460 BFLlabel = 0x2000, // block preceded by label 461 BFLvolatile = 0x4000, // block is volatile 462 BFLnounroll = 0x8000, // do not unroll loop 463 } 464 465 struct block 466 { 467 nothrow: 468 union 469 { 470 elem *Belem; // pointer to elem tree 471 list_t Blist; // list of expressions 472 } 473 474 block *Bnext; // pointer to next block in list 475 list_t Bsucc; // linked list of pointers to successors 476 // of this block 477 list_t Bpred; // and the predecessor list 478 int Bindex; // into created object stack 479 int Bendindex; // index at end of block 480 block *Btry; // BCtry,BC_try: enclosing try block, if any 481 // BC???: if in try-block, points to BCtry or BC_try 482 // note that can't have a BCtry and BC_try in 483 // the same function. 484 union 485 { 486 targ_llong* Bswitch; // BCswitch: pointer to switch data 487 struct 488 { 489 regm_t usIasmregs; // Registers modified 490 ubyte bIasmrefparam; // References parameters? 491 } 492 493 struct 494 { 495 Symbol* catchvar; // __throw() fills in this 496 } // BCtry 497 498 version (SCPP) 499 { 500 struct 501 { 502 type *Bcatchtype; // one type for each catch block 503 } // BCcatch 504 } 505 506 version (HTOD) 507 { 508 struct 509 { 510 type *Bcatchtype; // one type for each catch block 511 } // BCcatch 512 } 513 514 version (MARS) 515 { 516 struct 517 { 518 Symbol* Bcatchtype; // one type for each catch block 519 uint* actionTable; // EH_DWARF: indices into typeTable, first is # of entries 520 } // BCjcatch 521 } 522 523 struct 524 { 525 version (MARS) 526 { 527 Symbol *jcatchvar; // __d_throw() fills in this 528 } 529 int Bscope_index; // index into scope table 530 int Blast_index; // enclosing index into scope table 531 } // BC_try 532 533 struct 534 { 535 Symbol *flag; // EH_DWARF: set to 'flag' symbol that encloses finally 536 block *b_ret; // EH_DWARF: associated BC_ret block 537 } // finally 538 539 // add member mimicking the largest of the other elements of this union, so it can be copied 540 struct _BS { version (MARS) { Symbol *jcvar; } int Bscope_idx, Blast_idx; } 541 _BS BS; 542 } 543 Srcpos Bsrcpos; // line number (0 if not known) 544 ubyte BC; // exit condition (enum BC) 545 546 ubyte Balign; // alignment 547 548 bflags_t Bflags; // flags (BFLxxxx) 549 code* Bcode; // code generated for this block 550 551 uint Bweight; // relative number of times this block 552 // is executed (optimizer and codegen) 553 554 uint Bdfoidx; // index of this block in dfo[] 555 uint Bnumber; // sequence number of block 556 union 557 { 558 uint _BLU; // start of the union 559 560 // CPP 561 struct 562 { 563 SYMIDX Bsymstart; // (symstart <= symnum < symend) Symbols 564 SYMIDX Bsymend; // are declared in this block 565 block* Bendscope; // block that forms the end of the 566 // scope for the declared Symbols 567 uint Bblknum; // position of block from startblock 568 Symbol* Binitvar; // !=NULL points to an auto variable with 569 // an explicit or implicit initializer 570 block* Bgotolist; // BCtry, BCcatch: backward list of try scopes 571 block* Bgotothread; // BCgoto: threaded list of goto's to 572 // unknown labels 573 } 574 575 // OPTIMIZER 576 struct 577 { 578 vec_t Bdom; // mask of dominators for this block 579 vec_t Binrd; 580 vec_t Boutrd; // IN and OUT for reaching definitions 581 vec_t Binlv; 582 vec_t Boutlv; // IN and OUT for live variables 583 vec_t Bin; 584 vec_t Bout; // IN and OUT for other flow analyses 585 vec_t Bgen; 586 vec_t Bkill; // pointers to bit vectors used by data 587 // flow analysis 588 589 // BCiftrue can have different vectors for the 2nd successor: 590 vec_t Bout2; 591 vec_t Bgen2; 592 vec_t Bkill2; 593 } 594 595 // CODGEN 596 struct 597 { 598 // For BCswitch, BCjmptab 599 targ_size_t Btablesize; // size of generated table 600 targ_size_t Btableoffset; // offset to start of table 601 targ_size_t Btablebase; // offset to instruction pointer base 602 603 targ_size_t Boffset; // code offset of start of this block 604 targ_size_t Bsize; // code size of this block 605 con_t Bregcon; // register state at block exit 606 targ_size_t Btryoff; // BCtry: offset of try block data 607 } 608 } 609 610 void appendSucc(block* b) { list_append(&this.Bsucc, b); } 611 void prependSucc(block* b) { list_prepend(&this.Bsucc, b); } 612 int numSucc() { return list_nitems(this.Bsucc); } 613 block* nthSucc(int n) { return cast(block*)list_ptr(list_nth(Bsucc, n)); } 614 void setNthSucc(int n, block *b) { list_nth(Bsucc, n).ptr = b; } 615 } 616 617 inout(block)* list_block(inout list_t lst) { return cast(inout(block)*)list_ptr(lst); } 618 619 /** Basic block control flow operators. **/ 620 621 alias BC = int; 622 enum 623 { 624 BCgoto = 1, // goto Bsucc block 625 BCiftrue = 2, // if (Belem) goto Bsucc[0] else Bsucc[1] 626 BCret = 3, // return (no return value) 627 BCretexp = 4, // return with return value 628 BCexit = 5, // never reaches end of block (like exit() was called) 629 BCasm = 6, // inline assembler block (Belem is NULL, Bcode 630 // contains code generated). 631 // These blocks have one or more successors in Bsucc, 632 // never 0 633 BCswitch = 7, // switch statement 634 // Bswitch points to switch data 635 // Default is Bsucc 636 // Cases follow in linked list 637 BCifthen = 8, // a BCswitch is converted to if-then 638 // statements 639 BCjmptab = 9, // a BCswitch is converted to a jump 640 // table (switch value is index into 641 // the table) 642 BCtry = 10, // C++ try block 643 // first block in a try-block. The first block in 644 // Bsucc is the next one to go to, subsequent 645 // blocks are the catch blocks 646 BCcatch = 11, // C++ catch block 647 BCjump = 12, // Belem specifies (near) address to jump to 648 BC_try = 13, // SEH: first block of try-except or try-finally 649 // D: try-catch or try-finally 650 BC_filter = 14, // SEH exception-filter (always exactly one block) 651 BC_finally = 15, // first block of SEH termination-handler, 652 // or D finally block 653 BC_ret = 16, // last block of SEH termination-handler or D _finally block 654 BC_except = 17, // first block of SEH exception-handler 655 BCjcatch = 18, // D catch block 656 BC_lpad = 19, // EH_DWARF: landing pad for BC_except 657 BCMAX 658 } 659 660 /******************************** 661 * Range for blocks. 662 */ 663 struct BlockRange 664 { 665 pure nothrow @nogc @safe: 666 667 this(block* b) 668 { 669 this.b = b; 670 } 671 672 block* front() return { return b; } 673 void popFront() { b = b.Bnext; } 674 bool empty() const { return !b; } 675 676 private: 677 block* b; 678 } 679 680 /********************************** 681 * Functions 682 */ 683 684 alias func_flags_t = uint; 685 enum 686 { 687 Fpending = 1, // if function has been queued for being written 688 Foutput = 2, // if function has been written out 689 Foperator = 4, // if operator overload 690 Fcast = 8, // if cast overload 691 Finline = 0x10, // if SCinline, and function really is inline 692 Foverload = 0x20, // if function can be overloaded 693 Ftypesafe = 0x40, // if function name needs type appended 694 Fmustoutput = 0x80, // set for forward ref'd functions that 695 // must be output 696 Fvirtual = 0x100, // if function is a virtual function 697 Fctor = 0x200, // if function is a constructor 698 Fdtor = 0x400, // if function is a destructor 699 Fnotparent = 0x800, // if function is down Foversym chain 700 Finlinenest = 0x1000, // used as a marker to prevent nested 701 // inlines from expanding 702 Flinkage = 0x2000, // linkage is already specified 703 Fstatic = 0x4000, // static member function (no this) 704 Fbitcopy = 0x8000, // it's a simple bitcopy (op=() or X(X&)) 705 Fpure = 0x10000, // pure function 706 Finstance = 0x20000, // function is an instance of a template 707 Ffixed = 0x40000, // ctor has had cpp_fixconstructor() run on it, 708 // dtor has had cpp_fixdestructor() 709 Fintro = 0x80000, // function doesn't hide a previous virtual function 710 // unused = 0x100000, // unused bit 711 Fkeeplink = 0x200000, // don't change linkage to default 712 Fnodebug = 0x400000, // do not generate debug info for this function 713 Fgen = 0x800000, // compiler generated function 714 Finvariant = 0x1000000, // __invariant function 715 Fexplicit = 0x2000000, // explicit constructor 716 Fsurrogate = 0x4000000, // surrogate call function 717 } 718 719 alias func_flags3_t = uint; 720 enum 721 { 722 Fvtblgen = 1, // generate vtbl[] when this function is defined 723 Femptyexc = 2, // empty exception specification (obsolete, use Tflags & TFemptyexc) 724 Fcppeh = 4, // uses C++ EH 725 Fnteh = 8, // uses NT Structured EH 726 Fdeclared = 0x10, // already declared function Symbol 727 Fmark = 0x20, // has unbalanced OPctor's 728 Fdoinline = 0x40, // do inline walk 729 Foverridden = 0x80, // ignore for overriding purposes 730 Fjmonitor = 0x100, // Mars synchronized function 731 Fnosideeff = 0x200, // function has no side effects 732 F3badoparrow = 0x400, // bad operator->() 733 Fmain = 0x800, // function is main() or wmain() 734 Fnested = 0x1000, // D nested function with 'this' 735 Fmember = 0x2000, // D member function with 'this' 736 Fnotailrecursion = 0x4000, // no tail recursion optimizations 737 Ffakeeh = 0x8000, // allocate space for NT EH context sym anyway 738 Fnothrow = 0x10000, // function does not throw (even if not marked 'nothrow') 739 Feh_none = 0x20000, // ehmethod==EH_NONE for this function only 740 F3hiddenPtr = 0x40000, // function has hidden pointer to return value 741 } 742 743 struct func_t 744 { 745 symlist_t Fsymtree; // local Symbol table 746 block *Fstartblock; // list of blocks comprising function 747 symtab_t Flocsym; // local Symbol table 748 Srcpos Fstartline; // starting line # of function 749 Srcpos Fendline; // line # of closing brace of function 750 Symbol *F__func__; // symbol for __func__[] string 751 func_flags_t Fflags; 752 func_flags3_t Fflags3; 753 ubyte Foper; // operator number (OPxxxx) if Foperator 754 755 Symbol *Fparsescope; // use this scope to parse friend functions 756 // which are defined within a class, so the 757 // class is in scope, but are not members 758 // of the class 759 760 Classsym *Fclass; // if member of a class, this is the class 761 // (I think this is redundant with Sscope) 762 Funcsym *Foversym; // overloaded function at same scope 763 symlist_t Fclassfriends; // Symbol list of classes of which this 764 // function is a friend 765 block *Fbaseblock; // block where base initializers get attached 766 block *Fbaseendblock; // block where member destructors get attached 767 elem *Fbaseinit; // list of member initializers (meminit_t) 768 // this field has meaning only for 769 // functions which are constructors 770 token_t *Fbody; // if deferred parse, this is the list 771 // of tokens that make up the function 772 // body 773 // also used if SCfunctempl, SCftexpspec 774 uint Fsequence; // sequence number at point of definition 775 union 776 { 777 Symbol* Ftempl; // if Finstance this is the template that generated it 778 Thunk* Fthunk; // !=NULL if this function is actually a thunk 779 } 780 Funcsym *Falias; // SCfuncalias: function Symbol referenced 781 // by using-declaration 782 symlist_t Fthunks; // list of thunks off of this function 783 param_t *Farglist; // SCfunctempl: the template-parameter-list 784 param_t *Fptal; // Finstance: this is the template-argument-list 785 // SCftexpspec: for explicit specialization, this 786 // is the template-argument-list 787 list_t Ffwdrefinstances; // SCfunctempl: list of forward referenced instances 788 list_t Fexcspec; // List of types in the exception-specification 789 // (NULL if none or empty) 790 Funcsym *Fexplicitspec; // SCfunctempl, SCftexpspec: threaded list 791 // of SCftexpspec explicit specializations 792 Funcsym *Fsurrogatesym; // Fsurrogate: surrogate cast function 793 794 char *Fredirect; // redirect function name to this name in object 795 796 version (SPP) { } else 797 { 798 version (MARS) 799 // Array of catch types for EH_DWARF Types Table generation 800 Barray!(Symbol*) typesTable; 801 } 802 803 union 804 { 805 uint LSDAoffset; // ELFOBJ: offset in LSDA segment of the LSDA data for this function 806 Symbol* LSDAsym; // MACHOBJ: GCC_except_table%d 807 } 808 } 809 810 //func_t* func_calloc() { return cast(func_t *) mem_fcalloc(func_t.sizeof); } 811 //void func_free(func_t *f) { mem_ffree(f); } 812 813 /************************** 814 * Item in list for member initializer. 815 */ 816 817 struct meminit_t 818 { 819 list_t MIelemlist; // arg list for initializer 820 Symbol *MIsym; // if NULL, then this initializer is 821 // for the base class. Otherwise, this 822 // is the member that needs the ctor 823 // called for it 824 } 825 826 alias baseclass_flags_t = uint; 827 enum 828 { 829 BCFpublic = 1, // base class is public 830 BCFprotected = 2, // base class is protected 831 BCFprivate = 4, // base class is private 832 833 BCFvirtual = 8, // base class is virtual 834 BCFvfirst = 0x10, // virtual base class, and this is the 835 // first virtual appearance of it 836 BCFnewvtbl = 0x20, // new vtbl generated for this base class 837 BCFvirtprim = 0x40, // Primary base class of a virtual base class 838 BCFdependent = 0x80, // base class is a dependent type 839 } 840 enum baseclass_flags_t BCFpmask = BCFpublic | BCFprotected | BCFprivate; 841 842 843 /************************************ 844 * Base classes are a list of these. 845 */ 846 847 struct baseclass_t 848 { 849 Classsym* BCbase; // base class Symbol 850 baseclass_t* BCnext; // next base class 851 targ_size_t BCoffset; // offset from start of derived class to this 852 ushort BCvbtbloff; // for BCFvirtual, offset from start of 853 // vbtbl[] to entry for this virtual base. 854 // Valid in Sbase list 855 symlist_t BCpublics; // public members of base class (list is freeable) 856 list_t BCmptrlist; // (in Smptrbase only) this is the vtbl 857 // (NULL if not different from base class's vtbl 858 Symbol* BCvtbl; // Symbol for vtbl[] array (in Smptrbase list) 859 // Symbol for vbtbl[] array (in Svbptrbase list) 860 baseclass_flags_t BCflags; // base class flags 861 Classsym* BCparent; // immediate parent of this base class 862 // in Smptrbase 863 baseclass_t* BCpbase; // parent base, NULL if did not come from a parent 864 } 865 866 //baseclass_t* baseclass_malloc() { return cast(baseclass_t*) mem_fmalloc(baseclass_t.sizeof); } 867 void baseclass_free(baseclass_t *b) { } 868 869 /************************* 870 * For virtual tables. 871 */ 872 873 alias mptr_flags_t = char; 874 enum 875 { 876 MPTRvirtual = 1, // it's an offset to a virtual base 877 MPTRcovariant = 2, // need covariant return pointer adjustment 878 } 879 880 struct mptr_t 881 { 882 targ_short MPd; 883 targ_short MPi; 884 Symbol *MPf; 885 Symbol *MPparent; // immediate parent of this base class 886 // in Smptrbase 887 mptr_flags_t MPflags; 888 } 889 890 inout(mptr_t)* list_mptr(inout(list_t) lst) { return cast(inout(mptr_t)*) list_ptr(lst); } 891 892 893 /*********************************** 894 * Information gathered about externally defined template member functions, 895 * member data, and member classes. 896 */ 897 898 struct TMF 899 { 900 Classsym *stag; // if !=NULL, this is the enclosing class 901 token_t *tbody; // tokens making it up 902 token_t *to; // pointer within tbody where we left off in 903 // template_function_decl() 904 param_t *temp_arglist; // template parameter list 905 int member_class; // 1: it's a member class 906 907 // These are for member templates 908 int castoverload; // 1: it's a user defined cast 909 char *name; // name of template (NULL if castoverload) 910 int member_template; // 0: regular template 911 // 1: member template 912 param_t *temp_arglist2; // if member template, 913 // then member's template parameter list 914 915 param_t *ptal; // if explicit specialization, this is the 916 // explicit template-argument-list 917 Symbol *sclassfriend; // if member function is a friend of class X, 918 // this is class X 919 uint access_specifier; 920 } 921 922 /*********************************** 923 * Information gathered about primary member template explicit specialization. 924 */ 925 926 struct TME 927 { 928 /* Given: 929 * template<> template<class T2> struct A<short>::B { }; 930 * temp_arglist2 = <class T2> 931 * name = "B" 932 * ptal = <short> 933 */ 934 param_t *ptal; // explicit template-argument-list for enclosing 935 // template A 936 Symbol *stempl; // template symbol for B 937 } 938 939 /*********************************** 940 * Information gathered about nested explicit specializations. 941 */ 942 943 struct TMNE 944 { 945 /* For: 946 * template<> template<> struct A<short>::B<double> { }; 947 */ 948 949 enum_TK tk; // TKstruct / TKclass / TKunion 950 char *name; // name of template, i.e. "B" 951 param_t *ptal; // explicit template-argument-list for enclosing 952 // template A, i.e. "short" 953 token_t *tdecl; // the tokens "<double> { }" 954 } 955 956 /*********************************** 957 * Information gathered about nested class friends. 958 */ 959 960 struct TMNF 961 { 962 /* Given: 963 * template<class T> struct A { struct B { }; }; 964 * class C { template<class T> friend struct A<T>::B; 965 */ 966 token_t *tdecl; // the tokens "A<T>::B;" 967 param_t *temp_arglist; // <class T> 968 Classsym *stag; // the class symbol C 969 Symbol *stempl; // the template symbol A 970 } 971 972 /*********************************** 973 * Special information for class templates. 974 */ 975 976 struct template_t 977 { 978 symlist_t TMinstances; // list of Symbols that are instances 979 param_t* TMptpl; // template-parameter-list 980 token_t* TMbody; // tokens making up class body 981 uint TMsequence; // sequence number at point of definition 982 list_t TMmemberfuncs; // templates for member functions (list of TMF's) 983 list_t TMexplicit; // list of TME's: primary member template explicit specializations 984 list_t TMnestedexplicit; // list of TMNE's: primary member template nested explicit specializations 985 Symbol* TMnext; // threaded list of template classes headed 986 // up by template_class_list 987 enum_TK TMtk; // TKstruct, TKclass or TKunion 988 int TMflags; // STRxxx flags 989 990 Symbol* TMprimary; // primary class template 991 Symbol* TMpartial; // next class template partial specialization 992 param_t* TMptal; // template-argument-list for partial specialization 993 // (NULL for primary class template) 994 list_t TMfriends; // list of Classsym's for which any instantiated 995 // classes of this template will be friends of 996 list_t TMnestedfriends; // list of TMNF's 997 int TMflags2; // !=0 means dummy template created by template_createargtab() 998 } 999 1000 /*********************************** 1001 * Special information for enums. 1002 */ 1003 1004 alias enum_flags_t = uint; 1005 enum 1006 { 1007 SENnotagname = 1, // no tag name for enum 1008 SENforward = 2, // forward referenced enum 1009 } 1010 1011 struct enum_t 1012 { 1013 enum_flags_t SEflags; 1014 Symbol* SEalias; // pointer to identifier E to use if 1015 // enum was defined as: 1016 // typedef enum { ... } E; 1017 symlist_t SEenumlist; // all members of enum 1018 } 1019 1020 /*********************************** 1021 * Special information for structs. 1022 */ 1023 1024 alias struct_flags_t = uint; 1025 enum 1026 { 1027 STRanonymous = 1, // set for unions with no tag names 1028 STRglobal = 2, // defined at file scope 1029 STRnotagname = 4, // struct/class with no tag name 1030 STRoutdef = 8, // we've output the debug definition 1031 STRbitfields = 0x10, // set if struct contains bit fields 1032 STRabstract = 0x20, // abstract class 1033 STRbitcopy = 0x40, // set if operator=() is merely a bit copy 1034 STRanyctor = 0x80, // set if any constructors were defined 1035 // by the user 1036 STRnoctor = 0x100, // no constructors allowed 1037 STRgen = 0x200, // if struct is an instantiation of a 1038 // template class, and was generated by 1039 // that template 1040 STRvtblext = 0x400, // generate vtbl[] only when first member function 1041 // definition is encountered (see Fvtblgen) 1042 STRexport = 0x800, // all member functions are to be _export 1043 STRpredef = 0x1000, // a predefined struct 1044 STRunion = 0x2000, // actually, it's a union 1045 STRclass = 0x4000, // it's a class, not a struct 1046 STRimport = 0x8000, // imported class 1047 STRstaticmems = 0x10000, // class has static members 1048 STR0size = 0x20000, // zero sized struct 1049 STRinstantiating = 0x40000, // if currently being instantiated 1050 STRexplicit = 0x80000, // if explicit template instantiation 1051 STRgenctor0 = 0x100000, // need to gen X::X() 1052 STRnotpod = 0x200000, // struct is not POD 1053 } 1054 1055 struct struct_t 1056 { 1057 targ_size_t Sstructsize; // size of struct 1058 symlist_t Sfldlst; // all members of struct (list freeable) 1059 Symbol *Sroot; // root of binary tree Symbol table 1060 uint Salignsize; // size of struct for alignment purposes 1061 ubyte Sstructalign; // struct member alignment in effect 1062 struct_flags_t Sflags; 1063 tym_t ptrtype; // type of pointer to refer to classes by 1064 ushort access; // current access privilege, here so 1065 // enum declarations can get at it 1066 targ_size_t Snonvirtsize; // size of struct excluding virtual classes 1067 list_t Svirtual; // freeable list of mptrs 1068 // that go into vtbl[] 1069 list_t *Spvirtder; // pointer into Svirtual that points to start 1070 // of virtual functions for this (derived) class 1071 symlist_t Sopoverload; // overloaded operator funcs (list freeable) 1072 symlist_t Scastoverload; // overloaded cast funcs (list freeable) 1073 symlist_t Sclassfriends; // list of classes of which this is a friend 1074 // (list is freeable) 1075 symlist_t Sfriendclass; // classes which are a friend to this class 1076 // (list is freeable) 1077 symlist_t Sfriendfuncs; // functions which are a friend to this class 1078 // (list is freeable) 1079 symlist_t Sinlinefuncs; // list of tokenized functions 1080 baseclass_t *Sbase; // list of direct base classes 1081 baseclass_t *Svirtbase; // list of all virtual base classes 1082 baseclass_t *Smptrbase; // list of all base classes that have 1083 // their own vtbl[] 1084 baseclass_t *Sprimary; // if not NULL, then points to primary 1085 // base class 1086 Funcsym *Svecctor; // constructor for use by vec_new() 1087 Funcsym *Sctor; // constructor function 1088 1089 Funcsym *Sdtor; // basic destructor 1090 Funcsym *Sprimdtor; // primary destructor 1091 Funcsym *Spriminv; // primary invariant 1092 Funcsym *Sscaldeldtor; // scalar deleting destructor 1093 1094 Funcsym *Sinvariant; // basic invariant function 1095 1096 Symbol *Svptr; // Symbol of vptr 1097 Symbol *Svtbl; // Symbol of vtbl[] 1098 Symbol *Svbptr; // Symbol of pointer to vbtbl[] 1099 Symbol *Svbptr_parent; // base class for which Svbptr is a member. 1100 // NULL if Svbptr is a member of this class 1101 targ_size_t Svbptr_off; // offset of Svbptr member 1102 Symbol *Svbtbl; // virtual base offset table 1103 baseclass_t *Svbptrbase; // list of all base classes in canonical 1104 // order that have their own vbtbl[] 1105 Funcsym *Sopeq; // X& X::operator =(X&) 1106 Funcsym *Sopeq2; // Sopeq, but no copy of virtual bases 1107 Funcsym *Scpct; // copy constructor 1108 Funcsym *Sveccpct; // vector copy constructor 1109 Symbol *Salias; // pointer to identifier S to use if 1110 // struct was defined as: 1111 // typedef struct { ... } S; 1112 1113 Symbol *Stempsym; // if this struct is an instantiation 1114 // of a template class, this is the 1115 // template class Symbol 1116 1117 // For 64 bit Elf function ABI 1118 type *Sarg1type; 1119 type *Sarg2type; 1120 1121 /* For: 1122 * template<class T> struct A { }; 1123 * template<class T> struct A<T *> { }; 1124 * 1125 * A<int> a; // primary 1126 * Gives: 1127 * Sarglist = <int> 1128 * Spr_arglist = NULL; 1129 * 1130 * A<int*> a; // specialization 1131 * Gives: 1132 * Sarglist = <int> 1133 * Spr_arglist = <int*>; 1134 */ 1135 1136 param_t *Sarglist; // if this struct is an instantiation 1137 // of a template class, this is the 1138 // actual arg list used 1139 param_t *Spr_arglist; // if this struct is an instantiation 1140 // of a specialized template class, this is the 1141 // actual primary arg list used. 1142 // It is NULL for the 1143 // primary template class (since it would be 1144 // identical to Sarglist). 1145 } 1146 1147 /********************************** 1148 * Symbol Table 1149 */ 1150 1151 inout(Symbol)* list_symbol(inout list_t lst) { return cast(inout(Symbol)*) list_ptr(lst); } 1152 void list_setsymbol(list_t lst, Symbol* s) { lst.ptr = s; } 1153 inout(Classsym)* list_Classsym(inout list_t lst) { return cast(inout(Classsym)*) list_ptr(lst); } 1154 1155 enum 1156 { 1157 SFLvalue = 1, // Svalue contains const expression 1158 SFLimplem = 2, // if seen implementation of Symbol 1159 // (function body for functions, 1160 // initializer for variables) 1161 SFLdouble = 2, // SCregpar or SCparameter, where float 1162 // is really passed as a double 1163 SFLfree = 4, // if we can symbol_free() a Symbol in 1164 // a Symbol table[] 1165 SFLmark = 8, // temporary marker 1166 SFLexit = 0x10, // tyfunc: function does not return 1167 // (ex: exit,abort,_assert,longjmp) 1168 SFLtrue = 0x200, // value of Symbol != 0 1169 SFLreplace = SFLmark, // variable gets replaced in inline expansion 1170 SFLskipinit = 0x10000, // SCfield, SCmember: initializer is skipped 1171 SFLnodebug = 0x20000, // don't generate debug info 1172 SFLwasstatic = 0x800000, // was an uninitialized static 1173 SFLweak = 0x1000000, // resolve to NULL if not found 1174 SFLhidden = 0x2000000, // not visible outside of DSOs (-fvisibility=hidden) 1175 SFLartifical = 0x4000000, // compiler generated symbol 1176 1177 // CPP 1178 SFLnodtor = 0x10, // set if destructor for Symbol is already called 1179 SFLdtorexp = 0x80, // Svalue has expression to tack onto dtor 1180 SFLmutable = 0x100000, // SCmember or SCfield is mutable 1181 SFLdyninit = 0x200000, // symbol has dynamic initializer 1182 SFLtmp = 0x400000, // symbol is a generated temporary 1183 SFLthunk = 0x40000, // symbol is temporary for thunk 1184 1185 // Possible values for visibility bits 1186 SFLprivate = 0x60, 1187 SFLprotected = 0x40, 1188 SFLpublic = 0x20, 1189 SFLnone = 0x00, 1190 SFLpmask = 0x60, // mask for the visibility bits 1191 1192 SFLvtbl = 0x2000, // VEC_VTBL_LIST: Symbol is a vtable or vbtable 1193 1194 // OPTIMIZER and CODGEN 1195 GTregcand = 0x100, // if Symbol is a register candidate 1196 SFLdead = 0x800, // this variable is dead 1197 GTunregister = 0x8000000, // 'unregister' a previous register assignment 1198 1199 // OPTIMIZER only 1200 SFLunambig = 0x400, // only accessible by unambiguous reference, 1201 // i.e. cannot be addressed via pointer 1202 // (GTregcand is a subset of this) 1203 // P.S. code generator turns off this 1204 // flag if any reads are done from it. 1205 // This is to eliminate stores to it 1206 // that are never read. 1207 SFLlivexit = 0x1000, // live on exit from function 1208 SFLnotbasiciv = 0x4000, // not a basic induction variable 1209 SFLnord = SFLdouble, // SCauto,SCregister,SCtmp: disallow redundant warnings 1210 1211 // CODGEN only 1212 GTtried = SFLmark, // tried to place in register 1213 GTbyte = 0x8000, // variable is sometimes accessed as 1214 SFLread = 0x40000, // variable is actually read from 1215 // (to eliminate dead stores) 1216 SFLspill = 0x80000, // only in register part of the time 1217 } 1218 1219 struct Symbol 1220 { 1221 //#ifdef DEBUG 1222 debug ushort id; 1223 enum IDsymbol = 0x5678; 1224 //#define class_debug(s) assert((s)->id == IDsymbol) 1225 //#else 1226 //#define class_debug(s) 1227 //#endif 1228 1229 nothrow: 1230 1231 Symbol* Sl, Sr; // left, right child 1232 Symbol* Snext; // next in threaded list 1233 dt_t* Sdt; // variables: initializer 1234 int Salignment; // variables: alignment, 0 or -1 means default alignment 1235 1236 int Salignsize() // variables: return alignment 1237 { return Symbol_Salignsize(&this); } 1238 1239 type* Stype; // type of Symbol 1240 tym_t ty() const { return Stype.Tty; } 1241 1242 union // variants for different Symbol types 1243 { 1244 enum_t* Senum; // SCenum 1245 1246 struct 1247 { 1248 func_t* Sfunc; // tyfunc 1249 list_t Spath1; // SCfuncalias member functions: same as Spath 1250 // and in same position 1251 // SCadl: list of associated functions for ADL lookup 1252 } 1253 1254 struct // SClabel 1255 { 1256 int Slabel; // TRUE if label was defined 1257 block* Slabelblk_; // label block 1258 } 1259 1260 //#define Senumlist Senum->SEenumlist 1261 1262 version (SCPP) 1263 { 1264 struct // SClinkage 1265 { 1266 uint Slinkage; // tym linkage bits 1267 uint Smangle; 1268 } 1269 } 1270 1271 version (HTOD) 1272 { 1273 struct // SClinkage 1274 { 1275 uint Slinkage; // tym linkage bits 1276 uint Smangle; 1277 } 1278 } 1279 1280 struct 1281 { 1282 ubyte Sbit; // SCfield: bit position of start of bit field 1283 ubyte Swidth; // SCfield: width in bits of bit field 1284 targ_size_t Smemoff; // SCmember,SCfield: offset from start of struct 1285 } 1286 1287 elem* Svalue; /* SFLvalue: value of const 1288 SFLdtorexp: for objects with destructor, 1289 conditional expression to precede dtor call 1290 */ 1291 1292 struct_t* Sstruct; // SCstruct 1293 template_t* Stemplate; // SCtemplate 1294 1295 version (SCPP) 1296 { 1297 struct // SCnamespace 1298 { 1299 Symbol* Snameroot; // the Symbol table for the namespace 1300 list_t Susing; // other namespaces from using-directives 1301 } 1302 struct 1303 { 1304 Symbol* Smemalias; // SCalias: pointer to Symbol to use instead 1305 // (generated by using-declarations and 1306 // namespace-alias-definitions) 1307 // SCmemalias: pointer to member of base class 1308 // to use instead (using-declarations) 1309 symlist_t Spath; // SCmemalias: path of classes to get to base 1310 // class of which Salias is a member 1311 } 1312 Symbol* Simport ; // SCextern: if dllimport Symbol, this is the 1313 // Symbol it was imported from 1314 } 1315 version (HTOD) 1316 { 1317 struct // SCnamespace 1318 { 1319 Symbol* Snameroot; // the Symbol table for the namespace 1320 list_t Susing; // other namespaces from using-directives 1321 } 1322 struct 1323 { 1324 Symbol* Smemalias; // SCalias: pointer to Symbol to use instead 1325 // (generated by using-declarations and 1326 // namespace-alias-definitions) 1327 // SCmemalias: pointer to member of base class 1328 // to use instead (using-declarations) 1329 symlist_t Spath; // SCmemalias: path of classes to get to base 1330 // class of which Salias is a member 1331 } 1332 Symbol* Simport ; // SCextern: if dllimport Symbol, this is the 1333 // Symbol it was imported from 1334 } 1335 1336 struct // SCfastpar, SCshadowreg 1337 { 1338 reg_t Spreg; // register parameter is passed in 1339 reg_t Spreg2; // if 2 registers, this is the most significant, else NOREG 1340 } 1341 } 1342 1343 regm_t Spregm() // return mask of Spreg and Spreg2 1344 { 1345 return (1 << Spreg) | (Spreg2 == NOREG ? 0 : (1 << Spreg2)); 1346 } 1347 1348 //#if SCPP || MARS 1349 Symbol *Sscope; // enclosing scope (could be struct tag, 1350 // enclosing inline function for statics, 1351 // or namespace) 1352 //#endif 1353 1354 version (SCPP) 1355 { 1356 Symbol *Scover; // if there is a tag name and a regular name 1357 // of the same identifier, Scover is the tag 1358 // Scover can be SCstruct, SCenum, SCtemplate 1359 // or an SCalias to them. 1360 uint Ssequence; // sequence number (used for 2 level lookup) 1361 // also used as 'parameter number' for SCTtemparg 1362 } 1363 version (HTOD) 1364 { 1365 Symbol *Scover; // if there is a tag name and a regular name 1366 // of the same identifier, Scover is the tag 1367 // Scover can be SCstruct, SCenum, SCtemplate 1368 // or an SCalias to them. 1369 uint Ssequence; // sequence number (used for 2 level lookup) 1370 // also used as 'parameter number' for SCTtemparg 1371 } 1372 version (MARS) 1373 { 1374 const(char)* prettyIdent; // the symbol identifier as the user sees it 1375 } 1376 1377 //#if TARGET_OSX 1378 targ_size_t Slocalgotoffset; 1379 //#endif 1380 1381 enum_SC Sclass; // storage class (SCxxxx) 1382 char Sfl; // flavor (FLxxxx) 1383 SYMFLGS Sflags; // flag bits (SFLxxxx) 1384 1385 vec_t Srange; // live range, if any 1386 vec_t Slvreg; // when symbol is in register 1387 targ_size_t Ssize; // tyfunc: size of function 1388 targ_size_t Soffset; // variables: offset of Symbol in its storage class 1389 1390 // CPP || OPTIMIZER 1391 SYMIDX Ssymnum; // Symbol number (index into globsym[]) 1392 // SCauto,SCparameter,SCtmp,SCregpar,SCregister 1393 // CODGEN 1394 int Sseg; // segment index 1395 int Sweight; // usage count, the higher the number, 1396 // the more worthwhile it is to put in 1397 // a register 1398 int Sdw_ref_idx; // !=0 means index of DW.ref.name symbol (Dwarf EH) 1399 1400 union 1401 { 1402 uint Sxtrnnum; // SCcomdef,SCextern,SCcomdat: external symbol # (starting from 1) 1403 uint Stypidx; // SCstruct,SCunion,SCclass,SCenum,SCtypedef: debug info type index 1404 struct 1405 { 1406 ubyte Sreglsw; 1407 ubyte Sregmsw; 1408 regm_t Sregm; // mask of registers 1409 } // SCregister,SCregpar,SCpseudo: register number 1410 } 1411 regm_t Sregsaved; // mask of registers not affected by this func 1412 1413 uint lnoscopestart; // life time of var 1414 uint lnoscopeend; // the line after the scope 1415 1416 /** 1417 * Identifier for this symbol 1418 * 1419 * Note that this is used as a flexible array member. 1420 * When allocating a Symbol, the allocation is for 1421 * `sizeof(Symbol - 1 + strlen(identifier) + "\0".length)`. 1422 */ 1423 char[1] Sident; 1424 1425 int needThis() // !=0 if symbol needs a 'this' pointer 1426 { return Symbol_needThis(&this); } 1427 1428 bool Sisdead(bool anyiasm) // if variable is not referenced 1429 { return Symbol_Sisdead(&this, anyiasm); } 1430 } 1431 1432 void symbol_debug(const Symbol* s) 1433 { 1434 debug assert(s.id == s.IDsymbol); 1435 } 1436 1437 int Symbol_Salignsize(Symbol* s); 1438 bool Symbol_Sisdead(const Symbol* s, bool anyInlineAsm); 1439 int Symbol_needThis(const Symbol* s); 1440 bool Symbol_isAffected(const ref Symbol s); 1441 1442 bool isclassmember(const Symbol* s) { return s.Sscope && s.Sscope.Sclass == SCstruct; } 1443 1444 // Class, struct or union 1445 1446 alias Classsym = Symbol; 1447 1448 // Namespace Symbol 1449 alias Nspacesym = Symbol; 1450 1451 // Alias for another Symbol 1452 alias Aliassym = Symbol; 1453 1454 // Function symbol 1455 //alias Funcsym = Symbol; 1456 1457 // Determine if this Symbol is stored in a COMDAT 1458 //#if MARS 1459 //#define symbol_iscomdat(s) ((s)->Sclass == SCcomdat || \ 1460 // config.flags2 & CFG2comdat && (s)->Sclass == SCinline || \ 1461 // config.flags4 & CFG4allcomdat && ((s)->Sclass == SCglobal)) 1462 //#else 1463 //#define symbol_iscomdat(s) ((s)->Sclass == SCcomdat || \ 1464 // config.flags2 & CFG2comdat && (s)->Sclass == SCinline || \ 1465 // config.flags4 & CFG4allcomdat && ((s)->Sclass == SCglobal || (s)->Sclass == SCstatic)) 1466 //#endif 1467 1468 /* Format the identifier for presentation to the user */ 1469 version (SCPP) 1470 { 1471 const(char)* cpp_prettyident (const Symbol *s); 1472 const(char)* prettyident(const Symbol *s) { return CPP ? cpp_prettyident(s) : &s.Sident[0]; } 1473 } 1474 1475 version (SPP) 1476 { 1477 const(char)* cpp_prettyident (const Symbol *s); 1478 const(char)* prettyident(const Symbol *s) { return &s.Sident[0]; } 1479 } 1480 1481 version (HTOD) 1482 { 1483 const(char)* cpp_prettyident (const Symbol *s); 1484 const(char)* prettyident(const Symbol *s) { return &s.Sident[0]; } 1485 } 1486 1487 version (MARS) 1488 const(char)* prettyident(const Symbol *s) { return &s.Sident[0]; } 1489 1490 1491 /********************************** 1492 * Function parameters: 1493 * Pident identifier of parameter 1494 * Ptype type of argument 1495 * Pelem default value for argument 1496 * Psym symbol corresponding to Pident when using the 1497 * parameter list as a symbol table 1498 * For template-parameter-list: 1499 * Pident identifier of parameter 1500 * Ptype if NULL, this is a type-parameter 1501 * else the type for a parameter-declaration value argument 1502 * Pelem default value for value argument 1503 * Pdeftype default value for type-parameter 1504 * Pptpl template-parameter-list for template-template-parameter 1505 * Psym default value for template-template-parameter 1506 * For template-arg-list: (actual arguments) 1507 * Pident NULL 1508 * Ptype type-name 1509 * Pelem expression (either Ptype or Pelem is NULL) 1510 * Psym SCtemplate for template-template-argument 1511 */ 1512 1513 alias pflags_t = uint; 1514 enum 1515 { 1516 PFexplicit = 1, // this template argument was explicit, i.e. in < > 1517 } 1518 1519 /************************ 1520 * Params: 1521 * f = function symbol 1522 * Returns: 1523 * exception method for f 1524 */ 1525 EHmethod ehmethod(Symbol *f) 1526 { 1527 return f.Sfunc.Fflags3 & Feh_none ? EHmethod.EH_NONE : config.ehmethod; 1528 } 1529 1530 1531 struct param_t 1532 { 1533 nothrow: 1534 debug ushort id; 1535 enum IDparam = 0x7050; 1536 1537 char* Pident; // identifier 1538 type* Ptype; // type of parameter (NULL if not known yet) 1539 elem* Pelem; // default value 1540 token_t* PelemToken; // tokens making up default elem 1541 type* Pdeftype; // Ptype==NULL: default type for type-argument 1542 param_t* Pptpl; // template-parameter-list for template-template-parameter 1543 Symbol* Psym; 1544 param_t* Pnext; // next in list 1545 pflags_t Pflags; 1546 1547 param_t* createTal(param_t* p) // create template-argument-list blank from 1548 // template-parameter-list 1549 { return param_t_createTal(&this, p); } 1550 1551 param_t* search(char* id) // look for Pident matching id 1552 { return param_t_search(&this, id); } 1553 1554 int searchn(char* id); // look for Pident matching id, return index 1555 1556 uint length() // number of parameters in list 1557 { return param_t_length(&this); } 1558 1559 void print() // print this param_t 1560 { param_t_print(&this); } 1561 1562 void print_list() // print this list of param_t's 1563 { param_t_print_list(&this); } 1564 } 1565 1566 void param_t_print(const param_t* p); 1567 void param_t_print_list(param_t* p); 1568 uint param_t_length(param_t* p); 1569 param_t *param_t_createTal(param_t* p, param_t *ptali); 1570 param_t *param_t_search(param_t* p, char *id); 1571 int param_t_searchn(param_t* p, char *id); 1572 1573 1574 void param_debug(const param_t *p) 1575 { 1576 debug assert(p.id == p.IDparam); 1577 } 1578 1579 /************************************** 1580 * Element types. 1581 * These should be combined with storage classes. 1582 */ 1583 1584 alias FL = int; 1585 enum 1586 { 1587 // Change this, update debug.c too 1588 FLunde, 1589 FLconst, // numerical constant 1590 FLoper, // operator node 1591 FLfunc, // function symbol 1592 FLdata, // ref to data segment variable 1593 FLreg, // ref to register variable 1594 FLpseudo, // pseuodo register variable 1595 FLauto, // ref to automatic variable 1596 FLfast, // ref to variable passed as register 1597 FLpara, // ref to function parameter variable 1598 FLextern, // ref to external variable 1599 FLcode, // offset to code 1600 FLblock, // offset to block 1601 FLudata, // ref to udata segment variable 1602 FLcs, // ref to common subexpression number 1603 FLswitch, // ref to offset of switch data block 1604 FLfltreg, // ref to floating reg on stack, int contains offset 1605 FLoffset, // offset (a variation on constant, needed so we 1606 // can add offsets (different meaning for FLconst)) 1607 FLdatseg, // ref to data segment offset 1608 FLctor, // constructed object 1609 FLdtor, // destructed object 1610 FLregsave, // ref to saved register on stack, int contains offset 1611 FLasm, // (code) an ASM code 1612 1613 FLndp, // saved 8087 register 1614 1615 // Segmented systems 1616 FLfardata, // ref to far data segment 1617 FLcsdata, // ref to code segment variable 1618 1619 FLlocalsize, // replaced with # of locals in the stack frame 1620 FLtlsdata, // thread local storage 1621 FLbprel, // ref to variable at fixed offset from frame pointer 1622 FLframehandler, // ref to C++ frame handler for NT EH 1623 FLblockoff, // address of block 1624 FLallocatmp, // temp for built-in alloca() 1625 FLstack, // offset from ESP rather than EBP 1626 FLdsymbol, // it's a Dsymbol 1627 1628 // Global Offset Table 1629 FLgot, // global offset table entry outside this object file 1630 FLgotoff, // global offset table entry inside this object file 1631 1632 FLfuncarg, // argument to upcoming function call 1633 1634 FLMAX 1635 } 1636 1637 ////////// Srcfiles 1638 1639 version (MARS) 1640 { 1641 } 1642 else 1643 { 1644 // Collect information about a source file. 1645 alias sfile_flags_t = uint; 1646 enum 1647 { 1648 SFonce = 1, // file is to be #include'd only once 1649 SFhx = 2, // file is in an HX file and has not been loaded 1650 SFtop = 4, // file is a top level source file 1651 SFloaded = 8, // read from PH file 1652 } 1653 1654 private import parser : macro_t; 1655 1656 struct Sfile 1657 { 1658 debug ushort id; 1659 enum IDsfile = (('f' << 8) | 's'); 1660 1661 char *SFname; // name of file 1662 sfile_flags_t SFflags; 1663 list_t SFfillist; // file pointers of Sfile's that this Sfile is 1664 // dependent on (i.e. they were #include'd). 1665 // Does not include nested #include's 1666 macro_t *SFmacdefs; // threaded list of macros #defined by this file 1667 macro_t **SFpmacdefs; // end of macdefs list 1668 Symbol *SFsymdefs; // threaded list of global symbols declared by this file 1669 symlist_t SFcomdefs; // comdefs defined in PH 1670 symlist_t SFtemp_ft; // template_ftlist 1671 symlist_t SFtemp_class; // template_class_list 1672 Symbol *SFtagsymdefs; // list of tag names (C only) 1673 char *SFinc_once_id; // macro include guard identifier 1674 uint SFhashval; // hash of file name 1675 } 1676 1677 void sfile_debug(const Sfile* sf) 1678 { 1679 debug assert(sf.id == Sfile.IDsfile); 1680 } 1681 1682 // Source files are referred to by a pointer into pfiles[]. This is so that 1683 // when PH files are hydrated, only pfiles[] needs updating. Of course, this 1684 // means that pfiles[] cannot be reallocated to larger numbers, its size is 1685 // fixed at SRCFILES_MAX. 1686 1687 version (SPP) 1688 { 1689 enum SRCFILES_MAX = (2*512*4); // no precompiled headers for SPP 1690 } 1691 else 1692 { 1693 enum SRCFILES_MAX = (2*512); 1694 } 1695 1696 struct Srcfiles 1697 { 1698 // Sfile *arr; // array of Sfiles 1699 Sfile **pfiles; // parallel array of pointers into arr[] 1700 uint dim; // dimension of array 1701 uint idx; // # used in array 1702 } 1703 1704 Sfile* sfile(uint fi) 1705 { 1706 import dmd.backend.global : srcfiles; 1707 return srcfiles.pfiles[fi]; 1708 } 1709 1710 char* srcfiles_name(uint fi) { return sfile(fi).SFname; } 1711 } 1712 1713 /************************************************** 1714 * This is to support compiling expressions within the context of a function. 1715 */ 1716 1717 struct EEcontext 1718 { 1719 uint EElinnum; // line number to insert expression 1720 char *EEexpr; // expression 1721 char *EEtypedef; // typedef identifier 1722 byte EEpending; // !=0 means we haven't compiled it yet 1723 byte EEimminent; // we've installed it in the source text 1724 byte EEcompile; // we're compiling for the EE expression 1725 byte EEin; // we are parsing an EE expression 1726 elem *EEelem; // compiled version of EEexpr 1727 Symbol *EEfunc; // function expression is in 1728 code *EEcode; // generated code 1729 } 1730 1731 extern __gshared EEcontext eecontext; 1732 1733 1734 // Different goals for el_optimize() 1735 alias goal_t = uint; 1736 enum 1737 { 1738 GOALnone = 0, // evaluate for side effects only 1739 GOALvalue = 1, // evaluate for value 1740 GOALflags = 2, // evaluate for flags 1741 GOALagain = 4, 1742 GOALstruct = 8, 1743 GOALhandle = 0x10, // don't replace handle'd objects 1744 GOALignore_exceptions = 0x20, // ignore floating point exceptions 1745 } 1746 1747 /* Globals returned by declar() */ 1748 struct Declar 1749 { 1750 Classsym *class_sym; 1751 Nspacesym *namespace_sym; 1752 int oper; 1753 bool constructor; 1754 bool destructor; 1755 bool _invariant; 1756 param_t *ptal; 1757 bool explicitSpecialization; 1758 int hasExcSpec; // has exception specification 1759 } 1760 1761 extern __gshared Declar gdeclar; 1762 1763 /********************************** 1764 * Data definitions 1765 * DTibytes 1..7 bytes 1766 * DTabytes offset of bytes of data 1767 * a { a data bytes } 1768 * DTnbytes bytes of data 1769 * a { a data bytes } 1770 * a = offset 1771 * DTazeros # of 0 bytes 1772 * a 1773 * DTsymsize same as DTazeros, but the type of the symbol gives 1774 * the size 1775 * DTcommon # of 0 bytes (in a common block) 1776 * a 1777 * DTxoff offset from symbol 1778 * w a 1779 * w = symbol number (pointer for CPP) 1780 * a = offset 1781 * DTcoff offset into code segment 1782 */ 1783 1784 struct dt_t 1785 { 1786 dt_t *DTnext; // next in list 1787 char dt; // type (DTxxxx) 1788 ubyte Dty; // pointer type 1789 ubyte DTn; // DTibytes: number of bytes 1790 ubyte DTalign; // DTabytes: alignment (as power of 2) of pointed-to data 1791 union 1792 { 1793 struct // DTibytes 1794 { 1795 enum DTibytesMax = (char*).sizeof + uint.sizeof + int.sizeof + targ_size_t.sizeof; 1796 byte[DTibytesMax] DTdata; // data 1797 } 1798 targ_size_t DTazeros; // DTazeros,DTcommon,DTsymsize 1799 struct // DTabytes 1800 { 1801 byte *DTpbytes; // pointer to the bytes 1802 uint DTnbytes; // # of bytes 1803 int DTseg; // segment it went into 1804 targ_size_t DTabytes; // offset of abytes for DTabytes 1805 } 1806 struct // DTxoff 1807 { 1808 Symbol *DTsym; // symbol pointer 1809 targ_size_t DToffset; // offset from symbol 1810 } 1811 } 1812 } 1813 1814 enum 1815 { 1816 DT_abytes = 0, 1817 DT_azeros = 1, 1818 DT_xoff = 2, 1819 DT_nbytes = 3, 1820 DT_common = 4, 1821 DT_coff = 5, 1822 DT_ibytes = 6, 1823 } 1824 1825 // An efficient way to clear aligned memory 1826 //#define MEMCLEAR(p,sz) \ 1827 // if ((sz) == 10 * sizeof(size_t)) \ 1828 // { \ 1829 // ((size_t *)(p))[0] = 0; \ 1830 // ((size_t *)(p))[1] = 0; \ 1831 // ((size_t *)(p))[2] = 0; \ 1832 // ((size_t *)(p))[3] = 0; \ 1833 // ((size_t *)(p))[4] = 0; \ 1834 // ((size_t *)(p))[5] = 0; \ 1835 // ((size_t *)(p))[6] = 0; \ 1836 // ((size_t *)(p))[7] = 0; \ 1837 // ((size_t *)(p))[8] = 0; \ 1838 // ((size_t *)(p))[9] = 0; \ 1839 // } \ 1840 // else if ((sz) == 14 * sizeof(size_t)) \ 1841 // { \ 1842 // ((size_t *)(p))[0] = 0; \ 1843 // ((size_t *)(p))[1] = 0; \ 1844 // ((size_t *)(p))[2] = 0; \ 1845 // ((size_t *)(p))[3] = 0; \ 1846 // ((size_t *)(p))[4] = 0; \ 1847 // ((size_t *)(p))[5] = 0; \ 1848 // ((size_t *)(p))[6] = 0; \ 1849 // ((size_t *)(p))[7] = 0; \ 1850 // ((size_t *)(p))[8] = 0; \ 1851 // ((size_t *)(p))[9] = 0; \ 1852 // ((size_t *)(p))[10] = 0; \ 1853 // ((size_t *)(p))[11] = 0; \ 1854 // ((size_t *)(p))[12] = 0; \ 1855 // ((size_t *)(p))[13] = 0; \ 1856 // } \ 1857 // else \ 1858 // { \ 1859 // /*printf("%s(%d) sz = %d\n",__FILE__,__LINE__,(sz));fflush(stdout);*(char*)0=0;*/ \ 1860 // for (size_t i = 0; i < sz / sizeof(size_t); ++i) \ 1861 // ((size_t *)(p))[i] = 0; \ 1862 // }