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