diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2016-06-29 22:27:42 +0000 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-06-29 22:27:42 +0000 |
| commit | 8ec68fad33e4f5b9899f200b32a264df1a55be48 (patch) | |
| tree | 7b8b55b7038cfad6543cc61a55f3c791f86fb44d /llvm/tools/llvm-ar | |
| parent | e1af3c635c545ed12e7253c0b866a84420a690ab (diff) | |
| download | bcm5719-llvm-8ec68fad33e4f5b9899f200b32a264df1a55be48.tar.gz bcm5719-llvm-8ec68fad33e4f5b9899f200b32a264df1a55be48.zip | |
Object: Replace NewArchiveIterator with a simpler NewArchiveMember class. NFCI.
The NewArchiveIterator class has a problem: it requires too much context. Any
memory buffers added to the archive must be stored within an Archive::Member,
which must have an associated Archive. This makes it harder than necessary
to create new archive members (or new archives entirely) from scratch using
memory buffers.
This patch replaces NewArchiveIterator with a NewArchiveMember class that
stores just the memory buffer and the information that goes into the archive
member header.
Differential Revision: http://reviews.llvm.org/D21721
llvm-svn: 274183
Diffstat (limited to 'llvm/tools/llvm-ar')
| -rw-r--r-- | llvm/tools/llvm-ar/llvm-ar.cpp | 121 |
1 files changed, 54 insertions, 67 deletions
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp index f918a3e5136..d52355216b0 100644 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -65,6 +65,18 @@ static void failIfError(std::error_code EC, Twine Context = "") { fail(Context + ": " + EC.message()); } +static void failIfError(Error E, Twine Context = "") { + if (!E) + return; + + handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) { + std::string ContextStr = Context.str(); + if (ContextStr == "") + fail(EIB.message()); + fail(Context + ": " + EIB.message()); + }); +} + // llvm-ar/llvm-ranlib remaining positional arguments. static cl::list<std::string> RestOfArgs(cl::Positional, cl::ZeroOrMore, @@ -429,25 +441,28 @@ static void performReadOperation(ArchiveOperation Operation, std::exit(1); } -static void addMember(std::vector<NewArchiveIterator> &Members, +static void addMember(std::vector<NewArchiveMember> &Members, StringRef FileName, int Pos = -1) { - NewArchiveIterator NI(FileName); + Expected<NewArchiveMember> NMOrErr = + NewArchiveMember::getFile(FileName, Deterministic); + failIfError(NMOrErr.takeError(), FileName); if (Pos == -1) - Members.push_back(NI); + Members.push_back(std::move(*NMOrErr)); else - Members[Pos] = NI; + Members[Pos] = std::move(*NMOrErr); } -static void addMember(std::vector<NewArchiveIterator> &Members, - const object::Archive::Child &M, StringRef Name, - int Pos = -1) { +static void addMember(std::vector<NewArchiveMember> &Members, + const object::Archive::Child &M, int Pos = -1) { if (Thin && !M.getParent()->isThin()) fail("Cannot convert a regular archive to a thin one"); - NewArchiveIterator NI(M, Name); + Expected<NewArchiveMember> NMOrErr = + NewArchiveMember::getOldMember(M, Deterministic); + failIfError(NMOrErr.takeError()); if (Pos == -1) - Members.push_back(NI); + Members.push_back(std::move(*NMOrErr)); else - Members[Pos] = NI; + Members[Pos] = std::move(*NMOrErr); } enum InsertAction { @@ -508,11 +523,11 @@ static InsertAction computeInsertAction(ArchiveOperation Operation, // We have to walk this twice and computing it is not trivial, so creating an // explicit std::vector is actually fairly efficient. -static std::vector<NewArchiveIterator> +static std::vector<NewArchiveMember> computeNewArchiveMembers(ArchiveOperation Operation, object::Archive *OldArchive) { - std::vector<NewArchiveIterator> Ret; - std::vector<NewArchiveIterator> Moved; + std::vector<NewArchiveMember> Ret; + std::vector<NewArchiveMember> Moved; int InsertPos = -1; StringRef PosName = sys::path::filename(RelPos); if (OldArchive) { @@ -536,7 +551,7 @@ computeNewArchiveMembers(ArchiveOperation Operation, computeInsertAction(Operation, Child, Name, MemberI); switch (Action) { case IA_AddOldMember: - addMember(Ret, Child, Name); + addMember(Ret, Child); break; case IA_AddNewMeber: addMember(Ret, *MemberI); @@ -544,7 +559,7 @@ computeNewArchiveMembers(ArchiveOperation Operation, case IA_Delete: break; case IA_MoveOldMember: - addMember(Moved, Child, Name); + addMember(Moved, Child); break; case IA_MoveNewMember: addMember(Moved, *MemberI); @@ -565,10 +580,15 @@ computeNewArchiveMembers(ArchiveOperation Operation, InsertPos = Ret.size(); assert(unsigned(InsertPos) <= Ret.size()); - Ret.insert(Ret.begin() + InsertPos, Moved.begin(), Moved.end()); - - Ret.insert(Ret.begin() + InsertPos, Members.size(), NewArchiveIterator("")); int Pos = InsertPos; + for (auto &M : Moved) { + Ret.insert(Ret.begin() + Pos, std::move(M)); + ++Pos; + } + + for (unsigned I = 0; I != Members.size(); ++I) + Ret.insert(Ret.begin() + InsertPos, NewArchiveMember()); + Pos = InsertPos; for (auto &Member : Members) { addMember(Ret, Member, Pos); ++Pos; @@ -582,56 +602,26 @@ static object::Archive::Kind getDefaultForHost() { : object::Archive::K_GNU; } -static object::Archive::Kind -getKindFromMember(const NewArchiveIterator &Member) { - auto getKindFromMemberInner = - [](MemoryBufferRef Buffer) -> object::Archive::Kind { - Expected<std::unique_ptr<object::ObjectFile>> OptionalObject = - object::ObjectFile::createObjectFile(Buffer); - - if (OptionalObject) - return isa<object::MachOObjectFile>(**OptionalObject) - ? object::Archive::K_BSD - : object::Archive::K_GNU; +static object::Archive::Kind getKindFromMember(const NewArchiveMember &Member) { + Expected<std::unique_ptr<object::ObjectFile>> OptionalObject = + object::ObjectFile::createObjectFile(Member.Buf->getMemBufferRef()); - // squelch the error in case we had a non-object file - consumeError(OptionalObject.takeError()); - return getDefaultForHost(); - }; + if (OptionalObject) + return isa<object::MachOObjectFile>(**OptionalObject) + ? object::Archive::K_BSD + : object::Archive::K_GNU; - if (Member.isNewMember()) { - object::Archive::Kind Kind = getDefaultForHost(); - - sys::fs::file_status Status; - if (auto OptionalFD = Member.getFD(Status)) { - if (auto MB = MemoryBuffer::getOpenFile(*OptionalFD, Member.getName(), - Status.getSize(), false)) - Kind = getKindFromMemberInner((*MB)->getMemBufferRef()); - - if (close(*OptionalFD) != 0) - failIfError(std::error_code(errno, std::generic_category()), - "failed to close file"); - } - - return Kind; - } else { - const object::Archive::Child &OldMember = Member.getOld(); - if (OldMember.getParent()->isThin()) - return object::Archive::Kind::K_GNU; - - auto OptionalMB = OldMember.getMemoryBufferRef(); - failIfError(OptionalMB.getError()); - - return getKindFromMemberInner(*OptionalMB); - } + // squelch the error in case we had a non-object file + consumeError(OptionalObject.takeError()); + return getDefaultForHost(); } static void performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive, std::unique_ptr<MemoryBuffer> OldArchiveBuf, - std::vector<NewArchiveIterator> *NewMembersP) { - std::vector<NewArchiveIterator> NewMembers; + std::vector<NewArchiveMember> *NewMembersP) { + std::vector<NewArchiveMember> NewMembers; if (!NewMembersP) NewMembers = computeNewArchiveMembers(Operation, OldArchive); @@ -681,7 +671,7 @@ static void createSymbolTable(object::Archive *OldArchive) { static void performOperation(ArchiveOperation Operation, object::Archive *OldArchive, std::unique_ptr<MemoryBuffer> OldArchiveBuf, - std::vector<NewArchiveIterator> *NewMembers) { + std::vector<NewArchiveMember> *NewMembers) { switch (Operation) { case Print: case DisplayTable: @@ -704,7 +694,7 @@ static void performOperation(ArchiveOperation Operation, } static int performOperation(ArchiveOperation Operation, - std::vector<NewArchiveIterator> *NewMembers) { + std::vector<NewArchiveMember> *NewMembers) { // Create or open the archive object. ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = MemoryBuffer::getFile(ArchiveName, -1, false); @@ -744,7 +734,7 @@ static void runMRIScript() { failIfError(Buf.getError()); const MemoryBuffer &Ref = *Buf.get(); bool Saved = false; - std::vector<NewArchiveIterator> NewMembers; + std::vector<NewArchiveMember> NewMembers; std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers; std::vector<std::unique_ptr<object::Archive>> Archives; @@ -776,10 +766,7 @@ static void runMRIScript() { object::Archive &Lib = *Archives.back(); for (auto &MemberOrErr : Lib.children()) { failIfError(MemberOrErr.getError()); - auto &Member = MemberOrErr.get(); - ErrorOr<StringRef> NameOrErr = Member.getName(); - failIfError(NameOrErr.getError()); - addMember(NewMembers, Member, *NameOrErr); + addMember(NewMembers, *MemberOrErr); } break; } |

