Rework LDMD command-line translation and add -verrors-spec

Simplify LDMD quite a bit by translating the few different command-line
options directly in-place. This puts some more stress onto LDC's
command-line parsing, especially due to multiple occurrences of a single
Boolean option (e.g., '-o-') or mixtures of `-m64` and `-m32` etc. for
dmd-testsuite.

Also add new command-line option `-verrors-spec` showing gagged errors
(DMD's equivalent is `-verrors=<spec|limit>`) and sync the usage text with
DMD. LDMD now also recognizes `-h` (and `/?` on Windows).
This commit is contained in:
Martin 2017-02-05 23:57:19 +01:00
parent 99795b8a57
commit 84e74e3932
4 changed files with 332 additions and 719 deletions

View file

@ -88,11 +88,11 @@ static cl::opt<bool, true> verbose("v", cl::desc("Verbose"), cl::ZeroOrMore,
static cl::opt<bool, true> static cl::opt<bool, true>
vcolumns("vcolumns", vcolumns("vcolumns",
cl::desc("print character (column) numbers in diagnostics"), cl::desc("Print character (column) numbers in diagnostics"),
cl::ZeroOrMore, cl::location(global.params.showColumns)); cl::ZeroOrMore, cl::location(global.params.showColumns));
static cl::opt<bool, true> static cl::opt<bool, true>
vgc("vgc", cl::desc("list all gc allocations including hidden ones"), vgc("vgc", cl::desc("List all gc allocations including hidden ones"),
cl::ZeroOrMore, cl::location(global.params.vgc)); cl::ZeroOrMore, cl::location(global.params.vgc));
static cl::opt<bool, true> verbose_cg("v-cg", cl::desc("Verbose codegen"), static cl::opt<bool, true> verbose_cg("v-cg", cl::desc("Verbose codegen"),
@ -100,10 +100,16 @@ static cl::opt<bool, true> verbose_cg("v-cg", cl::desc("Verbose codegen"),
cl::location(global.params.verbose_cg)); cl::location(global.params.verbose_cg));
static cl::opt<unsigned, true> errorLimit( static cl::opt<unsigned, true> errorLimit(
"verrors", "verrors", cl::ZeroOrMore,
cl::desc("limit the number of error messages (0 means unlimited)"), cl::desc("Limit the number of error messages (0 means unlimited)"),
cl::location(global.errorLimit)); cl::location(global.errorLimit));
static cl::opt<bool, true>
showGaggedErrors("verrors-spec", cl::ZeroOrMore,
cl::location(global.params.showGaggedErrors),
cl::desc("Show errors from speculative compiles such as "
"__traits(compiles,...)"));
static cl::opt<ubyte, true> warnings( static cl::opt<ubyte, true> warnings(
cl::desc("Warnings:"), cl::ZeroOrMore, cl::desc("Warnings:"), cl::ZeroOrMore,
clEnumValues( clEnumValues(
@ -133,27 +139,31 @@ static cl::opt<unsigned, true>
cl::opt<bool> noAsm("noasm", cl::desc("Disallow use of inline assembler")); cl::opt<bool> noAsm("noasm", cl::desc("Disallow use of inline assembler"));
// Output file options // Output file options
cl::opt<bool> dontWriteObj("o-", cl::desc("Do not write object file")); cl::opt<bool> dontWriteObj("o-", cl::desc("Do not write object file"),
cl::ZeroOrMore);
cl::opt<std::string> objectFile("of", cl::value_desc("filename"), cl::Prefix, cl::opt<std::string> objectFile("of", cl::value_desc("filename"), cl::Prefix,
cl::desc("Use <filename> as output file name")); cl::desc("Use <filename> as output file name"),
cl::ZeroOrMore);
cl::opt<std::string> cl::opt<std::string>
objectDir("od", cl::value_desc("objdir"), cl::Prefix, objectDir("od", cl::value_desc("directory"), cl::Prefix, cl::ZeroOrMore,
cl::desc("Write object files to directory <objdir>")); cl::desc("Write object files to <directory>"));
cl::opt<std::string> cl::opt<std::string>
soname("soname", cl::value_desc("soname"), cl::Hidden, cl::Prefix, soname("soname", cl::value_desc("soname"), cl::Hidden, cl::Prefix,
cl::desc("Use <soname> as output shared library soname")); cl::desc("Use <soname> as output shared library soname"));
// Output format options // Output format options
cl::opt<bool> output_bc("output-bc", cl::desc("Write LLVM bitcode")); cl::opt<bool> output_bc("output-bc", cl::desc("Write LLVM bitcode"),
cl::ZeroOrMore);
cl::opt<bool> output_ll("output-ll", cl::desc("Write LLVM IR")); cl::opt<bool> output_ll("output-ll", cl::desc("Write LLVM IR"), cl::ZeroOrMore);
cl::opt<bool> output_s("output-s", cl::desc("Write native assembly")); cl::opt<bool> output_s("output-s", cl::desc("Write native assembly"),
cl::ZeroOrMore);
cl::opt<cl::boolOrDefault> output_o("output-o", cl::opt<cl::boolOrDefault> output_o("output-o", cl::ZeroOrMore,
cl::desc("Write native object")); cl::desc("Write native object"));
static cl::opt<bool, true> static cl::opt<bool, true>
@ -170,33 +180,36 @@ cl::opt<bool, true>
// DDoc options // DDoc options
static cl::opt<bool, true> doDdoc("D", cl::desc("Generate documentation"), static cl::opt<bool, true> doDdoc("D", cl::desc("Generate documentation"),
cl::location(global.params.doDocComments)); cl::location(global.params.doDocComments),
cl::ZeroOrMore);
cl::opt<std::string> cl::opt<std::string>
ddocDir("Dd", cl::desc("Write documentation file to <docdir> directory"), ddocDir("Dd", cl::desc("Write documentation file to <directory>"),
cl::value_desc("docdir"), cl::Prefix); cl::value_desc("directory"), cl::Prefix, cl::ZeroOrMore);
cl::opt<std::string> cl::opt<std::string>
ddocFile("Df", cl::desc("Write documentation file to <filename>"), ddocFile("Df", cl::desc("Write documentation file to <filename>"),
cl::value_desc("filename"), cl::Prefix); cl::value_desc("filename"), cl::Prefix, cl::ZeroOrMore);
// Json options // Json options
static cl::opt<bool, true> doJson("X", cl::desc("Generate JSON file"), static cl::opt<bool, true> doJson("X", cl::desc("Generate JSON file"),
cl::ZeroOrMore,
cl::location(global.params.doJsonGeneration)); cl::location(global.params.doJsonGeneration));
cl::opt<std::string> jsonFile("Xf", cl::desc("Write JSON file to <filename>"), cl::opt<std::string> jsonFile("Xf", cl::desc("Write JSON file to <filename>"),
cl::value_desc("filename"), cl::Prefix); cl::value_desc("filename"), cl::Prefix,
cl::ZeroOrMore);
// Header generation options // Header generation options
static cl::opt<bool, true> static cl::opt<bool, true>
doHdrGen("H", cl::desc("Generate 'header' file"), doHdrGen("H", cl::desc("Generate 'header' file"), cl::ZeroOrMore,
cl::location(global.params.doHdrGeneration)); cl::location(global.params.doHdrGeneration));
cl::opt<std::string> cl::opt<std::string>
hdrDir("Hd", cl::desc("Write 'header' file to <hdrdir> directory"), hdrDir("Hd", cl::desc("Write 'header' file to <directory>"),
cl::value_desc("hdrdir"), cl::Prefix); cl::value_desc("directory"), cl::Prefix, cl::ZeroOrMore);
cl::opt<std::string> hdrFile("Hf", cl::opt<std::string> hdrFile("Hf", cl::ZeroOrMore,
cl::desc("Write 'header' file to <filename>"), cl::desc("Write 'header' file to <filename>"),
cl::value_desc("filename"), cl::Prefix); cl::value_desc("filename"), cl::Prefix);
@ -205,7 +218,7 @@ cl::opt<bool>
cl::desc("Keep all function bodies in .di files"), cl::desc("Keep all function bodies in .di files"),
cl::ZeroOrMore); cl::ZeroOrMore);
static cl::opt<bool, true> unittest("unittest", static cl::opt<bool, true> unittest("unittest", cl::ZeroOrMore,
cl::desc("Compile in unit tests"), cl::desc("Compile in unit tests"),
cl::location(global.params.useUnitTests)); cl::location(global.params.useUnitTests));
@ -215,10 +228,9 @@ cl::opt<std::string>
cl::value_desc("cache dir")); cl::value_desc("cache dir"));
static StringsAdapter strImpPathStore("J", global.params.fileImppath); static StringsAdapter strImpPathStore("J", global.params.fileImppath);
static cl::list<std::string, StringsAdapter> static cl::list<std::string, StringsAdapter> stringImportPaths(
stringImportPaths("J", cl::desc("Where to look for string imports"), "J", cl::desc("Look for string imports also in <directory>"),
cl::value_desc("path"), cl::location(strImpPathStore), cl::value_desc("directory"), cl::location(strImpPathStore), cl::Prefix);
cl::Prefix);
static cl::opt<bool, true> static cl::opt<bool, true>
addMain("main", cl::desc("Add default main() (e.g. for unittesting)"), addMain("main", cl::desc("Add default main() (e.g. for unittesting)"),
@ -252,7 +264,7 @@ static D_DebugStorage dds;
// so we need to be a bit more verbose. // so we need to be a bit more verbose.
static cl::list<std::string, D_DebugStorage> debugVersionsOption( static cl::list<std::string, D_DebugStorage> debugVersionsOption(
"d-debug", "d-debug",
cl::desc("Compile in debug code >= <level> or identified by <idents>."), cl::desc("Compile in debug code >= <level> or identified by <idents>"),
cl::value_desc("level/idents"), cl::location(dds), cl::CommaSeparated, cl::value_desc("level/idents"), cl::location(dds), cl::CommaSeparated,
cl::ValueOptional); cl::ValueOptional);
@ -264,7 +276,7 @@ cl::list<std::string> versions(
cl::list<std::string> transitions( cl::list<std::string> transitions(
"transition", "transition",
cl::desc("help with language change identified by <idents>, use ? for list"), cl::desc("Help with language change identified by <idents>, use ? for list"),
cl::value_desc("idents"), cl::CommaSeparated); cl::value_desc("idents"), cl::CommaSeparated);
static StringsAdapter linkSwitchStore("L", global.params.linkswitches); static StringsAdapter linkSwitchStore("L", global.params.linkswitches);
@ -275,7 +287,9 @@ static cl::list<std::string, StringsAdapter>
cl::opt<std::string> cl::opt<std::string>
moduleDeps("deps", moduleDeps("deps",
cl::desc("Write module dependencies to filename (only imports)"), cl::desc("Write module dependencies to filename (only imports). "
"'-deps' alone prints module dependencies "
"(imports/file/version/debug/lib)"),
cl::value_desc("filename"), cl::ValueOptional); cl::value_desc("filename"), cl::ValueOptional);
cl::opt<std::string> mArch("march", cl::opt<std::string> mArch("march",
@ -345,7 +359,7 @@ cl::opt<FloatABI::Type> mFloatABI(
"Hardware floating-point ABI and instructions"))); "Hardware floating-point ABI and instructions")));
cl::opt<bool> cl::opt<bool>
disableFpElim("disable-fp-elim", disableFpElim("disable-fp-elim", cl::ZeroOrMore,
cl::desc("Disable frame pointer elimination optimization"), cl::desc("Disable frame pointer elimination optimization"),
cl::init(false)); cl::init(false));
@ -355,12 +369,11 @@ static cl::opt<bool, true, FlagParser<bool>>
cl::init(true)); cl::init(true));
cl::opt<BOUNDSCHECK> boundsCheck( cl::opt<BOUNDSCHECK> boundsCheck(
"boundscheck", cl::desc("Enable array bounds check"), "boundscheck", cl::desc("Array bounds check"),
clEnumValues(clEnumValN(BOUNDSCHECKoff, "off", "no array bounds checks"), clEnumValues(clEnumValN(BOUNDSCHECKoff, "off", "Disabled"),
clEnumValN(BOUNDSCHECKsafeonly, "safeonly", clEnumValN(BOUNDSCHECKsafeonly, "safeonly",
"array bounds checks for safe functions only"), "Enabled for @safe functions only"),
clEnumValN(BOUNDSCHECKon, "on", clEnumValN(BOUNDSCHECKon, "on", "Enabled for all functions")),
"array bounds checks for all functions")),
cl::init(BOUNDSCHECKdefault)); cl::init(BOUNDSCHECKdefault));
static cl::opt<bool, true, FlagParser<bool>> static cl::opt<bool, true, FlagParser<bool>>
@ -401,7 +414,7 @@ cl::opt<bool, true>
cl::opt<uint32_t, true> hashThreshold( cl::opt<uint32_t, true> hashThreshold(
"hash-threshold", "hash-threshold",
cl::desc("hash symbol names longer than this threshold (experimental)"), cl::desc("Hash symbol names longer than this threshold (experimental)"),
cl::location(global.params.hashThreshold), cl::init(0)); cl::location(global.params.hashThreshold), cl::init(0));
cl::opt<bool> linkonceTemplates( cl::opt<bool> linkonceTemplates(
@ -428,24 +441,23 @@ void setDefaultMathOptions(llvm::TargetMachine &target) {
} }
cl::opt<bool, true> cl::opt<bool, true>
allinst("allinst", allinst("allinst", cl::ZeroOrMore,
cl::desc("generate code for all template instantiations"), cl::desc("Generate code for all template instantiations"),
cl::location(global.params.allInst)); cl::location(global.params.allInst));
cl::opt<unsigned, true> nestedTemplateDepth( cl::opt<unsigned, true> nestedTemplateDepth(
"template-depth", "template-depth", cl::location(global.params.nestedTmpl), cl::init(500),
cl::desc( cl::desc(
"(experimental) set maximum number of nested template instantiations"), "Set maximum number of nested template instantiations (experimental)"));
cl::location(global.params.nestedTmpl), cl::init(500));
cl::opt<bool, true> cl::opt<bool, true>
useDIP25("dip25", useDIP25("dip25", cl::ZeroOrMore,
cl::desc("implement http://wiki.dlang.org/DIP25 (experimental)"), cl::desc("Implement http://wiki.dlang.org/DIP25 (experimental)"),
cl::location(global.params.useDIP25)); cl::location(global.params.useDIP25));
cl::opt<bool, true> betterC( cl::opt<bool, true> betterC(
"betterC", "betterC", cl::ZeroOrMore,
cl::desc("omit generating some runtime information and helper functions"), cl::desc("Omit generating some runtime information and helper functions"),
cl::location(global.params.betterC)); cl::location(global.params.betterC));
cl::opt<unsigned char, true, CoverageParser> coverageAnalysis( cl::opt<unsigned char, true, CoverageParser> coverageAnalysis(
@ -486,7 +498,7 @@ static cl::extrahelp footer(
"\n" "\n"
"-d-debug can also be specified without options, in which case it enables " "-d-debug can also be specified without options, in which case it enables "
"all\n" "all\n"
"debug checks (i.e. (asserts, boundchecks, contracts and invariants) as " "debug checks (i.e. (asserts, boundschecks, contracts and invariants) as "
"well\n" "well\n"
"as acting as -d-debug=1\n\n" "as acting as -d-debug=1\n\n"
"Options marked with (*) also have a -disable-FOO variant with inverted\n" "Options marked with (*) also have a -disable-FOO variant with inverted\n"

File diff suppressed because it is too large Load diff

View file

@ -87,8 +87,8 @@ static cl::opt<bool>
static StringsAdapter impPathsStore("I", global.params.imppath); static StringsAdapter impPathsStore("I", global.params.imppath);
static cl::list<std::string, StringsAdapter> static cl::list<std::string, StringsAdapter>
importPaths("I", cl::desc("Where to look for imports"), importPaths("I", cl::desc("Look for imports also in <directory>"),
cl::value_desc("path"), cl::location(impPathsStore), cl::value_desc("directory"), cl::location(impPathsStore),
cl::Prefix); cl::Prefix);
static cl::opt<std::string> static cl::opt<std::string>
@ -959,21 +959,16 @@ int cppmain(int argc, char **argv) {
} }
// Set up the TargetMachine. // Set up the TargetMachine.
ExplicitBitness::Type bitness = ExplicitBitness::None;
if ((m32bits || m64bits) && (!mArch.empty() || !mTargetTriple.empty())) { if ((m32bits || m64bits) && (!mArch.empty() || !mTargetTriple.empty())) {
error(Loc(), "-m32 and -m64 switches cannot be used together with -march " error(Loc(), "-m32 and -m64 switches cannot be used together with -march "
"and -mtriple switches"); "and -mtriple switches");
} }
if (m32bits) { ExplicitBitness::Type bitness = ExplicitBitness::None;
if (m32bits)
bitness = ExplicitBitness::M32; bitness = ExplicitBitness::M32;
} if (m64bits && (!m32bits || m32bits.getPosition() < m64bits.getPosition()))
if (m64bits) {
if (bitness != ExplicitBitness::None) {
error(Loc(), "cannot use both -m32 and -m64 options");
}
bitness = ExplicitBitness::M64; bitness = ExplicitBitness::M64;
}
if (global.errors) { if (global.errors) {
fatal(); fatal();

View file

@ -107,10 +107,10 @@ static cl::opt<bool> stripDebug(
cl::opt<opts::SanitizerCheck> opts::sanitize( cl::opt<opts::SanitizerCheck> opts::sanitize(
"sanitize", cl::desc("Enable runtime instrumentation for bug detection"), "sanitize", cl::desc("Enable runtime instrumentation for bug detection"),
cl::init(opts::None), cl::init(opts::None),
clEnumValues(clEnumValN(opts::AddressSanitizer, "address", "memory errors"), clEnumValues(clEnumValN(opts::AddressSanitizer, "address", "Memory errors"),
clEnumValN(opts::MemorySanitizer, "memory", "memory errors"), clEnumValN(opts::MemorySanitizer, "memory", "Memory errors"),
clEnumValN(opts::ThreadSanitizer, "thread", clEnumValN(opts::ThreadSanitizer, "thread",
"race detection"))); "Race detection")));
static cl::opt<bool> disableLoopUnrolling( static cl::opt<bool> disableLoopUnrolling(
"disable-loop-unrolling", "disable-loop-unrolling",