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 365 366 version (MARS) 367 { 368 } 369 else 370 { 371 version (_WINDLL) 372 { 373 /* We reference the required Windows-1252 encoding of the copyright symbol 374 by escaping its character code (0xA9) rather than directly embedding it in 375 the source text. The character code is invalid in UTF-8, which causes some 376 of our source-code preprocessing tools (e.g. tolf) to choke. 377 */ 378 enum COPYRIGHT_SYMBOL = "\xA9"; 379 enum COPYRIGHT = "Copyright " ~ COPYRIGHT_SYMBOL ~ " 2001 Digital Mars"; 380 } 381 else 382 { 383 debug 384 { 385 enum COPYRIGHT = "Copyright (C) Digital Mars 2000-2019. All Rights Reserved. 386 Written by Walter Bright 387 *****BETA TEST VERSION*****"; 388 } 389 else 390 { 391 version (linux) 392 { 393 enum COPYRIGHT = "Copyright (C) Digital Mars 2000-2019. All Rights Reserved. 394 Written by Walter Bright, Linux version by Pat Nelson"; 395 } 396 else 397 { 398 enum COPYRIGHT = "Copyright (C) Digital Mars 2000-2019. All Rights Reserved. 399 Written by Walter Bright"; 400 } 401 } 402 } 403 } 404 405 /********************************** 406 * Configuration 407 */ 408 409 /* Linkage type */ 410 enum linkage_t 411 { 412 LINK_C, /* C style */ 413 LINK_CPP, /* C++ style */ 414 LINK_PASCAL, /* Pascal style */ 415 LINK_FORTRAN, 416 LINK_SYSCALL, 417 LINK_STDCALL, 418 LINK_D, // D code 419 LINK_MAXDIM /* array dimension */ 420 } 421 422 /********************************** 423 * Exception handling method 424 */ 425 426 enum EHmethod 427 { 428 EH_NONE, // no exception handling 429 EH_SEH, // SEH __try, __except, __finally only 430 EH_WIN32, // Win32 SEH 431 EH_WIN64, // Win64 SEH (not supported yet) 432 EH_DM, // Digital Mars method 433 EH_DWARF, // Dwarf method 434 } 435 436 // CPU target 437 alias cpu_target_t = byte; 438 enum 439 { 440 TARGET_8086 = 0, 441 TARGET_80286 = 2, 442 TARGET_80386 = 3, 443 TARGET_80486 = 4, 444 TARGET_Pentium = 5, 445 TARGET_PentiumMMX = 6, 446 TARGET_PentiumPro = 7, 447 TARGET_PentiumII = 8, 448 } 449 450 // Symbolic debug info 451 alias symbolic_debug_t = byte; 452 enum 453 { 454 CVNONE = 0, // No symbolic info 455 CVOLD = 1, // Codeview 1 symbolic info 456 CV4 = 2, // Codeview 4 symbolic info 457 CVSYM = 3, // Symantec format 458 CVTDB = 4, // Symantec format written to file 459 CVDWARF_C = 5, // Dwarf in C format 460 CVDWARF_D = 6, // Dwarf in D format 461 CVSTABS = 7, // Elf Stabs in C format 462 CV8 = 8, // Codeview 8 symbolic info 463 } 464 465 // Windows code gen flags 466 alias windows_flags_t = uint; 467 enum 468 { 469 WFwindows = 1, // generating code for Windows app or DLL 470 WFdll = 2, // generating code for Windows DLL 471 WFincbp = 4, // mark far stack frame with inc BP / dec BP 472 WFloadds = 8, // assume __loadds for all functions 473 WFexpdef = 0x10, // generate export definition records for 474 // exported functions 475 WFss = 0x20, // load DS from SS 476 WFreduced = 0x40, // skip DS load for non-exported functions 477 WFdgroup = 0x80, // load DS from DGROUP 478 WFexport = 0x100, // assume __export for all far functions 479 WFds = 0x200, // load DS from DS 480 WFmacros = 0x400, // define predefined windows macros 481 WFssneds = 0x800, // SS != DS 482 WFthunk = 0x1000, // use fixups instead of direct ref to CS 483 WFsaveds = 0x2000, // use push/pop DS for far functions 484 WFdsnedgroup = 0x4000, // DS != DGROUP 485 WFexe = 0x8000, // generating code for Windows EXE 486 } 487 488 // Object file format 489 alias objfmt_t = uint; 490 enum 491 { 492 OBJ_OMF = 1, 493 OBJ_MSCOFF = 2, 494 OBJ_ELF = 4, 495 OBJ_MACH = 8, 496 } 497 498 // Executable file format 499 alias exefmt_t = uint; 500 enum 501 { 502 EX_DOSX = 1, // DOSX 386 program 503 EX_ZPM = 2, // ZPM 286 program 504 EX_RATIONAL = 4, // RATIONAL 286 program 505 EX_PHARLAP = 8, // PHARLAP 386 program 506 EX_COM = 0x10, // MSDOS .COM program 507 // EX_WIN16 = 0x20, // Windows 3.x 16 bit program (no longer supported) 508 EX_OS2 = 0x40, // OS/2 2.0 32 bit program 509 EX_OS1 = 0x80, // OS/2 1.x 16 bit program 510 EX_WIN32 = 0x100, 511 EX_MZ = 0x200, // MSDOS real mode program 512 EX_XENIX = 0x400, 513 EX_SCOUNIX = 0x800, 514 EX_UNIXSVR4 = 0x1000, 515 EX_LINUX = 0x2000, 516 EX_WIN64 = 0x4000, // AMD64 and Windows (64 bit mode) 517 EX_LINUX64 = 0x8000, // AMD64 and Linux (64 bit mode) 518 EX_OSX = 0x10000, 519 EX_OSX64 = 0x20000, 520 EX_FREEBSD = 0x40000, 521 EX_FREEBSD64 = 0x80000, 522 EX_SOLARIS = 0x100000, 523 EX_SOLARIS64 = 0x200000, 524 EX_OPENBSD = 0x400000, 525 EX_OPENBSD64 = 0x800000, 526 EX_DRAGONFLYBSD64 = 0x1000000, 527 } 528 529 530 // All flat memory models (no segment registers) 531 enum exefmt_t EX_flat = EX_OS2 | EX_WIN32 | EX_LINUX | EX_WIN64 | EX_LINUX64 | 532 EX_OSX | EX_OSX64 | EX_FREEBSD | EX_FREEBSD64 | 533 EX_OPENBSD | EX_OPENBSD64 | 534 EX_DRAGONFLYBSD64 | 535 EX_SOLARIS | EX_SOLARIS64; 536 537 // All DOS executable types 538 enum exefmt_t EX_dos = EX_DOSX | EX_ZPM | EX_RATIONAL | EX_PHARLAP | 539 EX_COM | EX_MZ /*| EX_WIN16*/; 540 541 alias config_flags_t = uint; 542 enum 543 { 544 CFGuchar = 1, // chars are unsigned 545 CFGsegs = 2, // new code seg for each far func 546 CFGtrace = 4, // output trace functions 547 CFGglobal = 8, // make all static functions global 548 CFGstack = 0x10, // add stack overflow checking 549 CFGalwaysframe = 0x20, // always generate stack frame 550 CFGnoebp = 0x40, // do not use EBP as general purpose register 551 CFGromable = 0x80, // put switch tables in code segment 552 CFGeasyomf = 0x100, // generate Pharlap Easy-OMF format 553 CFGfarvtbls = 0x200, // store vtables in far segments 554 CFGnoinlines = 0x400, // do not inline functions 555 CFGnowarning = 0x800, // disable warnings 556 } 557 558 alias config_flags2_t = uint; 559 enum 560 { 561 CFG2comdat = 1, // use initialized common blocks 562 CFG2nodeflib = 2, // no default library imbedded in OBJ file 563 CFG2browse = 4, // generate browse records 564 CFG2dyntyping = 8, // generate dynamic typing information 565 CFG2fulltypes = 0x10, // don't optimize CV4 class info 566 CFG2warniserr = 0x20, // treat warnings as errors 567 CFG2phauto = 0x40, // automatic precompiled headers 568 CFG2phuse = 0x80, // use precompiled headers 569 CFG2phgen = 0x100, // generate precompiled header 570 CFG2once = 0x200, // only include header files once 571 CFG2hdrdebug = 0x400, // generate debug info for header 572 CFG2phautoy = 0x800, // fast build precompiled headers 573 CFG2noobj = 0x1000, // we are not generating a .OBJ file 574 CFG2noerrmax = 0x2000, // no error count maximum 575 CFG2expand = 0x4000, // expanded output to list file 576 CFG2stomp = 0x8000, // enable stack stomping code 577 CFG2gms = 0x10000, // optimize debug symbols for microsoft debuggers 578 } 579 580 alias config_flags3_t = uint; 581 enum 582 { 583 CFG3ju = 1, // char == unsigned char 584 CFG3eh = 2, // generate exception handling stuff 585 CFG3strcod = 4, // strings are placed in code segment 586 CFG3eseqds = 8, // ES == DS at all times 587 CFG3ptrchk = 0x10, // generate pointer validation code 588 CFG3strictproto = 0x20, // strict prototyping 589 CFG3autoproto = 0x40, // auto prototyping 590 CFG3rtti = 0x80, // add RTTI support 591 CFG3relax = 0x100, // relaxed type checking (C only) 592 CFG3cpp = 0x200, // C++ compile 593 CFG3igninc = 0x400, // ignore standard include directory 594 CFG3mars = 0x800, // use mars libs and headers 595 CFG3nofar = 0x1000, // ignore __far and __huge keywords 596 CFG3noline = 0x2000, // do not output #line directives 597 CFG3comment = 0x4000, // leave comments in preprocessed output 598 CFG3cppcomment = 0x8000, // allow C++ style comments 599 CFG3wkfloat = 0x10000, // make floating point references weak externs 600 CFG3digraphs = 0x20000, // support ANSI C++ digraphs 601 CFG3semirelax = 0x40000, // moderate relaxed type checking (non-Windows targets) 602 CFG3pic = 0x80000, // position independent code 603 CFG3pie = 0x10_0000, // position independent executable (CFG3pic also set) 604 } 605 606 alias config_flags4_t = uint; 607 enum 608 { 609 CFG4speed = 1, // optimized for speed 610 CFG4space = 2, // optimized for space 611 CFG4allcomdat = 4, // place all functions in COMDATs 612 CFG4fastfloat = 8, // fast floating point (-ff) 613 CFG4fdivcall = 0x10, // make function call for FDIV opcodes 614 CFG4tempinst = 0x20, // instantiate templates for undefined functions 615 CFG4oldstdmangle = 0x40, // do stdcall mangling without @ 616 CFG4pascal = 0x80, // default to pascal linkage 617 CFG4stdcall = 0x100, // default to std calling convention 618 CFG4cacheph = 0x200, // cache precompiled headers in memory 619 CFG4alternate = 0x400, // if alternate digraph tokens 620 CFG4bool = 0x800, // support 'bool' as basic type 621 CFG4wchar_t = 0x1000, // support 'wchar_t' as basic type 622 CFG4notempexp = 0x2000, // no instantiation of template functions 623 CFG4anew = 0x4000, // allow operator new[] and delete[] overloading 624 CFG4oldtmangle = 0x8000, // use old template name mangling 625 CFG4dllrtl = 0x10000, // link with DLL RTL 626 CFG4noemptybaseopt = 0x20000, // turn off empty base class optimization 627 CFG4nowchar_t = 0x40000, // use unsigned short name mangling for wchar_t 628 CFG4forscope = 0x80000, // new C++ for scoping rules 629 CFG4warnccast = 0x100000, // warn about C style casts 630 CFG4adl = 0x200000, // argument dependent lookup 631 CFG4enumoverload = 0x400000, // enum overloading 632 CFG4implicitfromvoid = 0x800000, // allow implicit cast from void* to T* 633 CFG4dependent = 0x1000000, // dependent / non-dependent lookup 634 CFG4wchar_is_long = 0x2000000, // wchar_t is 4 bytes 635 CFG4underscore = 0x4000000, // prepend _ for C mangling 636 } 637 638 enum config_flags4_t CFG4optimized = CFG4speed | CFG4space; 639 enum config_flags4_t CFG4stackalign = CFG4speed; // align stack to 8 bytes 640 641 alias config_flags5_t = uint; 642 enum 643 { 644 CFG5debug = 1, // compile in __debug code 645 CFG5in = 2, // compile in __in code 646 CFG5out = 4, // compile in __out code 647 CFG5invariant = 8, // compile in __invariant code 648 } 649 650 /* CFGX: flags ignored in precompiled headers 651 * CFGY: flags copied from precompiled headers into current config 652 */ 653 enum config_flags_t CFGX = CFGnowarning; 654 enum config_flags2_t CFGX2 = CFG2warniserr | CFG2phuse | CFG2phgen | CFG2phauto | 655 CFG2once | CFG2hdrdebug | CFG2noobj | CFG2noerrmax | 656 CFG2expand | CFG2nodeflib | CFG2stomp | CFG2gms; 657 enum config_flags3_t CFGX3 = CFG3strcod | CFG3ptrchk; 658 enum config_flags4_t CFGX4 = CFG4optimized | CFG4fastfloat | CFG4fdivcall | 659 CFG4tempinst | CFG4cacheph | CFG4notempexp | 660 CFG4stackalign | CFG4dependent; 661 662 enum config_flags4_t CFGY4 = CFG4nowchar_t | CFG4noemptybaseopt | CFG4adl | 663 CFG4enumoverload | CFG4implicitfromvoid | 664 CFG4wchar_is_long | CFG4underscore; 665 666 // Configuration flags for HTOD executable 667 alias htod_flags_t = uint; 668 enum 669 { 670 HTODFinclude = 1, // -hi drill down into #include files 671 HTODFsysinclude = 2, // -hs drill down into system #include files 672 HTODFtypedef = 4, // -ht drill down into typedefs 673 HTODFcdecl = 8, // -hc skip C declarations as comments 674 } 675 676 // This part of the configuration is saved in the precompiled header for use 677 // in comparing to make sure it hasn't changed. 678 679 struct Config 680 { 681 char language; // 'C' = C, 'D' = C++ 682 string _version; /// Compiler version 683 char[3] exetype; // distinguish exe types so PH 684 // files are distinct (= SUFFIX) 685 686 cpu_target_t target_cpu; // instruction selection 687 cpu_target_t target_scheduler; // instruction scheduling (normally same as selection) 688 689 short versionint; // intermediate file version (= VERSIONINT) 690 int defstructalign; // struct alignment specified by command line 691 short hxversion; // HX version number 692 symbolic_debug_t fulltypes; // format of symbolic debug info 693 694 windows_flags_t wflags; // flags for Windows code generation 695 696 bool fpxmmregs; // use XMM registers for floating point 697 ubyte avx; // use AVX instruction set (0, 1, 2) 698 ubyte inline8087; /* 0: emulator 699 1: IEEE 754 inline 8087 code 700 2: fast inline 8087 code 701 */ 702 short memmodel; // 0:S,X,N,F, 1:M, 2:C, 3:L, 4:V 703 objfmt_t objfmt; // target object format 704 exefmt_t exe; // target operating system 705 706 config_flags_t flags; 707 config_flags2_t flags2; 708 config_flags3_t flags3; 709 config_flags4_t flags4; 710 config_flags5_t flags5; 711 712 htod_flags_t htodFlags; // configuration for htod 713 ubyte ansi_c; // strict ANSI C 714 // 89 for ANSI C89, 99 for ANSI C99 715 ubyte asian_char; // 0: normal, 1: Japanese, 2: Chinese 716 // and Taiwanese, 3: Korean 717 uint threshold; // data larger than threshold is assumed to 718 // be far (16 bit models only) 719 // if threshold == THRESHMAX, all data defaults 720 // to near 721 linkage_t linkage; // default function call linkage 722 EHmethod ehmethod; // exception handling method 723 bool useModuleInfo; // implement ModuleInfo 724 bool useTypeInfo; // implement TypeInfo 725 bool useExceptions; // implement exception handling 726 } 727 728 enum THRESHMAX = 0xFFFF; 729 730 // Language for error messages 731 enum LANG 732 { LANGenglish, 733 LANGgerman, 734 LANGfrench, 735 LANGjapanese, 736 } 737 738 // Configuration that is not saved in precompiled header 739 740 struct Configv 741 { 742 ubyte addlinenumbers; // put line number info in .OBJ file 743 ubyte verbose; // 0: compile quietly (no messages) 744 // 1: show progress to DLL (default) 745 // 2: full verbosity 746 char* csegname; // code segment name 747 char* deflibname; // default library name 748 LANG language; // message language 749 int errmax; // max error count 750 } 751 752 alias reg_t = ubyte; // register number 753 alias regm_t = uint; // Register mask type 754 struct immed_t 755 { 756 targ_size_t[REGMAX] value; // immediate values in registers 757 regm_t mval; // Mask of which values in regimmed.value[] are valid 758 } 759 760 761 struct cse_t 762 { 763 elem*[REGMAX] value; // expression values in registers 764 regm_t mval; // mask of which values in value[] are valid 765 regm_t mops; // subset of mval that contain common subs that need 766 // to be stored in csextab[] if they are destroyed 767 } 768 769 struct con_t 770 { 771 cse_t cse; // CSEs in registers 772 immed_t immed; // immediate values in registers 773 regm_t mvar; // mask of register variables 774 regm_t mpvar; // mask of SCfastpar, SCshadowreg register variables 775 regm_t indexregs; // !=0 if more than 1 uncommitted index register 776 regm_t used; // mask of registers used 777 regm_t params; // mask of registers which still contain register 778 // function parameters 779 } 780 781 /********************************* 782 * Bootstrap complex types. 783 */ 784 785 import dmd.backend.bcomplex; 786 787 /********************************* 788 * Union of all data types. Storage allocated must be the right 789 * size of the data on the TARGET, not the host. 790 */ 791 792 struct Cent 793 { 794 targ_ullong lsw; 795 targ_ullong msw; 796 } 797 798 union eve 799 { 800 targ_char Vchar; 801 targ_schar Vschar; 802 targ_uchar Vuchar; 803 targ_short Vshort; 804 targ_ushort Vushort; 805 targ_int Vint; 806 targ_uns Vuns; 807 targ_long Vlong; 808 targ_ulong Vulong; 809 targ_llong Vllong; 810 targ_ullong Vullong; 811 Cent Vcent; 812 targ_float Vfloat; 813 targ_double Vdouble; 814 targ_ldouble Vldouble; 815 Complex_f Vcfloat; // 2x float 816 Complex_d Vcdouble; // 2x double 817 Complex_ld Vcldouble; // 2x long double 818 targ_size_t Vpointer; 819 targ_ptrdiff_t Vptrdiff; 820 targ_uchar Vreg; // register number for OPreg elems 821 822 // 16 byte vector types 823 targ_float[4] Vfloat4; // float[4] 824 targ_double[2] Vdouble2; // double[2] 825 targ_schar[16] Vschar16; // byte[16] 826 targ_uchar[16] Vuchar16; // ubyte[16] 827 targ_short[8] Vshort8; // short[8] 828 targ_ushort[8] Vushort8; // ushort[8] 829 targ_long[4] Vlong4; // int[4] 830 targ_ulong[4] Vulong4; // uint[4] 831 targ_llong[2] Vllong2; // long[2] 832 targ_ullong[2] Vullong2; // ulong[2] 833 834 // 32 byte vector types 835 targ_float[8] Vfloat8; // float[8] 836 targ_double[4] Vdouble4; // double[4] 837 targ_schar[32] Vschar32; // byte[32] 838 targ_uchar[32] Vuchar32; // ubyte[32] 839 targ_short[16] Vshort16; // short[16] 840 targ_ushort[16] Vushort16; // ushort[16] 841 targ_long[8] Vlong8; // int[8] 842 targ_ulong[8] Vulong8; // uint[8] 843 targ_llong[4] Vllong4; // long[4] 844 targ_ullong[4] Vullong4; // ulong[4] 845 846 struct // 48 bit 386 far pointer 847 { targ_long Voff; 848 targ_ushort Vseg; 849 } 850 struct 851 { 852 targ_size_t Voffset;// offset from symbol 853 Symbol *Vsym; // pointer to symbol table 854 union 855 { 856 param_t* Vtal; // template-argument-list for SCfunctempl, 857 // used only to transmit it to cpp_overload() 858 LIST* Erd; // OPvar: reaching definitions 859 } 860 } 861 struct 862 { 863 targ_size_t Voffset2;// member pointer offset 864 Classsym* Vsym2; // struct tag 865 elem* ethis; // OPrelconst: 'this' for member pointer 866 } 867 struct 868 { 869 targ_size_t Voffset3;// offset from string 870 char* Vstring; // pointer to string (OPstring or OPasm) 871 targ_size_t Vstrlen;// length of string 872 } 873 struct 874 { 875 elem* E1; // left child for unary & binary nodes 876 elem* E2; // right child for binary nodes 877 Symbol* Edtor; // OPctor: destructor 878 } 879 struct 880 { 881 elem* Eleft2; // left child for OPddtor 882 void* Edecl; // VarDeclaration being constructed 883 } // OPdctor,OPddtor 884 } // variants for each type of elem 885 886 // Symbols 887 888 //#ifdef DEBUG 889 //#define IDSYMBOL IDsymbol, 890 //#else 891 //#define IDSYMBOL 892 //#endif 893 894 alias SYMFLGS = uint; 895 896 897 /********************************** 898 * Storage classes 899 */ 900 901 alias SC = int; 902 enum 903 { 904 SCunde, // undefined 905 SCauto, // automatic (stack) 906 SCstatic, // statically allocated 907 SCthread, // thread local 908 SCextern, // external 909 SCregister, // registered variable 910 SCpseudo, // pseudo register variable 911 SCglobal, // top level global definition 912 SCcomdat, // initialized common block 913 SCparameter, // function parameter 914 SCregpar, // function register parameter 915 SCfastpar, // function parameter passed in register 916 SCshadowreg, // function parameter passed in register, shadowed on stack 917 SCtypedef, // type definition 918 SCexplicit, // explicit 919 SCmutable, // mutable 920 SClabel, // goto label 921 SCstruct, // struct/class/union tag name 922 SCenum, // enum tag name 923 SCfield, // bit field of struct or union 924 SCconst, // constant integer 925 SCmember, // member of struct or union 926 SCanon, // member of anonymous union 927 SCinline, // for inline functions 928 SCsinline, // for static inline functions 929 SCeinline, // for extern inline functions 930 SCoverload, // for overloaded function names 931 SCfriend, // friend of a class 932 SCvirtual, // virtual function 933 SClocstat, // static, but local to a function 934 SCtemplate, // class template 935 SCfunctempl, // function template 936 SCftexpspec, // function template explicit specialization 937 SClinkage, // function linkage symbol 938 SCpublic, // generate a pubdef for this 939 SCcomdef, // uninitialized common block 940 SCbprel, // variable at fixed offset from frame pointer 941 SCnamespace, // namespace 942 SCalias, // alias to another symbol 943 SCfuncalias, // alias to another function symbol 944 SCmemalias, // alias to base class member 945 SCstack, // offset from stack pointer (not frame pointer) 946 SCadl, // list of ADL symbols for overloading 947 SCMAX 948 } 949 950 int ClassInline(int c) { return c == SCinline || c == SCsinline || c == SCeinline; } 951 int SymInline(Symbol* s) { return ClassInline(s.Sclass); } 952