diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-03-14 10:51:38 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-03-14 10:51:38 +0000 |
commit | 647735c781c5b37061ee03d6e9e6c7dda92218e2 (patch) | |
tree | 5a5e56606d41060263048b5a5586b3d2380898ba /lib/Bitcode/Reader | |
parent | 6aed25d93d1cfcde5809a73ffa7dc1b0d6396f66 (diff) | |
parent | f635ef401786c84df32090251a8cf45981ecca33 (diff) |
Updating branches/google/stable to r176857
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/stable@177040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode/Reader')
-rw-r--r-- | lib/Bitcode/Reader/BitReader.cpp | 2 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 577 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 10 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitstreamReader.cpp | 371 | ||||
-rw-r--r-- | lib/Bitcode/Reader/CMakeLists.txt | 1 |
5 files changed, 703 insertions, 258 deletions
diff --git a/lib/Bitcode/Reader/BitReader.cpp b/lib/Bitcode/Reader/BitReader.cpp index a47c013a52..5cd6c552bd 100644 --- a/lib/Bitcode/Reader/BitReader.cpp +++ b/lib/Bitcode/Reader/BitReader.cpp @@ -9,7 +9,7 @@ #include "llvm-c/BitReader.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/MemoryBuffer.h" #include <cstring> #include <string> diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 1fdea799d0..f34884391a 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -6,23 +6,19 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This header defines the BitcodeReader class. -// -//===----------------------------------------------------------------------===// #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/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/OperandTraits.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" @@ -432,6 +428,26 @@ Type *BitcodeReader::getTypeByID(unsigned ID) { // Functions for parsing blocks from the bitcode file //===----------------------------------------------------------------------===// + +/// \brief This fills an AttrBuilder object with the LLVM attributes that have +/// been decoded from the given integer. This function must stay in sync with +/// 'encodeLLVMAttributesForBitcode'. +static void decodeLLVMAttributesForBitcode(AttrBuilder &B, + uint64_t EncodedAttrs) { + // FIXME: Remove in 4.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 = (EncodedAttrs & (0xffffULL << 16)) >> 16; + assert((!Alignment || isPowerOf2_32(Alignment)) && + "Alignment must be a power of two."); + + if (Alignment) + B.addAlignmentAttr(Alignment); + B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) | + (EncodedAttrs & 0xffff)); +} + bool BitcodeReader::ParseAttributeBlock() { if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) return Error("Malformed block record"); @@ -441,51 +457,46 @@ bool BitcodeReader::ParseAttributeBlock() { SmallVector<uint64_t, 64> Record; - SmallVector<AttributeWithIndex, 8> Attrs; + SmallVector<AttributeSet, 8> Attrs; // Read all the records. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of PARAMATTR block"); - return false; - } + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - 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; + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("Error at end of PARAMATTR block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: ignore. break; - case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...] + case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...] + // FIXME: Remove in 4.0. if (Record.size() & 1) return Error("Invalid ENTRY record"); for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - Attributes ReconstitutedAttr = - Attributes::decodeLLVMAttributesForBitcode(Context, Record[i+1]); - Record[i+1] = ReconstitutedAttr.Raw(); + AttrBuilder B; + decodeLLVMAttributesForBitcode(B, Record[i+1]); + Attrs.push_back(AttributeSet::get(Context, Record[i], B)); } - for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - AttrBuilder B(Record[i+1]); - if (B.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(Record[i], - Attributes::get(Context, B))); - } + MAttributes.push_back(AttributeSet::get(Context, Attrs)); + Attrs.clear(); + break; + } + case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...] + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Attrs.push_back(MAttributeGroups[Record[i]]); MAttributes.push_back(AttributeSet::get(Context, Attrs)); Attrs.clear(); @@ -495,6 +506,81 @@ bool BitcodeReader::ParseAttributeBlock() { } } +bool BitcodeReader::ParseAttributeGroupBlock() { + if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) + return Error("Malformed block record"); + + if (!MAttributeGroups.empty()) + return Error("Multiple PARAMATTR_GROUP blocks found!"); + + SmallVector<uint64_t, 64> Record; + + // Read all the records. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("Error at end of PARAMATTR_GROUP block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: ignore. + break; + case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] + if (Record.size() < 3) + return Error("Invalid ENTRY record"); + + uint64_t GrpID = Record[0]; + uint64_t Idx = Record[1]; // Index of the object this attribute refers to. + + AttrBuilder B; + for (unsigned i = 2, e = Record.size(); i != e; ++i) { + if (Record[i] == 0) { // Enum attribute + B.addAttribute(Attribute::AttrKind(Record[++i])); + } else if (Record[i] == 1) { // Align attribute + if (Attribute::AttrKind(Record[++i]) == Attribute::Alignment) + B.addAlignmentAttr(Record[++i]); + else + B.addStackAlignmentAttr(Record[++i]); + } else { // String attribute + assert((Record[i] == 3 || Record[i] == 4) && + "Invalid attribute group entry"); + bool HasValue = (Record[i++] == 4); + SmallString<64> KindStr; + SmallString<64> ValStr; + + while (Record[i] != 0 && i != e) + KindStr += Record[i++]; + assert(Record[i] == 0 && "Kind string not null terminated"); + + if (HasValue) { + // Has a value associated with it. + ++i; // Skip the '0' that terminates the "kind" string. + while (Record[i] != 0 && i != e) + ValStr += Record[i++]; + assert(Record[i] == 0 && "Value string not null terminated"); + } + + B.addAttribute(KindStr.str(), ValStr.str()); + } + } + + MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B); + break; + } + } + } +} + bool BitcodeReader::ParseTypeTable() { if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) return Error("Malformed block record"); @@ -513,32 +599,26 @@ bool BitcodeReader::ParseTypeTableBody() { // Read all the records for this type table. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + Error("Error in the type table block"); + return true; + case BitstreamEntry::EndBlock: if (NumRecords != TypeList.size()) return Error("Invalid type forward reference in TYPE_BLOCK"); - if (Stream.ReadBlockEnd()) - return Error("Error at end of type table block"); return false; - } - - 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; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); Type *ResultTy = 0; - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: return Error("unknown type in type table"); case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] // TYPE_CODE_NUMENTRY contains a count of the number of types in the @@ -736,28 +816,22 @@ bool BitcodeReader::ParseValueSymbolTable() { // Read all the records for this value table. SmallString<128> ValueName; while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of value symbol table block"); - return false; - } - if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. - Stream.ReadSubBlockID(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; - } + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed value symbol table block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: unknown type. break; case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N] @@ -797,41 +871,35 @@ bool BitcodeReader::ParseMetadata() { // Read all the records. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of PARAMATTR block"); - return false; - } + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - 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; + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + Error("malformed metadata block"); + return true; + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } bool IsFunctionLocal = false; // Read a record. Record.clear(); - Code = Stream.ReadRecord(Code, Record); + unsigned Code = Stream.readRecord(Entry.ID, Record); switch (Code) { default: // Default behavior: ignore. break; case bitc::METADATA_NAME: { - // Read named of the named metadata. + // Read name of the named metadata. SmallString<8> Name(Record.begin(), Record.end()); Record.clear(); Code = Stream.ReadCode(); // METADATA_NAME is always followed by METADATA_NAMED_NODE. - unsigned NextBitCode = Stream.ReadRecord(Code, Record); + unsigned NextBitCode = Stream.readRecord(Code, Record); assert(NextBitCode == bitc::METADATA_NAMED_NODE); (void)NextBitCode; // Read named metadata elements. @@ -958,27 +1026,29 @@ bool BitcodeReader::ParseConstants() { Type *CurTy = Type::getInt32Ty(Context); unsigned NextCstNo = ValueList.size(); while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed block record in AST file"); + case BitstreamEntry::EndBlock: + if (NextCstNo != ValueList.size()) + return Error("Invalid constant reference!"); + + // Once all the constants have been read, go through and resolve forward + // references. + ValueList.ResolveConstantForwardRefs(); + return false; + case BitstreamEntry::Record: + // The interesting case. break; - - 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; - unsigned BitCode = Stream.ReadRecord(Code, Record); + unsigned BitCode = Stream.readRecord(Entry.ID, Record); switch (BitCode) { default: // Default behavior: unknown constant case bitc::CST_CODE_UNDEF: // UNDEF @@ -1013,21 +1083,27 @@ bool BitcodeReader::ParseConstants() { if (Record.empty()) return Error("Invalid FLOAT record"); if (CurTy->isHalfTy()) - V = ConstantFP::get(Context, APFloat(APInt(16, (uint16_t)Record[0]))); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf, + APInt(16, (uint16_t)Record[0]))); else if (CurTy->isFloatTy()) - V = ConstantFP::get(Context, APFloat(APInt(32, (uint32_t)Record[0]))); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle, + APInt(32, (uint32_t)Record[0]))); else if (CurTy->isDoubleTy()) - V = ConstantFP::get(Context, APFloat(APInt(64, Record[0]))); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble, + APInt(64, Record[0]))); else if (CurTy->isX86_FP80Ty()) { // Bits are not stored the same way as a normal i80 APInt, compensate. uint64_t Rearrange[2]; Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); Rearrange[1] = Record[0] >> 48; - V = ConstantFP::get(Context, APFloat(APInt(80, Rearrange))); + V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended, + APInt(80, Rearrange))); } else if (CurTy->isFP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, Record), true)); + V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad, + APInt(128, Record))); else if (CurTy->isPPC_FP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, Record))); + V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble, + APInt(128, Record))); else V = UndefValue::get(CurTy); break; @@ -1333,17 +1409,6 @@ bool BitcodeReader::ParseConstants() { ValueList.AssignValue(V, NextCstNo); ++NextCstNo; } - - if (NextCstNo != ValueList.size()) - return Error("Invalid constant reference!"); - - if (Stream.ReadBlockEnd()) - return Error("Error at end of constants block"); - - // Once all the constants have been read, go through and resolve forward - // references. - ValueList.ResolveConstantForwardRefs(); - return false; } bool BitcodeReader::ParseUseLists() { @@ -1354,29 +1419,22 @@ bool BitcodeReader::ParseUseLists() { // Read all the records. while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - 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(); - if (Stream.SkipBlock()) - return Error("Malformed block record"); - continue; - } + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed use list block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a use list record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: unknown type. break; case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD. @@ -1448,17 +1506,18 @@ bool BitcodeReader::ParseModule(bool Resume) { std::vector<std::string> GCTable; // Read all the records for this module. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of module block"); + while (1) { + BitstreamEntry Entry = Stream.advance(); + switch (Entry.Kind) { + case BitstreamEntry::Error: + Error("malformed module block"); + return true; + case BitstreamEntry::EndBlock: return GlobalCleanup(); - } - if (Code == bitc::ENTER_SUBBLOCK) { - switch (Stream.ReadSubBlockID()) { + case BitstreamEntry::SubBlock: + switch (Entry.ID) { default: // Skip unknown content. if (Stream.SkipBlock()) return Error("Malformed block record"); @@ -1471,6 +1530,10 @@ bool BitcodeReader::ParseModule(bool Resume) { if (ParseAttributeBlock()) return true; break; + case bitc::PARAMATTR_GROUP_BLOCK_ID: + if (ParseAttributeGroupBlock()) + return true; + break; case bitc::TYPE_BLOCK_ID_NEW: if (ParseTypeTable()) return true; @@ -1517,15 +1580,15 @@ bool BitcodeReader::ParseModule(bool Resume) { break; } continue; - } - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } + // Read a record. - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { // VERSION: [version#] if (Record.size() < 1) @@ -1620,9 +1683,13 @@ bool BitcodeReader::ParseModule(bool Resume) { if (Record.size() > 8) UnnamedAddr = Record[8]; + bool ExternallyInitialized = false; + if (Record.size() > 9) + ExternallyInitialized = Record[9]; + GlobalVariable *NewGV = new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0, - TLM, AddressSpace); + TLM, AddressSpace, ExternallyInitialized); NewGV->setAlignment(Alignment); if (!Section.empty()) NewGV->setSection(Section); @@ -1713,8 +1780,6 @@ bool BitcodeReader::ParseModule(bool Resume) { } Record.clear(); } - - return Error("Premature end of bitstream"); } bool BitcodeReader::ParseBitcodeInto(Module *M) { @@ -1733,47 +1798,55 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); + while (1) { + if (Stream.AtEndOfStream()) + return false; + + BitstreamEntry Entry = + Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + Error("malformed module file"); + return true; + case BitstreamEntry::EndBlock: + return false; - if (Code != bitc::ENTER_SUBBLOCK) { + case BitstreamEntry::SubBlock: + switch (Entry.ID) { + case bitc::BLOCKINFO_BLOCK_ID: + if (Stream.ReadBlockInfoBlock()) + return Error("Malformed BlockInfoBlock"); + break; + case bitc::MODULE_BLOCK_ID: + // Reject multiple MODULE_BLOCK's in a single bitstream. + if (TheModule) + return Error("Multiple MODULE_BLOCKs in same stream"); + TheModule = M; + if (ParseModule(false)) + return true; + if (LazyStreamer) return false; + break; + default: + if (Stream.SkipBlock()) + return Error("Malformed block record"); + break; + } + continue; + case BitstreamEntry::Record: + // There should be no records in the top-level of blocks. - // The ranlib in xcode 4 will align archive members by appending newlines + // The ranlib in Xcode 4 will align archive members by appending newlines // to the end of them. If this file size is a multiple of 4 but not 8, we // have to read and ignore these final 4 bytes :-( - if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 && + if (Stream.getAbbrevIDWidth() == 2 && Entry.ID == 2 && Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && Stream.AtEndOfStream()) return false; return Error("Invalid record at top-level"); } - - unsigned BlockID = Stream.ReadSubBlockID(); - - // We only know the MODULE subblock ID. - switch (BlockID) { - case bitc::BLOCKINFO_BLOCK_ID: - if (Stream.ReadBlockInfoBlock()) - return Error("Malformed BlockInfoBlock"); - break; - case bitc::MODULE_BLOCK_ID: - // Reject multiple MODULE_BLOCK's in a single bitstream. - if (TheModule) - return Error("Multiple MODULE_BLOCKs in same stream"); - TheModule = M; - if (ParseModule(false)) - return true; - if (LazyStreamer) return false; - break; - default: - if (Stream.SkipBlock()) - return Error("Malformed block record"); - break; - } } - - return false; } bool BitcodeReader::ParseModuleTriple(std::string &Triple) { @@ -1783,32 +1856,22 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { SmallVector<uint64_t, 64> Record; // Read all the records for this module. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of module block"); + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed module block"); + case BitstreamEntry::EndBlock: return false; - } - - if (Code == bitc::ENTER_SUBBLOCK) { - switch (Stream.ReadSubBlockID()) { - default: // Skip unknown content. - if (Stream.SkipBlock()) - return Error("Malformed block record"); - break; - } - continue; - } - - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; @@ -1820,8 +1883,6 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) { } Record.clear(); } - - return Error("Premature end of bitstream"); } bool BitcodeReader::ParseTriple(std::string &Triple) { @@ -1838,28 +1899,32 @@ bool BitcodeReader::ParseTriple(std::string &Triple) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. - while (!Stream.AtEndOfStream()) { - unsigned Code = Stream.ReadCode(); + while (1) { + BitstreamEntry Entry = Stream.advance(); - if (Code != bitc::ENTER_SUBBLOCK) - return Error("Invalid record at top-level"); + switch (Entry.Kind) { + case BitstreamEntry::Error: + Error("malformed module file"); + return true; + case BitstreamEntry::EndBlock: + return false; - unsigned BlockID = Stream.ReadSubBlockID(); + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return ParseModuleTriple(Triple); - // We only know the MODULE subblock ID. - switch (BlockID) { - case bitc::MODULE_BLOCK_ID: - if (ParseModuleTriple(Triple)) + // Ignore other sub-blocks. + if (Stream.SkipBlock()) { + Error("malformed block record in AST file"); return true; - break; - default: - if (Stream.SkipBlock()) - return Error("Malformed block record"); - break; + } + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; } } - - return false; } /// ParseMetadataAttachment - Parse metadata attachments. @@ -1868,20 +1933,23 @@ bool BitcodeReader::ParseMetadataAttachment() { return Error("Malformed block record"); SmallVector<uint64_t, 64> Record; - while(1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of PARAMATTR block"); + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return Error("malformed metadata block"); + case BitstreamEntry::EndBlock: + return false; + case BitstreamEntry::Record: + // The interesting case. break; } - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; - } + // Read a metadata attachment record. Record.clear(); - switch (Stream.ReadRecord(Code, Record)) { + switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: ignore. break; case bitc::METADATA_ATTACHMENT: { @@ -1902,7 +1970,6 @@ bool BitcodeReader::ParseMetadataAttachment() { } } } - return false; } /// ParseFunctionBody - Lazily parse the specified function body block. @@ -1927,15 +1994,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { // Read all the records. SmallVector<uint64_t, 64> Record; while (1) { - unsigned Code = Stream.ReadCode(); - if (Code == bitc::END_BLOCK) { - if (Stream.ReadBlockEnd()) - return Error("Error at end of function block"); - break; - } + BitstreamEntry Entry = Stream.advance(); - if (Code == bitc::ENTER_SUBBLOCK) { - switch (Stream.ReadSubBlockID()) { + switch (Entry.Kind) { + case BitstreamEntry::Error: + return Error("Bitcode error in function block"); + case BitstreamEntry::EndBlock: + goto OutOfRecordLoop; + + case BitstreamEntry::SubBlock: + switch (Entry.ID) { default: // Skip unknown content. if (Stream.SkipBlock()) return Error("Malformed block record"); @@ -1955,17 +2023,16 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; } continue; - } - if (Code == bitc::DEFINE_ABBREV) { - Stream.ReadAbbrevRecord(); - continue; + case BitstreamEntry::Record: + // The interesting case. + break; } // Read a record. Record.clear(); Instruction *I = 0; - unsigned BitCode = Stream.ReadRecord(Code, Record); + unsigned BitCode = Stream.readRecord(Entry.ID, Record); switch (BitCode) { default: // Default behavior: reject return Error("Unknown instruction"); @@ -2742,6 +2809,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { ValueList.AssignValue(I, NextValueNo++); } +OutOfRecordLoop: + // Check the function list for unresolved values. if (Argument *A = dyn_cast<Argument>(ValueList.back())) { if (A->getParent() == 0) { diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 6d27eff128..28674eb14e 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -15,13 +15,13 @@ #define BITCODE_READER_H #include "llvm/ADT/DenseMap.h" -#include "llvm/Attributes.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/GVMaterializer.h" -#include "llvm/OperandTraits.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/OperandTraits.h" +#include "llvm/IR/Type.h" #include "llvm/Support/ValueHandle.h" -#include "llvm/Type.h" #include <vector> namespace llvm { @@ -148,6 +148,9 @@ class BitcodeReader : public GVMaterializer { /// are off by one. std::vector<AttributeSet> MAttributes; + /// \brief The set of attribute groups. + std::map<unsigned, AttributeSet> MAttributeGroups; + /// FunctionBBs - While parsing a function body, this is a list of the basic /// blocks for the function. std::vector<BasicBlock*> FunctionBBs; @@ -320,6 +323,7 @@ private: bool ParseModule(bool Resume); bool ParseAttributeBlock(); + bool ParseAttributeGroupBlock(); bool ParseTypeTable(); bool ParseTypeTableBody(); diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp new file mode 100644 index 0000000000..942346b44e --- /dev/null +++ b/lib/Bitcode/Reader/BitstreamReader.cpp @@ -0,0 +1,371 @@ +//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/BitstreamReader.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// BitstreamCursor implementation +//===----------------------------------------------------------------------===// + +void BitstreamCursor::operator=(const BitstreamCursor &RHS) { + freeState(); + + BitStream = RHS.BitStream; + NextChar = RHS.NextChar; + CurWord = RHS.CurWord; + BitsInCurWord = RHS.BitsInCurWord; + CurCodeSize = RHS.CurCodeSize; + + // Copy abbreviations, and bump ref counts. + CurAbbrevs = RHS.CurAbbrevs; + for (size_t i = 0, e = CurAbbrevs.size(); i != e; ++i) + CurAbbrevs[i]->addRef(); + + // Copy block scope and bump ref counts. + BlockScope = RHS.BlockScope; + for (size_t S = 0, e = BlockScope.size(); S != e; ++S) { + std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; + for (size_t i = 0, e = Abbrevs.size(); i != e; ++i) + Abbrevs[i]->addRef(); + } +} + +void BitstreamCursor::freeState() { + // Free all the Abbrevs. + for (size_t i = 0, e = CurAbbrevs.size(); i != e; ++i) + CurAbbrevs[i]->dropRef(); + CurAbbrevs.clear(); + + // Free all the Abbrevs in the block scope. + for (size_t S = 0, e = BlockScope.size(); S != e; ++S) { + std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs; + for (size_t i = 0, e = Abbrevs.size(); i != e; ++i) + Abbrevs[i]->dropRef(); + } + BlockScope.clear(); +} + +/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter +/// the block, and return true if the block has an error. +bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { + // Save the current block's state on BlockScope. + BlockScope.push_back(Block(CurCodeSize)); + BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); + + // Add the abbrevs specific to this block to the CurAbbrevs list. + if (const BitstreamReader::BlockInfo *Info = + BitStream->getBlockInfo(BlockID)) { + for (size_t i = 0, e = Info->Abbrevs.size(); i != e; ++i) { + CurAbbrevs.push_back(Info->Abbrevs[i]); + CurAbbrevs.back()->addRef(); + } + } + + // Get the codesize of this block. + CurCodeSize = ReadVBR(bitc::CodeLenWidth); + SkipToFourByteBoundary(); + unsigned NumWords = Read(bitc::BlockSizeWidth); + if (NumWordsP) *NumWordsP = NumWords; + + // Validate that this block is sane. + if (CurCodeSize == 0 || AtEndOfStream()) + return true; + + return false; +} + +void BitstreamCursor::readAbbreviatedLiteral(const BitCodeAbbrevOp &Op, + SmallVectorImpl<uint64_t> &Vals) { + assert(Op.isLiteral() && "Not a literal"); + // If the abbrev specifies the literal value to use, use it. + Vals.push_back(Op.getLiteralValue()); +} + +void BitstreamCursor::readAbbreviatedField(const BitCodeAbbrevOp &Op, + SmallVectorImpl<uint64_t> &Vals) { + assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); + + // Decode the value as we are commanded. + switch (Op.getEncoding()) { + case BitCodeAbbrevOp::Array: + case BitCodeAbbrevOp::Blob: + assert(0 && "Should not reach here"); + case BitCodeAbbrevOp::Fixed: + Vals.push_back(Read((unsigned)Op.getEncodingData())); + break; + case BitCodeAbbrevOp::VBR: + Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData())); + break; + case BitCodeAbbrevOp::Char6: + Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6))); + break; + } +} + +void BitstreamCursor::skipAbbreviatedField(const BitCodeAbbrevOp &Op) { + assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); + + // Decode the value as we are commanded. + switch (Op.getEncoding()) { + case BitCodeAbbrevOp::Array: + case BitCodeAbbrevOp::Blob: + assert(0 && "Should not reach here"); + case BitCodeAbbrevOp::Fixed: + (void)Read((unsigned)Op.getEncodingData()); + break; + case BitCodeAbbrevOp::VBR: + (void)ReadVBR64((unsigned)Op.getEncodingData()); + break; + case BitCodeAbbrevOp::Char6: + (void)Read(6); + break; + } +} + + + +/// skipRecord - Read the current record and discard it. +void BitstreamCursor::skipRecord(unsigned AbbrevID) { + // Skip unabbreviated records by reading past their entries. + if (AbbrevID == bitc::UNABBREV_RECORD) { + unsigned Code = ReadVBR(6); + (void)Code; + unsigned NumElts = ReadVBR(6); + for (unsigned i = 0; i != NumElts; ++i) + (void)ReadVBR64(6); + return; + } + + const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); + + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + if (Op.isLiteral()) + continue; + + if (Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob) { + skipAbbreviatedField(Op); + continue; + } + + if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + // Array case. Read the number of elements as a vbr6. + unsigned NumElts = ReadVBR(6); + + // Get the element encoding. + assert(i+2 == e && "array op not second to last?"); + const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + + // Read all the elements. + for (; NumElts; --NumElts) + skipAbbreviatedField(EltEnc); + continue; + } + + assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); + // Blob case. Read the number of bytes as a vbr6. + unsigned NumElts = ReadVBR(6); + SkipToFourByteBoundary(); // 32-bit alignment + + // Figure out where the end of this blob will be including tail padding. + size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8; + + // If this would read off the end of the bitcode file, just set the + // record to empty and return. + if (!canSkipToPos(NewEnd/8)) { + NextChar = BitStream->getBitcodeBytes().getExtent(); + break; + } + + // Skip over the blob. + JumpToBit(NewEnd); + } +} + +unsigned BitstreamCursor::readRecord(unsigned AbbrevID, + SmallVectorImpl<uint64_t> &Vals, + StringRef *Blob) { + if (AbbrevID == bitc::UNABBREV_RECORD) { + unsigned Code = ReadVBR(6); + unsigned NumElts = ReadVBR(6); + for (unsigned i = 0; i != NumElts; ++i) + Vals.push_back(ReadVBR64(6)); + return Code; + } + + const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); + + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + if (Op.isLiteral()) { + readAbbreviatedLiteral(Op, Vals); + continue; + } + + if (Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob) { + readAbbreviatedField(Op, Vals); + continue; + } + + if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + // Array case. Read the number of elements as a vbr6. + unsigned NumElts = ReadVBR(6); + + // Get the element encoding. + assert(i+2 == e && "array op not second to last?"); + const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + + // Read all the elements. + for (; NumElts; --NumElts) + readAbbreviatedField(EltEnc, Vals); + continue; + } + + assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); + // Blob case. Read the number of bytes as a vbr6. + unsigned NumElts = ReadVBR(6); + SkipToFourByteBoundary(); // 32-bit alignment + + // Figure out where the end of this blob will be including tail padding. + size_t CurBitPos = GetCurrentBitNo(); + size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8; + + // If this would read off the end of the bitcode file, just set the + // record to empty and return. + if (!canSkipToPos(NewEnd/8)) { + Vals.append(NumElts, 0); + NextChar = BitStream->getBitcodeBytes().getExtent(); + break; + } + + // Otherwise, inform the streamer that we need these bytes in memory. + const char *Ptr = (const char*) + BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts); + + // If we can return a reference to the data, do so to avoid copying it. + if (Blob) { + *Blob = StringRef(Ptr, NumElts); + } else { + // Otherwise, unpack into Vals with zero extension. + for (; NumElts; --NumElts) + Vals.push_back((unsigned char)*Ptr++); + } + // Skip over tail padding. + JumpToBit(NewEnd); + } + + unsigned Code = (unsigned)Vals[0]; + Vals.erase(Vals.begin()); + return Code; +} + + +void BitstreamCursor::ReadAbbrevRecord() { + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + unsigned NumOpInfo = ReadVBR(5); + for (unsigned i = 0; i != NumOpInfo; ++i) { + bool IsLiteral = Read(1) ? true : false; + if (IsLiteral) { + Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); + continue; + } + + BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); + if (BitCodeAbbrevOp::hasEncodingData(E)) { + unsigned Data = ReadVBR64(5); + + // As a special case, handle fixed(0) (i.e., a fixed field with zero bits) + // and vbr(0) as a literal zero. This is decoded the same way, and avoids + // a slow path in Read() to have to handle reading zero bits. + if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) && + Data == 0) { + Abbv->Add(BitCodeAbbrevOp(0)); + continue; + } + + Abbv->Add(BitCodeAbbrevOp(E, Data)); + } else + Abbv->Add(BitCodeAbbrevOp(E)); + } + CurAbbrevs.push_back(Abbv); +} + +bool BitstreamCursor::ReadBlockInfoBlock() { + // If this is the second stream to get to the block info block, skip it. + if (BitStream->hasBlockInfoRecords()) + return SkipBlock(); + + if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true; + + SmallVector<uint64_t, 64> Record; + BitstreamReader::BlockInfo *CurBlockInfo = 0; + + // Read all the records for this module. + while (1) { + BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs); + + switch (Entry.Kind) { + case llvm::BitstreamEntry::SubBlock: // Handled for us already. + case llvm::BitstreamEntry::Error: + return true; + case llvm::BitstreamEntry::EndBlock: + return false; + case llvm::BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read abbrev records, associate them with CurBID. + if (Entry.ID == bitc::DEFINE_ABBREV) { + if (!CurBlockInfo) return true; + ReadAbbrevRecord(); + + // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the + // appropriate BlockInfo. + BitCodeAbbrev *Abbv = CurAbbrevs.back(); + CurAbbrevs.pop_back(); + CurBlockInfo->Abbrevs.push_back(Abbv); + continue; + } + + // Read a record. + Record.clear(); + switch (readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::BLOCKINFO_CODE_SETBID: + if (Record.size() < 1) return true; + CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]); + break; + case bitc::BLOCKINFO_CODE_BLOCKNAME: { + if (!CurBlockInfo) return true; + if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. + std::string Name; + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->Name = Name; + break; + } + case bitc::BLOCKINFO_CODE_SETRECORDNAME: { + if (!CurBlockInfo) return true; + if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. + std::string Name; + for (unsigned i = 1, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0], + Name)); + break; + } + } + } +} + diff --git a/lib/Bitcode/Reader/CMakeLists.txt b/lib/Bitcode/Reader/CMakeLists.txt index dfe7e1065c..f614c9fd4a 100644 --- a/lib/Bitcode/Reader/CMakeLists.txt +++ b/lib/Bitcode/Reader/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_library(LLVMBitReader BitReader.cpp BitcodeReader.cpp + BitstreamReader.cpp ) add_dependencies(LLVMBitReader intrinsics_gen) |