summaryrefslogtreecommitdiff
path: root/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp78
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h4
2 files changed, 82 insertions, 0 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 2c1e535120..110f47c7d8 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -498,6 +498,80 @@ 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");
+
+ // FIXME: Record[0] is the 'group ID'. What should we do with it here?
+
+ 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
+ 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 terminated with 0");
+
+ 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 terminated with 0");
+ }
+
+ B.addAttribute(KindStr.str(), ValStr.str());
+ }
+ }
+
+ MAttributeGroups.push_back(AttributeSet::get(Context, Idx, B));
+ break;
+ }
+ }
+ }
+}
+
bool BitcodeReader::ParseTypeTable() {
if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW))
return Error("Malformed block record");
@@ -1447,6 +1521,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;
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 3347418de8..8d36e67075 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -148,6 +148,9 @@ class BitcodeReader : public GVMaterializer {
/// are off by one.
std::vector<AttributeSet> MAttributes;
+ /// \brief The set of attribute groups.
+ std::vector<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();