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