mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
Error Handling Cleanup:
- get rid of PARSE_ERROR macro - add error(std::string) function - use error(std::string) for all errors - make input dependent asserts call error(std::string) instead - ensure asserts are only for logic bugs, not input discrepancies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14729 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
011bed5ef8
commit
2439972a61
@ -29,13 +29,6 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
/// A convenience macro for handling parsing errors.
|
||||
#define PARSE_ERROR(inserters) { \
|
||||
std::ostringstream errormsg; \
|
||||
errormsg << inserters; \
|
||||
throw std::string(errormsg.str()); \
|
||||
}
|
||||
|
||||
/// @brief A class for maintaining the slot number definition
|
||||
/// as a placeholder for the actual definition.
|
||||
template<class SuperType>
|
||||
@ -55,6 +48,16 @@ struct ConstantPlaceHolderHelper : public ConstantExpr {
|
||||
|
||||
typedef PlaceholderDef<ConstantPlaceHolderHelper> ConstPHolder;
|
||||
|
||||
// Provide some details on error
|
||||
inline void BytecodeReader::error(std::string err) {
|
||||
err += " (Vers=" ;
|
||||
err += itostr(RevisionNum) ;
|
||||
err += ", Pos=" ;
|
||||
err += itostr(At-MemStart);
|
||||
err += ")";
|
||||
throw err;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Bytecode Reading Methods
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -67,7 +70,7 @@ inline bool BytecodeReader::moreInBlock() {
|
||||
/// Throw an error if we've read past the end of the current block
|
||||
inline void BytecodeReader::checkPastBlockEnd(const char * block_name) {
|
||||
if ( At > BlockEnd )
|
||||
PARSE_ERROR("Attempt to read past the end of " << block_name << " block.");
|
||||
error(std::string("Attempt to read past the end of ") + block_name + " block.");
|
||||
}
|
||||
|
||||
/// Align the buffer position to a 32 bit boundary
|
||||
@ -77,13 +80,13 @@ inline void BytecodeReader::align32() {
|
||||
if ( At > Save )
|
||||
if (Handler) Handler->handleAlignment( At - Save );
|
||||
if (At > BlockEnd)
|
||||
throw std::string("Ran out of data while aligning!");
|
||||
error("Ran out of data while aligning!");
|
||||
}
|
||||
|
||||
/// Read a whole unsigned integer
|
||||
inline unsigned BytecodeReader::read_uint() {
|
||||
if (At+4 > BlockEnd)
|
||||
throw std::string("Ran out of data reading uint!");
|
||||
error("Ran out of data reading uint!");
|
||||
At += 4;
|
||||
return At[-4] | (At[-3] << 8) | (At[-2] << 16) | (At[-1] << 24);
|
||||
}
|
||||
@ -96,7 +99,7 @@ inline unsigned BytecodeReader::read_vbr_uint() {
|
||||
|
||||
do {
|
||||
if (At == BlockEnd)
|
||||
throw std::string("Ran out of data reading vbr_uint!");
|
||||
error("Ran out of data reading vbr_uint!");
|
||||
Result |= (unsigned)((*At++) & 0x7F) << Shift;
|
||||
Shift += 7;
|
||||
} while (At[-1] & 0x80);
|
||||
@ -112,7 +115,7 @@ inline uint64_t BytecodeReader::read_vbr_uint64() {
|
||||
|
||||
do {
|
||||
if (At == BlockEnd)
|
||||
throw std::string("Ran out of data reading vbr_uint64!");
|
||||
error("Ran out of data reading vbr_uint64!");
|
||||
Result |= (uint64_t)((*At++) & 0x7F) << Shift;
|
||||
Shift += 7;
|
||||
} while (At[-1] & 0x80);
|
||||
@ -139,7 +142,7 @@ inline std::string BytecodeReader::read_str() {
|
||||
const unsigned char *OldAt = At;
|
||||
At += Size;
|
||||
if (At > BlockEnd) // Size invalid?
|
||||
throw std::string("Ran out of data reading a string!");
|
||||
error("Ran out of data reading a string!");
|
||||
return std::string((char*)OldAt, Size);
|
||||
}
|
||||
|
||||
@ -148,7 +151,7 @@ inline void BytecodeReader::read_data(void *Ptr, void *End) {
|
||||
unsigned char *Start = (unsigned char *)Ptr;
|
||||
unsigned Amount = (unsigned char *)End - Start;
|
||||
if (At+Amount > BlockEnd)
|
||||
throw std::string("Ran out of data!");
|
||||
error("Ran out of data!");
|
||||
std::copy(At, At+Amount, Start);
|
||||
At += Amount;
|
||||
}
|
||||
@ -159,7 +162,7 @@ inline void BytecodeReader::read_block(unsigned &Type, unsigned &Size) {
|
||||
Size = read_uint();
|
||||
BlockStart = At;
|
||||
if ( At + Size > BlockEnd )
|
||||
throw std::string("Attempt to size a block past end of memory");
|
||||
error("Attempt to size a block past end of memory");
|
||||
BlockEnd = At + Size;
|
||||
if (Handler) Handler->handleBlock( Type, BlockStart, Size );
|
||||
}
|
||||
@ -225,7 +228,7 @@ const Type *BytecodeReader::getType(unsigned ID) {
|
||||
|
||||
if (!CompactionTypes.empty()) {
|
||||
if (ID >= CompactionTypes.size())
|
||||
throw std::string("Type ID out of range for compaction table!");
|
||||
error("Type ID out of range for compaction table!");
|
||||
return CompactionTypes[ID];
|
||||
}
|
||||
|
||||
@ -238,7 +241,7 @@ const Type *BytecodeReader::getType(unsigned ID) {
|
||||
if (ID < FunctionTypes.size())
|
||||
return FunctionTypes[ID].get();
|
||||
|
||||
throw std::string("Illegal type reference!");
|
||||
error("Illegal type reference!");
|
||||
return Type::VoidTy;
|
||||
}
|
||||
|
||||
@ -246,18 +249,18 @@ const Type *BytecodeReader::getType(unsigned ID) {
|
||||
/// is both sanitized and not the "type type" of pre-1.3 bytecode.
|
||||
/// @see sanitizeTypeId
|
||||
inline const Type* BytecodeReader::getSanitizedType(unsigned& ID) {
|
||||
bool isTypeType = sanitizeTypeId(ID);
|
||||
assert(!isTypeType && "Invalid type id occurred");
|
||||
if ( sanitizeTypeId(ID) )
|
||||
error("Invalid type id encountered");
|
||||
return getType(ID);
|
||||
}
|
||||
|
||||
/// This method just saves some coding. It uses read_typeid to read
|
||||
/// in a sanitized type id, asserts that its not the type type, and
|
||||
/// in a sanitized type id, errors that its not the type type, and
|
||||
/// then calls getType to return the type value.
|
||||
inline const Type* BytecodeReader::readSanitizedType() {
|
||||
unsigned ID;
|
||||
bool isTypeType = read_typeid(ID);
|
||||
assert(!isTypeType && "Invalid type id occurred");
|
||||
if ( read_typeid(ID) )
|
||||
error( "Invalid type id encountered");
|
||||
return getType(ID);
|
||||
}
|
||||
|
||||
@ -273,7 +276,7 @@ unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
||||
find(CompactionTypes.begin(), CompactionTypes.end(), Ty);
|
||||
|
||||
if (I == CompactionTypes.end())
|
||||
throw std::string("Couldn't find type specified in compaction table!");
|
||||
error("Couldn't find type specified in compaction table!");
|
||||
return Type::FirstDerivedTyID + (&*I - &CompactionTypes[0]);
|
||||
}
|
||||
|
||||
@ -287,7 +290,7 @@ unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
||||
// Check the module level types now...
|
||||
I = find(ModuleTypes.begin(), ModuleTypes.end(), Ty);
|
||||
if (I == ModuleTypes.end())
|
||||
throw std::string("Didn't find type in ModuleTypes.");
|
||||
error("Didn't find type in ModuleTypes.");
|
||||
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
|
||||
}
|
||||
|
||||
@ -297,12 +300,13 @@ unsigned BytecodeReader::getTypeSlot(const Type *Ty) {
|
||||
const Type *BytecodeReader::getGlobalTableType(unsigned Slot) {
|
||||
if (Slot < Type::FirstDerivedTyID) {
|
||||
const Type *Ty = Type::getPrimitiveType((Type::TypeID)Slot);
|
||||
assert(Ty && "Not a primitive type ID?");
|
||||
if ( ! Ty )
|
||||
error("Not a primitive type ID?");
|
||||
return Ty;
|
||||
}
|
||||
Slot -= Type::FirstDerivedTyID;
|
||||
if (Slot >= ModuleTypes.size())
|
||||
throw std::string("Illegal compaction table type reference!");
|
||||
error("Illegal compaction table type reference!");
|
||||
return ModuleTypes[Slot];
|
||||
}
|
||||
|
||||
@ -314,7 +318,7 @@ unsigned BytecodeReader::getGlobalTableTypeSlot(const Type *Ty) {
|
||||
TypeListTy::iterator I = find(ModuleTypes.begin(),
|
||||
ModuleTypes.end(), Ty);
|
||||
if (I == ModuleTypes.end())
|
||||
throw std::string("Didn't find type in ModuleTypes.");
|
||||
error("Didn't find type in ModuleTypes.");
|
||||
return Type::FirstDerivedTyID + (&*I - &ModuleTypes[0]);
|
||||
}
|
||||
|
||||
@ -389,10 +393,11 @@ Value* BytecodeReader::getGlobalTableValue(const Type *Ty, unsigned SlotNo) {
|
||||
|
||||
if (TyID >= ModuleValues.size() || ModuleValues[TyID] == 0 ||
|
||||
SlotNo >= ModuleValues[TyID]->size()) {
|
||||
PARSE_ERROR("Corrupt compaction table entry!"
|
||||
<< TyID << ", " << SlotNo << ": " << ModuleValues.size() << ", "
|
||||
<< (void*)ModuleValues[TyID] << ", "
|
||||
<< ModuleValues[TyID]->size() << "\n");
|
||||
error("Corrupt compaction table entry!"
|
||||
+ utostr(TyID) + ", " + utostr(SlotNo) + ": "
|
||||
+ utostr(ModuleValues.size()) + ", "
|
||||
+ utohexstr(int((void*)ModuleValues[TyID])) + ", "
|
||||
+ utostr(ModuleValues[TyID]->size()) );
|
||||
}
|
||||
return ModuleValues[TyID]->getOperand(SlotNo);
|
||||
}
|
||||
@ -411,7 +416,7 @@ Constant* BytecodeReader::getConstantValue(unsigned TypeSlot, unsigned Slot) {
|
||||
// to infest bytecode files.
|
||||
return ConstantPointerRef::get(GV);
|
||||
else
|
||||
throw std::string("Reference of a value is expected to be a constant!");
|
||||
error("Reference of a value is expected to be a constant!");
|
||||
|
||||
const Type *Ty = getType(TypeSlot);
|
||||
std::pair<const Type*, unsigned> Key(Ty, Slot);
|
||||
@ -534,7 +539,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
Oprnds.resize(NumOprnds);
|
||||
|
||||
if (NumOprnds == 0)
|
||||
throw std::string("Zero-argument instruction found; this is invalid.");
|
||||
error("Zero-argument instruction found; this is invalid.");
|
||||
|
||||
for (unsigned i = 0; i != NumOprnds; ++i)
|
||||
Oprnds[i] = read_vbr_uint();
|
||||
@ -560,7 +565,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
switch (Opcode) {
|
||||
default:
|
||||
if (Result == 0)
|
||||
throw std::string("Illegal instruction read!");
|
||||
error("Illegal instruction read!");
|
||||
break;
|
||||
case Instruction::VAArg:
|
||||
Result = new VAArgInst(getValue(iType, Oprnds[0]),
|
||||
@ -581,7 +586,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
break;
|
||||
case Instruction::PHI: {
|
||||
if (Oprnds.size() == 0 || (Oprnds.size() & 1))
|
||||
throw std::string("Invalid phi node encountered!");
|
||||
error("Invalid phi node encountered!");
|
||||
|
||||
PHINode *PN = new PHINode(InstTy);
|
||||
PN->op_reserve(Oprnds.size());
|
||||
@ -603,7 +608,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
else if (Oprnds.size() == 1)
|
||||
Result = new ReturnInst(getValue(iType, Oprnds[0]));
|
||||
else
|
||||
throw std::string("Unrecognized instruction!");
|
||||
error("Unrecognized instruction!");
|
||||
break;
|
||||
|
||||
case Instruction::Br:
|
||||
@ -613,11 +618,11 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
Result = new BranchInst(getBasicBlock(Oprnds[0]),
|
||||
getBasicBlock(Oprnds[1]), getValue(Type::BoolTyID , Oprnds[2]));
|
||||
else
|
||||
throw std::string("Invalid number of operands for a 'br' instruction!");
|
||||
error("Invalid number of operands for a 'br' instruction!");
|
||||
break;
|
||||
case Instruction::Switch: {
|
||||
if (Oprnds.size() & 1)
|
||||
throw std::string("Switch statement with odd number of arguments!");
|
||||
error("Switch statement with odd number of arguments!");
|
||||
|
||||
SwitchInst *I = new SwitchInst(getValue(iType, Oprnds[0]),
|
||||
getBasicBlock(Oprnds[1]));
|
||||
@ -630,15 +635,15 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
|
||||
case Instruction::Call: {
|
||||
if (Oprnds.size() == 0)
|
||||
throw std::string("Invalid call instruction encountered!");
|
||||
error("Invalid call instruction encountered!");
|
||||
|
||||
Value *F = getValue(iType, Oprnds[0]);
|
||||
|
||||
// Check to make sure we have a pointer to function type
|
||||
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
||||
if (PTy == 0) throw std::string("Call to non function pointer value!");
|
||||
if (PTy == 0) error("Call to non function pointer value!");
|
||||
const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
|
||||
if (FTy == 0) throw std::string("Call to non function pointer value!");
|
||||
if (FTy == 0) error("Call to non function pointer value!");
|
||||
|
||||
std::vector<Value *> Params;
|
||||
if (!FTy->isVarArg()) {
|
||||
@ -646,17 +651,17 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
|
||||
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
|
||||
if (It == FTy->param_end())
|
||||
throw std::string("Invalid call instruction!");
|
||||
error("Invalid call instruction!");
|
||||
Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
|
||||
}
|
||||
if (It != FTy->param_end())
|
||||
throw std::string("Invalid call instruction!");
|
||||
error("Invalid call instruction!");
|
||||
} else {
|
||||
Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
|
||||
|
||||
unsigned FirstVariableOperand;
|
||||
if (Oprnds.size() < FTy->getNumParams())
|
||||
throw std::string("Call instruction missing operands!");
|
||||
error("Call instruction missing operands!");
|
||||
|
||||
// Read all of the fixed arguments
|
||||
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
|
||||
@ -665,7 +670,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
FirstVariableOperand = FTy->getNumParams();
|
||||
|
||||
if ((Oprnds.size()-FirstVariableOperand) & 1) // Must be pairs of type/value
|
||||
throw std::string("Invalid call instruction!");
|
||||
error("Invalid call instruction!");
|
||||
|
||||
for (unsigned i = FirstVariableOperand, e = Oprnds.size();
|
||||
i != e; i += 2)
|
||||
@ -677,16 +682,16 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
}
|
||||
case Instruction::Invoke: {
|
||||
if (Oprnds.size() < 3)
|
||||
throw std::string("Invalid invoke instruction!");
|
||||
error("Invalid invoke instruction!");
|
||||
Value *F = getValue(iType, Oprnds[0]);
|
||||
|
||||
// Check to make sure we have a pointer to function type
|
||||
const PointerType *PTy = dyn_cast<PointerType>(F->getType());
|
||||
if (PTy == 0)
|
||||
throw std::string("Invoke to non function pointer value!");
|
||||
error("Invoke to non function pointer value!");
|
||||
const FunctionType *FTy = dyn_cast<FunctionType>(PTy->getElementType());
|
||||
if (FTy == 0)
|
||||
throw std::string("Invoke to non function pointer value!");
|
||||
error("Invoke to non function pointer value!");
|
||||
|
||||
std::vector<Value *> Params;
|
||||
BasicBlock *Normal, *Except;
|
||||
@ -698,11 +703,11 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
FunctionType::param_iterator It = FTy->param_begin();
|
||||
for (unsigned i = 3, e = Oprnds.size(); i != e; ++i) {
|
||||
if (It == FTy->param_end())
|
||||
throw std::string("Invalid invoke instruction!");
|
||||
error("Invalid invoke instruction!");
|
||||
Params.push_back(getValue(getTypeSlot(*It++), Oprnds[i]));
|
||||
}
|
||||
if (It != FTy->param_end())
|
||||
throw std::string("Invalid invoke instruction!");
|
||||
error("Invalid invoke instruction!");
|
||||
} else {
|
||||
Oprnds.erase(Oprnds.begin(), Oprnds.begin()+1);
|
||||
|
||||
@ -715,7 +720,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
Oprnds[i]));
|
||||
|
||||
if (Oprnds.size()-FirstVariableArgument & 1) // Must be type/value pairs
|
||||
throw std::string("Invalid invoke instruction!");
|
||||
error("Invalid invoke instruction!");
|
||||
|
||||
for (unsigned i = FirstVariableArgument; i < Oprnds.size(); i += 2)
|
||||
Params.push_back(getValue(Oprnds[i], Oprnds[i+1]));
|
||||
@ -726,9 +731,9 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
}
|
||||
case Instruction::Malloc:
|
||||
if (Oprnds.size() > 2)
|
||||
throw std::string("Invalid malloc instruction!");
|
||||
error("Invalid malloc instruction!");
|
||||
if (!isa<PointerType>(InstTy))
|
||||
throw std::string("Invalid malloc instruction!");
|
||||
error("Invalid malloc instruction!");
|
||||
|
||||
Result = new MallocInst(cast<PointerType>(InstTy)->getElementType(),
|
||||
Oprnds.size() ? getValue(Type::UIntTyID,
|
||||
@ -737,9 +742,9 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
|
||||
case Instruction::Alloca:
|
||||
if (Oprnds.size() > 2)
|
||||
throw std::string("Invalid alloca instruction!");
|
||||
error("Invalid alloca instruction!");
|
||||
if (!isa<PointerType>(InstTy))
|
||||
throw std::string("Invalid alloca instruction!");
|
||||
error("Invalid alloca instruction!");
|
||||
|
||||
Result = new AllocaInst(cast<PointerType>(InstTy)->getElementType(),
|
||||
Oprnds.size() ? getValue(Type::UIntTyID,
|
||||
@ -747,12 +752,12 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
break;
|
||||
case Instruction::Free:
|
||||
if (!isa<PointerType>(InstTy))
|
||||
throw std::string("Invalid free instruction!");
|
||||
error("Invalid free instruction!");
|
||||
Result = new FreeInst(getValue(iType, Oprnds[0]));
|
||||
break;
|
||||
case Instruction::GetElementPtr: {
|
||||
if (Oprnds.size() == 0 || !isa<PointerType>(InstTy))
|
||||
throw std::string("Invalid getelementptr instruction!");
|
||||
error("Invalid getelementptr instruction!");
|
||||
|
||||
std::vector<Value*> Idx;
|
||||
|
||||
@ -760,7 +765,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
for (unsigned i = 1, e = Oprnds.size(); i != e; ++i) {
|
||||
const CompositeType *TopTy = dyn_cast_or_null<CompositeType>(NextTy);
|
||||
if (!TopTy)
|
||||
throw std::string("Invalid getelementptr instruction!");
|
||||
error("Invalid getelementptr instruction!");
|
||||
|
||||
unsigned ValIdx = Oprnds[i];
|
||||
unsigned IdxTy = 0;
|
||||
@ -801,14 +806,14 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
case 62: // volatile load
|
||||
case Instruction::Load:
|
||||
if (Oprnds.size() != 1 || !isa<PointerType>(InstTy))
|
||||
throw std::string("Invalid load instruction!");
|
||||
error("Invalid load instruction!");
|
||||
Result = new LoadInst(getValue(iType, Oprnds[0]), "", Opcode == 62);
|
||||
break;
|
||||
|
||||
case 63: // volatile store
|
||||
case Instruction::Store: {
|
||||
if (!isa<PointerType>(InstTy) || Oprnds.size() != 2)
|
||||
throw std::string("Invalid store instruction!");
|
||||
error("Invalid store instruction!");
|
||||
|
||||
Value *Ptr = getValue(iType, Oprnds[1]);
|
||||
const Type *ValTy = cast<PointerType>(Ptr->getType())->getElementType();
|
||||
@ -818,7 +823,7 @@ void BytecodeReader::ParseInstruction(std::vector<unsigned> &Oprnds,
|
||||
}
|
||||
case Instruction::Unwind:
|
||||
if (Oprnds.size() != 0)
|
||||
throw std::string("Invalid unwind instruction!");
|
||||
error("Invalid unwind instruction!");
|
||||
Result = new UnwindInst();
|
||||
break;
|
||||
} // end switch(Opcode)
|
||||
@ -902,7 +907,7 @@ unsigned BytecodeReader::ParseInstructionList(Function* F) {
|
||||
ParseInstruction(Args, BB);
|
||||
|
||||
if (!BB->getTerminator())
|
||||
throw std::string("Non-terminated basic block found!");
|
||||
error("Non-terminated basic block found!");
|
||||
|
||||
if (Handler) Handler->handleBasicBlockEnd( BlockNo-1 );
|
||||
}
|
||||
@ -958,7 +963,7 @@ void BytecodeReader::ParseSymbolTable(Function *CurrentFunction,
|
||||
if ( isTypeType ) {
|
||||
const Type* T = getType(slot);
|
||||
if ( T == 0 )
|
||||
PARSE_ERROR("Failed type look-up for name '" << Name << "'");
|
||||
error("Failed type look-up for name '" + Name + "'");
|
||||
ST->insert(Name, T);
|
||||
continue; // code below must be short circuited
|
||||
} else {
|
||||
@ -970,7 +975,7 @@ void BytecodeReader::ParseSymbolTable(Function *CurrentFunction,
|
||||
V = getValue(Typ, slot, false); // Find mapping...
|
||||
}
|
||||
if (V == 0)
|
||||
PARSE_ERROR("Failed value look-up for name '" << Name << "'");
|
||||
error("Failed value look-up for name '" + Name + "'");
|
||||
V->setName(Name, ST);
|
||||
}
|
||||
}
|
||||
@ -983,8 +988,8 @@ void BytecodeReader::ParseSymbolTable(Function *CurrentFunction,
|
||||
void BytecodeReader::ParseCompactionTypes( unsigned NumEntries ) {
|
||||
for (unsigned i = 0; i != NumEntries; ++i) {
|
||||
unsigned TypeSlot = 0;
|
||||
bool isTypeType = read_typeid(TypeSlot);
|
||||
assert(!isTypeType && "Invalid type in compaction table: type type");
|
||||
if ( read_typeid(TypeSlot) )
|
||||
error("Invalid type in compaction table: type type");
|
||||
const Type *Typ = getGlobalTableType(TypeSlot);
|
||||
CompactionTypes.push_back(Typ);
|
||||
if (Handler) Handler->handleCompactionTableType( i, TypeSlot, Typ );
|
||||
@ -1028,7 +1033,7 @@ void BytecodeReader::ParseCompactionTable() {
|
||||
CompactionValues.resize(Ty+1);
|
||||
|
||||
if (!CompactionValues[Ty].empty())
|
||||
throw std::string("Compaction table plane contains multiple entries!");
|
||||
error("Compaction table plane contains multiple entries!");
|
||||
|
||||
if (Handler) Handler->handleCompactionTablePlane( Ty, NumEntries );
|
||||
|
||||
@ -1049,8 +1054,8 @@ void BytecodeReader::ParseCompactionTable() {
|
||||
// Parse a single type constant.
|
||||
const Type *BytecodeReader::ParseTypeConstant() {
|
||||
unsigned PrimType = 0;
|
||||
bool isTypeType = read_typeid(PrimType);
|
||||
assert(!isTypeType && "Invalid type (type type) in type constants!");
|
||||
if ( read_typeid(PrimType) )
|
||||
error("Invalid type (type type) in type constants!");
|
||||
|
||||
const Type *Result = 0;
|
||||
if ((Result = Type::getPrimitiveType((Type::TypeID)PrimType)))
|
||||
@ -1081,12 +1086,13 @@ const Type *BytecodeReader::ParseTypeConstant() {
|
||||
case Type::StructTyID: {
|
||||
std::vector<const Type*> Elements;
|
||||
unsigned Typ = 0;
|
||||
bool isTypeType = read_typeid(Typ);
|
||||
assert(!isTypeType && "Invalid element type (type type) for structure!");
|
||||
if ( read_typeid(Typ) )
|
||||
error("Invalid element type (type type) for structure!");
|
||||
|
||||
while (Typ) { // List is terminated by void/0 typeid
|
||||
Elements.push_back(getType(Typ));
|
||||
bool isTypeType = read_typeid(Typ);
|
||||
assert(!isTypeType && "Invalid element type (type type) for structure!");
|
||||
if ( read_typeid(Typ) )
|
||||
error("Invalid element type (type type) for structure!");
|
||||
}
|
||||
|
||||
Result = StructType::get(Elements);
|
||||
@ -1103,8 +1109,7 @@ const Type *BytecodeReader::ParseTypeConstant() {
|
||||
}
|
||||
|
||||
default:
|
||||
PARSE_ERROR("Don't know how to deserialize primitive type"
|
||||
<< PrimType << "\n");
|
||||
error("Don't know how to deserialize primitive type " + utostr(PrimType));
|
||||
break;
|
||||
}
|
||||
if (Handler) Handler->handleType( Result );
|
||||
@ -1136,7 +1141,7 @@ void BytecodeReader::ParseTypeConstants(TypeListTy &Tab, unsigned NumEntries){
|
||||
const Type* NewTy = ParseTypeConstant();
|
||||
const Type* OldTy = Tab[i].get();
|
||||
if (NewTy == 0)
|
||||
throw std::string("Couldn't parse type!");
|
||||
error("Couldn't parse type!");
|
||||
|
||||
// Don't directly push the new type on the Tab. Instead we want to replace
|
||||
// the opaque type we previously inserted with the new concrete value. This
|
||||
@ -1171,8 +1176,8 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
for (unsigned i = 0; i != isExprNumArgs; ++i) {
|
||||
unsigned ArgValSlot = read_vbr_uint();
|
||||
unsigned ArgTypeSlot = 0;
|
||||
bool isTypeType = read_typeid(ArgTypeSlot);
|
||||
assert(!isTypeType && "Invalid argument type (type type) for constant value");
|
||||
if ( read_typeid(ArgTypeSlot) )
|
||||
error("Invalid argument type (type type) for constant value");
|
||||
|
||||
// Get the arg value from its slot if it exists, otherwise a placeholder
|
||||
ArgVec.push_back(getConstantValue(ArgTypeSlot, ArgValSlot));
|
||||
@ -1195,7 +1200,7 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
for (unsigned i = 0; GTI != E; ++GTI, ++i)
|
||||
if (isa<StructType>(*GTI)) {
|
||||
if (IdxList[i]->getType() != Type::UByteTy)
|
||||
throw std::string("Invalid index for getelementptr!");
|
||||
error("Invalid index for getelementptr!");
|
||||
IdxList[i] = ConstantExpr::getCast(IdxList[i], Type::UIntTy);
|
||||
}
|
||||
}
|
||||
@ -1222,7 +1227,7 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
case Type::BoolTyID: {
|
||||
unsigned Val = read_vbr_uint();
|
||||
if (Val != 0 && Val != 1)
|
||||
throw std::string("Invalid boolean value read.");
|
||||
error("Invalid boolean value read.");
|
||||
Constant* Result = ConstantBool::get(Val == 1);
|
||||
if (Handler) Handler->handleConstantValue(Result);
|
||||
return Result;
|
||||
@ -1233,7 +1238,7 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
case Type::UIntTyID: {
|
||||
unsigned Val = read_vbr_uint();
|
||||
if (!ConstantUInt::isValueValidForType(Ty, Val))
|
||||
throw std::string("Invalid unsigned byte/short/int read.");
|
||||
error("Invalid unsigned byte/short/int read.");
|
||||
Constant* Result = ConstantUInt::get(Ty, Val);
|
||||
if (Handler) Handler->handleConstantValue(Result);
|
||||
return Result;
|
||||
@ -1251,7 +1256,7 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
case Type::LongTyID:
|
||||
int64_t Val = read_vbr_int64();
|
||||
if (!ConstantSInt::isValueValidForType(Ty, Val))
|
||||
throw std::string("Invalid signed byte/short/int/long read.");
|
||||
error("Invalid signed byte/short/int/long read.");
|
||||
Constant* Result = ConstantSInt::get(Ty, Val);
|
||||
if (Handler) Handler->handleConstantValue(Result);
|
||||
return Result;
|
||||
@ -1310,9 +1315,9 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
GlobalValue *GV;
|
||||
if (Val) {
|
||||
if (!(GV = dyn_cast<GlobalValue>(Val)))
|
||||
throw std::string("Value of ConstantPointerRef not in ValueTable!");
|
||||
error("Value of ConstantPointerRef not in ValueTable!");
|
||||
} else {
|
||||
throw std::string("Forward references are not allowed here.");
|
||||
error("Forward references are not allowed here.");
|
||||
}
|
||||
|
||||
Constant* Result = ConstantPointerRef::get(GV);
|
||||
@ -1321,10 +1326,11 @@ Constant *BytecodeReader::ParseConstantValue( unsigned TypeID) {
|
||||
}
|
||||
|
||||
default:
|
||||
PARSE_ERROR("Don't know how to deserialize constant value of type '"+
|
||||
error("Don't know how to deserialize constant value of type '" +
|
||||
Ty->getDescription());
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Resolve references for constants. This function resolves the forward
|
||||
@ -1346,16 +1352,16 @@ void BytecodeReader::ResolveReferencesToConstant(Constant *NewV, unsigned Slot){
|
||||
void BytecodeReader::ParseStringConstants(unsigned NumEntries, ValueTable &Tab){
|
||||
for (; NumEntries; --NumEntries) {
|
||||
unsigned Typ = 0;
|
||||
bool isTypeType = read_typeid(Typ);
|
||||
assert(!isTypeType && "Invalid type (type type) for string constant");
|
||||
if ( read_typeid(Typ) )
|
||||
error("Invalid type (type type) for string constant");
|
||||
const Type *Ty = getType(Typ);
|
||||
if (!isa<ArrayType>(Ty))
|
||||
throw std::string("String constant data invalid!");
|
||||
error("String constant data invalid!");
|
||||
|
||||
const ArrayType *ATy = cast<ArrayType>(Ty);
|
||||
if (ATy->getElementType() != Type::SByteTy &&
|
||||
ATy->getElementType() != Type::UByteTy)
|
||||
throw std::string("String constant data invalid!");
|
||||
error("String constant data invalid!");
|
||||
|
||||
// Read character data. The type tells us how long the string is.
|
||||
char Data[ATy->getNumElements()];
|
||||
@ -1442,7 +1448,7 @@ void BytecodeReader::ParseFunctionBody(Function* F ) {
|
||||
case 3: Linkage = GlobalValue::InternalLinkage; break;
|
||||
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
|
||||
default:
|
||||
throw std::string("Invalid linkage type for Function.");
|
||||
error("Invalid linkage type for Function.");
|
||||
Linkage = GlobalValue::InternalLinkage;
|
||||
break;
|
||||
}
|
||||
@ -1501,7 +1507,7 @@ void BytecodeReader::ParseFunctionBody(Function* F ) {
|
||||
}
|
||||
|
||||
if (BlockNum)
|
||||
throw std::string("Already parsed basic blocks!");
|
||||
error("Already parsed basic blocks!");
|
||||
BlockNum = ParseInstructionList(F);
|
||||
break;
|
||||
}
|
||||
@ -1513,7 +1519,7 @@ void BytecodeReader::ParseFunctionBody(Function* F ) {
|
||||
default:
|
||||
At += Size;
|
||||
if (OldAt > At)
|
||||
throw std::string("Wrapped around reading bytecode.");
|
||||
error("Wrapped around reading bytecode.");
|
||||
break;
|
||||
}
|
||||
BlockEnd = MyEnd;
|
||||
@ -1524,7 +1530,7 @@ void BytecodeReader::ParseFunctionBody(Function* F ) {
|
||||
|
||||
// Make sure there were no references to non-existant basic blocks.
|
||||
if (BlockNum != ParsedBasicBlocks.size())
|
||||
throw std::string("Illegal basic block operand reference");
|
||||
error("Illegal basic block operand reference");
|
||||
|
||||
ParsedBasicBlocks.clear();
|
||||
|
||||
@ -1580,7 +1586,7 @@ void BytecodeReader::ParseFunctionBody(Function* F ) {
|
||||
/// ParseAllFunctionBodies to get handler events for the functions.
|
||||
void BytecodeReader::ParseFunctionLazily() {
|
||||
if (FunctionSignatureList.empty())
|
||||
throw std::string("FunctionSignatureList empty!");
|
||||
error("FunctionSignatureList empty!");
|
||||
|
||||
Function *Func = FunctionSignatureList.back();
|
||||
FunctionSignatureList.pop_back();
|
||||
@ -1604,13 +1610,13 @@ void BytecodeReader::ParseFunction(Function* Func) {
|
||||
|
||||
// Make sure we found it
|
||||
if ( Fi == LazyFunctionLoadMap.end() ) {
|
||||
PARSE_ERROR("Unrecognized function of type " << Func->getType()->getDescription());
|
||||
error("Unrecognized function of type " + Func->getType()->getDescription());
|
||||
return;
|
||||
}
|
||||
|
||||
BlockStart = At = Fi->second.Buf;
|
||||
BlockEnd = Fi->second.EndBuf;
|
||||
assert(Fi->first == Func);
|
||||
assert(Fi->first == Func && "Found wrong function?");
|
||||
|
||||
LazyFunctionLoadMap.erase(Fi);
|
||||
|
||||
@ -1660,8 +1666,8 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
||||
// VarType Fields: bit0 = isConstant, bit1 = hasInitializer, bit2,3,4 =
|
||||
// Linkage, bit4+ = slot#
|
||||
unsigned SlotNo = VarType >> 5;
|
||||
bool isTypeType = sanitizeTypeId(SlotNo);
|
||||
assert(!isTypeType && "Invalid type (type type) for global var!");
|
||||
if ( sanitizeTypeId(SlotNo) )
|
||||
error("Invalid type (type type) for global var!");
|
||||
unsigned LinkageID = (VarType >> 2) & 7;
|
||||
bool isConstant = VarType & 1;
|
||||
bool hasInitializer = VarType & 2;
|
||||
@ -1674,18 +1680,18 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
||||
case 3: Linkage = GlobalValue::InternalLinkage; break;
|
||||
case 4: Linkage = GlobalValue::LinkOnceLinkage; break;
|
||||
default:
|
||||
PARSE_ERROR("Unknown linkage type: " << LinkageID);
|
||||
error("Unknown linkage type: " + utostr(LinkageID));
|
||||
Linkage = GlobalValue::InternalLinkage;
|
||||
break;
|
||||
}
|
||||
|
||||
const Type *Ty = getType(SlotNo);
|
||||
if ( !Ty ) {
|
||||
PARSE_ERROR("Global has no type! SlotNo=" << SlotNo);
|
||||
error("Global has no type! SlotNo=" + utostr(SlotNo));
|
||||
}
|
||||
|
||||
if ( !isa<PointerType>(Ty)) {
|
||||
PARSE_ERROR("Global not a pointer type! Ty= " << Ty->getDescription());
|
||||
error("Global not a pointer type! Ty= " + Ty->getDescription());
|
||||
}
|
||||
|
||||
const Type *ElTy = cast<PointerType>(Ty)->getElementType();
|
||||
@ -1710,14 +1716,15 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
||||
|
||||
// Read the function objects for all of the functions that are coming
|
||||
unsigned FnSignature = 0;
|
||||
bool isTypeType = read_typeid(FnSignature);
|
||||
assert(!isTypeType && "Invalid function type (type type) found");
|
||||
if ( read_typeid(FnSignature) )
|
||||
error("Invalid function type (type type) found");
|
||||
|
||||
while (FnSignature != Type::VoidTyID) { // List is terminated by Void
|
||||
const Type *Ty = getType(FnSignature);
|
||||
if (!isa<PointerType>(Ty) ||
|
||||
!isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
|
||||
PARSE_ERROR( "Function not a pointer to function type! Ty = " +
|
||||
Ty->getDescription());
|
||||
error("Function not a pointer to function type! Ty = " +
|
||||
Ty->getDescription());
|
||||
// FIXME: what should Ty be if handler continues?
|
||||
}
|
||||
|
||||
@ -1736,8 +1743,8 @@ void BytecodeReader::ParseModuleGlobalInfo() {
|
||||
if (Handler) Handler->handleFunctionDeclaration(Func);
|
||||
|
||||
// Get Next function signature
|
||||
isTypeType = read_typeid(FnSignature);
|
||||
assert(!isTypeType && "Invalid function type (type type) found");
|
||||
if ( read_typeid(FnSignature) )
|
||||
error("Invalid function type (type type) found");
|
||||
}
|
||||
|
||||
if (hasInconsistentModuleGlobalInfo)
|
||||
@ -1806,7 +1813,7 @@ void BytecodeReader::ParseVersionInfo() {
|
||||
break;
|
||||
|
||||
default:
|
||||
PARSE_ERROR("Unknown bytecode version number: " << RevisionNum);
|
||||
error("Unknown bytecode version number: " + itostr(RevisionNum));
|
||||
}
|
||||
|
||||
if (hasNoEndianness) Endianness = Module::AnyEndianness;
|
||||
@ -1836,7 +1843,7 @@ void BytecodeReader::ParseModule() {
|
||||
|
||||
case BytecodeFormat::GlobalTypePlane:
|
||||
if ( SeenGlobalTypePlane )
|
||||
throw std::string("Two GlobalTypePlane Blocks Encountered!");
|
||||
error("Two GlobalTypePlane Blocks Encountered!");
|
||||
|
||||
ParseGlobalTypes();
|
||||
SeenGlobalTypePlane = true;
|
||||
@ -1844,7 +1851,7 @@ void BytecodeReader::ParseModule() {
|
||||
|
||||
case BytecodeFormat::ModuleGlobalInfo:
|
||||
if ( SeenModuleGlobalInfo )
|
||||
throw std::string("Two ModuleGlobalInfo Blocks Encountered!");
|
||||
error("Two ModuleGlobalInfo Blocks Encountered!");
|
||||
ParseModuleGlobalInfo();
|
||||
SeenModuleGlobalInfo = true;
|
||||
break;
|
||||
@ -1864,7 +1871,7 @@ void BytecodeReader::ParseModule() {
|
||||
default:
|
||||
At += Size;
|
||||
if (OldAt > At) {
|
||||
PARSE_ERROR("Unexpected Block of Type" << Type << "encountered!" );
|
||||
error("Unexpected Block of Type #" + utostr(Type) + " encountered!" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1886,18 +1893,17 @@ void BytecodeReader::ParseModule() {
|
||||
unsigned TypeSlot = getTypeSlot(GVType->getElementType());
|
||||
if (Constant *CV = getConstantValue(TypeSlot, Slot)) {
|
||||
if (GV->hasInitializer())
|
||||
throw std::string("Global *already* has an initializer?!");
|
||||
error("Global *already* has an initializer?!");
|
||||
if (Handler) Handler->handleGlobalInitializer(GV,CV);
|
||||
GV->setInitializer(CV);
|
||||
} else
|
||||
throw std::string("Cannot find initializer value.");
|
||||
error("Cannot find initializer value.");
|
||||
}
|
||||
|
||||
/// Make sure we pulled them all out. If we didn't then there's a declaration
|
||||
/// but a missing body. That's not allowed.
|
||||
if (!FunctionSignatureList.empty())
|
||||
throw std::string(
|
||||
"Function declared, but bytecode stream ended before definition");
|
||||
error("Function declared, but bytecode stream ended before definition");
|
||||
}
|
||||
|
||||
/// This function completely parses a bytecode buffer given by the \p Buf
|
||||
@ -1919,7 +1925,7 @@ void BytecodeReader::ParseBytecode(
|
||||
// Read and check signature...
|
||||
unsigned Sig = read_uint();
|
||||
if (Sig != ('l' | ('l' << 8) | ('v' << 16) | ('m' << 24))) {
|
||||
PARSE_ERROR("Invalid bytecode signature: " << Sig);
|
||||
error("Invalid bytecode signature: " + utostr(Sig));
|
||||
}
|
||||
|
||||
|
||||
@ -1930,12 +1936,12 @@ void BytecodeReader::ParseBytecode(
|
||||
unsigned Type, Size;
|
||||
read_block(Type, Size);
|
||||
if ( Type != BytecodeFormat::Module ) {
|
||||
PARSE_ERROR("Expected Module Block! At: " << unsigned(intptr_t(At))
|
||||
<< ", Type:" << Type << ", Size:" << Size);
|
||||
error("Expected Module Block! Type:" + utostr(Type) + ", Size:"
|
||||
+ utostr(Size));
|
||||
}
|
||||
if ( At + Size != MemEnd ) {
|
||||
PARSE_ERROR("Invalid Top Level Block Length! At: "
|
||||
<< unsigned(intptr_t(At)) << ", Type:" << Type << ", Size:" << Size);
|
||||
error("Invalid Top Level Block Length! Type:" + utostr(Type)
|
||||
+ ", Size:" + utostr(Size));
|
||||
}
|
||||
|
||||
// Parse the module contents
|
||||
@ -1943,7 +1949,7 @@ void BytecodeReader::ParseBytecode(
|
||||
|
||||
// Check for missing functions
|
||||
if ( hasFunctions() )
|
||||
throw std::string("Function expected, but bytecode stream ended!");
|
||||
error("Function expected, but bytecode stream ended!");
|
||||
|
||||
// Process all the function bodies now, if requested
|
||||
if ( processFunctions )
|
||||
|
@ -405,6 +405,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
inline void error(std::string errmsg);
|
||||
|
||||
BytecodeReader(const BytecodeReader &); // DO NOT IMPLEMENT
|
||||
void operator=(const BytecodeReader &); // DO NOT IMPLEMENT
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user