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