llvm.org GIT mirror llvm / a954618
DIEHash: Summary hashing of nested types git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193427 91177308-0d34-0410-b5e6-96231b3b80d8 David Blaikie 7 years ago
4 changed file(s) with 74 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
139139 DW_TAG_APPLE_property = 0x4200,
140140 DW_TAG_hi_user = 0xffff
141141 };
142
143 inline bool isType(Tag T) {
144 switch (T) {
145 case DW_TAG_array_type:
146 case DW_TAG_class_type:
147 case DW_TAG_interface_type:
148 case DW_TAG_enumeration_type:
149 case DW_TAG_pointer_type:
150 case DW_TAG_reference_type:
151 case DW_TAG_rvalue_reference_type:
152 case DW_TAG_string_type:
153 case DW_TAG_structure_type:
154 case DW_TAG_subroutine_type:
155 case DW_TAG_union_type:
156 case DW_TAG_ptr_to_member_type:
157 case DW_TAG_set_type:
158 case DW_TAG_subrange_type:
159 case DW_TAG_base_type:
160 case DW_TAG_const_type:
161 case DW_TAG_file_type:
162 case DW_TAG_packed_type:
163 case DW_TAG_volatile_type:
164 case DW_TAG_typedef:
165 return true;
166 default:
167 return false;
168 }
169 }
142170
143171 enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) {
144172 // Attributes
383383 hashAttributes(Attrs, Die.getTag());
384384 }
385385
386 void DIEHash::hashNestedType(const DIE &Die, StringRef Name) {
387 // 7.27 Step 7
388 // ... append the letter 'S',
389 addULEB128('S');
390
391 // the tag of C,
392 addULEB128(Die.getTag());
393
394 // and the name.
395 addString(Name);
396 }
397
386398 // Compute the hash of a DIE. This is based on the type signature computation
387399 // given in section 7.27 of the DWARF4 standard. It is the md5 hash of a
388400 // flattened description of the DIE.
397409 // Then hash each of the children of the DIE.
398410 for (std::vector::const_iterator I = Die.getChildren().begin(),
399411 E = Die.getChildren().end();
400 I != E; ++I)
412 I != E; ++I) {
413 // 7.27 Step 7
414 // If C is a nested type entry or a member function entry, ...
415 if (isType((*I)->getTag())) {
416 StringRef Name = getDIEStringAttr(**I, dwarf::DW_AT_name);
417 // ... and has a DW_AT_name attribute
418 if (!Name.empty()) {
419 hashNestedType(**I, Name);
420 continue;
421 }
422 }
401423 computeHash(**I);
424 }
402425
403426 // Following the last (or if there are no children), append a zero byte.
404427 Hash.update(makeArrayRef((uint8_t)'\0'));
136136 /// \brief Hashes a reference to a previously referenced type DIE.
137137 void hashRepeatedTypeReference(dwarf::Attribute Attribute, unsigned DieNumber);
138138
139 void hashNestedType(const DIE &Die, StringRef Name);
140
139141 private:
140142 MD5 Hash;
141143 DenseMap Numbering;
476476
477477 ASSERT_EQ(0x954e026f01c02529ULL, MD5Res);
478478 }
479 }
479
480 // struct { struct bar { }; };
481 TEST(DIEHashTest, NestedType) {
482 DIE Unnamed(dwarf::DW_TAG_structure_type);
483 DIEInteger One(1);
484 Unnamed.addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
485
486 DIE *Foo = new DIE(dwarf::DW_TAG_structure_type);
487 DIEString FooStr(&One, "foo");
488 Foo->addValue(dwarf::DW_AT_name, dwarf::DW_FORM_strp, &FooStr);
489 Foo->addValue(dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, &One);
490
491 Unnamed.addChild(Foo);
492
493 uint64_t MD5Res = DIEHash().computeTypeSignature(Unnamed);
494
495 // The exact same hash GCC produces for this DIE.
496 ASSERT_EQ(0xde8a3b7b43807f4aULL, MD5Res);
497 }
498 }