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