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 && Name.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