LLVM: lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
13
14using namespace llvm;
17
20 std::optional<std::pair<size_t, size_t>> ChildIndex) {
23 assert(Info.needToPlaceInTypeTable() &&
24 "Cann't assign name for non-type DIE");
25
27 nullptr)
29
32 return addDIETypeName(InputUnitEntryPair, ChildIndex, true);
33}
34
42 if (CurChild->getTag() == dwarf::DW_TAG_subrange_type ||
43 CurChild->getTag() == dwarf::DW_TAG_generic_subrange) {
45 if (std::optional Val =
46 InputUnitEntryPair.CU->find(CurChild, dwarf::DW_AT_count)) {
47 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
49 } else if (std::optional<int64_t> ConstVal =
50 Val->getAsSignedConstant()) {
52 }
53 }
54
56 }
57 }
58}
59
62 bool addTemplateParameters) {
63
65 return Err;
67
75 dwarf::Tag ChildTag = CurChild->getTag();
76 if (addTemplateParameters &&
77 (ChildTag == dwarf::DW_TAG_template_type_parameter ||
78 ChildTag == dwarf::DW_TAG_template_value_parameter))
79 TemplateParameters.push_back(CurChild);
80 else if (ChildTag == dwarf::DW_TAG_formal_parameter ||
81 ChildTag == dwarf::DW_TAG_unspecified_parameters)
82 FunctionParameters.push_back(CurChild);
83 else if (addTemplateParameters &&
84 ChildTag == dwarf::DW_TAG_GNU_template_parameter_pack) {
88 CurGNUChild = InputUnitEntryPair.CU->getSiblingEntry(CurGNUChild))
89 TemplateParameters.push_back(CurGNUChild);
90 } else if (ChildTag == dwarf::DW_TAG_GNU_formal_parameter_pack) {
94 CurGNUChild = InputUnitEntryPair.CU->getSiblingEntry(CurGNUChild))
95 FunctionParameters.push_back(CurGNUChild);
96 }
97 }
98
99
101 return Err;
102
103
106 return Err;
107
109}
110
115 for (const DWARFDebugInfoEntry *FunctionParameter : FunctionParameters) {
118 if (dwarf::toUnsigned(CU.find(FunctionParameter, dwarf::DW_AT_artificial),
119 0))
123 return Err;
124 }
127}
128
132 if (!TemplateParameters.empty()) {
137
138 if (Parameter->getTag() == dwarf::DW_TAG_template_value_parameter) {
139 if (std::optional Val =
140 CU.find(Parameter, dwarf::DW_AT_const_value)) {
141 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant())
143 else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant())
145 }
146 }
147
150 return Err;
151 }
153 }
155}
156
158 std::pair<size_t, size_t> ChildIdx) {
159 std::string Name;
163}
164
165
166
167static std::optional
170 case dwarf::DW_TAG_null:
171 case dwarf::DW_TAG_compile_unit:
172 case dwarf::DW_TAG_partial_unit:
173 case dwarf::DW_TAG_type_unit:
174 case dwarf::DW_TAG_skeleton_unit: {
175 return std::nullopt;
176 }
177 case dwarf::DW_TAG_namespace: {
178
179 if (UnitEntryPair.CU->find(UnitEntryPair.DieEntry, dwarf::DW_AT_extension))
181
182
183 if (!UnitEntryPair.CU->find(UnitEntryPair.DieEntry, dwarf::DW_AT_name))
185
186 return UnitEntryPair;
187 }
188 default:
189 return UnitEntryPair;
190 }
191}
192
195 std::optional UnitEntryPair = InputUnitEntryPair.getParent();
196 if (!UnitEntryPair)
198
200 if (!UnitEntryPair)
202
203 if (TypeEntry *ImmediateParentName =
204 UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry)) {
208 }
209
210
212 do {
213 Parents.push_back(*UnitEntryPair);
214
215 UnitEntryPair = UnitEntryPair->getParent();
216 if (!UnitEntryPair)
217 break;
218
220 if (!UnitEntryPair)
221 break;
222
223 } while (!UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry));
224
225
230 return Err;
231 }
232
233
236}
237
239 UnitEntryPairTy &InputUnitEntryPair, bool &HasDeclFileName) {
240 if (std::optional DeclFileVal = InputUnitEntryPair.CU->find(
241 InputUnitEntryPair.DieEntry, dwarf::DW_AT_decl_file)) {
242 if (std::optional DeclLineVal = InputUnitEntryPair.CU->find(
243 InputUnitEntryPair.DieEntry, dwarf::DW_AT_decl_line)) {
244 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
246 *DeclFileVal)) {
249
250 if (std::optional<uint64_t> DeclLineIntVal =
254 }
255
256 HasDeclFileName = true;
257 }
258 }
259 }
260}
261
264 if (std::optional Val =
265 InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry, Attr)) {
266 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
269 } else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant()) {
272 }
273 }
274}
275
277 UnitEntryPairTy InputUnitEntryPair, bool AssignNameToTypeDescriptor,
279 bool FirstIteration = true;
281 if (std::optional AttrValue =
282 InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry, Attr)) {
283 std::optional RefDie =
286
287 if (!RefDie)
288 continue;
289
290 if (!RefDie->DieEntry)
292 "Cann't resolve DIE reference");
293
294 if (!FirstIteration)
296
300 std::errc::invalid_argument,
301 "Cann't parse input DWARF. Recursive dependence.");
302
304 addDIETypeName(*RefDie, std::nullopt, AssignNameToTypeDescriptor))
305 return Err;
307 FirstIteration = false;
308 }
309 }
310
312}
313
315 bool AddParentNames) {
316 bool HasLinkageName = false;
317 bool HasShortName = false;
318 bool HasTemplatesInShortName = false;
319 bool HasDeclFileName = false;
320
321
322 if (std::optional Val = InputUnitEntryPair.CU->find(
324 {dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_AT_linkage_name})) {
325
327 HasLinkageName = true;
328 } else if (std::optional Val = InputUnitEntryPair.CU->find(
329 InputUnitEntryPair.DieEntry, dwarf::DW_AT_name)) {
330
333
334 HasShortName = true;
335 HasTemplatesInShortName =
336 Name.ends_with(">") && Name.count("<") != 0 && !Name.ends_with("<=>");
337 } else {
338
340 }
341
342
344 case dwarf::DW_TAG_union_type:
345 case dwarf::DW_TAG_interface_type:
346 case dwarf::DW_TAG_class_type:
347 case dwarf::DW_TAG_structure_type:
348 case dwarf::DW_TAG_subroutine_type:
349 case dwarf::DW_TAG_subprogram: {
350 if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
351 dwarf::DW_AT_artificial))
353
354
355
356
357 if (!HasLinkageName)
359 addSignature(InputUnitEntryPair, !HasTemplatesInShortName))
360 return Err;
361 } break;
362 case dwarf::DW_TAG_coarray_type:
363 case dwarf::DW_TAG_array_type: {
365 } break;
366 case dwarf::DW_TAG_subrange_type: {
367 addValueName(InputUnitEntryPair, dwarf::DW_AT_count);
368 } break;
369 case dwarf::DW_TAG_template_value_parameter: {
370 if (!HasTemplatesInShortName) {
371
372 addValueName(InputUnitEntryPair, dwarf::DW_AT_const_value);
373 }
374 } break;
375 default: {
376
377 } break;
378 }
379
380
381
382 if ((!HasLinkageName && !HasShortName && !HasDeclFileName) ||
383 InputUnitEntryPair.DieEntry->getTag() == dwarf::DW_TAG_typedef) {
384 if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
388 return Err;
389 }
390
392}
393
396 std::optional<std::pair<size_t, size_t>> ChildIndex,
397 bool AssignNameToTypeDescriptor) {
398 std::optional UnitEntryPair =
400 if (!UnitEntryPair)
402
405
406 if (!TypeEntryPtr) {
408 if (AssignNameToTypeDescriptor) {
410 return Err;
411 }
413
414 if (ChildIndex) {
416 } else {
417 if (Error Err = addTypeName(*UnitEntryPair, AssignNameToTypeDescriptor))
418 return Err;
419 }
420
421 if (AssignNameToTypeDescriptor) {
422
425 TypeEntryPtr);
426 }
427 } else
429
431}
432
435 switch (DieEntry->getTag()) {
436 case dwarf::DW_TAG_base_type: {
438 } break;
439 case dwarf::DW_TAG_namespace: {
441 } break;
442 case dwarf::DW_TAG_formal_parameter: {
444 } break;
445
446 case dwarf::DW_TAG_unspecified_parameters: {
448 } break;
449 case dwarf::DW_TAG_template_type_parameter: {
451 } break;
452
453 case dwarf::DW_TAG_template_value_parameter: {
455 } break;
456 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
458 } break;
459 case dwarf::DW_TAG_GNU_template_parameter_pack: {
461 } break;
462 case dwarf::DW_TAG_inheritance: {
464 } break;
465 case dwarf::DW_TAG_array_type: {
467 } break;
468 case dwarf::DW_TAG_class_type: {
470 } break;
471 case dwarf::DW_TAG_enumeration_type: {
473 } break;
474 case dwarf::DW_TAG_imported_declaration: {
476 } break;
477 case dwarf::DW_TAG_member: {
479 } break;
480 case dwarf::DW_TAG_pointer_type: {
482 } break;
483 case dwarf::DW_TAG_reference_type: {
485 } break;
486 case dwarf::DW_TAG_string_type: {
488 } break;
489 case dwarf::DW_TAG_structure_type: {
491 } break;
492 case dwarf::DW_TAG_subroutine_type: {
494 } break;
495 case dwarf::DW_TAG_typedef: {
497 } break;
498 case dwarf::DW_TAG_union_type: {
500 } break;
501 case dwarf::DW_TAG_variant: {
503 } break;
504 case dwarf::DW_TAG_inlined_subroutine: {
506 } break;
507 case dwarf::DW_TAG_module: {
509 } break;
510 case dwarf::DW_TAG_ptr_to_member_type: {
512 } break;
513 case dwarf::DW_TAG_set_type: {
515 } break;
516 case dwarf::DW_TAG_subrange_type: {
518 } break;
519 case dwarf::DW_TAG_with_stmt: {
521 } break;
522 case dwarf::DW_TAG_access_declaration: {
524 } break;
525 case dwarf::DW_TAG_catch_block: {
527 } break;
528 case dwarf::DW_TAG_const_type: {
530 } break;
531 case dwarf::DW_TAG_constant: {
533 } break;
534 case dwarf::DW_TAG_enumerator: {
536 } break;
537 case dwarf::DW_TAG_file_type: {
539 } break;
540 case dwarf::DW_TAG_friend: {
542 } break;
543 case dwarf::DW_TAG_namelist: {
545 } break;
546 case dwarf::DW_TAG_namelist_item: {
548 } break;
549 case dwarf::DW_TAG_packed_type: {
551 } break;
552 case dwarf::DW_TAG_subprogram: {
554 } break;
555 case dwarf::DW_TAG_thrown_type: {
557 } break;
558 case dwarf::DW_TAG_variant_part: {
560 } break;
561 case dwarf::DW_TAG_variable: {
563 } break;
564 case dwarf::DW_TAG_volatile_type: {
566 } break;
567 case dwarf::DW_TAG_dwarf_procedure: {
569 } break;
570 case dwarf::DW_TAG_restrict_type: {
572 } break;
573 case dwarf::DW_TAG_interface_type: {
575 } break;
576 case dwarf::DW_TAG_imported_module: {
578 } break;
579 case dwarf::DW_TAG_unspecified_type: {
581 } break;
582 case dwarf::DW_TAG_imported_unit: {
584 } break;
585 case dwarf::DW_TAG_condition: {
587 } break;
588 case dwarf::DW_TAG_shared_type: {
590 } break;
591 case dwarf::DW_TAG_rvalue_reference_type: {
593 } break;
594 case dwarf::DW_TAG_template_alias: {
596 } break;
597 case dwarf::DW_TAG_coarray_type: {
599 } break;
600 case dwarf::DW_TAG_generic_subrange: {
602 } break;
603 case dwarf::DW_TAG_dynamic_type: {
605 } break;
606 case dwarf::DW_TAG_atomic_type: {
608 } break;
609 case dwarf::DW_TAG_call_site: {
611 } break;
612 case dwarf::DW_TAG_call_site_parameter: {
614 } break;
615 case dwarf::DW_TAG_immutable_type: {
617 } break;
618 case dwarf::DW_TAG_entry_point: {
620 } break;
621 case dwarf::DW_TAG_label: {
623 } break;
624 case dwarf::DW_TAG_lexical_block: {
626 } break;
627 case dwarf::DW_TAG_common_block: {
629 } break;
630 case dwarf::DW_TAG_common_inclusion: {
632 } break;
633 case dwarf::DW_TAG_try_block: {
635 } break;
636
637 case dwarf::DW_TAG_null: {
639 } break;
640 case dwarf::DW_TAG_compile_unit: {
642 } break;
643 case dwarf::DW_TAG_partial_unit: {
645 } break;
646 case dwarf::DW_TAG_type_unit: {
648 } break;
649 case dwarf::DW_TAG_skeleton_unit: {
651 } break;
652
653 default: {
657 } break;
658 }
659}
660
663 switch (DieEntry->getTag()) {
664 case dwarf::DW_TAG_array_type:
665 case dwarf::DW_TAG_coarray_type:
666 case dwarf::DW_TAG_class_type:
667 case dwarf::DW_TAG_common_block:
668 case dwarf::DW_TAG_lexical_block:
669 case dwarf::DW_TAG_structure_type:
670 case dwarf::DW_TAG_subprogram:
671 case dwarf::DW_TAG_subroutine_type:
672 case dwarf::DW_TAG_union_type:
673 case dwarf::DW_TAG_GNU_template_template_param:
674 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
676 } break;
677 case dwarf::DW_TAG_enumeration_type: {
678
680 } break;
681 default: {
682
683 }
684 }
685
686
689 CurChild && CurChild->getAbbreviationDeclarationPtr();
690 CurChild = CU.getSiblingEntry(CurChild)) {
691 std::optional<size_t> ArrayIndex = tagToArrayIndex(CU, CurChild);
692 if (!ArrayIndex)
693 continue;
694
696 "Wrong index for ChildIndexesWidth");
698 }
699
700
701
703 size_t digitsCounter = 1;
704 size_t NumToCompare = 15;
705
706 while (NumToCompare < Width) {
707 NumToCompare <<= 4;
708 digitsCounter++;
709 }
710
711 Width = digitsCounter;
712 }
713 }
714}
715
719 return std::nullopt;
720
721 switch (DieEntry->getTag()) {
722 case dwarf::DW_TAG_unspecified_parameters:
723 case dwarf::DW_TAG_formal_parameter:
724 return 0;
725 case dwarf::DW_TAG_template_value_parameter:
726 case dwarf::DW_TAG_template_type_parameter:
727 return 1;
728 case dwarf::DW_TAG_enumeration_type:
729 if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx()) {
730 if (*ParentIdx && CU.getDebugInfoEntry(*ParentIdx)->getTag() ==
731 dwarf::DW_TAG_array_type)
732 return 2;
733 }
734 return std::nullopt;
735 case dwarf::DW_TAG_subrange_type:
736 return 3;
737 case dwarf::DW_TAG_generic_subrange:
738 return 4;
739 case dwarf::DW_TAG_enumerator:
740 return 5;
741 case dwarf::DW_TAG_namelist_item:
742 return 6;
743 case dwarf::DW_TAG_member:
744 return 7;
745 default:
746 return std::nullopt;
747 };
748}
749
750std::optional<std::pair<size_t, size_t>>
753 std::optional<size_t> ArrayIndex = tagToArrayIndex(CU, ChildDieEntry);
754 if (!ArrayIndex)
755 return std::nullopt;
756
758 "Wrong index for ChildIndexesWidth");
760 "Index width exceeds 16 digits.");
761
762 std::pair<size_t, size_t> Result = std::make_pair(
765 return Result;
766}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static std::optional< UnitEntryPairTy > getTypeDeduplicationCandidate(UnitEntryPairTy UnitEntryPair)
Definition SyntheticTypeNameBuilder.cpp:168
static dwarf::Attribute TypeAttr[]
Definition SyntheticTypeNameBuilder.cpp:60
ArrayRef - 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
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
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)
Definition SyntheticTypeNameBuilder.cpp:661
std::optional< size_t > tagToArrayIndex(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry)
Definition SyntheticTypeNameBuilder.cpp:716
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.
Definition SyntheticTypeNameBuilder.cpp:751
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...
Definition SyntheticTypeNameBuilder.cpp:276
Error addTemplateParamNames(CompileUnit &CU, SmallVector< const DWARFDebugInfoEntry *, 10 > &TemplateParameters)
Add specified TemplateParameters to the built name.
Definition SyntheticTypeNameBuilder.cpp:129
Error addParentName(UnitEntryPairTy &InputUnitEntryPair)
Add names of parent dies to the built name.
Definition SyntheticTypeNameBuilder.cpp:193
void addOrderedName(CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry)
Add ordered name to the built name.
Error addSignature(UnitEntryPairTy InputUnitEntryPair, bool addTemplateParameters)
Add signature( entry type plus type of parameters plus type of template parameters(if addTemplatePara...
Definition SyntheticTypeNameBuilder.cpp:61
Error addParamNames(CompileUnit &CU, SmallVector< const DWARFDebugInfoEntry *, 20 > &FunctionParameters)
Add specified FunctionParameters to the built name.
Definition SyntheticTypeNameBuilder.cpp:111
void addDieNameFromDeclFileAndDeclLine(UnitEntryPairTy &InputUnitEntryPair, bool &HasDeclFileName)
Definition SyntheticTypeNameBuilder.cpp:238
TypePool & TypePoolRef
Type pool.
size_t RecursionDepth
Recursion counter.
void addTypePrefix(const DWARFDebugInfoEntry *DieEntry)
Add type prefix to the built name.
Definition SyntheticTypeNameBuilder.cpp:433
SmallString< 1000 > SyntheticName
Buffer keeping bult 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...
Definition SyntheticTypeNameBuilder.cpp:18
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...
Definition SyntheticTypeNameBuilder.cpp:394
Error addTypeName(UnitEntryPairTy InputUnitEntryPair, bool AddParentNames)
Add type name to the built name.
Definition SyntheticTypeNameBuilder.cpp:314
void addArrayDimension(UnitEntryPairTy InputUnitEntryPair)
Add array type dimension.
Definition SyntheticTypeNameBuilder.cpp:35
void addValueName(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr)
Add value name to the built name.
Definition SyntheticTypeNameBuilder.cpp:262
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()
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.
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.
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.
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