DIEHash: Support for simple (non-recursive, non-reused) type references

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192924 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2013-10-17 22:07:09 +00:00
parent 7014d274e4
commit 47f66d5a75
3 changed files with 61 additions and 13 deletions

View File

@ -274,6 +274,9 @@ void DIEHash::collectAttributes(DIE *Die, DIEAttrs &Attrs) {
case dwarf::DW_AT_vtable_elem_location:
COLLECT_ATTR(DW_AT_vtable_elem_location)
break;
case dwarf::DW_AT_type:
COLLECT_ATTR(DW_AT_type)
break;
default:
break;
}
@ -286,19 +289,39 @@ void DIEHash::hashAttribute(AttrEntry Attr) {
const DIEValue *Value = Attr.Val;
const DIEAbbrevData *Desc = Attr.Desc;
// TODO: Add support for types.
// 7.27s3
// ... An attribute that refers to another type entry T is processed as
// follows:
// a) If T is in the list of [previously hashed types], use the letter 'R' as
// the marker and use the unsigned LEB128 encoding of [the index of T in the
// list] as the attribute value; otherwise,
// Add the letter A to the hash.
// [TODO: implement clause (a)]
if (const DIEEntry *EntryAttr = dyn_cast<DIEEntry>(Value)) {
DIE *Entry = EntryAttr->getEntry();
// b) use the letter 'T' as a the marker, ...
addULEB128('T');
addULEB128(Desc->getAttribute());
// ... process the type T recursively by performing Steps 2 through 7, and
// use the result as the attribute value.
computeHash(Entry);
return;
}
// Other attribute values use the letter 'A' as the marker, ...
addULEB128('A');
// Then the attribute code.
addULEB128(Desc->getAttribute());
// To ensure reproducibility of the signature, the set of forms used in the
// ... and the value consists of the form code (encoded as an unsigned LEB128
// value) followed by the encoding of the value according to the form code. To
// ensure reproducibility of the signature, the set of forms used in the
// signature computation is limited to the following: DW_FORM_sdata,
// DW_FORM_flag, DW_FORM_string, and DW_FORM_block.
// TODO: Add support for additional forms.
switch (Desc->getForm()) {
case dwarf::DW_FORM_string:
llvm_unreachable(
@ -315,6 +338,7 @@ void DIEHash::hashAttribute(AttrEntry Attr) {
addULEB128(dwarf::DW_FORM_sdata);
addSLEB128((int64_t)cast<DIEInteger>(Value)->getValue());
break;
// TODO: Add support for additional forms.
}
}
@ -375,6 +399,7 @@ void DIEHash::hashAttributes(const DIEAttrs &Attrs) {
ADD_ATTR(Attrs.DW_AT_virtuality);
ADD_ATTR(Attrs.DW_AT_visibility);
ADD_ATTR(Attrs.DW_AT_vtable_elem_location);
ADD_ATTR(Attrs.DW_AT_type);
// FIXME: Add the extended attributes.
}

View File

@ -76,6 +76,7 @@ class DIEHash {
AttrEntry DW_AT_virtuality;
AttrEntry DW_AT_visibility;
AttrEntry DW_AT_vtable_elem_location;
AttrEntry DW_AT_type;
// Insert any additional ones here...
};

View File

@ -51,9 +51,6 @@ TEST(NamedType, DIEHash) {
Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
// Line and file number are ignored.
Foo.addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
Foo.addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
uint64_t MD5Res = DIEHash().computeTypeSignature(&Foo);
// The exact same hash GCC produces for this DIE.
@ -78,10 +75,6 @@ TEST(NamespacedType, DIEHash) {
Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
// Line and file number are ignored.
Foo->addValue(dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, &One);
Foo->addValue(dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, &One);
Space->addChild(Foo);
CU.addChild(Space);
@ -90,4 +83,33 @@ TEST(NamespacedType, DIEHash) {
// The exact same hash GCC produces for this DIE.
ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
}
TEST(TypeWithMember, DIEHash) {
DIE Unnamed(dwarf::DW_TAG_structure_type);
DIEInteger Four(4);
Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
DIE *Member = new DIE(dwarf::DW_TAG_member);
DIEString MemberStr(&Four, "member");
Member->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemberStr);
// type
DIEInteger Zero(0);
Member->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
Unnamed.addChild(Member);
DIE Int(dwarf::DW_TAG_base_type);
DIEString IntStr(&Four, "int");
Int.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &IntStr);
Int.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Four);
DIEInteger Five(5);
Int.addValue(dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, &Five);
DIEEntry IntRef(&Int);
Member->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &IntRef);
uint64_t MD5Res = DIEHash().computeTypeSignature(&Unnamed);
ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
}
}