ldc/driver/cl_options.cpp
2016-10-12 23:55:59 +02:00

461 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//===-- cl_options.cpp ----------------------------------------------------===//
//
// LDC the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
#include "driver/cl_options.h"
#include "mars.h"
#include "gen/cl_helpers.h"
#include "gen/logger.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/IR/DataLayout.h"
namespace opts {
// This vector is filled by parseCommandLine in main.cpp.
llvm::SmallVector<const char *, 32> allArguments;
/* Option parser that defaults to zero when no explicit number is given.
* i.e.: -cov --> value = 0
* -cov=9 --> value = 9
* -cov=101 --> error, value must be in range [0..100]
*/
struct CoverageParser : public cl::parser<unsigned char> {
#if LDC_LLVM_VER >= 307
explicit CoverageParser(cl::Option &O) : cl::parser<unsigned char>(O) {}
#endif
bool parse(cl::Option &O, llvm::StringRef /*ArgName*/, llvm::StringRef Arg,
unsigned char &Val) {
if (Arg == "") {
Val = 0;
return false;
}
if (Arg.getAsInteger(0, Val)) {
return O.error("'" + Arg +
"' value invalid for required coverage percentage");
}
if (Val > 100) {
return O.error("Required coverage percentage must be <= 100");
}
return false;
}
};
// Positional options first, in order:
cl::list<std::string> fileList(cl::Positional, cl::desc("files"));
cl::list<std::string> runargs(
"run",
cl::desc(
"Runs the resulting program, passing the remaining arguments to it"),
cl::Positional, cl::PositionalEatsArgs);
static cl::opt<ubyte, true> useDeprecated(
cl::desc("Allow deprecated code/language features:"), cl::ZeroOrMore,
clEnumValues(clEnumValN(0, "de", "Do not allow deprecated features"),
clEnumValN(1, "d", "Silently allow deprecated features"),
clEnumValN(2, "dw",
"Warn about the use of deprecated features")),
cl::location(global.params.useDeprecated), cl::init(2));
cl::opt<bool, true>
enforcePropertySyntax("property", cl::desc("Enforce property syntax"),
cl::ZeroOrMore,
cl::location(global.params.enforcePropertySyntax));
cl::opt<bool> compileOnly("c", cl::desc("Do not link"), cl::ZeroOrMore);
static cl::opt<bool, true> createStaticLib("lib",
cl::desc("Create static library"),
cl::ZeroOrMore,
cl::location(global.params.lib));
static cl::opt<bool, true> createSharedLib("shared",
cl::desc("Create shared library"),
cl::ZeroOrMore,
cl::location(global.params.dll));
static cl::opt<bool, true> verbose("v", cl::desc("Verbose"), cl::ZeroOrMore,
cl::location(global.params.verbose));
static cl::opt<bool, true>
vcolumns("vcolumns",
cl::desc("print character (column) numbers in diagnostics"),
cl::ZeroOrMore, cl::location(global.params.showColumns));
static cl::opt<bool, true>
vgc("vgc", cl::desc("list all gc allocations including hidden ones"),
cl::ZeroOrMore, cl::location(global.params.vgc));
static cl::opt<bool, true> verbose_cg("v-cg", cl::desc("Verbose codegen"),
cl::ZeroOrMore,
cl::location(global.params.verbose_cg));
static cl::opt<unsigned, true> errorLimit(
"verrors",
cl::desc("limit the number of error messages (0 means unlimited)"),
cl::location(global.errorLimit));
static cl::opt<ubyte, true>
warnings(cl::desc("Warnings:"), cl::ZeroOrMore,
clEnumValues(clEnumValN(1, "w", "Enable warnings"),
clEnumValN(2, "wi", "Enable informational warnings")),
cl::location(global.params.warnings), cl::init(0));
static cl::opt<bool, true> ignoreUnsupportedPragmas(
"ignore", cl::desc("Ignore unsupported pragmas"), cl::ZeroOrMore,
cl::location(global.params.ignoreUnsupportedPragmas));
static cl::opt<ubyte, true> debugInfo(
cl::desc("Generating debug information:"), cl::ZeroOrMore,
clEnumValues(clEnumValN(1, "g", "Generate debug information"),
clEnumValN(2, "gc", "Same as -g, but pretend to be C")),
cl::location(global.params.symdebug), cl::init(0));
static cl::opt<unsigned, true>
dwarfVersion("dwarf-version", cl::desc("Dwarf version"),
cl::location(global.params.dwarfVersion), cl::init(0),
cl::Hidden);
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>"));
cl::opt<std::string>
soname("soname", cl::value_desc("soname"), cl::Hidden, cl::Prefix,
cl::desc("Use <soname> as output shared library soname"));
// 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"));
// Disabling Red Zone
cl::opt<bool, true>
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<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);
// Json options
static cl::opt<bool, true> doJson("X", cl::desc("Generate JSON file"),
cl::location(global.params.doJsonGeneration));
cl::opt<std::string> jsonFile("Xf", cl::desc("Write JSON file to <filename>"),
cl::value_desc("filename"), cl::Prefix);
// Header generation options
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);
static cl::opt<bool, true> hdrKeepAllBodies(
"Hkeep-all-bodies", cl::desc("Keep all function bodies in .di files"),
cl::ZeroOrMore, cl::location(global.params.hdrKeepAllBodies));
static cl::opt<bool, true> unittest("unittest",
cl::desc("Compile in unit tests"),
cl::location(global.params.useUnitTests));
cl::opt<std::string>
ir2objCacheDir("ir2obj-cache", cl::desc("Use <cache dir> to cache object files for whole IR modules (experimental)"),
cl::value_desc("cache dir"));
static StringsAdapter strImpPathStore("J", global.params.fileImppath);
static cl::list<std::string, StringsAdapter>
stringImportPaths("J", cl::desc("Where to look for string imports"),
cl::value_desc("path"), cl::location(strImpPathStore),
cl::Prefix);
static cl::opt<bool, true>
addMain("main", cl::desc("Add empty main() (e.g. for unittesting)"),
cl::ZeroOrMore, cl::location(global.params.addMain));
// -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 = BOUNDSCHECKon;
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);
cl::list<std::string> transitions(
"transition",
cl::desc("help with language change identified by <idents>, use ? for list"),
cl::value_desc("idents"), cl::CommaSeparated);
static StringsAdapter linkSwitchStore("L", global.params.linkswitches);
static cl::list<std::string, StringsAdapter>
linkerSwitches("L", cl::desc("Pass <linkerflag> to the linker"),
cl::value_desc("linkerflag"), cl::location(linkSwitchStore),
cl::Prefix);
cl::opt<std::string>
moduleDeps("deps",
cl::desc("Write module dependencies to filename (only imports)"),
cl::value_desc("filename"), cl::ValueOptional);
cl::opt<std::string> 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"));
#if LDC_LLVM_VER >= 307
cl::opt<std::string>
mABI("mabi",
cl::desc("The name of the ABI to be targeted from the backend"),
cl::Hidden, cl::init(""));
#endif
cl::opt<llvm::Reloc::Model> mRelocModel(
"relocation-model", cl::desc("Relocation model"),
#if LDC_LLVM_VER < 309
cl::init(llvm::Reloc::Default),
#endif
clEnumValues(
#if LDC_LLVM_VER < 309
clEnumValN(llvm::Reloc::Default, "default",
"Target default relocation model"),
#endif
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")));
cl::opt<llvm::CodeModel::Model> mCodeModel(
"code-model", cl::desc("Code model"), cl::init(llvm::CodeModel::Default),
clEnumValues(
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")));
cl::opt<FloatABI::Type> mFloatABI(
"float-abi", cl::desc("ABI/operations to use for floating-point types:"),
cl::init(FloatABI::Default),
clEnumValues(
clEnumValN(FloatABI::Default, "default",
"Target default floating-point ABI"),
clEnumValN(FloatABI::Soft, "soft",
"Software floating-point ABI and operations"),
clEnumValN(FloatABI::SoftFP, "softfp",
"Soft-float ABI, but hardware floating-point instructions"),
clEnumValN(FloatABI::Hard, "hard",
"Hardware floating-point ABI and instructions")));
cl::opt<bool>
disableFpElim("disable-fp-elim",
cl::desc("Disable frame pointer elimination optimization"),
cl::init(false));
static cl::opt<bool, true, FlagParser<bool>>
asserts("asserts", cl::desc("(*) Enable assertions"),
cl::value_desc("bool"), cl::location(global.params.useAssert),
cl::init(true));
cl::opt<BOUNDSCHECK> boundsCheck(
"boundscheck", cl::desc("Enable array bounds check"),
clEnumValues(clEnumValN(BOUNDSCHECKoff, "off", "no array bounds checks"),
clEnumValN(BOUNDSCHECKsafeonly, "safeonly",
"array bounds checks for safe functions only"),
clEnumValN(BOUNDSCHECKon, "on",
"array bounds checks for all functions")),
cl::init(BOUNDSCHECKdefault));
static cl::opt<bool, true, FlagParser<bool>>
invariants("invariants", cl::desc("(*) Enable invariants"),
cl::location(global.params.useInvariants), cl::init(true));
static cl::opt<bool, true, FlagParser<bool>>
preconditions("preconditions",
cl::desc("(*) Enable function preconditions"),
cl::location(global.params.useIn), cl::init(true));
static cl::opt<bool, true, FlagParser<bool>>
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<bool>>
contracts("contracts",
cl::desc("(*) Enable function pre- and post-conditions"),
cl::location(ContractsSetter));
bool nonSafeBoundsChecks = true;
static MultiSetter ReleaseSetter(true, &global.params.useAssert,
&nonSafeBoundsChecks,
&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);
cl::opt<bool, true>
singleObj("singleobj", cl::desc("Create only a single output object file"),
cl::location(global.params.oneobj));
cl::opt<uint32_t, true> hashThreshold(
"hash-threshold",
cl::desc("hash symbol names longer than this threshold (experimental)"),
cl::location(global.params.hashThreshold), cl::init(0));
cl::opt<bool> linkonceTemplates(
"linkonce-templates",
cl::desc(
"Use linkonce_odr linkage for template symbols instead of weak_odr"),
cl::ZeroOrMore);
cl::opt<bool> disableLinkerStripDead(
"disable-linker-strip-dead",
cl::desc("Do not try to remove unused symbols during linking"),
cl::init(false));
cl::opt<bool, true>
allinst("allinst",
cl::desc("generate code for all template instantiations"),
cl::location(global.params.allInst));
cl::opt<unsigned, true> nestedTemplateDepth(
"template-depth",
cl::desc(
"(experimental) set maximum number of nested template instantiations"),
cl::location(global.params.nestedTmpl), cl::init(500));
#if LDC_LLVM_VER < 307
cl::opt<bool, true, FlagParser<bool>>
color("color", cl::desc("Force colored console output"),
cl::location(global.params.color));
#else
void CreateColorOption() {
new cl::opt<bool, true, FlagParser<bool>>(
"color", cl::desc("Force colored console output"),
cl::location(global.params.color));
}
#endif
cl::opt<bool, true>
useDIP25("dip25",
cl::desc("implement http://wiki.dlang.org/DIP25 (experimental)"),
cl::location(global.params.useDIP25));
cl::opt<unsigned char, true, CoverageParser> coverageAnalysis(
"cov", cl::desc("Compile-in code coverage analysis\n(use -cov=n for n% "
"minimum required coverage)"),
cl::location(global.params.covPercent), cl::ValueOptional, cl::init(127));
#if LDC_WITH_PGO
cl::opt<std::string>
genfileInstrProf("fprofile-instr-generate", cl::value_desc("filename"),
cl::desc("Generate instrumented code to collect "
"execution counts (e.g. for PGO)"),
cl::ValueOptional);
cl::opt<std::string> usefileInstrProf(
"fprofile-instr-use", cl::value_desc("filename"),
cl::desc("Use instrumentation data for profile-guided optimization"),
cl::ValueRequired);
#endif
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