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