From d3ca239fe8ccc6b1188d61130b887ebdc94f8059 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 31 Oct 2015 21:44:42 +0000 Subject: [PATCH] Don't store a Child to the first regular member. This is a bit ugly, but has a few advantages: * Archive is now easy to copy since there is no Archive -> Child -> Archive loop. * It makes it clear that we already checked for errors when finding the Child data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251750 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/Archive.h | 8 +++++++- lib/Object/Archive.cpp | 25 +++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 987ade81a51..a2797ad2d8e 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -52,6 +52,7 @@ class Archive : public Binary { virtual void anchor(); public: class Child { + friend Archive; const Archive *Parent; /// \brief Includes header but not padding byte. StringRef Data; @@ -66,6 +67,7 @@ public: public: Child(const Archive *Parent, const char *Start); + Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile); bool operator ==(const Child &other) const { assert(Parent == other.Parent); @@ -206,7 +208,11 @@ public: private: StringRef SymbolTable; StringRef StringTable; - child_iterator FirstRegular; + + StringRef FirstRegularData; + uint16_t FirstRegularStartOfFile = -1; + void setFirstRegular(const Child &C); + unsigned Format : 2; unsigned IsThin : 1; mutable std::vector> ThinBuffers; diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp index 4bb50a0f757..d50a69951e1 100644 --- a/lib/Object/Archive.cpp +++ b/lib/Object/Archive.cpp @@ -82,6 +82,10 @@ unsigned ArchiveMemberHeader::getGID() const { return Ret; } +Archive::Child::Child(const Archive *Parent, StringRef Data, + uint16_t StartOfFile) + : Parent(Parent), Data(Data), StartOfFile(StartOfFile) {} + Archive::Child::Child(const Archive *Parent, const char *Start) : Parent(Parent) { if (!Start) @@ -232,8 +236,13 @@ ErrorOr> Archive::create(MemoryBufferRef Source) { return std::move(Ret); } +void Archive::setFirstRegular(const Child &C) { + FirstRegularData = C.Data; + FirstRegularStartOfFile = C.StartOfFile; +} + Archive::Archive(MemoryBufferRef Source, std::error_code &ec) - : Binary(Binary::ID_Archive, Source), FirstRegular(child_end()) { + : Binary(Binary::ID_Archive, Source) { StringRef Buffer = Data.getBuffer(); // Check for sufficient magic. if (Buffer.startswith(ThinMagic)) { @@ -281,7 +290,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) // there is no error. SymbolTable = *i->getBuffer(); ++i; - FirstRegular = i; + setFirstRegular(*i); ec = std::error_code(); return; } @@ -300,7 +309,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) SymbolTable = *i->getBuffer(); ++i; } - FirstRegular = i; + setFirstRegular(*i); return; } @@ -331,14 +340,14 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) // ErrorOr. StringTable = *i->getBuffer(); ++i; - FirstRegular = i; + setFirstRegular(*i); ec = std::error_code(); return; } if (Name[0] != '/') { Format = has64SymTable ? K_MIPS64 : K_GNU; - FirstRegular = i; + setFirstRegular(*i); ec = std::error_code(); return; } @@ -355,7 +364,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) ++i; if (i == e) { - FirstRegular = i; + setFirstRegular(*i); ec = std::error_code(); return; } @@ -369,7 +378,7 @@ Archive::Archive(MemoryBufferRef Source, std::error_code &ec) ++i; } - FirstRegular = i; + setFirstRegular(*i); ec = std::error_code(); } @@ -378,7 +387,7 @@ Archive::child_iterator Archive::child_begin(bool SkipInternal) const { return child_end(); if (SkipInternal) - return FirstRegular; + return Child(this, FirstRegularData, FirstRegularStartOfFile); const char *Loc = Data.getBufferStart() + strlen(Magic); Child c(this, Loc); -- 2.34.1