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