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=ctfe", "Include code executed during CTFE in coverage report"),
245         Option("cov=<nnn>",
246             "require at least nnn% code coverage",
247             `Perform $(LINK2 $(ROOT_DIR)code_coverage.html, code coverage analysis) and generate
248             $(TT .lst) file with report.)
249 ---
250 dmd -cov -unittest myprog.d
251 ---
252             `,
253         ),
254         Option("D",
255             "generate documentation",
256             `$(P Generate $(LINK2 $(ROOT_DIR)spec/ddoc.html, documentation) from source.)
257             $(P Note: mind the $(LINK2 $(ROOT_DIR)spec/ddoc.html#security, security considerations).)
258             `,
259         ),
260         Option("Dd<directory>",
261             "write documentation file to directory",
262             `Write documentation file to $(I directory) . $(SWLINK -op)
263             can be used if the original package hierarchy should
264             be retained`,
265         ),
266         Option("Df<filename>",
267             "write documentation file to filename"
268         ),
269         Option("d",
270             "silently allow deprecated features and symbols",
271             `Silently allow $(DDLINK deprecate,deprecate,deprecated features) and use of symbols with
272             $(DDSUBLINK $(ROOT_DIR)spec/attribute, deprecated, deprecated attributes).`,
273         ),
274         Option("de",
275             "issue an error when deprecated features or symbols are used (halt compilation)"
276         ),
277         Option("dw",
278             "issue a message when deprecated features or symbols are used (default)"
279         ),
280         Option("debug",
281             "compile in debug code",
282             `Compile in $(LINK2 spec/version.html#debug, debug) code`,
283         ),
284         Option("debug=<level>",
285             "compile in debug code <= level",
286             `Compile in $(LINK2 spec/version.html#debug, debug level) &lt;= $(I level)`,
287         ),
288         Option("debug=<ident>",
289             "compile in debug code identified by ident",
290             `Compile in $(LINK2 spec/version.html#debug, debug identifier) $(I ident)`,
291         ),
292         Option("debuglib=<name>",
293             "set symbolic debug library to name",
294             `Link in $(I libname) as the default library when
295             compiling for symbolic debugging instead of $(B $(LIB)).
296             If $(I libname) is not supplied, then no default library is linked in.`
297         ),
298         Option("defaultlib=<name>",
299             "set default library to name",
300             `Link in $(I libname) as the default library when
301             not compiling for symbolic debugging instead of $(B $(LIB)).
302             If $(I libname) is not supplied, then no default library is linked in.`,
303         ),
304         Option("deps",
305             "print module dependencies (imports/file/version/debug/lib)"
306         ),
307         Option("deps=<filename>",
308             "write module dependencies to filename (only imports)",
309             `Without $(I filename), print module dependencies
310             (imports/file/version/debug/lib).
311             With $(I filename), write module dependencies as text to $(I filename)
312             (only imports).`,
313         ),
314         Option("extern-std=<standard>",
315             "set C++ name mangling compatibility with <standard>",
316             "Standards supported are:
317             $(UL
318                 $(LI $(I c++98) (default): Use C++98 name mangling,
319                     Sets `__traits(getTargetInfo, \"cppStd\")` to `199711`)
320                 $(LI $(I c++11): Use C++11 name mangling,
321                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201103`)
322                 $(LI $(I c++14): Use C++14 name mangling,
323                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`)
324                 $(LI $(I c++17): Use C++17 name mangling,
325                     Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`)
326             )",
327         ),
328         Option("extern-std=[h|help|?]",
329             "list all supported standards"
330         ),
331         Option("fPIC",
332             "generate position independent code",
333             TargetOS.all & ~(TargetOS.windows | TargetOS.macOS)
334         ),
335         Option("g",
336             "add symbolic debug info",
337             `$(WINDOWS
338                 Add CodeView symbolic debug info. See
339                 $(LINK2 http://dlang.org/windbg.html, Debugging on Windows).
340             )
341             $(UNIX
342                 Add symbolic debug info in Dwarf format
343                 for debuggers such as
344                 $(D gdb)
345             )`,
346         ),
347         Option("gf",
348             "emit debug info for all referenced types",
349             `Symbolic debug info is emitted for all types referenced by the compiled code,
350              even if the definition is in an imported file not currently being compiled.`,
351         ),
352         Option("gs",
353             "always emit stack frame"
354         ),
355         Option("gx",
356             "add stack stomp code",
357             `Adds stack stomp code, which overwrites the stack frame memory upon function exit.`,
358         ),
359         Option("H",
360             "generate 'header' file",
361             `Generate $(RELATIVE_LINK2 $(ROOT_DIR)interface-files, D interface file)`,
362         ),
363         Option("Hd=<directory>",
364             "write 'header' file to directory",
365             `Write D interface file to $(I dir) directory. $(SWLINK -op)
366             can be used if the original package hierarchy should
367             be retained.`,
368         ),
369         Option("Hf=<filename>",
370             "write 'header' file to filename"
371         ),
372         Option("HC[=[silent|verbose]]",
373             "generate C++ 'header' file",
374             `Generate C++ 'header' files using the given configuration:",
375             $(DL
376             $(DT silent)$(DD only list extern(C[++]) declarations (default))
377             $(DT verbose)$(DD also add comments for ignored declarations (e.g. extern(D)))
378             )`,
379         ),
380         Option("HC=[?|h|help]",
381             "list available modes for C++ 'header' file generation"
382         ),
383         Option("HCd=<directory>",
384             "write C++ 'header' file to directory"
385         ),
386         Option("HCf=<filename>",
387             "write C++ 'header' file to filename"
388         ),
389         Option("-help",
390             "print help and exit"
391         ),
392         Option("I=<directory>",
393             "look for imports also in directory"
394         ),
395         Option("i[=<pattern>]",
396             "include imported modules in the compilation",
397             q"{$(P Enables "include imports" mode, where the compiler will include imported
398              modules in the compilation, as if they were given on the command line. By default, when
399              this option is enabled, all imported modules are included except those in
400              druntime/phobos. This behavior can be overriden by providing patterns via `-i=<pattern>`.
401              A pattern of the form `-i=<package>` is an "inclusive pattern", whereas a pattern
402              of the form `-i=-<package>` is an "exclusive pattern". Inclusive patterns will include
403              all module's whose names match the pattern, whereas exclusive patterns will exclude them.
404              For example. all modules in the package `foo.bar` can be included using `-i=foo.bar` or excluded
405              using `-i=-foo.bar`. Note that each component of the fully qualified name must match the
406              pattern completely, so the pattern `foo.bar` would not match a module named `foo.barx`.)
407 
408              $(P The default behavior of excluding druntime/phobos is accomplished by internally adding a
409              set of standard exclusions, namely, `-i=-std -i=-core -i=-etc -i=-object`. Note that these
410              can be overriden with `-i=std -i=core -i=etc -i=object`.)
411 
412              $(P When a module matches multiple patterns, matches are prioritized by their component length, where
413              a match with more components takes priority (i.e. pattern `foo.bar.baz` has priority over `foo.bar`).)
414 
415              $(P By default modules that don't match any pattern will be included. However, if at
416              least one inclusive pattern is given, then modules not matching any pattern will
417              be excluded. This behavior can be overriden by usig `-i=.` to include by default or `-i=-.` to
418              exclude by default.)
419 
420              $(P Note that multiple `-i=...` options are allowed, each one adds a pattern.)}"
421         ),
422         Option("ignore",
423             "ignore unsupported pragmas"
424         ),
425         Option("inline",
426             "do function inlining",
427             `Inline functions at the discretion of the compiler.
428             This can improve performance, at the expense of making
429             it more difficult to use a debugger on it.`,
430         ),
431         Option("J=<directory>",
432             "look for string imports also in directory",
433             `Where to look for files for
434             $(LINK2 $(ROOT_DIR)spec/expression.html#ImportExpression, $(I ImportExpression))s.
435             This switch is required in order to use $(I ImportExpression)s.
436             $(I path) is a ; separated
437             list of paths. Multiple $(B -J)'s can be used, and the paths
438             are searched in the same order.`,
439         ),
440         Option("L=<linkerflag>",
441             "pass linkerflag to link",
442             `Pass $(I linkerflag) to the
443             $(WINDOWS linker $(OPTLINK))
444             $(UNIX linker), for example, ld`,
445         ),
446         Option("lib",
447             "generate library rather than object files",
448             `Generate library file as output instead of object file(s).
449             All compiled source files, as well as object files and library
450             files specified on the command line, are inserted into
451             the output library.
452             Compiled source modules may be partitioned into several object
453             modules to improve granularity.
454             The name of the library is taken from the name of the first
455             source module to be compiled. This name can be overridden with
456             the $(SWLINK -of) switch.`,
457         ),
458         Option("lowmem",
459             "enable garbage collection for the compiler",
460             `Enable the garbage collector for the compiler, reducing the
461             compiler memory requirements but increasing compile times.`,
462         ),
463         Option("m32",
464             "generate 32 bit code",
465             `$(UNIX Compile a 32 bit executable. This is the default for the 32 bit dmd.)
466             $(WINDOWS Compile a 32 bit executable. This is the default.
467             The generated object code is in OMF and is meant to be used with the
468             $(LINK2 http://www.digitalmars.com/download/freecompiler.html, Digital Mars C/C++ compiler)).`,
469             (TargetOS.all & ~TargetOS.dragonFlyBSD)  // available on all OS'es except DragonFly, which does not support 32-bit binaries
470         ),
471         Option("m32mscoff",
472             "generate 32 bit code and write MS-COFF object files",
473             TargetOS.windows
474         ),
475         Option("m64",
476             "generate 64 bit code",
477             `$(UNIX Compile a 64 bit executable. This is the default for the 64 bit dmd.)
478             $(WINDOWS The generated object code is in MS-COFF and is meant to be used with the
479             $(LINK2 https://msdn.microsoft.com/en-us/library/dd831853(v=vs.100).aspx, Microsoft Visual Studio 10)
480             or later compiler.`,
481         ),
482         Option("main",
483             "add default main() (e.g. for unittesting)",
484             `Add a default $(D main()) function when compiling. This is useful when
485             unittesting a library, as it enables running the unittests
486             in a library without having to manually define an entry-point function.`,
487         ),
488         Option("man",
489             "open web browser on manual page",
490             `$(WINDOWS
491                 Open default browser on this page
492             )
493             $(LINUX
494                 Open browser specified by the $(B BROWSER)
495                 environment variable on this page. If $(B BROWSER) is
496                 undefined, $(B x-www-browser) is assumed.
497             )
498             $(FREEBSD
499                 Open browser specified by the $(B BROWSER)
500                 environment variable on this page. If $(B BROWSER) is
501                 undefined, $(B x-www-browser) is assumed.
502             )
503             $(OSX
504                 Open browser specified by the $(B BROWSER)
505                 environment variable on this page. If $(B BROWSER) is
506                 undefined, $(B Safari) is assumed.
507             )`,
508         ),
509         Option("map",
510             "generate linker .map file",
511             `Generate a $(TT .map) file`,
512         ),
513         Option("mcpu=<id>",
514             "generate instructions for architecture identified by 'id'",
515             `Set the target architecture for code generation,
516             where:
517             $(DL
518             $(DT help)$(DD list alternatives)
519             $(DT baseline)$(DD the minimum architecture for the target platform (default))
520             $(DT avx)$(DD
521             generate $(LINK2 https://en.wikipedia.org/wiki/Advanced_Vector_Extensions, AVX)
522             instructions instead of $(LINK2 https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions, SSE)
523             instructions for vector and floating point operations.
524             Not available for 32 bit memory models other than OSX32.
525             )
526             $(DT native)$(DD use the architecture the compiler is running on)
527             )`,
528         ),
529         Option("mcpu=[h|help|?]",
530             "list all architecture options"
531         ),
532         Option("mixin=<filename>",
533             "expand and save mixins to file specified by <filename>"
534         ),
535         Option("mscrtlib=<libname>",
536             "MS C runtime library to reference from main/WinMain/DllMain",
537             "If building MS-COFF object files with -m64 or -m32mscoff, embed a reference to
538             the given C runtime library $(I libname) into the object file containing `main`,
539             `DllMain` or `WinMain` for automatic linking. The default is $(TT libcmt)
540             (release version with static linkage), the other usual alternatives are
541             $(TT libcmtd), $(TT msvcrt) and $(TT msvcrtd).
542             If no Visual C installation is detected, a wrapper for the redistributable
543             VC2010 dynamic runtime library and mingw based platform import libraries will
544             be linked instead using the LLD linker provided by the LLVM project.
545             The detection can be skipped explicitly if $(TT msvcrt120) is specified as
546             $(I libname).
547             If $(I libname) is empty, no C runtime library is automatically linked in.",
548             TargetOS.windows,
549         ),
550         Option("mv=<package.module>=<filespec>",
551             "use <filespec> as source file for <package.module>",
552             `Use $(I path/filename) as the source file for $(I package.module).
553             This is used when the source file path and names are not the same
554             as the package and module hierarchy.
555             The rightmost components of the  $(I path/filename) and $(I package.module)
556             can be omitted if they are the same.`,
557         ),
558         Option("noboundscheck",
559             "no array bounds checking (deprecated, use -boundscheck=off)",
560             `Turns off all array bounds checking, even for safe functions. $(RED Deprecated
561             (use $(TT $(SWLINK -boundscheck)=off) instead).)`,
562         ),
563         Option("O",
564             "optimize",
565             `Optimize generated code. For fastest executables, compile
566             with the $(TT $(SWLINK -O) $(SWLINK -release) $(SWLINK -inline) $(SWLINK -boundscheck)=off)
567             switches together.`,
568         ),
569         Option("o-",
570             "do not write object file",
571             `Suppress generation of object file. Useful in
572             conjuction with $(SWLINK -D) or $(SWLINK -H) flags.`
573         ),
574         Option("od=<directory>",
575             "write object & library files to directory",
576             `Write object files relative to directory $(I objdir)
577             instead of to the current directory. $(SWLINK -op)
578             can be used if the original package hierarchy should
579             be retained`,
580         ),
581         Option("of=<filename>",
582             "name output file to filename",
583             `Set output file name to $(I filename) in the output
584             directory. The output file can be an object file,
585             executable file, or library file depending on the other
586             switches.`
587         ),
588         Option("op",
589             "preserve source path for output files",
590             `Normally the path for $(B .d) source files is stripped
591             off when generating an object, interface, or Ddoc file
592             name. $(SWLINK -op) will leave it on.`,
593         ),
594         Option("preview=<name>",
595             "enable an upcoming language change identified by 'name'",
596             `Preview an upcoming language change identified by $(I id)`,
597         ),
598         Option("preview=[h|help|?]",
599             "list all upcoming language changes"
600         ),
601         Option("profile",
602             "profile runtime performance of generated code"
603         ),
604         Option("profile=gc",
605             "profile runtime allocations",
606             `$(LINK2 http://www.digitalmars.com/ctg/trace.html, profile)
607             the runtime performance of the generated code.
608             $(UL
609                 $(LI $(B gc): Instrument calls to memory allocation and write a report
610                 to the file $(TT profilegc.log) upon program termination.)
611             )`,
612         ),
613         Option("release",
614             "compile release version",
615             `Compile release version, which means not emitting run-time
616             checks for contracts and asserts. Array bounds checking is not
617             done for system and trusted functions, and assertion failures
618             are undefined behaviour.`
619         ),
620         Option("revert=<name>",
621             "revert language change identified by 'name'",
622             `Revert language change identified by $(I id)`,
623         ),
624         Option("revert=[h|help|?]",
625             "list all revertable language changes"
626         ),
627         Option("run <srcfile>",
628             "compile, link, and run the program srcfile",
629             `Compile, link, and run the program $(I srcfile) with the
630             rest of the
631             command line, $(I args...), as the arguments to the program.
632             No .$(OBJEXT) or executable file is left behind.`
633         ),
634         Option("shared",
635             "generate shared library (DLL)",
636             `$(UNIX Generate shared library)
637              $(WINDOWS Generate DLL library)`,
638         ),
639         Option("transition=<name>",
640             "help with language change identified by 'name'",
641             `Show additional info about language change identified by $(I id)`,
642         ),
643         Option("transition=[h|help|?]",
644             "list all language changes"
645         ),
646         Option("unittest",
647             "compile in unit tests",
648             `Compile in $(LINK2 spec/unittest.html, unittest) code, turns on asserts, and sets the
649              $(D unittest) $(LINK2 spec/version.html#PredefinedVersions, version identifier)`,
650         ),
651         Option("v",
652             "verbose",
653             `Enable verbose output for each compiler pass`,
654         ),
655         Option("vcolumns",
656             "print character (column) numbers in diagnostics"
657         ),
658         Option("verror-style=[digitalmars|gnu]",
659             "set the style for file/line number annotations on compiler messages",
660             `Set the style for file/line number annotations on compiler messages,
661             where:
662             $(DL
663             $(DT digitalmars)$(DD 'file(line[,column]): message'. This is the default.)
664             $(DT gnu)$(DD 'file:line[:column]: message', conforming to the GNU standard used by gcc and clang.)
665             )`,
666         ),
667         Option("verrors=<num>",
668             "limit the number of error messages (0 means unlimited)"
669         ),
670         Option("verrors=context",
671             "show error messages with the context of the erroring source line"
672         ),
673         Option("verrors=spec",
674             "show errors from speculative compiles such as __traits(compiles,...)"
675         ),
676         Option("-version",
677             "print compiler version and exit"
678         ),
679         Option("version=<level>",
680             "compile in version code >= level",
681             `Compile in $(LINK2 $(ROOT_DIR)spec/version.html#version, version level) >= $(I level)`,
682         ),
683         Option("version=<ident>",
684             "compile in version code identified by ident",
685             `Compile in $(LINK2 $(ROOT_DIR)spec/version.html#version, version identifier) $(I ident)`
686         ),
687         Option("vgc",
688             "list all gc allocations including hidden ones"
689         ),
690         Option("vtls",
691             "list all variables going into thread local storage"
692         ),
693         Option("vtemplates=[list-instances]",
694             "list statistics on template instantiations",
695             `An optional argument determines extra diagnostics,
696             where:
697             $(DL
698             $(DT list-instances)$(DD Also shows all instantiation contexts for each template.)
699             )`,
700         ),
701         Option("w",
702             "warnings as errors (compilation will halt)",
703             `Enable $(LINK2 $(ROOT_DIR)articles/warnings.html, warnings)`
704         ),
705         Option("wi",
706             "warnings as messages (compilation will continue)",
707             `Enable $(LINK2 $(ROOT_DIR)articles/warnings.html, informational warnings (i.e. compilation
708             still proceeds normally))`,
709         ),
710         Option("X",
711             "generate JSON file"
712         ),
713         Option("Xf=<filename>",
714             "write JSON file to filename"
715         ),
716         Option("Xcc=<driverflag>",
717             "pass driverflag to linker driver (cc)",
718             "Pass $(I driverflag) to the linker driver (`$CC` or `cc`)",
719             TargetOS.all & ~TargetOS.windows
720         ),
721     ];
722 
723     /// Representation of a CLI feature
724     struct Feature
725     {
726         string name; /// name of the feature
727         string paramName; // internal transition parameter name
728         string helpText; // detailed description of the feature
729         bool documented = true; // whether this option should be shown in the documentation
730         bool deprecated_; /// whether the feature is still in use
731     }
732 
733     /// Returns all available transitions
734     static immutable transitions = [
735         Feature("field", "vfield",
736             "list all non-mutable fields which occupy an object instance"),
737         Feature("complex", "vcomplex",
738             "give deprecation messages about all usages of complex or imaginary types"),
739         Feature("tls", "vtls",
740             "list all variables going into thread local storage"),
741         Feature("vmarkdown", "vmarkdown",
742             "list instances of Markdown replacements in Ddoc"),
743     ];
744 
745     /// Returns all available reverts
746     static immutable reverts = [
747         Feature("dip25", "noDIP25", "revert DIP25 changes https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md"),
748         Feature("markdown", "markdown", "disable Markdown replacements in Ddoc"),
749     ];
750 
751     /// Returns all available previews
752     static immutable previews = [
753         Feature("dip25", "useDIP25",
754             "implement https://github.com/dlang/DIPs/blob/master/DIPs/archive/DIP25.md (Sealed references)"),
755         Feature("dip1000", "vsafe",
756             "implement https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md (Scoped Pointers)"),
757         Feature("dip1008", "ehnogc",
758             "implement https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1008.md (@nogc Throwable)"),
759         Feature("dip1021", "useDIP1021",
760             "implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md (Mutable function arguments)"),
761         Feature("fieldwise", "fieldwise", "use fieldwise comparisons for struct equality"),
762         Feature("fixAliasThis", "fixAliasThis",
763             "when a symbol is resolved, check alias this scope before going to upper scopes"),
764         Feature("intpromote", "fix16997",
765             "fix integral promotions for unary + - ~ operators"),
766         Feature("dtorfields", "dtorFields",
767             "destruct fields of partially constructed objects"),
768         Feature("rvaluerefparam", "rvalueRefParam",
769             "enable rvalue arguments to ref parameters"),
770         Feature("nosharedaccess", "noSharedAccess",
771             "disable access to shared memory objects"),
772         Feature("in", "previewIn",
773             "`in` on parameters means `scope const [ref]` and accepts rvalues"),
774         // DEPRECATED previews
775         // trigger deprecation message once D repositories don't use this flag anymore
776         Feature("markdown", "markdown", "enable Markdown replacements in Ddoc", false, false),
777     ];
778 }
779 
780 /**
781 Formats the `Options` for CLI printing.
782 */
783 struct CLIUsage
784 {
785     /**
786     Returns a string of all available CLI options for the current targetOS.
787     Options are separated by newlines.
788     */
789     static string usage()
790     {
791         enum maxFlagLength = 18;
792         enum s = () {
793             char[] buf;
794             foreach (option; Usage.options)
795             {
796                 if (option.os.isCurrentTargetOS)
797                 {
798                     buf ~= "  -" ~ option.flag;
799                     // create new lines if the flag name is too long
800                     if (option.flag.length >= 17)
801                     {
802                             buf ~= "\n                    ";
803                     }
804                     else if (option.flag.length <= maxFlagLength)
805                     {
806                         const spaces = maxFlagLength - option.flag.length - 1;
807                         buf.length += spaces;
808                         buf[$ - spaces .. $] = ' ';
809                     }
810                     else
811                     {
812                             buf ~= "  ";
813                     }
814                     buf ~= option.helpText;
815                     buf ~= "\n";
816                 }
817             }
818             return cast(string) buf;
819         }();
820         return s;
821     }
822 
823     /// CPU architectures supported -mcpu=id
824     enum mcpuUsage = "CPU architectures supported by -mcpu=id:
825   =[h|help|?]    list information on all available choices
826   =baseline      use default architecture as determined by target
827   =avx           use AVX 1 instructions
828   =avx2          use AVX 2 instructions
829   =native        use CPU architecture that this compiler is running on
830 ";
831 
832     static string generateFeatureUsage(const Usage.Feature[] features, string flagName, string description)
833     {
834         enum maxFlagLength = 20;
835         auto buf = description.capitalize ~ " listed by -"~flagName~"=name:
836 ";
837         auto allTransitions = [Usage.Feature("all", null,
838             "Enables all available " ~ description)] ~ features;
839         foreach (t; allTransitions)
840         {
841             if (t.deprecated_)
842                 continue;
843             if (!t.documented)
844                 continue;
845             buf ~= "  =";
846             buf ~= t.name;
847             auto lineLength = 3 + t.name.length;
848             foreach (i; lineLength .. maxFlagLength)
849                 buf ~= " ";
850             buf ~= t.helpText;
851             buf ~= "\n";
852         }
853         return buf;
854     }
855 
856     /// Language changes listed by -transition=id
857     enum transitionUsage = generateFeatureUsage(Usage.transitions, "transition", "language transitions");
858 
859     /// Language changes listed by -revert
860     enum revertUsage = generateFeatureUsage(Usage.reverts, "revert", "revertable language changes");
861 
862     /// Language previews listed by -preview
863     enum previewUsage = generateFeatureUsage(Usage.previews, "preview", "upcoming language changes");
864 
865     /// Options supported by -checkaction=
866     enum checkActionUsage = "Behavior on assert/boundscheck/finalswitch failure:
867   =[h|help|?]    List information on all available choices
868   =D             Usual D behavior of throwing an AssertError
869   =C             Call the C runtime library assert failure function
870   =halt          Halt the program execution (very lightweight)
871   =context       Use D assert with context information (when available)
872 ";
873 
874     /// Options supported by -check
875     enum checkUsage = "Enable or disable specific checks:
876   =[h|help|?]           List information on all available choices
877   =assert[=[on|off]]    Assertion checking
878   =bounds[=[on|off]]    Array bounds checking
879   =in[=[on|off]]        Generate In contracts
880   =invariant[=[on|off]] Class/struct invariants
881   =out[=[on|off]]       Out contracts
882   =switch[=[on|off]]    Final switch failure checking
883   =on                   Enable all assertion checking
884                         (default for non-release builds)
885   =off                  Disable all assertion checking
886 ";
887 
888     /// Options supported by -extern-std
889     enum externStdUsage = "Available C++ standards:
890   =[h|help|?]           List information on all available choices
891   =c++98                Sets `__traits(getTargetInfo, \"cppStd\")` to `199711`
892   =c++11                Sets `__traits(getTargetInfo, \"cppStd\")` to `201103`
893   =c++14                Sets `__traits(getTargetInfo, \"cppStd\")` to `201402`
894   =c++17                Sets `__traits(getTargetInfo, \"cppStd\")` to `201703`
895 ";
896 
897     /// Options supported by -HC
898     enum hcUsage = "Available header generation modes:
899   =[h|help|?]           List information on all available choices
900   =silent               Silently ignore non-exern(C[++]) declarations
901   =verbose              Add a comment for ignored non-exern(C[++]) declarations
902 ";
903 }