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(&params, 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;