-Archive::child_iterator Archive::begin_children() {
- const char *Loc = Data->getBufferStart() + Magic.size();
- size_t Size = sizeof(ArchiveMemberHeader) +
- ToHeader(Loc)->getSize();
- return Child(this, StringRef(Loc, Size));
+Archive::child_iterator Archive::begin_children(bool SkipInternal) const {
+ if (Data->getBufferSize() == 8) // empty archive.
+ return end_children();
+
+ if (SkipInternal)
+ return FirstRegular;
+
+ const char *Loc = Data->getBufferStart() + strlen(Magic);
+ Child c(this, Loc);
+ return c;
+}
+
+Archive::child_iterator Archive::end_children() const {
+ return Child(this, NULL);
+}
+
+error_code Archive::Symbol::getName(StringRef &Result) const {
+ Result = StringRef(Parent->SymbolTable->getBuffer().begin() + StringIndex);
+ return object_error::success;
+}
+
+error_code Archive::Symbol::getMember(child_iterator &Result) const {
+ const char *Buf = Parent->SymbolTable->getBuffer().begin();
+ const char *Offsets = Buf + 4;
+ uint32_t Offset = 0;
+ if (Parent->kind() == K_GNU) {
+ Offset = *(reinterpret_cast<const support::ubig32_t*>(Offsets)
+ + SymbolIndex);
+ } else if (Parent->kind() == K_BSD) {
+ llvm_unreachable("BSD format is not supported");
+ } else {
+ uint32_t MemberCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
+
+ // Skip offsets.
+ Buf += sizeof(support::ulittle32_t)
+ + (MemberCount * sizeof(support::ulittle32_t));
+
+ uint32_t SymbolCount = *reinterpret_cast<const support::ulittle32_t*>(Buf);
+
+ if (SymbolIndex >= SymbolCount)
+ return object_error::parse_failed;
+
+ // Skip SymbolCount to get to the indices table.
+ const char *Indices = Buf + sizeof(support::ulittle32_t);
+
+ // Get the index of the offset in the file member offset table for this
+ // symbol.
+ uint16_t OffsetIndex =
+ *(reinterpret_cast<const support::ulittle16_t*>(Indices)
+ + SymbolIndex);
+ // Subtract 1 since OffsetIndex is 1 based.
+ --OffsetIndex;
+
+ if (OffsetIndex >= MemberCount)
+ return object_error::parse_failed;
+
+ Offset = *(reinterpret_cast<const support::ulittle32_t*>(Offsets)
+ + OffsetIndex);
+ }
+
+ const char *Loc = Parent->getData().begin() + Offset;
+ Result = Child(Parent, Loc);
+
+ return object_error::success;
+}
+
+Archive::Symbol Archive::Symbol::getNext() const {
+ Symbol t(*this);
+ // Go to one past next null.
+ t.StringIndex =
+ Parent->SymbolTable->getBuffer().find('\0', t.StringIndex) + 1;
+ ++t.SymbolIndex;
+ return t;