From e16504eb4ef8f09611cdf6e9a0be9eb886b4ed89 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Apr 2007 03:30:34 +0000 Subject: read basic constants: null, undef, integers <= 64bits git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36389 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 77 ++++++++++++++++++++++++++++++++++++ lib/Bitcode/Reader/BitcodeReader.h | 5 ++- 2 files changed, 80 insertions(+), 2 deletions(-) (limited to 'lib/Bitcode') diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e728b3f7f0..b7d6b43e57 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -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 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(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(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; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index ed11692391..bdb64c8c99 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -22,14 +22,14 @@ namespace llvm { class BitstreamReader; class Value; - class GlobalValue; + class GlobalVariable; class BitcodeReader : public ModuleProvider { const char *ErrorString; std::vector TypeList; std::vector ValueList; - std::vector > GlobalInits; + std::vector > 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 -- cgit v1.2.3