llvm.org GIT mirror llvm / f1545a2
DWARF type hashing: begin implementing Step 5, summary hashing in declarable contexts There are several other tag types that need similar handling but to ensure test coverage they'll be coming incrementally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193126 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 7 years ago
3 changed file(s) with 75 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
188188
189189 // Hash an individual attribute \param Attr based on the type of attribute and
190190 // the form.
191 void DIEHash::hashAttribute(AttrEntry Attr) {
191 void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
192192 const DIEValue *Value = Attr.Val;
193193 const DIEAbbrevData *Desc = Attr.Desc;
194194
195 // 7.27s3
195 // 7.27 Step 3
196196 // ... An attribute that refers to another type entry T is processed as
197197 // follows:
198198 if (const DIEEntry *EntryAttr = dyn_cast(Value)) {
199199 DIE *Entry = EntryAttr->getEntry();
200
201 // Step 5
202 // If the tag in Step 3 is one of ...
203 if (Tag == dwarf::DW_TAG_pointer_type) {
204 // ... and the referenced type (via the DW_AT_type or DW_AT_friend
205 // attribute) ...
206 assert(Desc->getAttribute() == dwarf::DW_AT_type ||
207 Desc->getAttribute() == dwarf::DW_AT_friend);
208 // [FIXME] ... has a DW_AT_name attribute,
209 // append the letter 'N'
210 addULEB128('N');
211
212 // the DWARF attribute code (DW_AT_type or DW_AT_friend),
213 addULEB128(Desc->getAttribute());
214
215 // the context of the tag,
216 if (DIE *Parent = Entry->getParent())
217 addParentContext(Parent);
218
219 // the letter 'E',
220 addULEB128('E');
221
222 // and the name of the type.
223 addString(getDIEStringAttr(Entry, dwarf::DW_AT_name));
224
225 // FIXME:
226 // For DW_TAG_friend, if the referenced entry is the DW_TAG_subprogram,
227 // the context is omitted and the name to be used is the ABI-specific name
228 // of the subprogram (e.g., the mangled linker name).
229 return;
230 }
231
200232 unsigned &DieNumber = Numbering[Entry];
201233 if (DieNumber) {
202234 // a) If T is in the list of [previously hashed types], use the letter
257289
258290 // Go through the attributes from \param Attrs in the order specified in 7.27.4
259291 // and hash them.
260 void DIEHash::hashAttributes(const DIEAttrs &Attrs) {
292 void DIEHash::hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag) {
261293 #define ADD_ATTR(ATTR) \
262294 { \
263295 if (ATTR.Val != 0) \
264 hashAttribute(ATTR); \
296 hashAttribute(ATTR, Tag); \
265297 }
266298
267299 ADD_ATTR(Attrs.DW_AT_name);
321353 void DIEHash::addAttributes(DIE *Die) {
322354 DIEAttrs Attrs = {};
323355 collectAttributes(Die, Attrs);
324 hashAttributes(Attrs);
356 hashAttributes(Attrs, Die->getTag());
325357 }
326358
327359 // Compute the hash of a DIE. This is based on the type signature computation
118118 void collectAttributes(DIE *Die, DIEAttrs &Attrs);
119119
120120 /// \brief Hashes the attributes in \param Attrs in order.
121 void hashAttributes(const DIEAttrs &Attrs);
121 void hashAttributes(const DIEAttrs &Attrs, dwarf::Tag Tag);
122122
123123 /// \brief Hashes an individual attribute.
124 void hashAttribute(AttrEntry Attr);
124 void hashAttribute(AttrEntry Attr, dwarf::Tag Tag);
125125
126126 private:
127127 MD5 Hash;
2525 ASSERT_EQ(0x1AFE116E83701108ULL, MD5Res);
2626 }
2727
28 // struct {};
2829 TEST(DIEHashTest, TrivialType) {
29 // A complete, but simple, type containing no members and defined on the first
30 // line of a file.
3130 DIE Unnamed(dwarf::DW_TAG_structure_type);
3231 DIEInteger One(1);
3332 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
4140 ASSERT_EQ(0x715305ce6cfd9ad1ULL, MD5Res);
4241 }
4342
43 // struct foo { };
4444 TEST(DIEHashTest, NamedType) {
45 // A complete named type containing no members and defined on the first line
46 // of a file.
4745 DIE Foo(dwarf::DW_TAG_structure_type);
4846 DIEInteger One(1);
4947 DIEString FooStr(&One, "foo");
5654 ASSERT_EQ(0xd566dbd2ca5265ffULL, MD5Res);
5755 }
5856
57 // namespace space { struct foo { }; }
5958 TEST(DIEHashTest, NamespacedType) {
60 // A complete named type containing no members and defined on the first line
61 // of a file.
6259 DIE CU(dwarf::DW_TAG_compile_unit);
6360
6461 DIE *Space = new DIE(dwarf::DW_TAG_namespace);
8380 ASSERT_EQ(0x7b80381fd17f1e33ULL, MD5Res);
8481 }
8582
83 // struct { int member; };
8684 TEST(DIEHashTest, TypeWithMember) {
8785 DIE Unnamed(dwarf::DW_TAG_structure_type);
8886 DIEInteger Four(4);
111109 ASSERT_EQ(0x5646aa436b7e07c6ULL, MD5Res);
112110 }
113111
112 // struct foo { int mem1, mem2; };
114113 TEST(DIEHashTest, ReusedType) {
115114 DIE Unnamed(dwarf::DW_TAG_structure_type);
116115 DIEInteger Eight(8);
148147 ASSERT_EQ(0x3a7dc3ed7b76b2f8ULL, MD5Res);
149148 }
150149
150 // struct foo { static foo f; };
151151 TEST(DIEHashTest, RecursiveType) {
152152 DIE Foo(dwarf::DW_TAG_structure_type);
153153 DIEInteger One(1);
168168
169169 ASSERT_EQ(0x73d8b25aef227b06ULL, MD5Res);
170170 }
171 }
171
172 // struct foo { foo *mem; };
173 TEST(DIEHashTest, Pointer) {
174 DIE Foo(dwarf::DW_TAG_structure_type);
175 DIEInteger Eight(8);
176 Foo.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
177 DIEString FooStr(&Eight, "foo");
178 Foo.addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
179
180 DIE *Mem = new DIE(dwarf::DW_TAG_member);
181 DIEString MemStr(&Eight, "mem");
182 Mem->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &MemStr);
183 DIEInteger Zero(0);
184 Mem->addValue(dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1, &Zero);
185
186 DIE FooPtr(dwarf::DW_TAG_pointer_type);
187 FooPtr.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &Eight);
188 DIEEntry FooRef(&Foo);
189 FooPtr.addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooRef);
190
191 DIEEntry FooPtrRef(&FooPtr);
192 Mem->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, &FooPtrRef);
193
194 Foo.addChild(Mem);
195
196 uint64_t MD5Res = DIEHash().computeTypeSignature(&Foo);
197
198 ASSERT_EQ(0x74ea73862e8708d2ULL, MD5Res);
199 }
200 }