view gen/cl_options.cpp @ 1064:f0b6549055ab

Make LDC work with LLVM trunk (s/LinkOnceLinkage/LinkOnceOdrLinkage/) Also moved the #defines for linkage types into a separate header instead of mars.h so we can #include revisions.h without having to rebuild the entire frontend every time we update. (I'm using revisions.h to get the LLVM revision for use in preprocessor conditionals. It should work with LLVM release 2.5, old trunk and new trunk)
author Frits van Bommel <fvbommel wxs.nl>
date Sun, 08 Mar 2009 16:13:10 +0100
parents d1ec9ff0e9ba
children 7ce8355fbcc6
line wrap: on
line source

#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:"));

cl::opt<bool> m32bits("m32",
    cl::desc("32 bit target"),
    cl::ZeroOrMore);

cl::opt<bool> m64bits("m64",
    cl::desc("64 bit target"),
    cl::ZeroOrMore);

cl::opt<std::string> mCPU("mcpu",
    cl::desc("Target a specific cpu type (-mcpu=help for details)"),
    cl::value_desc("cpu-name"),
    cl::init(""));

cl::list<std::string> mAttrs("mattr",
    cl::CommaSeparated,
    cl::desc("Target specific attributes (-mattr=help for details)"),
    cl::value_desc("a1,+a2,-a3,..."));

cl::opt<std::string> mTargetTriple("mtriple",
    cl::desc("Override target triple"));


// "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