diff options
Diffstat (limited to 'include/llvm/Object/Archive.h')
-rw-r--r-- | include/llvm/Object/Archive.h | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 597f0d48c118..8dd042a2533f 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -37,7 +37,7 @@ struct ArchiveMemberHeader { llvm::StringRef getName() const; /// Members are not larger than 4GB. - uint32_t getSize() const; + ErrorOr<uint32_t> getSize() const; sys::fs::perms getAccessMode() const; sys::TimeValue getLastModified() const; @@ -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; @@ -62,19 +63,19 @@ public: return reinterpret_cast<const ArchiveMemberHeader *>(Data.data()); } + bool isThinMember() const; + public: - Child(const Archive *Parent, const char *Start); + Child(const Archive *Parent, const char *Start, std::error_code *EC); + Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile); bool operator ==(const Child &other) const { assert(Parent == other.Parent); return Data.begin() == other.Data.begin(); } - bool operator <(const Child &other) const { - return Data.begin() < other.Data.begin(); - } - - Child getNext() const; + const Archive *getParent() const { return Parent; } + ErrorOr<Child> getNext() const; ErrorOr<StringRef> getName() const; StringRef getRawName() const { return getHeader()->getName(); } @@ -90,9 +91,9 @@ public: return getHeader()->getAccessMode(); } /// \return the size of the archive member without the header or padding. - uint64_t getSize() const; + ErrorOr<uint64_t> getSize() const; /// \return the size in the archive header for this member. - uint64_t getRawSize() const; + ErrorOr<uint64_t> getRawSize() const; ErrorOr<StringRef> getBuffer() const; uint64_t getChildOffset() const; @@ -104,28 +105,32 @@ public: }; class child_iterator { - Child child; + ErrorOr<Child> child; public: - child_iterator() : child(Child(nullptr, nullptr)) {} + child_iterator() : child(Child(nullptr, nullptr, nullptr)) {} child_iterator(const Child &c) : child(c) {} - const Child *operator->() const { return &child; } - const Child &operator*() const { return child; } + child_iterator(std::error_code EC) : child(EC) {} + const ErrorOr<Child> *operator->() const { return &child; } + const ErrorOr<Child> &operator*() const { return child; } bool operator==(const child_iterator &other) const { - return child == other.child; + // We ignore error states so that comparisions with end() work, which + // allows range loops. + if (child.getError() || other.child.getError()) + return false; + return *child == *other.child; } bool operator!=(const child_iterator &other) const { return !(*this == other); } - bool operator<(const child_iterator &other) const { - return child < other.child; - } - + // Code in loops with child_iterators must check for errors on each loop + // iteration. And if there is an error break out of the loop. child_iterator &operator++() { // Preincrement - child = child.getNext(); + assert(child && "Can't increment iterator with error"); + child = child->getNext(); return *this; } }; @@ -145,7 +150,7 @@ public: , SymbolIndex(symi) , StringIndex(stri) {} StringRef getName() const; - ErrorOr<child_iterator> getMember() const; + ErrorOr<Child> getMember() const; Symbol getNext() const; }; @@ -186,14 +191,13 @@ public: child_iterator child_begin(bool SkipInternal = true) const; child_iterator child_end() const; iterator_range<child_iterator> children(bool SkipInternal = true) const { - return iterator_range<child_iterator>(child_begin(SkipInternal), - child_end()); + return make_range(child_begin(SkipInternal), child_end()); } symbol_iterator symbol_begin() const; symbol_iterator symbol_end() const; iterator_range<symbol_iterator> symbols() const { - return iterator_range<symbol_iterator>(symbol_begin(), symbol_end()); + return make_range(symbol_begin(), symbol_end()); } // Cast methods. @@ -205,18 +209,17 @@ public: child_iterator findSym(StringRef name) const; bool hasSymbolTable() const; - child_iterator getSymbolTableChild() const { return SymbolTable; } - StringRef getSymbolTable() const { - // We know that the symbol table is not an external file, - // so we just assert there is no error. - return *SymbolTable->getBuffer(); - } + StringRef getSymbolTable() const { return SymbolTable; } uint32_t getNumberOfSymbols() const; private: - child_iterator SymbolTable; - child_iterator StringTable; - child_iterator FirstRegular; + StringRef SymbolTable; + StringRef StringTable; + + StringRef FirstRegularData; + uint16_t FirstRegularStartOfFile = -1; + void setFirstRegular(const Child &C); + unsigned Format : 2; unsigned IsThin : 1; mutable std::vector<std::unique_ptr<MemoryBuffer>> ThinBuffers; |