diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-06-08 22:00:24 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-06-08 22:00:24 +0000 |
commit | b9fc96d9dd2373756673d0d5046100d0499f123d (patch) | |
tree | 4ab3455ce2eab11dde3f400109fa26d49da3d9f5 | |
parent | e99f33afd94dae9983b65033f2c3bd7b9a4b44a9 (diff) |
Bitcode: Introduce a BitcodeFileContents data type. NFCI.
This data type includes the contents of a bitcode file.
Right now a bitcode file can only contain modules, but
a later change will add a symbol table.
Differential Revision: https://reviews.llvm.org/D33969
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305019 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Bitcode/BitcodeReader.h | 13 | ||||
-rw-r--r-- | include/llvm/Object/IRObjectFile.h | 1 | ||||
-rw-r--r-- | include/llvm/Object/IRSymtab.h | 4 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 22 | ||||
-rw-r--r-- | lib/Object/IRObjectFile.cpp | 11 | ||||
-rw-r--r-- | lib/Object/IRSymtab.cpp | 17 |
6 files changed, 47 insertions, 21 deletions
diff --git a/include/llvm/Bitcode/BitcodeReader.h b/include/llvm/Bitcode/BitcodeReader.h index 31ffb7645f3..61e4f6351b1 100644 --- a/include/llvm/Bitcode/BitcodeReader.h +++ b/include/llvm/Bitcode/BitcodeReader.h @@ -40,6 +40,8 @@ namespace llvm { return std::move(*Val); } + struct BitcodeFileContents; + /// Represents a module in a bitcode file. class BitcodeModule { // This covers the identification (if present) and module blocks. @@ -61,8 +63,8 @@ namespace llvm { IdentificationBit(IdentificationBit), ModuleBit(ModuleBit) {} // Calls the ctor. - friend Expected<std::vector<BitcodeModule>> - getBitcodeModuleList(MemoryBufferRef Buffer); + friend Expected<BitcodeFileContents> + getBitcodeFileContents(MemoryBufferRef Buffer); Expected<std::unique_ptr<Module>> getModuleImpl(LLVMContext &Context, bool MaterializeAll, @@ -99,6 +101,13 @@ namespace llvm { Error readSummary(ModuleSummaryIndex &CombinedIndex, unsigned ModuleId); }; + struct BitcodeFileContents { + std::vector<BitcodeModule> Mods; + }; + + /// Returns the contents of a bitcode file. + Expected<BitcodeFileContents> getBitcodeFileContents(MemoryBufferRef Buffer); + /// Returns a list of modules in the specified bitcode buffer. Expected<std::vector<BitcodeModule>> getBitcodeModuleList(MemoryBufferRef Buffer); diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index b4b6677037d..3bce7813ee9 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -20,6 +20,7 @@ #include "llvm/Object/SymbolicFile.h" namespace llvm { +class BitcodeModule; class Mangler; class Module; class GlobalValue; diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h index a5398977cb6..5b832141a86 100644 --- a/include/llvm/Object/IRSymtab.h +++ b/include/llvm/Object/IRSymtab.h @@ -37,7 +37,7 @@ namespace llvm { -class BitcodeModule; +struct BitcodeFileContents; namespace irsymtab { @@ -325,7 +325,7 @@ struct FileContents { }; /// Reads the contents of a bitcode file, creating its irsymtab if necessary. -Expected<FileContents> readBitcode(ArrayRef<BitcodeModule> Mods); +Expected<FileContents> readBitcode(const BitcodeFileContents &BFC); } // end namespace irsymtab } // end namespace llvm diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index c2dc67b8785..95987fac74e 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -5370,12 +5370,20 @@ static Expected<StringRef> readStrtab(BitstreamCursor &Stream) { Expected<std::vector<BitcodeModule>> llvm::getBitcodeModuleList(MemoryBufferRef Buffer) { + auto FOrErr = getBitcodeFileContents(Buffer); + if (!FOrErr) + return FOrErr.takeError(); + return std::move(FOrErr->Mods); +} + +Expected<BitcodeFileContents> +llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { Expected<BitstreamCursor> StreamOrErr = initStream(Buffer); if (!StreamOrErr) return StreamOrErr.takeError(); BitstreamCursor &Stream = *StreamOrErr; - std::vector<BitcodeModule> Modules; + BitcodeFileContents F; while (true) { uint64_t BCBegin = Stream.getCurrentByteNo(); @@ -5383,7 +5391,7 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) { // of the bitcode stream (e.g. Apple's ar tool). If we are close enough to // the end that there cannot possibly be another module, stop looking. if (BCBegin + 8 >= Stream.getBitcodeBytes().size()) - return Modules; + return F; BitstreamEntry Entry = Stream.advance(); switch (Entry.Kind) { @@ -5409,10 +5417,10 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) { if (Stream.SkipBlock()) return error("Malformed block"); - Modules.push_back({Stream.getBitcodeBytes().slice( - BCBegin, Stream.getCurrentByteNo() - BCBegin), - Buffer.getBufferIdentifier(), IdentificationBit, - ModuleBit}); + F.Mods.push_back({Stream.getBitcodeBytes().slice( + BCBegin, Stream.getCurrentByteNo() - BCBegin), + Buffer.getBufferIdentifier(), IdentificationBit, + ModuleBit}); continue; } @@ -5424,7 +5432,7 @@ llvm::getBitcodeModuleList(MemoryBufferRef Buffer) { // not have its own string table. A bitcode file may have multiple // string tables if it was created by binary concatenation, for example // with "llvm-cat -b". - for (auto I = Modules.rbegin(), E = Modules.rend(); I != E; ++I) { + for (auto I = F.Mods.rbegin(), E = F.Mods.rend(); I != E; ++I) { if (!I->Strtab.empty()) break; I->Strtab = *Strtab; diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 9996661fbde..e7807b03833 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -147,16 +147,15 @@ Expected<IRSymtabFile> object::readIRSymtab(MemoryBufferRef MBRef) { if (!BCOrErr) return errorCodeToError(BCOrErr.getError()); - Expected<std::vector<BitcodeModule>> BMsOrErr = - getBitcodeModuleList(*BCOrErr); - if (!BMsOrErr) - return BMsOrErr.takeError(); + Expected<BitcodeFileContents> BFCOrErr = getBitcodeFileContents(*BCOrErr); + if (!BFCOrErr) + return BFCOrErr.takeError(); - Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BMsOrErr); + Expected<irsymtab::FileContents> FCOrErr = irsymtab::readBitcode(*BFCOrErr); if (!FCOrErr) return FCOrErr.takeError(); - F.Mods = std::move(*BMsOrErr); + F.Mods = std::move(BFCOrErr->Mods); F.Symtab = std::move(FCOrErr->Symtab); F.Strtab = std::move(FCOrErr->Strtab); F.TheReader = std::move(FCOrErr->TheReader); diff --git a/lib/Object/IRSymtab.cpp b/lib/Object/IRSymtab.cpp index fa343618caf..94f13490939 100644 --- a/lib/Object/IRSymtab.cpp +++ b/lib/Object/IRSymtab.cpp @@ -262,11 +262,10 @@ Error irsymtab::build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab, return Builder(Symtab, Strtab).build(Mods); } -Expected<FileContents> irsymtab::readBitcode(ArrayRef<BitcodeModule> BMs) { +// Upgrade a vector of bitcode modules created by an old version of LLVM by +// creating an irsymtab for them in the current format. +static Expected<FileContents> upgrade(ArrayRef<BitcodeModule> BMs) { FileContents FC; - if (BMs.empty()) - return make_error<StringError>("Bitcode file does not contain any modules", - inconvertibleErrorCode()); LLVMContext Ctx; std::vector<Module *> Mods; @@ -293,3 +292,13 @@ Expected<FileContents> irsymtab::readBitcode(ArrayRef<BitcodeModule> BMs) { {FC.Strtab.data(), FC.Strtab.size()}}; return std::move(FC); } + +Expected<FileContents> irsymtab::readBitcode(const BitcodeFileContents &BFC) { + if (BFC.Mods.empty()) + return make_error<StringError>("Bitcode file does not contain any modules", + inconvertibleErrorCode()); + + // Right now we have no on-disk representation of symbol tables, so we always + // upgrade. + return upgrade(BFC.Mods); +} |