llvm.org GIT mirror llvm / 2da1484
AsmPrinter: Use an intrusively linked list for DIE::Children Replace the `std::vector<>` for `DIE::Children` with an intrusively linked list. This is a strict memory improvement: it requires no auxiliary storage, and reduces `sizeof(DIE)` by one pointer. It also factors out the DIE-related malloc traffic. This drops llc memory usage from 735 MB down to 718 MB, or ~2.3%. (I'm looking at `llc` memory usage on `verify-uselistorder.lto.opt.bc`; see r236629 for details.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240736 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
11 changed file(s) with 146 addition(s) and 150 deletion(s). Raw diff Collapse all Expand all
608608 //===--------------------------------------------------------------------===//
609609 /// DIE - A structured debug information entry. Has an abbreviation which
610610 /// describes its organization.
611 class DIE {
611 class DIE : IntrusiveBackListNode {
612 friend class IntrusiveBackList;
613
612614 protected:
613615 /// Offset - Offset in debug info section.
614616 ///
625627 dwarf::Tag Tag = (dwarf::Tag)0;
626628
627629 /// Children DIEs.
628 ///
629 // This can't be a vector because pointer validity is requirent for the
630 // Parent pointer and DIEEntry.
631 // It can't be a list because some clients need pointer validity before
632 // the object has been added to any child list
633 // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
634 // be more convoluted than beneficial.
635 std::vector> Children;
636
637 DIE *Parent;
630 IntrusiveBackList Children;
631
632 DIE *Parent = nullptr;
638633
639634 /// Attribute values.
640635 ///
641636 DIEValueList Values;
642637
643638 protected:
644 DIE() : Offset(0), Size(0), Parent(nullptr) {}
645
646 public:
647 explicit DIE(dwarf::Tag Tag)
648 : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {}
639 DIE() : Offset(0), Size(0) {}
640
641 private:
642 explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {}
643
644 public:
645 static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) {
646 return new (Alloc) DIE(Tag);
647 }
649648
650649 // Accessors.
651650 unsigned getAbbrevNumber() const { return AbbrevNumber; }
654653 unsigned getSize() const { return Size; }
655654 bool hasChildren() const { return !Children.empty(); }
656655
657 typedef std::vector>::const_iterator child_iterator;
656 typedef IntrusiveBackList::iterator child_iterator;
657 typedef IntrusiveBackList::const_iterator const_child_iterator;
658658 typedef iterator_range child_range;
659
660 child_range children() const {
659 typedef iterator_range const_child_range;
660
661 child_range children() {
662 return llvm::make_range(Children.begin(), Children.end());
663 }
664 const_child_range children() const {
661665 return llvm::make_range(Children.begin(), Children.end());
662666 }
663667
706710 return Values.emplace(Alloc, Attribute, Form, std::forward(Value));
707711 }
708712
709 /// addChild - Add a child to the DIE.
710 ///
711 DIE &addChild(std::unique_ptr Child) {
712 assert(!Child->getParent());
713 /// Add a child to the DIE.
714 DIE &addChild(DIE *Child) {
715 assert(!Child->getParent() && "Child should be orphaned");
713716 Child->Parent = this;
714 Children.push_back(std::move(Child));
715 return *Children.back();
717 Children.push_back(*Child);
718 return Children.back();
716719 }
717720
718721 /// Find a value in the DIE with the attribute given.
276276 // Emit the DIE children if any.
277277 if (Die.hasChildren()) {
278278 for (auto &Child : Die.children())
279 emitDwarfDIE(*Child);
279 emitDwarfDIE(Child);
280280
281281 OutStreamer->AddComment("End Of Children Mark");
282282 EmitInt8(0);
179179 }
180180 IndentCount -= 2;
181181
182 for (unsigned j = 0, M = Children.size(); j < M; ++j) {
183 Children[j]->print(O, IndentCount+4);
184 }
182 for (const auto &Child : children())
183 Child.print(O, IndentCount + 4);
185184
186185 if (!isBlock) O << "\n";
187186 }
453453 for (auto &C : Die.children()) {
454454 // 7.27 Step 7
455455 // If C is a nested type entry or a member function entry, ...
456 if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) {
457 StringRef Name = getDIEStringAttr(*C, dwarf::DW_AT_name);
456 if (isType(C.getTag()) || C.getTag() == dwarf::DW_TAG_subprogram) {
457 StringRef Name = getDIEStringAttr(C, dwarf::DW_AT_name);
458458 // ... and has a DW_AT_name attribute
459459 if (!Name.empty()) {
460 hashNestedType(*C, Name);
460 hashNestedType(C, Name);
461461 continue;
462462 }
463463 }
464 computeHash(*C);
464 computeHash(C);
465465 }
466466
467467 // Following the last (or if there are no children), append a zero byte.
300300
301301 // Construct a DIE for this scope.
302302 void DwarfCompileUnit::constructScopeDIE(
303 LexicalScope *Scope, SmallVectorImpl<std::unique_ptr> &FinalChildren) {
303 LexicalScope *Scope, SmallVectorImpl<DIE *> &FinalChildren) {
304304 if (!Scope || !Scope->getScopeNode())
305305 return;
306306
311311 "constructSubprogramScopeDIE for non-inlined "
312312 "subprograms");
313313
314 SmallVector<std::unique_ptr, 8> Children;
314 SmallVector<DIE *, 8> Children;
315315
316316 // We try to create the scope DIE first, then the children DIEs. This will
317317 // avoid creating un-used children then removing them later when we find out
318318 // the scope DIE is null.
319 std::unique_ptr ScopeDIE;
319 DIE *ScopeDIE;
320320 if (Scope->getParent() && isa(DS)) {
321321 ScopeDIE = constructInlinedScopeDIE(Scope);
322322 if (!ScopeDIE)
415415
416416 // This scope represents inlined body of a function. Construct DIE to
417417 // represent this concrete inlined copy of the function.
418 std::unique_ptr
419 DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
418 DIE *DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
420419 assert(Scope->getScopeNode());
421420 auto *DS = Scope->getScopeNode();
422421 auto *InlinedSP = getDISubprogram(DS);
425424 DIE *OriginDIE = DU->getAbstractSPDies()[InlinedSP];
426425 assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
427426
428 auto ScopeDIE = make_unique(dwarf::DW_TAG_inlined_subroutine);
427 auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_inlined_subroutine);
429428 addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
430429
431430 attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
445444
446445 // Construct new DW_TAG_lexical_block for this scope and attach
447446 // DW_AT_low_pc/DW_AT_high_pc labels.
448 std::unique_ptr
449 DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
447 DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
450448 if (DD->isLexicalScopeDIENull(Scope))
451449 return nullptr;
452450
453 auto ScopeDIE = make_unique(dwarf::DW_TAG_lexical_block);
451 auto ScopeDIE = DIE::get(DIEValueAllocator, dwarf::DW_TAG_lexical_block);
454452 if (Scope->isAbstractScope())
455453 return ScopeDIE;
456454
460458 }
461459
462460 /// constructVariableDIE - Construct a DIE for the given DbgVariable.
463 std::unique_ptr DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
464 bool Abstract) {
461 DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV, bool Abstract) {
465462 auto D = constructVariableDIEImpl(DV, Abstract);
466463 DV.setDIE(*D);
467464 return D;
468465 }
469466
470 std::unique_ptr
471 DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
472 bool Abstract) {
467 DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
468 bool Abstract) {
473469 // Define variable debug information entry.
474 auto VariableDie = make_unique(DV.getTag());
470 auto VariableDie = DIE::get(DIEValueAllocator, DV.getTag());
475471
476472 if (Abstract) {
477473 applyVariableAttributes(DV, *VariableDie);
531527 return VariableDie;
532528 }
533529
534 std::unique_ptr DwarfCompileUnit::constructVariableDIE(
535 DbgVariable &DV, const LexicalScope &Scope, DIE *&ObjectPointer) {
530 DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
531 const LexicalScope &Scope,
532 DIE *&ObjectPointer) {
536533 auto Var = constructVariableDIE(DV, Scope.isAbstractScope());
537534 if (DV.isObjectPointer())
538 ObjectPointer = Var.get();
535 ObjectPointer = Var;
539536 return Var;
540537 }
541538
542 DIE *DwarfCompileUnit::createScopeChildrenDIE(
543 LexicalScope *Scope, SmallVectorImpl> &Children,
544 unsigned *ChildScopeCount) {
539 DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
540 SmallVectorImpl &Children,
541 unsigned *ChildScopeCount) {
545542 DIE *ObjectPointer = nullptr;
546543
547544 for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope))
582579 // variadic function.
583580 if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
584581 !includeMinimalInlineScopes())
585 ScopeDIE.addChild(make_unique(dwarf::DW_TAG_unspecified_parameters));
582 ScopeDIE.addChild(
583 DIE::get(DIEValueAllocator, dwarf::DW_TAG_unspecified_parameters));
586584 }
587585
588586 DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
589587 DIE &ScopeDIE) {
590588 // We create children when the scope DIE is not null.
591 SmallVector<std::unique_ptr, 8> Children;
589 SmallVector<DIE *, 8> Children;
592590 DIE *ObjectPointer = createScopeChildrenDIE(Scope, Children);
593591
594592 // Add children
631629 addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
632630 }
633631
634 std::unique_ptr
635 DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity *Module) {
636 std::unique_ptr IMDie = make_unique((dwarf::Tag)Module->getTag());
637 insertDIE(Module, IMDie.get());
632 DIE *DwarfCompileUnit::constructImportedEntityDIE(
633 const DIImportedEntity *Module) {
634 DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());
635 insertDIE(Module, IMDie);
638636 DIE *EntityDie;
639637 auto *Entity = resolve(Module->getEntity());
640638 if (auto *NS = dyn_cast(Entity))
5757
5858 /// \brief Construct a DIE for the given DbgVariable without initializing the
5959 /// DbgVariable's DIE reference.
60 std::unique_ptr constructVariableDIEImpl(const DbgVariable &DV,
61 bool Abstract);
60 DIE *constructVariableDIEImpl(const DbgVariable &DV, bool Abstract);
6261
6362 bool isDwoUnit() const override;
6463
116115 DIE &updateSubprogramScopeDIE(const DISubprogram *SP);
117116
118117 void constructScopeDIE(LexicalScope *Scope,
119 SmallVectorImpl<std::unique_ptr> &FinalChildren);
118 SmallVectorImpl<DIE *> &FinalChildren);
120119
121120 /// \brief A helper function to construct a RangeSpanList for a given
122121 /// lexical scope.
128127 const SmallVectorImpl &Ranges);
129128 /// \brief This scope represents inlined body of a function. Construct
130129 /// DIE to represent this concrete inlined copy of the function.
131 std::unique_ptr constructInlinedScopeDIE(LexicalScope *Scope);
130 DIE *constructInlinedScopeDIE(LexicalScope *Scope);
132131
133132 /// \brief Construct new DW_TAG_lexical_block for this scope and
134133 /// attach DW_AT_low_pc/DW_AT_high_pc labels.
135 std::unique_ptr constructLexicalScopeDIE(LexicalScope *Scope);
134 DIE *constructLexicalScopeDIE(LexicalScope *Scope);
136135
137136 /// constructVariableDIE - Construct a DIE for the given DbgVariable.
138 std::unique_ptr constructVariableDIE(DbgVariable &DV,
139 bool Abstract = false);
140
141 std::unique_ptr constructVariableDIE(DbgVariable &DV,
142 const LexicalScope &Scope,
143 DIE *&ObjectPointer);
137 DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);
138
139 DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,
140 DIE *&ObjectPointer);
144141
145142 /// A helper function to create children of a Scope DIE.
146143 DIE *createScopeChildrenDIE(LexicalScope *Scope,
147 SmallVectorImpl<std::unique_ptr> &Children,
144 SmallVectorImpl<DIE *> &Children,
148145 unsigned *ChildScopeCount = nullptr);
149146
150147 /// \brief Construct a DIE for this subprogram scope.
155152 void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
156153
157154 /// \brief Construct import_module DIE.
158 std::unique_ptr
159 constructImportedEntityDIE(const DIImportedEntity *Module);
155 DIE *constructImportedEntityDIE(const DIImportedEntity *Module);
160156
161157 void finishSubprogramDefinition(const DISubprogram *SP);
162158
110110 assert(Abbrev.hasChildren() && "Children flag not set");
111111
112112 for (auto &Child : Die.children())
113 Offset = computeSizeAndOffset(*Child, Offset);
113 Offset = computeSizeAndOffset(Child, Offset);
114114
115115 // End of children marker.
116116 Offset += sizeof(int8_t);
6565 DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag,
6666 const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW,
6767 DwarfFile *DWU)
68 : UniqueID(UID), CUNode(Node), UnitDie(UnitTag), DebugInfoOffset(0), Asm(A),
69 DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) {
68 : UniqueID(UID), CUNode(Node),
69 UnitDie(*DIE::get(DIEValueAllocator, UnitTag)), DebugInfoOffset(0),
70 Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) {
7071 assert(UnitTag == dwarf::DW_TAG_compile_unit ||
7172 UnitTag == dwarf::DW_TAG_type_unit);
7273 }
292293 DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) {
293294 assert(Tag != dwarf::DW_TAG_auto_variable &&
294295 Tag != dwarf::DW_TAG_arg_variable);
295 DIE &Die = Parent.addChild(make_unique((dwarf::Tag)Tag));
296 DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, (dwarf::Tag)Tag));
296297 if (N)
297298 insertDIE(N, &Die);
298299 return Die;
7676 BumpPtrAllocator DIEValueAllocator;
7777
7878 /// Unit debug information entry.
79 DIE UnitDie;
79 DIE &UnitDie;
8080
8181 /// Offset of the UnitDie from beginning of debug info section.
8282 unsigned DebugInfoOffset;
112112
113113 unsigned getUniqueID() const { return ID; }
114114
115 DIE *getOutputUnitDIE() const { return CUDie.get(); }
116 void setOutputUnitDIE(DIE *Die) { CUDie.reset(Die); }
115 DIE *getOutputUnitDIE() const { return CUDie; }
116 void setOutputUnitDIE(DIE *Die) { CUDie = Die; }
117117
118118 DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
119119 const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
193193 DWARFUnit &OrigUnit;
194194 unsigned ID;
195195 std::vector Info; ///< DIE info indexed by DIE index.
196 std::unique_ptr CUDie; ///< Root of the linked DIE tree.
196 DIE *CUDie; ///< Root of the linked DIE tree.
197197
198198 uint64_t StartOffset;
199199 uint64_t NextUnitOffset;
18601860 assert(Ref > InputDIE.getOffset());
18611861 // We haven't cloned this DIE yet. Just create an empty one and
18621862 // store it. It'll get really cloned when we process it.
1863 RefInfo.Clone = new DIE(dwarf::Tag(RefDie->getTag()));
1863 RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie->getTag()));
18641864 }
18651865 NewRefDie = RefInfo.Clone;
18661866
21622162 // (see cloneDieReferenceAttribute()).
21632163 DIE *Die = Info.Clone;
21642164 if (!Die)
2165 Die = Info.Clone = new DIE(dwarf::Tag(InputDIE.getTag()));
2165 Die = Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag()));
21662166 assert(Die->getTag() == InputDIE.getTag());
21672167 Die->setOffset(OutOffset);
21682168
22542254 for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL();
22552255 Child = Child->getSibling()) {
22562256 if (DIE *Clone = cloneDIE(*Child, Unit, PCOffset, OutOffset)) {
2257 Die->addChild(std::unique_ptr(Clone));
2257 Die->addChild(Clone);
22582258 OutOffset = Clone->getOffset() + Clone->getSize();
22592259 }
22602260 }
3737
3838 TEST_F(DIEHashTest, Data1) {
3939 DIEHash Hash;
40 DIE Die(dwarf::DW_TAG_base_type);
40 DIE &Die = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
4141 DIEInteger Size(4);
4242 Die.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Size);
4343 uint64_t MD5Res = Hash.computeTypeSignature(Die);
4646
4747 // struct {};
4848 TEST_F(DIEHashTest, TrivialType) {
49 DIE Unnamed(dwarf::DW_TAG_structure_type);
49 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
5050 DIEInteger One(1);
5151 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
5252
6161
6262 // struct foo { };
6363 TEST_F(DIEHashTest, NamedType) {
64 DIE Foo(dwarf::DW_TAG_structure_type);
64 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
6565 DIEInteger One(1);
6666 DIEString FooStr = getString("foo");
6767 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
7575
7676 // namespace space { struct foo { }; }
7777 TEST_F(DIEHashTest, NamespacedType) {
78 DIE CU(dwarf::DW_TAG_compile_unit);
79
80 auto Space = make_unique(dwarf::DW_TAG_namespace);
78 DIE &CU = *DIE::get(Alloc, dwarf::DW_TAG_compile_unit);
79
80 auto Space = DIE::get(Alloc, dwarf::DW_TAG_namespace);
8181 DIEInteger One(1);
8282 DIEString SpaceStr = getString("space");
8383 Space->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, SpaceStr);
8686 One);
8787 // sibling?
8888
89 auto Foo = make_unique(dwarf::DW_TAG_structure_type);
89 auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
9090 DIEString FooStr = getString("foo");
9191 Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
9292 Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
103103
104104 // struct { int member; };
105105 TEST_F(DIEHashTest, TypeWithMember) {
106 DIE Unnamed(dwarf::DW_TAG_structure_type);
106 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
107107 DIEInteger Four(4);
108108 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
109109
110 DIE Int(dwarf::DW_TAG_base_type);
110 DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
111111 DIEString IntStr = getString("int");
112112 Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
113113 Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
116116
117117 DIEEntry IntRef(Int);
118118
119 auto Member = make_unique(dwarf::DW_TAG_member);
119 auto Member = DIE::get(Alloc, dwarf::DW_TAG_member);
120120 DIEString MemberStr = getString("member");
121121 Member->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemberStr);
122122 DIEInteger Zero(0);
133133
134134 // struct foo { int mem1, mem2; };
135135 TEST_F(DIEHashTest, ReusedType) {
136 DIE Unnamed(dwarf::DW_TAG_structure_type);
136 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
137137 DIEInteger Eight(8);
138138 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
139139
140140 DIEInteger Four(4);
141 DIE Int(dwarf::DW_TAG_base_type);
141 DIE &Int = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
142142 DIEString IntStr = getString("int");
143143 Int.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, IntStr);
144144 Int.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
147147
148148 DIEEntry IntRef(Int);
149149
150 auto Mem1 = make_unique(dwarf::DW_TAG_member);
150 auto Mem1 = DIE::get(Alloc, dwarf::DW_TAG_member);
151151 DIEString Mem1Str = getString("mem1");
152152 Mem1->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem1Str);
153153 DIEInteger Zero(0);
157157
158158 Unnamed.addChild(std::move(Mem1));
159159
160 auto Mem2 = make_unique(dwarf::DW_TAG_member);
160 auto Mem2 = DIE::get(Alloc, dwarf::DW_TAG_member);
161161 DIEString Mem2Str = getString("mem2");
162162 Mem2->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, Mem2Str);
163163 Mem2->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
173173
174174 // struct foo { static foo f; };
175175 TEST_F(DIEHashTest, RecursiveType) {
176 DIE Foo(dwarf::DW_TAG_structure_type);
176 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
177177 DIEInteger One(1);
178178 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
179179 DIEString FooStr = getString("foo");
180180 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
181181
182 auto Mem = make_unique(dwarf::DW_TAG_member);
182 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
183183 DIEString MemStr = getString("mem");
184184 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
185185 DIEEntry FooRef(Foo);
195195
196196 // struct foo { foo *mem; };
197197 TEST_F(DIEHashTest, Pointer) {
198 DIE Foo(dwarf::DW_TAG_structure_type);
198 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
199199 DIEInteger Eight(8);
200200 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
201201 DIEString FooStr = getString("foo");
202202 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
203203
204 auto Mem = make_unique(dwarf::DW_TAG_member);
204 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
205205 DIEString MemStr = getString("mem");
206206 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
207207 DIEInteger Zero(0);
208208 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
209209 Zero);
210210
211 DIE FooPtr(dwarf::DW_TAG_pointer_type);
211 DIE &FooPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
212212 FooPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
213213 DIEEntry FooRef(Foo);
214214 FooPtr.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooRef);
225225
226226 // struct foo { foo &mem; };
227227 TEST_F(DIEHashTest, Reference) {
228 DIE Foo(dwarf::DW_TAG_structure_type);
228 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
229229 DIEInteger Eight(8);
230230 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
231231 DIEString FooStr = getString("foo");
232232 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
233233
234 auto Mem = make_unique(dwarf::DW_TAG_member);
234 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
235235 DIEString MemStr = getString("mem");
236236 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
237237 DIEInteger Zero(0);
238238 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
239239 Zero);
240240
241 DIE FooRef(dwarf::DW_TAG_reference_type);
241 DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_reference_type);
242242 FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
243243 DIEEntry FooEntry(Foo);
244244 FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
245245
246 DIE FooRefConst(dwarf::DW_TAG_const_type);
246 DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
247247 DIEEntry FooRefRef(FooRef);
248248 FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
249249 FooRefRef);
260260
261261 // struct foo { foo &&mem; };
262262 TEST_F(DIEHashTest, RValueReference) {
263 DIE Foo(dwarf::DW_TAG_structure_type);
263 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
264264 DIEInteger Eight(8);
265265 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
266266 DIEString FooStr = getString("foo");
267267 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
268268
269 auto Mem = make_unique(dwarf::DW_TAG_member);
269 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
270270 DIEString MemStr = getString("mem");
271271 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
272272 DIEInteger Zero(0);
273273 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
274274 Zero);
275275
276 DIE FooRef(dwarf::DW_TAG_rvalue_reference_type);
276 DIE &FooRef = *DIE::get(Alloc, dwarf::DW_TAG_rvalue_reference_type);
277277 FooRef.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
278278 DIEEntry FooEntry(Foo);
279279 FooRef.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
280280
281 DIE FooRefConst(dwarf::DW_TAG_const_type);
281 DIE &FooRefConst = *DIE::get(Alloc, dwarf::DW_TAG_const_type);
282282 DIEEntry FooRefRef(FooRef);
283283 FooRefConst.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
284284 FooRefRef);
295295
296296 // struct foo { foo foo::*mem; };
297297 TEST_F(DIEHashTest, PtrToMember) {
298 DIE Foo(dwarf::DW_TAG_structure_type);
298 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
299299 DIEInteger Eight(8);
300300 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
301301 DIEString FooStr = getString("foo");
302302 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
303303
304 auto Mem = make_unique(dwarf::DW_TAG_member);
304 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
305305 DIEString MemStr = getString("mem");
306306 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
307307 DIEInteger Zero(0);
308308 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
309309 Zero);
310310
311 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
311 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
312312 DIEEntry FooEntry(Foo);
313313 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FooEntry);
314314 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
338338 DIEString MemStr = getString("mem");
339339 uint64_t MD5ResDecl;
340340 {
341 DIE Bar(dwarf::DW_TAG_structure_type);
341 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
342342 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
343343 Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
344344 One);
345345
346 DIE Foo(dwarf::DW_TAG_structure_type);
346 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
347347 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
348348 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
349349
350 auto Mem = make_unique(dwarf::DW_TAG_member);
350 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
351351 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
352352 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
353353 dwarf::DW_FORM_data1, Zero);
354354
355 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
355 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
356356 DIEEntry BarEntry(Bar);
357357 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
358358 BarEntry);
370370 }
371371 uint64_t MD5ResDef;
372372 {
373 DIE Bar(dwarf::DW_TAG_structure_type);
373 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
374374 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
375375 Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
376376
377 DIE Foo(dwarf::DW_TAG_structure_type);
377 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
378378 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
379379 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
380380
381 auto Mem = make_unique(dwarf::DW_TAG_member);
381 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
382382 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
383383 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
384384 dwarf::DW_FORM_data1, Zero);
385385
386 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
386 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
387387 DIEEntry BarEntry(Bar);
388388 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
389389 BarEntry);
416416 DIEString MemStr = getString("mem");
417417 uint64_t MD5ResDecl;
418418 {
419 DIE Bar(dwarf::DW_TAG_structure_type);
419 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
420420 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
421421 Bar.addValue(Alloc, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present,
422422 One);
423423
424 DIE Foo(dwarf::DW_TAG_structure_type);
424 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
425425 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
426426 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
427427
428 auto Mem = make_unique(dwarf::DW_TAG_member);
428 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
429429 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
430430 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
431431 dwarf::DW_FORM_data1, Zero);
432432
433 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
433 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
434434 DIEEntry BarEntry(Bar);
435435 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
436436 BarEntry);
447447 }
448448 uint64_t MD5ResDef;
449449 {
450 DIE Bar(dwarf::DW_TAG_structure_type);
450 DIE &Bar = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
451451 Bar.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, BarStr);
452452 Bar.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
453453
454 DIE Foo(dwarf::DW_TAG_structure_type);
454 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
455455 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
456456 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
457457
458 auto Mem = make_unique(dwarf::DW_TAG_member);
458 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
459459 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
460460 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location,
461461 dwarf::DW_FORM_data1, Zero);
462462
463 DIE PtrToFooMem(dwarf::DW_TAG_ptr_to_member_type);
463 DIE &PtrToFooMem = *DIE::get(Alloc, dwarf::DW_TAG_ptr_to_member_type);
464464 DIEEntry BarEntry(Bar);
465465 PtrToFooMem.addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4,
466466 BarEntry);
492492 DIEString FooStr = getString("foo");
493493 DIEString MemStr = getString("mem");
494494
495 DIE Unnamed(dwarf::DW_TAG_structure_type);
495 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
496496 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
497497
498 DIE Foo(dwarf::DW_TAG_structure_type);
498 DIE &Foo = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
499499 Foo.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Eight);
500500 Foo.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
501501
502 auto Mem = make_unique(dwarf::DW_TAG_member);
502 auto Mem = DIE::get(Alloc, dwarf::DW_TAG_member);
503503 Mem->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, MemStr);
504504 Mem->addValue(Alloc, dwarf::DW_AT_data_member_location, dwarf::DW_FORM_data1,
505505 Zero);
506506
507 DIE UnnamedPtr(dwarf::DW_TAG_pointer_type);
507 DIE &UnnamedPtr = *DIE::get(Alloc, dwarf::DW_TAG_pointer_type);
508508 UnnamedPtr.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
509509 Eight);
510510 DIEEntry UnnamedRef(Unnamed);
523523
524524 // struct { struct foo { }; };
525525 TEST_F(DIEHashTest, NestedType) {
526 DIE Unnamed(dwarf::DW_TAG_structure_type);
526 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
527527 DIEInteger One(1);
528528 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
529529
530 auto Foo = make_unique(dwarf::DW_TAG_structure_type);
530 auto Foo = DIE::get(Alloc, dwarf::DW_TAG_structure_type);
531531 DIEString FooStr = getString("foo");
532532 Foo->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FooStr);
533533 Foo->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
542542
543543 // struct { static void func(); };
544544 TEST_F(DIEHashTest, MemberFunc) {
545 DIE Unnamed(dwarf::DW_TAG_structure_type);
545 DIE &Unnamed = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
546546 DIEInteger One(1);
547547 Unnamed.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, One);
548548
549 auto Func = make_unique(dwarf::DW_TAG_subprogram);
549 auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
550550 DIEString FuncStr = getString("func");
551551 Func->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FuncStr);
552552
562562 // static void func();
563563 // };
564564 TEST_F(DIEHashTest, MemberFuncFlag) {
565 DIE A(dwarf::DW_TAG_structure_type);
565 DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
566566 DIEInteger One(1);
567567 DIEString AStr = getString("A");
568568 A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
570570 A.addValue(Alloc, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data1, One);
571571 A.addValue(Alloc, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data1, One);
572572
573 auto Func = make_unique(dwarf::DW_TAG_subprogram);
573 auto Func = DIE::get(Alloc, dwarf::DW_TAG_subprogram);
574574 DIEString FuncStr = getString("func");
575575 DIEString FuncLinkage = getString("_ZN1A4funcEv");
576576 DIEInteger Two(2);
598598 // };
599599 // A a;
600600 TEST_F(DIEHashTest, MemberSdata) {
601 DIE A(dwarf::DW_TAG_structure_type);
601 DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
602602 DIEInteger One(1);
603603 DIEString AStr = getString("A");
604604 A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
609609 DIEInteger Four(4);
610610 DIEInteger Five(5);
611611 DIEString FStr = getString("int");
612 DIE IntTyDIE(dwarf::DW_TAG_base_type);
612 DIE &IntTyDIE = *DIE::get(Alloc, dwarf::DW_TAG_base_type);
613613 IntTyDIE.addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1, Four);
614614 IntTyDIE.addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Five);
615615 IntTyDIE.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
616616
617617 DIEEntry IntTy(IntTyDIE);
618 auto PITyDIE = make_unique(dwarf::DW_TAG_const_type);
618 auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
619619 PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IntTy);
620620
621621 DIEEntry PITy(*PITyDIE);
622 auto PI = make_unique(dwarf::DW_TAG_member);
622 auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
623623 DIEString PIStr = getString("PI");
624624 DIEInteger Two(2);
625625 DIEInteger NegThree(-3);
644644 // };
645645 // A a;
646646 TEST_F(DIEHashTest, MemberBlock) {
647 DIE A(dwarf::DW_TAG_structure_type);
647 DIE &A = *DIE::get(Alloc, dwarf::DW_TAG_structure_type);
648648 DIEInteger One(1);
649649 DIEString AStr = getString("A");
650650 A.addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, AStr);
654654
655655 DIEInteger Four(4);
656656 DIEString FStr = getString("float");
657 auto FloatTyDIE = make_unique(dwarf::DW_TAG_base_type);
657 auto FloatTyDIE = DIE::get(Alloc, dwarf::DW_TAG_base_type);
658658 FloatTyDIE->addValue(Alloc, dwarf::DW_AT_byte_size, dwarf::DW_FORM_data1,
659659 Four);
660660 FloatTyDIE->addValue(Alloc, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
661661 Four);
662662 FloatTyDIE->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, FStr);
663
664663 DIEEntry FloatTy(*FloatTyDIE);
665 auto PITyDIE = make_unique(dwarf::DW_TAG_const_type);
664 auto PITyDIE = DIE::get(Alloc, dwarf::DW_TAG_const_type);
666665 PITyDIE->addValue(Alloc, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, FloatTy);
667666
668667 DIEEntry PITy(*PITyDIE);
669 auto PI = make_unique(dwarf::DW_TAG_member);
668 auto PI = DIE::get(Alloc, dwarf::DW_TAG_member);
670669 DIEString PIStr = getString("PI");
671670 DIEInteger Two(2);
672671 PI->addValue(Alloc, dwarf::DW_AT_name, dwarf::DW_FORM_strp, PIStr);