1 /**
2  * Defines the help texts for the CLI options offered by DMD.
3  *
4  * This file is not shared with other compilers which use the DMD front-end.
5  * However, this file will be used to generate the
6  * $(LINK2 https://dlang.org/dmd-linux.html, online documentation) and MAN pages.
7  *
8  * Copyright:   Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/cli.d, _cli.d)
12  * Documentation:  https://dlang.org/phobos/dmd_cli.html
13  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/cli.d
14  */
15 module dmd.cli;
16 
17 /* The enum TargetOS is an exact copy of the one in dmd.globals.
18  * Duplicated here because this file is stand-alone.
19  */
20 
21 /// Bit decoding of the TargetOS
22 enum TargetOS : ubyte
23 {
24     /* These are mutually exclusive; one and only one is set.
25      * Match spelling and casing of corresponding version identifiers
26      */
27     linux        = 1,
28     Windows      = 2,
29     OSX          = 4,
30     OpenBSD      = 8,
31     FreeBSD      = 0x10,
32     Solaris      = 0x20,
33     DragonFlyBSD = 0x40,
34 
35     // Combination masks
36     all = linux | Windows | OSX | FreeBSD | Solaris | DragonFlyBSD,
37     Posix = linux | OSX | FreeBSD | Solaris | DragonFlyBSD,
38 }
39 
40 // Detect the current TargetOS
41 version (linux)
42 {
43     private enum targetOS = TargetOS.linux;
44 }
45 else version(Windows)
46 {
47     private enum targetOS = TargetOS.Windows;
48 }
49 else version(OSX)
50 {
51     private enum targetOS = TargetOS.OSX;
52 }
53 else version(FreeBSD)
54 {
55     private enum targetOS = TargetOS.FreeBSD;
56 }
57 else version(DragonFlyBSD)
58 {
59     private enum targetOS = TargetOS.DragonFlyBSD;
60 }
61 else version(Solaris)
62 {
63     private enum targetOS = TargetOS.Solaris;
64 }
65 else
66 {
67     private enum targetOS = TargetOS.all;
68 }
69 
70 /**
71 Checks whether `os` is the current $(LREF TargetOS).
72 For `TargetOS.all` it will always return true.
73 
74 Params:
75     os = $(LREF TargetOS) to check
76 
77 Returns: true iff `os` contains the current targetOS.
78 */
79 bool isCurrentTargetOS(TargetOS os)
80 {
81     return (os & targetOS) > 0;
82 }
83 
84 /**
85 Capitalize a the first character of a ASCII string.
86 Params:
87     w = ASCII i string to capitalize
88 Returns: capitalized string
89 */
90 static string capitalize(string w)
91 {
92     char[] result = cast(char[]) w;
93     char c1 = w.length ? w[0] : '\0';
94 
95     if (c1 >= 'a' && c1 <= 'z')
96     {
97         enum adjustment = 'A' - 'a';
98 
99         result = new char[] (w.length);
100         result[0] = cast(char) (c1 + adjustment);
101         result[1 .. $] = w[1 .. $];
102     }
103 
104     return cast(string) result;
105 }
106 
107 /**
108 Contains all available CLI $(LREF Usage.Option)s.
109 
110 See_Also: $(LREF Usage.Option)
111 */
112 struct Usage
113 {
114     /**
115     * Representation of a CLI `Option`
116     *
117     * The DDoc description `ddoxText` is only available when compiled with `-version=DdocOptions`.
118     */
119     struct Option
120     {
121         string flag; /// The CLI flag without leading `-`, e.g. `color`
122         string helpText; /// A detailed description of the flag
123         TargetOS os = TargetOS.all; /// For which `TargetOS` the flags are applicable
124 
125         // Needs to be version-ed to prevent the text ending up in the binary
126         // See also: https://issues.dlang.org/show_bug.cgi?id=18238
127         version(DdocOptions) string ddocText; /// Detailed description of the flag (in Ddoc)
128 
129         /**
130         * Params:
131         *  flag = CLI flag without leading `-`, e.g. `color`
132         *  helpText = detailed description of the flag
133         *  os = for which `TargetOS` the flags are applicable
134         *  ddocText = detailed description of the flag (in Ddoc)
135         */
136         this(string flag, string helpText, TargetOS os = TargetOS.all)
137         {
138             this.flag = flag;
139             this.helpText = helpText;
140             version(DdocOptions) this.ddocText = helpText;
141             this.os = os;
142         }
143 
144         /// ditto
145         this(string flag, string helpText, string ddocText, TargetOS os = TargetOS.all)
146         {
147             this.flag = flag;
148             this.helpText = helpText;
149             version(DdocOptions) this.ddocText = ddocText;
150             this.os = os;
151         }
152     }
153 
154     /// Returns all available CLI options
155     static immutable options = [
156         Option("allinst",
157             "generate code for all template instantiations"
158         ),
159         Option("betterC",
160             "omit generating some runtime information and helper functions",
161             "Adjusts the compiler to implement D as a $(LINK2 $(ROOT_DIR)spec/betterc.html, better C):
162             $(UL
163                 $(LI Predefines `D_BetterC` $(LINK2 $(ROOT_DIR)spec/version.html#predefined-versions, version).)
164                 $(LI $(LINK2 $(ROOT_DIR)spec/expression.html#AssertExpression, Assert Expressions), when they fail,
165                 call the C runtime library assert failure function
166                 rather than a function in the D runtime.)
167                 $(LI $(LINK2 $(ROOT_DIR)spec/arrays.html#bounds, Array overflows)
168                 call the C runtime library assert failure function
169                 rather than a function in the D runtime.)
170                 $(LI $(LINK2 spec/statement.html#final-switch-statement/, Final switch errors)
171                 call the C runtime library assert failure function
172                 rather than a function in the D runtime.)
173                 $(LI Does not automatically link with phobos runtime library.)
174                 $(UNIX
175                 $(LI Does not generate Dwarf `eh_frame` with full unwinding information, i.e. exception tables
176                 are not inserted into `eh_frame`.)
177                 )
178                 $(LI Module constructors and destructors are not generated meaning that
179                 $(LINK2 $(ROOT_DIR)spec/class.html#StaticConstructor, static) and
180                 $(LINK2 $(ROOT_DIR)spec/class.html#SharedStaticConstructor, shared static constructors) and
181                 $(LINK2 $(ROOT_DIR)spec/class.html#StaticDestructor, destructors)
182                 will not get called.)
183                 $(LI `ModuleInfo` is not generated.)
184                 $(LI $(LINK2 $(ROOT_DIR)phobos/object.html#.TypeInfo, `TypeInfo`)
185                 instances will not be generated for structs.)
186             )",
187         ),
188         Option("boundscheck=[on|safeonly|off]",
189             "bounds checks on, in @safe only, or off",
190             `Controls if bounds checking is enabled.
191                 $(UL
192                     $(LI $(I on): Bounds checks are enabled for all code. This is the default.)
193                     $(LI $(I safeonly): Bounds checks are enabled only in $(D @safe) code.
194                                         This is the default for $(SWLINK -release) builds.)
195                     $(LI $(I off): Bounds checks are disabled completely (even in $(D @safe)
196                                    code). This option should be used with caution and as a
197                                    last resort to improve performance. Confirm turning off
198                                    $(D @safe) bounds checks is worthwhile by benchmarking.)
199                 )`
200         ),
201         Option("c",
202             "compile only, do not link"
203         ),
204         Option("check=[assert|bounds|in|invariant|out|switch][=[on|off]]",
205             "enable or disable specific checks",
206             `Overrides default, -boundscheck, -release and -unittest options to enable or disable specific checks.
207                 $(UL
208                     $(LI $(B assert): assertion checking)
209                     $(LI $(B bounds): array bounds)
210                     $(LI $(B in): in contracts)
211                     $(LI $(B invariant): class/struct invariants)
212                     $(LI $(B out): out contracts)
213                     $(LI $(B switch): finalswitch failure checking)
214                 )
215                 $(UL
216                     $(LI $(B on) or not specified: specified check is enabled.)
217                     $(LI $(B off): specified check is disabled.)
218                 )`
219         ),
220         Option("check=[h|help|?]",
221             "list information on all available checks"
222         ),
223         Option("checkaction=[D|C|halt|context]",
224             "behavior on assert/boundscheck/finalswitch failure",
225             `Sets behavior when an assert fails, and array boundscheck fails,
226              or a final switch errors.
227                 $(UL
228                     $(LI $(B D): Default behavior, which throws an unrecoverable $(D AssertError).)
229                     $(LI $(B C): Calls the C runtime library assert failure function.)
230                     $(LI $(B halt): Executes a halt instruction, terminating the program.)
231                     $(LI $(B context): Prints the error context as part of the unrecoverable $(D AssertError).)
232                 )`
233         ),
234         Option("checkaction=[h|help|?]",
235             "list information on all available check actions"
236         ),
237         Option("color",
238             "turn colored console output on"
239         ),
240         Option("color=[on|off|auto]",
241             "force colored console output on or off, or only when not redirected (default)",
242             `Show colored console output. The default depends on terminal capabilities.
243             $(UL
244                 $(LI $(B auto): use colored output if a tty is detected (default))
245                 $(LI $(B on): always use colored output.)
246                 $(LI $(B off): never use colored output.)
247             )`
248         ),
249         Option("conf=<filename>",
250             "use config file at filename"
251         ),
252         Option("cov",
253             "do code coverage analysis"
254         ),
255         Option("cov=ctfe", "Include code executed during CTFE in coverage report"),
256         Option("cov=<nnn>",
257             "require at least nnn% code coverage",
258             `Perform $(LINK2 $(ROOT_DIR)code_coverage.html, code coverage analysis) and generate
259             $(TT .lst) file with report.)
260 ---
261 dmd -cov -unittest myprog.d
262 ---
263             `,
264         ),
265         Option("D",
266             "generate documentation",
267             `$(P Generate $(LINK2 $(ROOT_DIR)spec/ddoc.html, documentation) from source.)
268             $(P Note: mind the $(LINK2 $(ROOT_DIR)spec/ddoc.html#security, security considerations).)
269             `,
270         ),
271         Option("Dd<directory>",
272             "write documentation file to directory",
273             `Write documentation file to $(I directory) . $(SWLINK -op)
274             can be used if the original package hierarchy should
275             be retained`,
276         ),
277         Option("Df<filename>",
278             "write documentation file to filename"
279         ),
280         Option("d",
281             "silently allow deprecated features and symbols",
282             `Silently allow $(DDLINK deprecate,deprecate,deprecated features) and use of symbols with
283             $(DDSUBLINK $(ROOT_DIR)spec/attribute, deprecated, deprecated attributes).`,
284         ),
285         Option("de",
286             "issue an error when deprecated features or symbols are used (halt compilation)"
287         ),
288         Option("dw",
289             "issue a message when deprecated features or symbols are used (default)"
290         ),
291         Option("debug",
292             "compile in debug code",
293             `Compile in $(LINK2 spec/version.html#debug, debug) code`,
294         ),
295         Option("debug=<level>",
296             "compile in debug code <= level",
297             `Compile in $(LINK2 spec/version.html#debug, debug level) &lt;= $(I level)`,
298         ),
299         Option("debug=<ident>",
300             "compile in debug code identified by ident",
301             `Compile in $(LINK2 spec/version.html#debug, debug identifier) $(I ident)`,
302         ),
303         Option("debuglib=<name>",
304             "set symbolic debug library to name",
305             `Link in $(I libname) as the default library when
306             compiling for symbolic debugging instead of $(B $(LIB)).
307             If $(I libname) is not supplied, then no default library is linked in.`
308         ),
309         Option("defaultlib=<name>",
310             "set default library to name",
311             `Link in $(I libname) as the default library when
312             not compiling for symbolic debugging instead of $(B $(LIB)).
313             If $(I libname) is not supplied, then no default library is linked in.`,
314         ),
315         Option("deps",
316             "print module dependencies (imports/file/version/debug/lib)"
317         ),
318         Option("deps=<filename>",
319             "write module dependencies to filename (only imports)",
320             `Without $(I filename), print module dependencies
321             (imports/file/version/debug/lib).
322             With $(I filename), write module dependencies as text to $(I filename)
323             (only imports).`,
324         ),
325         Option("extern-std=<standard>",
326             "set C++ name mangling compatibility with <standard>",
327             "Standards supported are:
328             $(UL
329                 $(LI $(I c++98): Use C++98 name mangling,
330                     Sets `__traits(getTargetInfo, \"cppStd\")` to `199711`)
331                 $(LI $(I c++11) (default): Use C++11 name mangling,
332                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201103`)
333                 $(LI $(I c++14): Use C++14 name mangling,
334                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`)
335                 $(LI $(I c++17): Use C++17 name mangling,
336                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`)
337                 $(LI $(I c++20): Use C++20 name mangling,
338                     Sets `__traits(getTargetInfo, \"cppStd\")` to `202002`)
339             )",
340         ),
341         Option("extern-std=[h|help|?]",
342             "list all supported standards"
343         ),
344         Option("fPIC",
345             "generate position independent code",
346             cast(TargetOS) (TargetOS.all & ~(TargetOS.Windows | TargetOS.OSX))
347         ),
348         Option("g",
349             "add symbolic debug info",
350             `$(WINDOWS
351                 Add CodeView symbolic debug info. See
352                 $(LINK2 http://dlang.org/windbg.html, Debugging on Windows).
353             )
354             $(UNIX
355                 Add symbolic debug info in DWARF format
356                 for debuggers such as
357                 $(D gdb)
358             )`,
359         ),
360         Option("gdwarf=<version>",
361             "add DWARF symbolic debug info",
362             "The value of version may be 3, 4 or 5, defaulting to 3.",
363             cast(TargetOS) (TargetOS.all & ~cast(uint)TargetOS.Windows)
364         ),
365         Option("gf",
366             "emit debug info for all referenced types",
367             `Symbolic debug info is emitted for all types referenced by the compiled code,
368              even if the definition is in an imported file not currently being compiled.`,
369         ),
370         Option("gs",
371             "always emit stack frame"
372         ),
373         Option("gx",
374             "add stack stomp code",
375             `Adds stack stomp code, which overwrites the stack frame memory upon function exit.`,
376         ),
377         Option("H",
378             "generate 'header' file",
379             `Generate $(RELATIVE_LINK2 $(ROOT_DIR)interface-files, D interface file)`,
380         ),
381         Option("Hd=<directory>",
382             "write 'header' file to directory",
383             `Write D interface file to $(I dir) directory. $(SWLINK -op)
384             can be used if the original package hierarchy should
385             be retained.`,
386         ),
387         Option("Hf=<filename>",
388             "write 'header' file to filename"
389         ),
390         Option("HC[=[silent|verbose]]",
391             "generate C++ 'header' file",
392             `Generate C++ 'header' files using the given configuration:",
393             $(DL
394             $(DT silent)$(DD only list extern(C[++]) declarations (default))
395             $(DT verbose)$(DD also add comments for ignored declarations (e.g. extern(D)))
396             )`,
397         ),
398         Option("HC=[?|h|help]",
399             "list available modes for C++ 'header' file generation"
400         ),
401         Option("HCd=<directory>",
402             "write C++ 'header' file to directory"
403         ),
404         Option("HCf=<filename>",
405             "write C++ 'header' file to filename"
406         ),
407         Option("-help",
408             "print help and exit"
409         ),
410         Option("I=<directory>",
411             "look for imports also in directory"
412         ),
413         Option("i[=<pattern>]",
414             "include imported modules in the compilation",
415             q"{$(P Enables "include imports" mode, where the compiler will include imported
416              modules in the compilation, as if they were given on the command line. By default, when
417              this option is enabled, all imported modules are included except those in
418              druntime/phobos. This behavior can be overriden by providing patterns via `-i=<pattern>`.
419              A pattern of the form `-i=<package>` is an "inclusive pattern", whereas a pattern
420              of the form `-i=-<package>` is an "exclusive pattern". Inclusive patterns will include
421              all module's whose names match the pattern, whereas exclusive patterns will exclude them.
422              For example. all modules in the package `foo.bar` can be included using `-i=foo.bar` or excluded
423              using `-i=-foo.bar`. Note that each component of the fully qualified name must match the
424              pattern completely, so the pattern `foo.bar` would not match a module named `foo.barx`.)
425 
426              $(P The default behavior of excluding druntime/phobos is accomplished by internally adding a
427              set of standard exclusions, namely, `-i=-std -i=-core -i=-etc -i=-object`. Note that these
428              can be overriden with `-i=std -i=core -i=etc -i=object`.)
429 
430              $(P When a module matches multiple patterns, matches are prioritized by their component length, where
431              a match with more components takes priority (i.e. pattern `foo.bar.baz` has priority over `foo.bar`).)
432 
433              $(P By default modules that don't match any pattern will be included. However, if at
434              least one inclusive pattern is given, then modules not matching any pattern will
435              be excluded. This behavior can be overriden by usig `-i=.` to include by default or `-i=-.` to
436              exclude by default.)
437 
438              $(P Note that multiple `-i=...` options are allowed, each one adds a pattern.)}"
439         ),
440         Option("ignore",
441             "ignore unsupported pragmas"
442         ),
443         Option("inline",
444             "do function inlining",
445             `Inline functions at the discretion of the compiler.
446             This can improve performance, at the expense of making
447             it more difficult to use a debugger on it.`,
448         ),
449         Option("J=<directory>",
450             "look for string imports also in directory",
451             `Where to look for files for
452             $(LINK2 $(ROOT_DIR)spec/expression.html#ImportExpression, $(I ImportExpression))s.
453             This switch is required in order to use $(I ImportExpression)s.
454             $(I path) is a ; separated
455             list of paths. Multiple $(B -J)'s can be used, and the paths
456             are searched in the same order.`,
457         ),
458         Option("L=<linkerflag>",
459             "pass linkerflag to link",
460             `Pass $(I linkerflag) to the
461             $(WINDOWS linker $(OPTLINK))
462             $(UNIX linker), for example, ld`,
463         ),
464         Option("lib",
465             "generate library rather than object files",
466             `Generate library file as output instead of object file(s).
467             All compiled source files, as well as object files and library
468             files specified on the command line, are inserted into
469             the output library.
470             Compiled source modules may be partitioned into several object
471             modules to improve granularity.
472             The name of the library is taken from the name of the first
473             source module to be compiled. This name can be overridden with
474             the $(SWLINK -of) switch.`,
475         ),
476         Option("lowmem",
477             "enable garbage collection for the compiler",
478             `Enable the garbage collector for the compiler, reducing the
479             compiler memory requirements but increasing compile times.`,
480         ),
481         Option("m32",
482             "generate 32 bit code",
483             `$(UNIX Compile a 32 bit executable. This is the default for the 32 bit dmd.)
484             $(WINDOWS Compile a 32 bit executable. This is the default.
485             The generated object code is in OMF and is meant to be used with the
486             $(LINK2 http://www.digitalmars.com/download/freecompiler.html, Digital Mars C/C++ compiler)).`,
487             cast(TargetOS) (TargetOS.all & ~cast(uint)TargetOS.DragonFlyBSD)  // available on all OS'es except DragonFly, which does not support 32-bit binaries
488         ),
489         Option("m32mscoff",
490             "generate 32 bit code and write MS-COFF object files",
491             TargetOS.Windows
492         ),
493         Option("m64",
494             "generate 64 bit code",
495             `$(UNIX Compile a 64 bit executable. This is the default for the 64 bit dmd.)
496             $(WINDOWS The generated object code is in MS-COFF and is meant to be used with the
497             $(LINK2 https://msdn.microsoft.com/en-us/library/dd831853(v=vs.100).aspx, Microsoft Visual Studio 10)
498             or later compiler.`,
499         ),
500         Option("main",
501             "add default main() (e.g. for unittesting)",
502             `Add a default $(D main()) function when compiling. This is useful when
503             unittesting a library, as it enables running the unittests
504             in a library without having to manually define an entry-point function.`,
505         ),
506         Option("makedeps[=<filename>]",
507             "print dependencies in Makefile compatible format to filename or stdout.",
508             `Print dependencies in Makefile compatible format.
509             If filename is omitted, it prints to stdout.
510             The emitted targets are the compiled artifacts (executable, object files, libraries).
511             The emitted dependencies are imported modules and imported string files (via $(B -J) switch).
512             Special characters in a dependency or target filename are escaped in the GNU Make manner.
513             `,
514         ),
515         Option("man",
516             "open web browser on manual page",
517             `$(WINDOWS
518                 Open default browser on this page
519             )
520             $(LINUX
521                 Open browser specified by the $(B BROWSER)
522                 environment variable on this page. If $(B BROWSER) is
523                 undefined, $(B x-www-browser) is assumed.
524             )
525             $(FREEBSD
526                 Open browser specified by the $(B BROWSER)
527                 environment variable on this page. If $(B BROWSER) is
528                 undefined, $(B x-www-browser) is assumed.
529             )
530             $(OSX
531                 Open browser specified by the $(B BROWSER)
532                 environment variable on this page. If $(B BROWSER) is
533                 undefined, $(B Safari) is assumed.
534             )`,
535         ),
536         Option("map",
537             "generate linker .map file",
538             `Generate a $(TT .map) file`,
539         ),
540         Option("mcpu=<id>",
541             "generate instructions for architecture identified by 'id'",
542             `Set the target architecture for code generation,
543             where:
544             $(DL
545             $(DT help)$(DD list alternatives)
546             $(DT baseline)$(DD the minimum architecture for the target platform (default))
547             $(DT avx)$(DD
548             generate $(LINK2 https://en.wikipedia.org/wiki/Advanced_Vector_Extensions, AVX)
549             instructions instead of $(LINK2 https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions, SSE)
550             instructions for vector and floating point operations.
551             Not available for 32 bit memory models other than OSX32.
552             )
553             $(DT native)$(DD use the architecture the compiler is running on)
554             )`,
555         ),
556         Option("mcpu=[h|help|?]",
557             "list all architecture options"
558         ),
559         Option("mixin=<filename>",
560             "expand and save mixins to file specified by <filename>"
561         ),
562         Option("mscrtlib=<libname>",
563             "MS C runtime library to reference from main/WinMain/DllMain",
564             "If building MS-COFF object files with -m64 or -m32mscoff, embed a reference to
565             the given C runtime library $(I libname) into the object file containing `main`,
566             `DllMain` or `WinMain` for automatic linking. The default is $(TT libcmt)
567             (release version with static linkage), the other usual alternatives are
568             $(TT libcmtd), $(TT msvcrt) and $(TT msvcrtd).
569             If no Visual C installation is detected, a wrapper for the redistributable
570             VC2010 dynamic runtime library and mingw based platform import libraries will
571             be linked instead using the LLD linker provided by the LLVM project.
572             The detection can be skipped explicitly if $(TT msvcrt120) is specified as
573             $(I libname).
574             If $(I libname) is empty, no C runtime library is automatically linked in.",
575             TargetOS.Windows,
576         ),
577         Option("mv=<package.module>=<filespec>",
578             "use <filespec> as source file for <package.module>",
579             `Use $(I path/filename) as the source file for $(I package.module).
580             This is used when the source file path and names are not the same
581             as the package and module hierarchy.
582             The rightmost components of the  $(I path/filename) and $(I package.module)
583             can be omitted if they are the same.`,
584         ),
585         Option("noboundscheck",
586             "no array bounds checking (deprecated, use -boundscheck=off)",
587             `Turns off all array bounds checking, even for safe functions. $(RED Deprecated
588             (use $(TT $(SWLINK -boundscheck)=off) instead).)`,
589         ),
590         Option("O",
591             "optimize",
592             `Optimize generated code. For fastest executables, compile
593             with the $(TT $(SWLINK -O) $(SWLINK -release) $(SWLINK -inline) $(SWLINK -boundscheck)=off)
594             switches together.`,
595         ),
596         Option("o-",
597             "do not write object file",
598             `Suppress generation of object file. Useful in
599             conjuction with $(SWLINK -D) or $(SWLINK -H) flags.`
600         ),
601         Option("od=<directory>",
602             "write object & library files to directory",
603             `Write object files relative to directory $(I objdir)
604             instead of to the current directory. $(SWLINK -op)
605             can be used if the original package hierarchy should
606             be retained`,
607         ),
608         Option("of=<filename>",
609             "name output file to filename",
610             `Set output file name to $(I filename) in the output
611             directory. The output file can be an object file,
612             executable file, or library file depending on the other
613             switches.`
614         ),
615         Option("op",
616             "preserve source path for output files",
617             `Normally the path for $(B .d) source files is stripped
618             off when generating an object, interface, or Ddoc file
619             name. $(SWLINK -op) will leave it on.`,
620         ),
621         Option("preview=<name>",
622             "enable an upcoming language change identified by 'name'",
623             `Preview an upcoming language change identified by $(I id)`,
624         ),
625         Option("preview=[h|help|?]",
626             "list all upcoming language changes"
627         ),
628         Option("profile",
629             "profile runtime performance of generated code"
630         ),
631         Option("profile=gc",
632             "profile runtime allocations",
633             `$(LINK2 http://www.digitalmars.com/ctg/trace.html, profile)
634             the runtime performance of the generated code.
635             $(UL
636                 $(LI $(B gc): Instrument calls to memory allocation and write a report
637                 to the file $(TT profilegc.log) upon program termination.)
638             )`,
639         ),
640         Option("release",
641             "compile release version",
642             `Compile release version, which means not emitting run-time
643             checks for contracts and asserts. Array bounds checking is not
644             done for system and trusted functions, and assertion failures
645             are undefined behaviour.`
646         ),
647         Option("revert=<name>",
648             "revert language change identified by 'name'",
649             `Revert language change identified by $(I id)`,
650         ),
651         Option("revert=[h|help|?]",
652             "list all revertable language changes"
653         ),
654         Option("run <srcfile>",
655             "compile, link, and run the program srcfile",
656             `Compile, link, and run the program $(I srcfile) with the
657             rest of the
658             command line, $(I args...), as the arguments to the program.
659             No .$(OBJEXT) or executable file is left behind.`
660         ),
661         Option("shared",
662             "generate shared library (DLL)",
663             `$(UNIX Generate shared library)
664              $(WINDOWS Generate DLL library)`,
665         ),
666         Option("transition=<name>",
667             "help with language change identified by 'name'",
668             `Show additional info about language change identified by $(I id)`,
669         ),
670         Option("transition=[h|help|?]",
671             "list all language changes"
672         ),
673         Option("unittest",
674             "compile in unit tests",
675             `Compile in $(LINK2 spec/unittest.html, unittest) code, turns on asserts, and sets the
676              $(D unittest) $(LINK2 spec/version.html#PredefinedVersions, version identifier)`,
677         ),
678         Option("v",
679             "verbose",
680             `Enable verbose output for each compiler pass`,
681         ),
682         Option("vcolumns",
683             "print character (column) numbers in diagnostics"
684         ),
685         Option("verror-style=[digitalmars|gnu]",
686             "set the style for file/line number annotations on compiler messages",
687             `Set the style for file/line number annotations on compiler messages,
688             where:
689             $(DL
690             $(DT digitalmars)$(DD 'file(line[,column]): message'. This is the default.)
691             $(DT gnu)$(DD 'file:line[:column]: message', conforming to the GNU standard used by gcc and clang.)
692             )`,
693         ),
694         Option("verrors=<num>",
695             "limit the number of error messages (0 means unlimited)"
696         ),
697         Option("verrors=context",
698             "show error messages with the context of the erroring source line"
699         ),
700         Option("verrors=spec",
701             "show errors from speculative compiles such as __traits(compiles,...)"
702         ),
703         Option("-version",
704             "print compiler version and exit"
705         ),
706         Option("version=<level>",
707             "compile in version code >= level",
708             `Compile in $(LINK2 $(ROOT_DIR)spec/version.html#version, version level) >= $(I level)`,
709         ),
710         Option("version=<ident>",
711             "compile in version code identified by ident",
712             `Compile in $(LINK2 $(ROOT_DIR)spec/version.html#version, version identifier) $(I ident)`
713         ),
714         Option("vgc",
715             "list all gc allocations including hidden ones"
716         ),
717         Option("vtls",
718             "list all variables going into thread local storage"
719         ),
720         Option("vtemplates=[list-instances]",
721             "list statistics on template instantiations",
722             `An optional argument determines extra diagnostics,
723             where:
724             $(DL
725             $(DT list-instances)$(DD Also shows all instantiation contexts for each template.)
726             )`,
727         ),
728         Option("w",
729             "warnings as errors (compilation will halt)",
730             `Enable $(LINK2 $(ROOT_DIR)articles/warnings.html, warnings)`
731         ),
732         Option("wi",
733             "warnings as messages (compilation will continue)",
734             `Enable $(LINK2 $(ROOT_DIR)articles/warnings.html, informational warnings (i.e. compilation
735             still proceeds normally))`,
736         ),
737         Option("X",
738             "generate JSON file"
739         ),
740         Option("Xf=<filename>",
741             "write JSON file to filename"
742         ),
743         Option("Xcc=<driverflag>",
744             "pass driverflag to linker driver (cc)",
745             "Pass $(I driverflag) to the linker driver (`$CC` or `cc`)",
746             cast(TargetOS) (TargetOS.all & ~cast(uint)TargetOS.Windows)
747         ),
748     ];
749 
750     /// Representation of a CLI feature
751     struct Feature
752     {
753         string name; /// name of the feature
754         string paramName; // internal transition parameter name
755         string helpText; // detailed description of the feature
756         bool documented = true; // whether this option should be shown in the documentation
757         bool deprecated_; /// whether the feature is still in use
758     }
759 
760     /// Returns all available transitions
761     static immutable transitions = [
762         Feature("field", "vfield",
763             "list all non-mutable fields which occupy an object instance"),
764         Feature("complex", "vcomplex",
765             "give deprecation messages about all usages of complex or imaginary types"),
766         Feature("tls", "vtls",
767             "list all variables going into thread local storage"),
768         Feature("vmarkdown", "vmarkdown",
769             "list instances of Markdown replacements in Ddoc"),
770     ];
771 
772     /// Returns all available reverts
773     static immutable reverts = [
774         Feature("dip25", "useDIP25", "revert DIP25 changes https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md"),
775         Feature("markdown", "markdown", "disable Markdown replacements in Ddoc"),
776         Feature("dtorfields", "dtorFields", "don't destruct fields of partially constructed objects"),
777     ];
778 
779     /// Returns all available previews
780     static immutable previews = [
781         Feature("dip25", "useDIP25",
782             "implement https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md (Sealed references)"),
783         Feature("dip1000", "vsafe",
784             "implement https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md (Scoped Pointers)"),
785         Feature("dip1008", "ehnogc",
786             "implement https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1008.md (@nogc Throwable)"),
787         Feature("dip1021", "useDIP1021",
788             "implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md (Mutable function arguments)"),
789         Feature("fieldwise", "fieldwise", "use fieldwise comparisons for struct equality"),
790         Feature("fixAliasThis", "fixAliasThis",
791             "when a symbol is resolved, check alias this scope before going to upper scopes"),
792         Feature("intpromote", "fix16997",
793             "fix integral promotions for unary + - ~ operators"),
794         Feature("dtorfields", "dtorFields",
795             "destruct fields of partially constructed objects", false, false),
796         Feature("rvaluerefparam", "rvalueRefParam",
797             "enable rvalue arguments to ref parameters"),
798         Feature("nosharedaccess", "noSharedAccess",
799             "disable access to shared memory objects"),
800         Feature("in", "previewIn",
801             "`in` on parameters means `scope const [ref]` and accepts rvalues"),
802         Feature("inclusiveincontracts", "inclusiveInContracts",
803             "'in' contracts of overridden methods must be a superset of parent contract"),
804         Feature("shortenedMethods", "shortenedMethods",
805             "allow use of => for methods and top-level functions in addition to lambdas"),
806         // DEPRECATED previews
807         // trigger deprecation message once D repositories don't use this flag anymore
808         Feature("markdown", "markdown", "enable Markdown replacements in Ddoc", false, false),
809     ];
810 }
811 
812 /**
813 Formats the `Options` for CLI printing.
814 */
815 struct CLIUsage
816 {
817     /**
818     Returns a string of all available CLI options for the current targetOS.
819     Options are separated by newlines.
820     */
821     static string usage()
822     {
823         enum maxFlagLength = 18;
824         enum s = () {
825             char[] buf;
826             foreach (option; Usage.options)
827             {
828                 if (option.os.isCurrentTargetOS)
829                 {
830                     buf ~= "  -" ~ option.flag;
831                     // create new lines if the flag name is too long
832                     if (option.flag.length >= 17)
833                     {
834                             buf ~= "\n                    ";
835                     }
836                     else if (option.flag.length <= maxFlagLength)
837                     {
838                         const spaces = maxFlagLength - option.flag.length - 1;
839                         buf.length += spaces;
840                         buf[$ - spaces .. $] = ' ';
841                     }
842                     else
843                     {
844                             buf ~= "  ";
845                     }
846                     buf ~= option.helpText;
847                     buf ~= "\n";
848                 }
849             }
850             return cast(string) buf;
851         }();
852         return s;
853     }
854 
855     /// CPU architectures supported -mcpu=id
856     enum mcpuUsage = "CPU architectures supported by -mcpu=id:
857   =[h|help|?]    list information on all available choices
858   =baseline      use default architecture as determined by target
859   =avx           use AVX 1 instructions
860   =avx2          use AVX 2 instructions
861   =native        use CPU architecture that this compiler is running on
862 ";
863 
864     static string generateFeatureUsage(const Usage.Feature[] features, string flagName, string description)
865     {
866         enum maxFlagLength = 20;
867         auto buf = description.capitalize ~ " listed by -"~flagName~"=name:
868 ";
869         auto allTransitions = [Usage.Feature("all", null,
870             "Enables all available " ~ description)] ~ features;
871         foreach (t; allTransitions)
872         {
873             if (t.deprecated_)
874                 continue;
875             if (!t.documented)
876                 continue;
877             buf ~= "  =";
878             buf ~= t.name;
879             buf ~= " "; // at least one separating space
880             auto lineLength = "  =".length + t.name.length + " ".length;
881             foreach (i; lineLength .. maxFlagLength)
882                 buf ~= " ";
883             buf ~= t.helpText;
884             buf ~= "\n";
885         }
886         return buf;
887     }
888 
889     /// Language changes listed by -transition=id
890     enum transitionUsage = generateFeatureUsage(Usage.transitions, "transition", "language transitions");
891 
892     /// Language changes listed by -revert
893     enum revertUsage = generateFeatureUsage(Usage.reverts, "revert", "revertable language changes");
894 
895     /// Language previews listed by -preview
896     enum previewUsage = generateFeatureUsage(Usage.previews, "preview", "upcoming language changes");
897 
898     /// Options supported by -checkaction=
899     enum checkActionUsage = "Behavior on assert/boundscheck/finalswitch failure:
900   =[h|help|?]    List information on all available choices
901   =D             Usual D behavior of throwing an AssertError
902   =C             Call the C runtime library assert failure function
903   =halt          Halt the program execution (very lightweight)
904   =context       Use D assert with context information (when available)
905 ";
906 
907     /// Options supported by -check
908     enum checkUsage = "Enable or disable specific checks:
909   =[h|help|?]           List information on all available choices
910   =assert[=[on|off]]    Assertion checking
911   =bounds[=[on|off]]    Array bounds checking
912   =in[=[on|off]]        Generate In contracts
913   =invariant[=[on|off]] Class/struct invariants
914   =out[=[on|off]]       Out contracts
915   =switch[=[on|off]]    Final switch failure checking
916   =on                   Enable all assertion checking
917                         (default for non-release builds)
918   =off                  Disable all assertion checking
919 ";
920 
921     /// Options supported by -extern-std
922     enum externStdUsage = "Available C++ standards:
923   =[h|help|?]           List information on all available choices
924   =c++98                Sets `__traits(getTargetInfo, \"cppStd\")` to `199711`
925   =c++11                Sets `__traits(getTargetInfo, \"cppStd\")` to `201103`
926   =c++14                Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`
927   =c++17                Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`
928   =c++20                Sets `__traits(getTargetInfo, \"cppStd\")` to `202002`
929 ";
930 
931     /// Options supported by -HC
932     enum hcUsage = "Available header generation modes:
933   =[h|help|?]           List information on all available choices
934   =silent               Silently ignore non-exern(C[++]) declarations
935   =verbose              Add a comment for ignored non-exern(C[++]) declarations
936 ";
937 
938     /// Options supported by -gdwarf
939     enum gdwarfUsage = "Available DWARF versions:
940   =[h|help|?]           List information on choices
941   =3                    Emit DWARF version 3 debug information
942   =4                    Emit DWARF version 4 debug information
943   =5                    Emit DWARF version 5 debug information
944 ";
945 
946 }