From 47f66d5a756d4eaeba9082ff4c82023a213daf45 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Thu, 17 Oct 2013 22:07:09 +0000 Subject: [PATCH] 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 --- lib/CodeGen/AsmPrinter/DIEHash.cpp | 37 +++++++++++++++++++++++++----- lib/CodeGen/AsmPrinter/DIEHash.h | 1 + unittests/CodeGen/DIEHashTest.cpp | 36 +++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index 8409a7f56c2..c3dc7af2f80 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(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(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 78238e19ab3..ee753fea99c 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 fd1845eb167..834a16a2ce1 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); +} } -- 2.34.1