1 // Compiler implementation of the D programming language 2 // Copyright (c) 1999-2015 by Digital Mars 3 // All Rights Reserved 4 // written by Walter Bright 5 // http://www.digitalmars.com 6 // Distributed under the Boost Software License, Version 1.0. 7 // http://www.boost.org/LICENSE_1_0.txt 8 9 module ddmd.globals; 10 11 import core.stdc.stdint, core.stdc.stdio, core.stdc..string; 12 import ddmd.root.array, ddmd.root.filename, ddmd.root.outbuffer; 13 14 template xversion(string s) 15 { 16 enum xversion = mixin(`{ version (` ~ s ~ `) return true; else return false; }`)(); 17 } 18 19 enum __linux__ = xversion!`linux`; 20 enum __APPLE__ = xversion!`OSX`; 21 enum __FreeBSD__ = xversion!`FreeBSD`; 22 enum __OpenBSD__ = xversion!`OpenBSD`; 23 enum __sun = xversion!`Solaris`; 24 25 enum IN_GCC = xversion!`IN_GCC`; 26 27 enum TARGET_LINUX = xversion!`linux`; 28 enum TARGET_OSX = xversion!`OSX`; 29 enum TARGET_FREEBSD = xversion!`FreeBSD`; 30 enum TARGET_OPENBSD = xversion!`OpenBSD`; 31 enum TARGET_SOLARIS = xversion!`Solaris`; 32 enum TARGET_WINDOS = xversion!`Windows`; 33 34 enum BOUNDSCHECK : int 35 { 36 BOUNDSCHECKdefault, // initial value 37 BOUNDSCHECKoff, // never do bounds checking 38 BOUNDSCHECKon, // always do bounds checking 39 BOUNDSCHECKsafeonly, // do bounds checking only in @safe functions 40 } 41 42 alias BOUNDSCHECKdefault = BOUNDSCHECK.BOUNDSCHECKdefault; 43 alias BOUNDSCHECKoff = BOUNDSCHECK.BOUNDSCHECKoff; 44 alias BOUNDSCHECKon = BOUNDSCHECK.BOUNDSCHECKon; 45 alias BOUNDSCHECKsafeonly = BOUNDSCHECK.BOUNDSCHECKsafeonly; 46 47 // Put command line switches in here 48 struct Param 49 { 50 bool obj; // write object file 51 bool link; // perform link 52 bool dll; // generate shared dynamic library 53 bool lib; // write library file instead of object file(s) 54 bool multiobj; // break one object file into multiple ones 55 bool oneobj; // write one object file instead of multiple ones 56 bool trace; // insert profiling hooks 57 bool tracegc; // instrument calls to 'new' 58 bool verbose; // verbose compile 59 bool showColumns; // print character (column) numbers in diagnostics 60 bool vtls; // identify thread local variables 61 char vgc; // identify gc usage 62 bool vfield; // identify non-mutable field variables 63 bool vcomplex; // identify complex/imaginary type usage 64 char symdebug; // insert debug symbolic information 65 bool alwaysframe; // always emit standard stack frame 66 bool optimize; // run optimizer 67 bool map; // generate linker .map file 68 bool is64bit; // generate 64 bit code 69 bool isLP64; // generate code for LP64 70 bool isLinux; // generate code for linux 71 bool isOSX; // generate code for Mac OSX 72 bool isWindows; // generate code for Windows 73 bool isFreeBSD; // generate code for FreeBSD 74 bool isOpenBSD; // generate code for OpenBSD 75 bool isSolaris; // generate code for Solaris 76 bool mscoff; // for Win32: write COFF object files instead of OMF 77 char useDeprecated; // 0: don't allow use of deprecated features 78 // 1: silently allow use of deprecated features 79 // 2: warn about the use of deprecated features 80 bool useAssert; // generate runtime code for assert()'s 81 bool useInvariants; // generate class invariant checks 82 bool useIn; // generate precondition checks 83 bool useOut; // generate postcondition checks 84 bool stackstomp; // add stack stomping code 85 bool useSwitchError; // check for switches without a default 86 bool useUnitTests; // generate unittest code 87 bool useInline; // inline expand functions 88 bool useDIP25; // implement http://wiki.dlang.org/DIP25 89 bool release; // build release version 90 bool preservePaths; // true means don't strip path from source file 91 char warnings; // 0: disable warnings 92 // 1: warnings as errors 93 // 2: informational warnings (no errors) 94 bool pic; // generate position-independent-code for shared libs 95 bool color; // use ANSI colors in console output 96 bool cov; // generate code coverage data 97 ubyte covPercent; // 0..100 code coverage percentage required 98 bool nofloat; // code should not pull in floating point support 99 bool ignoreUnsupportedPragmas; // rather than error on them 100 bool enforcePropertySyntax; 101 bool betterC; // be a "better C" compiler; no dependency on D runtime 102 bool addMain; // add a default main() function 103 bool allInst; // generate code for all template instantiations 104 BOUNDSCHECK useArrayBounds; 105 const(char)* argv0; // program name 106 Array!(const(char)*)* imppath; // array of char*'s of where to look for import modules 107 Array!(const(char)*)* fileImppath; // array of char*'s of where to look for file import modules 108 const(char)* objdir; // .obj/.lib file output directory 109 const(char)* objname; // .obj file output name 110 const(char)* libname; // .lib file output name 111 bool doDocComments; // process embedded documentation comments 112 const(char)* docdir; // write documentation file to docdir directory 113 const(char)* docname; // write documentation file to docname 114 Array!(const(char)*)* ddocfiles; // macro include files for Ddoc 115 bool doHdrGeneration; // process embedded documentation comments 116 const(char)* hdrdir; // write 'header' file to docdir directory 117 const(char)* hdrname; // write 'header' file to docname 118 bool doJsonGeneration; // write JSON file 119 const(char)* jsonfilename; // write JSON file to jsonfilename 120 uint debuglevel; // debug level 121 Array!(const(char)*)* debugids; // debug identifiers 122 uint versionlevel; // version level 123 Array!(const(char)*)* versionids; // version identifiers 124 const(char)* defaultlibname; // default library for non-debug builds 125 const(char)* debuglibname; // default library for debug builds 126 const(char)* moduleDepsFile; // filename for deps output 127 OutBuffer* moduleDeps; // contents to be written to deps file 128 // Hidden debug switches 129 bool debugb; 130 bool debugc; 131 bool debugf; 132 bool debugr; 133 bool debugx; 134 bool debugy; 135 bool run; // run resulting executable 136 Strings runargs; // arguments for executable 137 // Linker stuff 138 Array!(const(char)*)* objfiles; 139 Array!(const(char)*)* linkswitches; 140 Array!(const(char)*)* libfiles; 141 Array!(const(char)*)* dllfiles; 142 const(char)* deffile; 143 const(char)* resfile; 144 const(char)* exefile; 145 const(char)* mapfile; 146 } 147 148 struct Compiler 149 { 150 const(char)* vendor; // Compiler backend name 151 } 152 153 alias structalign_t = uint; 154 155 enum STRUCTALIGN_DEFAULT = (cast(structalign_t)~0); 156 157 // magic value means "match whatever the underlying C compiler does" 158 // other values are all powers of 2 159 struct Global 160 { 161 const(char)* inifilename; 162 const(char)* mars_ext; 163 const(char)* obj_ext; 164 const(char)* lib_ext; 165 const(char)* dll_ext; 166 const(char)* doc_ext; // for Ddoc generated files 167 const(char)* ddoc_ext; // for Ddoc macro include files 168 const(char)* hdr_ext; // for D 'header' import files 169 const(char)* json_ext; // for JSON files 170 const(char)* map_ext; // for .map files 171 bool run_noext; // allow -run sources without extensions. 172 const(char)* copyright; 173 const(char)* written; 174 const(char)* main_d; // dummy filename for dummy main() 175 Array!(const(char)*)* path; // Array of char*'s which form the import lookup path 176 Array!(const(char)*)* filePath; // Array of char*'s which form the file import lookup path 177 const(char)* _version; 178 Compiler compiler; 179 Param params; 180 uint errors; // number of errors reported so far 181 uint warnings; // number of warnings reported so far 182 FILE* stdmsg; // where to send verbose messages 183 uint gag; // !=0 means gag reporting of errors & warnings 184 uint gaggedErrors; // number of errors reported while gagged 185 uint errorLimit; 186 187 /* Start gagging. Return the current number of gagged errors 188 */ 189 extern (C++) uint startGagging() 190 { 191 ++gag; 192 return gaggedErrors; 193 } 194 195 /* End gagging, restoring the old gagged state. 196 * Return true if errors occured while gagged. 197 */ 198 extern (C++) bool endGagging(uint oldGagged) 199 { 200 bool anyErrs = (gaggedErrors != oldGagged); 201 --gag; 202 // Restore the original state of gagged errors; set total errors 203 // to be original errors + new ungagged errors. 204 errors -= (gaggedErrors - oldGagged); 205 gaggedErrors = oldGagged; 206 return anyErrs; 207 } 208 209 /* Increment the error count to record that an error 210 * has occured in the current context. An error message 211 * may or may not have been printed. 212 */ 213 extern (C++) void increaseErrorCount() 214 { 215 if (gag) 216 ++gaggedErrors; 217 ++errors; 218 } 219 220 extern (C++) void _init() 221 { 222 inifilename = null; 223 mars_ext = "d"; 224 hdr_ext = "di"; 225 doc_ext = "html"; 226 ddoc_ext = "ddoc"; 227 json_ext = "json"; 228 map_ext = "map"; 229 static if (TARGET_WINDOS) 230 { 231 obj_ext = "obj"; 232 } 233 else static if (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS) 234 { 235 obj_ext = "o"; 236 } 237 else 238 { 239 static assert(0, "fix this"); 240 } 241 static if (TARGET_WINDOS) 242 { 243 lib_ext = "lib"; 244 } 245 else static if (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS) 246 { 247 lib_ext = "a"; 248 } 249 else 250 { 251 static assert(0, "fix this"); 252 } 253 static if (TARGET_WINDOS) 254 { 255 dll_ext = "dll"; 256 } 257 else static if (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS) 258 { 259 dll_ext = "so"; 260 } 261 else static if (TARGET_OSX) 262 { 263 dll_ext = "dylib"; 264 } 265 else 266 { 267 static assert(0, "fix this"); 268 } 269 static if (TARGET_WINDOS) 270 { 271 run_noext = false; 272 } 273 else static if (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS) 274 { 275 // Allow 'script' D source files to have no extension. 276 run_noext = true; 277 } 278 else 279 { 280 static assert(0, "fix this"); 281 } 282 copyright = "Copyright (c) 1999-2015 by Digital Mars"; 283 written = "written by Walter Bright"; 284 _version = "v2.068"; 285 compiler.vendor = "Digital Mars D"; 286 stdmsg = stdout; 287 main_d = "__main.d"; 288 memset(¶ms, 0, Param.sizeof); 289 errorLimit = 20; 290 } 291 } 292 293 // Because int64_t and friends may be any integral type of the 294 // correct size, we have to explicitly ask for the correct 295 // integer type to get the correct mangling with ddmd 296 297 // Be careful not to care about sign when using dinteger_t 298 // use this instead of integer_t to 299 // avoid conflicts with system #include's 300 alias dinteger_t = ulong; 301 // Signed and unsigned variants 302 alias sinteger_t = long; 303 alias uinteger_t = ulong; 304 305 alias d_int8 = int8_t; 306 alias d_uns8 = uint8_t; 307 alias d_int16 = int16_t; 308 alias d_uns16 = uint16_t; 309 alias d_int32 = int32_t; 310 alias d_uns32 = uint32_t; 311 alias d_int64 = int64_t; 312 alias d_uns64 = uint64_t; 313 alias d_float32 = float; 314 alias d_float64 = double; 315 alias d_float80 = real; 316 alias d_char = d_uns8; 317 alias d_wchar = d_uns16; 318 alias d_dchar = d_uns32; 319 alias real_t = real; 320 321 // file location 322 struct Loc 323 { 324 const(char)* filename; 325 uint linnum; 326 uint charnum; 327 328 extern (D) this(const(char)* filename, uint linnum, uint charnum) 329 { 330 this.linnum = linnum; 331 this.charnum = charnum; 332 this.filename = filename; 333 } 334 335 extern (C++) char* toChars() 336 { 337 OutBuffer buf; 338 if (filename) 339 { 340 buf.printf("%s", filename); 341 } 342 if (linnum) 343 { 344 buf.printf("(%d", linnum); 345 if (global.params.showColumns && charnum) 346 buf.printf(",%d", charnum); 347 buf.writeByte(')'); 348 } 349 return buf.extractString(); 350 } 351 352 extern (C++) bool equals(ref const(Loc) loc) 353 { 354 return (!global.params.showColumns || charnum == loc.charnum) && linnum == loc.linnum && FileName.equals(filename, loc.filename); 355 } 356 } 357 358 enum LINK : int 359 { 360 LINKdefault, 361 LINKd, 362 LINKc, 363 LINKcpp, 364 LINKwindows, 365 LINKpascal, 366 } 367 368 alias LINKdefault = LINK.LINKdefault; 369 alias LINKd = LINK.LINKd; 370 alias LINKc = LINK.LINKc; 371 alias LINKcpp = LINK.LINKcpp; 372 alias LINKwindows = LINK.LINKwindows; 373 alias LINKpascal = LINK.LINKpascal; 374 375 enum DYNCAST : int 376 { 377 DYNCAST_OBJECT, 378 DYNCAST_EXPRESSION, 379 DYNCAST_DSYMBOL, 380 DYNCAST_TYPE, 381 DYNCAST_IDENTIFIER, 382 DYNCAST_TUPLE, 383 DYNCAST_PARAMETER, 384 } 385 386 alias DYNCAST_OBJECT = DYNCAST.DYNCAST_OBJECT; 387 alias DYNCAST_EXPRESSION = DYNCAST.DYNCAST_EXPRESSION; 388 alias DYNCAST_DSYMBOL = DYNCAST.DYNCAST_DSYMBOL; 389 alias DYNCAST_TYPE = DYNCAST.DYNCAST_TYPE; 390 alias DYNCAST_IDENTIFIER = DYNCAST.DYNCAST_IDENTIFIER; 391 alias DYNCAST_TUPLE = DYNCAST.DYNCAST_TUPLE; 392 alias DYNCAST_PARAMETER = DYNCAST.DYNCAST_PARAMETER; 393 394 enum MATCH : int 395 { 396 MATCHnomatch, // no match 397 MATCHconvert, // match with conversions 398 MATCHconst, // match with conversion to const 399 MATCHexact, // exact match 400 } 401 402 alias MATCHnomatch = MATCH.MATCHnomatch; 403 alias MATCHconvert = MATCH.MATCHconvert; 404 alias MATCHconst = MATCH.MATCHconst; 405 alias MATCHexact = MATCH.MATCHexact; 406 407 enum PINLINE : int 408 { 409 PINLINEdefault, // as specified on the command line 410 PINLINEnever, // never inline 411 PINLINEalways, // always inline 412 } 413 414 alias PINLINEdefault = PINLINE.PINLINEdefault; 415 alias PINLINEnever = PINLINE.PINLINEnever; 416 alias PINLINEalways = PINLINE.PINLINEalways; 417 418 alias StorageClass = uinteger_t; 419 420 extern (C++) __gshared Global global;