d: Merge dmd, druntime d8e3976a58, phobos 7a6e95688
[official-gcc.git] / gcc / d / dmd / globals.d
blobb60a3f8cad155e2356265566966c137f21f6b25a
1 /**
2 * Stores command line options and contains other miscellaneous declarations.
4 * Copyright: Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
6 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/globals.d, _globals.d)
8 * Documentation: https://dlang.org/phobos/dmd_globals.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/globals.d
12 module dmd.globals;
14 import core.stdc.stdio;
15 import core.stdc.stdint;
16 import core.stdc.string;
18 import dmd.root.array;
19 import dmd.root.filename;
20 import dmd.common.outbuffer;
21 import dmd.errorsink;
22 import dmd.errors;
23 import dmd.file_manager;
24 import dmd.identifier;
25 import dmd.location;
26 import dmd.lexer : CompileEnv;
27 import dmd.utils;
29 version (IN_GCC) {}
30 else version (IN_LLVM) {}
31 else version = MARS;
33 /// Defines a setting for how compiler warnings and deprecations are handled
34 enum DiagnosticReporting : ubyte
36 error, /// generate an error
37 inform, /// generate a warning
38 off, /// disable diagnostic
41 /// In which context checks for assertions, contracts, bounds checks etc. are enabled
42 enum CHECKENABLE : ubyte
44 _default, /// initial value
45 off, /// never do checking
46 on, /// always do checking
47 safeonly, /// do checking only in @safe functions
50 /// What should happend when an assertion fails
51 enum CHECKACTION : ubyte
53 D, /// call D assert on failure
54 C, /// call C assert on failure
55 halt, /// cause program halt on failure
56 context, /// call D assert with the error context on failure
59 /**
60 Each flag represents a field that can be included in the JSON output.
62 NOTE: set type to uint so its size matches C++ unsigned type
64 enum JsonFieldFlags : uint
66 none = 0,
67 compilerInfo = (1 << 0),
68 buildInfo = (1 << 1),
69 modules = (1 << 2),
70 semantics = (1 << 3),
73 /// Version of C++ standard to support
74 enum CppStdRevision : uint
76 cpp98 = 1997_11,
77 cpp11 = 2011_03,
78 cpp14 = 2014_02,
79 cpp17 = 2017_03,
80 cpp20 = 2020_02,
83 /// Trivalent boolean to represent the state of a `revert`able change
84 enum FeatureState : ubyte
86 default_ = 0, /// Not specified by the user
87 disabled = 1, /// Specified as `-revert=`
88 enabled = 2, /// Specified as `-preview=`
91 extern(C++) struct Output
93 bool doOutput; // Output is enabled
94 bool fullOutput; // Generate comments for hidden declarations (for -HC),
95 // and don't strip the bodies of plain (non-template) functions (for -H)
97 const(char)[] dir; // write to directory 'dir'
98 const(char)[] name; // write to file 'name'
99 Array!(const(char)*) files; // Other files associated with this output,
100 // e.g. macro include files for Ddoc, dependencies for makedeps
101 OutBuffer* buffer; // if this output is buffered, this is the buffer
102 int bufferLines; // number of lines written to the buffer
105 /// Command line state related to printing usage about other switches
106 extern(C++) struct Help
108 bool manual; // open browser on compiler manual
109 bool usage; // print usage and exit
110 // print help of switch:
111 bool mcpu; // -mcpu
112 bool transition; // -transition
113 bool check; // -check
114 bool checkAction; // -checkaction
115 bool revert; // -revert
116 bool preview; // -preview
117 bool externStd; // -extern-std
118 bool hc; // -HC
121 extern(C++) struct Verbose
123 bool verbose; // verbose compile
124 bool showColumns; // print character (column) numbers in diagnostics
125 bool tls; // identify thread local variables
126 bool templates; // collect and list statistics on template instantiations
127 // collect and list statistics on template instantiations origins.
128 // TODO: make this an enum when we want to list other kinds of instances
129 bool templatesListInstances;
130 bool gc; // identify gc usage
131 bool field; // identify non-mutable field variables
132 bool complex = true; // identify complex/imaginary type usage
133 bool vin; // identify 'in' parameters
134 bool showGaggedErrors; // print gagged errors anyway
135 bool printErrorContext; // print errors with the error context (the error line in the source file)
136 bool logo; // print compiler logo
137 bool color; // use ANSI colors in console output
138 bool cov; // generate code coverage data
139 MessageStyle messageStyle = MessageStyle.digitalmars; // style of file/line annotations on messages
140 uint errorLimit = 20;
141 uint errorSupplementLimit = 6; // Limit the number of supplemental messages for each error (0 means unlimited)
143 uint errorSupplementCount()
145 if (verbose)
146 return uint.max;
147 if (errorSupplementLimit == 0)
148 return uint.max;
149 return errorSupplementLimit;
153 /// Put command line switches in here
154 extern (C++) struct Param
156 bool obj = true; // write object file
157 bool multiobj; // break one object file into multiple ones
158 bool trace; // insert profiling hooks
159 bool tracegc; // instrument calls to 'new'
160 bool vcg_ast; // write-out codegen-ast
161 DiagnosticReporting useDeprecated = DiagnosticReporting.inform; // how use of deprecated features are handled
162 bool useUnitTests; // generate unittest code
163 bool useInline = false; // inline expand functions
164 bool release; // build release version
165 bool preservePaths; // true means don't strip path from source file
166 DiagnosticReporting warnings = DiagnosticReporting.off; // how compiler warnings are handled
167 bool cov; // generate code coverage data
168 ubyte covPercent; // 0..100 code coverage percentage required
169 bool ctfe_cov = false; // generate coverage data for ctfe
170 bool ignoreUnsupportedPragmas = true; // rather than error on them
171 bool useModuleInfo = true; // generate runtime module information
172 bool useTypeInfo = true; // generate runtime type information
173 bool useExceptions = true; // support exception handling
174 bool useGC = true; // support features that require the D runtime GC
175 bool betterC; // be a "better C" compiler; no dependency on D runtime
176 bool addMain; // add a default main() function
177 bool allInst; // generate code for all template instantiations
178 bool bitfields; // support C style bit fields
180 CppStdRevision cplusplus = CppStdRevision.cpp11; // version of C++ standard to support
182 Help help;
183 Verbose v;
185 // Options for `-preview=/-revert=`
186 FeatureState useDIP25 = FeatureState.enabled; // implement https://wiki.dlang.org/DIP25
187 FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
188 bool ehnogc; // use @nogc exception handling
189 bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
190 FeatureState fieldwise; // do struct equality testing field-wise rather than by memcmp()
191 bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes
192 FeatureState rvalueRefParam; // allow rvalues to be arguments to ref parameters
193 // https://dconf.org/2019/talks/alexandrescu.html
194 // https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
195 // https://digitalmars.com/d/archives/digitalmars/D/Binding_rvalues_to_ref_parameters_redux_325087.html
196 // Implementation: https://github.com/dlang/dmd/pull/9817
197 FeatureState noSharedAccess; // read/write access to shared memory objects
198 bool previewIn; // `in` means `[ref] scope const`, accepts rvalues
199 bool inclusiveInContracts; // 'in' contracts of overridden methods must be a superset of parent contract
200 bool shortenedMethods = true; // allow => in normal function declarations
201 bool fixImmutableConv; // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070
202 bool fix16997 = true; // fix integral promotions for unary + - ~ operators
203 // https://issues.dlang.org/show_bug.cgi?id=16997
204 FeatureState dtorFields; // destruct fields of partially constructed objects
205 // https://issues.dlang.org/show_bug.cgi?id=14246
206 FeatureState systemVariables; // limit access to variables marked @system from @safe code
208 CHECKENABLE useInvariants = CHECKENABLE._default; // generate class invariant checks
209 CHECKENABLE useIn = CHECKENABLE._default; // generate precondition checks
210 CHECKENABLE useOut = CHECKENABLE._default; // generate postcondition checks
211 CHECKENABLE useArrayBounds = CHECKENABLE._default; // when to generate code for array bounds checks
212 CHECKENABLE useAssert = CHECKENABLE._default; // when to generate code for assert()'s
213 CHECKENABLE useSwitchError = CHECKENABLE._default; // check for switches without a default
214 CHECKENABLE boundscheck = CHECKENABLE._default; // state of -boundscheck switch
216 CHECKACTION checkAction = CHECKACTION.D; // action to take when bounds, asserts or switch defaults are violated
218 const(char)[] argv0; // program name
219 Array!(const(char)*) modFileAliasStrings; // array of char*'s of -I module filename alias strings
220 Array!(const(char)*)* imppath; // array of char*'s of where to look for import modules
221 Array!(const(char)*)* fileImppath; // array of char*'s of where to look for file import modules
222 const(char)[] objdir; // .obj/.lib file output directory
223 const(char)[] objname; // .obj file output name
224 const(char)[] libname; // .lib file output name
226 Output ddoc; // Generate embedded documentation comments
227 Output dihdr; // Generate `.di` 'header' files
228 Output cxxhdr; // Generate 'Cxx header' file
229 Output json; // Generate JSON file
230 JsonFieldFlags jsonFieldFlags; // JSON field flags to include
231 Output makeDeps; // Generate make file dependencies
232 Output mixinOut; // write expanded mixins for debugging
233 Output moduleDeps; // Generate `.deps` module dependencies
235 uint debuglevel; // debug level
236 uint versionlevel; // version level
238 bool run; // run resulting executable
239 Strings runargs; // arguments for executable
240 Array!(const(char)*) cppswitches; // C preprocessor switches
241 const(char)* cpp; // if not null, then this specifies the C preprocessor
243 // Linker stuff
244 Array!(const(char)*) objfiles;
245 Array!(const(char)*) linkswitches;
246 Array!bool linkswitchIsForCC;
247 Array!(const(char)*) libfiles;
248 Array!(const(char)*) dllfiles;
249 const(char)[] deffile;
250 const(char)[] resfile;
251 const(char)[] exefile;
252 const(char)[] mapfile;
255 bool parsingUnittestsRequired()
257 return useUnitTests || ddoc.doOutput || dihdr.doOutput;
261 enum mars_ext = "d"; // for D source files
262 enum doc_ext = "html"; // for Ddoc generated files
263 enum ddoc_ext = "ddoc"; // for Ddoc macro include files
264 enum dd_ext = "dd"; // for Ddoc source files
265 enum hdr_ext = "di"; // for D 'header' import files
266 enum json_ext = "json"; // for JSON files
267 enum map_ext = "map"; // for .map files
268 enum c_ext = "c"; // for C source files
269 enum i_ext = "i"; // for preprocessed C source file
272 * Collection of global compiler settings and global state used by the frontend
274 extern (C++) struct Global
276 const(char)[] inifilename; /// filename of configuration file as given by `-conf=`, or default value
278 string copyright = "Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved";
279 string written = "written by Walter Bright";
281 Array!(const(char)*)* path; /// Array of char*'s which form the import lookup path
282 Array!(const(char)*)* filePath; /// Array of char*'s which form the file import lookup path
284 private enum string _version = import("VERSION");
285 char[26] datetime; /// string returned by ctime()
286 CompileEnv compileEnv;
288 Param params; /// command line parameters
289 uint errors; /// number of errors reported so far
290 uint warnings; /// number of warnings reported so far
291 uint gag; /// !=0 means gag reporting of errors & warnings
292 uint gaggedErrors; /// number of errors reported while gagged
293 uint gaggedWarnings; /// number of warnings reported while gagged
295 void* console; /// opaque pointer to console for controlling text attributes
297 Array!Identifier* versionids; /// command line versions and predefined versions
298 Array!Identifier* debugids; /// command line debug versions and predefined versions
300 bool hasMainFunction; /// Whether a main function has already been compiled in (for -main switch)
301 uint varSequenceNumber = 1; /// Relative lifetime of `VarDeclaration` within a function, used for `scope` checks
303 /// Cache files read from disk
304 FileManager fileManager;
306 enum recursionLimit = 500; /// number of recursive template expansions before abort
308 ErrorSink errorSink; /// where the error messages go
309 ErrorSink errorSinkNull; /// where the error messages are ignored
311 extern (C++) FileName function(FileName, ref const Loc, out bool, OutBuffer*) preprocess;
313 nothrow:
316 * Start ignoring compile errors instead of reporting them.
318 * Used for speculative compilation like `__traits(compiles, XXX)`, but also internally
319 * to e.g. try out an `alias this` rewrite without comitting to it.
321 * Works like a stack, so N calls to `startGagging` should be paired with N
322 * calls to `endGagging`.
324 * Returns: the current number of gagged errors, which should later be passed to `endGagging`
326 extern (C++) uint startGagging() @safe
328 ++gag;
329 gaggedWarnings = 0;
330 return gaggedErrors;
334 * Stop gagging, restoring the old gagged state before the most recent call to `startGagging`.
336 * Params:
337 * oldGagged = the previous number of errors, as returned by `startGagging`
338 * Returns: true if errors occurred while gagged.
340 extern (C++) bool endGagging(uint oldGagged) @safe
342 bool anyErrs = (gaggedErrors != oldGagged);
343 --gag;
344 // Restore the original state of gagged errors; set total errors
345 // to be original errors + new ungagged errors.
346 errors -= (gaggedErrors - oldGagged);
347 gaggedErrors = oldGagged;
348 return anyErrs;
352 * Increment the error count to record that an error has occurred in the current context.
354 * An error message may or may not have been printed.
356 extern (C++) void increaseErrorCount() @safe
358 if (gag)
359 ++gaggedErrors;
360 ++errors;
363 extern (C++) void _init()
365 errorSink = new ErrorSinkCompiler;
366 errorSinkNull = new ErrorSinkNull;
368 this.fileManager = new FileManager();
369 version (MARS)
371 compileEnv.vendor = "Digital Mars D";
373 // -color=auto is the default value
374 import dmd.console : detectTerminal, detectColorPreference;
375 params.v.color = detectTerminal() && detectColorPreference();
377 else version (IN_GCC)
379 compileEnv.vendor = "GNU D";
381 compileEnv.versionNumber = parseVersionNumber(_version);
383 /* Initialize date, time, and timestamp
385 import core.stdc.time;
386 import core.stdc.stdlib : getenv;
388 time_t ct;
389 // https://issues.dlang.org/show_bug.cgi?id=20444
390 if (auto p = getenv("SOURCE_DATE_EPOCH"))
392 if (!ct.parseDigits(p[0 .. strlen(p)]))
393 errorSink.error(Loc.initial, "value of environment variable `SOURCE_DATE_EPOCH` should be a valid UNIX timestamp, not: `%s`", p);
395 else
396 core.stdc.time.time(&ct);
397 const p = ctime(&ct);
398 assert(p);
399 datetime[] = p[0 .. 26];
401 __gshared char[11 + 1] date = 0; // put in BSS segment
402 __gshared char[8 + 1] time = 0;
403 __gshared char[24 + 1] timestamp = 0;
405 const dsz = snprintf(&date[0], date.length, "%.6s %.4s", p + 4, p + 20);
406 const tsz = snprintf(&time[0], time.length, "%.8s", p + 11);
407 const tssz = snprintf(&timestamp[0], timestamp.length, "%.24s", p);
408 assert(dsz > 0 && tsz > 0 && tssz > 0);
409 compileEnv.time = time[0 .. tsz];
410 compileEnv.date = date[0 .. dsz];
411 compileEnv.timestamp = timestamp[0 .. tssz];
415 * Deinitializes the global state of the compiler.
417 * This can be used to restore the state set by `_init` to its original
418 * state.
420 extern (D) void deinitialize()
422 this = this.init;
426 * Computes the version number __VERSION__ from the compiler version string.
428 extern (D) private static uint parseVersionNumber(string version_) @safe
431 // parse _version
433 uint major = 0;
434 uint minor = 0;
435 bool point = false;
436 // skip initial 'v'
437 foreach (const c; version_[1..$])
439 if ('0' <= c && c <= '9') // isdigit
441 minor = minor * 10 + c - '0';
443 else if (c == '.')
445 if (point)
446 break; // ignore everything after second '.'
447 point = true;
448 major = minor;
449 minor = 0;
451 else
452 break;
454 return major * 1000 + minor;
458 Returns: the version as the number that would be returned for __VERSION__
460 extern(C++) uint versionNumber() @safe
462 return compileEnv.versionNumber;
466 Returns: compiler version string.
468 extern(D) string versionString() @safe
470 return _version;
474 Returns: compiler version as char string.
476 extern(C++) const(char*) versionChars()
478 return _version.ptr;
482 // Because int64_t and friends may be any integral type of the
483 // correct size, we have to explicitly ask for the correct
484 // integer type to get the correct mangling with dmd
486 // Be careful not to care about sign when using dinteger_t
487 // use this instead of integer_t to
488 // avoid conflicts with system #include's
489 alias dinteger_t = ulong;
490 // Signed and unsigned variants
491 alias sinteger_t = long;
492 alias uinteger_t = ulong;
494 /// Collection of global state
495 extern (C++) __gshared Global global;