//
//===----------------------------------------------------------------------===//
-#ifndef BITCODE_READER_H
-#define BITCODE_READER_H
+#ifndef LLVM_LIB_BITCODE_READER_BITCODEREADER_H
+#define LLVM_LIB_BITCODE_READER_BITCODEREADER_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
-#include "llvm/GVMaterializer.h"
#include "llvm/IR/Attributes.h"
+#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Type.h"
-#include "llvm/Support/ValueHandle.h"
+#include "llvm/IR/ValueHandle.h"
+#include <deque>
+#include <system_error>
#include <vector>
namespace llvm {
+ class Comdat;
class MemoryBuffer;
class LLVMContext;
class BitcodeReader : public GVMaterializer {
LLVMContext &Context;
Module *TheModule;
- MemoryBuffer *Buffer;
- bool BufferOwned;
- OwningPtr<BitstreamReader> StreamFile;
+ std::unique_ptr<MemoryBuffer> Buffer;
+ std::unique_ptr<BitstreamReader> StreamFile;
BitstreamCursor Stream;
DataStreamer *LazyStreamer;
uint64_t NextUnreadBit;
bool SeenValueSymbolTable;
- const char *ErrorString;
-
std::vector<Type*> TypeList;
BitcodeReaderValueList ValueList;
BitcodeReaderMDValueList MDValueList;
+ std::vector<Comdat *> ComdatList;
SmallVector<Instruction *, 64> InstructionList;
- SmallVector<SmallVector<uint64_t, 64>, 64> UseListRecords;
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
+ SmallVector<Instruction*, 64> InstsWithTBAATag;
+
/// MAttributes - The set of attributes by index. Index zero in the
/// file is for null, and is thus not represented here. As such all indices
/// are off by one.
/// stream.
DenseMap<Function*, uint64_t> DeferredFunctionInfo;
- /// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These
- /// are resolved lazily when functions are loaded.
- typedef std::pair<unsigned, GlobalVariable*> BlockAddrRefTy;
- DenseMap<Function*, std::vector<BlockAddrRefTy> > BlockAddrFwdRefs;
+ /// These are basic blocks forward-referenced by block addresses. They are
+ /// inserted lazily into functions when they're loaded. The basic block ID is
+ /// its index into the vector.
+ DenseMap<Function *, std::vector<BasicBlock *>> BasicBlockFwdRefs;
+ std::deque<Function *> BasicBlockFwdRefQueue;
/// UseRelativeIDs - Indicates that we are using a new encoding for
/// instruction operands where most operands in the current
/// not need this flag.
bool UseRelativeIDs;
+ /// True if all functions will be materialized, negating the need to process
+ /// (e.g.) blockaddress forward references.
+ bool WillMaterializeAllForwardRefs;
+
+ /// Functions that have block addresses taken. This is usually empty.
+ SmallPtrSet<const Function *, 4> BlockAddressesTaken;
+
public:
+ std::error_code Error(BitcodeError E) { return make_error_code(E); }
+
explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C)
- : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false),
- LazyStreamer(0), NextUnreadBit(0), SeenValueSymbolTable(false),
- ErrorString(0), ValueList(C), MDValueList(C),
- SeenFirstFunctionBody(false), UseRelativeIDs(false) {
- }
+ : Context(C), TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
+ NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
+ MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
+ WillMaterializeAllForwardRefs(false) {}
explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C)
- : Context(C), TheModule(0), Buffer(0), BufferOwned(false),
- LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false),
- ErrorString(0), ValueList(C), MDValueList(C),
- SeenFirstFunctionBody(false), UseRelativeIDs(false) {
- }
- ~BitcodeReader() {
- FreeState();
- }
+ : Context(C), TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer),
+ NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
+ MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
+ WillMaterializeAllForwardRefs(false) {}
+ ~BitcodeReader() { FreeState(); }
- void materializeForwardReferencedFunctions();
+ std::error_code materializeForwardReferencedFunctions();
void FreeState();
- /// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer
- /// when the reader is destroyed.
- void setBufferOwned(bool Owned) { BufferOwned = Owned; }
+ void releaseBuffer() override;
- virtual bool isMaterializable(const GlobalValue *GV) const;
- virtual bool isDematerializable(const GlobalValue *GV) const;
- virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0);
- virtual bool MaterializeModule(Module *M, std::string *ErrInfo = 0);
- virtual void Dematerialize(GlobalValue *GV);
-
- bool Error(const char *Str) {
- ErrorString = Str;
- return true;
- }
- const char *getErrorString() const { return ErrorString; }
+ bool isMaterializable(const GlobalValue *GV) const override;
+ bool isDematerializable(const GlobalValue *GV) const override;
+ std::error_code Materialize(GlobalValue *GV) override;
+ std::error_code MaterializeModule(Module *M) override;
+ void Dematerialize(GlobalValue *GV) override;
/// @brief Main interface to parsing a bitcode buffer.
/// @returns true if an error occurred.
- bool ParseBitcodeInto(Module *M);
+ std::error_code ParseBitcodeInto(Module *M);
/// @brief Cheap mechanism to just extract module triple
/// @returns true if an error occurred.
- bool ParseTriple(std::string &Triple);
+ ErrorOr<std::string> parseTriple();
static uint64_t decodeSignRotatedValue(uint64_t V);
return ValueList.getValueFwdRef(ID, Ty);
}
BasicBlock *getBasicBlock(unsigned ID) const {
- if (ID >= FunctionBBs.size()) return 0; // Invalid ID
+ if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID
return FunctionBBs[ID];
}
AttributeSet getAttributes(unsigned i) const {
if (ValNo < InstNum) {
// If this is not a forward reference, just return the value we already
// have.
- ResVal = getFnValueByID(ValNo, 0);
- return ResVal == 0;
+ ResVal = getFnValueByID(ValNo, nullptr);
+ return ResVal == nullptr;
} else if (Slot == Record.size()) {
return true;
}
unsigned TypeNo = (unsigned)Record[Slot++];
ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
- return ResVal == 0;
+ return ResVal == nullptr;
}
/// popValue - Read a value out of the specified record from slot 'Slot'.
bool getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
unsigned InstNum, Type *Ty, Value *&ResVal) {
ResVal = getValue(Record, Slot, InstNum, Ty);
- return ResVal == 0;
+ return ResVal == nullptr;
}
/// getValue -- Version of getValue that returns ResVal directly,
/// or 0 if there is an error.
Value *getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
unsigned InstNum, Type *Ty) {
- if (Slot == Record.size()) return 0;
+ if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)Record[Slot];
// Adjust the ValNo, if it was encoded relative to the InstNum.
if (UseRelativeIDs)
/// getValueSigned -- Like getValue, but decodes signed VBRs.
Value *getValueSigned(SmallVectorImpl<uint64_t> &Record, unsigned Slot,
unsigned InstNum, Type *Ty) {
- if (Slot == Record.size()) return 0;
+ if (Slot == Record.size()) return nullptr;
unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
// Adjust the ValNo, if it was encoded relative to the InstNum.
if (UseRelativeIDs)
return getFnValueByID(ValNo, Ty);
}
- bool ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
- bool ParseModule(bool Resume);
- bool ParseAttributeBlock();
- bool ParseAttributeGroupBlock();
- bool ParseTypeTable();
- bool ParseTypeTableBody();
-
- bool ParseValueSymbolTable();
- bool ParseConstants();
- bool RememberAndSkipFunctionBody();
- bool ParseFunctionBody(Function *F);
- bool GlobalCleanup();
- bool ResolveGlobalAndAliasInits();
- bool ParseMetadata();
- bool ParseMetadataAttachment();
- bool ParseModuleTriple(std::string &Triple);
- bool ParseUseLists();
- bool InitStream();
- bool InitStreamFromBuffer();
- bool InitLazyStream();
- bool FindFunctionInStream(Function *F,
- DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator);
+ std::error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind);
+ std::error_code ParseModule(bool Resume);
+ std::error_code ParseAttributeBlock();
+ std::error_code ParseAttributeGroupBlock();
+ std::error_code ParseTypeTable();
+ std::error_code ParseTypeTableBody();
+
+ std::error_code ParseValueSymbolTable();
+ std::error_code ParseConstants();
+ std::error_code RememberAndSkipFunctionBody();
+ std::error_code ParseFunctionBody(Function *F);
+ std::error_code GlobalCleanup();
+ std::error_code ResolveGlobalAndAliasInits();
+ std::error_code ParseMetadata();
+ std::error_code ParseMetadataAttachment();
+ ErrorOr<std::string> parseModuleTriple();
+ std::error_code ParseUseLists();
+ std::error_code InitStream();
+ std::error_code InitStreamFromBuffer();
+ std::error_code InitLazyStream();
+ std::error_code FindFunctionInStream(
+ Function *F,
+ DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator);
};
} // End llvm namespace