#include "llvm/Constants.h"
#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
-#include "llvm/SymbolTable.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/Bytecode/Format.h"
#include "llvm/Config/alloca.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/Compressor.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include <sstream>
#include <algorithm>
inline void BytecodeReader::error(const std::string& err) {
ErrorMsg = err + " (Vers=" + itostr(RevisionNum) + ", Pos="
+ itostr(At-MemStart) + ")";
+ if (Handler) Handler->handleError(ErrorMsg);
longjmp(context,1);
}
return TyID != Type::LabelTyID && TyID != Type::VoidTyID;
}
-/// Obtain a type given a typeid and account for things like compaction tables,
-/// function level vs module level, and the offsetting for the primitive types.
+/// Obtain a type given a typeid and account for things like function level vs
+/// module level, and the offsetting for the primitive types.
const Type *BytecodeReader::getType(unsigned ID) {
- if (ID < Type::FirstDerivedTyID)
+ if (ID <= Type::LastPrimitiveTyID)
if (const Type *T = Type::getPrimitiveType((Type::TypeID)ID))
return T; // Asked for a primitive type...
// Otherwise, derived types need offset...
ID -= Type::FirstDerivedTyID;
- if (!CompactionTypes.empty()) {
- if (ID >= CompactionTypes.size())
- error("Type ID out of range for compaction table!");
- return CompactionTypes[ID].first;
- }
-
// Is it a module-level type?
if (ID < ModuleTypes.size())
return ModuleTypes[ID].get();
}
/// Get the slot number associated with a type accounting for primitive
-/// types, compaction tables, and function level vs module level.
+/// types and function level vs module level.
unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
if (Ty->isPrimitiveType())
return Ty->getTypeID();
- // Scan the compaction table for the type if needed.
- if (!CompactionTypes.empty()) {
- for (unsigned i = 0, e = CompactionTypes.size(); i != e; ++i)
- if (CompactionTypes[i].first == Ty)
- return Type::FirstDerivedTyID + i;
-
- error("Couldn't find type specified in compaction table!");
- }
-
// Check the function level types first...
TypeListTy::iterator I = std::find(FunctionTypes.begin(),
FunctionTypes.end(), Ty);
return Type::FirstDerivedTyID + IT->second;
}
-/// This is just like getType, but when a compaction table is in use, it is
-/// ignored. It also ignores function level types.
-/// @see getType
-const Type *BytecodeReader::getGlobalTableType(unsigned Slot) {
- if (Slot < Type::FirstDerivedTyID) {
- const Type *Ty = Type::getPrimitiveType((Type::TypeID)Slot);
- if (!Ty)
- error("Not a primitive type ID?");
- return Ty;
- }
- Slot -= Type::FirstDerivedTyID;
- if (Slot >= ModuleTypes.size())
- error("Illegal compaction table type reference!");
- return ModuleTypes[Slot];
-}
-
-/// This is just like getTypeSlot, but when a compaction table is in use, it
-/// is ignored. It also ignores function level types.
-unsigned BytecodeReader::getGlobalTableTypeSlot(const Type *Ty) {
- if (Ty->isPrimitiveType())
- return Ty->getTypeID();
-
- // If we don't have our cache yet, build it now.
- if (ModuleTypeIDCache.empty()) {
- unsigned N = 0;
- ModuleTypeIDCache.reserve(ModuleTypes.size());
- for (TypeListTy::iterator I = ModuleTypes.begin(), E = ModuleTypes.end();
- I != E; ++I, ++N)
- ModuleTypeIDCache.push_back(std::make_pair(*I, N));
-
- std::sort(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end());
- }
-
- // Binary search the cache for the entry.
- std::vector<std::pair<const Type*, unsigned> >::iterator IT =
- std::lower_bound(ModuleTypeIDCache.begin(), ModuleTypeIDCache.end(),
- std::make_pair(Ty, 0U));
- if (IT == ModuleTypeIDCache.end() || IT->first != Ty)
- error("Didn't find type in ModuleTypes.");
-
- return Type::FirstDerivedTyID + IT->second;
-}
-
/// Retrieve a value of a given type and slot number, possibly creating
/// it if it doesn't already exist.
Value * BytecodeReader::getValue(unsigned type, unsigned oNum, bool Create) {
assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
unsigned Num = oNum;
- // If there is a compaction table active, it defines the low-level numbers.
- // If not, the module values define the low-level numbers.
- if (CompactionValues.size() > type && !CompactionValues[type].empty()) {
- if (Num < CompactionValues[type].size())
- return CompactionValues[type][Num];
- Num -= CompactionValues[type].size();
- } else {
- // By default, the global type id is the type id passed in
- unsigned GlobalTyID = type;
-
- // If the type plane was compactified, figure out the global type ID by
- // adding the derived type ids and the distance.
- if (!CompactionTypes.empty() && type >= Type::FirstDerivedTyID)
- GlobalTyID = CompactionTypes[type-Type::FirstDerivedTyID].second;
-
- if (hasImplicitNull(GlobalTyID)) {
- const Type *Ty = getType(type);
- if (!isa<OpaqueType>(Ty)) {
- if (Num == 0)
- return Constant::getNullValue(Ty);
- --Num;
- }
- }
+ // By default, the global type id is the type id passed in
+ unsigned GlobalTyID = type;
- if (GlobalTyID < ModuleValues.size() && ModuleValues[GlobalTyID]) {
- if (Num < ModuleValues[GlobalTyID]->size())
- return ModuleValues[GlobalTyID]->getOperand(Num);
- Num -= ModuleValues[GlobalTyID]->size();
+ if (hasImplicitNull(GlobalTyID)) {
+ const Type *Ty = getType(type);
+ if (!isa<OpaqueType>(Ty)) {
+ if (Num == 0)
+ return Constant::getNullValue(Ty);
+ --Num;
}
}
+ if (GlobalTyID < ModuleValues.size() && ModuleValues[GlobalTyID]) {
+ if (Num < ModuleValues[GlobalTyID]->size())
+ return ModuleValues[GlobalTyID]->getOperand(Num);
+ Num -= ModuleValues[GlobalTyID]->size();
+ }
+
if (FunctionValues.size() > type &&
FunctionValues[type] &&
Num < FunctionValues[type]->size())
return 0; // just silence warning, error calls longjmp
}
-/// This is just like getValue, but when a compaction table is in use, it
-/// is ignored. Also, no forward references or other fancy features are
-/// supported.
-Value* BytecodeReader::getGlobalTableValue(unsigned TyID, unsigned SlotNo) {
- if (SlotNo == 0)
- return Constant::getNullValue(getType(TyID));
-
- if (!CompactionTypes.empty() && TyID >= Type::FirstDerivedTyID) {
- TyID -= Type::FirstDerivedTyID;
- if (TyID >= CompactionTypes.size())
- error("Type ID out of range for compaction table!");
- TyID = CompactionTypes[TyID].second;
- }
-
- --SlotNo;
-
- if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0 ||
- SlotNo >= ModuleValues[TyID]->size()) {
- if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0)
- error("Corrupt compaction table entry!"
- + utostr(TyID) + ", " + utostr(SlotNo) + ": "
- + utostr(ModuleValues.size()));
- else
- error("Corrupt compaction table entry!"
- + utostr(TyID) + ", " + utostr(SlotNo) + ": "
- + utostr(ModuleValues.size()) + ", "
- + utohexstr(reinterpret_cast<uint64_t>(((void*)ModuleValues[TyID])))
- + ", "
- + utostr(ModuleValues[TyID]->size()));
- }
- return ModuleValues[TyID]->getOperand(SlotNo);
-}
/// Just like getValue, except that it returns a null pointer
/// only on error. It always returns a constant (meaning that if the value is
// of opcodes.
Instruction* Result = 0;
- // We have enough info to inform the handler now.
- if (Handler)
- Handler->handleInstruction(Opcode, InstTy, Oprnds, At-SaveAt);
-
// First, handle the easy binary operators case
if (Opcode >= Instruction::BinaryOpsBegin &&
Opcode < Instruction::BinaryOpsEnd && Oprnds.size() == 2) {
if (Oprnds.size() != 2)
error("Invalid extractelement instruction!");
Value *V1 = getValue(iType, Oprnds[0]);
- Value *V2 = getValue(Type::Int32TyID, Oprnds[1]);
+ Value *V2 = getValue(Int32TySlot, Oprnds[1]);
if (!ExtractElementInst::isValidOperands(V1, V2))
error("Invalid extractelement instruction!");
Value *V1 = getValue(iType, Oprnds[0]);
Value *V2 = getValue(getTypeSlot(PackedTy->getElementType()),Oprnds[1]);
- Value *V3 = getValue(Type::Int32TyID, Oprnds[2]);
+ Value *V3 = getValue(Int32TySlot, Oprnds[2]);
if (!InsertElementInst::isValidOperands(V1, V2, V3))
error("Invalid insertelement instruction!");
case Instruction::Select:
if (Oprnds.size() != 3)
error("Invalid Select instruction!");
- Result = new SelectInst(getValue(Type::BoolTyID, Oprnds[0]),
+ Result = new SelectInst(getValue(BoolTySlot, Oprnds[0]),
getValue(iType, Oprnds[1]),
getValue(iType, Oprnds[2]));
break;
static_cast<unsigned short>(Oprnds[2]),
getValue(iType, Oprnds[0]), getValue(iType, Oprnds[1]));
break;
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:
- Result = new ShiftInst(Instruction::OtherOps(Opcode),
- getValue(iType, Oprnds[0]),
- getValue(Type::Int8TyID, Oprnds[1]));
- break;
case Instruction::Ret:
if (Oprnds.size() == 0)
Result = new ReturnInst();
Result = new BranchInst(getBasicBlock(Oprnds[0]));
else if (Oprnds.size() == 3)
Result = new BranchInst(getBasicBlock(Oprnds[0]),
- getBasicBlock(Oprnds[1]), getValue(Type::BoolTyID , Oprnds[2]));
+ getBasicBlock(Oprnds[1]), getValue(BoolTySlot, Oprnds[2]));
else
error("Invalid number of operands for a 'br' instruction!");
break;
error("Invalid malloc instruction!");
Result = new MallocInst(cast<PointerType>(InstTy)->getElementType(),
- getValue(Type::Int32TyID, Oprnds[0]), Align);
+ getValue(Int32TySlot, Oprnds[0]), Align);
break;
}
case Instruction::Alloca: {
error("Invalid alloca instruction!");
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
- getValue(Type::Int32TyID, Oprnds[0]), Align);
+ getValue(Int32TySlot, Oprnds[0]), Align);
break;
}
case Instruction::Free:
if (Oprnds.size() == 0 || !isa<PointerType>(InstTy))
error("Invalid getelementptr instruction!");
- std::vector<Value*> Idx;
+ SmallVector<Value*, 8> Idx;
const Type *NextTy = InstTy;
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
// any of the 32 or 64-bit integer types. The actual choice of
// type is encoded in the low bit of the slot number.
if (isa<StructType>(TopTy))
- IdxTy = Type::Int32TyID;
+ IdxTy = Int32TySlot;
else {
switch (ValIdx & 1) {
default:
- case 0: IdxTy = Type::Int32TyID; break;
- case 1: IdxTy = Type::Int64TyID; break;
+ case 0: IdxTy = Int32TySlot; break;
+ case 1: IdxTy = Int64TySlot; break;
}
ValIdx >>= 1;
}
Idx.push_back(getValue(IdxTy, ValIdx));
- NextTy = GetElementPtrInst::getIndexedType(InstTy, Idx, true);
+ NextTy = GetElementPtrInst::getIndexedType(InstTy, &Idx[0], Idx.size(),
+ true);
}
- Result = new GetElementPtrInst(getValue(iType, Oprnds[0]), Idx);
+ Result = new GetElementPtrInst(getValue(iType, Oprnds[0]),
+ &Idx[0], Idx.size());
break;
}
case 62: // volatile load
else
TypeSlot = getTypeSlot(Result->getType());
+ // We have enough info to inform the handler now.
+ if (Handler)
+ Handler->handleInstruction(Opcode, InstTy, Oprnds, Result, At-SaveAt);
+
insertValue(Result, TypeSlot, FunctionValues);
}
/// CurrentFunction's symbol table. For Module level symbol tables, the
/// CurrentFunction argument must be zero.
void BytecodeReader::ParseValueSymbolTable(Function *CurrentFunction,
- SymbolTable *ST) {
+ ValueSymbolTable *VST) {
- if (Handler) Handler->handleSymbolTableBegin(CurrentFunction,ST);
+ if (Handler) Handler->handleValueSymbolTableBegin(CurrentFunction,VST);
// Allow efficient basic block lookup by number.
std::vector<BasicBlock*> BBMap;
unsigned slot = read_vbr_uint();
std::string Name = read_str();
Value *V = 0;
- if (Typ == Type::LabelTyID) {
+ if (Typ == LabelTySlot) {
if (slot < BBMap.size())
V = BBMap[slot];
} else {
V = getValue(Typ, slot, false); // Find mapping...
}
+ if (Handler) Handler->handleSymbolTableValue(Typ, slot, Name);
if (V == 0)
- error("Failed value look-up for name '" + Name + "'");
+ error("Failed value look-up for name '" + Name + "', type #" +
+ utostr(Typ) + " slot #" + utostr(slot));
V->setName(Name);
}
}
checkPastBlockEnd("Symbol Table");
- if (Handler) Handler->handleSymbolTableEnd();
-}
-
-/// Read in the types portion of a compaction table.
-void BytecodeReader::ParseCompactionTypes(unsigned NumEntries) {
- for (unsigned i = 0; i != NumEntries; ++i) {
- unsigned TypeSlot = read_vbr_uint();
- const Type *Typ = getGlobalTableType(TypeSlot);
- CompactionTypes.push_back(std::make_pair(Typ, TypeSlot));
- if (Handler) Handler->handleCompactionTableType(i, TypeSlot, Typ);
- }
-}
-
-/// Parse a compaction table.
-void BytecodeReader::ParseCompactionTable() {
-
- // Notify handler that we're beginning a compaction table.
- if (Handler) Handler->handleCompactionTableBegin();
-
- // Get the types for the compaction table.
- unsigned NumEntries = read_vbr_uint();
- ParseCompactionTypes(NumEntries);
-
- // Compaction tables live in separate blocks so we have to loop
- // until we've read the whole thing.
- while (moreInBlock()) {
- // Read the number of Value* entries in the compaction table
- unsigned NumEntries = read_vbr_uint();
- unsigned Ty = 0;
-
- // Decode the type from value read in. Most compaction table
- // planes will have one or two entries in them. If that's the
- // case then the length is encoded in the bottom two bits and
- // the higher bits encode the type. This saves another VBR value.
- if ((NumEntries & 3) == 3) {
- // In this case, both low-order bits are set (value 3). This
- // is a signal that the typeid follows.
- NumEntries >>= 2;
- Ty = read_vbr_uint();
- } else {
- // In this case, the low-order bits specify the number of entries
- // and the high order bits specify the type.
- Ty = NumEntries >> 2;
- NumEntries &= 3;
- }
-
- // Make sure we have enough room for the plane.
- if (Ty >= CompactionValues.size())
- CompactionValues.resize(Ty+1);
-
- // Make sure the plane is empty or we have some kind of error.
- if (!CompactionValues[Ty].empty())
- error("Compaction table plane contains multiple entries!");
-
- // Notify handler about the plane.
- if (Handler) Handler->handleCompactionTablePlane(Ty, NumEntries);
-
- // Push the implicit zero.
- CompactionValues[Ty].push_back(Constant::getNullValue(getType(Ty)));
-
- // Read in each of the entries, put them in the compaction table
- // and notify the handler that we have a new compaction table value.
- for (unsigned i = 0; i != NumEntries; ++i) {
- unsigned ValSlot = read_vbr_uint();
- Value *V = getGlobalTableValue(Ty, ValSlot);
- CompactionValues[Ty].push_back(V);
- if (Handler) Handler->handleCompactionTableValue(i, Ty, ValSlot);
- }
- }
- // Notify handler that the compaction table is done.
- if (Handler) Handler->handleCompactionTableEnd();
+ if (Handler) Handler->handleValueSymbolTableEnd();
}
// Parse a single type. The typeid is read in first. If its a primitive type
return Result;
switch (PrimType) {
+ case Type::IntegerTyID: {
+ unsigned NumBits = read_vbr_uint();
+ Result = IntegerType::get(NumBits);
+ break;
+ }
case Type::FunctionTyID: {
const Type *RetType = readType();
unsigned RetAttr = read_vbr_uint();
Result = StructType::get(Elements, false);
break;
}
- case Type::BC_ONLY_PackedStructTyID: {
+ case Type::PackedStructTyID: {
std::vector<const Type*> Elements;
unsigned Typ = read_vbr_uint();
while (Typ) { // List is terminated by void/0 typeid
if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
return Result;
} else if (Opcode == Instruction::GetElementPtr) { // GetElementPtr
- std::vector<Constant*> IdxList(ArgVec.begin()+1, ArgVec.end());
- Constant *Result = ConstantExpr::getGetElementPtr(ArgVec[0], IdxList);
+ Constant *Result = ConstantExpr::getGetElementPtr(ArgVec[0], &ArgVec[1],
+ ArgVec.size()-1);
if (Handler) Handler->handleConstantExpression(Opcode, ArgVec, Result);
return Result;
} else if (Opcode == Instruction::Select) {
const Type *Ty = getType(TypeID);
Constant *Result = 0;
switch (Ty->getTypeID()) {
- case Type::BoolTyID: {
- unsigned Val = read_vbr_uint();
- if (Val != 0 && Val != 1)
- error("Invalid boolean value read.");
- Result = ConstantInt::get(Val == 1);
- if (Handler) Handler->handleConstantValue(Result);
- break;
- }
-
- case Type::Int8TyID: // Unsigned integer types...
- case Type::Int16TyID:
- case Type::Int32TyID: {
- unsigned Val = read_vbr_uint();
- if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
- error("Invalid unsigned byte/short/int read.");
- Result = ConstantInt::get(Ty, Val);
- if (Handler) Handler->handleConstantValue(Result);
- break;
- }
-
- case Type::Int64TyID: {
- uint64_t Val = read_vbr_uint64();
- if (!ConstantInt::isValueValidForType(Ty, Val))
- error("Invalid constant integer read.");
- Result = ConstantInt::get(Ty, Val);
- if (Handler) Handler->handleConstantValue(Result);
+ case Type::IntegerTyID: {
+ const IntegerType *IT = cast<IntegerType>(Ty);
+ if (IT->getBitWidth() <= 32) {
+ uint32_t Val = read_vbr_uint();
+ if (!ConstantInt::isValueValidForType(Ty, uint64_t(Val)))
+ error("Integer value read is invalid for type.");
+ Result = ConstantInt::get(IT, Val);
+ if (Handler) Handler->handleConstantValue(Result);
+ } else if (IT->getBitWidth() <= 64) {
+ uint64_t Val = read_vbr_uint64();
+ if (!ConstantInt::isValueValidForType(Ty, Val))
+ error("Invalid constant integer read.");
+ Result = ConstantInt::get(IT, Val);
+ if (Handler) Handler->handleConstantValue(Result);
+ } else
+ assert("Integer types > 64 bits not supported");
break;
}
case Type::FloatTyID: {
unsigned FuncSize = BlockEnd - At;
GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
+ GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
- unsigned LinkageType = read_vbr_uint();
- switch (LinkageType) {
+ unsigned rWord = read_vbr_uint();
+ unsigned LinkageID = rWord & 65535;
+ unsigned VisibilityID = rWord >> 16;
+ switch (LinkageID) {
case 0: Linkage = GlobalValue::ExternalLinkage; break;
case 1: Linkage = GlobalValue::WeakLinkage; break;
case 2: Linkage = GlobalValue::AppendingLinkage; break;
Linkage = GlobalValue::InternalLinkage;
break;
}
+ switch (VisibilityID) {
+ case 0: Visibility = GlobalValue::DefaultVisibility; break;
+ case 1: Visibility = GlobalValue::HiddenVisibility; break;
+ default:
+ error("Unknown visibility type: " + utostr(VisibilityID));
+ Visibility = GlobalValue::DefaultVisibility;
+ break;
+ }
F->setLinkage(Linkage);
+ F->setVisibility(Visibility);
if (Handler) Handler->handleFunctionBegin(F,FuncSize);
// Keep track of how many basic blocks we have read in...
case BytecodeFormat::ConstantPoolBlockID:
if (!InsertedArguments) {
// Insert arguments into the value table before we parse the first basic
- // block in the function, but after we potentially read in the
- // compaction table.
+ // block in the function
insertArguments(F);
InsertedArguments = true;
}
ParseConstantPool(FunctionValues, FunctionTypes, true);
break;
- case BytecodeFormat::CompactionTableBlockID:
- ParseCompactionTable();
- break;
-
case BytecodeFormat::InstructionListBlockID: {
// Insert arguments into the value table before we parse the instruction
- // list for the function, but after we potentially read in the compaction
- // table.
+ // list for the function
if (!InsertedArguments) {
insertArguments(F);
InsertedArguments = true;
// Clear out function-level types...
FunctionTypes.clear();
- CompactionTypes.clear();
- CompactionValues.clear();
freeTable(FunctionValues);
if (Handler) Handler->handleFunctionEnd(F);
// Linkage, bit4+ = slot#
unsigned SlotNo = VarType >> 5;
unsigned LinkageID = (VarType >> 2) & 7;
+ unsigned VisibilityID = 0;
bool isConstant = VarType & 1;
bool hasInitializer = (VarType & 2) != 0;
unsigned Alignment = 0;
if (LinkageID == 3 && !hasInitializer) {
unsigned ExtWord = read_vbr_uint();
// The extension word has this format: bit 0 = has initializer, bit 1-3 =
- // linkage, bit 4-8 = alignment (log2), bits 10+ = future use.
+ // linkage, bit 4-8 = alignment (log2), bit 9 = has section,
+ // bits 10-12 = visibility, bits 13+ = future use.
hasInitializer = ExtWord & 1;
LinkageID = (ExtWord >> 1) & 7;
Alignment = (1 << ((ExtWord >> 4) & 31)) >> 1;
+ VisibilityID = (ExtWord >> 10) & 7;
if (ExtWord & (1 << 9)) // Has a section ID.
GlobalSectionID = read_vbr_uint();
Linkage = GlobalValue::InternalLinkage;
break;
}
-
+ GlobalValue::VisibilityTypes Visibility;
+ switch (VisibilityID) {
+ case 0: Visibility = GlobalValue::DefaultVisibility; break;
+ case 1: Visibility = GlobalValue::HiddenVisibility; break;
+ default:
+ error("Unknown visibility type: " + utostr(VisibilityID));
+ Visibility = GlobalValue::DefaultVisibility;
+ break;
+ }
+
const Type *Ty = getType(SlotNo);
if (!Ty)
error("Global has no type! SlotNo=" + utostr(SlotNo));
GlobalVariable *GV = new GlobalVariable(ElTy, isConstant, Linkage,
0, "", TheModule);
GV->setAlignment(Alignment);
+ GV->setVisibility(Visibility);
insertValue(GV, SlotNo, ModuleValues);
if (GlobalSectionID != 0)
// Notify handler about the global value.
if (Handler)
- Handler->handleGlobalVariable(ElTy, isConstant, Linkage, SlotNo,initSlot);
+ Handler->handleGlobalVariable(ElTy, isConstant, Linkage, Visibility,
+ SlotNo, initSlot);
// Get next item
VarType = read_vbr_uint();
if (Handler)
Handler->handleTargetTriple(triple);
+ // Read the data layout string and place into the module.
+ std::string datalayout = read_str();
+ TheModule->setDataLayout(datalayout);
+ // FIXME: Implement
+ // if (Handler)
+ // Handler->handleDataLayout(datalayout);
+
if (At != BlockEnd) {
// If the file has section info in it, read the section names now.
unsigned NumSections = read_vbr_uint();
/// Parse the version information and decode it by setting flags on the
/// Reader that enable backward compatibility of the reader.
void BytecodeReader::ParseVersionInfo() {
- unsigned Version = read_vbr_uint();
-
- // Unpack version number: low four bits are for flags, top bits = version
- Module::Endianness Endianness;
- Module::PointerSize PointerSize;
- Endianness = (Version & 1) ? Module::BigEndian : Module::LittleEndian;
- PointerSize = (Version & 2) ? Module::Pointer64 : Module::Pointer32;
-
- bool hasNoEndianness = Version & 4;
- bool hasNoPointerSize = Version & 8;
-
- RevisionNum = Version >> 4;
+ unsigned RevisionNum = read_vbr_uint();
// We don't provide backwards compatibility in the Reader any more. To
// upgrade, the user should use llvm-upgrade.
if (RevisionNum < 7)
error("Bytecode formats < 7 are no longer supported. Use llvm-upgrade.");
- if (hasNoEndianness) Endianness = Module::AnyEndianness;
- if (hasNoPointerSize) PointerSize = Module::AnyPointerSize;
-
- TheModule->setEndianness(Endianness);
- TheModule->setPointerSize(PointerSize);
-
- if (Handler) Handler->handleVersionInfo(RevisionNum, Endianness, PointerSize);
+ if (Handler) Handler->handleVersionInfo(RevisionNum);
}
/// Parse a whole module.