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-2016 by Digital Mars, All Rights Reserved
7  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
8  * License:     backendlicense.txt
9  * Source:      $(DMDSRC backend/_cdef.d)
10  */
11 
12 module ddmd.backend.cdef;
13 
14 import ddmd.backend.cc: Classsym, Symbol;
15 import ddmd.backend.el;
16 
17 import tk.dlist;
18 
19 extern (C++):
20 @nogc:
21 nothrow:
22 
23 //struct Classsym;
24 //struct Symbol;
25 //struct LIST;
26 struct param_t;
27 
28 
29 //
30 //      Attributes
31 //
32 
33 //      Types of attributes
34 enum
35 {
36     ATTR_LINKMOD    = 1,     // link modifier
37     ATTR_TYPEMOD    = 2,     // basic type modifier
38     ATTR_FUNCINFO   = 4,     // function information
39     ATTR_DATAINFO   = 8,     // data information
40     ATTR_TRANSU     = 0x10,  // transparent union
41     ATTR_IGNORED    = 0x20,  // attribute can be ignored
42     ATTR_WARNING    = 0x40,  // attribute was ignored
43     ATTR_SEGMENT    = 0x80,  // segment secified
44 }
45 
46 //      attribute location in code
47 enum
48 {
49     ALOC_DECSTART   = 1,   // start of declaration
50     ALOC_SYMDEF     = 2,   // symbol defined
51     ALOC_PARAM      = 4,   // follows function parameter
52     ALOC_FUNC       = 8,   // follows function declaration
53 }
54 
55 //#define ATTR_LINK_MODIFIERS (mTYconst|mTYvolatile|mTYcdecl|mTYstdcall)
56 //#define ATTR_CAN_IGNORE(a) (((a) & (ATTR_LINKMOD|ATTR_TYPEMOD|ATTR_FUNCINFO|ATTR_DATAINFO|ATTR_TRANSU)) == 0)
57 //#define LNX_CHECK_ATTRIBUTES(a,x) assert(((a) & ~(x|ATTR_IGNORED|ATTR_WARNING)) == 0)
58 
59 
60 // C++ Language Features
61 enum ANGLE_BRACKET_HACK = 0;       // >> means two template arglist closes
62 
63 // C/C++ Language Features
64 enum IMPLIED_PRAGMA_ONCE = 1;       // include guards count as #pragma once
65 enum bool HEADER_LIST = true;
66 
67 // Support generating code for 16 bit memory models
68 //#define SIXTEENBIT              (SCPP && TARGET_WINDOS)
69 
70 /* Set for supporting the FLAT memory model.
71  * This is not quite the same as !SIXTEENBIT, as one could
72  * have near/far with 32 bit code.
73  */
74 //#define TARGET_SEGMENTED     (!MARS && TARGET_WINDOS)
75 
76 
77 //#if __GNUC__
78 //#define LDOUBLE                 0       // no support for true long doubles
79 //#else
80 //#define LDOUBLE         (config.exe == EX_WIN32)   // support true long doubles
81 //#endif
82 
83 
84 // Precompiled header variations
85 //#define MEMORYHX        (_WINDLL && _WIN32)     // HX and SYM files are cached in memory
86 //#define MMFIO           (_WIN32 || __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun)  // if memory mapped files
87 //#define LINEARALLOC     _WIN32  // if we can reserve address ranges
88 
89 // H_STYLE takes on one of these precompiled header methods
90 enum
91 {
92     H_NONE    = 1,       // no hydration/dehydration necessary
93     H_BIT0    = 2,       // bit 0 of the pointer determines if pointer
94                          // is dehydrated, an offset is added to
95                          // hydrate it
96     H_OFFSET  = 4,       // the address range of the pointer determines
97                          // if pointer is dehydrated, and an offset is
98                          // added to hydrate it. No dehydration necessary.
99     H_COMPLEX = 8,       // dehydrated pointers have bit 0 set, hydrated
100                          // pointers are in non-contiguous buffers
101 }
102 
103 // Do we need hydration code
104 //#define HYDRATE         (H_STYLE & (H_BIT0 | H_OFFSET | H_COMPLEX))
105 
106 // Do we need dehydration code
107 //#define DEHYDRATE       (H_STYLE & (H_BIT0 | H_COMPLEX))
108 
109 // Determine hydration style
110 //      NT console:     H_NONE
111 //      NT DLL:         H_OFFSET
112 //      DOSX:           H_COMPLEX
113 //#if MARS
114 //#define H_STYLE         H_NONE                  // precompiled headers only used for C/C++ compiler
115 //#else
116 //#if MMFIO
117 //#if _WINDLL
118 //#define H_STYLE         H_OFFSET
119 //#else
120 //#define H_STYLE         H_OFFSET //H_NONE
121 //#endif
122 //#elif LINEARALLOC
123 //#define H_STYLE         H_BIT0
124 //#else
125 //#define H_STYLE         H_COMPLEX
126 //#endif
127 //#endif
128 
129 // NT structured exception handling
130 //      0: no support
131 //      1: old style
132 //      2: new style
133 enum NTEXCEPTIONS = 2;
134 
135 // For Shared Code Base
136 //#if _WINDLL
137 //#define dbg_printf dll_printf
138 //#else
139 //#define dbg_printf printf
140 //#endif
141 
142 //#ifndef ERRSTREAM
143 //#define ERRSTREAM stdout
144 //#endif
145 //#define err_printf printf
146 //#define err_vprintf vfprintf
147 //#define err_fputc fputc
148 //#define dbg_fputc fputc
149 //#define LF '\n'
150 //#define LF_STR "\n"
151 //#define CR '\r'
152 //#define ANSI        config.ansi_c
153 //#define ANSI_STRICT config.ansi_c
154 //#define ANSI_RELAX  config.ansi_c
155 //#define TRIGRAPHS   ANSI
156 //#define T80x86(x)       x
157 
158 // For Share MEM_ macros - default to mem_xxx package
159 // PH           precompiled header
160 // PARF         parser, life of function
161 // PARC         parser, life of compilation
162 // BEF          back end, function
163 // BEC          back end, compilation
164 
165 //#define MEM_PH_FREE      mem_free
166 //#define MEM_PARF_FREE    mem_free
167 //#define MEM_PARC_FREE    mem_free
168 //#define MEM_BEF_FREE     mem_free
169 //#define MEM_BEC_FREE     mem_free
170 
171 //#define MEM_PH_CALLOC    mem_calloc
172 //#define MEM_PARC_CALLOC  mem_calloc
173 //#define MEM_PARF_CALLOC  mem_calloc
174 //#define MEM_BEF_CALLOC   mem_calloc
175 //#define MEM_BEC_CALLOC   mem_calloc
176 
177 //#define MEM_PH_MALLOC    mem_malloc
178 //#define MEM_PARC_MALLOC  mem_malloc
179 //#define MEM_PARF_MALLOC  mem_malloc
180 //#define MEM_BEF_MALLOC   mem_malloc
181 //#define MEM_BEC_MALLOC   mem_malloc
182 
183 //#define MEM_PH_STRDUP    mem_strdup
184 //#define MEM_PARC_STRDUP  mem_strdup
185 //#define MEM_PARF_STRDUP  mem_strdup
186 //#define MEM_BEF_STRDUP   mem_strdup
187 //#define MEM_BEC_STRDUP   mem_strdup
188 
189 //#define MEM_PH_REALLOC   mem_realloc
190 //#define MEM_PARC_REALLOC mem_realloc
191 //#define MEM_PARF_REALLOC mem_realloc
192 //#define MEM_PERM_REALLOC mem_realloc
193 //#define MEM_BEF_REALLOC  mem_realloc
194 //#define MEM_BEC_REALLOC  mem_realloc
195 
196 //#define MEM_PH_FREEFP    mem_freefp
197 //#define MEM_PARC_FREEFP  mem_freefp
198 //#define MEM_PARF_FREEFP  mem_freefp
199 //#define MEM_BEF_FREEFP   mem_freefp
200 //#define MEM_BEC_FREEFP   mem_freefp
201 
202 
203 // If we can use 386 instruction set (possible in 16 bit code)
204 //#define I386 (config.target_cpu >= TARGET_80386)
205 
206 // If we are generating 32 bit code
207 //#if MARS
208 //#define I16     0               // no 16 bit code for D
209 //#define I32     (NPTRSIZE == 4)
210 //#define I64     (NPTRSIZE == 8) // 1 if generating 64 bit code
211 //#else
212 //#define I16     (NPTRSIZE == 2)
213 //#define I32     (NPTRSIZE == 4)
214 //#define I64     (NPTRSIZE == 8) // 1 if generating 64 bit code
215 //#endif
216 
217 /**********************************
218  * Limits & machine dependent stuff.
219  */
220 
221 /* Define stuff that's different between VAX and IBMPC.
222  * HOSTBYTESWAPPED      TRUE if on the host machine the bytes are
223  *                      swapped (TRUE for 6809, 68000, FALSE for 8088
224  *                      and VAX).
225  */
226 
227 
228 enum EXIT_BREAK = 255;     // aborted compile with ^C
229 
230 /* Take advantage of machines that can store a word, lsb first  */
231 //#if _M_I86              // if Intel processor
232 //#define TOWORD(ptr,val) (*(unsigned short *)(ptr) = (unsigned short)(val))
233 //#define TOLONG(ptr,val) (*(unsigned *)(ptr) = (unsigned)(val))
234 //#else
235 //#define TOWORD(ptr,val) (((ptr)[0] = (unsigned char)(val)),\
236 //                         ((ptr)[1] = (unsigned char)((val) >> 8)))
237 //#define TOLONG(ptr,val) (((ptr)[0] = (unsigned char)(val)),\
238 //                         ((ptr)[1] = (unsigned char)((val) >> 8)),\
239 //                         ((ptr)[2] = (unsigned char)((val) >> 16)),\
240 //                         ((ptr)[3] = (unsigned char)((val) >> 24)))
241 //#endif
242 //
243 //#define TOOFFSET(a,b)   (I32 ? TOLONG(a,b) : TOWORD(a,b))
244 
245 /***************************
246  * Target machine data types as they appear on the host.
247  */
248 
249 alias targ_char = byte;
250 alias targ_uchar = ubyte;
251 alias targ_schar = byte;
252 alias targ_short = short;
253 alias targ_ushort= ushort;
254 alias targ_long = int;
255 alias targ_ulong = uint;
256 alias targ_llong = long;
257 alias targ_ullong = ulong;
258 alias targ_float = float;
259 alias targ_double = double;
260 alias targ_ldouble = real;
261 
262 // Extract most significant register from constant
263 //#define MSREG(p)        ((REGSIZE == 2) ? (p) >> 16 : ((sizeof(targ_llong) == 8) ? (p) >> 32 : 0))
264 
265 alias targ_int = int;
266 alias targ_uns = uint;
267 
268 /* Sizes of base data types in bytes */
269 enum
270 {
271     CHARSIZE       = 1,
272     SHORTSIZE      = 2,
273     WCHARSIZE      = 2,       // 2 for WIN32, 4 for linux/OSX/FreeBSD/OpenBSD/Solaris
274     LONGSIZE       = 4,
275     LLONGSIZE      = 8,
276     CENTSIZE       = 16,
277     FLOATSIZE      = 4,
278     DOUBLESIZE     = 8,
279     TMAXSIZE       = 16,      // largest size a constant can be
280 }
281 
282 //#define intsize         _tysize[TYint]
283 //#define REGSIZE         _tysize[TYnptr]
284 //#define NPTRSIZE        _tysize[TYnptr]
285 //#define FPTRSIZE        _tysize[TYfptr]
286 //#define REGMASK         0xFFFF
287 
288 // targ_llong is also used to store host pointers, so it should have at least their size
289 //#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS || TARGET_OSX || MARS
290 alias targ_ptrdiff_t = targ_llong;  // ptrdiff_t for target machine
291 alias targ_size_t = targ_ullong;    // size_t for the target machine
292 //#else
293 //typedef targ_int        targ_ptrdiff_t; /* ptrdiff_t for target machine  */
294 //typedef targ_uns        targ_size_t;    /* size_t for the target machine */
295 //#endif
296 
297 /* Enable/disable various features
298    (Some features may no longer work the old way when compiled out,
299     I don't test the old ways once the new way is set.)
300  */
301 //#define NEWTEMPMANGLE   (!(config.flags4 & CFG4oldtmangle))     // do new template mangling
302 //#define USEDLLSHELL     _WINDLL
303 //#define MFUNC           (I32) //0 && config.exe == EX_WIN32)       // member functions are TYmfunc
304 //#define CV3             0       // 1 means support CV3 debug format
305 
306 /* Object module format
307  */
308 //#ifndef OMFOBJ
309 //#define OMFOBJ          TARGET_WINDOS
310 //#endif
311 //#ifndef ELFOBJ
312 //#define ELFOBJ          (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS)
313 //#endif
314 //#ifndef MACHOBJ
315 //#define MACHOBJ         TARGET_OSX
316 //#endif
317 
318 //#define SYMDEB_CODEVIEW TARGET_WINDOS
319 //#define SYMDEB_DWARF    (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS || TARGET_OSX)
320 
321 //#define TOOLKIT_H
322 
323 enum Smodel = 0;        // 64k code, 64k data, or flat model
324 
325 //#ifndef MEMMODELS
326 //#define LARGEDATA       (config.memmodel & 6)
327 //#define LARGECODE       (config.memmodel & 5)
328 //
329 //#define Mmodel 1        /* large code, 64k data         */
330 //#define Cmodel 2        /* 64k code, large data         */
331 //#define Lmodel 3        /* large code, large data       */
332 //#define Vmodel 4        /* large code, large data, vcm  */
333 //#define MEMMODELS 5     /* number of memory models      */
334 //#endif
335 
336 /* Segments     */
337 enum
338 {
339     CODE      = 1,     // code segment
340     DATA      = 2,     // initialized data
341     CDATA     = 3,     // constant data
342     UDATA     = 4,     // uninitialized data
343     CDATAREL  = 5,     // constant data with relocs
344     UNKNOWN   = -1,    // unknown segment
345     DGROUPIDX = 1,     // group index of DGROUP
346 }
347 
348 enum REGMAX = 29;      // registers are numbered 0..10
349 
350 alias tym_t = uint;    // data type big enough for type masks
351 alias SYMIDX = int;    // symbol table index
352 
353 //#define _chkstack()     (void)0
354 
355 //#if _WINDLL
356 ///* We reference the required Windows-1252 encoding of the copyright symbol
357 //   by escaping its character code (0xA9) rather than directly embedding it in
358 //   the source text. The character code is invalid in UTF-8, which causes some
359 //   of our source-code preprocessing tools (e.g. tolf) to choke. */
360 //#ifndef COPYRIGHT_SYMBOL
361 //#define COPYRIGHT_SYMBOL "\xA9"
362 //#endif
363 //#define COPYRIGHT "Copyright " COPYRIGHT_SYMBOL " 2001 Digital Mars"
364 //#else
365 //#ifdef DEBUG
366 //#define COPYRIGHT "Copyright (C) Digital Mars 2000-2016.  All Rights Reserved.\n\
367 //Written by Walter Bright\n\
368 //*****BETA TEST VERSION*****"
369 //#else
370 //#if __linux__
371 //#define COPYRIGHT "Copyright (C) Digital Mars 2000-2016.  All Rights Reserved.\n\
372 //Written by Walter Bright, Linux version by Pat Nelson"
373 //#else
374 //#define COPYRIGHT "Copyright (C) Digital Mars 2000-2016.  All Rights Reserved.\n\
375 //Written by Walter Bright"
376 //#endif
377 //#endif
378 //#endif
379 
380 /**********************************
381  * Configuration
382  */
383 
384 /* Linkage type         */
385 enum linkage_t
386 {
387     LINK_C,                     /* C style                              */
388     LINK_CPP,                   /* C++ style                            */
389     LINK_PASCAL,                /* Pascal style                         */
390     LINK_FORTRAN,
391     LINK_SYSCALL,
392     LINK_STDCALL,
393     LINK_D,                     // D code
394     LINK_MAXDIM                 /* array dimension                      */
395 }
396 
397 /**********************************
398  * Exception handling method
399  */
400 
401 enum EHmethod
402 {
403     EH_NONE,                    // no exception handling
404     EH_WIN32,                   // Win32 SEH
405     EH_WIN64,                   // Win64 SEH (not supported yet)
406     EH_DM,                      // Digital Mars method
407     EH_DWARF,                   // Dwarf method
408 }
409 
410 // CPU target
411 alias cpu_target_t = byte;
412 enum
413 {
414     TARGET_8086             = 0,
415     TARGET_80286            = 2,
416     TARGET_80386            = 3,
417     TARGET_80486            = 4,
418     TARGET_Pentium          = 5,
419     TARGET_PentiumMMX       = 6,
420     TARGET_PentiumPro       = 7,
421     TARGET_PentiumII        = 8,
422 }
423 
424 // Symbolic debug info
425 alias symbolic_debug_t = byte;
426 enum
427 {
428     CVNONE    = 0,           // No symbolic info
429     CVOLD     = 1,           // Codeview 1 symbolic info
430     CV4       = 2,           // Codeview 4 symbolic info
431     CVSYM     = 3,           // Symantec format
432     CVTDB     = 4,           // Symantec format written to file
433     CVDWARF_C = 5,           // Dwarf in C format
434     CVDWARF_D = 6,           // Dwarf in D format
435     CVSTABS   = 7,           // Elf Stabs in C format
436     CV8       = 8,           // Codeview 8 symbolic info
437 }
438 
439 // Windows code gen flags
440 alias windows_flags_t = uint;
441 enum
442 {
443     WFwindows    = 1,      // generating code for Windows app or DLL
444     WFdll        = 2,      // generating code for Windows DLL
445     WFincbp      = 4,      // mark far stack frame with inc BP / dec BP
446     WFloadds     = 8,      // assume __loadds for all functions
447     WFexpdef     = 0x10,   // generate export definition records for
448                            // exported functions
449     WFss         = 0x20,   // load DS from SS
450     WFreduced    = 0x40,   // skip DS load for non-exported functions
451     WFdgroup     = 0x80,   // load DS from DGROUP
452     WFexport     = 0x100,  // assume __export for all far functions
453     WFds         = 0x200,  // load DS from DS
454     WFmacros     = 0x400,  // define predefined windows macros
455     WFssneds     = 0x800,  // SS != DS
456     WFthunk      = 0x1000, // use fixups instead of direct ref to CS
457     WFsaveds     = 0x2000, // use push/pop DS for far functions
458     WFdsnedgroup = 0x4000, // DS != DGROUP
459     WFexe        = 0x8000, // generating code for Windows EXE
460 }
461 
462 // Object file format
463 alias objfmt_t = uint;
464 enum
465 {
466     OBJ_OMF         = 1,
467     OBJ_MSCOFF      = 2,
468     OBJ_ELF         = 4,
469     OBJ_MACH        = 8,
470 }
471 
472 // Executable file format
473 alias exefmt_t = uint;
474 enum
475 {
476     EX_DOSX         = 1,       // DOSX 386 program
477     EX_ZPM          = 2,       // ZPM 286 program
478     EX_RATIONAL     = 4,       // RATIONAL 286 program
479     EX_PHARLAP      = 8,       // PHARLAP 386 program
480     EX_COM          = 0x10,    // MSDOS .COM program
481 //  EX_WIN16        = 0x20,    // Windows 3.x 16 bit program (no longer supported)
482     EX_OS2          = 0x40,    // OS/2 2.0 32 bit program
483     EX_OS1          = 0x80,    // OS/2 1.x 16 bit program
484     EX_WIN32        = 0x100,
485     EX_MZ           = 0x200,   // MSDOS real mode program
486     EX_XENIX        = 0x400,
487     EX_SCOUNIX      = 0x800,
488     EX_UNIXSVR4     = 0x1000,
489     EX_LINUX        = 0x2000,
490     EX_WIN64        = 0x4000,  // AMD64 and Windows (64 bit mode)
491     EX_LINUX64      = 0x8000,  // AMD64 and Linux (64 bit mode)
492     EX_OSX          = 0x10000,
493     EX_OSX64        = 0x20000,
494     EX_FREEBSD      = 0x40000,
495     EX_FREEBSD64    = 0x80000,
496     EX_SOLARIS      = 0x100000,
497     EX_SOLARIS64    = 0x200000,
498     EX_OPENBSD      = 0x400000,
499     EX_OPENBSD64    = 0x800000,
500 }
501 
502 
503 // All flat memory models (no segment registers)
504 enum exefmt_t EX_flat = EX_OS2 | EX_WIN32 | EX_LINUX | EX_WIN64 | EX_LINUX64 |
505                          EX_OSX | EX_OSX64 | EX_FREEBSD | EX_FREEBSD64 |
506                          EX_OPENBSD | EX_OPENBSD64 |
507                          EX_SOLARIS | EX_SOLARIS64;
508 
509 // All DOS executable types
510 enum exefmt_t EX_dos =  EX_DOSX | EX_ZPM | EX_RATIONAL | EX_PHARLAP |
511                          EX_COM | EX_MZ /*| EX_WIN16*/;
512 
513 alias config_flags_t = uint;
514 enum
515 {
516     CFGuchar        = 1,       // chars are unsigned
517     CFGsegs         = 2,       // new code seg for each far func
518     CFGtrace        = 4,       // output trace functions
519     CFGglobal       = 8,       // make all static functions global
520     CFGstack        = 0x10,    // add stack overflow checking
521     CFGalwaysframe  = 0x20,    // always generate stack frame
522     CFGnoebp        = 0x40,    // do not use EBP as general purpose register
523     CFGromable      = 0x80,    // put switch tables in code segment
524     CFGeasyomf      = 0x100,   // generate Pharlap Easy-OMF format
525     CFGfarvtbls     = 0x200,   // store vtables in far segments
526     CFGnoinlines    = 0x400,   // do not inline functions
527     CFGnowarning    = 0x800,   // disable warnings
528 }
529 
530 alias config_flags2_t = uint;
531 enum
532 {
533     CFG2comdat      = 1,       // use initialized common blocks
534     CFG2nodeflib    = 2,       // no default library imbedded in OBJ file
535     CFG2browse      = 4,       // generate browse records
536     CFG2dyntyping   = 8,       // generate dynamic typing information
537     CFG2fulltypes   = 0x10,    // don't optimize CV4 class info
538     CFG2warniserr   = 0x20,    // treat warnings as errors
539     CFG2phauto      = 0x40,    // automatic precompiled headers
540     CFG2phuse       = 0x80,    // use precompiled headers
541     CFG2phgen       = 0x100,   // generate precompiled header
542     CFG2once        = 0x200,   // only include header files once
543     CFG2hdrdebug    = 0x400,   // generate debug info for header
544     CFG2phautoy     = 0x800,   // fast build precompiled headers
545     CFG2noobj       = 0x1000,  // we are not generating a .OBJ file
546     CFG2noerrmax    = 0x2000,  // no error count maximum
547     CFG2expand      = 0x4000,  // expanded output to list file
548     CFG2stomp       = 0x8000,  // enable stack stomping code
549     CFG2gms         = 0x10000, // optimize debug symbols for microsoft debuggers
550 }
551 
552 alias config_flags3_t = uint;
553 enum
554 {
555     CFG3ju          = 1,       // char == unsigned char
556     CFG3eh          = 2,       // generate exception handling stuff
557     CFG3strcod      = 4,       // strings are placed in code segment
558     CFG3eseqds      = 8,       // ES == DS at all times
559     CFG3ptrchk      = 0x10,    // generate pointer validation code
560     CFG3strictproto = 0x20,    // strict prototyping
561     CFG3autoproto   = 0x40,    // auto prototyping
562     CFG3rtti        = 0x80,    // add RTTI support
563     CFG3relax       = 0x100,   // relaxed type checking (C only)
564     CFG3cpp         = 0x200,   // C++ compile
565     CFG3igninc      = 0x400,   // ignore standard include directory
566     CFG3mars        = 0x800,   // use mars libs and headers
567     CFG3nofar       = 0x1000,  // ignore __far and __huge keywords
568     CFG3noline      = 0x2000,  // do not output #line directives
569     CFG3comment     = 0x4000,  // leave comments in preprocessed output
570     CFG3cppcomment  = 0x8000,  // allow C++ style comments
571     CFG3wkfloat     = 0x10000, // make floating point references weak externs
572     CFG3digraphs    = 0x20000, // support ANSI C++ digraphs
573     CFG3semirelax   = 0x40000, // moderate relaxed type checking (non-Windows targets)
574     CFG3pic         = 0x80000, // position independent code
575 }
576 
577 alias config_flags4_t = uint;
578 enum
579 {
580     CFG4speed            = 1,          // optimized for speed
581     CFG4space            = 2,          // optimized for space
582     CFG4allcomdat        = 4,          // place all functions in COMDATs
583     CFG4fastfloat        = 8,          // fast floating point (-ff)
584     CFG4fdivcall         = 0x10,       // make function call for FDIV opcodes
585     CFG4tempinst         = 0x20,       // instantiate templates for undefined functions
586     CFG4oldstdmangle     = 0x40,       // do stdcall mangling without @
587     CFG4pascal           = 0x80,       // default to pascal linkage
588     CFG4stdcall          = 0x100,      // default to std calling convention
589     CFG4cacheph          = 0x200,      // cache precompiled headers in memory
590     CFG4alternate        = 0x400,      // if alternate digraph tokens
591     CFG4bool             = 0x800,      // support 'bool' as basic type
592     CFG4wchar_t          = 0x1000,     // support 'wchar_t' as basic type
593     CFG4notempexp        = 0x2000,     // no instantiation of template functions
594     CFG4anew             = 0x4000,     // allow operator new[] and delete[] overloading
595     CFG4oldtmangle       = 0x8000,     // use old template name mangling
596     CFG4dllrtl           = 0x10000,    // link with DLL RTL
597     CFG4noemptybaseopt   = 0x20000,    // turn off empty base class optimization
598     CFG4nowchar_t        = 0x40000,    // use unsigned short name mangling for wchar_t
599     CFG4forscope         = 0x80000,    // new C++ for scoping rules
600     CFG4warnccast        = 0x100000,   // warn about C style casts
601     CFG4adl              = 0x200000,   // argument dependent lookup
602     CFG4enumoverload     = 0x400000,   // enum overloading
603     CFG4implicitfromvoid = 0x800000,   // allow implicit cast from void* to T*
604     CFG4dependent        = 0x1000000,  // dependent / non-dependent lookup
605     CFG4wchar_is_long    = 0x2000000,  // wchar_t is 4 bytes
606     CFG4underscore       = 0x4000000,  // prepend _ for C mangling
607 }
608 
609 enum config_flags4_t CFG4optimized  = CFG4speed | CFG4space;
610 enum config_flags4_t CFG4stackalign = CFG4speed;       // align stack to 8 bytes
611 
612 alias config_flags5_t = uint;
613 enum
614 {
615     CFG5debug       = 1,      // compile in __debug code
616     CFG5in          = 2,      // compile in __in code
617     CFG5out         = 4,      // compile in __out code
618     CFG5invariant   = 8,      // compile in __invariant code
619 }
620 
621 /* CFGX: flags ignored in precompiled headers
622  * CFGY: flags copied from precompiled headers into current config
623  */
624 enum config_flags_t CFGX   = CFGnowarning;
625 enum config_flags2_t CFGX2 = CFG2warniserr | CFG2phuse | CFG2phgen | CFG2phauto |
626                              CFG2once | CFG2hdrdebug | CFG2noobj | CFG2noerrmax |
627                              CFG2expand | CFG2nodeflib | CFG2stomp | CFG2gms;
628 enum config_flags3_t CFGX3 = CFG3strcod | CFG3ptrchk;
629 enum config_flags4_t CFGX4 = CFG4optimized | CFG4fastfloat | CFG4fdivcall |
630                              CFG4tempinst | CFG4cacheph | CFG4notempexp |
631                              CFG4stackalign | CFG4dependent;
632 
633 enum config_flags4_t CFGY4 = CFG4nowchar_t | CFG4noemptybaseopt | CFG4adl |
634                              CFG4enumoverload | CFG4implicitfromvoid |
635                              CFG4wchar_is_long | CFG4underscore;
636 
637 // Configuration flags for HTOD executable
638 alias htod_flags_t = uint;
639 enum
640 {
641     HTODFinclude    = 1,      // -hi drill down into #include files
642     HTODFsysinclude = 2,      // -hs drill down into system #include files
643     HTODFtypedef    = 4,      // -ht drill down into typedefs
644     HTODFcdecl      = 8,      // -hc skip C declarations as comments
645 }
646 
647 // This part of the configuration is saved in the precompiled header for use
648 // in comparing to make sure it hasn't changed.
649 
650 struct Config
651 {
652     char language;              // 'C' = C, 'D' = C++
653     char[8] _version;           // = VERSION
654     char[3] exetype;            // distinguish exe types so PH
655                                 // files are distinct (= SUFFIX)
656 
657     cpu_target_t target_cpu;       // instruction selection
658     cpu_target_t target_scheduler; // instruction scheduling (normally same as selection)
659 
660     short versionint;           // intermediate file version (= VERSIONINT)
661     int defstructalign;         // struct alignment specified by command line
662     short hxversion;            // HX version number
663     symbolic_debug_t fulltypes; // format of symbolic debug info
664 
665     windows_flags_t wflags;     // flags for Windows code generation
666 
667     bool fpxmmregs;             // use XMM registers for floating point
668     ubyte inline8087;           /* 0:   emulator
669                                    1:   IEEE 754 inline 8087 code
670                                    2:   fast inline 8087 code
671                                  */
672     short memmodel;             // 0:S,X,N,F, 1:M, 2:C, 3:L, 4:V
673     objfmt_t objfmt;            // target object format
674     exefmt_t exe;               // target operating system
675 
676     config_flags_t  flags;
677     config_flags2_t flags2;
678     config_flags3_t flags3;
679     config_flags4_t flags4;
680     config_flags5_t flags5;
681 
682     htod_flags_t htodFlags;     // configuration for htod
683     ubyte ansi_c;               // strict ANSI C
684                                 // 89 for ANSI C89, 99 for ANSI C99
685     ubyte asian_char;           // 0: normal, 1: Japanese, 2: Chinese
686                                 // and Taiwanese, 3: Korean
687     uint threshold;             // data larger than threshold is assumed to
688                                 // be far (16 bit models only)
689                                 // if threshold == THRESHMAX, all data defaults
690                                 // to near
691     linkage_t linkage;          // default function call linkage
692     EHmethod ehmethod;          // exception handling method
693 
694     static uint sizeCheck();
695     unittest { assert(sizeCheck() == Config.sizeof); }
696 }
697 
698 enum THRESHMAX = 0xFFFF;
699 
700 // Language for error messages
701 enum LANG
702 {       LANGenglish,
703         LANGgerman,
704         LANGfrench,
705         LANGjapanese,
706 }
707 
708 // Configuration that is not saved in precompiled header
709 
710 struct Configv
711 {
712     ubyte addlinenumbers;       // put line number info in .OBJ file
713     ubyte verbose;              // 0: compile quietly (no messages)
714                                 // 1: show progress to DLL (default)
715                                 // 2: full verbosity
716     char* csegname;             // code segment name
717     char* deflibname;           // default library name
718     LANG language;              // message language
719     int errmax;                 // max error count
720 
721     static uint sizeCheck();
722     unittest { assert(sizeCheck() == Configv.sizeof); }
723 }
724 
725 alias reg_t = ubyte;            // register number
726 alias regm_t = uint;            // Register mask type
727 struct immed_t
728 {
729     targ_size_t[REGMAX] value;  // immediate values in registers
730     regm_t mval;                // Mask of which values in regimmed.value[] are valid
731 }
732 
733 
734 struct cse_t
735 {
736     elem*[REGMAX] value;        // expression values in registers
737     regm_t mval;                // mask of which values in value[] are valid
738     regm_t mops;                // subset of mval that contain common subs that need
739                                 // to be stored in csextab[] if they are destroyed
740 }
741 
742 struct con_t
743 {
744     cse_t cse;                  // CSEs in registers
745     immed_t immed;              // immediate values in registers
746     regm_t mvar;                // mask of register variables
747     regm_t mpvar;               // mask of SCfastpar, SCshadowreg register variables
748     regm_t indexregs;           // !=0 if more than 1 uncommitted index register
749     regm_t used;                // mask of registers used
750     regm_t params;              // mask of registers which still contain register
751                                 // function parameters
752 }
753 
754 /*********************************
755  * Bootstrap complex types.
756  */
757 
758 import ddmd.backend.bcomplex;
759 
760 /*********************************
761  * Union of all data types. Storage allocated must be the right
762  * size of the data on the TARGET, not the host.
763  */
764 
765 struct Cent
766 {
767     targ_ullong lsw;
768     targ_ullong msw;
769 }
770 
771 union eve
772 {
773         targ_char       Vchar;
774         targ_schar      Vschar;
775         targ_uchar      Vuchar;
776         targ_short      Vshort;
777         targ_ushort     Vushort;
778         targ_int        Vint;
779         targ_uns        Vuns;
780         targ_long       Vlong;
781         targ_ulong      Vulong;
782         targ_llong      Vllong;
783         targ_ullong     Vullong;
784         Cent            Vcent;
785         targ_float[4]   Vfloat4;
786         targ_double[2]  Vdouble2;
787         targ_float      Vfloat;
788         targ_double     Vdouble;
789         targ_ldouble    Vldouble;
790         Complex_f       Vcfloat;   // 2x float
791         Complex_d       Vcdouble;  // 2x double
792         Complex_ld      Vcldouble; // 2x long double
793         targ_size_t     Vpointer;
794         targ_ptrdiff_t  Vptrdiff;
795         targ_uchar      Vreg;   // register number for OPreg elems
796         struct                  // 48 bit 386 far pointer
797         {   targ_long   Voff;
798             targ_ushort Vseg;
799         }
800         struct
801         {
802             targ_size_t Voffset;// offset from symbol
803             Symbol *Vsym;       // pointer to symbol table
804             union
805             {
806                 param_t* Vtal;  // template-argument-list for SCfunctempl,
807                                 // used only to transmit it to cpp_overload()
808                 LIST* Erd;      // OPvar: reaching definitions
809             }
810         }
811         struct
812         {
813             targ_size_t Voffset2;// member pointer offset
814             Classsym* Vsym2;    // struct tag
815             elem* ethis;        // OPrelconst: 'this' for member pointer
816         }
817         struct
818         {
819             targ_size_t Voffset3;// offset from string
820             char* Vstring;      // pointer to string (OPstring or OPasm)
821             targ_size_t Vstrlen;// length of string
822         }
823         struct
824         {
825             elem* Eleft;        // left child for unary & binary nodes
826             elem* Eright;       // right child for binary nodes
827             Symbol* Edtor;      // OPctor: destructor
828         }
829         struct
830         {
831             elem* Eleft2;       // left child for OPddtor
832             void* Edecl;        // VarDeclaration being constructed
833         }                       // OPdctor,OPddtor
834 
835     static uint sizeCheck();
836     unittest { assert(sizeCheck() == eve.sizeof); }
837 }                               // variants for each type of elem
838 
839 // Symbols
840 
841 //#ifdef DEBUG
842 //#define IDSYMBOL        IDsymbol,
843 //#else
844 //#define IDSYMBOL
845 //#endif
846 
847 alias SYMFLGS = uint;
848 
849 
850 /**********************************
851  * Storage classes
852  */
853 
854 alias SC = int;
855 enum
856 {
857     SCunde,           // undefined
858     SCauto,           // automatic (stack)
859     SCstatic,         // statically allocated
860     SCthread,         // thread local
861     SCextern,         // external
862     SCregister,       // registered variable
863     SCpseudo,         // pseudo register variable
864     SCglobal,         // top level global definition
865     SCcomdat,         // initialized common block
866     SCparameter,      // function parameter
867     SCregpar,         // function register parameter
868     SCfastpar,        // function parameter passed in register
869     SCshadowreg,      // function parameter passed in register, shadowed on stack
870     SCtypedef,        // type definition
871     SCexplicit,       // explicit
872     SCmutable,        // mutable
873     SClabel,          // goto label
874     SCstruct,         // struct/class/union tag name
875     SCenum,           // enum tag name
876     SCfield,          // bit field of struct or union
877     SCconst,          // constant integer
878     SCmember,         // member of struct or union
879     SCanon,           // member of anonymous union
880     SCinline,         // for inline functions
881     SCsinline,        // for static inline functions
882     SCeinline,        // for extern inline functions
883     SCoverload,       // for overloaded function names
884     SCfriend,         // friend of a class
885     SCvirtual,        // virtual function
886     SClocstat,        // static, but local to a function
887     SCtemplate,       // class template
888     SCfunctempl,      // function template
889     SCftexpspec,      // function template explicit specialization
890     SClinkage,        // function linkage symbol
891     SCpublic,         // generate a pubdef for this
892     SCcomdef,         // uninitialized common block
893     SCbprel,          // variable at fixed offset from frame pointer
894     SCnamespace,      // namespace
895     SCalias,          // alias to another symbol
896     SCfuncalias,      // alias to another function symbol
897     SCmemalias,       // alias to base class member
898     SCstack,          // offset from stack pointer (not frame pointer)
899     SCadl,            // list of ADL symbols for overloading
900     SCMAX
901 }
902 
903 int ClassInline(int c) { return c == SCinline || c == SCsinline || c == SCeinline; }
904 //#define SymInline(s)   ClassInline((s).Sclass)
905