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