LLVM 20.0.0git
SyntheticTypeNameBuilder.cpp
Go to the documentation of this file.
1//===- SyntheticTypeNameBuilder.cpp ---------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
14
15using namespace llvm;
16using namespace dwarf_linker;
17using namespace dwarf_linker::parallel;
18
20 UnitEntryPairTy InputUnitEntryPair,
21 std::optional<std::pair<size_t, size_t>> ChildIndex) {
22 [[maybe_unused]] const CompileUnit::DIEInfo &Info =
23 InputUnitEntryPair.CU->getDIEInfo(InputUnitEntryPair.DieEntry);
24 assert(Info.needToPlaceInTypeTable() &&
25 "Cann't assign name for non-type DIE");
26
27 if (InputUnitEntryPair.CU->getDieTypeEntry(InputUnitEntryPair.DieEntry) !=
28 nullptr)
29 return Error::success();
30
33 return addDIETypeName(InputUnitEntryPair, ChildIndex, true);
34}
35
37 UnitEntryPairTy InputUnitEntryPair) {
38 for (const DWARFDebugInfoEntry *CurChild =
39 InputUnitEntryPair.CU->getFirstChildEntry(
40 InputUnitEntryPair.DieEntry);
41 CurChild && CurChild->getAbbreviationDeclarationPtr();
42 CurChild = InputUnitEntryPair.CU->getSiblingEntry(CurChild)) {
43 if (CurChild->getTag() == dwarf::DW_TAG_subrange_type ||
44 CurChild->getTag() == dwarf::DW_TAG_generic_subrange) {
45 SyntheticName += "[";
46 if (std::optional<DWARFFormValue> Val =
47 InputUnitEntryPair.CU->find(CurChild, dwarf::DW_AT_count)) {
48 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
49 SyntheticName += std::to_string(*ConstVal);
50 } else if (std::optional<int64_t> ConstVal =
51 Val->getAsSignedConstant()) {
52 SyntheticName += std::to_string(*ConstVal);
53 }
54 }
55
56 SyntheticName += "]";
57 }
58 }
59}
60
61static dwarf::Attribute TypeAttr[] = {dwarf::DW_AT_type};
63 bool addTemplateParameters) {
64 // Add entry type.
65 if (Error Err = addReferencedODRDies(InputUnitEntryPair, false, TypeAttr))
66 return Err;
67 SyntheticName += ':';
68
71 for (const DWARFDebugInfoEntry *CurChild =
72 InputUnitEntryPair.CU->getFirstChildEntry(
73 InputUnitEntryPair.DieEntry);
74 CurChild && CurChild->getAbbreviationDeclarationPtr();
75 CurChild = InputUnitEntryPair.CU->getSiblingEntry(CurChild)) {
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) {
86 for (const DWARFDebugInfoEntry *CurGNUChild =
87 InputUnitEntryPair.CU->getFirstChildEntry(CurChild);
88 CurGNUChild && CurGNUChild->getAbbreviationDeclarationPtr();
89 CurGNUChild = InputUnitEntryPair.CU->getSiblingEntry(CurGNUChild))
90 TemplateParameters.push_back(CurGNUChild);
91 } else if (ChildTag == dwarf::DW_TAG_GNU_formal_parameter_pack) {
92 for (const DWARFDebugInfoEntry *CurGNUChild =
93 InputUnitEntryPair.CU->getFirstChildEntry(CurChild);
94 CurGNUChild && CurGNUChild->getAbbreviationDeclarationPtr();
95 CurGNUChild = InputUnitEntryPair.CU->getSiblingEntry(CurGNUChild))
96 FunctionParameters.push_back(CurGNUChild);
97 }
98 }
99
100 // Add parameters.
101 if (Error Err = addParamNames(*InputUnitEntryPair.CU, FunctionParameters))
102 return Err;
103
104 // Add template parameters.
105 if (Error Err =
106 addTemplateParamNames(*InputUnitEntryPair.CU, TemplateParameters))
107 return Err;
108
109 return Error::success();
110}
111
115 SyntheticName += '(';
116 for (const DWARFDebugInfoEntry *FunctionParameter : FunctionParameters) {
117 if (SyntheticName.back() != '(')
118 SyntheticName += ", ";
119 if (dwarf::toUnsigned(CU.find(FunctionParameter, dwarf::DW_AT_artificial),
120 0))
121 SyntheticName += "^";
122 if (Error Err = addReferencedODRDies(
123 UnitEntryPairTy{&CU, FunctionParameter}, false, TypeAttr))
124 return Err;
125 }
126 SyntheticName += ')';
127 return Error::success();
128}
129
133 if (!TemplateParameters.empty()) {
134 SyntheticName += '<';
135 for (const DWARFDebugInfoEntry *Parameter : TemplateParameters) {
136 if (SyntheticName.back() != '<')
137 SyntheticName += ", ";
138
139 if (Parameter->getTag() == dwarf::DW_TAG_template_value_parameter) {
140 if (std::optional<DWARFFormValue> Val =
141 CU.find(Parameter, dwarf::DW_AT_const_value)) {
142 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant())
143 SyntheticName += std::to_string(*ConstVal);
144 else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant())
145 SyntheticName += std::to_string(*ConstVal);
146 }
147 }
148
149 if (Error Err = addReferencedODRDies(UnitEntryPairTy{&CU, Parameter},
150 false, TypeAttr))
151 return Err;
152 }
153 SyntheticName += '>';
154 }
155 return Error::success();
156}
157
159 std::pair<size_t, size_t> ChildIdx) {
160 std::string Name;
162 stream << format_hex_no_prefix(ChildIdx.first, ChildIdx.second);
164}
165
166// Examine DIE and return type deduplication candidate: some DIEs could not be
167// deduplicated, namespace may refer to another namespace.
168static std::optional<UnitEntryPairTy>
170 switch (UnitEntryPair.DieEntry->getTag()) {
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 // Check if current namespace refers another.
180 if (UnitEntryPair.CU->find(UnitEntryPair.DieEntry, dwarf::DW_AT_extension))
181 UnitEntryPair = UnitEntryPair.getNamespaceOrigin();
182
183 // Content of anonimous namespaces should not be deduplicated.
184 if (!UnitEntryPair.CU->find(UnitEntryPair.DieEntry, dwarf::DW_AT_name))
185 llvm_unreachable("Cann't deduplicate anonimous namespace");
186
187 return UnitEntryPair;
188 }
189 default:
190 return UnitEntryPair;
191 }
192}
193
195 UnitEntryPairTy &InputUnitEntryPair) {
196 std::optional<UnitEntryPairTy> UnitEntryPair = InputUnitEntryPair.getParent();
197 if (!UnitEntryPair)
198 return Error::success();
199
200 UnitEntryPair = getTypeDeduplicationCandidate(*UnitEntryPair);
201 if (!UnitEntryPair)
202 return Error::success();
203
204 if (TypeEntry *ImmediateParentName =
205 UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry)) {
206 SyntheticName += ImmediateParentName->getKey();
207 SyntheticName += ".";
208 return Error::success();
209 }
210
211 // Collect parent entries.
213 do {
214 Parents.push_back(*UnitEntryPair);
215
216 UnitEntryPair = UnitEntryPair->getParent();
217 if (!UnitEntryPair)
218 break;
219
220 UnitEntryPair = getTypeDeduplicationCandidate(*UnitEntryPair);
221 if (!UnitEntryPair)
222 break;
223
224 } while (!UnitEntryPair->CU->getDieTypeEntry(UnitEntryPair->DieEntry));
225
226 // Assign name for each parent entry.
227 size_t NameStart = SyntheticName.size();
228 for (UnitEntryPairTy Parent : reverse(Parents)) {
229 SyntheticName.resize(NameStart);
230 if (Error Err = addDIETypeName(Parent, std::nullopt, true))
231 return Err;
232 }
233
234 // Add parents delimiter.
235 SyntheticName += ".";
236 return Error::success();
237}
238
240 UnitEntryPairTy &InputUnitEntryPair, bool &HasDeclFileName) {
241 if (std::optional<DWARFFormValue> DeclFileVal = InputUnitEntryPair.CU->find(
242 InputUnitEntryPair.DieEntry, dwarf::DW_AT_decl_file)) {
243 if (std::optional<DWARFFormValue> DeclLineVal = InputUnitEntryPair.CU->find(
244 InputUnitEntryPair.DieEntry, dwarf::DW_AT_decl_line)) {
245 if (std::optional<std::pair<StringRef, StringRef>> DirAndFilename =
246 InputUnitEntryPair.CU->getDirAndFilenameFromLineTable(
247 *DeclFileVal)) {
248 SyntheticName += DirAndFilename->first;
249 SyntheticName += DirAndFilename->second;
250
251 if (std::optional<uint64_t> DeclLineIntVal =
252 dwarf::toUnsigned(*DeclLineVal)) {
253 SyntheticName += " ";
254 SyntheticName += utohexstr(*DeclLineIntVal);
255 }
256
257 HasDeclFileName = true;
258 }
259 }
260 }
261}
262
264 dwarf::Attribute Attr) {
265 if (std::optional<DWARFFormValue> Val =
266 InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry, Attr)) {
267 if (std::optional<uint64_t> ConstVal = Val->getAsUnsignedConstant()) {
268 SyntheticName += " ";
269 SyntheticName += std::to_string(*ConstVal);
270 } else if (std::optional<int64_t> ConstVal = Val->getAsSignedConstant()) {
271 SyntheticName += " ";
272 SyntheticName += std::to_string(*ConstVal);
273 }
274 }
275}
276
278 UnitEntryPairTy InputUnitEntryPair, bool AssignNameToTypeDescriptor,
280 bool FirstIteration = true;
281 for (dwarf::Attribute Attr : ODRAttrs) {
282 if (std::optional<DWARFFormValue> AttrValue =
283 InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry, Attr)) {
284 std::optional<UnitEntryPairTy> RefDie =
285 InputUnitEntryPair.CU->resolveDIEReference(
287
288 if (!RefDie)
289 continue;
290
291 if (!RefDie->DieEntry)
292 return createStringError(std::errc::invalid_argument,
293 "Cann't resolve DIE reference");
294
295 if (!FirstIteration)
296 SyntheticName += ",";
297
299 if (RecursionDepth > 1000)
300 return createStringError(
301 std::errc::invalid_argument,
302 "Cann't parse input DWARF. Recursive dependence.");
303
304 if (Error Err =
305 addDIETypeName(*RefDie, std::nullopt, AssignNameToTypeDescriptor))
306 return Err;
308 FirstIteration = false;
309 }
310 }
311
312 return Error::success();
313}
314
316 bool AddParentNames) {
317 bool HasLinkageName = false;
318 bool HasShortName = false;
319 bool HasTemplatesInShortName = false;
320 bool HasDeclFileName = false;
321
322 // Try to get name from the DIE.
323 if (std::optional<DWARFFormValue> Val = InputUnitEntryPair.CU->find(
324 InputUnitEntryPair.DieEntry,
325 {dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_AT_linkage_name})) {
326 // Firstly check for linkage name.
328 HasLinkageName = true;
329 } else if (std::optional<DWARFFormValue> Val = InputUnitEntryPair.CU->find(
330 InputUnitEntryPair.DieEntry, dwarf::DW_AT_name)) {
331 // Then check for short name.
334
335 HasShortName = true;
336 HasTemplatesInShortName =
337 Name.ends_with(">") && Name.count("<") != 0 && !Name.ends_with("<=>");
338 } else {
339 // Finally check for declaration attributes.
340 addDieNameFromDeclFileAndDeclLine(InputUnitEntryPair, HasDeclFileName);
341 }
342
343 // Add additional name parts for some DIEs.
344 switch (InputUnitEntryPair.DieEntry->getTag()) {
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))
353 SyntheticName += "^";
354
355 // No need to add signature information for linkage name,
356 // also no need to add template parameters name if short name already
357 // includes them.
358 if (!HasLinkageName)
359 if (Error Err =
360 addSignature(InputUnitEntryPair, !HasTemplatesInShortName))
361 return Err;
362 } break;
363 case dwarf::DW_TAG_coarray_type:
364 case dwarf::DW_TAG_array_type: {
365 addArrayDimension(InputUnitEntryPair);
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 // TODO add support for DW_AT_location
373 addValueName(InputUnitEntryPair, dwarf::DW_AT_const_value);
374 }
375 } break;
376 default: {
377 // Nothing to do.
378 } break;
379 }
380
381 // If name for the DIE is not determined yet add referenced types to the name.
382 if (!HasLinkageName && !HasShortName && !HasDeclFileName) {
383 if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
385 if (Error Err = addReferencedODRDies(InputUnitEntryPair, AddParentNames,
387 return Err;
388 }
389
390 return Error::success();
391}
392
394 UnitEntryPairTy InputUnitEntryPair,
395 std::optional<std::pair<size_t, size_t>> ChildIndex,
396 bool AssignNameToTypeDescriptor) {
397 std::optional<UnitEntryPairTy> UnitEntryPair =
398 getTypeDeduplicationCandidate(InputUnitEntryPair);
399 if (!UnitEntryPair)
400 return Error::success();
401
402 TypeEntry *TypeEntryPtr =
403 InputUnitEntryPair.CU->getDieTypeEntry(InputUnitEntryPair.DieEntry);
404 // Check if DIE already has a name.
405 if (!TypeEntryPtr) {
406 size_t NameStart = SyntheticName.size();
407 if (AssignNameToTypeDescriptor) {
408 if (Error Err = addParentName(*UnitEntryPair))
409 return Err;
410 }
411 addTypePrefix(UnitEntryPair->DieEntry);
412
413 if (ChildIndex) {
414 addOrderedName(*ChildIndex);
415 } else {
416 if (Error Err = addTypeName(*UnitEntryPair, AssignNameToTypeDescriptor))
417 return Err;
418 }
419
420 if (AssignNameToTypeDescriptor) {
421 // Add built name to the DIE.
422 TypeEntryPtr = TypePoolRef.insert(SyntheticName.substr(NameStart));
423 InputUnitEntryPair.CU->setDieTypeEntry(InputUnitEntryPair.DieEntry,
424 TypeEntryPtr);
425 }
426 } else
427 SyntheticName += TypeEntryPtr->getKey();
428
429 return Error::success();
430}
431
433 const DWARFDebugInfoEntry *DieEntry) {
434 switch (DieEntry->getTag()) {
435 case dwarf::DW_TAG_base_type: {
436 SyntheticName += "{0}";
437 } break;
438 case dwarf::DW_TAG_namespace: {
439 SyntheticName += "{1}";
440 } break;
441 case dwarf::DW_TAG_formal_parameter: {
442 SyntheticName += "{2}";
443 } break;
444 // dwarf::DW_TAG_unspecified_parameters have the same prefix as before.
445 case dwarf::DW_TAG_unspecified_parameters: {
446 SyntheticName += "{2}";
447 } break;
448 case dwarf::DW_TAG_template_type_parameter: {
449 SyntheticName += "{3}";
450 } break;
451 // dwarf::DW_TAG_template_value_parameter have the same prefix as before.
452 case dwarf::DW_TAG_template_value_parameter: {
453 SyntheticName += "{3}";
454 } break;
455 case dwarf::DW_TAG_GNU_formal_parameter_pack: {
456 SyntheticName += "{4}";
457 } break;
458 case dwarf::DW_TAG_GNU_template_parameter_pack: {
459 SyntheticName += "{5}";
460 } break;
461 case dwarf::DW_TAG_inheritance: {
462 SyntheticName += "{6}";
463 } break;
464 case dwarf::DW_TAG_array_type: {
465 SyntheticName += "{7}";
466 } break;
467 case dwarf::DW_TAG_class_type: {
468 SyntheticName += "{8}";
469 } break;
470 case dwarf::DW_TAG_enumeration_type: {
471 SyntheticName += "{9}";
472 } break;
473 case dwarf::DW_TAG_imported_declaration: {
474 SyntheticName += "{A}";
475 } break;
476 case dwarf::DW_TAG_member: {
477 SyntheticName += "{B}";
478 } break;
479 case dwarf::DW_TAG_pointer_type: {
480 SyntheticName += "{C}";
481 } break;
482 case dwarf::DW_TAG_reference_type: {
483 SyntheticName += "{D}";
484 } break;
485 case dwarf::DW_TAG_string_type: {
486 SyntheticName += "{E}";
487 } break;
488 case dwarf::DW_TAG_structure_type: {
489 SyntheticName += "{F}";
490 } break;
491 case dwarf::DW_TAG_subroutine_type: {
492 SyntheticName += "{G}";
493 } break;
494 case dwarf::DW_TAG_typedef: {
495 SyntheticName += "{H}";
496 } break;
497 case dwarf::DW_TAG_union_type: {
498 SyntheticName += "{I}";
499 } break;
500 case dwarf::DW_TAG_variant: {
501 SyntheticName += "{J}";
502 } break;
503 case dwarf::DW_TAG_inlined_subroutine: {
504 SyntheticName += "{K}";
505 } break;
506 case dwarf::DW_TAG_module: {
507 SyntheticName += "{L}";
508 } break;
509 case dwarf::DW_TAG_ptr_to_member_type: {
510 SyntheticName += "{M}";
511 } break;
512 case dwarf::DW_TAG_set_type: {
513 SyntheticName += "{N}";
514 } break;
515 case dwarf::DW_TAG_subrange_type: {
516 SyntheticName += "{O}";
517 } break;
518 case dwarf::DW_TAG_with_stmt: {
519 SyntheticName += "{P}";
520 } break;
521 case dwarf::DW_TAG_access_declaration: {
522 SyntheticName += "{Q}";
523 } break;
524 case dwarf::DW_TAG_catch_block: {
525 SyntheticName += "{R}";
526 } break;
527 case dwarf::DW_TAG_const_type: {
528 SyntheticName += "{S}";
529 } break;
530 case dwarf::DW_TAG_constant: {
531 SyntheticName += "{T}";
532 } break;
533 case dwarf::DW_TAG_enumerator: {
534 SyntheticName += "{U}";
535 } break;
536 case dwarf::DW_TAG_file_type: {
537 SyntheticName += "{V}";
538 } break;
539 case dwarf::DW_TAG_friend: {
540 SyntheticName += "{W}";
541 } break;
542 case dwarf::DW_TAG_namelist: {
543 SyntheticName += "{X}";
544 } break;
545 case dwarf::DW_TAG_namelist_item: {
546 SyntheticName += "{Y}";
547 } break;
548 case dwarf::DW_TAG_packed_type: {
549 SyntheticName += "{Z}";
550 } break;
551 case dwarf::DW_TAG_subprogram: {
552 SyntheticName += "{a}";
553 } break;
554 case dwarf::DW_TAG_thrown_type: {
555 SyntheticName += "{b}";
556 } break;
557 case dwarf::DW_TAG_variant_part: {
558 SyntheticName += "{c}";
559 } break;
560 case dwarf::DW_TAG_variable: {
561 SyntheticName += "{d}";
562 } break;
563 case dwarf::DW_TAG_volatile_type: {
564 SyntheticName += "{e}";
565 } break;
566 case dwarf::DW_TAG_dwarf_procedure: {
567 SyntheticName += "{f}";
568 } break;
569 case dwarf::DW_TAG_restrict_type: {
570 SyntheticName += "{g}";
571 } break;
572 case dwarf::DW_TAG_interface_type: {
573 SyntheticName += "{h}";
574 } break;
575 case dwarf::DW_TAG_imported_module: {
576 SyntheticName += "{i}";
577 } break;
578 case dwarf::DW_TAG_unspecified_type: {
579 SyntheticName += "{j}";
580 } break;
581 case dwarf::DW_TAG_imported_unit: {
582 SyntheticName += "{k}";
583 } break;
584 case dwarf::DW_TAG_condition: {
585 SyntheticName += "{l}";
586 } break;
587 case dwarf::DW_TAG_shared_type: {
588 SyntheticName += "{m}";
589 } break;
590 case dwarf::DW_TAG_rvalue_reference_type: {
591 SyntheticName += "{n}";
592 } break;
593 case dwarf::DW_TAG_template_alias: {
594 SyntheticName += "{o}";
595 } break;
596 case dwarf::DW_TAG_coarray_type: {
597 SyntheticName += "{p}";
598 } break;
599 case dwarf::DW_TAG_generic_subrange: {
600 SyntheticName += "{q}";
601 } break;
602 case dwarf::DW_TAG_dynamic_type: {
603 SyntheticName += "{r}";
604 } break;
605 case dwarf::DW_TAG_atomic_type: {
606 SyntheticName += "{s}";
607 } break;
608 case dwarf::DW_TAG_call_site: {
609 SyntheticName += "{t}";
610 } break;
611 case dwarf::DW_TAG_call_site_parameter: {
612 SyntheticName += "{u}";
613 } break;
614 case dwarf::DW_TAG_immutable_type: {
615 SyntheticName += "{v}";
616 } break;
617 case dwarf::DW_TAG_entry_point: {
618 SyntheticName += "{w}";
619 } break;
620 case dwarf::DW_TAG_label: {
621 SyntheticName += "{x}";
622 } break;
623 case dwarf::DW_TAG_lexical_block: {
624 SyntheticName += "{y}";
625 } break;
626 case dwarf::DW_TAG_common_block: {
627 SyntheticName += "{z}";
628 } break;
629 case dwarf::DW_TAG_common_inclusion: {
630 SyntheticName += "{|}";
631 } break;
632 case dwarf::DW_TAG_try_block: {
633 SyntheticName += "{~}";
634 } break;
635
636 case dwarf::DW_TAG_null: {
637 llvm_unreachable("No type prefix for DW_TAG_null");
638 } break;
639 case dwarf::DW_TAG_compile_unit: {
640 llvm_unreachable("No type prefix for DW_TAG_compile_unit");
641 } break;
642 case dwarf::DW_TAG_partial_unit: {
643 llvm_unreachable("No type prefix for DW_TAG_partial_unit");
644 } break;
645 case dwarf::DW_TAG_type_unit: {
646 llvm_unreachable("No type prefix for DW_TAG_type_unit");
647 } break;
648 case dwarf::DW_TAG_skeleton_unit: {
649 llvm_unreachable("No type prefix for DW_TAG_skeleton_unit");
650 } break;
651
652 default: {
653 SyntheticName += "{~~";
654 SyntheticName += utohexstr(DieEntry->getTag());
655 SyntheticName += "}";
656 } break;
657 }
658}
659
661 CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry) {
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: {
674 NeedCountChildren = true;
675 } break;
676 case dwarf::DW_TAG_enumeration_type: {
677 // TODO : do we need to add condition
678 NeedCountChildren = true;
679 } break;
680 default: {
681 // Nothing to do.
682 }
683 }
684
685 // Calculate maximal index value
686 if (NeedCountChildren) {
687 for (const DWARFDebugInfoEntry *CurChild = CU.getFirstChildEntry(DieEntry);
688 CurChild && CurChild->getAbbreviationDeclarationPtr();
689 CurChild = CU.getSiblingEntry(CurChild)) {
690 std::optional<size_t> ArrayIndex = tagToArrayIndex(CU, CurChild);
691 if (!ArrayIndex)
692 continue;
693
694 assert((*ArrayIndex < ChildIndexesWidth.size()) &&
695 "Wrong index for ChildIndexesWidth");
696 ChildIndexesWidth[*ArrayIndex]++;
697 }
698
699 // Calculate index field width(number of digits in hexadecimal
700 // representation).
701 for (size_t &Width : ChildIndexesWidth) {
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
716 CompileUnit &CU, const DWARFDebugInfoEntry *DieEntry) {
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>>
751 CompileUnit &CU, const DWARFDebugInfoEntry *ChildDieEntry) {
752 std::optional<size_t> ArrayIndex = tagToArrayIndex(CU, ChildDieEntry);
753 if (!ArrayIndex)
754 return std::nullopt;
755
756 assert((*ArrayIndex < OrderedChildIdxs.size()) &&
757 "Wrong index for ChildIndexesWidth");
758 assert(ChildIndexesWidth[*ArrayIndex] < 16 &&
759 "Index width exceeds 16 digits.");
760
761 std::pair<size_t, size_t> Result = std::make_pair(
762 OrderedChildIdxs[*ArrayIndex], ChildIndexesWidth[*ArrayIndex]);
763 OrderedChildIdxs[*ArrayIndex]++;
764 return Result;
765}
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
std::string Name
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),...
Definition: ArrayRef.h:41
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
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
StringRef substr(size_t Start, size_t N=StringRef::npos) const
Return a reference to the substring from [Start, Start + N).
Definition: SmallString.h:232
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
void resize(size_type N)
Definition: SmallVector.h:638
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef getKey() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
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.
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.
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)
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)
Definition: TypePool.h:121
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
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()
Attribute
Attributes.
Definition: Dwarf.h:123
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.
Definition: AddressRanges.h:18
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1291
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
Definition: Format.h:200
This is a helper structure which keeps a debug info entry with it's containing compilation unit.