LLVM: lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
14
15using namespace llvm;
16using namespace dwarf_linker;
17using namespace dwarf_linker::parallel;
18
21 std::optional<std::pair<size_t, size_t>> ChildIndex) {
24 assert(Info.needToPlaceInTypeTable() &&
25 "Cann't assign name for non-type DIE");
26
28 nullptr)
30
33 return addDIETypeName(InputUnitEntryPair, ChildIndex, true);
34}
35
43 if (CurChild->getTag() == dwarf::DW_TAG_subrange_type ||
44 CurChild->getTag() == dwarf::DW_TAG_generic_subrange) {
46 if (std::optional Val =
47 InputUnitEntryPair.CU->find(CurChild, dwarf::DW_AT_count)) {
48 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
50 } else if (std::optional<int64_t> ConstVal =
51 Val->getAsSignedConstant()) {
53 }
54 }
55
57 }
58 }
59}
60
63 bool addTemplateParameters) {
64
66 return Err;
68
76 dwarf::Tag ChildTag = CurChild->getTag();
77 if (addTemplateParameters &&
78 (ChildTag == dwarf::DW_TAG_template_type_parameter ||
79 ChildTag == dwarf::DW_TAG_template_value_parameter))
80 TemplateParameters.push_back(CurChild);
81 else if (ChildTag == dwarf::DW_TAG_formal_parameter ||
82 ChildTag == dwarf::DW_TAG_unspecified_parameters)
83 FunctionParameters.push_back(CurChild);
84 else if (addTemplateParameters &&
85 ChildTag == dwarf::DW_TAG_GNU_template_parameter_pack) {
89 CurGNUChild = InputUnitEntryPair.CU->getSiblingEntry(CurGNUChild))
90 TemplateParameters.push_back(CurGNUChild);
91 } else if (ChildTag == dwarf::DW_TAG_GNU_formal_parameter_pack) {
95 CurGNUChild = InputUnitEntryPair.CU->getSiblingEntry(CurGNUChild))
96 FunctionParameters.push_back(CurGNUChild);
97 }
98 }
99
100
102 return Err;
103
104
107 return Err;
108
110}
111
116 for (const DWARFDebugInfoEntry *FunctionParameter : FunctionParameters) {
119 if (dwarf::toUnsigned(CU.find(FunctionParameter, dwarf::DW_AT_artificial),
120 0))
124 return Err;
125 }
128}
129
133 if (!TemplateParameters.empty()) {
138
139 if (Parameter->getTag() == dwarf::DW_TAG_template_value_parameter) {
140 if (std::optional Val =
141 CU.find(Parameter, dwarf::DW_AT_const_value)) {
142 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant())
144 else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant())
146 }
147 }
148
151 return Err;
152 }
154 }
156}
157
159 std::pair<size_t, size_t> ChildIdx) {
160 std::string Name;
164}
165
166
167
168static std::optional
171 case dwarf::DW_TAG_null:
172 case dwarf::DW_TAG_compile_unit:
173 case dwarf::DW_TAG_partial_unit:
174 case dwarf::DW_TAG_type_unit:
175 case dwarf::DW_TAG_skeleton_unit: {
176 return std::nullopt;
177 }
178 case dwarf::DW_TAG_namespace: {
179
180 if (UnitEntryPair.CU->find(UnitEntryPair.DieEntry, dwarf::DW_AT_extension))
182
183
184 if (!UnitEntryPair.CU->find(UnitEntryPair.DieEntry, dwarf::DW_AT_name))
186
187 return UnitEntryPair;
188 }
189 default:
190 return UnitEntryPair;
191 }
192}
193
196 std::optional UnitEntryPair = InputUnitEntryPair.getParent();
197 if (!UnitEntryPair)
199
201 if (!UnitEntryPair)
203
204 if (TypeEntry *ImmediateParentName =
205 UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry)) {
209 }
210
211
213 do {
214 Parents.push_back(*UnitEntryPair);
215
216 UnitEntryPair = UnitEntryPair->getParent();
217 if (!UnitEntryPair)
218 break;
219
221 if (!UnitEntryPair)
222 break;
223
224 } while (!UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry));
225
226
231 return Err;
232 }
233
234
237}
238
240 UnitEntryPairTy &InputUnitEntryPair, bool &HasDeclFileName) {
241 if (std::optional DeclFileVal = InputUnitEntryPair.CU->find(
242 InputUnitEntryPair.DieEntry, dwarf::DW_AT_decl_file)) {
243 if (std::optional DeclLineVal = InputUnitEntryPair.CU->find(
244 InputUnitEntryPair.DieEntry, dwarf::DW_AT_decl_line)) {
245 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
247 *DeclFileVal)) {
250
251 if (std::optional<uint64_t> DeclLineIntVal =
255 }
256
257 HasDeclFileName = true;
258 }
259 }
260 }
261}
262
265 if (std::optional Val =
266 InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry, Attr)) {
267 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
270 } else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant()) {
273 }
274 }
275}
276
278 UnitEntryPairTy InputUnitEntryPair, bool AssignNameToTypeDescriptor,
280 bool FirstIteration = true;
282 if (std::optional AttrValue =
283 InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry, Attr)) {
284 std::optional RefDie =
287
288 if (!RefDie)
289 continue;
290
291 if (!RefDie->DieEntry)
293 "Cann't resolve DIE reference");
294
295 if (!FirstIteration)
297
301 std::errc::invalid_argument,
302 "Cann't parse input DWARF. Recursive dependence.");
303
305 addDIETypeName(*RefDie, std::nullopt, AssignNameToTypeDescriptor))
306 return Err;
308 FirstIteration = false;
309 }
310 }
311
313}
314
316 bool AddParentNames) {
317 bool HasLinkageName = false;
318 bool HasShortName = false;
319 bool HasTemplatesInShortName = false;
320 bool HasDeclFileName = false;
321
322
323 if (std::optional Val = InputUnitEntryPair.CU->find(
325 {dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_AT_linkage_name})) {
326
328 HasLinkageName = true;
329 } else if (std::optional Val = InputUnitEntryPair.CU->find(
330 InputUnitEntryPair.DieEntry, dwarf::DW_AT_name)) {
331
334
335 HasShortName = true;
336 HasTemplatesInShortName =
337 Name.ends_with(">") && Name.count("<") != 0 && .ends_with("<=>");
338 } else {
339
341 }
342
343
345 case dwarf::DW_TAG_union_type:
346 case dwarf::DW_TAG_interface_type:
347 case dwarf::DW_TAG_class_type:
348 case dwarf::DW_TAG_structure_type:
349 case dwarf::DW_TAG_subroutine_type:
350 case dwarf::DW_TAG_subprogram: {
351 if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
352 dwarf::DW_AT_artificial))
354
355
356
357
358 if (!HasLinkageName)
360 addSignature(InputUnitEntryPair, !HasTemplatesInShortName))
361 return Err;
362 } break;
363 case dwarf::DW_TAG_coarray_type:
364 case dwarf::DW_TAG_array_type: {
366 } break;
367 case dwarf::DW_TAG_subrange_type: {
368 addValueName(InputUnitEntryPair, dwarf::DW_AT_count);
369 } break;
370 case dwarf::DW_TAG_template_value_parameter: {
371 if (!HasTemplatesInShortName) {
372
373 addValueName(InputUnitEntryPair, dwarf::DW_AT_const_value);
374 }
375 } break;
376 default: {
377
378 } break;
379 }
380
381
382 if (!HasLinkageName && !HasShortName && !HasDeclFileName) {
383 if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
387 return Err;
388 }
389
391}
392
395 std::optional<std::pair<size_t, size_t>> ChildIndex,
396 bool AssignNameToTypeDescriptor) {
397 std::optional UnitEntryPair =
399 if (!UnitEntryPair)
401
404
405 if (!TypeEntryPtr) {
407 if (AssignNameToTypeDescriptor) {
409 return Err;
410 }
412
413 if (ChildIndex) {
415 } else {
416 if (Error Err = addTypeName(*UnitEntryPair, AssignNameToTypeDescriptor))
417 return Err;
418 }
419
420 if (AssignNameToTypeDescriptor) {
421
424 TypeEntryPtr);
425 }
426 } else
428
430}
431
434 switch (DieEntry->getTag()) {
435 case dwarf::DW_TAG_base_type: {
437 } break;
438 case dwarf::DW_TAG_namespace: {
440 } break;
441 case dwarf::DW_TAG_formal_parameter: {
443 } break;
444
445 case dwarf::DW_TAG_unspecified_parameters: {
447 } break;
448 case dwarf::DW_TAG_template_type_parameter: {
450 } break;
451
452 case dwarf::DW_TAG_template_value_parameter: {
454 } break;
455 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
457 } break;
458 case dwarf::DW_TAG_GNU_template_parameter_pack: {
460 } break;
461 case dwarf::DW_TAG_inheritance: {
463 } break;
464 case dwarf::DW_TAG_array_type: {
466 } break;
467 case dwarf::DW_TAG_class_type: {
469 } break;
470 case dwarf::DW_TAG_enumeration_type: {
472 } break;
473 case dwarf::DW_TAG_imported_declaration: {
475 } break;
476 case dwarf::DW_TAG_member: {
478 } break;
479 case dwarf::DW_TAG_pointer_type: {
481 } break;
482 case dwarf::DW_TAG_reference_type: {
484 } break;
485 case dwarf::DW_TAG_string_type: {
487 } break;
488 case dwarf::DW_TAG_structure_type: {
490 } break;
491 case dwarf::DW_TAG_subroutine_type: {
493 } break;
494 case dwarf::DW_TAG_typedef: {
496 } break;
497 case dwarf::DW_TAG_union_type: {
499 } break;
500 case dwarf::DW_TAG_variant: {
502 } break;
503 case dwarf::DW_TAG_inlined_subroutine: {
505 } break;
506 case dwarf::DW_TAG_module: {
508 } break;
509 case dwarf::DW_TAG_ptr_to_member_type: {
511 } break;
512 case dwarf::DW_TAG_set_type: {
514 } break;
515 case dwarf::DW_TAG_subrange_type: {
517 } break;
518 case dwarf::DW_TAG_with_stmt: {
520 } break;
521 case dwarf::DW_TAG_access_declaration: {
523 } break;
524 case dwarf::DW_TAG_catch_block: {
526 } break;
527 case dwarf::DW_TAG_const_type: {
529 } break;
530 case dwarf::DW_TAG_constant: {
532 } break;
533 case dwarf::DW_TAG_enumerator: {
535 } break;
536 case dwarf::DW_TAG_file_type: {
538 } break;
539 case dwarf::DW_TAG_friend: {
541 } break;
542 case dwarf::DW_TAG_namelist: {
544 } break;
545 case dwarf::DW_TAG_namelist_item: {
547 } break;
548 case dwarf::DW_TAG_packed_type: {
550 } break;
551 case dwarf::DW_TAG_subprogram: {
553 } break;
554 case dwarf::DW_TAG_thrown_type: {
556 } break;
557 case dwarf::DW_TAG_variant_part: {
559 } break;
560 case dwarf::DW_TAG_variable: {
562 } break;
563 case dwarf::DW_TAG_volatile_type: {
565 } break;
566 case dwarf::DW_TAG_dwarf_procedure: {
568 } break;
569 case dwarf::DW_TAG_restrict_type: {
571 } break;
572 case dwarf::DW_TAG_interface_type: {
574 } break;
575 case dwarf::DW_TAG_imported_module: {
577 } break;
578 case dwarf::DW_TAG_unspecified_type: {
580 } break;
581 case dwarf::DW_TAG_imported_unit: {
583 } break;
584 case dwarf::DW_TAG_condition: {
586 } break;
587 case dwarf::DW_TAG_shared_type: {
589 } break;
590 case dwarf::DW_TAG_rvalue_reference_type: {
592 } break;
593 case dwarf::DW_TAG_template_alias: {
595 } break;
596 case dwarf::DW_TAG_coarray_type: {
598 } break;
599 case dwarf::DW_TAG_generic_subrange: {
601 } break;
602 case dwarf::DW_TAG_dynamic_type: {
604 } break;
605 case dwarf::DW_TAG_atomic_type: {
607 } break;
608 case dwarf::DW_TAG_call_site: {
610 } break;
611 case dwarf::DW_TAG_call_site_parameter: {
613 } break;
614 case dwarf::DW_TAG_immutable_type: {
616 } break;
617 case dwarf::DW_TAG_entry_point: {
619 } break;
620 case dwarf::DW_TAG_label: {
622 } break;
623 case dwarf::DW_TAG_lexical_block: {
625 } break;
626 case dwarf::DW_TAG_common_block: {
628 } break;
629 case dwarf::DW_TAG_common_inclusion: {
631 } break;
632 case dwarf::DW_TAG_try_block: {
634 } break;
635
636 case dwarf::DW_TAG_null: {
638 } break;
639 case dwarf::DW_TAG_compile_unit: {
641 } break;
642 case dwarf::DW_TAG_partial_unit: {
644 } break;
645 case dwarf::DW_TAG_type_unit: {
647 } break;
648 case dwarf::DW_TAG_skeleton_unit: {
650 } break;
651
652 default: {
656 } break;
657 }
658}
659
662 switch (DieEntry->getTag()) {
663 case dwarf::DW_TAG_array_type:
664 case dwarf::DW_TAG_coarray_type:
665 case dwarf::DW_TAG_class_type:
666 case dwarf::DW_TAG_common_block:
667 case dwarf::DW_TAG_lexical_block:
668 case dwarf::DW_TAG_structure_type:
669 case dwarf::DW_TAG_subprogram:
670 case dwarf::DW_TAG_subroutine_type:
671 case dwarf::DW_TAG_union_type:
672 case dwarf::DW_TAG_GNU_template_template_param:
673 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
675 } break;
676 case dwarf::DW_TAG_enumeration_type: {
677
679 } break;
680 default: {
681
682 }
683 }
684
685
688 CurChild && CurChild->getAbbreviationDeclarationPtr();
689 CurChild = CU.getSiblingEntry(CurChild)) {
690 std::optional<size_t> ArrayIndex = tagToArrayIndex(CU, CurChild);
691 if (!ArrayIndex)
692 continue;
693
695 "Wrong index for ChildIndexesWidth");
697 }
698
699
700
702 size_t digitsCounter = 1;
703 size_t NumToCompare = 15;
704
705 while (NumToCompare < Width) {
706 NumToCompare <<= 4;
707 digitsCounter++;
708 }
709
710 Width = digitsCounter;
711 }
712 }
713}
714
718 return std::nullopt;
719
720 switch (DieEntry->getTag()) {
721 case dwarf::DW_TAG_unspecified_parameters:
722 case dwarf::DW_TAG_formal_parameter:
723 return 0;
724 case dwarf::DW_TAG_template_value_parameter:
725 case dwarf::DW_TAG_template_type_parameter:
726 return 1;
727 case dwarf::DW_TAG_enumeration_type:
728 if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx()) {
729 if (*ParentIdx && CU.getDebugInfoEntry(*ParentIdx)->getTag() ==
730 dwarf::DW_TAG_array_type)
731 return 2;
732 }
733 return std::nullopt;
734 case dwarf::DW_TAG_subrange_type:
735 return 3;
736 case dwarf::DW_TAG_generic_subrange:
737 return 4;
738 case dwarf::DW_TAG_enumerator:
739 return 5;
740 case dwarf::DW_TAG_namelist_item:
741 return 6;
742 case dwarf::DW_TAG_member:
743 return 7;
744 default:
745 return std::nullopt;
746 };
747}
748
749std::optional<std::pair<size_t, size_t>>
752 std::optional<size_t> ArrayIndex = tagToArrayIndex(CU, ChildDieEntry);
753 if (!ArrayIndex)
754 return std::nullopt;
755
757 "Wrong index for ChildIndexesWidth");
759 "Index width exceeds 16 digits.");
760
761 std::pair<size_t, size_t> Result = std::make_pair(
764 return Result;
765}
Analysis containing CSE Info
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static std::optional< UnitEntryPairTy > getTypeDeduplicationCandidate(UnitEntryPairTy UnitEntryPair)
static dwarf::Attribute TypeAttr[]
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.
StringRef substr(size_t Start, size_t N=StringRef::npos) const
Return a reference to the substring from [Start, Start + N).
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
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)
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 addParentName(UnitEntryPairTy &InputUnitEntryPair)
Add names of parent dies to the built name.
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...
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.
size_t RecursionDepth
Recursion counter.
void addTypePrefix(const DWARFDebugInfoEntry *DieEntry)
Add type prefix to the built name.
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...
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...
Error addTypeName(UnitEntryPairTy InputUnitEntryPair, bool AddParentNames)
Add type name to the built name.
void addArrayDimension(UnitEntryPairTy InputUnitEntryPair)
Add array type dimension.
void addValueName(UnitEntryPairTy InputUnitEntryPair, dwarf::Attribute Attr)
Add value name to the built name.
TypeEntry * insert(StringRef 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.
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.
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