30#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
37 while (!Worklist.
empty()) {
53 CU.getDIEInfo(Child.getDebugInfoEntry());
57 if (!ParentPlainDieIsKept && ChildPlainDieIsKept)
59 "Found invalid link in keep chain");
61 if (Child.getTag() == dwarf::DW_TAG_subprogram) {
63 &
CU, Child.getDebugInfoEntry()))) {
65 "Live subprogram is not marked as kept");
69 if (!ChildInfo.getODRAvailable()) {
70 assert(!ChildTypeDieIsKept);
74 if (!ParentTypeDieIsKept && ChildTypeDieIsKept)
76 "Found invalid link in keep chain");
78 if (CurrentInfo.getIsInAnonNamespaceScope() &&
81 "Found invalid placement marking for member "
82 "of anonymous namespace");
87 if (!BrokenLinks.
empty()) {
89 errs() <<
"\n=================================\n";
91 Link.Parent.getOffset(),
92 Link.Child.getOffset());
94 errs() <<
"\nParent:";
95 Link.Parent.dump(
errs(), 0, {});
97 CU.getDIEInfo(Link.Parent).dump();
100 Link.Child.dump(
errs(), 2, {});
102 CU.getDIEInfo(Link.Child).dump();
110 switch (Entry->getTag()) {
111 case dwarf::DW_TAG_compile_unit:
112 case dwarf::DW_TAG_module:
113 case dwarf::DW_TAG_namespace:
122 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
131 "recorded subtrees would be walked in a different resolution mode");
138 std::nullopt,
false);
142 HasNewInterconnectedCUs);
147 std::optional<UnitEntryPairTy> ReferencedBy,
151 ReferencedTypeDieEntry);
159 const UnitEntryPairTy &Entry, std::optional<UnitEntryPairTy> ReferencedBy,
162 Entry.CU->getFirstChildEntry(Entry.DieEntry);
164 CurChild = Entry.CU->getSiblingEntry(CurChild)) {
168 bool IsLiveChild =
false;
170 switch (CurChild->getTag()) {
171 case dwarf::DW_TAG_label: {
176 if (IsLiveChild || (IsLiveParent && ChildInfo.getHasAnAddress())) {
182 case dwarf::DW_TAG_subprogram: {
190 (ChildInfo.getIsInMouduleScope() && ChildInfo.getODRAvailable())
197 case dwarf::DW_TAG_constant:
198 case dwarf::DW_TAG_variable: {
207 (ChildInfo.getIsInMouduleScope() && ChildInfo.getODRAvailable())
214 case dwarf::DW_TAG_base_type: {
220 case dwarf::DW_TAG_imported_module:
221 case dwarf::DW_TAG_imported_declaration:
222 case dwarf::DW_TAG_imported_unit: {
224 if (Entry.DieEntry->getTag() == dwarf::DW_TAG_compile_unit) {
235 case dwarf::DW_TAG_type_unit:
236 case dwarf::DW_TAG_partial_unit:
237 case dwarf::DW_TAG_compile_unit: {
261 if (!Entry.CU->isClangModule() &&
262 Entry.DieEntry->getTag() == dwarf::DW_TAG_module &&
278 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
287 HasNewInterconnectedCUs)) {
326 std::atomic<bool> HasNewInterconnectedCUs =
false;
328 Ref.Action,
Ref.ReferencedBy,
Ref.Subtree,
331 assert(Res && !HasNewInterconnectedCUs &&
"record-deps-only walk failed");
351 ReferencedTypeDieEntry ? ReferencedTypeDieEntry : Root.
DieEntry;
368 bool HasNewDependency =
false;
371 Ref.ReferencedBy.CU->getDIEInfo(
Ref.ReferencedBy.DieEntry);
385 HasNewDependency =
true;
391 return HasNewDependency;
397 bool HasNewDependency =
false;
399 assert(Root.hasReferencedByOtherEntry() &&
400 "Root entry without dependency inside the dependencies list");
403 Root.getReferencedTypeDieEntry(),
404 Root.getReferencedByEntry()))
405 HasNewDependency =
true;
409 HasNewDependency =
true;
411 return HasNewDependency;
418 !Info.getKeepTypeChildren())
422 Info.unsetKeepTypeChildren();
426 Entry.CU->getFirstChildEntry(Entry.DieEntry);
428 CurChild = Entry.CU->getSiblingEntry(CurChild))
437 switch (NewPlacement) {
439 return Info.needToPlaceInTypeTable();
442 return Info.needToKeepInPlainDwarf();
445 return Info.needToPlaceInTypeTable() && Info.needToKeepInPlainDwarf();
456 return isAlreadyMarked(Entry.CU->getDIEInfo(Entry.DieEntry), NewPlacement);
461 if (Entry.DieEntry->getAbbreviationDeclarationPtr() ==
nullptr)
466 bool NeedKeepPlainChildren = Info.needToKeepInPlainDwarf();
468 bool AreTypeParentsDone = !NeedKeepTypeChildren;
469 bool ArePlainParentsDone = !NeedKeepPlainChildren;
472 std::optional<uint32_t> ParentIdx = Entry.DieEntry->getParentIdx();
475 Entry.CU->getDebugInfoEntry(*ParentIdx);
478 if (!AreTypeParentsDone && NeedKeepTypeChildren) {
479 if (ParentInfo.getKeepTypeChildren())
480 AreTypeParentsDone =
true;
484 ParentInfo.setKeepTypeChildren();
493 if (!ArePlainParentsDone && NeedKeepPlainChildren) {
494 if (ParentInfo.getKeepPlainChildren())
495 ArePlainParentsDone =
true;
499 ParentInfo.setKeepPlainChildren();
508 if (AreTypeParentsDone && ArePlainParentsDone)
516struct FinalPlacement {
551 if (!EntryInfo.getODRAvailable())
554 if (Entry.DieEntry->getTag() == dwarf::DW_TAG_variable) {
564 Entry.CU->find(Entry.DieEntry, dwarf::DW_AT_declaration), 0);
565 bool ParentIsType =
false;
567 if (std::optional<uint32_t> ParentIdx = Entry.DieEntry->getParentIdx()) {
569 Entry.CU->getDebugInfoEntry(*ParentIdx)->getTag();
570 ParentIsType = ParentTag == dwarf::DW_TAG_class_type ||
571 ParentTag == dwarf::DW_TAG_structure_type ||
572 ParentTag == dwarf::DW_TAG_union_type;
575 if (IsDeclaration && ParentIsType) {
587 return {
Placement, FinalPlacement::JoinVariable};
590 return {
Placement, FinalPlacement::Join};
596 std::atomic<bool> &HasNewInterconnectedCUs,
TreeWalkKindTy Kind) {
597 if (Entry.DieEntry->getAbbreviationDeclarationPtr() ==
nullptr)
609 "Wrong kind of placement for ODR unavailable entry");
630 switch (Final.Mode) {
631 case FinalPlacement::Overwrite:
634 case FinalPlacement::Join:
637 case FinalPlacement::JoinVariable:
646 bool IsSubprogram = Entry.DieEntry->getTag() == dwarf::DW_TAG_subprogram;
660 InterCUProcessingStarted,
661 HasNewInterconnectedCUs, FinalKind))
665 if (isSingleAction(Action))
670 if (Entry.DieEntry->getTag() == dwarf::DW_TAG_subprogram &&
671 Info.getODRAvailable()) {
682 Entry.CU->getFirstChildEntry(Entry.DieEntry);
684 CurChild = Entry.CU->getSiblingEntry(CurChild)) {
687 switch (CurChild->getTag()) {
688 case dwarf::DW_TAG_variable:
689 case dwarf::DW_TAG_constant:
690 case dwarf::DW_TAG_subprogram:
691 case dwarf::DW_TAG_label: {
692 if (ChildInfo.getHasAnAddress())
697 case dwarf::DW_TAG_lexical_block:
698 case dwarf::DW_TAG_friend:
699 case dwarf::DW_TAG_inheritance:
700 case dwarf::DW_TAG_formal_parameter:
701 case dwarf::DW_TAG_unspecified_parameters:
702 case dwarf::DW_TAG_template_type_parameter:
703 case dwarf::DW_TAG_template_value_parameter:
704 case dwarf::DW_TAG_GNU_template_parameter_pack:
705 case dwarf::DW_TAG_GNU_formal_parameter_pack:
706 case dwarf::DW_TAG_GNU_template_template_param:
707 case dwarf::DW_TAG_thrown_type: {
728 InterCUProcessingStarted, HasNewInterconnectedCUs, FinalKind))
737 Entry.CU->getFirstChildEntry(Entry.DieEntry);
739 CurChild = Entry.CU->getSiblingEntry(CurChild)) {
741 switch (CurChild->getTag()) {
742 case dwarf::DW_TAG_variable:
743 case dwarf::DW_TAG_constant:
744 case dwarf::DW_TAG_subprogram:
745 case dwarf::DW_TAG_label: {
746 if (ChildInfo.getHasAnAddress())
755 InterCUProcessingStarted, HasNewInterconnectedCUs, FinalKind))
768 case dwarf::DW_TAG_imported_module:
769 case dwarf::DW_TAG_imported_declaration:
770 case dwarf::DW_TAG_imported_unit:
771 case dwarf::DW_TAG_array_type:
772 case dwarf::DW_TAG_class_type:
773 case dwarf::DW_TAG_enumeration_type:
774 case dwarf::DW_TAG_pointer_type:
775 case dwarf::DW_TAG_reference_type:
776 case dwarf::DW_TAG_string_type:
777 case dwarf::DW_TAG_structure_type:
778 case dwarf::DW_TAG_subroutine_type:
779 case dwarf::DW_TAG_typedef:
780 case dwarf::DW_TAG_union_type:
781 case dwarf::DW_TAG_variant:
782 case dwarf::DW_TAG_module:
783 case dwarf::DW_TAG_ptr_to_member_type:
784 case dwarf::DW_TAG_set_type:
785 case dwarf::DW_TAG_subrange_type:
786 case dwarf::DW_TAG_base_type:
787 case dwarf::DW_TAG_const_type:
788 case dwarf::DW_TAG_enumerator:
789 case dwarf::DW_TAG_file_type:
790 case dwarf::DW_TAG_packed_type:
791 case dwarf::DW_TAG_thrown_type:
792 case dwarf::DW_TAG_volatile_type:
793 case dwarf::DW_TAG_dwarf_procedure:
794 case dwarf::DW_TAG_restrict_type:
795 case dwarf::DW_TAG_interface_type:
796 case dwarf::DW_TAG_namespace:
797 case dwarf::DW_TAG_unspecified_type:
798 case dwarf::DW_TAG_shared_type:
799 case dwarf::DW_TAG_rvalue_reference_type:
800 case dwarf::DW_TAG_coarray_type:
801 case dwarf::DW_TAG_dynamic_type:
802 case dwarf::DW_TAG_atomic_type:
803 case dwarf::DW_TAG_immutable_type:
804 case dwarf::DW_TAG_function_template:
805 case dwarf::DW_TAG_class_template:
813 std::atomic<bool> &HasNewInterconnectedCUs,
TreeWalkKindTy Kind) {
814 const auto *Abbrev = Entry.DieEntry->getAbbreviationDeclarationPtr();
815 if (Abbrev ==
nullptr)
828 ReferencedTypeDieEntry);
836 {RootAction, Root, ReferencedTypeDieEntry});
843 ReferencedTypeDieEntry);
849 DWARFUnit &Unit = Entry.CU->getOrigUnit();
855 for (
const auto &AttrSpec : Abbrev->attributes()) {
858 AttrSpec.Attr == dwarf::DW_AT_sibling) {
860 Unit.getFormParams());
866 std::optional<UnitEntryPairTy> RefDie = Entry.CU->resolveDIEReference(
867 Val, InterCUProcessingStarted
871 Entry.CU->warn(
"could not find referenced DIE", Entry.DieEntry);
875 if (!RefDie->DieEntry) {
883 RefDie->CU->setInterconnectedCU();
884 Entry.CU->setInterconnectedCU();
885 HasNewInterconnectedCUs =
true;
889 assert((Entry.CU->getUniqueID() == RefDie->CU->getUniqueID() ||
890 InterCUProcessingStarted) &&
891 "Inter-CU reference while inter-CU processing is not started");
894 if (!RefInfo.getODRAvailable())
896 else if (RefInfo.getODRAvailable() &&
907 if (AttrSpec.Attr == dwarf::DW_AT_import) {
916 AddRoot(Action, *RefDie,
nullptr);
925 AddRoot(Action, RootForReferencedDie, RefDie->DieEntry);
936 switch (Entry.DieEntry->getTag()) {
937 case dwarf::DW_TAG_subprogram:
938 case dwarf::DW_TAG_label:
939 case dwarf::DW_TAG_variable:
940 case dwarf::DW_TAG_constant: {
949 std::optional<uint32_t> ParentIdx = Result.DieEntry->getParentIdx();
954 Result.CU->getDebugInfoEntry(*ParentIdx);
957 Result.DieEntry = ParentEntry;
966 outs() <<
"Keeping " << Kind <<
" DIE:";
978 if (Info.getTrackLiveness()) {
979 const auto *Abbrev =
DIE.getAbbreviationDeclarationPtr();
981 if (!Info.getIsInFunctionScope() &&
982 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) {
990 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
991 Entry.CU->getContainingFile().Addresses->getVariableRelocAdjustment(
992 DIE, Entry.CU->getGlobalData().getOptions().Verbose);
994 if (LocExprAddrAndRelocAdjustment.first)
995 Info.setHasAnAddress();
997 if (!LocExprAddrAndRelocAdjustment.second)
1000 if (!IsLiveParent && Info.getIsInFunctionScope() &&
1001 !Entry.CU->getGlobalData().getOptions().KeepFunctionForStatic)
1005 Info.setHasAnAddress();
1007 dumpKeptDIE(
DIE,
"variable", Entry.CU->getGlobalData().getOptions().Verbose);
1015 std::optional<DWARFFormValue> LowPCVal =
DIE.find(dwarf::DW_AT_low_pc);
1017 const bool Verbose = Entry.CU->getGlobalData().getOptions().Verbose;
1018 std::optional<uint64_t> LowPc;
1019 std::optional<uint64_t> HighPc;
1020 std::optional<int64_t> RelocAdjustment;
1021 if (Info.getTrackLiveness()) {
1026 Info.setHasAnAddress();
1029 Entry.CU->getContainingFile().Addresses->getSubprogramRelocAdjustment(
1031 if (!RelocAdjustment)
1034 if (
DIE.
getTag() == dwarf::DW_TAG_subprogram) {
1037 HighPc =
DIE.getHighPC(*LowPc);
1039 Entry.CU->warn(
"function without high_pc. Range will be discarded.",
1044 if (*LowPc > *HighPc) {
1045 Entry.CU->warn(
"low_pc greater than high_pc. Range will be discarded.",
1049 }
else if (
DIE.
getTag() == dwarf::DW_TAG_label) {
1050 if (Entry.CU->hasLabelAt(*LowPc))
1067 Entry.CU->getOrigUnit().getUnitDIE().find(dwarf::DW_AT_language), 0);
1068 if (Language == dwarf::DW_LANG_Mips_Assembler ||
1069 Language == dwarf::DW_LANG_Assembly) {
1070 if (
auto Range = Entry.CU->getContainingFile()
1071 .Addresses->getSymbolRangeForAddress(*LowPc))
1072 Entry.CU->addFunctionRange(
Range->LowPC,
Range->HighPC,
1076 Entry.CU->addLabelLowPc(*LowPc, *RelocAdjustment);
1079 Info.setHasAnAddress();
1083 if (!Info.getTrackLiveness() ||
DIE.
getTag() == dwarf::DW_TAG_label)
1086 Entry.CU->addFunctionRange(
1088 Entry.CU->getContainingFile().Addresses->constrainCodeRangeHighPC(
1089 *LowPc, *HighPc, *RelocAdjustment),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
bool isAlreadyMarked(const CompileUnit::DIEInfo &Info, CompileUnit::DieOutputPlacement NewPlacement)
static void dumpKeptDIE(const DWARFDie &DIE, StringRef Kind, bool Verbose)
static FinalPlacement getFinalPlacementForEntry(const UnitEntryPairTy &Entry, CompileUnit::DieOutputPlacement Placement)
static bool isNamespaceLikeEntry(const DWARFDebugInfoEntry *Entry)
Branch Probability Basic Block Placement
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file provides utility classes that use RAII to save and restore values.
A pointer to another debug information entry.
A structured debug information entry.
dwarf::Tag getTag() const
LLVM_ABI void dump() const
DWARFDebugInfoEntry - A DIE with only the minimum required data.
std::optional< uint32_t > getParentIdx() const
Returns index of the parent die.
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
iterator_range< iterator > children() const
const DWARFDebugInfoEntry * getDebugInfoEntry() const
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
static LLVM_ABI raw_ostream & error()
Convenience method for printing "error: " to stderr.
DieOutputPlacement
Kinds of placement for the output die.
@ Both
Corresponding DIE goes to type table and to plain dwarf.
@ TypeTable
Corresponding DIE goes to the type table only.
@ PlainDwarf
Corresponding DIE goes to the plain dwarf only.
Class keeping live worklist item data.
UnitEntryPairTy getRootEntry() const
LiveRootWorklistActionTy getAction() const
bool hasReferencedByOtherEntry() const
bool markDIEEntryAsKeptRec(LiveRootWorklistActionTy Action, const UnitEntryPairTy &RootEntry, const UnitEntryPairTy &Entry, bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs, TreeWalkKindTy Kind=TreeWalkKindTy::MarkTree)
Mark whole DIE tree as kept recursively.
void verifyKeepChain()
Recursively walk the DIE tree and check "keepness" and "placement" information.
RootEntriesListTy Dependencies
List of entries dependencies.
void markParentsAsKeepingChildren(const UnitEntryPairTy &Entry)
Mark parents as keeping children.
UnitEntryPairTy getRootForSpecifiedEntry(UnitEntryPairTy Entry)
static bool recordsDepsOnly(TreeWalkKindTy Kind)
bool demoteIfIncomplete(const UnitEntryPairTy &Root, const DWARFDebugInfoEntry *ReferencedTypeDieEntry, const UnitEntryPairTy &ReferencedBy)
Demote ReferencedBy to plain DWARF if it may not stay in the type table while the DIE it references t...
bool markCollectedLiveRootsAsKept(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)
Examine worklist and mark all 'root DIE's as kept and set "Placement" property.
bool InterCUProcessingWasStarted
Whether inter-unit references could be resolved during marking.
bool applySubtreeSummaries()
Apply each summarized subtree's dependencies to every root recorded as referencing it.
bool isLiveAction(LiveRootWorklistActionTy Action)
bool isChildrenAction(LiveRootWorklistActionTy Action)
TreeWalkKindTy
What a tree walk does, and for a walk that only records dependencies, which root the dependencies it ...
@ MarkTree
Mark the tree as kept and schedule the roots it references.
@ RecordSubtreeDeps
Do not mark.
@ RecordNestedSubprogramDeps
Do not mark.
bool isTypeAction(LiveRootWorklistActionTy Action)
void addActionToRootEntriesWorkList(LiveRootWorklistActionTy Action, const UnitEntryPairTy &Entry, std::optional< UnitEntryPairTy > ReferencedBy, const DWARFDebugInfoEntry *ReferencedTypeDieEntry=nullptr)
Add action item to the work list.
DenseMap< SubtreeDependenciesKeyTy, SubtreeDependenciesTy > SubtreeSummaries
Dependency summaries of already-marked subtrees, keyed by subtree and action.
SubtreeDependenciesTy * CollectedSubtreeDeps
Where the walk in progress collects the dependencies that belong to the root referencing the walked s...
bool isTypeTableCandidate(const DWARFDebugInfoEntry *DIEEntry)
size_t MaterializedRefs
Number of leading SubtreeDependencyRefs whose subtree is summarized.
void setPlainDwarfPlacementRec(const UnitEntryPairTy &Entry)
Mark whole DIE tree as placed in "PlainDwarf".
RootEntriesListTy RootEntriesWorkList
List of entries which are 'root DIE's.
SmallVector< SubtreeDependencyTy > SubtreeDependenciesTy
static bool isLiveSubprogramEntry(const UnitEntryPairTy &Entry)
Returns true if specified subprogram references live code section.
std::tuple< CompileUnit *, const DWARFDebugInfoEntry *, LiveRootWorklistActionTy > SubtreeDependenciesKeyTy
A subtree paired with the action it is walked with, which selects both the visited children and the a...
void recordSubtreeDependencies(LiveRootWorklistActionTy Action, const UnitEntryPairTy &RootEntry, const UnitEntryPairTy &Entry)
Record that RootEntry references the already-marked subtree Entry, and therefore carries the complete...
bool resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)
Recursively walk the DIE tree and look for DIEs to keep.
static bool isLiveVariableEntry(const UnitEntryPairTy &Entry, bool IsLiveParent)
Returns true if specified variable references live code section.
@ MarkSingleTypeEntry
Mark current item as type entry.
@ MarkSingleLiveEntry
Mark current item as live entry.
@ MarkTypeEntryRec
Mark current item and all its children as type entry.
@ MarkLiveChildrenRec
Mark all children of current item as live entry.
@ MarkLiveEntryRec
Mark current item and all its children as live entry.
@ MarkTypeChildrenRec
Mark all children of current item as type entry.
SmallVector< SubtreeDependencyRefTy > SubtreeDependencyRefs
Roots referencing an already-marked subtree.
void collectRootsToKeep(const UnitEntryPairTy &Entry, std::optional< UnitEntryPairTy > ReferencedBy, bool IsLiveParent)
This function navigates DIEs tree starting from specified Entry.
bool maybeAddReferencedRoots(LiveRootWorklistActionTy Action, const UnitEntryPairTy &RootEntry, const UnitEntryPairTy &Entry, bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs, TreeWalkKindTy Kind=TreeWalkKindTy::MarkTree)
Check referenced DIEs and add them into the worklist.
bool updateDependenciesCompleteness()
Check if dependencies have incompatible placement.
void materializeSubtreeSummaries()
Walk every subtree that a recorded reference stands for, once per subtree and action,...
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ArrayRef< dwarf::Attribute > getODRAttributes()
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
LLVM_ABI unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
BrokenLink(DWARFDie Parent, DWARFDie Child, const char *Message)
A broken link in the keep chain.
Container for dump options that control which debug information will be dumped.
unsigned ChildRecurseDepth
A utility class that uses RAII to save and restore the value of a variable.
Information gathered about a DIE in the object file.
Information gathered about source DIEs.
void setPlacement(DieOutputPlacement Placement)
Sets Placement kind for the corresponding die.
bool needToKeepInPlainDwarf() const
bool needToPlaceInTypeTable() const
A root referencing an already-marked subtree, standing in for all of that subtree's dependencies.
A completeness dependency of a subtree that belongs to whichever root references the subtree,...
const DWARFDebugInfoEntry * ReferencedTypeDieEntry
This is a helper structure which keeps a debug info entry with it's containing compilation unit.
const DWARFDebugInfoEntry * DieEntry