From 68c272d6d9320c27e46151374e69ee375a828ec8 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 5 Oct 2013 22:38:15 +0200 Subject: [PATCH 1/7] Renamed driver/target to .../targetmachine to avoid confusion with the frontend file. --- CMakeLists.txt | 4 ++-- driver/main.cpp | 2 +- driver/{target.cpp => targetmachine.cpp} | 4 ++-- driver/{target.h => targetmachine.h} | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename driver/{target.cpp => targetmachine.cpp} (98%) rename driver/{target.h => targetmachine.h} (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e47cec6..b8095ea5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,7 +184,7 @@ file(GLOB IR_HDR ir/*.h) set(DRV_SRC driver/cl_options.cpp driver/configfile.cpp - driver/target.cpp + driver/targetmachine.cpp driver/toobj.cpp driver/tool.cpp driver/linker.cpp @@ -196,7 +196,7 @@ set(DRV_HDR driver/cl_options.h driver/configfile.h driver/ldc-version.h - driver/target.h + driver/targetmachine.h driver/toobj.h driver/tool.h ) diff --git a/driver/main.cpp b/driver/main.cpp index 27b2dfe8..8b95a2af 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -19,7 +19,7 @@ #include "driver/configfile.h" #include "driver/ldc-version.h" #include "driver/linker.h" -#include "driver/target.h" +#include "driver/targetmachine.h" #include "driver/toobj.h" #include "gen/cl_helpers.h" #include "gen/irstate.h" diff --git a/driver/target.cpp b/driver/targetmachine.cpp similarity index 98% rename from driver/target.cpp rename to driver/targetmachine.cpp index 4e4156aa..20b3ba29 100644 --- a/driver/target.cpp +++ b/driver/targetmachine.cpp @@ -1,4 +1,4 @@ -//===-- target.cpp --------------------------------------------------------===// +//===-- targetmachine.cpp -------------------------------------------------===// // // LDC – the LLVM D compiler // @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "driver/target.h" +#include "driver/targetmachine.h" #include "llvm/ADT/Triple.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/Host.h" diff --git a/driver/target.h b/driver/targetmachine.h similarity index 95% rename from driver/target.h rename to driver/targetmachine.h index 0b1b7926..0dd8018f 100644 --- a/driver/target.h +++ b/driver/targetmachine.h @@ -1,4 +1,4 @@ -//===-- driver/target.h - LLVM target setup ---------------------*- C++ -*-===// +//===-- driver/targetmachine.h - LLVM target setup --------------*- C++ -*-===// // // LDC – the LLVM D compiler // From 177b892bf0d2188266843d0808c3534b3934080e Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 5 Oct 2013 22:41:58 +0200 Subject: [PATCH 2/7] Cleanup: We don't support DMC. --- driver/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index 8b95a2af..90db15ef 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -141,21 +141,10 @@ static void initFromString(char*& dest, const cl::opt& src) { } } -#if _WIN32 && __DMC__ -extern "C" -{ - extern int _xi_a; - extern int _end; -} -#endif - int main(int argc, char** argv) { mem.init(); // initialize storage allocator mem.setStackBottom(&argv); -#if _WIN32 && __DMC__ - mem.addroots((char *)&_xi_a, (char *)&_end); -#endif // stack trace on signals llvm::sys::PrintStackTraceOnErrorSignal(); From 71c67457c3bba7c7c183a6a4a5888d41a9f92b6e Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 5 Oct 2013 22:47:30 +0200 Subject: [PATCH 3/7] Cleanup: Kill backend_init/term. --- driver/main.cpp | 13 ++++++------- gen/toir.cpp | 15 --------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index 90db15ef..01b7775c 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -29,8 +29,10 @@ #include "gen/metadata.h" #include "gen/optimizer.h" #include "gen/passes/Passes.h" +#include "gen/runtime.h" #include "llvm/Linker.h" #include "llvm/Support/Host.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Target/TargetMachine.h" @@ -57,8 +59,6 @@ using namespace opts; extern void getenv_setargv(const char *envvar, int *pargc, char** *pargv); -extern void backend_init(); -extern void backend_term(); static cl::opt noDefaultLib("nodefaultlib", cl::desc("Don't add a default library for linking implicitly"), @@ -668,10 +668,6 @@ int main(int argc, char** argv) Expression::init(); initPrecedence(); - backend_init(); - - //printf("%d source files\n",files.dim); - // Build import search path if (global.params.imppath) { @@ -1108,7 +1104,10 @@ int main(int argc, char** argv) } } - backend_term(); + + LLVM_D_FreeRuntime(); + llvm::llvm_shutdown(); + if (global.errors) fatal(); diff --git a/gen/toir.cpp b/gen/toir.cpp index 3fbdf039..8c6c6362 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -3544,18 +3544,3 @@ llvm::Constant* Expression::toConstElem(IRState * p) fatal(); return NULL; } - - -////////////////////////////////////////////////////////////////////////////////////////// - -void backend_init() -{ - // LLVM_D_InitRuntime is done in Module::genLLVMModule - // since it requires the semantic pass to be done -} - -void backend_term() -{ - LLVM_D_FreeRuntime(); - llvm::llvm_shutdown(); -} From cc11af3473fc0ed0d4902e6e92650f0ff86a401d Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sat, 5 Oct 2013 23:01:41 +0200 Subject: [PATCH 4/7] Factored predefined version handling code out of main(). --- driver/main.cpp | 357 +++++++++++++++++++++++++----------------------- 1 file changed, 184 insertions(+), 173 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index 01b7775c..5ed4e382 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -141,6 +141,188 @@ static void initFromString(char*& dest, const cl::opt& src) { } } +/// Registers the predefined versions specific to the current target triple +/// and other target specific options with VersionCondition. +static void registerPredefinedTargetVersions() { + switch (global.params.targetTriple.getArch()) + { + case llvm::Triple::x86: + VersionCondition::addPredefinedGlobalIdent("X86"); + if (global.params.useInlineAsm) { + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86"); + } + VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); + break; + case llvm::Triple::x86_64: + VersionCondition::addPredefinedGlobalIdent("X86_64"); + if (global.params.useInlineAsm) { + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86_64"); + } + VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); + break; + case llvm::Triple::ppc: + // FIXME: Detect soft float (PPC_SoftFP/PPC_HardFP). + VersionCondition::addPredefinedGlobalIdent("PPC"); + break; + case llvm::Triple::ppc64: + VersionCondition::addPredefinedGlobalIdent("PPC64"); + VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); + break; + case llvm::Triple::arm: + // FIXME: Detect various FP ABIs (ARM_Soft, ARM_SoftFP, ARM_HardFP). + VersionCondition::addPredefinedGlobalIdent("ARM"); + break; + case llvm::Triple::thumb: + VersionCondition::addPredefinedGlobalIdent("ARM"); + VersionCondition::addPredefinedGlobalIdent("Thumb"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("ARM_Thumb"); + VersionCondition::addPredefinedGlobalIdent("ARM_Soft"); + VersionCondition::addPredefinedGlobalIdent("D_SoftFloat"); + break; +#if LDC_LLVM_VER >= 303 + case llvm::Triple::aarch64: + VersionCondition::addPredefinedGlobalIdent("AArch64"); + break; +#endif + case llvm::Triple::mips: + case llvm::Triple::mipsel: + // FIXME: Detect O32/N32 variants (MIPS_{O32,N32}[_SoftFP,_HardFP]). + VersionCondition::addPredefinedGlobalIdent("MIPS"); + break; + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + // FIXME: Detect N64 variants (MIPS64_N64[_SoftFP,_HardFP]). + VersionCondition::addPredefinedGlobalIdent("MIPS64"); + break; + case llvm::Triple::sparc: + // FIXME: Detect SPARC v8+ (SPARC_V8Plus). + // FIXME: Detect soft float (SPARC_SoftFP/SPARC_HardFP). + VersionCondition::addPredefinedGlobalIdent("SPARC"); + break; + case llvm::Triple::sparcv9: + VersionCondition::addPredefinedGlobalIdent("SPARC64"); + VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); + break; + default: + error("invalid cpu architecture specified: %s", global.params.targetTriple.getArchName().str().c_str()); + fatal(); + } + + // endianness + if (gDataLayout->isLittleEndian()) { + VersionCondition::addPredefinedGlobalIdent("LittleEndian"); + } + else { + VersionCondition::addPredefinedGlobalIdent("BigEndian"); + } + + // a generic 64bit version + if (global.params.is64bit) { + VersionCondition::addPredefinedGlobalIdent("LLVM64"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("D_LP64"); + } + + if (gTargetMachine->getRelocationModel() == llvm::Reloc::PIC_) { + VersionCondition::addPredefinedGlobalIdent("D_PIC"); + } + + // parse the OS out of the target triple + // see http://gcc.gnu.org/install/specific.html for details + // also llvm's different SubTargets have useful information + switch (global.params.targetTriple.getOS()) + { + case llvm::Triple::Win32: + VersionCondition::addPredefinedGlobalIdent("Windows"); + VersionCondition::addPredefinedGlobalIdent(global.params.is64bit ? "Win64" : "Win32"); + break; + case llvm::Triple::MinGW32: + VersionCondition::addPredefinedGlobalIdent("Windows"); + VersionCondition::addPredefinedGlobalIdent(global.params.is64bit ? "Win64" : "Win32"); + VersionCondition::addPredefinedGlobalIdent("mingw32"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("MinGW"); + break; + case llvm::Triple::Cygwin: + error("Cygwin is not yet supported"); + fatal(); + VersionCondition::addPredefinedGlobalIdent("Cygwin"); + break; + case llvm::Triple::Linux: + VersionCondition::addPredefinedGlobalIdent("linux"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::Haiku: + VersionCondition::addPredefinedGlobalIdent("Haiku"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::Darwin: + VersionCondition::addPredefinedGlobalIdent("OSX"); + VersionCondition::addPredefinedGlobalIdent("darwin"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::FreeBSD: + VersionCondition::addPredefinedGlobalIdent("freebsd"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("FreeBSD"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::Solaris: + VersionCondition::addPredefinedGlobalIdent("solaris"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("Solaris"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::DragonFly: + VersionCondition::addPredefinedGlobalIdent("DragonFlyBSD"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::NetBSD: + VersionCondition::addPredefinedGlobalIdent("NetBSD"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; + case llvm::Triple::OpenBSD: + VersionCondition::addPredefinedGlobalIdent("OpenBSD"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; +#if LDC_LLVM_VER >= 302 + case llvm::Triple::AIX: + VersionCondition::addPredefinedGlobalIdent("AIX"); + VersionCondition::addPredefinedGlobalIdent("Posix"); + break; +#endif + default: + error("target '%s' is not yet supported", global.params.targetTriple.str().c_str()); + fatal(); + } +} + +/// Registers all predefined D version identifiers for the current +/// configuration with VersionCondition. +static void registerPredefinedVersions() { + VersionCondition::addPredefinedGlobalIdent("LLVM"); // For backwards compatibility. + VersionCondition::addPredefinedGlobalIdent("LDC"); + VersionCondition::addPredefinedGlobalIdent("all"); + VersionCondition::addPredefinedGlobalIdent("D_Version2"); + + if (global.params.doDocComments) + VersionCondition::addPredefinedGlobalIdent("D_Ddoc"); + + if (global.params.useUnitTests) + VersionCondition::addPredefinedGlobalIdent("unittest"); + + if (global.params.useAssert) + VersionCondition::addPredefinedGlobalIdent("assert"); + + if (!global.params.useArrayBounds) + VersionCondition::addPredefinedGlobalIdent("D_NoBoundsChecks"); + + registerPredefinedTargetVersions(); + + // Expose LLVM version to runtime +#define STR(x) #x +#define XSTR(x) STR(x) + VersionCondition::addPredefinedGlobalIdent("LDC_LLVM_" XSTR(LDC_LLVM_VER)); +#undef XSTR +#undef STR +} + int main(int argc, char** argv) { mem.init(); // initialize storage allocator @@ -178,11 +360,6 @@ int main(int argc, char** argv) global.params.moduleDeps = NULL; global.params.moduleDepsFile = NULL; - // Set predefined version identifiers - VersionCondition::addPredefinedGlobalIdent("LLVM"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("LDC"); - VersionCondition::addPredefinedGlobalIdent("all"); - VersionCondition::addPredefinedGlobalIdent("D_Version2"); // build complete fixed up list of command line arguments std::vector final_args; @@ -483,160 +660,8 @@ int main(int argc, char** argv) // Starting with LLVM 3.1 we could also use global.params.targetTriple.isArch64Bit(); global.params.is64bit = gDataLayout->getPointerSizeInBits(ADDRESS_SPACE) == 64; - switch (global.params.targetTriple.getArch()) - { - case llvm::Triple::x86: - VersionCondition::addPredefinedGlobalIdent("X86"); - if (global.params.useInlineAsm) { - VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86"); - } - VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); - break; - case llvm::Triple::x86_64: - VersionCondition::addPredefinedGlobalIdent("X86_64"); - if (global.params.useInlineAsm) { - VersionCondition::addPredefinedGlobalIdent("D_InlineAsm_X86_64"); - } - VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); - break; - case llvm::Triple::ppc: - // FIXME: Detect soft float (PPC_SoftFP/PPC_HardFP). - VersionCondition::addPredefinedGlobalIdent("PPC"); - break; - case llvm::Triple::ppc64: - VersionCondition::addPredefinedGlobalIdent("PPC64"); - VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); - break; - case llvm::Triple::arm: - // FIXME: Detect various FP ABIs (ARM_Soft, ARM_SoftFP, ARM_HardFP). - VersionCondition::addPredefinedGlobalIdent("ARM"); - break; - case llvm::Triple::thumb: - VersionCondition::addPredefinedGlobalIdent("ARM"); - VersionCondition::addPredefinedGlobalIdent("Thumb"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("ARM_Thumb"); - VersionCondition::addPredefinedGlobalIdent("ARM_Soft"); - VersionCondition::addPredefinedGlobalIdent("D_SoftFloat"); - break; -#if LDC_LLVM_VER >= 303 - case llvm::Triple::aarch64: - VersionCondition::addPredefinedGlobalIdent("AArch64"); - break; -#endif - case llvm::Triple::mips: - case llvm::Triple::mipsel: - // FIXME: Detect O32/N32 variants (MIPS_{O32,N32}[_SoftFP,_HardFP]). - VersionCondition::addPredefinedGlobalIdent("MIPS"); - break; - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - // FIXME: Detect N64 variants (MIPS64_N64[_SoftFP,_HardFP]). - VersionCondition::addPredefinedGlobalIdent("MIPS64"); - break; - case llvm::Triple::sparc: - // FIXME: Detect SPARC v8+ (SPARC_V8Plus). - // FIXME: Detect soft float (SPARC_SoftFP/SPARC_HardFP). - VersionCondition::addPredefinedGlobalIdent("SPARC"); - break; - case llvm::Triple::sparcv9: - VersionCondition::addPredefinedGlobalIdent("SPARC64"); - VersionCondition::addPredefinedGlobalIdent("D_HardFloat"); - break; - default: - error("invalid cpu architecture specified: %s", global.params.targetTriple.getArchName().str().c_str()); - fatal(); - } - - // endianness - if (gDataLayout->isLittleEndian()) { - VersionCondition::addPredefinedGlobalIdent("LittleEndian"); - } - else { - VersionCondition::addPredefinedGlobalIdent("BigEndian"); - } - - // a generic 64bit version - if (global.params.is64bit) { - VersionCondition::addPredefinedGlobalIdent("LLVM64"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("D_LP64"); - } - - if (gTargetMachine->getRelocationModel() == llvm::Reloc::PIC_) { - VersionCondition::addPredefinedGlobalIdent("D_PIC"); - } - - // parse the OS out of the target triple - // see http://gcc.gnu.org/install/specific.html for details - // also llvm's different SubTargets have useful information - switch (global.params.targetTriple.getOS()) - { - case llvm::Triple::Win32: - VersionCondition::addPredefinedGlobalIdent("Windows"); - VersionCondition::addPredefinedGlobalIdent(global.params.is64bit ? "Win64" : "Win32"); - break; - case llvm::Triple::MinGW32: - VersionCondition::addPredefinedGlobalIdent("Windows"); - VersionCondition::addPredefinedGlobalIdent(global.params.is64bit ? "Win64" : "Win32"); - VersionCondition::addPredefinedGlobalIdent("mingw32"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("MinGW"); - break; - case llvm::Triple::Cygwin: - error("Cygwin is not yet supported"); - fatal(); - VersionCondition::addPredefinedGlobalIdent("Cygwin"); - break; - case llvm::Triple::Linux: - VersionCondition::addPredefinedGlobalIdent("linux"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::Haiku: - VersionCondition::addPredefinedGlobalIdent("Haiku"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::Darwin: - VersionCondition::addPredefinedGlobalIdent("OSX"); - VersionCondition::addPredefinedGlobalIdent("darwin"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::FreeBSD: - VersionCondition::addPredefinedGlobalIdent("freebsd"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("FreeBSD"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::Solaris: - VersionCondition::addPredefinedGlobalIdent("solaris"); // For backwards compatibility. - VersionCondition::addPredefinedGlobalIdent("Solaris"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::DragonFly: - VersionCondition::addPredefinedGlobalIdent("DragonFlyBSD"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::NetBSD: - VersionCondition::addPredefinedGlobalIdent("NetBSD"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; - case llvm::Triple::OpenBSD: - VersionCondition::addPredefinedGlobalIdent("OpenBSD"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; -#if LDC_LLVM_VER >= 302 - case llvm::Triple::AIX: - VersionCondition::addPredefinedGlobalIdent("AIX"); - VersionCondition::addPredefinedGlobalIdent("Posix"); - break; -#endif - default: - error("target '%s' is not yet supported", global.params.targetTriple.str().c_str()); - fatal(); - } - - // Expose LLVM version to runtime -#define STR(x) #x -#define XSTR(x) STR(x) - VersionCondition::addPredefinedGlobalIdent("LDC_LLVM_" XSTR(LDC_LLVM_VER)); -#undef XSTR -#undef STR + // Set predefined version identifiers. + registerPredefinedVersions(); if (global.params.targetTriple.isOSWindows()) { global.dll_ext = "dll"; @@ -646,20 +671,6 @@ int main(int argc, char** argv) global.lib_ext = "a"; } - // added in 1.039 - if (global.params.doDocComments) - VersionCondition::addPredefinedGlobalIdent("D_Ddoc"); - - // unittests? - if (global.params.useUnitTests) - VersionCondition::addPredefinedGlobalIdent("unittest"); - - if (global.params.useAssert) - VersionCondition::addPredefinedGlobalIdent("assert"); - - if (!global.params.useArrayBounds) - VersionCondition::addPredefinedGlobalIdent("D_NoBoundsChecks"); - // Initialization Type::init(&ir); Id::initialize(); From 7e74f65b3222f06626b896983b88aa902c57026b Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 6 Oct 2013 00:25:12 +0200 Subject: [PATCH 5/7] Also factored out argument parsing to separate function. The code is still messy, but we have to start somewhere... --- driver/main.cpp | 535 ++++++++++++++++++++++++------------------------ 1 file changed, 269 insertions(+), 266 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index 5ed4e382..87336031 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -141,6 +141,266 @@ static void initFromString(char*& dest, const cl::opt& src) { } } +int main(int argc, char **argv); + +/// Parses switches from the command line, any response files and the global +/// config file and sets up global.params accordingly. +/// +/// Returns a list of source file names. +static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool &helpOnly) { +#if _WIN32 + char buf[MAX_PATH]; + GetModuleFileName(NULL, buf, MAX_PATH); + const char* argv0 = &buf; + // FIXME: We cannot set params.argv0 here, as we would escape a stack + // reference, but it is unused anyway. + global.params.argv0 = NULL; +#else + const char* argv0 = global.params.argv0 = argv[0]; +#endif + + // Set some default values. + global.params.useSwitchError = 1; + global.params.useArrayBounds = 2; + + global.params.linkswitches = new Strings(); + global.params.libfiles = new Strings(); + global.params.objfiles = new Strings(); + global.params.ddocfiles = new Strings(); + + global.params.moduleDeps = NULL; + global.params.moduleDepsFile = NULL; + + // build complete fixed up list of command line arguments + std::vector final_args; + final_args.reserve(argc); + + // insert command line args until -run is reached + int run_argnum = 1; + while (run_argnum < argc && strncmp(argv[run_argnum], "-run", 4) != 0) + ++run_argnum; + final_args.insert(final_args.end(), &argv[0], &argv[run_argnum]); + + // read the configuration file + ConfigFile cfg_file; + + // just ignore errors for now, they are still printed + cfg_file.read(argv0, (void*)main, "ldc2.conf"); + + // insert config file additions to the argument list + final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end()); + + // insert -run and everything beyond + final_args.insert(final_args.end(), &argv[run_argnum], &argv[argc]); + + // Handle fixed-up arguments! + cl::SetVersionPrinter(&printVersion); + cl::ParseCommandLineOptions(final_args.size(), const_cast(&final_args[0]), + "LDC - the LLVM D compiler\n" +#if LDC_LLVM_VER < 302 + , true +#endif + ); + + // Print config file path if -v was passed + if (global.params.verbose) { + const std::string& path = cfg_file.path(); + if (!path.empty()) + printf("config %s\n", path.c_str()); + } + + // Negated options + global.params.link = !compileOnly; + global.params.obj = !dontWriteObj; + global.params.useInlineAsm = !noAsm; + + // String options: std::string --> char* + initFromString(global.params.objname, objectFile); + initFromString(global.params.objdir, objectDir); + + initFromString(global.params.docdir, ddocDir); + initFromString(global.params.docname, ddocFile); + global.params.doDocComments |= + global.params.docdir || global.params.docname; + + initFromString(global.params.xfilename, jsonFile); + if (global.params.xfilename) + global.params.doXGeneration = true; + + initFromString(global.params.hdrdir, hdrDir); + initFromString(global.params.hdrname, hdrFile); + global.params.doHdrGeneration |= + global.params.hdrdir || global.params.hdrname; + + initFromString(global.params.moduleDepsFile, moduleDepsFile); + if (global.params.moduleDepsFile != NULL) + { + global.params.moduleDeps = new OutBuffer; + } + + processVersions(debugArgs, "debug", + DebugCondition::setGlobalLevel, + DebugCondition::addGlobalIdent); + processVersions(versions, "version", + VersionCondition::setGlobalLevel, + VersionCondition::addGlobalIdent); + + global.params.output_o = + (opts::output_o == cl::BOU_UNSET + && !(opts::output_bc || opts::output_ll || opts::output_s)) + ? OUTPUTFLAGdefault + : opts::output_o == cl::BOU_TRUE + ? OUTPUTFLAGset + : OUTPUTFLAGno; + global.params.output_bc = opts::output_bc ? OUTPUTFLAGset : OUTPUTFLAGno; + global.params.output_ll = opts::output_ll ? OUTPUTFLAGset : OUTPUTFLAGno; + global.params.output_s = opts::output_s ? OUTPUTFLAGset : OUTPUTFLAGno; + + templateLinkage = + opts::linkonceTemplates ? LLGlobalValue::LinkOnceODRLinkage + : LLGlobalValue::WeakODRLinkage; + + if (global.params.run || !runargs.empty()) { + // FIXME: how to properly detect the presence of a PositionalEatsArgs + // option without parameters? We want to emit an error in that case... + // You'd think getNumOccurrences would do it, but it just returns the + // number of parameters) + // NOTE: Hacked around it by detecting -run in getenv_setargv(), where + // we're looking for it anyway, and pre-setting the flag... + global.params.run = true; + if (!runargs.empty()) { + char const * name = runargs[0].c_str(); + char const * ext = FileName::ext(name); + if (ext && FileName::equals(ext, "d") == 0 && + FileName::equals(ext, "di") == 0) { + error("-run must be followed by a source file, not '%s'", name); + } + + sourceFiles.push(mem.strdup(name)); + runargs.erase(runargs.begin()); + } else { + global.params.run = false; + error("Expected at least one argument to '-run'\n"); + } + } + + sourceFiles.reserve(fileList.size()); + typedef std::vector::iterator It; + for(It I = fileList.begin(), E = fileList.end(); I != E; ++I) + if (!I->empty()) + sourceFiles.push(mem.strdup(I->c_str())); + + Array* libs; + if (global.params.symdebug) + { + libs = global.params.debuglibnames; + } + else + libs = global.params.defaultlibnames; + + if (!noDefaultLib) + { + if (libs) + { + for (unsigned i = 0; i < libs->dim; i++) + { + char* lib = static_cast(libs->data[i]); + char *arg = static_cast(mem.malloc(strlen(lib) + 3)); + strcpy(arg, "-l"); + strcpy(arg+2, lib); + global.params.linkswitches->push(arg); + } + } + else + { + global.params.linkswitches->push(mem.strdup("-ldruntime-ldc")); + } + } + + if (global.params.useUnitTests) + global.params.useAssert = 1; + + // Bounds checking is a bit peculiar: -enable/disable-boundscheck is an + // absolute decision. Only if no explicit option is specified, -release + // downgrades useArrayBounds 2 to 1 (only for safe functions). + if (opts::boundsChecks == cl::BOU_UNSET) + global.params.useArrayBounds = opts::nonSafeBoundsChecks ? 2 : 1; + else + global.params.useArrayBounds = (opts::boundsChecks == cl::BOU_TRUE) ? 2 : 0; + + // LDC output determination + + // if we don't link, autodetect target from extension + if(!global.params.link && !createStaticLib && global.params.objname) { + const char *ext = FileName::ext(global.params.objname); + bool autofound = false; + if (!ext) { + // keep things as they are + } else if (strcmp(ext, global.ll_ext) == 0) { + global.params.output_ll = OUTPUTFLAGset; + autofound = true; + } else if (strcmp(ext, global.bc_ext) == 0) { + global.params.output_bc = OUTPUTFLAGset; + autofound = true; + } else if (strcmp(ext, global.s_ext) == 0) { + global.params.output_s = OUTPUTFLAGset; + autofound = true; + } else if (strcmp(ext, global.obj_ext) == 0 || strcmp(ext, global.obj_ext_alt) == 0) { + global.params.output_o = OUTPUTFLAGset; + autofound = true; + } else { + // append dot, so forceExt won't change existing name even if it contains dots + size_t len = strlen(global.params.objname); + char* s = static_cast(mem.malloc(len + 1 + 1)); + memcpy(s, global.params.objname, len); + s[len] = '.'; + s[len+1] = 0; + global.params.objname = s; + + } + if(autofound && global.params.output_o == OUTPUTFLAGdefault) + global.params.output_o = OUTPUTFLAGno; + } + + // only link if possible + if (!global.params.obj || !global.params.output_o || createStaticLib) + global.params.link = 0; + + if (createStaticLib && createSharedLib) + error("-lib and -shared switches cannot be used together"); + + if (createSharedLib && mRelocModel == llvm::Reloc::Default) + mRelocModel = llvm::Reloc::PIC_; + + if (global.params.link && !createSharedLib) + { + global.params.exefile = global.params.objname; + if (sourceFiles.dim > 1) + global.params.objname = NULL; + } + else if (global.params.run) + { + error("flags conflict with -run"); + fatal(); + } + else if (global.params.objname && sourceFiles.dim > 1) { + if (createStaticLib || createSharedLib) + { + singleObj = true; + } + if (!singleObj) + { + error("multiple source files, but only one .obj name"); + fatal(); + } + } + + if (soname.getNumOccurrences() > 0 && !createSharedLib) { + error("-soname can be used only when building a shared library"); + fatal(); + } +} + /// Registers the predefined versions specific to the current target triple /// and other target specific options with VersionCondition. static void registerPredefinedTargetVersions() { @@ -323,7 +583,7 @@ static void registerPredefinedVersions() { #undef STR } -int main(int argc, char** argv) +int main(int argc, char **argv) { mem.init(); // initialize storage allocator mem.setStackBottom(&argv); @@ -331,8 +591,7 @@ int main(int argc, char** argv) // stack trace on signals llvm::sys::PrintStackTraceOnErrorSignal(); - Strings files; - const char *p, *ext; + const char *p; Module *m; int status = EXIT_SUCCESS; @@ -341,282 +600,26 @@ int main(int argc, char** argv) global.ldc_version = ldc::ldc_version; global.llvm_version = ldc::llvm_version; - // Set some default values -#if _WIN32 - char buf[MAX_PATH]; - GetModuleFileName(NULL, buf, MAX_PATH); - global.params.argv0 = buf; -#else - global.params.argv0 = argv[0]; -#endif - global.params.useSwitchError = 1; - global.params.useArrayBounds = 2; - - global.params.linkswitches = new Strings(); - global.params.libfiles = new Strings(); - global.params.objfiles = new Strings(); - global.params.ddocfiles = new Strings(); - - global.params.moduleDeps = NULL; - global.params.moduleDepsFile = NULL; - - - // build complete fixed up list of command line arguments - std::vector final_args; - final_args.reserve(argc); - - // insert command line args until -run is reached - int run_argnum = 1; - while (run_argnum < argc && strncmp(argv[run_argnum], "-run", 4) != 0) - ++run_argnum; - final_args.insert(final_args.end(), &argv[0], &argv[run_argnum]); - - // read the configuration file - ConfigFile cfg_file; - - // just ignore errors for now, they are still printed - cfg_file.read(global.params.argv0, (void*)main, "ldc2.conf"); - - // insert config file additions to the argument list - final_args.insert(final_args.end(), cfg_file.switches_begin(), cfg_file.switches_end()); - - // insert -run and everything beyond - final_args.insert(final_args.end(), &argv[run_argnum], &argv[argc]); - -#if 0 - for (size_t i = 0; i < final_args.size(); ++i) - { - printf("final_args[%zu] = %s\n", i, final_args[i]); - } -#endif - - // Initialize LLVM. - // Initialize targets first, so that --version shows registered targets. + // Initialize LLVM before parsing the command line so that --version shows + // registered targets. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); - // Handle fixed-up arguments! - cl::SetVersionPrinter(&printVersion); - cl::ParseCommandLineOptions(final_args.size(), const_cast(&final_args[0]), - "LDC - the LLVM D compiler\n" -#if LDC_LLVM_VER < 302 - , true -#endif - ); + bool helpOnly; + Strings files; + parseCommandLine(argc, argv, files, helpOnly); - // Print config file path if -v was passed - if (global.params.verbose) { - const std::string& path = cfg_file.path(); - if (!path.empty()) - printf("config %s\n", path.c_str()); - } - - bool skipModules = mCPU == "help" ||(!mAttrs.empty() && mAttrs.front() == "help"); - - // Negated options - global.params.link = !compileOnly; - global.params.obj = !dontWriteObj; - global.params.useInlineAsm = !noAsm; - - // String options: std::string --> char* - initFromString(global.params.objname, objectFile); - initFromString(global.params.objdir, objectDir); - - initFromString(global.params.docdir, ddocDir); - initFromString(global.params.docname, ddocFile); - global.params.doDocComments |= - global.params.docdir || global.params.docname; - - initFromString(global.params.xfilename, jsonFile); - if (global.params.xfilename) - global.params.doXGeneration = true; - - initFromString(global.params.hdrdir, hdrDir); - initFromString(global.params.hdrname, hdrFile); - global.params.doHdrGeneration |= - global.params.hdrdir || global.params.hdrname; - - initFromString(global.params.moduleDepsFile, moduleDepsFile); - if (global.params.moduleDepsFile != NULL) - { - global.params.moduleDeps = new OutBuffer; - } - - processVersions(debugArgs, "debug", - DebugCondition::setGlobalLevel, - DebugCondition::addGlobalIdent); - processVersions(versions, "version", - VersionCondition::setGlobalLevel, - VersionCondition::addGlobalIdent); - - global.params.output_o = - (opts::output_o == cl::BOU_UNSET - && !(opts::output_bc || opts::output_ll || opts::output_s)) - ? OUTPUTFLAGdefault - : opts::output_o == cl::BOU_TRUE - ? OUTPUTFLAGset - : OUTPUTFLAGno; - global.params.output_bc = opts::output_bc ? OUTPUTFLAGset : OUTPUTFLAGno; - global.params.output_ll = opts::output_ll ? OUTPUTFLAGset : OUTPUTFLAGno; - global.params.output_s = opts::output_s ? OUTPUTFLAGset : OUTPUTFLAGno; - - templateLinkage = - opts::linkonceTemplates ? LLGlobalValue::LinkOnceODRLinkage - : LLGlobalValue::WeakODRLinkage; - - if (global.params.run || !runargs.empty()) { - // FIXME: how to properly detect the presence of a PositionalEatsArgs - // option without parameters? We want to emit an error in that case... - // You'd think getNumOccurrences would do it, but it just returns the - // number of parameters) - // NOTE: Hacked around it by detecting -run in getenv_setargv(), where - // we're looking for it anyway, and pre-setting the flag... - global.params.run = true; - if (!runargs.empty()) { - char const * name = runargs[0].c_str(); - char const * ext = FileName::ext(name); - if (ext && FileName::equals(ext, "d") == 0 && - FileName::equals(ext, "di") == 0) { - error("-run must be followed by a source file, not '%s'", name); - } - - files.push(mem.strdup(name)); - runargs.erase(runargs.begin()); - } else { - global.params.run = false; - error("Expected at least one argument to '-run'\n"); - } - } - - - files.reserve(fileList.size()); - typedef std::vector::iterator It; - for(It I = fileList.begin(), E = fileList.end(); I != E; ++I) - if (!I->empty()) - files.push(mem.strdup(I->c_str())); - - if (global.errors) - { - fatal(); - } - if (files.dim == 0 && !skipModules) + if (files.dim == 0 && !helpOnly) { cl::PrintHelpMessage(); return EXIT_FAILURE; } - Array* libs; - if (global.params.symdebug) - { - libs = global.params.debuglibnames; - } - else - libs = global.params.defaultlibnames; - - if (!noDefaultLib) - { - if (libs) - { - for (unsigned i = 0; i < libs->dim; i++) - { - char* lib = static_cast(libs->data[i]); - char *arg = static_cast(mem.malloc(strlen(lib) + 3)); - strcpy(arg, "-l"); - strcpy(arg+2, lib); - global.params.linkswitches->push(arg); - } - } - else - { - global.params.linkswitches->push(mem.strdup("-ldruntime-ldc")); - } - } - - if (global.params.useUnitTests) - global.params.useAssert = 1; - - // Bounds checking is a bit peculiar: -enable/disable-boundscheck is an - // absolute decision. Only if no explicit option is specified, -release - // downgrades useArrayBounds 2 to 1 (only for safe functions). - if (opts::boundsChecks == cl::BOU_UNSET) - global.params.useArrayBounds = opts::nonSafeBoundsChecks ? 2 : 1; - else - global.params.useArrayBounds = (opts::boundsChecks == cl::BOU_TRUE) ? 2 : 0; - - // LDC output determination - - // if we don't link, autodetect target from extension - if(!global.params.link && !createStaticLib && global.params.objname) { - ext = FileName::ext(global.params.objname); - bool autofound = false; - if (!ext) { - // keep things as they are - } else if (strcmp(ext, global.ll_ext) == 0) { - global.params.output_ll = OUTPUTFLAGset; - autofound = true; - } else if (strcmp(ext, global.bc_ext) == 0) { - global.params.output_bc = OUTPUTFLAGset; - autofound = true; - } else if (strcmp(ext, global.s_ext) == 0) { - global.params.output_s = OUTPUTFLAGset; - autofound = true; - } else if (strcmp(ext, global.obj_ext) == 0 || strcmp(ext, global.obj_ext_alt) == 0) { - global.params.output_o = OUTPUTFLAGset; - autofound = true; - } else { - // append dot, so forceExt won't change existing name even if it contains dots - size_t len = strlen(global.params.objname); - char* s = static_cast(mem.malloc(len + 1 + 1)); - memcpy(s, global.params.objname, len); - s[len] = '.'; - s[len+1] = 0; - global.params.objname = s; - - } - if(autofound && global.params.output_o == OUTPUTFLAGdefault) - global.params.output_o = OUTPUTFLAGno; - } - - // only link if possible - if (!global.params.obj || !global.params.output_o || createStaticLib) - global.params.link = 0; - - if (createStaticLib && createSharedLib) - error("-lib and -shared switches cannot be used together"); - - if (createSharedLib && mRelocModel == llvm::Reloc::Default) - mRelocModel = llvm::Reloc::PIC_; - - if (global.params.link && !createSharedLib) - { - global.params.exefile = global.params.objname; - if (files.dim > 1) - global.params.objname = NULL; - } - else if (global.params.run) - { - error("flags conflict with -run"); + if (global.errors) fatal(); - } - else if (global.params.objname && files.dim > 1) { - if (createStaticLib || createSharedLib) - { - singleObj = true; - } - if (!singleObj) - { - error("multiple source files, but only one .obj name"); - fatal(); - } - } - - if (soname.getNumOccurrences() > 0 && !createSharedLib) { - error("-soname can be used only when building a shared library"); - fatal(); - } // create a proper target Ir ir; From b94ed4092ee7c2f05889f019c767250fd281f897 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 6 Oct 2013 00:26:12 +0200 Subject: [PATCH 6/7] De-ancient-C-ification, spelled out EXIT_SUCCESS. --- driver/main.cpp | 62 ++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 37 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index 87336031..b66da7ef 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -591,10 +591,6 @@ int main(int argc, char **argv) // stack trace on signals llvm::sys::PrintStackTraceOnErrorSignal(); - const char *p; - Module *m; - int status = EXIT_SUCCESS; - global.init(); global.version = ldc::dmd_version; global.ldc_version = ldc::ldc_version; @@ -730,7 +726,7 @@ int main(int argc, char **argv) const char *ext; const char *name; - p = static_cast(files.data[i]); + const char *p = static_cast(files.data[i]); p = FileName::name(p); // strip path ext = FileName::ext(p); @@ -829,7 +825,7 @@ int main(int argc, char **argv) } id = Lexer::idPool(name); - m = new Module(static_cast(files.data[i]), id, global.params.doDocComments, global.params.doHdrGeneration); + Module *m = new Module(static_cast(files.data[i]), id, global.params.doDocComments, global.params.doHdrGeneration); m->isRoot = true; modules.push(m); } @@ -837,7 +833,7 @@ int main(int argc, char **argv) // Read files, parse them for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); + Module *m = modules[i]; if (global.params.verbose) printf("parse %s\n", m->toChars()); if (!Module::rootModule) @@ -879,10 +875,9 @@ int main(int argc, char **argv) */ for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); if (global.params.verbose) - printf("import %s\n", m->toChars()); - m->genhdrfile(); + printf("import %s\n", modules[i]->toChars()); + modules[i]->genhdrfile(); } } if (global.errors) @@ -891,10 +886,9 @@ int main(int argc, char **argv) // load all unconditional imports for better symbol resolving for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); if (global.params.verbose) - printf("importall %s\n", m->toChars()); - m->importAll(0); + printf("importall %s\n", modules[i]->toChars()); + modules[i]->importAll(0); } if (global.errors) fatal(); @@ -902,10 +896,9 @@ int main(int argc, char **argv) // Do semantic analysis for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); if (global.params.verbose) - printf("semantic %s\n", m->toChars()); - m->semantic(); + printf("semantic %s\n", modules[i]->toChars()); + modules[i]->semantic(); } if (global.errors) fatal(); @@ -916,10 +909,9 @@ int main(int argc, char **argv) // Do pass 2 semantic analysis for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); if (global.params.verbose) - printf("semantic2 %s\n", m->toChars()); - m->semantic2(); + printf("semantic2 %s\n", modules[i]->toChars()); + modules[i]->semantic2(); } if (global.errors) fatal(); @@ -927,10 +919,9 @@ int main(int argc, char **argv) // Do pass 3 semantic analysis for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); if (global.params.verbose) - printf("semantic3 %s\n", m->toChars()); - m->semantic3(); + printf("semantic3 %s\n", modules[i]->toChars()); + modules[i]->semantic3(); } if (global.errors) fatal(); @@ -961,7 +952,7 @@ int main(int argc, char **argv) // since otherwise functions in them cannot be inlined for (unsigned i = 0; i < Module::amodules.dim; i++) { - m = static_cast(Module::amodules.data[i]); + Module *m = Module::amodules[i]; if (global.params.verbose) printf("semantic3 %s\n", m->toChars()); m->semantic2(); @@ -993,7 +984,7 @@ int main(int argc, char **argv) // Generate output files for (unsigned i = 0; i < modules.dim; i++) { - m = static_cast(modules.data[i]); + Module *m = modules[i]; if (global.params.verbose) printf("code %s\n", m->toChars()); if (global.params.obj) @@ -1021,7 +1012,7 @@ int main(int argc, char **argv) // internal linking for singleobj if (singleObj && llvmModules.size() > 0) { - Module* m = static_cast(modules.data[0]); + Module *m = modules[0]; char* oname; const char* filename; @@ -1125,6 +1116,7 @@ int main(int argc, char **argv) if (global.errors) fatal(); + int status = EXIT_SUCCESS; if (!global.params.objfiles->dim) { if (global.params.link) @@ -1139,21 +1131,17 @@ int main(int argc, char **argv) else if (createStaticLib) createStaticLibrary(); - if (global.params.run) + if (global.params.run && status == EXIT_SUCCESS) { - if (!status) - { - status = runExecutable(); + status = runExecutable(); - /* Delete .obj files and .exe file - */ - for (unsigned i = 0; i < modules.dim; i++) - { - m = static_cast(modules.data[i]); - m->deleteObjFile(); - } - deleteExecutable(); + /* Delete .obj files and .exe file + */ + for (unsigned i = 0; i < modules.dim; i++) + { + modules[i]->deleteObjFile(); } + deleteExecutable(); } } From 639bc0ab71e5d4ec4346a096dacd45490e443dcd Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 6 Oct 2013 00:28:40 +0200 Subject: [PATCH 7/7] Removed a few fatal() calls in argument parsing code. global.errors is checked immediately after return anyway. --- driver/main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/driver/main.cpp b/driver/main.cpp index b66da7ef..eb8901c8 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -381,7 +381,6 @@ static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool & else if (global.params.run) { error("flags conflict with -run"); - fatal(); } else if (global.params.objname && sourceFiles.dim > 1) { if (createStaticLib || createSharedLib) @@ -391,13 +390,11 @@ static void parseCommandLine(int argc, char **argv, Strings &sourceFiles, bool & if (!singleObj) { error("multiple source files, but only one .obj name"); - fatal(); } } if (soname.getNumOccurrences() > 0 && !createSharedLib) { error("-soname can be used only when building a shared library"); - fatal(); } }