#include "driver/cl_options.h" #include "gen/cl_helpers.h" #include "llvm/Target/TargetMachine.h" #if LDC_LLVM_VER >= 302 #include "llvm/DataLayout.h" #else #include "llvm/Target/TargetData.h" #endif #include "gen/logger.h" #include "llvm/Support/CommandLine.h" namespace opts { // Positional options first, in order: cl::list fileList( cl::Positional, cl::desc("files")); cl::list runargs("run", cl::desc("program args..."), cl::Positional, cl::PositionalEatsArgs); static cl::opt useDeprecated("d", cl::desc("Allow deprecated language features"), cl::ZeroOrMore, cl::location(global.params.useDeprecated)); #if DMDV2 cl::opt enforcePropertySyntax("property", cl::desc("Enforce property syntax"), cl::ZeroOrMore, cl::location(global.params.enforcePropertySyntax)); #endif static cl::opt 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 compileOnly("c", cl::desc("Do not link"), cl::ZeroOrMore); cl::opt createStaticLib("lib", cl::desc("Create static library"), cl::ZeroOrMore); cl::opt createSharedLib("shared", cl::desc("Create shared library"), cl::ZeroOrMore); static cl::opt verbose("v", cl::desc("Verbose"), cl::ZeroOrMore, cl::location(global.params.verbose)); static cl::opt verbose_cg("v-cg", cl::desc("Verbose codegen"), cl::ZeroOrMore, cl::location(global.params.verbose_cg)); static cl::opt warnings( cl::desc("Warnings:"), cl::ZeroOrMore, cl::values( clEnumValN(1, "w", "Enable warnings"), clEnumValN(2, "wi", "Enable informational warnings"), clEnumValEnd), cl::location(global.params.warnings), cl::init(0)); static cl::opt ignoreUnsupportedPragmas("ignore", cl::desc("Ignore unsupported pragmas"), cl::ZeroOrMore, cl::location(global.params.ignoreUnsupportedPragmas)); static cl::opt 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 annotate("annotate", cl::desc("Annotate the bitcode with human readable source code"), cl::location(global.params.llvmAnnotate)); cl::opt noAsm("noasm", cl::desc("Disallow use of inline assembler")); // Output file options cl::opt dontWriteObj("o-", cl::desc("Do not write object file")); cl::opt objectFile("of", cl::value_desc("filename"), cl::Prefix, cl::desc("Use as output file name")); cl::opt objectDir("od", cl::value_desc("objdir"), cl::Prefix, cl::desc("Write object files to directory ")); cl::opt soname("soname", cl::value_desc("soname"), cl::Hidden, cl::Prefix, cl::desc("Use as output shared library soname")); // Output format options cl::opt output_bc("output-bc", cl::desc("Write LLVM bitcode")); cl::opt output_ll("output-ll", cl::desc("Write LLVM IR")); cl::opt output_s("output-s", cl::desc("Write native assembly")); cl::opt output_o("output-o", cl::desc("Write native object")); // Disabling Red Zone cl::opt disableRedZone("disable-red-zone", cl::desc("Do not emit code that uses the red zone."), cl::location(global.params.disableRedZone), cl::init(false)); // DDoc options static cl::opt doDdoc("D", cl::desc("Generate documentation"), cl::location(global.params.doDocComments)); cl::opt ddocDir("Dd", cl::desc("Write documentation file to directory"), cl::value_desc("docdir"), cl::Prefix); cl::opt ddocFile("Df", cl::desc("Write documentation file to "), cl::value_desc("filename"), cl::Prefix); // Json options static cl::opt doJson("X", cl::desc("generate JSON file"), cl::location(global.params.doXGeneration)); cl::opt jsonFile("Xf", cl::desc("write JSON file to "), cl::value_desc("filename"), cl::Prefix); // Header generation options static cl::opt doHdrGen("H", cl::desc("Generate 'header' file"), cl::location(global.params.doHdrGeneration)); cl::opt hdrDir("Hd", cl::desc("Write 'header' file to directory"), cl::value_desc("hdrdir"), cl::Prefix); cl::opt hdrFile("Hf", cl::desc("Write 'header' file to "), cl::value_desc("filename"), cl::Prefix); static cl::opt unittest("unittest", cl::desc("Compile in unit tests"), cl::location(global.params.useUnitTests)); static StringsAdapter strImpPathStore("J", global.params.fileImppath); static cl::list 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 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 debugVersionsOption("d-debug", cl::desc("Compile in debug code >= or identified by ."), 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 versions("d-version", cl::desc("Compile in version code >= or identified by "), cl::value_desc("level/idents"), cl::CommaSeparated); static StringsAdapter linkSwitchStore("L", global.params.linkswitches); static cl::list linkerSwitches("L", cl::desc("Pass to the linker"), cl::value_desc("linkerflag"), cl::location(linkSwitchStore), cl::Prefix); cl::opt moduleDepsFile("deps", cl::desc("Write module dependencies to filename"), cl::value_desc("filename")); cl::opt mArch("march", cl::desc("Architecture to generate code for:")); cl::opt m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore); cl::opt m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore); cl::opt mCPU("mcpu", cl::desc("Target a specific cpu type (-mcpu=help for details)"), cl::value_desc("cpu-name"), cl::init("")); cl::list mAttrs("mattr", cl::CommaSeparated, cl::desc("Target specific attributes (-mattr=help for details)"), cl::value_desc("a1,+a2,-a3,...")); cl::opt mTargetTriple("mtriple", cl::desc("Override target triple")); cl::opt mRelocModel("relocation-model", cl::desc("Relocation model"), cl::init(llvm::Reloc::Default), cl::values( clEnumValN(llvm::Reloc::Default, "default", "Target default relocation model"), clEnumValN(llvm::Reloc::Static, "static", "Non-relocatable code"), clEnumValN(llvm::Reloc::PIC_, "pic", "Fully relocatable, position independent code"), clEnumValN(llvm::Reloc::DynamicNoPIC, "dynamic-no-pic", "Relocatable external references, non-relocatable code"), clEnumValEnd)); cl::opt mCodeModel("code-model", cl::desc("Code model"), cl::init(llvm::CodeModel::Default), cl::values( clEnumValN(llvm::CodeModel::Default, "default", "Target default code model"), clEnumValN(llvm::CodeModel::Small, "small", "Small code model"), clEnumValN(llvm::CodeModel::Kernel, "kernel", "Kernel code model"), clEnumValN(llvm::CodeModel::Medium, "medium", "Medium code model"), clEnumValN(llvm::CodeModel::Large, "large", "Large code model"), clEnumValEnd)); // "Hidden debug switches" // Are these ever used? static cl::opt debuga("hidden-debug--a", cl::desc("Hidden debug option A"), cl::ReallyHidden, cl::location(global.params.debuga)); static cl::opt debugb("hidden-debug-b", cl::desc("Hidden debug option B"), cl::ReallyHidden, cl::location(global.params.debugb)); static cl::opt debugc("hidden-debug-c", cl::desc("Hidden debug option C"), cl::ReallyHidden, cl::location(global.params.debugc)); static cl::opt debugf("hidden-debug-f", cl::desc("Hidden debug option F"), cl::ReallyHidden, cl::location(global.params.debugf)); static cl::opt debugr("hidden-debug-r", cl::desc("Hidden debug option R"), cl::ReallyHidden, cl::location(global.params.debugr)); static cl::opt debugw("hidden-debug-w", cl::desc("Hidden debug option W"), cl::ReallyHidden, cl::location(global.params.debugw)); static cl::opt debugx("hidden-debug-x", cl::desc("Hidden debug option X"), cl::ReallyHidden, cl::location(global.params.debugx)); static cl::opt debugy("hidden-debug-y", cl::desc("Hidden debug option Y"), cl::ReallyHidden, cl::location(global.params.debugy)); static cl::opt asserts("asserts", cl::desc("(*) Enable assertions"), cl::value_desc("bool"), cl::location(global.params.useAssert), cl::init(true)); static cl::opt boundsChecks("boundscheck", cl::desc("(*) Enable array bounds checks"), cl::value_desc("bool"), cl::location(global.params.useArrayBounds), cl::init(true)); static cl::opt invariants("invariants", cl::desc("(*) Enable invariants"), cl::location(global.params.useInvariants), cl::init(true)); static cl::opt preconditions("preconditions", cl::desc("(*) Enable function preconditions"), cl::location(global.params.useIn), cl::init(true)); static cl::opt 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 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 > release("release", cl::desc("Disables asserts, invariants, contracts and boundscheck"), cl::location(ReleaseSetter), cl::ValueDisallowed); cl::opt singleObj("singleobj", cl::desc("Create only a single output object file"), cl::location(global.params.singleObj)); cl::opt linkonceTemplates("linkonce-templates", cl::desc("Use linkonce_odr linkage for template symbols instead of weak_odr"), cl::ZeroOrMore); 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