Pass a std::unique_ptr& to the create??? methods is lib/Object.

This makes the buffer ownership on error conditions very natural. The buffer
is only moved out of the argument if an object is constructed that now
owns the buffer.

llvm-svn: 211546
This commit is contained in:
Rafael Espindola 2014-06-23 22:00:37 +00:00
parent aed5c96684
commit 6304e94108
16 changed files with 68 additions and 53 deletions

View File

@ -128,7 +128,7 @@ public:
/// @param Source The data to create the Binary from. Ownership is transferred
/// to the Binary if successful. If an error is returned,
/// Source is destroyed by createBinary before returning.
ErrorOr<Binary *> createBinary(MemoryBuffer *Source,
ErrorOr<Binary *> createBinary(std::unique_ptr<MemoryBuffer> &Source,
LLVMContext *Context = nullptr);
ErrorOr<Binary *> createBinary(StringRef Path);

View File

@ -333,9 +333,11 @@ public:
/// return true.
/// @brief Create ObjectFile from path.
static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object,
sys::fs::file_magic Type);
static ErrorOr<ObjectFile *> createObjectFile(MemoryBuffer *Object) {
static ErrorOr<ObjectFile *>
createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
sys::fs::file_magic Type);
static ErrorOr<ObjectFile *>
createObjectFile(std::unique_ptr<MemoryBuffer> &Object) {
return createObjectFile(Object, sys::fs::file_magic::unknown);
}
@ -346,8 +348,10 @@ public:
public:
static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object);
static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object);
static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object);
static ErrorOr<ObjectFile *>
createELFObjectFile(std::unique_ptr<MemoryBuffer> &Object);
static ErrorOr<ObjectFile *>
createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Object);
};
// Inline function definitions.

View File

@ -145,11 +145,12 @@ public:
static ErrorOr<SymbolicFile *> createIRObjectFile(MemoryBuffer *Object,
LLVMContext &Context);
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object,
sys::fs::file_magic Type,
LLVMContext *Context);
static ErrorOr<SymbolicFile *>
createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
sys::fs::file_magic Type, LLVMContext *Context);
static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) {
static ErrorOr<SymbolicFile *>
createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object) {
return createSymbolicFile(Object, sys::fs::file_magic::unknown, nullptr);
}
static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath);

View File

@ -48,7 +48,8 @@ public:
{
// FIXME: error checking? createObjectFile returns an ErrorOr<ObjectFile*>
// and should probably be checked for failure.
ObjFile.reset(object::ObjectFile::createObjectFile(Buffer->getMemBuffer()).get());
std::unique_ptr<MemoryBuffer> Buf(Buffer->getMemBuffer());
ObjFile.reset(object::ObjectFile::createObjectFile(Buf).get());
}
ObjectImageCommon(std::unique_ptr<object::ObjectFile> Input)
: ObjectImage(nullptr), ObjFile(std::move(Input)) {}

View File

@ -183,10 +183,7 @@ Archive::Child::getAsBinary(LLVMContext *Context) const {
return EC;
std::unique_ptr<MemoryBuffer> Buff(BuffOrErr.get().release());
ErrorOr<std::unique_ptr<Binary>> Ret = createBinary(Buff.get(), Context);
if (!Ret.getError())
Buff.release();
return Ret;
return createBinary(Buff, Context);
}
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {

View File

@ -38,13 +38,13 @@ StringRef Binary::getFileName() const {
return Data->getBufferIdentifier();
}
ErrorOr<Binary *> object::createBinary(MemoryBuffer *Buffer,
ErrorOr<Binary *> object::createBinary(std::unique_ptr<MemoryBuffer> &Buffer,
LLVMContext *Context) {
sys::fs::file_magic Type = sys::fs::identify_magic(Buffer->getBuffer());
switch (Type) {
case sys::fs::file_magic::archive:
return Archive::create(Buffer);
return Archive::create(Buffer.release());
case sys::fs::file_magic::elf_relocatable:
case sys::fs::file_magic::elf_executable:
case sys::fs::file_magic::elf_shared_object:
@ -65,7 +65,7 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Buffer,
case sys::fs::file_magic::bitcode:
return ObjectFile::createSymbolicFile(Buffer, Type, Context);
case sys::fs::file_magic::macho_universal_binary:
return MachOUniversalBinary::create(Buffer);
return MachOUniversalBinary::create(Buffer.release());
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::windows_resource:
// Unrecognized object file format.
@ -78,5 +78,5 @@ ErrorOr<Binary *> object::createBinary(StringRef Path) {
std::unique_ptr<MemoryBuffer> File;
if (std::error_code EC = MemoryBuffer::getFileOrSTDIN(Path, File))
return EC;
return createBinary(File.release());
return createBinary(File);
}

View File

@ -17,8 +17,9 @@
namespace llvm {
using namespace object;
ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
ErrorOr<ObjectFile *>
ObjectFile::createELFObjectFile(std::unique_ptr<MemoryBuffer> &Obj) {
std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj.get());
std::size_t MaxAlignment =
1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
@ -27,41 +28,49 @@ ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(Obj, EC));
R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(
Obj.release(), EC));
else
#endif
if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(Obj, EC));
R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(
Obj.release(), EC));
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 4)
R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj, EC));
R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj.release(),
EC));
else
#endif
if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj, EC));
R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj.release(),
EC));
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(Obj, EC));
R.reset(
new ELFObjectFile<ELFType<support::big, 8, true>>(Obj.release(), EC));
else
#endif
if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(Obj, EC));
R.reset(
new ELFObjectFile<ELFType<support::big, 2, true>>(Obj.release(), EC));
else
return object_error::parse_failed;
else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
#if !LLVM_IS_UNALIGNED_ACCESS_FAST
if (MaxAlignment >= 8)
R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(Obj, EC));
R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(
Obj.release(), EC));
else
#endif
if (MaxAlignment >= 2)
R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(Obj, EC));
R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(
Obj.release(), EC));
else
return object_error::parse_failed;
}

View File

@ -1811,22 +1811,21 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index,
}
}
ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
ErrorOr<ObjectFile *>
ObjectFile::createMachOObjectFile(std::unique_ptr<MemoryBuffer> &Buffer) {
StringRef Magic = Buffer->getBuffer().slice(0, 4);
std::error_code EC;
std::unique_ptr<MachOObjectFile> Ret;
if (Magic == "\xFE\xED\xFA\xCE")
Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
Ret.reset(new MachOObjectFile(Buffer.release(), false, false, EC));
else if (Magic == "\xCE\xFA\xED\xFE")
Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
Ret.reset(new MachOObjectFile(Buffer.release(), true, false, EC));
else if (Magic == "\xFE\xED\xFA\xCF")
Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
Ret.reset(new MachOObjectFile(Buffer.release(), false, true, EC));
else if (Magic == "\xCF\xFA\xED\xFE")
Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
else {
delete Buffer;
Ret.reset(new MachOObjectFile(Buffer.release(), true, true, EC));
else
return object_error::parse_failed;
}
if (EC)
return EC;

View File

@ -73,8 +73,8 @@ MachOUniversalBinary::ObjectForArch::getAsObjectFile() const {
StringRef ParentData = Parent->getData();
StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
std::string ObjectName = Parent->getFileName().str();
MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
ObjectData, ObjectName, false);
std::unique_ptr<MemoryBuffer> ObjBuffer(
MemoryBuffer::getMemBuffer(ObjectData, ObjectName, false));
return ObjectFile::createMachOObjectFile(ObjBuffer);
}
return object_error::parse_failed;

View File

@ -59,7 +59,9 @@ wrap(const relocation_iterator *SI) {
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf)));
std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buf));
Buf.release();
ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : nullptr;
return wrap(Obj);
}

View File

@ -45,8 +45,9 @@ section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
return section_iterator(SectionRef(Sec, this));
}
ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
sys::fs::file_magic Type) {
ErrorOr<ObjectFile *>
ObjectFile::createObjectFile(std::unique_ptr<MemoryBuffer> &Object,
sys::fs::file_magic Type) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
@ -76,7 +77,7 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
case sys::fs::file_magic::coff_object:
case sys::fs::file_magic::coff_import_library:
case sys::fs::file_magic::pecoff_executable:
return createCOFFObjectFile(Object);
return createCOFFObjectFile(Object.release());
}
llvm_unreachable("Unexpected Object File Type");
}
@ -85,5 +86,5 @@ ErrorOr<ObjectFile *> ObjectFile::createObjectFile(StringRef ObjectPath) {
std::unique_ptr<MemoryBuffer> File;
if (std::error_code EC = MemoryBuffer::getFile(ObjectPath, File))
return EC;
return createObjectFile(File.release());
return createObjectFile(File);
}

View File

@ -25,7 +25,8 @@ SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source)
SymbolicFile::~SymbolicFile() {}
ErrorOr<SymbolicFile *>
SymbolicFile::createSymbolicFile(MemoryBuffer *Object, sys::fs::file_magic Type,
SymbolicFile::createSymbolicFile(std::unique_ptr<MemoryBuffer> &Object,
sys::fs::file_magic Type,
LLVMContext *Context) {
if (Type == sys::fs::file_magic::unknown)
Type = sys::fs::identify_magic(Object->getBuffer());
@ -33,7 +34,7 @@ SymbolicFile::createSymbolicFile(MemoryBuffer *Object, sys::fs::file_magic Type,
switch (Type) {
case sys::fs::file_magic::bitcode:
if (Context)
return IRObjectFile::createIRObjectFile(Object, *Context);
return IRObjectFile::createIRObjectFile(Object.release(), *Context);
// Fallthrough
case sys::fs::file_magic::unknown:
case sys::fs::file_magic::archive:

View File

@ -685,7 +685,7 @@ static void writeStringTable(raw_fd_ostream &Out,
static void
writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
ArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
MutableArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
std::vector<std::pair<unsigned, unsigned>> &MemberOffsetRefs) {
unsigned StartOffset = 0;
unsigned MemberNum = 0;
@ -696,7 +696,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(),
E = Members.end();
I != E; ++I, ++MemberNum) {
MemoryBuffer *MemberBuffer = Buffers[MemberNum].get();
std::unique_ptr<MemoryBuffer> &MemberBuffer = Buffers[MemberNum];
ErrorOr<object::SymbolicFile *> ObjOrErr =
object::SymbolicFile::createSymbolicFile(
MemberBuffer, sys::fs::file_magic::unknown, &Context);
@ -724,7 +724,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
print32BE(Out, 0);
}
Obj->releaseBuffer();
MemberBuffer.reset(Obj->releaseBuffer());
}
Out << NameOS.str();

View File

@ -73,7 +73,7 @@ static void DumpInput(const StringRef &Filename) {
return;
}
ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(Buff.release()));
ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buff));
if (std::error_code EC = ObjOrErr.getError()) {
errs() << Filename << ": " << EC.message() << '\n';
return;

View File

@ -726,7 +726,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
return;
LLVMContext &Context = getGlobalContext();
ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.get(), &Context);
ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer, &Context);
if (error(BinaryOrErr.getError(), Filename))
return;
Buffer.release();

View File

@ -203,7 +203,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
}
std::unique_ptr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile *>(
ObjectFile::createMachOObjectFile(Buff.release()).get()));
ObjectFile::createMachOObjectFile(Buff).get()));
DisassembleInputMachO2(Filename, MachOOF.get());
}
@ -293,7 +293,7 @@ static void DisassembleInputMachO2(StringRef Filename,
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
return;
}
DbgObj = ObjectFile::createMachOObjectFile(Buf.release()).get();
DbgObj = ObjectFile::createMachOObjectFile(Buf).get();
}
// Setup the DIContext