23 std::optional<std::pair<size_t, size_t>> ChildIndex) {
26 assert(Info.needToPlaceInTypeTable() &&
27 "Cann't assign name for non-type DIE");
45 if (CurChild->getTag() == dwarf::DW_TAG_subrange_type ||
46 CurChild->getTag() == dwarf::DW_TAG_generic_subrange) {
48 if (std::optional<DWARFFormValue> Val =
49 InputUnitEntryPair.
CU->
find(CurChild, dwarf::DW_AT_count)) {
50 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
52 }
else if (std::optional<int64_t> ConstVal =
53 Val->getAsSignedConstant()) {
65 bool addTemplateParameters) {
79 if (addTemplateParameters &&
80 (ChildTag == dwarf::DW_TAG_template_type_parameter ||
81 ChildTag == dwarf::DW_TAG_template_value_parameter))
83 else if (ChildTag == dwarf::DW_TAG_formal_parameter ||
84 ChildTag == dwarf::DW_TAG_unspecified_parameters)
86 else if (addTemplateParameters &&
87 ChildTag == dwarf::DW_TAG_GNU_template_parameter_pack) {
92 TemplateParameters.
push_back(CurGNUChild);
93 }
else if (ChildTag == dwarf::DW_TAG_GNU_formal_parameter_pack) {
98 FunctionParameters.
push_back(CurGNUChild);
135 if (!TemplateParameters.
empty()) {
141 if (Parameter->getTag() == dwarf::DW_TAG_template_value_parameter) {
142 if (std::optional<DWARFFormValue> Val =
143 CU.find(Parameter, dwarf::DW_AT_const_value)) {
144 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant())
146 else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant())
161 std::pair<size_t, size_t> ChildIdx) {
170static std::optional<UnitEntryPairTy>
173 case dwarf::DW_TAG_null:
174 case dwarf::DW_TAG_compile_unit:
175 case dwarf::DW_TAG_partial_unit:
176 case dwarf::DW_TAG_type_unit:
177 case dwarf::DW_TAG_skeleton_unit: {
180 case dwarf::DW_TAG_namespace: {
182 if (UnitEntryPair.
CU->
find(UnitEntryPair.
DieEntry, dwarf::DW_AT_extension))
186 if (!UnitEntryPair.
CU->
find(UnitEntryPair.
DieEntry, dwarf::DW_AT_name))
189 return UnitEntryPair;
192 return UnitEntryPair;
198 std::optional<UnitEntryPairTy> UnitEntryPair = InputUnitEntryPair.
getParent();
207 UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry)) {
216 Parents.push_back(*UnitEntryPair);
218 UnitEntryPair = UnitEntryPair->getParent();
226 }
while (!UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry));
243 if (std::optional<DWARFFormValue> DeclFileVal = InputUnitEntryPair.
CU->
find(
244 InputUnitEntryPair.
DieEntry, dwarf::DW_AT_decl_file)) {
245 if (std::optional<DWARFFormValue> DeclLineVal = InputUnitEntryPair.
CU->
find(
246 InputUnitEntryPair.
DieEntry, dwarf::DW_AT_decl_line)) {
247 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
253 if (std::optional<uint64_t> DeclLineIntVal =
259 HasDeclFileName =
true;
267 if (std::optional<DWARFFormValue> Val =
269 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
272 }
else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant()) {
282 std::optional<DWARFFormValue> AttrValue =
287 std::optional<UnitEntryPairTy> RefDie =
290 if (RefDie && !RefDie->DieEntry)
292 "cannot resolve DIE reference");
299 "cannot parse input DWARF: recursive dependence");
306 bool FirstIteration =
true;
321 addDIETypeName(**RefDie, std::nullopt, AssignNameToTypeDescriptor))
324 FirstIteration =
false;
331 bool AddParentNames) {
332 bool HasLinkageName =
false;
333 bool HasShortName =
false;
334 bool HasTemplatesInShortName =
false;
335 bool HasDeclFileName =
false;
338 if (std::optional<DWARFFormValue> Val = InputUnitEntryPair.
CU->
find(
340 {dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_AT_linkage_name})) {
343 HasLinkageName =
true;
344 }
else if (std::optional<DWARFFormValue> Val = InputUnitEntryPair.
CU->
find(
345 InputUnitEntryPair.
DieEntry, dwarf::DW_AT_name)) {
351 HasTemplatesInShortName =
352 Name.ends_with(
">") && Name.count(
"<") != 0 && !Name.ends_with(
"<=>");
365 case dwarf::DW_TAG_union_type:
366 case dwarf::DW_TAG_interface_type:
367 case dwarf::DW_TAG_class_type:
368 case dwarf::DW_TAG_structure_type:
369 case dwarf::DW_TAG_subroutine_type:
370 case dwarf::DW_TAG_subprogram: {
372 dwarf::DW_AT_artificial))
380 addSignature(InputUnitEntryPair, !HasTemplatesInShortName))
383 case dwarf::DW_TAG_coarray_type:
384 case dwarf::DW_TAG_array_type: {
387 case dwarf::DW_TAG_subrange_type: {
390 case dwarf::DW_TAG_template_value_parameter: {
391 if (!HasTemplatesInShortName) {
393 addValueName(InputUnitEntryPair, dwarf::DW_AT_const_value);
403 if ((!HasLinkageName && !HasShortName && !HasDeclFileName) ||
417 std::optional<std::pair<size_t, size_t>> ChildIndex,
418 bool AssignNameToTypeDescriptor) {
419 std::optional<UnitEntryPairTy> UnitEntryPair =
445 if (AssignNameToTypeDescriptor) {
472 CU.getFirstChildEntry(InputUnitEntryPair.
DieEntry);
473 CurChild && CurChild->getAbbreviationDeclarationPtr();
474 CurChild =
CU.getSiblingEntry(CurChild)) {
481 if (std::optional<DWARFFormValue> Val =
482 CU.find(CurChild, dwarf::DW_AT_name))
516 if (std::optional<DWARFFormValue> Val =
517 Type.CU->find(
Type.DieEntry, dwarf::DW_AT_name)) {
520 if (
Type.DieEntry->getTag() == dwarf::DW_TAG_array_type)
534 switch (DieEntry->
getTag()) {
535 case dwarf::DW_TAG_base_type: {
538 case dwarf::DW_TAG_namespace: {
541 case dwarf::DW_TAG_formal_parameter: {
545 case dwarf::DW_TAG_unspecified_parameters: {
548 case dwarf::DW_TAG_template_type_parameter: {
552 case dwarf::DW_TAG_template_value_parameter: {
555 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
558 case dwarf::DW_TAG_GNU_template_parameter_pack: {
561 case dwarf::DW_TAG_inheritance: {
564 case dwarf::DW_TAG_array_type: {
567 case dwarf::DW_TAG_class_type: {
570 case dwarf::DW_TAG_enumeration_type: {
573 case dwarf::DW_TAG_imported_declaration: {
576 case dwarf::DW_TAG_member: {
584 case dwarf::DW_TAG_pointer_type: {
587 case dwarf::DW_TAG_reference_type: {
590 case dwarf::DW_TAG_string_type: {
593 case dwarf::DW_TAG_structure_type: {
596 case dwarf::DW_TAG_subroutine_type: {
599 case dwarf::DW_TAG_typedef: {
602 case dwarf::DW_TAG_union_type: {
605 case dwarf::DW_TAG_variant: {
608 case dwarf::DW_TAG_inlined_subroutine: {
611 case dwarf::DW_TAG_module: {
614 case dwarf::DW_TAG_ptr_to_member_type: {
617 case dwarf::DW_TAG_set_type: {
620 case dwarf::DW_TAG_subrange_type: {
623 case dwarf::DW_TAG_with_stmt: {
626 case dwarf::DW_TAG_access_declaration: {
629 case dwarf::DW_TAG_catch_block: {
632 case dwarf::DW_TAG_const_type: {
635 case dwarf::DW_TAG_constant: {
638 case dwarf::DW_TAG_enumerator: {
641 case dwarf::DW_TAG_file_type: {
644 case dwarf::DW_TAG_friend: {
647 case dwarf::DW_TAG_namelist: {
650 case dwarf::DW_TAG_namelist_item: {
653 case dwarf::DW_TAG_packed_type: {
656 case dwarf::DW_TAG_subprogram: {
659 case dwarf::DW_TAG_thrown_type: {
662 case dwarf::DW_TAG_variant_part: {
665 case dwarf::DW_TAG_variable: {
668 case dwarf::DW_TAG_volatile_type: {
671 case dwarf::DW_TAG_dwarf_procedure: {
674 case dwarf::DW_TAG_restrict_type: {
677 case dwarf::DW_TAG_interface_type: {
680 case dwarf::DW_TAG_imported_module: {
683 case dwarf::DW_TAG_unspecified_type: {
686 case dwarf::DW_TAG_imported_unit: {
689 case dwarf::DW_TAG_condition: {
692 case dwarf::DW_TAG_shared_type: {
695 case dwarf::DW_TAG_rvalue_reference_type: {
698 case dwarf::DW_TAG_template_alias: {
701 case dwarf::DW_TAG_coarray_type: {
704 case dwarf::DW_TAG_generic_subrange: {
707 case dwarf::DW_TAG_dynamic_type: {
710 case dwarf::DW_TAG_atomic_type: {
713 case dwarf::DW_TAG_call_site: {
716 case dwarf::DW_TAG_call_site_parameter: {
719 case dwarf::DW_TAG_immutable_type: {
722 case dwarf::DW_TAG_entry_point: {
725 case dwarf::DW_TAG_label: {
728 case dwarf::DW_TAG_lexical_block: {
731 case dwarf::DW_TAG_common_block: {
734 case dwarf::DW_TAG_common_inclusion: {
737 case dwarf::DW_TAG_try_block: {
741 case dwarf::DW_TAG_null: {
744 case dwarf::DW_TAG_compile_unit: {
747 case dwarf::DW_TAG_partial_unit: {
750 case dwarf::DW_TAG_type_unit: {
753 case dwarf::DW_TAG_skeleton_unit: {
767 switch (DieEntry->
getTag()) {
768 case dwarf::DW_TAG_array_type:
769 case dwarf::DW_TAG_coarray_type:
770 case dwarf::DW_TAG_class_type:
771 case dwarf::DW_TAG_common_block:
772 case dwarf::DW_TAG_lexical_block:
773 case dwarf::DW_TAG_structure_type:
774 case dwarf::DW_TAG_subprogram:
775 case dwarf::DW_TAG_subroutine_type:
776 case dwarf::DW_TAG_union_type:
777 case dwarf::DW_TAG_GNU_template_template_param:
778 case dwarf::DW_TAG_GNU_formal_parameter_pack:
779 case dwarf::DW_TAG_GNU_template_parameter_pack: {
782 case dwarf::DW_TAG_enumeration_type: {
794 CurChild && CurChild->getAbbreviationDeclarationPtr();
795 CurChild =
CU.getSiblingEntry(CurChild)) {
801 "Wrong index for ChildIndexesWidth");
808 size_t digitsCounter = 1;
809 size_t NumToCompare = 15;
811 while (NumToCompare < Width) {
816 Width = digitsCounter;
826 switch (DieEntry->
getTag()) {
827 case dwarf::DW_TAG_unspecified_parameters:
828 case dwarf::DW_TAG_formal_parameter:
830 case dwarf::DW_TAG_template_value_parameter:
831 case dwarf::DW_TAG_template_type_parameter:
832 case dwarf::DW_TAG_GNU_template_template_param:
834 case dwarf::DW_TAG_enumeration_type:
835 if (std::optional<uint32_t> ParentIdx = DieEntry->
getParentIdx()) {
836 if (*ParentIdx &&
CU.getDebugInfoEntry(*ParentIdx)->getTag() ==
837 dwarf::DW_TAG_array_type)
841 case dwarf::DW_TAG_subrange_type:
843 case dwarf::DW_TAG_generic_subrange:
845 case dwarf::DW_TAG_enumerator:
847 case dwarf::DW_TAG_namelist_item:
849 case dwarf::DW_TAG_member:
860std::optional<std::pair<size_t, size_t>>
868 "Wrong index for ChildIndexesWidth");
870 "Index width exceeds 16 digits.");
872 std::pair<size_t, size_t> Result = std::make_pair(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static std::optional< UnitEntryPairTy > getTypeDeduplicationCandidate(UnitEntryPairTy UnitEntryPair)
static dwarf::Attribute TypeAttr[]
Represent a constant reference to an array (0 or more elements consecutively in memory),...
DWARFDebugInfoEntry - A DIE with only the minimum required data.
dwarf::Tag getTag() const
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.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
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.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
The instances of the Type class are immutable: once they are created, they are never changed.
Stores all information related to a compile unit, be it in its original instance of the object file o...
std::optional< std::pair< StringRef, StringRef > > getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue)
Returns directory and file from the line table by index.
std::optional< UnitEntryPairTy > resolveDIEReference(const DWARFFormValue &RefValue, ResolveInterCUReferencesMode CanResolveInterCUReferences)
Resolve the DIE attribute reference that has been extracted in RefValue.
OrderedChildrenIndexesArrayTy ChildIndexesWidth
OrderedChildrenIndexAssigner(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry)
std::optional< size_t > tagToArrayIndex(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry)
std::optional< std::pair< size_t, size_t > > getChildIndex(CompileUnit &CU, const DWARFDebugInfoEntry *ChildDieEntry)
Returns index of the specified child and width of hexadecimal representation.
OrderedChildrenIndexesArrayTy OrderedChildIdxs
Error addReferencedODRDies(UnitEntryPairTy InputUnitEntryPair, bool AssignNameToTypeDescriptor, ArrayRef< dwarf::Attribute > ODRAttrs)
Analyze InputUnitEntryPair's ODR attributes and put names of the referenced type dies to the built na...
Error addTemplateParamNames(CompileUnit &CU, SmallVector< const DWARFDebugInfoEntry *, 10 > &TemplateParameters)
Add specified TemplateParameters to the built name.
Error incrementRecursionDepth()
Count a referenced DIE toward the recursion limit.
Error addParentName(UnitEntryPairTy &InputUnitEntryPair)
Add names of parent dies to the built name.
Error addUnqualifiedTypeName(UnitEntryPairTy InputUnitEntryPair)
Add the type InputUnitEntryPair refers to, without parent scopes.
Error addSignature(UnitEntryPairTy InputUnitEntryPair, bool addTemplateParameters)
Add signature( entry type plus type of parameters plus type of template parameters(if addTemplatePara...
Error addParamNames(CompileUnit &CU, SmallVector< const DWARFDebugInfoEntry *, 20 > &FunctionParameters)
Add specified FunctionParameters to the built name.
void addDieNameFromDeclFileAndDeclLine(UnitEntryPairTy &InputUnitEntryPair, bool &HasDeclFileName)
TypePool & TypePoolRef
Type pool.
Error addUnnamedTypeContents(UnitEntryPairTy InputUnitEntryPair)
Add a fixed-size digest of the contents of the unnamed type InputUnitEntryPair, so the names of the t...
size_t RecursionDepth
Recursion counter.
Expected< std::optional< UnitEntryPairTy > > resolveReference(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr)
Resolve the DIE that Attr of InputUnitEntryPair refers to.
SmallString< 1000 > SyntheticName
Buffer keeping bult name.
void addOrderedName(std::pair< size_t, size_t > ChildIdx)
Add ordered name to the built name.
Error assignName(UnitEntryPairTy InputUnitEntryPair, std::optional< std::pair< size_t, size_t > > ChildIndex)
Create synthetic name for the specified DIE InputUnitEntryPair and assign created name to the DIE typ...
Error addDIETypeName(UnitEntryPairTy InputUnitEntryPair, std::optional< std::pair< size_t, size_t > > ChildIndex, bool AssignNameToTypeDescriptor)
Analyze InputUnitEntryPair for the type name and possibly assign built type name to the DIE's type in...
static constexpr size_t MaxRecursionDepth
Bounds RecursionDepth, which malformed input can make unbounded.
Error addTypeName(UnitEntryPairTy InputUnitEntryPair, bool AddParentNames)
Add type name to the built name.
DenseMap< const DWARFDebugInfoEntry *, std::string > ContentsDigests
Digests of the contents of unnamed types, by DIE.
void addArrayDimension(UnitEntryPairTy InputUnitEntryPair)
Add array type dimension.
void addValueName(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr)
Add value name to the built name.
void addTypePrefix(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry)
Add type prefix to the built name.
A raw_ostream that writes to an std::string.
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry)
Idx index of the DIE.
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
ArrayRef< dwarf::Attribute > getODRAttributes()
LLVM_ABI bool isIdentifiedByChildren(dwarf::Tag Tag)
Test if an unnamed type with tag Tag is identified by its children, which tell it apart from other un...
LLVM_ABI bool isStaticDataMember(const DWARFDie &Die)
Test if the DW_TAG_member Die is a DWARF 2-4 style static data member: a declaration with no storage ...
LLVM_ABI bool isIdentifyingChild(const DWARFDie &Die)
Test if Die is a child that identifies its unnamed parent type.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
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.
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct an array ref of bytes from a string ref.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
XXH128_hash_t xxh3_128bits(ArrayRef< uint8_t > data)
auto reverse(ContainerTy &&C)
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
The return value from 128-bit hashes.
uint64_t low64
value & 0xFFFFFFFFFFFFFFFF
uint64_t high64
value >> 64
Information gathered about source DIEs.
This is a helper structure which keeps a debug info entry with it's containing compilation unit.
std::optional< UnitEntryPairTy > getParent()
UnitEntryPairTy getNamespaceOrigin()
const DWARFDebugInfoEntry * DieEntry