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