read basic constants: null, undef, integers <= 64bits

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36389 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-04-24 03:30:34 +00:00
parent 631a8ed3ff
commit e16504eb4e
2 changed files with 80 additions and 2 deletions

View File

@ -13,6 +13,7 @@
#include "BitcodeReader.h"
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/ADT/SmallString.h"
@ -303,6 +304,78 @@ bool BitcodeReader::ParseValueSymbolTable(BitstreamReader &Stream) {
}
}
bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
if (Stream.EnterSubBlock())
return Error("Malformed block record");
SmallVector<uint64_t, 64> Record;
// Read all the records for this value table.
const Type *CurTy = Type::Int32Ty;
while (1) {
unsigned Code = Stream.ReadCode();
if (Code == bitc::END_BLOCK) {
// If there are global var inits to process, do so now.
if (!GlobalInits.empty()) {
while (!GlobalInits.empty()) {
unsigned ValID = GlobalInits.back().second;
if (ValID >= ValueList.size())
return Error("Invalid value ID for global var init!");
if (Constant *C = dyn_cast<Constant>(ValueList[ValID]))
GlobalInits.back().first->setInitializer(C);
else
return Error("Global variable initializer is not a constant!");
GlobalInits.pop_back();
}
}
return Stream.ReadBlockEnd();
}
if (Code == bitc::ENTER_SUBBLOCK) {
// No known subblocks, always skip them.
Stream.ReadSubBlockID();
if (Stream.SkipBlock())
return Error("Malformed block record");
continue;
}
if (Code == bitc::DEFINE_ABBREV) {
Stream.ReadAbbrevRecord();
continue;
}
// Read a record.
Record.clear();
Value *V = 0;
switch (Stream.ReadRecord(Code, Record)) {
default: // Default behavior: unknown constant
case bitc::CST_CODE_UNDEF: // UNDEF
V = UndefValue::get(CurTy);
break;
case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid]
if (Record.empty())
return Error("Malformed CST_SETTYPE record");
if (Record[0] >= TypeList.size())
return Error("Invalid Type ID in CST_SETTYPE record");
CurTy = TypeList[Record[0]];
continue;
case bitc::CST_CODE_NULL: // NULL
V = Constant::getNullValue(CurTy);
break;
case bitc::CST_CODE_INTEGER: // INTEGER: [intval]
if (!isa<IntegerType>(CurTy))
return Error("Invalid type for CST_INTEGER");
if (Record[0] & 1)
V = ConstantInt::get(CurTy, -(Record[0]>>1));
else
V = ConstantInt::get(CurTy, Record[0]>>1);
break;
}
ValueList.push_back(V);
}
}
bool BitcodeReader::ParseModule(BitstreamReader &Stream,
const std::string &ModuleID) {
@ -346,6 +419,10 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
if (ParseValueSymbolTable(Stream))
return true;
break;
case bitc::CONSTANTS_BLOCK_ID:
if (ParseConstants(Stream))
return true;
break;
}
continue;
}

View File

@ -22,14 +22,14 @@
namespace llvm {
class BitstreamReader;
class Value;
class GlobalValue;
class GlobalVariable;
class BitcodeReader : public ModuleProvider {
const char *ErrorString;
std::vector<PATypeHolder> TypeList;
std::vector<Value*> ValueList;
std::vector<std::pair<GlobalValue*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
public:
virtual ~BitcodeReader() {}
@ -64,6 +64,7 @@ private:
bool ParseTypeTable(BitstreamReader &Stream);
bool ParseTypeSymbolTable(BitstreamReader &Stream);
bool ParseValueSymbolTable(BitstreamReader &Stream);
bool ParseConstants(BitstreamReader &Stream);
};
} // End llvm namespace