summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-ar
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-06-29 22:27:42 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-06-29 22:27:42 +0000
commit8ec68fad33e4f5b9899f200b32a264df1a55be48 (patch)
tree7b8b55b7038cfad6543cc61a55f3c791f86fb44d /llvm/tools/llvm-ar
parente1af3c635c545ed12e7253c0b866a84420a690ab (diff)
downloadbcm5719-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.cpp121
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;
}
OpenPOWER on IntegriCloud