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