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);
136 if (!TemplateParameters.
empty()) {
143 if (Parameter->getTag() == dwarf::DW_TAG_template_value_parameter) {
144 if (std::optional<DWARFFormValue> Val =
145 CU.find(Parameter, dwarf::DW_AT_const_value)) {
146 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant())
148 else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant())
163 std::pair<size_t, size_t> ChildIdx) {
172static std::optional<UnitEntryPairTy>
175 case dwarf::DW_TAG_null:
176 case dwarf::DW_TAG_compile_unit:
177 case dwarf::DW_TAG_partial_unit:
178 case dwarf::DW_TAG_type_unit:
179 case dwarf::DW_TAG_skeleton_unit: {
182 case dwarf::DW_TAG_namespace: {
184 if (UnitEntryPair.
CU->
find(UnitEntryPair.
DieEntry, dwarf::DW_AT_extension))
188 if (!UnitEntryPair.
CU->
find(UnitEntryPair.
DieEntry, dwarf::DW_AT_name))
191 return UnitEntryPair;
194 return UnitEntryPair;
200 std::optional<UnitEntryPairTy> UnitEntryPair = InputUnitEntryPair.
getParent();
209 UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry)) {
218 Parents.push_back(*UnitEntryPair);
220 UnitEntryPair = UnitEntryPair->getParent();
228 }
while (!UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry));
245 if (std::optional<DWARFFormValue> DeclFileVal = InputUnitEntryPair.
CU->
find(
246 InputUnitEntryPair.
DieEntry, dwarf::DW_AT_decl_file)) {
247 if (std::optional<DWARFFormValue> DeclLineVal = InputUnitEntryPair.
CU->
find(
248 InputUnitEntryPair.
DieEntry, dwarf::DW_AT_decl_line)) {
249 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
255 if (std::optional<uint64_t> DeclLineIntVal =
261 HasDeclFileName =
true;
269 if (std::optional<DWARFFormValue> Val =
271 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
274 }
else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant()) {
284 std::optional<DWARFFormValue> AttrValue =
289 std::optional<UnitEntryPairTy> RefDie =
292 if (RefDie && !RefDie->DieEntry)
294 "cannot resolve DIE reference");
301 "cannot parse input DWARF: recursive dependence");
308 bool FirstIteration =
true;
323 addDIETypeName(**RefDie, std::nullopt, AssignNameToTypeDescriptor))
326 FirstIteration =
false;
333 bool AddParentNames) {
334 bool HasLinkageName =
false;
335 bool HasShortName =
false;
336 bool HasTemplatesInShortName =
false;
337 bool HasDeclFileName =
false;
340 if (std::optional<DWARFFormValue> Val = InputUnitEntryPair.
CU->
find(
342 {dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_AT_linkage_name})) {
345 HasLinkageName =
true;
346 }
else if (std::optional<DWARFFormValue> Val = InputUnitEntryPair.
CU->
find(
347 InputUnitEntryPair.
DieEntry, dwarf::DW_AT_name)) {
353 HasTemplatesInShortName =
354 Name.ends_with(
">") && Name.count(
"<") != 0 && !Name.ends_with(
"<=>");
367 case dwarf::DW_TAG_union_type:
368 case dwarf::DW_TAG_interface_type:
369 case dwarf::DW_TAG_class_type:
370 case dwarf::DW_TAG_structure_type:
371 case dwarf::DW_TAG_subroutine_type:
372 case dwarf::DW_TAG_subprogram: {
374 dwarf::DW_AT_artificial))
382 addSignature(InputUnitEntryPair, !HasTemplatesInShortName))
385 case dwarf::DW_TAG_coarray_type:
386 case dwarf::DW_TAG_array_type: {
389 case dwarf::DW_TAG_subrange_type: {
392 case dwarf::DW_TAG_template_value_parameter: {
393 if (!HasTemplatesInShortName) {
395 addValueName(InputUnitEntryPair, dwarf::DW_AT_const_value);
405 if ((!HasLinkageName && !HasShortName && !HasDeclFileName) ||
419 std::optional<std::pair<size_t, size_t>> ChildIndex,
420 bool AssignNameToTypeDescriptor) {
421 std::optional<UnitEntryPairTy> UnitEntryPair =
448 if (AssignNameToTypeDescriptor)
473 CU.getFirstChildEntry(InputUnitEntryPair.
DieEntry);
474 CurChild && CurChild->getAbbreviationDeclarationPtr();
475 CurChild =
CU.getSiblingEntry(CurChild)) {
482 if (std::optional<DWARFFormValue> Val =
483 CU.find(CurChild, dwarf::DW_AT_name))
517 if (std::optional<DWARFFormValue> Val =
518 Type.CU->find(
Type.DieEntry, dwarf::DW_AT_name)) {
521 if (
Type.DieEntry->getTag() == dwarf::DW_TAG_array_type)
535 switch (DieEntry->
getTag()) {
536 case dwarf::DW_TAG_base_type: {
539 case dwarf::DW_TAG_namespace: {
542 case dwarf::DW_TAG_formal_parameter: {
546 case dwarf::DW_TAG_unspecified_parameters: {
549 case dwarf::DW_TAG_template_type_parameter: {
553 case dwarf::DW_TAG_template_value_parameter: {
556 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
559 case dwarf::DW_TAG_GNU_template_parameter_pack: {
562 case dwarf::DW_TAG_inheritance: {
565 case dwarf::DW_TAG_array_type: {
568 case dwarf::DW_TAG_class_type: {
571 case dwarf::DW_TAG_enumeration_type: {
574 case dwarf::DW_TAG_imported_declaration: {
577 case dwarf::DW_TAG_member: {
585 case dwarf::DW_TAG_pointer_type: {
588 case dwarf::DW_TAG_reference_type: {
591 case dwarf::DW_TAG_string_type: {
594 case dwarf::DW_TAG_structure_type: {
597 case dwarf::DW_TAG_subroutine_type: {
600 case dwarf::DW_TAG_typedef: {
603 case dwarf::DW_TAG_union_type: {
606 case dwarf::DW_TAG_variant: {
609 case dwarf::DW_TAG_inlined_subroutine: {
612 case dwarf::DW_TAG_module: {
615 case dwarf::DW_TAG_ptr_to_member_type: {
618 case dwarf::DW_TAG_set_type: {
621 case dwarf::DW_TAG_subrange_type: {
624 case dwarf::DW_TAG_with_stmt: {
627 case dwarf::DW_TAG_access_declaration: {
630 case dwarf::DW_TAG_catch_block: {
633 case dwarf::DW_TAG_const_type: {
636 case dwarf::DW_TAG_constant: {
639 case dwarf::DW_TAG_enumerator: {
642 case dwarf::DW_TAG_file_type: {
645 case dwarf::DW_TAG_friend: {
648 case dwarf::DW_TAG_namelist: {
651 case dwarf::DW_TAG_namelist_item: {
654 case dwarf::DW_TAG_packed_type: {
657 case dwarf::DW_TAG_subprogram: {
660 case dwarf::DW_TAG_thrown_type: {
663 case dwarf::DW_TAG_variant_part: {
666 case dwarf::DW_TAG_variable: {
669 case dwarf::DW_TAG_volatile_type: {
672 case dwarf::DW_TAG_dwarf_procedure: {
675 case dwarf::DW_TAG_restrict_type: {
678 case dwarf::DW_TAG_interface_type: {
681 case dwarf::DW_TAG_imported_module: {
684 case dwarf::DW_TAG_unspecified_type: {
687 case dwarf::DW_TAG_imported_unit: {
690 case dwarf::DW_TAG_condition: {
693 case dwarf::DW_TAG_shared_type: {
696 case dwarf::DW_TAG_rvalue_reference_type: {
699 case dwarf::DW_TAG_template_alias: {
702 case dwarf::DW_TAG_coarray_type: {
705 case dwarf::DW_TAG_generic_subrange: {
708 case dwarf::DW_TAG_dynamic_type: {
711 case dwarf::DW_TAG_atomic_type: {
714 case dwarf::DW_TAG_call_site: {
717 case dwarf::DW_TAG_call_site_parameter: {
720 case dwarf::DW_TAG_immutable_type: {
723 case dwarf::DW_TAG_entry_point: {
726 case dwarf::DW_TAG_label: {
729 case dwarf::DW_TAG_lexical_block: {
732 case dwarf::DW_TAG_common_block: {
735 case dwarf::DW_TAG_common_inclusion: {
738 case dwarf::DW_TAG_try_block: {
742 case dwarf::DW_TAG_null: {
745 case dwarf::DW_TAG_compile_unit: {
748 case dwarf::DW_TAG_partial_unit: {
751 case dwarf::DW_TAG_type_unit: {
754 case dwarf::DW_TAG_skeleton_unit: {
768 switch (DieEntry->
getTag()) {
769 case dwarf::DW_TAG_array_type:
770 case dwarf::DW_TAG_coarray_type:
771 case dwarf::DW_TAG_class_type:
772 case dwarf::DW_TAG_common_block:
773 case dwarf::DW_TAG_lexical_block:
774 case dwarf::DW_TAG_structure_type:
775 case dwarf::DW_TAG_subprogram:
776 case dwarf::DW_TAG_subroutine_type:
777 case dwarf::DW_TAG_union_type:
778 case dwarf::DW_TAG_GNU_template_template_param:
779 case dwarf::DW_TAG_GNU_formal_parameter_pack:
780 case dwarf::DW_TAG_GNU_template_parameter_pack: {
783 case dwarf::DW_TAG_enumeration_type: {
795 CurChild && CurChild->getAbbreviationDeclarationPtr();
796 CurChild =
CU.getSiblingEntry(CurChild)) {
802 "Wrong index for ChildIndexesWidth");
809 size_t digitsCounter = 1;
810 size_t NumToCompare = 15;
812 while (NumToCompare < Width) {
817 Width = digitsCounter;
827 switch (DieEntry->
getTag()) {
828 case dwarf::DW_TAG_unspecified_parameters:
829 case dwarf::DW_TAG_formal_parameter:
831 case dwarf::DW_TAG_template_value_parameter:
832 case dwarf::DW_TAG_template_type_parameter:
833 case dwarf::DW_TAG_GNU_template_template_param:
835 case dwarf::DW_TAG_enumeration_type:
836 if (std::optional<uint32_t> ParentIdx = DieEntry->
getParentIdx()) {
837 if (*ParentIdx &&
CU.getDebugInfoEntry(*ParentIdx)->getTag() ==
838 dwarf::DW_TAG_array_type)
842 case dwarf::DW_TAG_subrange_type:
844 case dwarf::DW_TAG_generic_subrange:
846 case dwarf::DW_TAG_enumerator:
848 case dwarf::DW_TAG_namelist_item:
850 case dwarf::DW_TAG_member:
861std::optional<std::pair<size_t, size_t>>
869 "Wrong index for ChildIndexesWidth");
871 "Index width exceeds 16 digits.");
873 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.
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.
TypeKey SyntheticName
Buffer keeping bult 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.
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