summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.cpp37
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.h1
-rw-r--r--unittests/CodeGen/DIEHashTest.cpp36
3 files changed, 61 insertions, 13 deletions
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp
index 8409a7f..c3dc7af 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -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,
+
+ // [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());
- // Add the letter A to the hash.
+ // ... 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.
}
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h
index 78238e1..ee753fe 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -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...
};
diff --git a/unittests/CodeGen/DIEHashTest.cpp b/unittests/CodeGen/DIEHashTest.cpp
index fd1845e..834a16a2 100644
--- a/unittests/CodeGen/DIEHashTest.cpp
+++ b/unittests/CodeGen/DIEHashTest.cpp
@@ -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);
+}
}