+static void WriteAttributeGroupTable(const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
+ const std::vector<AttributeSet> &Attrs = VE.getAttributeSets();
+ if (Attrs.empty()) return;
+
+ Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3);
+
+ SmallVector<uint64_t, 64> Record;
+ for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
+ AttributeSet AS = Attrs[i];
+ for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) {
+ AttributeSet A = AS.getSlotAttributes(i);
+
+ Record.push_back(VE.getAttributeSetID(A));
+ Record.push_back(AS.getSlotIndex(i));
+
+ for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0);
+ I != E; ++I) {
+ Attribute Attr = *I;
+ if (Attr.isEnumAttribute()) {
+ Record.push_back(0);
+ Record.push_back(Attr.getKindAsEnum());
+ } else if (Attr.isAlignAttribute()) {
+ Record.push_back(1);
+ Record.push_back(Attr.getKindAsEnum());
+ Record.push_back(Attr.getValueAsInt());
+ } else {
+ StringRef Kind = Attr.getKindAsString();
+ StringRef Val = Attr.getValueAsString();
+
+ Record.push_back(Val.empty() ? 3 : 4);
+ Record.append(Kind.begin(), Kind.end());
+ Record.push_back(0);
+ if (!Val.empty()) {
+ Record.append(Val.begin(), Val.end());
+ Record.push_back(0);
+ }
+ }
+ }
+
+ Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record);
+ Record.clear();
+ }
+ }
+
+ Stream.ExitBlock();
+}
+