Index: llvm/trunk/include/llvm/LTO/LTOModule.h =================================================================== --- llvm/trunk/include/llvm/LTO/LTOModule.h +++ llvm/trunk/include/llvm/LTO/LTOModule.h @@ -57,8 +57,6 @@ std::vector _asm_undefines; LTOModule(std::unique_ptr Obj, TargetMachine *TM); - LTOModule(std::unique_ptr Obj, TargetMachine *TM, - std::unique_ptr Context); public: ~LTOModule(); @@ -100,13 +98,9 @@ static ErrorOr> createFromBuffer(LLVMContext &Context, const void *mem, size_t length, TargetOptions options, StringRef path = ""); - - static ErrorOr> - createInLocalContext(const void *mem, size_t length, TargetOptions options, - StringRef path); static ErrorOr> - createInContext(const void *mem, size_t length, TargetOptions options, - StringRef path, LLVMContext *Context); + createInLocalContext(std::unique_ptr Context, const void *mem, + size_t length, TargetOptions options, StringRef path); const Module &getModule() const { return const_cast(this)->getModule(); @@ -206,7 +200,7 @@ /// Create an LTOModule (private version). static ErrorOr> makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, - LLVMContext *Context); + LLVMContext &Context, bool ShouldBeLazy); }; } #endif Index: llvm/trunk/lib/LTO/LTOModule.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOModule.cpp +++ llvm/trunk/lib/LTO/LTOModule.cpp @@ -54,11 +54,6 @@ llvm::TargetMachine *TM) : IRFile(std::move(Obj)), _target(TM) {} -LTOModule::LTOModule(std::unique_ptr Obj, - llvm::TargetMachine *TM, - std::unique_ptr Context) - : OwnedContext(std::move(Context)), IRFile(std::move(Obj)), _target(TM) {} - LTOModule::~LTOModule() {} /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM @@ -110,7 +105,8 @@ return EC; } std::unique_ptr Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, &Context); + return makeLTOModule(Buffer->getMemBufferRef(), options, Context, + /* ShouldBeLazy*/ false); } ErrorOr> @@ -130,29 +126,32 @@ return EC; } std::unique_ptr Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, &Context); + return makeLTOModule(Buffer->getMemBufferRef(), options, Context, + /* ShouldBeLazy */ false); } ErrorOr> LTOModule::createFromBuffer(LLVMContext &Context, const void *mem, size_t length, TargetOptions options, StringRef path) { - return createInContext(mem, length, options, path, &Context); + StringRef Data((const char *)mem, length); + MemoryBufferRef Buffer(Data, path); + return makeLTOModule(Buffer, options, Context, /* ShouldBeLazy */ false); } ErrorOr> -LTOModule::createInLocalContext(const void *mem, size_t length, +LTOModule::createInLocalContext(std::unique_ptr Context, + const void *mem, size_t length, TargetOptions options, StringRef path) { - return createInContext(mem, length, options, path, nullptr); -} - -ErrorOr> -LTOModule::createInContext(const void *mem, size_t length, - TargetOptions options, StringRef path, - LLVMContext *Context) { StringRef Data((const char *)mem, length); MemoryBufferRef Buffer(Data, path); - return makeLTOModule(Buffer, options, Context); + // If we own a context, we know this is being used only for symbol extraction, + // not linking. Be lazy in that case. + ErrorOr> Ret = + makeLTOModule(Buffer, options, *Context, /* ShouldBeLazy */ true); + if (Ret) + (*Ret)->OwnedContext = std::move(Context); + return std::move(Ret); } static ErrorOr> @@ -187,18 +186,9 @@ ErrorOr> LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options, - LLVMContext *Context) { - std::unique_ptr OwnedContext; - if (!Context) { - OwnedContext = llvm::make_unique(); - Context = OwnedContext.get(); - } - - // If we own a context, we know this is being used only for symbol - // extraction, not linking. Be lazy in that case. + LLVMContext &Context, bool ShouldBeLazy) { ErrorOr> MOrErr = - parseBitcodeFileImpl(Buffer, *Context, - /* ShouldBeLazy */ static_cast(OwnedContext)); + parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy); if (std::error_code EC = MOrErr.getError()) return EC; std::unique_ptr &M = *MOrErr; @@ -236,12 +226,7 @@ std::unique_ptr IRObj( new object::IRObjectFile(Buffer, std::move(M))); - std::unique_ptr Ret; - if (OwnedContext) - Ret.reset(new LTOModule(std::move(IRObj), target, std::move(OwnedContext))); - else - Ret.reset(new LTOModule(std::move(IRObj), target)); - + std::unique_ptr Ret(new LTOModule(std::move(IRObj), target)); Ret->parseSymbols(); Ret->parseMetadata(); Index: llvm/trunk/test/tools/llvm-lto/error.ll =================================================================== --- llvm/trunk/test/tools/llvm-lto/error.ll +++ llvm/trunk/test/tools/llvm-lto/error.ll @@ -1,2 +1,5 @@ ; RUN: not llvm-lto foobar 2>&1 | FileCheck %s ; CHECK: llvm-lto: error loading file 'foobar': {{N|n}}o such file or directory + +; RUN: not llvm-lto --list-symbols-only %S/Inputs/empty.bc 2>&1 | FileCheck %s --check-prefix=CHECK-LIST +; CHECK-LIST: llvm-lto: error loading file '{{.*}}/Inputs/empty.bc': The file was not recognized as a valid object file Index: llvm/trunk/tools/llvm-lto/llvm-lto.cpp =================================================================== --- llvm/trunk/tools/llvm-lto/llvm-lto.cpp +++ llvm/trunk/tools/llvm-lto/llvm-lto.cpp @@ -158,8 +158,8 @@ exit(1); } -static void diagnosticHandlerWithContenxt(const DiagnosticInfo &DI, - void *Context) { +static void diagnosticHandlerWithContext(const DiagnosticInfo &DI, + void *Context) { diagnosticHandler(DI); } @@ -186,8 +186,11 @@ error(BufferOrErr, "error loading file '" + Path + "'"); Buffer = std::move(BufferOrErr.get()); CurrentActivity = ("loading file '" + Path + "'").str(); + std::unique_ptr Context = llvm::make_unique(); + Context->setDiagnosticHandler(diagnosticHandlerWithContext, nullptr, true); ErrorOr> Ret = LTOModule::createInLocalContext( - Buffer->getBufferStart(), Buffer->getBufferSize(), Options, Path); + std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(), + Options, Path); CurrentActivity = ""; return std::move(*Ret); } @@ -271,7 +274,7 @@ unsigned BaseArg = 0; LLVMContext Context; - Context.setDiagnosticHandler(diagnosticHandlerWithContenxt, nullptr, true); + Context.setDiagnosticHandler(diagnosticHandlerWithContext, nullptr, true); LTOCodeGenerator CodeGen(Context); Index: llvm/trunk/tools/lto/lto.cpp =================================================================== --- llvm/trunk/tools/lto/lto.cpp +++ llvm/trunk/tools/lto/lto.cpp @@ -248,8 +248,14 @@ const char *path) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + + // Create a local context. Ownership will be transfered to LTOModule. + std::unique_ptr Context = llvm::make_unique(); + Context->setDiagnosticHandler(diagnosticHandler, nullptr, true); + ErrorOr> M = - LTOModule::createInLocalContext(mem, length, Options, path); + LTOModule::createInLocalContext(std::move(Context), mem, length, Options, + path); if (!M) return nullptr; return wrap(M->release()); @@ -261,8 +267,8 @@ lto_code_gen_t cg) { lto_initialize(); llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - ErrorOr> M = LTOModule::createInContext( - mem, length, Options, path, &unwrap(cg)->getContext()); + ErrorOr> M = LTOModule::createFromBuffer( + unwrap(cg)->getContext(), mem, length, Options, path); return wrap(M->release()); }