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