Convert the Archive API to use ErrorOr.

Now that we have c++11, even things like ErrorOr<std::unique_ptr<...>> are
easy to use.

No intended functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211033 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2014-06-16 16:08:36 +00:00
parent d492c19894
commit 0659928fec
8 changed files with 93 additions and 98 deletions

View File

@ -72,7 +72,7 @@ public:
Child getNext() const;
std::error_code getName(StringRef &Result) const;
ErrorOr<StringRef> getName() const;
StringRef getRawName() const { return getHeader()->getName(); }
sys::TimeValue getLastModified() const {
return getHeader()->getLastModified();
@ -89,11 +89,11 @@ public:
return StringRef(Data.data() + StartOfFile, getSize());
}
std::error_code getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
bool FullPath = false) const;
ErrorOr<std::unique_ptr<MemoryBuffer>>
getMemoryBuffer(bool FullPath = false) const;
std::error_code getAsBinary(std::unique_ptr<Binary> &Result,
LLVMContext *Context = nullptr) const;
ErrorOr<std::unique_ptr<Binary>>
getAsBinary(LLVMContext *Context = nullptr) const;
};
class child_iterator {
@ -137,8 +137,8 @@ public:
: Parent(p)
, SymbolIndex(symi)
, StringIndex(stri) {}
std::error_code getName(StringRef &Result) const;
std::error_code getMember(child_iterator &Result) const;
StringRef getName() const;
ErrorOr<child_iterator> getMember() const;
Symbol getNext() const;
};

View File

@ -305,9 +305,13 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
// Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name);
if (ChildIt != A->child_end()) {
std::unique_ptr<object::Binary> ChildBin;
// FIXME: Support nested archives?
if (!ChildIt->getAsBinary(ChildBin) && ChildBin->isObject()) {
ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
ChildIt->getAsBinary();
if (ChildBinOrErr.getError())
continue;
std::unique_ptr<object::Binary> ChildBin = std::move(ChildBinOrErr.get());
if (ChildBin->isObject()) {
std::unique_ptr<object::ObjectFile> OF(
static_cast<object::ObjectFile *>(ChildBin.release()));
// This causes the object file to be loaded.

View File

@ -115,18 +115,14 @@ Archive::Child Archive::Child::getNext() const {
return Child(Parent, NextLoc);
}
std::error_code Archive::Child::getName(StringRef &Result) const {
ErrorOr<StringRef> Archive::Child::getName() const {
StringRef name = getRawName();
// Check if it's a special name.
if (name[0] == '/') {
if (name.size() == 1) { // Linker member.
Result = name;
return object_error::success;
}
if (name.size() == 2 && name[1] == '/') { // String table.
Result = name;
return object_error::success;
}
if (name.size() == 1) // Linker member.
return name;
if (name.size() == 2 && name[1] == '/') // String table.
return name;
// It's a long name.
// Get the offset.
std::size_t offset;
@ -147,53 +143,45 @@ std::error_code Archive::Child::getName(StringRef &Result) const {
// GNU long file names end with a /.
if (Parent->kind() == K_GNU) {
StringRef::size_type End = StringRef(addr).find('/');
Result = StringRef(addr, End);
} else {
Result = addr;
return StringRef(addr, End);
}
return object_error::success;
return StringRef(addr);
} else if (name.startswith("#1/")) {
uint64_t name_size;
if (name.substr(3).rtrim(" ").getAsInteger(10, name_size))
llvm_unreachable("Long name length is not an ingeter");
Result = Data.substr(sizeof(ArchiveMemberHeader), name_size)
return Data.substr(sizeof(ArchiveMemberHeader), name_size)
.rtrim(StringRef("\0", 1));
return object_error::success;
}
// It's a simple name.
if (name[name.size() - 1] == '/')
Result = name.substr(0, name.size() - 1);
else
Result = name;
return object_error::success;
return name.substr(0, name.size() - 1);
return name;
}
std::error_code
Archive::Child::getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result,
bool FullPath) const {
StringRef Name;
if (std::error_code ec = getName(Name))
return ec;
SmallString<128> Path;
Result.reset(MemoryBuffer::getMemBuffer(
getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name + ")")
.toStringRef(Path)
: Name,
false));
return std::error_code();
}
std::error_code Archive::Child::getAsBinary(std::unique_ptr<Binary> &Result,
LLVMContext *Context) const {
std::unique_ptr<Binary> ret;
std::unique_ptr<MemoryBuffer> Buff;
if (std::error_code ec = getMemoryBuffer(Buff))
return ec;
ErrorOr<Binary *> BinaryOrErr = createBinary(Buff.release(), Context);
if (std::error_code EC = BinaryOrErr.getError())
ErrorOr<std::unique_ptr<MemoryBuffer>>
Archive::Child::getMemoryBuffer(bool FullPath) const {
ErrorOr<StringRef> NameOrErr = getName();
if (std::error_code EC = NameOrErr.getError())
return EC;
Result.reset(BinaryOrErr.get());
return object_error::success;
StringRef Name = NameOrErr.get();
SmallString<128> Path;
std::unique_ptr<MemoryBuffer> Ret(MemoryBuffer::getMemBuffer(
getBuffer(),
FullPath
? (Twine(Parent->getFileName()) + "(" + Name + ")").toStringRef(Path)
: Name,
false));
return std::move(Ret);
}
ErrorOr<std::unique_ptr<Binary>>
Archive::Child::getAsBinary(LLVMContext *Context) const {
std::unique_ptr<Binary> ret;
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = getMemoryBuffer();
if (std::error_code EC = BuffOrErr.getError())
return EC;
return createBinary(BuffOrErr.get().release(), Context);
}
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
@ -256,9 +244,11 @@ Archive::Archive(MemoryBuffer *source, std::error_code &ec)
if (Name.startswith("#1/")) {
Format = K_BSD;
// We know this is BSD, so getName will work since there is no string table.
ec = i->getName(Name);
ErrorOr<StringRef> NameOrErr = i->getName();
ec = NameOrErr.getError();
if (ec)
return;
Name = NameOrErr.get();
if (Name == "__.SYMDEF SORTED") {
SymbolTable = i;
++i;
@ -336,12 +326,11 @@ Archive::child_iterator Archive::child_end() const {
return Child(this, nullptr);
}
std::error_code Archive::Symbol::getName(StringRef &Result) const {
Result = StringRef(Parent->SymbolTable->getBuffer().begin() + StringIndex);
return object_error::success;
StringRef Archive::Symbol::getName() const {
return Parent->SymbolTable->getBuffer().begin() + StringIndex;
}
std::error_code Archive::Symbol::getMember(child_iterator &Result) const {
ErrorOr<Archive::child_iterator> Archive::Symbol::getMember() const {
const char *Buf = Parent->SymbolTable->getBuffer().begin();
const char *Offsets = Buf + 4;
uint32_t Offset = 0;
@ -381,9 +370,8 @@ std::error_code Archive::Symbol::getMember(child_iterator &Result) const {
}
const char *Loc = Parent->getData().begin() + Offset;
Result = Child(Parent, Loc);
return object_error::success;
child_iterator Iter(Child(Parent, Loc));
return Iter;
}
Archive::Symbol Archive::Symbol::getNext() const {
@ -441,16 +429,15 @@ Archive::symbol_iterator Archive::symbol_end() const {
Archive::child_iterator Archive::findSym(StringRef name) const {
Archive::symbol_iterator bs = symbol_begin();
Archive::symbol_iterator es = symbol_end();
Archive::child_iterator result;
StringRef symname;
for (; bs != es; ++bs) {
if (bs->getName(symname))
StringRef SymName = bs->getName();
if (SymName == name) {
ErrorOr<Archive::child_iterator> ResultOrErr = bs->getMember();
// FIXME: Should we really eat the error?
if (ResultOrErr.getError())
return child_end();
if (symname == name) {
if (bs->getMember(result))
return child_end();
return result;
return ResultOrErr.get();
}
}
return child_end();

View File

@ -369,8 +369,9 @@ static void performReadOperation(ArchiveOperation Operation,
for (object::Archive::child_iterator I = OldArchive->child_begin(),
E = OldArchive->child_end();
I != E; ++I) {
StringRef Name;
failIfError(I->getName(Name));
ErrorOr<StringRef> NameOrErr = I->getName();
failIfError(NameOrErr.getError());
StringRef Name = NameOrErr.get();
if (!Members.empty() &&
std::find(Members.begin(), Members.end(), Name) == Members.end())
@ -544,8 +545,9 @@ computeNewArchiveMembers(ArchiveOperation Operation,
E = OldArchive->child_end();
I != E; ++I) {
int Pos = Ret.size();
StringRef Name;
failIfError(I->getName(Name));
ErrorOr<StringRef> NameOrErr = I->getName();
failIfError(NameOrErr.getError());
StringRef Name = NameOrErr.get();
if (Name == PosName) {
assert(AddAfter || AddBefore);
if (AddBefore)
@ -783,7 +785,10 @@ static void performWriteOperation(ArchiveOperation Operation,
} else {
object::Archive::child_iterator OldMember = Member.getOld();
failIfError(OldMember->getMemoryBuffer(MemberBuffer));
ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
OldMember->getMemoryBuffer();
failIfError(MemberBufferOrErr.getError());
MemberBuffer = std::move(MemberBufferOrErr.get());
}
MemberBuffers[I] = MemberBuffer.release();
}

View File

@ -733,16 +733,14 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
if (I != E) {
outs() << "Archive map\n";
for (; I != E; ++I) {
Archive::child_iterator C;
StringRef SymName;
StringRef FileName;
if (error(I->getMember(C)))
ErrorOr<Archive::child_iterator> C = I->getMember();
if (error(C.getError()))
return;
if (error(I->getName(SymName)))
ErrorOr<StringRef> FileNameOrErr = C.get()->getName();
if (error(FileNameOrErr.getError()))
return;
if (error(C->getName(FileName)))
return;
outs() << SymName << " in " << FileName << "\n";
StringRef SymName = I->getName();
outs() << SymName << " in " << FileNameOrErr.get() << "\n";
}
outs() << "\n";
}
@ -750,10 +748,10 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
I != E; ++I) {
std::unique_ptr<Binary> Child;
if (I->getAsBinary(Child, &Context))
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context);
if (ChildOrErr.getError())
continue;
if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
outs() << O->getFileName() << ":\n";
dumpSymbolNamesFromObject(O);
}
@ -773,10 +771,11 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
else if (!I->getAsArchive(A)) {
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
std::unique_ptr<Binary> Child;
if (AI->getAsBinary(Child, &Context))
ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
AI->getAsBinary(&Context);
if (ChildOrErr.getError())
continue;
if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
outs() << A->getFileName() << ":";
outs() << O->getFileName() << ":\n";
dumpSymbolNamesFromObject(O);

View File

@ -850,15 +850,15 @@ static void DumpObject(const ObjectFile *o) {
static void DumpArchive(const Archive *a) {
for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e;
++i) {
std::unique_ptr<Binary> child;
if (std::error_code EC = i->getAsBinary(child)) {
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
// Ignore non-object files.
if (EC != object_error::invalid_file_type)
errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message()
<< ".\n";
continue;
}
if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
DumpObject(o);
else
errs() << ToolName << ": '" << a->getFileName() << "': "

View File

@ -242,15 +242,15 @@ static void dumpArchive(const Archive *Arc) {
for (Archive::child_iterator ArcI = Arc->child_begin(),
ArcE = Arc->child_end();
ArcI != ArcE; ++ArcI) {
std::unique_ptr<Binary> child;
if (std::error_code EC = ArcI->getAsBinary(child)) {
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = ArcI->getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
// Ignore non-object files.
if (EC != object_error::invalid_file_type)
reportError(Arc->getFileName(), EC.message());
continue;
}
if (ObjectFile *Obj = dyn_cast<ObjectFile>(child.get()))
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
dumpObject(Obj);
else
reportError(Arc->getFileName(), readobj_error::unrecognized_file_format);

View File

@ -245,12 +245,12 @@ static void PrintFileSectionSizes(StringRef file) {
// This is an archive. Iterate over each member and display its sizes.
for (object::Archive::child_iterator i = a->child_begin(),
e = a->child_end(); i != e; ++i) {
std::unique_ptr<Binary> child;
if (std::error_code ec = i->getAsBinary(child)) {
errs() << ToolName << ": " << file << ": " << ec.message() << ".\n";
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
continue;
}
if (ObjectFile *o = dyn_cast<ObjectFile>(child.get())) {
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) {
if (OutputFormat == sysv)
outs() << o->getFileName() << " (ex " << a->getFileName()
<< "):\n";