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