#include "llvm/Bitcode/ReaderWriter.h"
#include "BitcodeReader.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/AutoUpgrade.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
+#include "llvm/OperandTraits.h"
#include "llvm/Operator.h"
-#include "llvm/AutoUpgrade.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataStream.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/OperandTraits.h"
using namespace llvm;
+enum {
+ SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
+};
+
void BitcodeReader::materializeForwardReferencedFunctions() {
while (!BlockAddrFwdRefs.empty()) {
Function *F = BlockAddrFwdRefs.begin()->first;
ValueList.clear();
MDValueList.clear();
- std::vector<AttrListPtr>().swap(MAttributes);
+ std::vector<AttributeSet>().swap(MAttributes);
std::vector<BasicBlock*>().swap(FunctionBBs);
std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear();
MDKindMap.clear();
+
+ assert(BlockAddrFwdRefs.empty() && "Unresolved blockaddress fwd references");
}
//===----------------------------------------------------------------------===//
/// ConvertToString - Convert a string from a record into an std::string, return
/// true on failure.
template<typename StrTy>
-static bool ConvertToString(SmallVector<uint64_t, 64> &Record, unsigned Idx,
+static bool ConvertToString(ArrayRef<uint64_t> Record, unsigned Idx,
StrTy &Result) {
if (Idx > Record.size())
return true;
case 12: return GlobalValue::AvailableExternallyLinkage;
case 13: return GlobalValue::LinkerPrivateLinkage;
case 14: return GlobalValue::LinkerPrivateWeakLinkage;
- case 15: return GlobalValue::LinkerPrivateWeakDefAutoLinkage;
+ case 15: return GlobalValue::LinkOnceODRAutoHideLinkage;
}
}
}
}
+static GlobalVariable::ThreadLocalMode GetDecodedThreadLocalMode(unsigned Val) {
+ switch (Val) {
+ case 0: return GlobalVariable::NotThreadLocal;
+ default: // Map unknown non-zero value to general dynamic.
+ case 1: return GlobalVariable::GeneralDynamicTLSModel;
+ case 2: return GlobalVariable::LocalDynamicTLSModel;
+ case 3: return GlobalVariable::InitialExecTLSModel;
+ case 4: return GlobalVariable::LocalExecTLSModel;
+ }
+}
+
static int GetDecodedCastOpcode(unsigned Val) {
switch (Val) {
default: return -1;
/// @brief A class for maintaining the slot number definition
/// as a placeholder for the actual definition for forward constants defs.
class ConstantPlaceHolder : public ConstantExpr {
- void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
+ void operator=(const ConstantPlaceHolder &) LLVM_DELETED_FUNCTION;
public:
// allocate space for exactly one operand
void *operator new(size_t s) {
}
/// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
- //static inline bool classof(const ConstantPlaceHolder *) { return true; }
static bool classof(const Value *V) {
return isa<ConstantExpr>(V) &&
cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1;
// The type table size is always specified correctly.
if (ID >= TypeList.size())
return 0;
-
+
if (Type *Ty = TypeList[ID])
return Ty;
if (Record.size() & 1)
return Error("Invalid ENTRY record");
- // FIXME : Remove this autoupgrade code in LLVM 3.0.
- // If Function attributes are using index 0 then transfer them
- // to index ~0. Index 0 is used for return value attributes but used to be
- // used for function attributes.
- Attributes RetAttribute;
- Attributes FnAttribute;
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
- // FIXME: remove in LLVM 3.0
- // The alignment is stored as a 16-bit raw value from bits 31--16.
- // We shift the bits above 31 down by 11 bits.
-
- unsigned Alignment = (Record[i+1] & (0xffffull << 16)) >> 16;
- if (Alignment && !isPowerOf2_32(Alignment))
- return Error("Alignment is not a power of two.");
-
- Attributes ReconstitutedAttr(Record[i+1] & 0xffff);
- if (Alignment)
- ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment);
- ReconstitutedAttr |=
- Attributes((Record[i+1] & (0xffffull << 32)) >> 11);
-
+ Attribute ReconstitutedAttr =
+ Attribute::decodeLLVMAttributesForBitcode(Context, Record[i+1]);
Record[i+1] = ReconstitutedAttr.Raw();
- if (Record[i] == 0)
- RetAttribute = ReconstitutedAttr;
- else if (Record[i] == ~0U)
- FnAttribute = ReconstitutedAttr;
- }
-
- Attributes OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|
- Attribute::ReadOnly|Attribute::ReadNone);
-
- if (FnAttribute == Attribute::None && RetAttribute != Attribute::None &&
- (RetAttribute & OldRetAttrs)) {
- if (FnAttribute == Attribute::None) { // add a slot so they get added.
- Record.push_back(~0U);
- Record.push_back(0);
- }
-
- FnAttribute |= RetAttribute & OldRetAttrs;
- RetAttribute &= ~OldRetAttrs;
}
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
- if (Record[i] == 0) {
- if (RetAttribute != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(0, RetAttribute));
- } else if (Record[i] == ~0U) {
- if (FnAttribute != Attribute::None)
- Attrs.push_back(AttributeWithIndex::get(~0U, FnAttribute));
- } else if (Attributes(Record[i+1]) != Attribute::None)
+ AttrBuilder B(Record[i+1]);
+ if (B.hasAttributes())
Attrs.push_back(AttributeWithIndex::get(Record[i],
- Attributes(Record[i+1])));
+ Attribute::get(Context, B)));
}
- MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end()));
+ MAttributes.push_back(AttributeSet::get(Context, Attrs));
Attrs.clear();
break;
}
bool BitcodeReader::ParseTypeTable() {
if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
return Error("Malformed block record");
-
+
return ParseTypeTableBody();
}
unsigned NumRecords = 0;
SmallString<64> TypeName;
-
+
// Read all the records for this type table.
while (1) {
unsigned Code = Stream.ReadCode();
break;
}
case bitc::TYPE_CODE_FUNCTION_OLD: {
- // FIXME: attrid is dead, remove it in LLVM 3.0
+ // FIXME: attrid is dead, remove it in LLVM 4.0
// FUNCTION: [vararg, attrid, retty, paramty x N]
if (Record.size() < 3)
return Error("Invalid FUNCTION type record");
else
break;
}
-
+
ResultTy = getTypeByID(Record[2]);
if (ResultTy == 0 || ArgTys.size() < Record.size()-3)
return Error("invalid type in function type");
else
break;
}
-
+
ResultTy = getTypeByID(Record[1]);
if (ResultTy == 0 || ArgTys.size() < Record.size()-2)
return Error("invalid type in function type");
case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N]
if (Record.size() < 1)
return Error("Invalid STRUCT type record");
-
+
if (NumRecords >= TypeList.size())
return Error("invalid TYPE table");
-
+
// Check to see if this was forward referenced, if so fill in the temp.
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
if (Res) {
} else // Otherwise, create a new struct.
Res = StructType::create(Context, TypeName);
TypeName.clear();
-
+
SmallVector<Type*, 8> EltTys;
for (unsigned i = 1, e = Record.size(); i != e; ++i) {
if (Type *T = getTypeByID(Record[i]))
if (NumRecords >= TypeList.size())
return Error("invalid TYPE table");
-
+
// Check to see if this was forward referenced, if so fill in the temp.
StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]);
if (Res) {
TypeName.clear();
ResultTy = Res;
break;
- }
+ }
case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty]
if (Record.size() < 2)
return Error("Invalid ARRAY type record");
break;
case bitc::METADATA_NAME: {
// Read named of the named metadata.
- unsigned NameLength = Record.size();
- SmallString<8> Name;
- Name.resize(NameLength);
- for (unsigned i = 0; i != NameLength; ++i)
- Name[i] = Record[i];
+ SmallString<8> Name(Record.begin(), Record.end());
Record.clear();
Code = Stream.ReadCode();
break;
}
case bitc::METADATA_STRING: {
- unsigned MDStringLength = Record.size();
- SmallString<8> String;
- String.resize(MDStringLength);
- for (unsigned i = 0; i != MDStringLength; ++i)
- String[i] = Record[i];
- Value *V = MDString::get(Context,
- StringRef(String.data(), String.size()));
+ SmallString<8> String(Record.begin(), Record.end());
+ Value *V = MDString::get(Context, String);
MDValueList.AssignValue(V, NextMDValueNo++);
break;
}
case bitc::METADATA_KIND: {
- unsigned RecordLength = Record.size();
- if (Record.empty() || RecordLength < 2)
+ if (Record.size() < 2)
return Error("Invalid METADATA_KIND record");
- SmallString<8> Name;
- Name.resize(RecordLength-1);
+
unsigned Kind = Record[0];
- for (unsigned i = 1; i != RecordLength; ++i)
- Name[i-1] = Record[i];
-
+ SmallString<8> Name(Record.begin()+1, Record.end());
+
unsigned NewKind = TheModule->getMDKindID(Name.str());
if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)
return Error("Conflicting METADATA_KIND records");
}
}
-/// DecodeSignRotatedValue - Decode a signed value stored with the sign bit in
+/// decodeSignRotatedValue - Decode a signed value stored with the sign bit in
/// the LSB for dense VBR encoding.
-static uint64_t DecodeSignRotatedValue(uint64_t V) {
+uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
if ((V & 1) == 0)
return V >> 1;
if (V != 1)
return false;
}
+static APInt ReadWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) {
+ SmallVector<uint64_t, 8> Words(Vals.size());
+ std::transform(Vals.begin(), Vals.end(), Words.begin(),
+ BitcodeReader::decodeSignRotatedValue);
+
+ return APInt(TypeBits, Words);
+}
+
bool BitcodeReader::ParseConstants() {
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
return Error("Malformed block record");
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
if (!CurTy->isIntegerTy() || Record.empty())
return Error("Invalid CST_INTEGER record");
- V = ConstantInt::get(CurTy, DecodeSignRotatedValue(Record[0]));
+ V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0]));
break;
case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval]
if (!CurTy->isIntegerTy() || Record.empty())
return Error("Invalid WIDE_INTEGER record");
- unsigned NumWords = Record.size();
- SmallVector<uint64_t, 8> Words;
- Words.resize(NumWords);
- for (unsigned i = 0; i != NumWords; ++i)
- Words[i] = DecodeSignRotatedValue(Record[i]);
- V = ConstantInt::get(Context,
- APInt(cast<IntegerType>(CurTy)->getBitWidth(),
- Words));
+ APInt VInt = ReadWideAPInt(Record,
+ cast<IntegerType>(CurTy)->getBitWidth());
+ V = ConstantInt::get(Context, VInt);
+
break;
}
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
}
break;
}
- case bitc::CST_CODE_STRING: { // STRING: [values]
- if (Record.empty())
- return Error("Invalid CST_AGGREGATE record");
-
- ArrayType *ATy = cast<ArrayType>(CurTy);
- Type *EltTy = ATy->getElementType();
-
- unsigned Size = Record.size();
- SmallVector<Constant*, 16> Elts;
- for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ConstantInt::get(EltTy, Record[i]));
- V = ConstantArray::get(ATy, Elts);
- break;
- }
+ case bitc::CST_CODE_STRING: // STRING: [values]
case bitc::CST_CODE_CSTRING: { // CSTRING: [values]
if (Record.empty())
- return Error("Invalid CST_AGGREGATE record");
-
- ArrayType *ATy = cast<ArrayType>(CurTy);
- Type *EltTy = ATy->getElementType();
+ return Error("Invalid CST_STRING record");
- unsigned Size = Record.size();
- SmallVector<Constant*, 16> Elts;
- for (unsigned i = 0; i != Size; ++i)
- Elts.push_back(ConstantInt::get(EltTy, Record[i]));
- Elts.push_back(Constant::getNullValue(EltTy));
- V = ConstantArray::get(ATy, Elts);
+ SmallString<16> Elts(Record.begin(), Record.end());
+ V = ConstantDataArray::getString(Context, Elts,
+ BitCode == bitc::CST_CODE_CSTRING);
break;
}
case bitc::CST_CODE_DATA: {// DATA: [n x value]
if (Record.empty())
return Error("Invalid CST_DATA record");
-
+
Type *EltTy = cast<SequentialType>(CurTy)->getElementType();
unsigned Size = Record.size();
-
+
if (EltTy->isIntegerTy(8)) {
SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end());
if (isa<VectorType>(CurTy))
else
V = ConstantDataArray::get(Context, Elts);
} else if (EltTy->isFloatTy()) {
- SmallVector<float, 16> Elts;
- for (unsigned i = 0; i != Size; ++i) {
- union { uint32_t I; float F; };
- I = Record[i];
- Elts.push_back(F);
- }
+ SmallVector<float, 16> Elts(Size);
+ std::transform(Record.begin(), Record.end(), Elts.begin(), BitsToFloat);
if (isa<VectorType>(CurTy))
V = ConstantDataVector::get(Context, Elts);
else
V = ConstantDataArray::get(Context, Elts);
} else if (EltTy->isDoubleTy()) {
- SmallVector<double, 16> Elts;
- for (unsigned i = 0; i != Size; ++i) {
- union { uint64_t I; double F; };
- I = Record[i];
- Elts.push_back(F);
- }
+ SmallVector<double, 16> Elts(Size);
+ std::transform(Record.begin(), Record.end(), Elts.begin(),
+ BitsToDouble);
if (isa<VectorType>(CurTy))
V = ConstantDataVector::get(Context, Elts);
else
}
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
if (Record.size() < 3) return Error("Invalid CE_SELECT record");
- V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0],
- Type::getInt1Ty(Context)),
- ValueList.getConstantFwdRef(Record[1],CurTy),
- ValueList.getConstantFwdRef(Record[2],CurTy));
+ V = ConstantExpr::getSelect(
+ ValueList.getConstantFwdRef(Record[0],
+ Type::getInt1Ty(Context)),
+ ValueList.getConstantFwdRef(Record[1],CurTy),
+ ValueList.getConstantFwdRef(Record[2],CurTy));
break;
case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval]
if (Record.size() < 3) return Error("Invalid CE_EXTRACTELT record");
dyn_cast_or_null<VectorType>(getTypeByID(Record[0]));
if (OpTy == 0) return Error("Invalid CE_EXTRACTELT record");
Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy);
- Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+ Constant *Op1 = ValueList.getConstantFwdRef(Record[2],
+ Type::getInt32Ty(Context));
V = ConstantExpr::getExtractElement(Op0, Op1);
break;
}
Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy);
Constant *Op1 = ValueList.getConstantFwdRef(Record[1],
OpTy->getElementType());
- Constant *Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context));
+ Constant *Op2 = ValueList.getConstantFwdRef(Record[2],
+ Type::getInt32Ty(Context));
V = ConstantExpr::getInsertElement(Op0, Op1, Op2);
break;
}
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
break;
}
- case bitc::CST_CODE_INLINEASM: {
+ // This maintains backward compatibility, pre-asm dialect keywords.
+ // FIXME: Remove with the 4.0 release.
+ case bitc::CST_CODE_INLINEASM_OLD: {
if (Record.size() < 2) return Error("Invalid INLINEASM record");
std::string AsmStr, ConstrStr;
bool HasSideEffects = Record[0] & 1;
AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
break;
}
+ // This version adds support for the asm dialect keywords (e.g.,
+ // inteldialect).
+ case bitc::CST_CODE_INLINEASM: {
+ if (Record.size() < 2) return Error("Invalid INLINEASM record");
+ std::string AsmStr, ConstrStr;
+ bool HasSideEffects = Record[0] & 1;
+ bool IsAlignStack = (Record[0] >> 1) & 1;
+ unsigned AsmDialect = Record[0] >> 2;
+ unsigned AsmStrSize = Record[1];
+ if (2+AsmStrSize >= Record.size())
+ return Error("Invalid INLINEASM record");
+ unsigned ConstStrSize = Record[2+AsmStrSize];
+ if (3+AsmStrSize+ConstStrSize > Record.size())
+ return Error("Invalid INLINEASM record");
+
+ for (unsigned i = 0; i != AsmStrSize; ++i)
+ AsmStr += (char)Record[2+i];
+ for (unsigned i = 0; i != ConstStrSize; ++i)
+ ConstrStr += (char)Record[3+AsmStrSize+i];
+ PointerType *PTy = cast<PointerType>(CurTy);
+ V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()),
+ AsmStr, ConstrStr, HasSideEffects, IsAlignStack,
+ InlineAsm::AsmDialect(AsmDialect));
+ break;
+ }
case bitc::CST_CODE_BLOCKADDRESS:{
if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record");
Type *FnTy = getTypeByID(Record[0]);
Function *Fn =
dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record");
-
- GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
- Type::getInt8Ty(Context),
+
+ // If the function is already parsed we can insert the block address right
+ // away.
+ if (!Fn->empty()) {
+ Function::iterator BBI = Fn->begin(), BBE = Fn->end();
+ for (size_t I = 0, E = Record[2]; I != E; ++I) {
+ if (BBI == BBE)
+ return Error("Invalid blockaddress block #");
+ ++BBI;
+ }
+ V = BlockAddress::get(Fn, BBI);
+ } else {
+ // Otherwise insert a placeholder and remember it so it can be inserted
+ // when the function is parsed.
+ GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+ Type::getInt8Ty(Context),
false, GlobalValue::InternalLinkage,
- 0, "");
- BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
- V = FwdRef;
+ 0, "");
+ BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+ V = FwdRef;
+ }
break;
- }
+ }
}
ValueList.AssignValue(V, NextCstNo);
return Error("Malformed block record");
SmallVector<uint64_t, 64> Record;
-
+
// Read all the records.
while (1) {
unsigned Code = Stream.ReadCode();
return Error("Error at end of use-list table block");
return false;
}
-
+
if (Code == bitc::ENTER_SUBBLOCK) {
// No known subblocks, always skip them.
Stream.ReadSubBlockID();
return Error("Malformed block record");
continue;
}
-
+
if (Code == bitc::DEFINE_ABBREV) {
Stream.ReadAbbrevRecord();
continue;
}
-
+
// Read a use list record.
Record.clear();
switch (Stream.ReadRecord(Code, Record)) {
return false;
}
-bool BitcodeReader::ParseModule() {
- if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+bool BitcodeReader::GlobalCleanup() {
+ // Patch the initializers for globals and aliases up.
+ ResolveGlobalAndAliasInits();
+ if (!GlobalInits.empty() || !AliasInits.empty())
+ return Error("Malformed global initializer set");
+
+ // Look for intrinsic functions which need to be upgraded at some point
+ for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
+ FI != FE; ++FI) {
+ Function *NewFn;
+ if (UpgradeIntrinsicFunction(FI, NewFn))
+ UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn));
+ }
+
+ // Look for global variables which need to be renamed.
+ for (Module::global_iterator
+ GI = TheModule->global_begin(), GE = TheModule->global_end();
+ GI != GE; ++GI)
+ UpgradeGlobalVariable(GI);
+ // Force deallocation of memory for these vectors to favor the client that
+ // want lazy deserialization.
+ std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+ std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+ return false;
+}
+
+bool BitcodeReader::ParseModule(bool Resume) {
+ if (Resume)
+ Stream.JumpToBit(NextUnreadBit);
+ else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
return Error("Malformed block record");
SmallVector<uint64_t, 64> Record;
if (Stream.ReadBlockEnd())
return Error("Error at end of module block");
- // Patch the initializers for globals and aliases up.
- ResolveGlobalAndAliasInits();
- if (!GlobalInits.empty() || !AliasInits.empty())
- return Error("Malformed global initializer set");
- if (!FunctionsWithBodies.empty())
- return Error("Too few function bodies found");
-
- // Look for intrinsic functions which need to be upgraded at some point
- for (Module::iterator FI = TheModule->begin(), FE = TheModule->end();
- FI != FE; ++FI) {
- Function* NewFn;
- if (UpgradeIntrinsicFunction(FI, NewFn))
- UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn));
- }
-
- // Look for global variables which need to be renamed.
- for (Module::global_iterator
- GI = TheModule->global_begin(), GE = TheModule->global_end();
- GI != GE; ++GI)
- UpgradeGlobalVariable(GI);
-
- // Force deallocation of memory for these vectors to favor the client that
- // want lazy deserialization.
- std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
- std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
- std::vector<Function*>().swap(FunctionsWithBodies);
- return false;
+ return GlobalCleanup();
}
if (Code == bitc::ENTER_SUBBLOCK) {
case bitc::VALUE_SYMTAB_BLOCK_ID:
if (ParseValueSymbolTable())
return true;
+ SeenValueSymbolTable = true;
break;
case bitc::CONSTANTS_BLOCK_ID:
if (ParseConstants() || ResolveGlobalAndAliasInits())
case bitc::FUNCTION_BLOCK_ID:
// If this is the first function body we've seen, reverse the
// FunctionsWithBodies list.
- if (!HasReversedFunctionsWithBodies) {
+ if (!SeenFirstFunctionBody) {
std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
- HasReversedFunctionsWithBodies = true;
+ if (GlobalCleanup())
+ return true;
+ SeenFirstFunctionBody = true;
}
if (RememberAndSkipFunctionBody())
return true;
+ // For streaming bitcode, suspend parsing when we reach the function
+ // bodies. Subsequent materialization calls will resume it when
+ // necessary. For streaming, the function bodies must be at the end of
+ // the bitcode. If the bitcode file is old, the symbol table will be
+ // at the end instead and will not have been seen yet. In this case,
+ // just finish the parse now.
+ if (LazyStreamer && SeenValueSymbolTable) {
+ NextUnreadBit = Stream.GetCurrentBitNo();
+ return false;
+ }
break;
case bitc::USELIST_BLOCK_ID:
if (ParseUseLists())
// Read a record.
switch (Stream.ReadRecord(Code, Record)) {
default: break; // Default behavior, ignore unknown content.
- case bitc::MODULE_CODE_VERSION: // VERSION: [version#]
+ case bitc::MODULE_CODE_VERSION: { // VERSION: [version#]
if (Record.size() < 1)
return Error("Malformed MODULE_CODE_VERSION");
- // Only version #0 is supported so far.
- if (Record[0] != 0)
- return Error("Unknown bitstream version!");
+ // Only version #0 and #1 are supported so far.
+ unsigned module_version = Record[0];
+ switch (module_version) {
+ default: return Error("Unknown bitstream version!");
+ case 0:
+ UseRelativeIDs = false;
+ break;
+ case 1:
+ UseRelativeIDs = true;
+ break;
+ }
break;
+ }
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
std::string S;
if (ConvertToString(Record, 0, S))
break;
}
case bitc::MODULE_CODE_DEPLIB: { // DEPLIB: [strchr x N]
+ // FIXME: Remove in 4.0.
std::string S;
if (ConvertToString(Record, 0, S))
return Error("Invalid MODULE_CODE_DEPLIB record");
- TheModule->addLibrary(S);
+ // Ignore value.
break;
}
case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N]
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
if (Record.size() > 6)
Visibility = GetDecodedVisibility(Record[6]);
- bool isThreadLocal = false;
+
+ GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal;
if (Record.size() > 7)
- isThreadLocal = Record[7];
+ TLM = GetDecodedThreadLocalMode(Record[7]);
bool UnnamedAddr = false;
if (Record.size() > 8)
GlobalVariable *NewGV =
new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0,
- isThreadLocal, AddressSpace);
+ TLM, AddressSpace);
NewGV->setAlignment(Alignment);
if (!Section.empty())
NewGV->setSection(Section);
NewGV->setVisibility(Visibility);
- NewGV->setThreadLocal(isThreadLocal);
NewGV->setUnnamedAddr(UnnamedAddr);
ValueList.push_back(NewGV);
// If this is a function with a body, remember the prototype we are
// creating now, so that we can match up the body with them later.
- if (!isProto)
+ if (!isProto) {
FunctionsWithBodies.push_back(Func);
+ if (LazyStreamer) DeferredFunctionInfo[Func] = 0;
+ }
break;
}
// ALIAS: [alias type, aliasee val#, linkage]
bool BitcodeReader::ParseBitcodeInto(Module *M) {
TheModule = 0;
- unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
- unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
-
- if (Buffer->getBufferSize() & 3) {
- if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
- return Error("Invalid bitcode signature");
- else
- return Error("Bitcode stream should be a multiple of 4 bytes in length");
- }
-
- // If we have a wrapper header, parse it and ignore the non-bc file contents.
- // The magic number is 0x0B17C0DE stored in little endian.
- if (isBitcodeWrapper(BufPtr, BufEnd))
- if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
- return Error("Invalid bitcode wrapper header");
-
- StreamFile.init(BufPtr, BufEnd);
- Stream.init(StreamFile);
+ if (InitStream()) return true;
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
// have to read and ignore these final 4 bytes :-(
if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 &&
Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a &&
- Stream.AtEndOfStream())
+ Stream.AtEndOfStream())
return false;
return Error("Invalid record at top-level");
if (TheModule)
return Error("Multiple MODULE_BLOCKs in same stream");
TheModule = M;
- if (ParseModule())
+ if (ParseModule(false))
return true;
+ if (LazyStreamer) return false;
break;
default:
if (Stream.SkipBlock())
// Read a record.
switch (Stream.ReadRecord(Code, Record)) {
default: break; // Default behavior, ignore unknown content.
- case bitc::MODULE_CODE_VERSION: // VERSION: [version#]
- if (Record.size() < 1)
- return Error("Malformed MODULE_CODE_VERSION");
- // Only version #0 is supported so far.
- if (Record[0] != 0)
- return Error("Unknown bitstream version!");
- break;
case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
std::string S;
if (ConvertToString(Record, 0, S))
}
bool BitcodeReader::ParseTriple(std::string &Triple) {
- if (Buffer->getBufferSize() & 3)
- return Error("Bitcode stream should be a multiple of 4 bytes in length");
-
- unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
- unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
-
- // If we have a wrapper header, parse it and ignore the non-bc file contents.
- // The magic number is 0x0B17C0DE stored in little endian.
- if (isBitcodeWrapper(BufPtr, BufEnd))
- if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
- return Error("Invalid bitcode wrapper header");
-
- StreamFile.init(BufPtr, BufEnd);
- Stream.init(StreamFile);
+ if (InitStream()) return true;
// Sniff for the signature.
if (Stream.Read(8) != 'B' ||
unsigned CurBBNo = 0;
DebugLoc LastLoc;
-
+
// Read all the records.
SmallVector<uint64_t, 64> Record;
while (1) {
FunctionBBs[i] = BasicBlock::Create(Context, "", F);
CurBB = FunctionBBs[0];
continue;
-
+
case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN
// This record indicates that the last instruction is at the same
// location as the previous instruction with a location.
I = 0;
-
+
// Get the last instruction emitted.
if (CurBB && !CurBB->empty())
I = &CurBB->back();
else if (CurBBNo && FunctionBBs[CurBBNo-1] &&
!FunctionBBs[CurBBNo-1]->empty())
I = &FunctionBBs[CurBBNo-1]->back();
-
+
if (I == 0) return Error("Invalid DEBUG_LOC_AGAIN record");
I->setDebugLoc(LastLoc);
I = 0;
continue;
-
+
case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia]
I = 0; // Get the last instruction emitted.
if (CurBB && !CurBB->empty())
I = &FunctionBBs[CurBBNo-1]->back();
if (I == 0 || Record.size() < 4)
return Error("Invalid FUNC_CODE_DEBUG_LOC record");
-
+
unsigned Line = Record[0], Col = Record[1];
unsigned ScopeID = Record[2], IAID = Record[3];
-
+
MDNode *Scope = 0, *IA = 0;
if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1));
if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1));
unsigned OpNum = 0;
Value *LHS, *RHS;
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
- getValue(Record, OpNum, LHS->getType(), RHS) ||
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
OpNum+1 > Record.size())
return Error("Invalid BINOP record");
Opc == Instruction::AShr) {
if (Record[OpNum] & (1 << bitc::PEO_EXACT))
cast<BinaryOperator>(I)->setIsExact(true);
+ } else if (isa<FPMathOperator>(I)) {
+ FastMathFlags FMF;
+ if (0 != (Record[OpNum] & FastMathFlags::UnsafeAlgebra))
+ FMF.setUnsafeAlgebra();
+ if (0 != (Record[OpNum] & FastMathFlags::NoNaNs))
+ FMF.setNoNaNs();
+ if (0 != (Record[OpNum] & FastMathFlags::NoInfs))
+ FMF.setNoInfs();
+ if (0 != (Record[OpNum] & FastMathFlags::NoSignedZeros))
+ FMF.setNoSignedZeros();
+ if (0 != (Record[OpNum] & FastMathFlags::AllowReciprocal))
+ FMF.setAllowReciprocal();
+ if (FMF.any())
+ I->setFastMathFlags(FMF);
}
+
}
break;
}
unsigned OpNum = 0;
Value *TrueVal, *FalseVal, *Cond;
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
- getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
- getValue(Record, OpNum, Type::getInt1Ty(Context), Cond))
+ popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
+ popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond))
return Error("Invalid SELECT record");
I = SelectInst::Create(Cond, TrueVal, FalseVal);
unsigned OpNum = 0;
Value *TrueVal, *FalseVal, *Cond;
if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
- getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
+ popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) ||
getValueTypePair(Record, OpNum, NextValueNo, Cond))
return Error("Invalid SELECT record");
unsigned OpNum = 0;
Value *Vec, *Idx;
if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
- getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
+ popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx))
return Error("Invalid EXTRACTELT record");
I = ExtractElementInst::Create(Vec, Idx);
InstructionList.push_back(I);
unsigned OpNum = 0;
Value *Vec, *Elt, *Idx;
if (getValueTypePair(Record, OpNum, NextValueNo, Vec) ||
- getValue(Record, OpNum,
+ popValue(Record, OpNum, NextValueNo,
cast<VectorType>(Vec->getType())->getElementType(), Elt) ||
- getValue(Record, OpNum, Type::getInt32Ty(Context), Idx))
+ popValue(Record, OpNum, NextValueNo, Type::getInt32Ty(Context), Idx))
return Error("Invalid INSERTELT record");
I = InsertElementInst::Create(Vec, Elt, Idx);
InstructionList.push_back(I);
unsigned OpNum = 0;
Value *Vec1, *Vec2, *Mask;
if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) ||
- getValue(Record, OpNum, Vec1->getType(), Vec2))
+ popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2))
return Error("Invalid SHUFFLEVEC record");
if (getValueTypePair(Record, OpNum, NextValueNo, Mask))
unsigned OpNum = 0;
Value *LHS, *RHS;
if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
- getValue(Record, OpNum, LHS->getType(), RHS) ||
+ popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) ||
OpNum+1 != Record.size())
return Error("Invalid CMP record");
}
else {
BasicBlock *FalseDest = getBasicBlock(Record[1]);
- Value *Cond = getFnValueByID(Record[2], Type::getInt1Ty(Context));
+ Value *Cond = getValue(Record, 2, NextValueNo,
+ Type::getInt1Ty(Context));
if (FalseDest == 0 || Cond == 0)
return Error("Invalid BR record");
I = BranchInst::Create(TrueDest, FalseDest, Cond);
break;
}
case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
+ // Check magic
+ if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
+ // New SwitchInst format with case ranges.
+
+ Type *OpTy = getTypeByID(Record[1]);
+ unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
+
+ Value *Cond = getValue(Record, 2, NextValueNo, OpTy);
+ BasicBlock *Default = getBasicBlock(Record[3]);
+ if (OpTy == 0 || Cond == 0 || Default == 0)
+ return Error("Invalid SWITCH record");
+
+ unsigned NumCases = Record[4];
+
+ SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+ InstructionList.push_back(SI);
+
+ unsigned CurIdx = 5;
+ for (unsigned i = 0; i != NumCases; ++i) {
+ IntegersSubsetToBB CaseBuilder;
+ unsigned NumItems = Record[CurIdx++];
+ for (unsigned ci = 0; ci != NumItems; ++ci) {
+ bool isSingleNumber = Record[CurIdx++];
+
+ APInt Low;
+ unsigned ActiveWords = 1;
+ if (ValueBitWidth > 64)
+ ActiveWords = Record[CurIdx++];
+ Low = ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
+ ValueBitWidth);
+ CurIdx += ActiveWords;
+
+ if (!isSingleNumber) {
+ ActiveWords = 1;
+ if (ValueBitWidth > 64)
+ ActiveWords = Record[CurIdx++];
+ APInt High =
+ ReadWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords),
+ ValueBitWidth);
+
+ CaseBuilder.add(IntItem::fromType(OpTy, Low),
+ IntItem::fromType(OpTy, High));
+ CurIdx += ActiveWords;
+ } else
+ CaseBuilder.add(IntItem::fromType(OpTy, Low));
+ }
+ BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
+ IntegersSubset Case = CaseBuilder.getCase();
+ SI->addCase(Case, DestBB);
+ }
+ uint16_t Hash = SI->hash();
+ if (Hash != (Record[0] & 0xFFFF))
+ return Error("Invalid SWITCH record");
+ I = SI;
+ break;
+ }
+
+ // Old SwitchInst format without case ranges.
+
if (Record.size() < 3 || (Record.size() & 1) == 0)
return Error("Invalid SWITCH record");
Type *OpTy = getTypeByID(Record[0]);
- Value *Cond = getFnValueByID(Record[1], OpTy);
+ Value *Cond = getValue(Record, 1, NextValueNo, OpTy);
BasicBlock *Default = getBasicBlock(Record[2]);
if (OpTy == 0 || Cond == 0 || Default == 0)
return Error("Invalid SWITCH record");
if (Record.size() < 2)
return Error("Invalid INDIRECTBR record");
Type *OpTy = getTypeByID(Record[0]);
- Value *Address = getFnValueByID(Record[1], OpTy);
+ Value *Address = getValue(Record, 1, NextValueNo, OpTy);
if (OpTy == 0 || Address == 0)
return Error("Invalid INDIRECTBR record");
unsigned NumDests = Record.size()-2;
I = IBI;
break;
}
-
+
case bitc::FUNC_CODE_INST_INVOKE: {
// INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...]
if (Record.size() < 4) return Error("Invalid INVOKE record");
- AttrListPtr PAL = getAttributes(Record[0]);
+ AttributeSet PAL = getAttributes(Record[0]);
unsigned CCInfo = Record[1];
BasicBlock *NormalBB = getBasicBlock(Record[2]);
BasicBlock *UnwindBB = getBasicBlock(Record[3]);
SmallVector<Value*, 16> Ops;
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) {
- Ops.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
+ Ops.push_back(getValue(Record, OpNum, NextValueNo,
+ FTy->getParamType(i)));
if (Ops.back() == 0) return Error("Invalid INVOKE record");
}
InstructionList.push_back(I);
break;
}
- case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
- I = new UnwindInst(Context);
- InstructionList.push_back(I);
- break;
case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
I = new UnreachableInst(Context);
InstructionList.push_back(I);
InstructionList.push_back(PN);
for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) {
- Value *V = getFnValueByID(Record[1+i], Ty);
+ Value *V;
+ // With the new function encoding, it is possible that operands have
+ // negative IDs (for forward references). Use a signed VBR
+ // representation to keep the encoding small.
+ if (UseRelativeIDs)
+ V = getValueSigned(Record, 1+i, NextValueNo, Ty);
+ else
+ V = getValue(Record, 1+i, NextValueNo, Ty);
BasicBlock *BB = getBasicBlock(Record[2+i]);
if (!V || !BB) return Error("Invalid PHI record");
PN->addIncoming(V, BB);
if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
OpNum+4 != Record.size())
return Error("Invalid LOADATOMIC record");
-
+
AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]);
if (Ordering == NotAtomic || Ordering == Release ||
unsigned OpNum = 0;
Value *Val, *Ptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- getValue(Record, OpNum,
+ popValue(Record, OpNum, NextValueNo,
cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
OpNum+2 != Record.size())
return Error("Invalid STORE record");
unsigned OpNum = 0;
Value *Val, *Ptr;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- getValue(Record, OpNum,
+ popValue(Record, OpNum, NextValueNo,
cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
OpNum+4 != Record.size())
return Error("Invalid STOREATOMIC record");
unsigned OpNum = 0;
Value *Ptr, *Cmp, *New;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- getValue(Record, OpNum,
+ popValue(Record, OpNum, NextValueNo,
cast<PointerType>(Ptr->getType())->getElementType(), Cmp) ||
- getValue(Record, OpNum,
+ popValue(Record, OpNum, NextValueNo,
cast<PointerType>(Ptr->getType())->getElementType(), New) ||
OpNum+3 != Record.size())
return Error("Invalid CMPXCHG record");
unsigned OpNum = 0;
Value *Ptr, *Val;
if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) ||
- getValue(Record, OpNum,
+ popValue(Record, OpNum, NextValueNo,
cast<PointerType>(Ptr->getType())->getElementType(), Val) ||
OpNum+4 != Record.size())
return Error("Invalid ATOMICRMW record");
if (Record.size() < 3)
return Error("Invalid CALL record");
- AttrListPtr PAL = getAttributes(Record[0]);
+ AttributeSet PAL = getAttributes(Record[0]);
unsigned CCInfo = Record[1];
unsigned OpNum = 2;
if (FTy->getParamType(i)->isLabelTy())
Args.push_back(getBasicBlock(Record[OpNum]));
else
- Args.push_back(getFnValueByID(Record[OpNum], FTy->getParamType(i)));
+ Args.push_back(getValue(Record, OpNum, NextValueNo,
+ FTy->getParamType(i)));
if (Args.back() == 0) return Error("Invalid CALL record");
}
if (Record.size() < 3)
return Error("Invalid VAARG record");
Type *OpTy = getTypeByID(Record[0]);
- Value *Op = getFnValueByID(Record[1], OpTy);
+ Value *Op = getValue(Record, 1, NextValueNo, OpTy);
Type *ResTy = getTypeByID(Record[2]);
if (!OpTy || !Op || !ResTy)
return Error("Invalid VAARG record");
unsigned BlockIdx = RefList[i].first;
if (BlockIdx >= FunctionBBs.size())
return Error("Invalid blockaddress block #");
-
+
GlobalVariable *FwdRef = RefList[i].second;
FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
FwdRef->eraseFromParent();
}
-
+
BlockAddrFwdRefs.erase(BAFRI);
}
-
+
// Trim the value list down to the size it was before we parsed this function.
ValueList.shrinkTo(ModuleValueListSize);
MDValueList.shrinkTo(ModuleMDValueListSize);
return false;
}
+/// FindFunctionInStream - Find the function body in the bitcode stream
+bool BitcodeReader::FindFunctionInStream(Function *F,
+ DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) {
+ while (DeferredFunctionInfoIterator->second == 0) {
+ if (Stream.AtEndOfStream())
+ return Error("Could not find Function in stream");
+ // ParseModule will parse the next body in the stream and set its
+ // position in the DeferredFunctionInfo map.
+ if (ParseModule(true)) return true;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// GVMaterializer implementation
//===----------------------------------------------------------------------===//
DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F);
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+ // If its position is recorded as 0, its body is somewhere in the stream
+ // but we haven't seen it yet.
+ if (DFII->second == 0)
+ if (LazyStreamer && FindFunctionInStream(F, DFII)) return true;
// Move the bit stream to the saved position of the deferred function body.
Stream.JumpToBit(DFII->second);
Materialize(F, ErrInfo))
return true;
+ // At this point, if there are any function bodies, the current bit is
+ // pointing to the END_BLOCK record after them. Now make sure the rest
+ // of the bits in the module have been read.
+ if (NextUnreadBit)
+ ParseModule(true);
+
// Upgrade any intrinsic calls that slipped through (should not happen!) and
// delete the old functions to clean up. We can't do this unless the entire
// module is materialized because there could always be another function body
return false;
}
+bool BitcodeReader::InitStream() {
+ if (LazyStreamer) return InitLazyStream();
+ return InitStreamFromBuffer();
+}
+
+bool BitcodeReader::InitStreamFromBuffer() {
+ const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart();
+ const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+ if (Buffer->getBufferSize() & 3) {
+ if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
+ return Error("Invalid bitcode signature");
+ else
+ return Error("Bitcode stream should be a multiple of 4 bytes in length");
+ }
+
+ // If we have a wrapper header, parse it and ignore the non-bc file contents.
+ // The magic number is 0x0B17C0DE stored in little endian.
+ if (isBitcodeWrapper(BufPtr, BufEnd))
+ if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
+ return Error("Invalid bitcode wrapper header");
+
+ StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
+ Stream.init(*StreamFile);
+
+ return false;
+}
+
+bool BitcodeReader::InitLazyStream() {
+ // Check and strip off the bitcode wrapper; BitstreamReader expects never to
+ // see it.
+ StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer);
+ StreamFile.reset(new BitstreamReader(Bytes));
+ Stream.init(*StreamFile);
+
+ unsigned char buf[16];
+ if (Bytes->readBytes(0, 16, buf, NULL) == -1)
+ return Error("Bitcode stream must be at least 16 bytes in length");
+
+ if (!isBitcode(buf, buf + 16))
+ return Error("Invalid bitcode signature");
+
+ if (isBitcodeWrapper(buf, buf + 4)) {
+ const unsigned char *bitcodeStart = buf;
+ const unsigned char *bitcodeEnd = buf + 16;
+ SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
+ Bytes->dropLeadingBytes(bitcodeStart - buf);
+ Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart);
+ }
+ return false;
+}
//===----------------------------------------------------------------------===//
// External interface
return M;
}
+
+Module *llvm::getStreamedBitcodeModule(const std::string &name,
+ DataStreamer *streamer,
+ LLVMContext &Context,
+ std::string *ErrMsg) {
+ Module *M = new Module(name, Context);
+ BitcodeReader *R = new BitcodeReader(streamer, Context);
+ M->setMaterializer(R);
+ if (R->ParseBitcodeInto(M)) {
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+ delete M; // Also deletes R.
+ return 0;
+ }
+ R->setBufferOwned(false); // no buffer to delete
+ return M;
+}
+
/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
/// If an error occurs, return null and fill in *ErrMsg if non-null.
Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,