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