diff gen/cl_options.cpp @ 986:a8cb25d478c4

Use LLVM-style command line (instead of DMD-style) Note: For a backward compatible interface, use the new bin/ldmd script. It supports all old options while passing on anything it doesn't recognize. Some changes caused by this: * -debug and -version are now -d-debug and -d-version due to a conflict with standard LLVM options. * All "flag" options now allow an optional =true/=1/=false/=0 suffix. * Some "hidden debug switches" starting with "--" were renamed because LLVM doesn't care about the number of dashes, so they were conflicting with other options (such as -c). The new versions start with "-hidden-debug-" instead of "--" * --help works, but has a non-zero exit code. This breaks some Tango scripts which use it to test for compiler existence. See tango.patch. Some changes not (directly) caused by this; * (-enable/-disable)-FOO options are now available for pre- and postconditions. * -march is used instead of -m (like other LLVM programs), but -m is an alias for it. * -defaultlib, -debuglib, -d-debug and -d-version allow comma-separated values. The effect should be identical to specifying the same option multiple times. I decided against allowing these for some other options because paths might contain commas on some systems. * -fPIC is removed in favor of the standard LLVM option -relocation-model=pic Bug: * If -run is specified as the last argument in DFLAGS, no error is generated. (Not very serious IMHO)
author Frits van Bommel <fvbommel wxs.nl>
date Wed, 25 Feb 2009 17:34:51 +0100
parents
children 2667e3a145be
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/cl_options.cpp	Wed Feb 25 17:34:51 2009 +0100
@@ -0,0 +1,337 @@
+#include "gen/cl_options.h"
+#include "gen/cl_helpers.h"
+
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetData.h"
+
+#include "gen/logger.h"
+
+#include "llvm/Support/CommandLine.h"
+
+namespace opts {
+
+// Positional options first, in order:
+cl::list<std::string> fileList(
+    cl::Positional, cl::desc("files"));
+
+cl::list<std::string> runargs("run",
+    cl::desc("program args..."),
+    cl::Positional,
+    cl::PositionalEatsArgs);
+
+
+
+// TODO: Replace this with a proper PassNameParser-based solution
+static cl::opt<bool, true> doInline("inline",
+    cl::desc("Do function inlining"),
+    cl::location(global.params.llvmInline),
+    cl::ZeroOrMore,
+    cl::init(false));
+
+
+
+static cl::opt<bool, true> useDeprecated("d",
+    cl::desc("Allow deprecated language features"),
+    cl::ZeroOrMore,
+    cl::location(global.params.useDeprecated));
+
+static cl::opt<char, true> useDv1(
+    cl::desc("Force language version:"),
+    cl::ZeroOrMore,
+    cl::values(
+        clEnumValN(1, "v1", "D language version 1.00"),
+        clEnumValEnd),
+    cl::location(global.params.Dversion),
+    cl::init(2),
+    cl::Hidden);
+
+cl::opt<bool> compileOnly("c",
+    cl::desc("Do not link"),
+    cl::ZeroOrMore);
+
+static cl::opt<bool, true> verbose("v",
+    cl::desc("Verbose"),
+    cl::ZeroOrMore,
+    cl::location(global.params.verbose));
+
+static cl::opt<bool, true> warnings("w",
+    cl::desc("Enable warnings"),
+    cl::ZeroOrMore,
+    cl::location(global.params.warnings));
+
+
+static cl::opt<char, true> optimizeLevel(
+    cl::desc("Setting the optimization level:"),
+    cl::ZeroOrMore,
+    cl::values(
+        clEnumValN(2, "O",  "Equivalent to -O2"),
+        clEnumValN(0, "O0", "Trivial optimizations only"),
+        clEnumValN(1, "O1", "Simple optimizations"),
+        clEnumValN(2, "O2", "Good optimizations"),
+        clEnumValN(3, "O3", "Aggressive optimizations"),
+        clEnumValN(4, "O4", "Link-time optimization"), //  not implemented?
+        clEnumValN(5, "O5", "Link-time optimization"), //  not implemented?
+        clEnumValEnd),
+    cl::location(global.params.optimizeLevel),
+    cl::init(-1));
+
+static cl::opt<char, true> debugInfo(
+    cl::desc("Generating debug information:"),
+    cl::ZeroOrMore,
+    cl::values(
+        clEnumValN(1, "g",  "Generate debug information"),
+        clEnumValN(2, "gc", "Same as -g, but pretend to be C"),
+        clEnumValEnd),
+    cl::location(global.params.symdebug),
+    cl::init(0));
+
+
+static cl::opt<bool, true> annotate("annotate",
+    cl::desc("Annotate the bitcode with human readable source code"),
+    cl::location(global.params.llvmAnnotate));
+
+cl::opt<bool> noAsm("noasm",
+    cl::desc("Disallow use of inline assembler"));
+
+// Output file options
+cl::opt<bool> dontWriteObj("o-",
+    cl::desc("Do not write object file"));
+
+cl::opt<std::string> objectFile("of",
+    cl::value_desc("filename"),
+    cl::Prefix,
+    cl::desc("Use <filename> as output file name"));
+
+cl::opt<std::string> objectDir("od",
+    cl::value_desc("objdir"),
+    cl::Prefix,
+    cl::desc("Write object files to directory <objdir>"));
+
+
+// Output format options
+cl::opt<bool> output_bc("output-bc",
+    cl::desc("Write LLVM bitcode"));
+
+cl::opt<bool> output_ll("output-ll",
+    cl::desc("Write LLVM IR"));
+
+cl::opt<bool> output_s("output-s",
+    cl::desc("Write native assembly"));
+
+cl::opt<cl::boolOrDefault> output_o("output-o",
+    cl::desc("Write native object"));
+
+
+// DDoc options
+static cl::opt<bool, true> doDdoc("D",
+    cl::desc("Generate documentation"),
+    cl::location(global.params.doDocComments));
+
+cl::opt<std::string> ddocDir("Dd",
+    cl::desc("Write documentation file to <docdir> directory"),
+    cl::value_desc("docdir"),
+    cl::Prefix);
+
+cl::opt<std::string> ddocFile("Df",
+    cl::desc("Write documentation file to <filename>"),
+    cl::value_desc("filename"),
+    cl::Prefix);
+
+
+// Header generation options
+#ifdef _DH
+static cl::opt<bool, true> doHdrGen("H",
+    cl::desc("Generate 'header' file"),
+    cl::location(global.params.doHdrGeneration));
+
+cl::opt<std::string> hdrDir("Hd",
+    cl::desc("Write 'header' file to <hdrdir> directory"),
+    cl::value_desc("hdrdir"),
+    cl::Prefix);
+
+cl::opt<std::string> hdrFile("Hf",
+    cl::desc("Write 'header' file to <filename>"),
+    cl::value_desc("filename"),
+    cl::Prefix);
+#endif
+
+
+
+static cl::opt<bool, true> unittest("unittest",
+    cl::desc("Compile in unit tests"),
+    cl::location(global.params.useUnitTests));
+
+
+static ArrayAdapter strImpPathStore("J", global.params.fileImppath);
+static cl::list<std::string, ArrayAdapter> stringImportPaths("J",
+    cl::desc("Where to look for string imports"),
+    cl::value_desc("path"),
+    cl::location(strImpPathStore),
+    cl::Prefix);
+
+
+
+// -d-debug is a bit messy, it has 3 modes:
+// -d-debug=ident, -d-debug=level and -d-debug (without argument)
+// That last of these must be acted upon immediately to ensure proper
+// interaction with other options, so it needs some special handling:
+std::vector<std::string> debugArgs;
+
+struct D_DebugStorage {
+    void push_back(const std::string& str) {
+        if (str.empty()) {
+            // Bare "-d-debug" has a special meaning.
+            global.params.useAssert = true;
+            global.params.useArrayBounds = true;
+            global.params.useInvariants = true;
+            global.params.useIn = true;
+            global.params.useOut = true;
+            debugArgs.push_back("1");
+        } else {
+            debugArgs.push_back(str);
+        }
+    }
+};
+
+static D_DebugStorage dds;
+
+// -debug is already declared in LLVM (at least, in debug builds),
+// so we need to be a bit more verbose.
+static cl::list<std::string, D_DebugStorage> debugVersionsOption("d-debug",
+    cl::desc("Compile in debug code >= <level> or identified by <idents>."),
+    cl::value_desc("level/idents"),
+    cl::location(dds),
+    cl::CommaSeparated,
+    cl::ValueOptional);
+
+
+
+// -version is also declared in LLVM, so again we need to be a bit more verbose.
+cl::list<std::string> versions("d-version",
+    cl::desc("Compile in version code >= <level> or identified by <idents>"),
+    cl::value_desc("level/idents"),
+    cl::CommaSeparated);
+
+
+static ArrayAdapter linkSwitchStore("L", global.params.linkswitches);
+static cl::list<std::string, ArrayAdapter> linkerSwitches("L",
+    cl::desc("Pass <linkerflag> to the linker"),
+    cl::value_desc("linkerflag"),
+    cl::location(linkSwitchStore),
+    cl::Prefix);
+
+
+cl::opt<const llvm::TargetMachineRegistry::entry*, false,
+        llvm::RegistryParser<llvm::TargetMachine> > mArch("march",
+    cl::desc("Architecture to generate code for:"));
+
+static cl::alias m("m",
+    cl::desc("Alias for '-march' for backwards compatibility"),
+    cl::Prefix,
+    cl::aliasopt(mArch));
+
+
+static cl::opt<OS, true> os("t",
+    cl::desc("Emit code for the specified OS:"),
+    cl::values(
+#define ENUMVAL_N(Name, Desc) clEnumValN(OS##Name, #Name, Desc)
+#define ENUMVAL(Name) ENUMVAL_N(Name, #Name)
+        ENUMVAL(Linux),
+        ENUMVAL(Windows),
+        ENUMVAL_N(MacOSX, "Mac OS X"),
+        ENUMVAL(FreeBSD),
+        ENUMVAL(Solaris),
+#undef ENUMVAL
+#undef ENUMVAL_N
+        clEnumValEnd),
+    cl::Prefix,
+    cl::location(global.params.os));
+
+
+// "Hidden debug switches"
+// Are these ever used?
+static cl::opt<bool, true> debuga("hidden-debug--a",
+    cl::desc("Hidden debug option A"),
+    cl::ReallyHidden,
+    cl::location(global.params.debuga));
+static cl::opt<bool, true> debugb("hidden-debug-b",
+    cl::desc("Hidden debug option B"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugb));
+static cl::opt<bool, true> debugc("hidden-debug-c",
+    cl::desc("Hidden debug option C"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugc));
+static cl::opt<bool, true> debugf("hidden-debug-f",
+    cl::desc("Hidden debug option F"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugf));
+static cl::opt<bool, true> debugr("hidden-debug-r",
+    cl::desc("Hidden debug option R"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugr));
+static cl::opt<bool, true> debugw("hidden-debug-w",
+    cl::desc("Hidden debug option W"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugw));
+static cl::opt<bool, true> debugx("hidden-debug-x",
+    cl::desc("Hidden debug option X"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugx));
+static cl::opt<bool, true> debugy("hidden-debug-y",
+    cl::desc("Hidden debug option Y"),
+    cl::ReallyHidden,
+    cl::location(global.params.debugy));
+
+
+static cl::opt<bool, true, FlagParser> asserts("asserts",
+    cl::desc("(*) Enable assertions"),
+    cl::value_desc("bool"),
+    cl::location(global.params.useAssert),
+    cl::init(true));
+
+static cl::opt<bool, true, FlagParser> boundsChecks("boundscheck",
+    cl::desc("(*) Enable array bounds checks"),
+    cl::value_desc("bool"),
+    cl::location(global.params.useArrayBounds),
+    cl::init(true));
+
+static cl::opt<bool, true, FlagParser> invariants("invariants",
+    cl::desc("(*) Enable invariants"),
+    cl::location(global.params.useInvariants),
+    cl::init(true));
+
+static cl::opt<bool, true, FlagParser> preconditions("preconditions",
+    cl::desc("(*) Enable function preconditions"),
+    cl::location(global.params.useIn),
+    cl::init(true));
+
+static cl::opt<bool, true, FlagParser> postconditions("postconditions",
+    cl::desc("(*) Enable function postconditions"),
+    cl::location(global.params.useOut),
+    cl::init(true));
+
+
+static MultiSetter ContractsSetter(false, 
+    &global.params.useIn, &global.params.useOut, NULL);
+static cl::opt<MultiSetter, true, FlagParser> contracts("contracts",
+    cl::desc("(*) Enable function pre- and post-conditions"),
+    cl::location(ContractsSetter));
+
+static MultiSetter ReleaseSetter(true, &global.params.useAssert,
+    &global.params.useArrayBounds, &global.params.useInvariants,
+    &global.params.useOut, &global.params.useIn, NULL);
+static cl::opt<MultiSetter, true, cl::parser<bool> > release("release",
+    cl::desc("Disables asserts, invariants, contracts and boundscheck"),
+    cl::location(ReleaseSetter),
+    cl::ValueDisallowed);
+
+
+static cl::extrahelp footer("\n"
+"-d-debug can also be specified without options, in which case it enables all\n"
+"debug checks (i.e. (asserts, boundchecks, contracts and invariants) as well\n"
+"as acting as -d-debug=1\n\n"
+"Options marked with (*) also have a -disable-FOO variant with inverted\n"
+"meaning.\n");
+
+} // namespace opts