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