diff --git a/.travis.yml b/.travis.yml index b5ec8eb3c6..5bf2387679 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,8 @@ env: - LLVM_PACKAGE="llvm-3.3 llvm-3.3-dev" TESTSUITE_FILTER=debug OPTS="-DMULTILIB=ON" - LLVM_PACKAGE="llvm-3.3 llvm-3.3-dev" TESTSUITE_FILTER=release - LLVM_PACKAGE="llvm-3.4 llvm-3.4-dev" TESTSUITE_FILTER=debug - - LLVM_PACKAGE="llvm-3.4 llvm-3.4-dev" TESTSUITE_FILTER=release OPTS="-DMULTILIB=ON" + - LLVM_PACKAGE="llvm-3.4 llvm-3.4-dev" TESTSUITE_FILTER="(druntime|dmd-testsuite).*_release" OPTS="-DMULTILIB=ON" + - LLVM_PACKAGE="llvm-3.4 llvm-3.4-dev" TESTSUITE_FILTER="phobos_.*_release" OPTS="-DMULTILIB=ON" - LLVM_PACKAGE="llvm-3.5 llvm-3.5-dev libedit2 libedit-dev" TESTSUITE_FILTER=debug - LLVM_PACKAGE="llvm-3.5 llvm-3.5-dev libedit2 libedit-dev" TESTSUITE_FILTER=release matrix: diff --git a/dmd2/root/port.h b/dmd2/root/port.h index 9c720df693..4362c7ca69 100644 --- a/dmd2/root/port.h +++ b/dmd2/root/port.h @@ -10,7 +10,7 @@ // Portable wrapper around compiler/system specific things. // The idea is to minimize #ifdef's in the app code. -#if defined(IN_LLVM) && (LDC_LLVM_VER >= 303) +#if defined(IN_LLVM) && ((LDC_LLVM_VER == 303) || (LDC_LLVM_VER == 304)) #include "llvm/Config/config.h" #endif #if IN_LLVM diff --git a/dmd2/root/rmem.h b/dmd2/root/rmem.h index 76cdd24653..9499475321 100644 --- a/dmd2/root/rmem.h +++ b/dmd2/root/rmem.h @@ -10,7 +10,7 @@ #ifndef ROOT_MEM_H #define ROOT_MEM_H -#if defined(IN_LLVM) && (LDC_LLVM_VER >= 303) +#if defined(IN_LLVM) && ((LDC_LLVM_VER == 303) || (LDC_LLVM_VER == 304)) #include "llvm/Config/config.h" #endif #include // for size_t diff --git a/driver/linker.cpp b/driver/linker.cpp index e6c22f6cb9..75bf03dbb6 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -45,7 +45,12 @@ static void CreateDirectoryOnDisk(llvm::StringRef fileName) if (!dir.empty() && !llvm::sys::fs::exists(dir)) { bool Existed; - llvm::error_code ec = llvm::sys::fs::create_directory(dir, Existed); +#if LDC_LLVM_VER >= 305 + std::error_code +#else + llvm::error_code +#endif + ec = llvm::sys::fs::create_directory(dir, Existed); if (ec) { error(Loc(), "failed to create path to file: %s\n%s", dir.data(), ec.message().c_str()); diff --git a/driver/main.cpp b/driver/main.cpp index 7fef1ad134..9bd5f16931 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -797,6 +797,7 @@ static void dumpPredefinedVersions() } static Module *entrypoint = NULL; +static Module *rootHasMain = NULL; /// Callback to generate a C main() function, invoked by the frontend. void genCmain(Scope *sc) @@ -826,7 +827,7 @@ void genCmain(Scope *sc) char v = global.params.verbose; global.params.verbose = 0; - m->importedFrom = sc->module; + m->importedFrom = m; m->importAll(NULL); m->semantic(); m->semantic2(); @@ -834,6 +835,7 @@ void genCmain(Scope *sc) global.params.verbose = v; entrypoint = m; + rootHasMain = sc->module; } int main(int argc, char **argv) @@ -1246,7 +1248,7 @@ int main(int argc, char **argv) if (global.params.obj) { llvm::Module* lm = m->genLLVMModule(context); - if (entrypoint && entrypoint->importedFrom == m) + if (entrypoint && rootHasMain == m) { #if LDC_LLVM_VER >= 303 llvm::Linker linker(lm); diff --git a/gen/functions.cpp b/gen/functions.cpp index 54729c9508..009e5a8e2e 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -928,44 +928,44 @@ void DtoDefineFunction(FuncDeclaration* fd) if (fd->ir.defined) return; + if ((fd->type && fd->type->ty == Tfunction && static_cast(fd->type)->next == NULL) || + (fd->type && fd->type->ty == Tfunction && static_cast(fd->type)->next->ty == Terror)) + { + IF_LOG Logger::println("Ignoring; no return type or return error type"); + fd->ir.defined = true; + return; + } + + if (fd->isUnitTestDeclaration() && !global.params.useUnitTests) + { + IF_LOG Logger::println("No code generation for unit test declaration %s", fd->toChars()); + fd->ir.defined = true; + return; + } + + if (fd->semanticRun == PASSsemanticdone) + { + /* What happened is this function failed semantic3() with errors, + * but the errors were gagged. + * Try to reproduce those errors, and then fail. + */ + error("errors compiling function %s", fd->toPrettyChars()); + fd->ir.defined = true; + return; + } + assert(fd->semanticRun == PASSsemantic3done); + assert(fd->ident != Id::empty); + // Skip generating code for this part of a TemplateInstance if it has been // instantiated by any non-root module (i.e. a module not listed on the // command line). - // See DMD's FuncDeclaration::toObjFile. Check this before calling - // DtoDeclareFunction DtoDeclareFunction to avoid touching unanalyzed code. - TemplateInstance *ti = fd->isInstantiated(); - if (!global.params.useUnitTests && - ti && ti->instantiatingModule && !ti->instantiatingModule->isRoot()) + // Check this before calling DtoDeclareFunction to avoid touching + // unanalyzed code. + if (!fd->needsCodegen()) { - Module *mi = ti->instantiatingModule; - - // If mi imports any root modules, we still need to generate the code. - for (size_t i = 0; i < Module::amodules.dim; ++i) - { - Module *m = Module::amodules[i]; - m->insearch = 0; - } - bool importsRoot = false; - for (size_t i = 0; i < Module::amodules.dim; ++i) - { - Module *m = Module::amodules[i]; - if (m->isRoot() && mi->imports(m)) - { - importsRoot = true; - break; - } - } - for (size_t i = 0; i < Module::amodules.dim; ++i) - { - Module *m = Module::amodules[i]; - m->insearch = 0; - } - if (!importsRoot) - { - IF_LOG Logger::println("Ignoring; already instantiated in %s (%s)", ti->instantiatingModule->toChars(), ti->toChars()); - fd->ir.defined = true; - return; - } + IF_LOG Logger::println("No code generation for %s", fd->toChars()); + fd->ir.defined = true; + return; } DtoDeclareFunction(fd); diff --git a/gen/toir.cpp b/gen/toir.cpp index bb24fa70eb..e3aed4a1bf 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2839,6 +2839,13 @@ DValue* FuncExp::toElem(IRState* p) // We need to actually codegen the function here, as literals are not added // to the module member list. Declaration_codegen(fd, p); + if (!fd->ir.irFunc) + { + // See DtoDefineFunction for reasons why codegen was suppressed. + // Instead just declare the function. + DtoDeclareFunction(fd); + assert(!fd->isNested()); + } assert(fd->ir.irFunc->func); if (fd->isNested()) {