Emitting ARM build attributes and values as ULEB, rather than char.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137115 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Renato Golin 2011-08-09 09:50:10 +00:00
parent e321d7ffc5
commit 719927a68f

View File

@ -100,13 +100,41 @@ namespace {
};
class ObjectAttributeEmitter : public AttributeEmitter {
// This structure holds all attributes, accounting for
// their string/numeric value, so we can later emmit them
// in declaration order, keeping all in the same vector
struct AttributeItemType {
enum {
HiddenAttribute = 0,
NumericAttribute,
TextAttribute
} Type;
unsigned Tag;
unsigned IntValue;
StringRef StringValue;
} AttributeItem;
MCObjectStreamer &Streamer;
StringRef CurrentVendor;
SmallString<64> Contents;
SmallVector<AttributeItemType, 64> Contents;
// Account for the ULEB/String size of each item,
// not just the number of items
size_t ContentsSize;
// FIXME: this should be in a more generic place, but
// getULEBSize() is in MCAsmInfo and will be moved to MCDwarf
size_t getULEBSize(int Value) {
size_t Size = 0;
do {
Value >>= 7;
Size += sizeof(int8_t); // Is this really necessary?
} while (Value);
return Size;
}
public:
ObjectAttributeEmitter(MCObjectStreamer &Streamer_) :
Streamer(Streamer_), CurrentVendor("") { }
Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { }
void MaybeSwitchVendor(StringRef Vendor) {
assert(!Vendor.empty() && "Vendor cannot be empty.");
@ -124,20 +152,32 @@ namespace {
}
void EmitAttribute(unsigned Attribute, unsigned Value) {
// FIXME: should be ULEB
Contents += Attribute;
Contents += Value;
AttributeItemType attr = {
AttributeItemType::NumericAttribute,
Attribute,
Value,
StringRef("")
};
ContentsSize += getULEBSize(Attribute);
ContentsSize += getULEBSize(Value);
Contents.push_back(attr);
}
void EmitTextAttribute(unsigned Attribute, StringRef String) {
Contents += Attribute;
Contents += UppercaseString(String);
Contents += 0;
AttributeItemType attr = {
AttributeItemType::TextAttribute,
Attribute,
0,
String
};
ContentsSize += getULEBSize(Attribute);
// String + \0
ContentsSize += String.size()+1;
Contents.push_back(attr);
}
void Finish() {
const size_t ContentsSize = Contents.size();
// Vendor size + Vendor name + '\0'
const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
@ -151,7 +191,23 @@ namespace {
Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
Streamer.EmitBytes(Contents, 0);
// Size should have been accounted for already, now
// emit each field as its type (ULEB or String)
for (unsigned int i=0; i<Contents.size(); ++i) {
AttributeItemType item = Contents[i];
Streamer.EmitULEB128IntValue(item.Tag, 0);
switch (item.Type) {
case AttributeItemType::NumericAttribute:
Streamer.EmitULEB128IntValue(item.IntValue, 0);
break;
case AttributeItemType::TextAttribute:
Streamer.EmitBytes(UppercaseString(item.StringValue), 0);
Streamer.EmitIntValue(0, 1); // '\0'
break;
default:
assert(0 && "Invalid attribute type");
}
}
Contents.clear();
}