forked from OSchip/llvm-project
[LTO] Fix error reporting from lto_module_create_in_local_context()
Function lto_module_create_in_local_context() would previously rely on the default LLVMContext being created for it by LTOModule::makeLTOModule(). This context exits the program on error and is not arranged to update sLastStringError in tools/lto/lto.cpp. Function lto_module_create_in_local_context() now creates an LLVMContext by itself, sets it up correctly to its needs and then passes it to LTOModule::createInLocalContext() which takes ownership of the context and keeps it present for the lifetime of the returned LTOModule. Function LTOModule::makeLTOModule() is modified to take a reference to LLVMContext (instead of a pointer) and no longer creates a default context when nullptr is passed to it. Method LTOModule::createInContext() that takes a pointer to LLVMContext is removed because it allows to pass a nullptr to it. Instead LTOModule::createFromBuffer() (that takes a reference to LLVMContext) should be used. Differential Revision: http://reviews.llvm.org/D17715 llvm-svn: 262330
This commit is contained in:
parent
15765f5db7
commit
7ad9ec9fcf
|
@ -57,8 +57,6 @@ private:
|
|||
std::vector<const char*> _asm_undefines;
|
||||
|
||||
LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM);
|
||||
LTOModule(std::unique_ptr<object::IRObjectFile> Obj, TargetMachine *TM,
|
||||
std::unique_ptr<LLVMContext> Context);
|
||||
|
||||
public:
|
||||
~LTOModule();
|
||||
|
@ -100,13 +98,9 @@ public:
|
|||
static ErrorOr<std::unique_ptr<LTOModule>>
|
||||
createFromBuffer(LLVMContext &Context, const void *mem, size_t length,
|
||||
TargetOptions options, StringRef path = "");
|
||||
|
||||
static ErrorOr<std::unique_ptr<LTOModule>>
|
||||
createInLocalContext(const void *mem, size_t length, TargetOptions options,
|
||||
StringRef path);
|
||||
static ErrorOr<std::unique_ptr<LTOModule>>
|
||||
createInContext(const void *mem, size_t length, TargetOptions options,
|
||||
StringRef path, LLVMContext *Context);
|
||||
createInLocalContext(std::unique_ptr<LLVMContext> Context, const void *mem,
|
||||
size_t length, TargetOptions options, StringRef path);
|
||||
|
||||
const Module &getModule() const {
|
||||
return const_cast<LTOModule*>(this)->getModule();
|
||||
|
@ -206,7 +200,7 @@ private:
|
|||
/// Create an LTOModule (private version).
|
||||
static ErrorOr<std::unique_ptr<LTOModule>>
|
||||
makeLTOModule(MemoryBufferRef Buffer, TargetOptions options,
|
||||
LLVMContext *Context);
|
||||
LLVMContext &Context, bool ShouldBeLazy);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -54,11 +54,6 @@ LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
|
|||
llvm::TargetMachine *TM)
|
||||
: IRFile(std::move(Obj)), _target(TM) {}
|
||||
|
||||
LTOModule::LTOModule(std::unique_ptr<object::IRObjectFile> Obj,
|
||||
llvm::TargetMachine *TM,
|
||||
std::unique_ptr<LLVMContext> 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 @@ LTOModule::createFromFile(LLVMContext &Context, const char *path,
|
|||
return EC;
|
||||
}
|
||||
std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
|
||||
return makeLTOModule(Buffer->getMemBufferRef(), options, &Context);
|
||||
return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
|
||||
/* ShouldBeLazy*/ false);
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<LTOModule>>
|
||||
|
@ -130,29 +126,32 @@ LTOModule::createFromOpenFileSlice(LLVMContext &Context, int fd,
|
|||
return EC;
|
||||
}
|
||||
std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get());
|
||||
return makeLTOModule(Buffer->getMemBufferRef(), options, &Context);
|
||||
return makeLTOModule(Buffer->getMemBufferRef(), options, Context,
|
||||
/* ShouldBeLazy */ false);
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<LTOModule>>
|
||||
LTOModule::createFromBuffer(LLVMContext &Context, const void *mem,
|
||||
size_t length, TargetOptions options,
|
||||
StringRef path) {
|
||||
return createInContext(mem, length, options, path, &Context);
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<LTOModule>>
|
||||
LTOModule::createInLocalContext(const void *mem, size_t length,
|
||||
TargetOptions options, StringRef path) {
|
||||
return createInContext(mem, length, options, path, nullptr);
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<LTOModule>>
|
||||
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);
|
||||
return makeLTOModule(Buffer, options, Context, /* ShouldBeLazy */ false);
|
||||
}
|
||||
|
||||
ErrorOr<std::unique_ptr<LTOModule>>
|
||||
LTOModule::createInLocalContext(std::unique_ptr<LLVMContext> Context,
|
||||
const void *mem, size_t length,
|
||||
TargetOptions options, StringRef path) {
|
||||
StringRef Data((const char *)mem, length);
|
||||
MemoryBufferRef Buffer(Data, path);
|
||||
// If we own a context, we know this is being used only for symbol extraction,
|
||||
// not linking. Be lazy in that case.
|
||||
ErrorOr<std::unique_ptr<LTOModule>> Ret =
|
||||
makeLTOModule(Buffer, options, *Context, /* ShouldBeLazy */ true);
|
||||
if (Ret)
|
||||
(*Ret)->OwnedContext = std::move(Context);
|
||||
return std::move(Ret);
|
||||
}
|
||||
|
||||
static ErrorOr<std::unique_ptr<Module>>
|
||||
|
@ -187,18 +186,9 @@ parseBitcodeFileImpl(MemoryBufferRef Buffer, LLVMContext &Context,
|
|||
|
||||
ErrorOr<std::unique_ptr<LTOModule>>
|
||||
LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options,
|
||||
LLVMContext *Context) {
|
||||
std::unique_ptr<LLVMContext> OwnedContext;
|
||||
if (!Context) {
|
||||
OwnedContext = llvm::make_unique<LLVMContext>();
|
||||
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<std::unique_ptr<Module>> MOrErr =
|
||||
parseBitcodeFileImpl(Buffer, *Context,
|
||||
/* ShouldBeLazy */ static_cast<bool>(OwnedContext));
|
||||
parseBitcodeFileImpl(Buffer, Context, ShouldBeLazy);
|
||||
if (std::error_code EC = MOrErr.getError())
|
||||
return EC;
|
||||
std::unique_ptr<Module> &M = *MOrErr;
|
||||
|
@ -236,12 +226,7 @@ LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetOptions options,
|
|||
std::unique_ptr<object::IRObjectFile> IRObj(
|
||||
new object::IRObjectFile(Buffer, std::move(M)));
|
||||
|
||||
std::unique_ptr<LTOModule> 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<LTOModule> Ret(new LTOModule(std::move(IRObj), target));
|
||||
Ret->parseSymbols();
|
||||
Ret->parseMetadata();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -158,8 +158,8 @@ static void diagnosticHandler(const DiagnosticInfo &DI) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static void diagnosticHandlerWithContenxt(const DiagnosticInfo &DI,
|
||||
void *Context) {
|
||||
static void diagnosticHandlerWithContext(const DiagnosticInfo &DI,
|
||||
void *Context) {
|
||||
diagnosticHandler(DI);
|
||||
}
|
||||
|
||||
|
@ -186,8 +186,11 @@ getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer,
|
|||
error(BufferOrErr, "error loading file '" + Path + "'");
|
||||
Buffer = std::move(BufferOrErr.get());
|
||||
CurrentActivity = ("loading file '" + Path + "'").str();
|
||||
std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>();
|
||||
Context->setDiagnosticHandler(diagnosticHandlerWithContext, nullptr, true);
|
||||
ErrorOr<std::unique_ptr<LTOModule>> 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 @@ int main(int argc, char **argv) {
|
|||
unsigned BaseArg = 0;
|
||||
|
||||
LLVMContext Context;
|
||||
Context.setDiagnosticHandler(diagnosticHandlerWithContenxt, nullptr, true);
|
||||
Context.setDiagnosticHandler(diagnosticHandlerWithContext, nullptr, true);
|
||||
|
||||
LTOCodeGenerator CodeGen(Context);
|
||||
|
||||
|
|
|
@ -248,8 +248,14 @@ lto_module_t lto_module_create_in_local_context(const void *mem, size_t length,
|
|||
const char *path) {
|
||||
lto_initialize();
|
||||
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
|
||||
|
||||
// Create a local context. Ownership will be transfered to LTOModule.
|
||||
std::unique_ptr<LLVMContext> Context = llvm::make_unique<LLVMContext>();
|
||||
Context->setDiagnosticHandler(diagnosticHandler, nullptr, true);
|
||||
|
||||
ErrorOr<std::unique_ptr<LTOModule>> 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_module_t lto_module_create_in_codegen_context(const void *mem,
|
|||
lto_code_gen_t cg) {
|
||||
lto_initialize();
|
||||
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
|
||||
ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInContext(
|
||||
mem, length, Options, path, &unwrap(cg)->getContext());
|
||||
ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromBuffer(
|
||||
unwrap(cg)->getContext(), mem, length, Options, path);
|
||||
return wrap(M->release());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue