1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2021 by The D Language Foundation, 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  * https://github.com/dlang/dmd/blob/master/src/dmd/globals.h
9  */
10 
11 #pragma once
12 
13 #include "root/dcompat.h"
14 #include "root/ctfloat.h"
15 #include "root/outbuffer.h"
16 #include "root/filename.h"
17 #include "compiler.h"
18 
19 // Can't include arraytypes.h here, need to declare these directly.
20 template <typename TYPE> struct Array;
21 
22 typedef unsigned char Diagnostic;
23 enum
24 {
25     DIAGNOSTICerror,  // generate an error
26     DIAGNOSTICinform, // generate a warning
27     DIAGNOSTICoff     // disable diagnostic
28 };
29 
30 typedef unsigned char MessageStyle;
31 enum
32 {
33     MESSAGESTYLEdigitalmars, // file(line,column): message
34     MESSAGESTYLEgnu          // file:line:column: message
35 };
36 
37 // The state of array bounds checking
38 typedef unsigned char CHECKENABLE;
39 enum
40 {
41     CHECKENABLEdefault, // initial value
42     CHECKENABLEoff,     // never do bounds checking
43     CHECKENABLEon,      // always do bounds checking
44     CHECKENABLEsafeonly // do bounds checking only in @safe functions
45 };
46 
47 typedef unsigned char CHECKACTION;
48 enum
49 {
50     CHECKACTION_D,        // call D assert on failure
51     CHECKACTION_C,        // call C assert on failure
52     CHECKACTION_halt,     // cause program halt on failure
53     CHECKACTION_context   // call D assert with the error context on failure
54 };
55 
56 enum JsonFieldFlags
57 {
58     none         = 0,
59     compilerInfo = (1 << 0),
60     buildInfo    = (1 << 1),
61     modules      = (1 << 2),
62     semantics    = (1 << 3)
63 };
64 
65 enum CppStdRevision
66 {
67     CppStdRevisionCpp98 = 199711,
68     CppStdRevisionCpp11 = 201103,
69     CppStdRevisionCpp14 = 201402,
70     CppStdRevisionCpp17 = 201703,
71     CppStdRevisionCpp20 = 202002
72 };
73 
74 /// Configuration for the C++ header generator
75 enum class CxxHeaderMode
76 {
77     none,   /// Don't generate headers
78     silent, /// Generate headers
79     verbose /// Generate headers and add comments for hidden declarations
80 };
81 
82 /// Trivalent boolean to represent the state of a `revert`able change
83 enum class FeatureState : signed char
84 {
85     default_ = -1, /// Not specified by the user
86     disabled = 0,  /// Specified as `-revert=`
87     enabled = 1    /// Specified as `-preview=`
88 };
89 
90 // Put command line switches in here
91 struct Param
92 {
93     bool obj;           // write object file
94     bool link;          // perform link
95     bool dll;           // generate shared dynamic library
96     bool lib;           // write library file instead of object file(s)
97     bool multiobj;      // break one object file into multiple ones
98     bool oneobj;        // write one object file instead of multiple ones
99     bool trace;         // insert profiling hooks
100     bool tracegc;       // instrument calls to 'new'
101     bool verbose;       // verbose compile
102     bool vcg_ast;       // write-out codegen-ast
103     bool showColumns;   // print character (column) numbers in diagnostics
104     bool vtls;          // identify thread local variables
105     bool vtemplates;    // collect and list statistics on template instantiations
106     bool vtemplatesListInstances; // collect and list statistics on template instantiations origins
107     bool vgc;           // identify gc usage
108     bool vfield;        // identify non-mutable field variables
109     bool vcomplex;      // identify complex/imaginary type usage
110     unsigned char symdebug;  // insert debug symbolic information
111     bool symdebugref;   // insert debug information for all referenced types, too
112     bool optimize;      // run optimizer
113     Diagnostic useDeprecated;
114     bool stackstomp;    // add stack stomping code
115     bool useUnitTests;  // generate unittest code
116     bool useInline;     // inline expand functions
117     FeatureState useDIP25;      // implement http://wiki.dlang.org/DIP25
118     FeatureState useDIP1000; // implement https://dlang.org/spec/memory-safe-d.html#scope-return-params
119     bool useDIP1021;    // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
120     bool release;       // build release version
121     bool preservePaths; // true means don't strip path from source file
122     Diagnostic warnings;
123     unsigned char pic;  // generate position-independent-code for shared libs
124     bool color;         // use ANSI colors in console output
125     bool cov;           // generate code coverage data
126     unsigned char covPercent;   // 0..100 code coverage percentage required
127     bool ctfe_cov;      // generate coverage data for ctfe
128     bool nofloat;       // code should not pull in floating point support
129     bool ignoreUnsupportedPragmas;      // rather than error on them
130     bool useModuleInfo; // generate runtime module information
131     bool useTypeInfo;   // generate runtime type information
132     bool useExceptions; // support exception handling
133     bool noSharedAccess; // read/write access to shared memory objects
134     bool previewIn;     // `in` means `scope const`, perhaps `ref`, accepts rvalues
135     bool shortenedMethods; // allow => in normal function declarations
136     bool betterC;       // be a "better C" compiler; no dependency on D runtime
137     bool addMain;       // add a default main() function
138     bool allInst;       // generate code for all template instantiations
139     bool fix16997;      // fix integral promotions for unary + - ~ operators
140                         // https://issues.dlang.org/show_bug.cgi?id=16997
141     bool fixAliasThis;  // if the current scope has an alias this, check it before searching upper scopes
142     bool inclusiveInContracts;   // 'in' contracts of overridden methods must be a superset of parent contract
143     bool ehnogc;        // use @nogc exception handling
144     FeatureState dtorFields;  // destruct fields of partially constructed objects
145                               // https://issues.dlang.org/show_bug.cgi?id=14246
146     bool fieldwise;         // do struct equality testing field-wise rather than by memcmp()
147     bool rvalueRefParam;    // allow rvalues to be arguments to ref parameters
148     CppStdRevision cplusplus;  // version of C++ name mangling to support
149     bool markdown;          // enable Markdown replacements in Ddoc
150     bool vmarkdown;         // list instances of Markdown replacements in Ddoc
151     bool showGaggedErrors;  // print gagged errors anyway
152     bool printErrorContext;  // print errors with the error context (the error line in the source file)
153     bool manual;            // open browser on compiler manual
154     bool usage;             // print usage and exit
155     bool mcpuUsage;         // print help on -mcpu switch
156     bool transitionUsage;   // print help on -transition switch
157     bool checkUsage;        // print help on -check switch
158     bool checkActionUsage;  // print help on -checkaction switch
159     bool revertUsage;       // print help on -revert switch
160     bool previewUsage;      // print help on -preview switch
161     bool externStdUsage;    // print help on -extern-std switch
162     bool hcUsage;           // print help on -HC switch
163     bool logo;              // print logo;
164 
165     CHECKENABLE useInvariants;     // generate class invariant checks
166     CHECKENABLE useIn;             // generate precondition checks
167     CHECKENABLE useOut;            // generate postcondition checks
168     CHECKENABLE useArrayBounds;    // when to generate code for array bounds checks
169     CHECKENABLE useAssert;         // when to generate code for assert()'s
170     CHECKENABLE useSwitchError;    // check for switches without a default
171     CHECKENABLE boundscheck;       // state of -boundscheck switch
172 
173     CHECKACTION checkAction;       // action to take when bounds, asserts or switch defaults are violated
174 
175     unsigned errorLimit;
176 
177     DString  argv0;    // program name
178     Array<const char *> modFileAliasStrings; // array of char*'s of -I module filename alias strings
179     Array<const char *> *imppath;     // array of char*'s of where to look for import modules
180     Array<const char *> *fileImppath; // array of char*'s of where to look for file import modules
181     DString objdir;    // .obj/.lib file output directory
182     DString objname;   // .obj file output name
183     DString libname;   // .lib file output name
184 
185     bool doDocComments;  // process embedded documentation comments
186     DString docdir;      // write documentation file to docdir directory
187     DString docname;     // write documentation file to docname
188     Array<const char *> ddocfiles;  // macro include files for Ddoc
189 
190     bool doHdrGeneration;  // process embedded documentation comments
191     DString hdrdir;        // write 'header' file to docdir directory
192     DString hdrname;       // write 'header' file to docname
193     bool hdrStripPlainFunctions; // strip the bodies of plain (non-template) functions
194 
195     CxxHeaderMode doCxxHdrGeneration;  // write 'Cxx header' file
196     DString cxxhdrdir;        // write 'header' file to docdir directory
197     DString cxxhdrname;       // write 'header' file to docname
198 
199     bool doJsonGeneration;    // write JSON file
200     DString jsonfilename;     // write JSON file to jsonfilename
201     unsigned jsonFieldFlags;  // JSON field flags to include
202 
203     OutBuffer *mixinOut;                // write expanded mixins for debugging
204     const char *mixinFile;             // .mixin file output name
205     int mixinLines;                     // Number of lines in writeMixins
206 
207     unsigned debuglevel;   // debug level
208     Array<const char *> *debugids;     // debug identifiers
209 
210     unsigned versionlevel; // version level
211     Array<const char *> *versionids;   // version identifiers
212 
213     DString defaultlibname;     // default library for non-debug builds
214     DString debuglibname;       // default library for debug builds
215     DString mscrtlib;           // MS C runtime library
216 
217     DString moduleDepsFile;     // filename for deps output
218     OutBuffer *moduleDeps;      // contents to be written to deps file
219 
220     bool emitMakeDeps;                // whether to emit makedeps
221     DString makeDepsFile;             // filename for makedeps output
222     Array<const char *> makeDeps;     // dependencies for makedeps
223 
224     MessageStyle messageStyle;  // style of file/line annotations on messages
225 
226     bool run;           // run resulting executable
227     Strings runargs;    // arguments for executable
228 
229     // Linker stuff
230     Array<const char *> objfiles;
231     Array<const char *> linkswitches;
232     Array<bool> linkswitchIsForCC;
233     Array<const char *> libfiles;
234     Array<const char *> dllfiles;
235     DString deffile;
236     DString resfile;
237     DString exefile;
238     DString mapfile;
239 };
240 
241 typedef unsigned structalign_t;
242 // magic value means "match whatever the underlying C compiler does"
243 // other values are all powers of 2
244 #define STRUCTALIGN_DEFAULT ((structalign_t) ~0)
245 
246 const DString mars_ext = "d";
247 const DString doc_ext  = "html";     // for Ddoc generated files
248 const DString ddoc_ext = "ddoc";     // for Ddoc macro include files
249 const DString dd_ext   = "dd";       // for Ddoc source files
250 const DString hdr_ext  = "di";       // for D 'header' import files
251 const DString json_ext = "json";     // for JSON files
252 const DString map_ext  = "map";      // for .map files
253 
254 struct Global
255 {
256     DString inifilename;
257 
258     const DString copyright;
259     const DString written;
260     Array<const char *> *path;        // Array of char*'s which form the import lookup path
261     Array<const char *> *filePath;    // Array of char*'s which form the file import lookup path
262 
263     DString vendor;          // Compiler backend name
264 
265     Param params;
266     unsigned errors;         // number of errors reported so far
267     unsigned warnings;       // number of warnings reported so far
268     unsigned gag;            // !=0 means gag reporting of errors & warnings
269     unsigned gaggedErrors;   // number of errors reported while gagged
270     unsigned gaggedWarnings; // number of warnings reported while gagged
271 
272     void* console;         // opaque pointer to console for controlling text attributes
273 
274     Array<class Identifier*>* versionids; // command line versions and predefined versions
275     Array<class Identifier*>* debugids;   // command line debug versions and predefined versions
276 
277     /* Start gagging. Return the current number of gagged errors
278      */
279     unsigned startGagging();
280 
281     /* End gagging, restoring the old gagged state.
282      * Return true if errors occurred while gagged.
283      */
284     bool endGagging(unsigned oldGagged);
285 
286     /*  Increment the error count to record that an error
287      *  has occurred in the current context. An error message
288      *  may or may not have been printed.
289      */
290     void increaseErrorCount();
291 
292     void _init();
293 
294     /**
295     Returns: the version as the number that would be returned for __VERSION__
296     */
297     unsigned versionNumber();
298 
299     /**
300     Returns: the compiler version string.
301     */
302     const char * versionChars();
303 };
304 
305 extern Global global;
306 
307 // Because int64_t and friends may be any integral type of the correct size,
308 // we have to explicitly ask for the correct integer type to get the correct
309 // mangling with dmd. The #if logic here should match the mangling of
310 // Tint64 and Tuns64 in cppmangle.d.
311 #if MARS && DMD_VERSION >= 2079 && DMD_VERSION <= 2081 && \
312     __APPLE__ && __SIZEOF_LONG__ == 8
313 // DMD versions between 2.079 and 2.081 mapped D long to int64_t on OS X.
314 typedef uint64_t dinteger_t;
315 typedef int64_t sinteger_t;
316 typedef uint64_t uinteger_t;
317 #elif __SIZEOF_LONG__ == 8
318 // Be careful not to care about sign when using dinteger_t
319 // use this instead of integer_t to
320 // avoid conflicts with system #include's
321 typedef unsigned long dinteger_t;
322 // Signed and unsigned variants
323 typedef long sinteger_t;
324 typedef unsigned long uinteger_t;
325 #else
326 typedef unsigned long long dinteger_t;
327 typedef long long sinteger_t;
328 typedef unsigned long long uinteger_t;
329 #endif
330 
331 typedef int8_t                  d_int8;
332 typedef uint8_t                 d_uns8;
333 typedef int16_t                 d_int16;
334 typedef uint16_t                d_uns16;
335 typedef int32_t                 d_int32;
336 typedef uint32_t                d_uns32;
337 typedef int64_t                 d_int64;
338 typedef uint64_t                d_uns64;
339 
340 // file location
341 struct Loc
342 {
343     const char *filename; // either absolute or relative to cwd
344     unsigned linnum;
345     unsigned charnum;
346 
LocLoc347     Loc()
348     {
349         linnum = 0;
350         charnum = 0;
351         filename = NULL;
352     }
353 
LocLoc354     Loc(const char *filename, unsigned linnum, unsigned charnum)
355     {
356         this->linnum = linnum;
357         this->charnum = charnum;
358         this->filename = filename;
359     }
360 
361     const char *toChars(
362         bool showColumns = global.params.showColumns,
363         MessageStyle messageStyle = global.params.messageStyle) const;
364     bool equals(const Loc& loc) const;
365 };
366 
367 enum class LINK : uint8_t
368 {
369     default_,
370     d,
371     c,
372     cpp,
373     windows,
374     objc,
375     system
376 };
377 
378 enum class CPPMANGLE : uint8_t
379 {
380     def,
381     asStruct,
382     asClass
383 };
384 
385 enum class MATCH : int
386 {
387     nomatch,       // no match
388     convert,       // match with conversions
389     constant,      // match with conversion to const
390     exact          // exact match
391 };
392 
393 enum class PINLINE : uint8_t
394 {
395     default_,     // as specified on the command line
396     never,        // never inline
397     always        // always inline
398 };
399 
400 typedef uinteger_t StorageClass;
401