LLVM: lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

39#include

40#include

41#include

42

43using namespace llvm;

44

45

47 "add-linkage-names-to-declaration-call-origins", cl::Hidden,

48 cl::desc("Add DW_AT_linkage_name to function declaration DIEs "

49 "referenced by DW_AT_call_origin attributes. Enabled by default "

50 "for -gsce debugger tuning."));

51

53 "emit-func-debug-line-table-offsets", cl::Hidden,

54 cl::desc("Include line table offset in function's debug info and emit end "

55 "sequence after each function's line data."),

57

59 bool EnabledByDefault = DD->tuneForSCE();

60 if (EnabledByDefault)

63}

64

66

67

68

69

70

71

72 if (DW->getDwarfVersion() >= 5 && Kind == UnitKind::Skeleton)

73 return dwarf::DW_TAG_skeleton_unit;

74

75 return dwarf::DW_TAG_compile_unit;

76}

77

84}

85

86

87

92

93

96

97 bool UseAddrOffsetFormOrExpressions =

99

101 if (Label->isInSection() && UseAddrOffsetFormOrExpressions)

103

104 if (Base || Base == Label) {

108 : dwarf::DW_FORM_GNU_addr_index,

110 return;

111 }

112

113

114

116 "Addr+offset expressions are only valuable when using debug_addr (to "

117 "reduce relocations) available in DWARFv5 or higher");

122 } else

126}

127

131 if (Label)

133 else

135}

136

138

139

140

141

142

144 if (!File)

145 return Asm->OutStreamer->emitDwarfFileDirective(0, "", "", std::nullopt,

146 std::nullopt, CUID);

147

148 if (LastFile != File) {

149 LastFile = File;

150 LastFileID = Asm->OutStreamer->emitDwarfFileDirective(

151 0, File->getDirectory(), File->getFilename(), DD->getMD5AsBytes(File),

152 File->getSource(), CUID);

153 }

154 return LastFileID;

155}

156

159

161 return Die;

162

164

165 auto *GVContext = GV->getScope();

167

168 auto *CB = GVContext ? dyn_cast(GVContext) : nullptr;

171

172

177 assert(SDMDecl->isStaticMember() && "Expected static member decl");

179

181 addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);

182

183

184 if (GTy != SDMDecl->getBaseType())

185 addType(*VariableDIE, GTy);

186 } else {

188

190 if (!DisplayName.empty())

192 if (GTy)

193 addType(*VariableDIE, GTy);

194

195

197 addFlag(*VariableDIE, dwarf::DW_AT_external);

198

199

201 }

202

204 addFlag(*VariableDIE, dwarf::DW_AT_declaration);

205 else

207

209

211 addUInt(*VariableDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,

212 AlignInBytes);

213

216

217

219

220 return VariableDIE;

221}

222

225 bool addToAccelTable = false;

226 DIELoc *Loc = nullptr;

227 std::optional NVPTXAddressSpace;

228 std::unique_ptr DwarfExpr;

229 for (const auto &GE : GlobalExprs) {

232

233

234

235

236

237 if (GlobalExprs.size() == 1 && Expr && Expr->isConstant()) {

238 addToAccelTable = true;

240 *VariableDIE,

244 break;

245 }

246

247

248

249 if (Global && Global->hasDLLImportStorageClass())

250 continue;

251

252

254 continue;

255

258 continue;

259

260 if (!Loc) {

261 addToAccelTable = true;

263 DwarfExpr = std::make_unique(*Asm, *this, *Loc);

264 }

265

266 if (Expr) {

267

268

269

270

271

272

273 unsigned LocalNVPTXAddressSpace;

279 NVPTXAddressSpace = LocalNVPTXAddressSpace;

280 }

281 }

282 DwarfExpr->addFragmentOffset(Expr);

283 }

284

287

288

289 auto GetPointerSizedFormAndOp = [this]() {

291 assert((PointerSize == 4 || PointerSize == 8) &&

292 "Add support for other sizes if necessary");

293 struct FormAndOp {

296 };

297 return PointerSize == 4

298 ? FormAndOp{dwarf::DW_FORM_data4, dwarf::DW_OP_const4u}

299 : FormAndOp{dwarf::DW_FORM_data8, dwarf::DW_OP_const8u};

300 };

301 if (Global->isThreadLocal()) {

303

304

305

306

307

308 addWasmRelocBaseGlobal(Loc, "__tls_base", 1);

310 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

312

313 } else {

314

315

317 auto FormAndOp = GetPointerSizedFormAndOp();

318

319 addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);

320

321

322 addExpr(*Loc, FormAndOp.Form,

324 } else {

325 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);

326 addUInt(*Loc, dwarf::DW_FORM_udata,

328 }

329

330 addUInt(*Loc, dwarf::DW_FORM_data1,

332 : dwarf::DW_OP_form_tls_address);

333 }

336

337

338

339 addWasmRelocBaseGlobal(Loc, "__memory_base", 1);

341 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

347 auto FormAndOp = GetPointerSizedFormAndOp();

348

349 addUInt(*Loc, dwarf::DW_FORM_data1, FormAndOp.Op);

350

351 addExpr(*Loc, FormAndOp.Form,

353

355 unsigned DwarfBaseReg =

357 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + DwarfBaseReg);

358

359 addSInt(*Loc, dwarf::DW_FORM_sdata, 0);

360

361 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

362 } else {

365 }

366 }

367

368

369

370

371 if (DwarfExpr->isUnknownLocation())

372 DwarfExpr->setMemoryLocationKind();

373 DwarfExpr->addExpression(Expr);

374 }

376

377

378

379

380 const unsigned NVPTX_ADDR_global_space = 5;

381 addUInt(*VariableDIE, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,

382 NVPTXAddressSpace.value_or(NVPTX_ADDR_global_space));

383 }

384 if (Loc)

385 addBlock(*VariableDIE, dwarf::DW_AT_location, DwarfExpr->finalize());

386

389

390 if (addToAccelTable) {

392 *VariableDIE);

393

394

395

399 *VariableDIE);

400 }

401}

402

405

407 return NDie;

409 DIE &NDie = createAndAddDIE(dwarf::DW_TAG_common_block, *ContextDIE, CB);

417 return &NDie;

418}

419

422

424 bool SameAsPrevCU = this == PrevCU;

426

427

428

429

430 if (CURanges.empty() || !SameAsPrevCU ||

431 (&CURanges.back().End->getSection() !=

432 &Range.End->getSection())) {

433

434 if (PrevCU)

436 CURanges.push_back(Range);

437 return;

438 }

439

440 CURanges.back().End = Range.End;

441}

442

445 return;

446

450 } else {

451 LineTableStartSym =

453 }

454

455

456

457

458

459

462}

463

466 addSectionLabel(D, dwarf::DW_AT_stmt_list, LineTableStartSym,

468}

469

472 assert(Begin && "Begin label should not be null!");

473 assert(End && "End label should not be null!");

475 assert(End->isDefined() && "Invalid end label");

476

480 else

482}

483

484

485

486

487void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,

489

490

491 const unsigned TI_GLOBAL_RELOC = 3;

494

495

496

501 true});

502 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);

503 addSInt(*Loc, dwarf::DW_FORM_sdata, TI_GLOBAL_RELOC);

504 if (!isDwoUnit()) {

505 addLabel(*Loc, dwarf::DW_FORM_data4, Sym);

506 } else {

507

508

509

510

511

512

513 addUInt(*Loc, dwarf::DW_FORM_data4, GlobalIndex);

514 }

515}

516

517

518

519

524

525

527 BB_List.push_back({R.second.BeginLabel, R.second.EndLabel});

528

530

534 addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);

535

538 *SPDie, dwarf::DW_AT_LLVM_stmt_sequence, LineTableSym,

540 }

541

542

547 switch (FrameBase.Kind) {

551 addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);

552 }

553 break;

554 }

557 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_call_frame_cfa);

559 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_consts);

561 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);

562 }

563 addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);

564 break;

565 }

567

568 const unsigned TI_GLOBAL_RELOC = 3;

570

573

574 addWasmRelocBaseGlobal(Loc, "__stack_pointer",

576 addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);

577 addBlock(*SPDie, dwarf::DW_AT_frame_base, Loc);

578 } else {

585 addBlock(*SPDie, dwarf::DW_AT_frame_base, DwarfExpr.finalize());

586 }

587 break;

588 }

589 }

590 }

591

592

593

595

596 return *SPDie;

597}

598

599

601 DIE &ParentScopeDIE) {

602 if (!Scope || !Scope->getScopeNode())

603 return;

604

605 auto *DS = Scope->getScopeNode();

606

607 assert((Scope->getInlinedAt() || !isa(DS)) &&

608 "Only handle inlined subprograms here, use "

609 "constructSubprogramScopeDIE for non-inlined "

610 "subprograms");

611

612

613 if (Scope->getParent() && isa(DS)) {

615 assert(ScopeDIE && "Scope DIE should not be null.");

617 return;

618 }

619

620

622 return;

623

624

626 assert(ScopeDIE && "Scope DIE should not be null.");

627

628 ParentScopeDIE.addChild(ScopeDIE);

630}

631

634

635 HasRangeLists = true;

636

637

638 auto IndexAndList =

640 ->addRange(*(Skeleton ? Skeleton : this), std::move(Range));

641

642 uint32_t Index = IndexAndList.first;

643 auto &List = *IndexAndList.second;

644

645

646

647

648

649

651 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_rnglistx, Index);

652 else {

654 const MCSymbol *RangeSectionSym =

656 if (isDwoUnit())

658 RangeSectionSym);

659 else

661 RangeSectionSym);

662 }

663}

664

667 assert(!Ranges.empty());

669 (Ranges.size() == 1 &&

672 Ranges.front().Begin))) {

673 const RangeSpan &Front = Ranges.front();

674 const RangeSpan &Back = Ranges.back();

676 } else

678}

679

683 List.reserve(Ranges.size());

684 for (const InsnRange &R : Ranges) {

687

688 const auto *BeginMBB = R.first->getParent();

689 const auto *EndMBB = R.second->getParent();

690

691 const auto *MBB = BeginMBB;

692

693

694

695

696

697

698 do {

701 List.push_back(

703 : MBBSectionRange.BeginLabel,

705 }

707 break;

709 } while (true);

710 }

712}

713

715 DIE &ParentScopeDIE) {

716 assert(Scope->getScopeNode());

717 auto *DS = Scope->getScopeNode();

719

720

721 DIE *OriginDIE = getAbstractScopeDIEs()[InlinedSP];

722 assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");

723

725 ParentScopeDIE.addChild(ScopeDIE);

726 addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);

727

729

730

731 const DILocation *IA = Scope->getInlinedAt();

732 addUInt(*ScopeDIE, dwarf::DW_AT_call_file, std::nullopt,

734 addUInt(*ScopeDIE, dwarf::DW_AT_call_line, std::nullopt, IA->getLine());

735 if (IA->getColumn())

736 addUInt(*ScopeDIE, dwarf::DW_AT_call_column, std::nullopt, IA->getColumn());

738 addUInt(*ScopeDIE, dwarf::DW_AT_GNU_discriminator, std::nullopt,

739 IA->getDiscriminator());

740

741

742

744 *ScopeDIE);

745

746 return ScopeDIE;

747}

748

749

750

753 return nullptr;

754 const auto *DS = Scope->getScopeNode();

755

757 if (Scope->isAbstractScope()) {

758 assert(!getAbstractScopeDIEs().count(DS) &&

759 "Abstract DIE for this scope exists!");

760 getAbstractScopeDIEs()[DS] = ScopeDIE;

761 return ScopeDIE;

762 }

763 if (!Scope->getInlinedAt()) {

764 assert(!LexicalBlockDIEs.count(DS) &&

765 "Concrete out-of-line DIE for this scope exists!");

766 LexicalBlockDIEs[DS] = ScopeDIE;

767 }

768

770

771 return ScopeDIE;

772}

773

777 DV.setDIE(*VariableDie);

778

779 if (Abstract) {

781 } else {

782 std::visit(

783 [&](const auto &V) {

784 applyConcreteDbgVariableAttributes(V, DV, *VariableDie);

785 },

787 }

788 return VariableDie;

789}

790

791void DwarfCompileUnit::applyConcreteDbgVariableAttributes(

793 const DbgValueLoc *DVal = &Single.getValueLoc();

795 !Single.getExpr()) {

796

797

798

799 addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1, 2);

800 }

803 if (Entry->isLocation()) {

805 } else if (Entry->isInt()) {

806 auto *Expr = Single.getExpr();

807 if (Expr && Expr->getNumElements()) {

810

811 DwarfExpr.addFragmentOffset(Expr);

812 DwarfExpr.addUnsignedConstant(Entry->getInt());

813 DwarfExpr.addExpression(Expr);

814 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());

815 if (DwarfExpr.TagOffset)

816 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset,

817 dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);

818 } else

820 } else if (Entry->isConstantFP()) {

822 } else if (Entry->isConstantInt()) {

824 } else if (Entry->isTargetIndexLocation()) {

830 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());

831 }

832 return;

833 }

834

835

837 return Entry.isLocation() && !Entry.getLoc().getReg();

838 }))

839 return;

841 assert(Expr && "Variadic Debug Value must have an Expression.");

844 DwarfExpr.addFragmentOffset(Expr);

847

850 if (Entry.isLocation()) {

851 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,

852 Entry.getLoc().getReg()))

853 return false;

854 } else if (Entry.isInt()) {

855

856 DwarfExpr.addUnsignedConstant(Entry.getInt());

857 } else if (Entry.isConstantFP()) {

858

859

860

861

862 APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();

864 return false;

865 DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());

866 } else if (Entry.isConstantInt()) {

867 APInt RawBytes = Entry.getConstantInt()->getValue();

869 return false;

870 DwarfExpr.addUnsignedConstant(RawBytes.getZExtValue());

871 } else if (Entry.isTargetIndexLocation()) {

873

874

877 } else {

879 }

880 return true;

881 };

882

883 if (!DwarfExpr.addExpression(

884 std::move(Cursor),

886 return AddEntry(DVal->getLocEntries()[Idx], Cursor);

887 }))

888 return;

889

890

891 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());

892 if (DwarfExpr.TagOffset)

893 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,

894 *DwarfExpr.TagOffset);

895}

896

897void DwarfCompileUnit::applyConcreteDbgVariableAttributes(

902 if (TagOffset)

903 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,

904 *TagOffset);

905}

906

907void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,

909 DIE &VariableDie) {

910 std::optional NVPTXAddressSpace;

919 DwarfExpr.addFragmentOffset(Expr);

920

923 TRI->getOffsetOpcodes(Offset, Ops);

924

925

926

927

928

929

930

931 unsigned LocalNVPTXAddressSpace;

937 NVPTXAddressSpace = LocalNVPTXAddressSpace;

938 }

939 }

940 if (Expr)

943 DwarfExpr.setMemoryLocationKind();

946 else

947 DwarfExpr.addMachineRegExpression(

949 DwarfExpr.addExpression(std::move(Cursor));

950 }

952

953

954

955

956

957 const unsigned NVPTX_ADDR_local_space = 6;

958 addUInt(VariableDie, dwarf::DW_AT_address_class, dwarf::DW_FORM_data1,

959 NVPTXAddressSpace.value_or(NVPTX_ADDR_local_space));

960 }

961 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());

962 if (DwarfExpr.TagOffset)

963 addUInt(VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,

964 *DwarfExpr.TagOffset);

965}

966

967void DwarfCompileUnit::applyConcreteDbgVariableAttributes(

969 DIE &VariableDie) {

972

974 DwarfExpr.addFragmentOffset(&Expr);

976 DwarfExpr.beginEntryValueExpression(Cursor);

977 DwarfExpr.addMachineRegExpression(

979 DwarfExpr.addExpression(std::move(Cursor));

980 }

981 addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());

982}

983

984void DwarfCompileUnit::applyConcreteDbgVariableAttributes(

985 const std::monostate &, const DbgVariable &DV, DIE &VariableDie) {}

986

989 DIE *&ObjectPointer) {

992 ObjectPointer = Var;

993 return Var;

994}

995

1000 DL.setDIE(*LabelDie);

1001

1002 if (Scope.isAbstractScope())

1004

1005 return LabelDie;

1006}

1007

1008

1011 auto *Array = dyn_cast(Var->getType());

1012 if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)

1013 return Result;

1014 if (auto *DLVar = Array->getDataLocation())

1015 Result.push_back(DLVar);

1016 if (auto *AsVar = Array->getAssociated())

1017 Result.push_back(AsVar);

1018 if (auto *AlVar = Array->getAllocated())

1019 Result.push_back(AlVar);

1020 for (auto *El : Array->getElements()) {

1021 if (auto *Subrange = dyn_cast(El)) {

1022 if (auto Count = Subrange->getCount())

1023 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))

1024 Result.push_back(Dependency);

1025 if (auto LB = Subrange->getLowerBound())

1026 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))

1027 Result.push_back(Dependency);

1028 if (auto UB = Subrange->getUpperBound())

1029 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))

1030 Result.push_back(Dependency);

1031 if (auto ST = Subrange->getStride())

1032 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))

1033 Result.push_back(Dependency);

1034 } else if (auto *GenericSubrange = dyn_cast(El)) {

1035 if (auto Count = GenericSubrange->getCount())

1036 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(Count))

1037 Result.push_back(Dependency);

1038 if (auto LB = GenericSubrange->getLowerBound())

1039 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(LB))

1040 Result.push_back(Dependency);

1041 if (auto UB = GenericSubrange->getUpperBound())

1042 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(UB))

1043 Result.push_back(Dependency);

1044 if (auto ST = GenericSubrange->getStride())

1045 if (auto *Dependency = dyn_cast_if_present<DIVariable *>(ST))

1046 Result.push_back(Dependency);

1047 }

1048 }

1049 return Result;

1050}

1051

1052

1053

1058

1060

1062

1064

1065

1066 for (auto *Var : reverse(Input)) {

1067 DbgVar.insert({Var->getVariable(), Var});

1069 }

1070

1071

1072 while (!WorkList.empty()) {

1073 auto Item = WorkList.back();

1075 bool visitedAllDependencies = Item.getInt();

1077

1079

1080

1081 if (Visited.count(Var))

1082 continue;

1083

1084

1085 if (visitedAllDependencies) {

1086 Visited.insert(Var);

1087 Result.push_back(Var);

1088 continue;

1089 }

1090

1091

1092 auto Res = Visiting.insert(Var);

1093 if (!Res.second) {

1094 assert(false && "dependency cycle in local variables");

1095 return Result;

1096 }

1097

1098

1099

1101 for (const auto *Dependency : dependencies(Var)) {

1102

1103 if (const auto *Dep = dyn_cast(Dependency))

1106 }

1107 }

1108 return Result;

1109}

1110

1115

1116 if (Scope) {

1117 assert(!Scope->getInlinedAt());

1118 assert(!Scope->isAbstractScope());

1119

1120

1121

1123 addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);

1124 }

1125

1126

1127 DITypeRefArray FnArgs = Sub->getType()->getTypeArray();

1128

1129

1130

1131

1132 if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&

1136

1137 return ScopeDIE;

1138}

1139

1141 DIE &ScopeDIE) {

1142 DIE *ObjectPointer = nullptr;

1143

1144

1146 for (auto &DV : Vars.Args)

1148

1149

1153

1154

1157

1158

1159

1160

1163 DeferredLocalDecls.insert(LocalDecls.begin(), LocalDecls.end());

1164 }

1165

1166

1167 auto skipLexicalScope = [this](LexicalScope *S) -> bool {

1168 if (isa(S->getScopeNode()))

1169 return false;

1171 if (!Vars.Args.empty() || !Vars.Locals.empty())

1172 return false;

1175 };

1176 for (LexicalScope *LS : Scope->getChildren()) {

1177

1178

1179 if (skipLexicalScope(LS))

1181 else

1183 }

1184

1185 return ObjectPointer;

1186}

1187

1190 auto *SP = cast(Scope->getScopeNode());

1191 if (getAbstractScopeDIEs().count(SP))

1192 return;

1193

1194 DIE *ContextDIE;

1196

1199

1200

1201

1202

1203 else if (auto *SPDecl = SP->getDeclaration()) {

1206 } else {

1208

1209

1210

1212 }

1213

1214

1215

1217 *ContextDIE, nullptr);

1218

1219

1220 ContextCU->getAbstractScopeDIEs()[SP] = &AbsDef;

1221

1223 ContextCU->addSInt(AbsDef, dwarf::DW_AT_inline,

1225 : dwarf::DW_FORM_implicit_const,

1228 ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);

1229}

1230

1233}

1234

1237 return Tag;

1238 switch (Tag) {

1239 case dwarf::DW_TAG_call_site:

1240 return dwarf::DW_TAG_GNU_call_site;

1241 case dwarf::DW_TAG_call_site_parameter:

1242 return dwarf::DW_TAG_GNU_call_site_parameter;

1243 default:

1245 }

1246}

1247

1251 return Attr;

1252 switch (Attr) {

1253 case dwarf::DW_AT_call_all_calls:

1254 return dwarf::DW_AT_GNU_all_call_sites;

1255 case dwarf::DW_AT_call_target:

1256 return dwarf::DW_AT_GNU_call_site_target;

1257 case dwarf::DW_AT_call_origin:

1258 return dwarf::DW_AT_abstract_origin;

1259 case dwarf::DW_AT_call_return_pc:

1260 return dwarf::DW_AT_low_pc;

1261 case dwarf::DW_AT_call_value:

1262 return dwarf::DW_AT_GNU_call_site_value;

1263 case dwarf::DW_AT_call_tail_call:

1264 return dwarf::DW_AT_GNU_tail_call;

1265 default:

1267 }

1268}

1269

1273 return Loc;

1274 switch (Loc) {

1275 case dwarf::DW_OP_entry_value:

1276 return dwarf::DW_OP_GNU_entry_value;

1277 default:

1278 llvm_unreachable("DWARF5 location atom with no GNU analog");

1279 }

1280}

1281

1284 bool IsTail,

1287 unsigned CallReg) {

1288

1290 ScopeDIE, nullptr);

1291

1292 if (CallReg) {

1293

1296 } else {

1298 assert(CalleeDIE && "Could not create DIE for call site entry origin");

1300 !CalleeSP->isDefinition() &&

1301 !CalleeDIE->findAttribute(dwarf::DW_AT_linkage_name)) {

1302 addLinkageName(*CalleeDIE, CalleeSP->getLinkageName());

1303 }

1304

1306 *CalleeDIE);

1307 }

1308

1309 if (IsTail) {

1310

1312

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1326 addLabelAddress(CallSiteDIE, dwarf::DW_AT_call_pc, CallAddr);

1327 }

1328

1329

1330

1331

1332

1333

1334

1336 assert(PCAddr && "Missing return PC information for a call");

1339 }

1340

1341 return CallSiteDIE;

1342}

1343

1346 for (const auto &Param : Params) {

1347 unsigned Register = Param.getRegister();

1348 auto CallSiteDieParam =

1352 addAddress(*CallSiteDieParam, dwarf::DW_AT_location,

1354

1358

1360

1363

1364 CallSiteDIE.addChild(CallSiteDieParam);

1365 }

1366}

1367

1372 DIE *EntityDie;

1373 auto *Entity = Module->getEntity();

1374 if (auto *NS = dyn_cast(Entity))

1376 else if (auto *M = dyn_cast(Entity))

1378 else if (auto *SP = dyn_cast(Entity)) {

1379

1380

1381

1382 if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))

1383 EntityDie = AbsSPDie;

1384 else

1386 } else if (auto *T = dyn_cast(Entity))

1388 else if (auto *GV = dyn_cast(Entity))

1390 else if (auto *IE = dyn_cast(Entity))

1392 else

1393 EntityDie = getDIE(Entity);

1396 addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);

1398 if (Name.empty()) {

1400

1401

1402

1403

1404

1405

1407 }

1408

1409

1410

1411 DINodeArray Elements = Module->getElements();

1412 for (const auto *Element : Elements) {

1413 if (!Element)

1414 continue;

1417 }

1418

1419 return IMDie;

1420}

1421

1424

1425

1427 return Die;

1428

1430 assert(ContextDIE && "Empty scope for the imported entity!");

1431

1433 ContextDIE->addChild(IMDie);

1434 return IMDie;

1435}

1436

1439 if (DIE *AbsSPDIE = getAbstractScopeDIEs().lookup(SP)) {

1440 if (D)

1441

1442 addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);

1443 } else {

1445 if (D)

1446

1448 }

1449}

1450

1453

1454 auto *Die = Entity->getDIE();

1455

1456

1457 const DbgLabel *Label = nullptr;

1458 if (AbsEntity && AbsEntity->getDIE()) {

1459 addDIEEntry(*Die, dwarf::DW_AT_abstract_origin, *AbsEntity->getDIE());

1460 Label = dyn_cast(Entity);

1461 } else {

1462 if (const DbgVariable *Var = dyn_cast(Entity))

1464 else if ((Label = dyn_cast(Entity)))

1466 else

1467 llvm_unreachable("DbgEntity must be DbgVariable or DbgLabel.");

1468 }

1469

1470 if (!Label)

1471 return;

1472

1473 const auto *Sym = Label->getSymbol();

1474 if (Sym)

1475 return;

1476

1478

1479

1482}

1483

1485 auto &AbstractEntities = getAbstractEntities();

1486 auto I = AbstractEntities.find(Node);

1487 if (I != AbstractEntities.end())

1488 return I->second.get();

1489 return nullptr;

1490}

1491

1494 assert(Scope && Scope->isAbstractScope());

1495 auto &Entity = getAbstractEntities()[Node];

1496 if (isa(Node)) {

1497 Entity = std::make_unique(cast(Node),

1498 nullptr );

1500 } else if (isa(Node)) {

1501 Entity = std::make_unique(

1502 cast(Node), nullptr );

1504 }

1505}

1506

1508

1512 }

1513

1514 dwarf::UnitType UT = Skeleton ? dwarf::DW_UT_split_compile

1516 : dwarf::DW_UT_compile;

1520}

1521

1525 return false;

1526

1527

1529 return true;

1531 return false;

1537 }

1538 llvm_unreachable("Unhandled DICompileUnit::DebugNameTableKind enum");

1539}

1540

1541

1543 const DIScope *Context) {

1545 return;

1547 GlobalNames[FullName] = &Die;

1548}

1549

1551 const DIScope *Context) {

1553 return;

1555

1556

1557

1558

1559 GlobalNames.insert(std::make_pair(std::move(FullName), &getUnitDie()));

1560}

1561

1562

1564 const DIScope *Context) {

1566 return;

1568 GlobalTypes[FullName] = &Die;

1569}

1570

1572 const DIScope *Context) {

1574 return;

1576

1577

1578

1579

1580 GlobalTypes.insert(std::make_pair(std::move(FullName), &getUnitDie()));

1581}

1582

1585 auto *Single = std::get_ifLoc::Single(&DV);

1586 if (Single && Single->getExpr())

1587 addComplexAddress(Single->getExpr(), Die, dwarf::DW_AT_location, Location);

1588 else

1589 addAddress(Die, dwarf::DW_AT_location, Location);

1590}

1591

1592

1597 if (Location.isIndirect())

1599

1603 return;

1605

1606

1608

1610 addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,

1612}

1613

1614

1615

1616

1617

1624 DwarfExpr.setLocation(Location, DIExpr);

1625

1627

1630

1633 return;

1635

1636

1638

1640 addUInt(Die, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,

1642}

1643

1644

1646 unsigned Index) {

1648 ? dwarf::DW_FORM_loclistx

1651}

1652

1654 DIE &VariableDie) {

1656 if (Name.empty())

1657 addString(VariableDie, dwarf::DW_AT_name, Name);

1659 if (DIVar) {

1660 if (uint32_t AlignInBytes = DIVar->getAlignInBytes())

1661 addUInt(VariableDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,

1662 AlignInBytes);

1663 addAnnotation(VariableDie, DIVar->getAnnotations());

1664 }

1665

1669 addFlag(VariableDie, dwarf::DW_AT_artificial);

1670}

1671

1673 DIE &LabelDie) {

1675 if (Name.empty())

1677 const auto *DILabel = Label.getLabel();

1679}

1680

1681

1683 const MCExpr *Expr) {

1685}

1686

1689 auto *SPDecl = SP->getDeclaration();

1690 auto *Context = SPDecl ? SPDecl->getScope() : SP->getScope();

1693}

1694

1695bool DwarfCompileUnit::isDwoUnit() const {

1697}

1698

1699void DwarfCompileUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {

1701}

1702

1706}

1707

1710}

1711

1717 : dwarf::DW_AT_GNU_addr_base,

1719}

1720

1724}

1725

1727

1728

1729

1730

1735 addString(Die, dwarf::DW_AT_name,

1738 addUInt(Die, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, Btr.Encoding);

1739

1740 addUInt(Die, dwarf::DW_AT_byte_size, std::nullopt,

1742

1743 Btr.Die = &Die;

1744 }

1745}

1746

1748

1749 bool isAbstract = getAbstractScopeDIEs().count(LB->getSubprogram());

1750 if (isAbstract && getAbstractScopeDIEs().count(LB))

1751 return getAbstractScopeDIEs()[LB];

1752 assert(!isAbstract && "Missed lexical block DIE in abstract tree!");

1753

1754

1755 return LexicalBlockDIEs.lookup(LB);

1756}

1757

1759 if (isa_and_nonnull(Context)) {

1760 if (auto *LFScope = dyn_cast(Context))

1761 Context = LFScope->getNonLexicalBlockFileScope();

1762 if (auto *LScope = dyn_cast(Context))

1764

1765

1766 auto *SPScope = cast(Context);

1767 if (getAbstractScopeDIEs().count(SPScope))

1768 return getAbstractScopeDIEs()[SPScope];

1769 }

1771}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

static SmallVector< DbgVariable *, 8 > sortLocalVars(SmallVectorImpl< DbgVariable * > &Input)

Sort local variables so that variables appearing inside of helper expressions come first.

static SmallVector< const DIVariable *, 2 > dependencies(DbgVariable *Var)

Return all DIVariables that appear in count: expressions.

static cl::opt< bool > EmitFuncLineTableOffsetsOption("emit-func-debug-line-table-offsets", cl::Hidden, cl::desc("Include line table offset in function's debug info and emit end " "sequence after each function's line data."), cl::init(false))

static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD)

static dwarf::Tag GetCompileUnitType(UnitKind Kind, DwarfDebug *DW)

cl::opt< cl::boolOrDefault > AddLinkageNamesToDeclCallOrigins("add-linkage-names-to-declaration-call-origins", cl::Hidden, cl::desc("Add DW_AT_linkage_name to function declaration DIEs " "referenced by DW_AT_call_origin attributes. Enabled by default " "for -gsce debugger tuning."))

Query value using AddLinkageNamesToDeclCallOriginsForTuning.

This file contains constants used for implementing Dwarf debug support.

static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)

A Lookup helper functions.

unsigned const TargetRegisterInfo * TRI

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallString class.

Class for arbitrary precision integers.

uint64_t getZExtValue() const

Get zero extended value.

unsigned getBitWidth() const

Return the number of bits in the APInt.

unsigned getIndex(const MCSymbol *Sym, bool TLS=false)

Returns the index into the address pool with the given label/symbol.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

This class is intended to be used as a driving class for all asm writers.

const TargetLoweringObjectFile & getObjFileLowering() const

Return information about object file lowering.

MCSymbol * getSymbol(const GlobalValue *GV) const

MapVector< MBBSectionID, MBBSectionRange > MBBSectionRanges

TargetMachine & TM

Target machine description.

const MCAsmInfo * MAI

Target Asm Printer information.

MachineFunction * MF

The current machine function.

virtual const MCSymbol * getFunctionFrameSymbol() const

Return symbol for the function pseudo stack if the stack frame is not a register based.

MCSymbol * createTempSymbol(const Twine &Name) const

MCSymbol * GetExternalSymbolSymbol(Twine Sym) const

Return the MCSymbol for the specified ExternalSymbol.

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

const DataLayout & getDataLayout() const

Return information about data layout.

void emitInt64(uint64_t Value) const

Emit a long long directive and value.

Basic type, like 'int' or 'float'.

unsigned getLineNo() const

StringRef getName() const

DIScope * getScope() const

DIGlobalVariable * getDecl() const

bool isDebugDirectivesOnly() const

static std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)

static std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)

DIEBlock - Represents a block of values.

DwarfExpression implementation for singular DW_AT_location.

Represents a pointer to a location list in the debug_loc section.

DIELoc - Represents an expression location.

A structured debug information entry.

DIEValue findAttribute(dwarf::Attribute Attribute) const

Find a value in the DIE with the attribute given.

DIE & addChild(DIE *Child)

Add a child to the DIE.

DIE & addChildFront(DIE *Child)

static DIE * get(BumpPtrAllocator &Alloc, dwarf::Tag Tag)

const DIE * getUnitDie() const

Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.

Holds a DIExpression and keeps track of how many operands have been consumed so far.

element_iterator elements_end() const

bool isEntryValue() const

Check if the expression consists of exactly one entry value operand.

element_iterator elements_begin() const

ArrayRef< uint64_t > getElements() const

uint64_t getElement(unsigned I) const

std::optional< SignedOrUnsignedConstant > isConstant() const

Determine whether this represents a constant value, if so.

static const DIExpression * extractAddressClass(const DIExpression *Expr, unsigned &AddrClass)

Checks if the last 4 elements of the expression are DW_OP_constu DW_OP_swap DW_...

DIDerivedType * getStaticDataMemberDeclaration() const

MDTuple * getTemplateParams() const

bool isLocalToUnit() const

StringRef getLinkageName() const

StringRef getDisplayName() const

bool isDefinition() const

DINodeArray getAnnotations() const

An imported module (C++ using directive or similar).

DISubprogram * getSubprogram() const

Get the subprogram for this scope.

Tagged DWARF-like metadata node.

dwarf::Tag getTag() const

Base class for scope-like contexts.

StringRef getName() const

DIScope * getScope() const

StringRef getName() const

uint32_t getAlignInBytes() const

DIScope * getScope() const

StringRef getName() const

unsigned getPointerSize(unsigned AS=0) const

Layout pointer size in bytes, rounded up to a whole number of bytes.

This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...

const DINode * getEntity() const

Accessors.

This class is used to track label information.

A single location or constant within a variable location description, with either a single entry (wit...

The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.

ArrayRef< DbgValueLocEntry > getLocEntries() const

This class is used to track local variable information.

bool isArtificial() const

Return true if DbgVariable is artificial.

dwarf::Tag getTag() const

bool isObjectPointer() const

const DILocalVariable * getVariable() const

StringRef getName() const

const DIType * getType() const

Loc::Variant & asVariant()

To workaround P2162R0 https://github.com/cplusplus/papers/issues/873 the base class subobject needs t...

MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)

Return Label preceding the instruction.

MCSymbol * getLabelAfterInsn(const MachineInstr *MI)

Return Label immediately following the instruction.

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

bool useGNUAnalogForDwarf5Feature() const

Whether to use the GNU analog for a DWARF5 tag, attribute, or location atom.

void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE, SmallVector< DbgCallSiteParam, 4 > &Params)

Construct call site parameter DIEs for the CallSiteDIE.

void attachLowHighPC(DIE &D, const MCSymbol *Begin, const MCSymbol *End)

void emitHeader(bool UseOffsets) override

Emit the header for this unit, not including the initial length field.

dwarf::Tag getDwarf5OrGNUTag(dwarf::Tag Tag) const

This takes a DWARF 5 tag and returns it or a GNU analog.

DIE & updateSubprogramScopeDIE(const DISubprogram *SP, MCSymbol *LineTableSym)

Find DIE for the given subprogram and attach appropriate DW_AT_low_pc, DW_AT_high_pc and DW_AT_LLVM_s...

void constructAbstractSubprogramScopeDIE(LexicalScope *Scope)

bool includeMinimalInlineScopes() const

DIE * getOrCreateImportedEntityDIE(const DIImportedEntity *IE)

Get or create a DIE for an imported entity.

void addBaseTypeRef(DIEValueList &Die, int64_t Idx)

void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context)

Add a new global name present in a type unit to this compile unit.

void finishEntityDefinition(const DbgEntity *Entity)

void addRange(RangeSpan Range)

addRange - Add an address range to the list of ranges for this unit.

void addAddrTableBase()

Add the DW_AT_addr_base attribute to the unit DIE.

DIE & constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr, unsigned CallReg)

Construct a call site entry DIE describing a call within Scope to a callee described by CalleeSP.

std::vector< BaseTypeRef > ExprRefedBaseTypes

DIE * constructInlinedScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE)

This scope represents an inlined body of a function.

void createBaseTypeDIEs()

void addScopeRangeList(DIE &ScopeDIE, SmallVector< RangeSpan, 2 > Range)

A helper function to construct a RangeSpanList for a given lexical scope.

uint64_t getDWOId() const

DIE * getOrCreateCommonBlock(const DICommonBlock *CB, ArrayRef< GlobalExpr > GlobalExprs)

void addVariableAddress(const DbgVariable &DV, DIE &Die, MachineLocation Location)

Add DW_AT_location attribute for a DbgVariable based on provided MachineLocation.

DIE * getLexicalBlockDIE(const DILexicalBlock *LB)

Get a DIE for the given DILexicalBlock.

void addGlobalName(StringRef Name, const DIE &Die, const DIScope *Context) override

Add a new global name to the compile unit.

void createAbstractEntity(const DINode *Node, LexicalScope *Scope)

void applyStmtList(DIE &D)

Apply the DW_AT_stmt_list from this compile unit to the specified DIE.

DIE * getOrCreateContextDIE(const DIScope *Ty) override

Construct a DIE for a given scope.

void applyCommonDbgVariableAttributes(const DbgVariable &Var, DIE &VariableDie)

Add attributes to Var which reflect the common attributes of VariableDie, namely those which are not ...

DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope, MCSymbol *LineTableSym)

Construct a DIE for this subprogram scope.

DIE * constructVariableDIE(DbgVariable &DV, bool Abstract=false)

Construct a DIE for the given DbgVariable.

dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const

This takes a DWARF 5 location atom and either returns it or a GNU analog.

DIE * getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV, ArrayRef< GlobalExpr > GlobalExprs)

Get or create global variable DIE.

void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV, ArrayRef< GlobalExpr > GlobalExprs)

void applySubprogramAttributesToDefinition(const DISubprogram *SP, DIE &SPDie)

DIE * createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE)

void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr)

Add a Dwarf expression attribute data and value.

dwarf::Attribute getDwarf5OrGNUAttr(dwarf::Attribute Attr) const

This takes a DWARF 5 attribute and returns it or a GNU analog.

void addAddress(DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location)

Add an address attribute to a die based on the location provided.

void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie)

void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label)

addLocalLabelAddress - Add a dwarf label attribute data and value using DW_FORM_addr only.

DIE * constructLexicalScopeDIE(LexicalScope *Scope)

Construct new DW_TAG_lexical_block for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.

void addGlobalTypeImpl(const DIType *Ty, const DIE &Die, const DIScope *Context) override

Add a new global type to the compile unit.

unsigned getOrCreateSourceID(const DIFile *File) override

Look up the source ID for the given file.

void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE)

DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, UnitKind Kind=UnitKind::Full)

DIE * constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope)

Construct a DIE for the given DbgLabel.

void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context)

Add a new global type present in a type unit to this compile unit.

DbgEntity * getExistingAbstractEntity(const DINode *Node)

bool hasDwarfPubSections() const

void addLabelAddress(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label)

addLabelAddress - Add a dwarf label attribute data and value using either DW_FORM_addr or DW_FORM_GNU...

void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index)

Add a Dwarf loclistptr attribute data and value.

bool emitFuncLineTableOffsets() const

void addComplexAddress(const DIExpression *DIExpr, DIE &Die, dwarf::Attribute Attribute, const MachineLocation &Location)

Start with the address based on the location provided, and generate the DWARF information necessary t...

DIE * constructImportedEntityDIE(const DIImportedEntity *IE)

DwarfCompileUnit & getCU() override

void attachRangesOrLowHighPC(DIE &D, SmallVector< RangeSpan, 2 > Ranges)

void finishSubprogramDefinition(const DISubprogram *SP)

Collects and handles dwarf debug information.

MDNodeSet & getLocalDeclsForScope(const DILocalScope *S)

std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const

If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.

bool useGNUTLSOpcode() const

Returns whether to use DW_OP_GNU_push_tls_address, instead of the standard DW_OP_form_tls_address opc...

bool useAddrOffsetForm() const

const DwarfCompileUnit * getPrevCU() const

Returns the previous CU that was being updated.

uint16_t getDwarfVersion() const

Returns the Dwarf Version.

void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)

bool alwaysUseRanges(const DwarfCompileUnit &) const

Returns whether range encodings should be used for single entry range lists.

void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)

bool useAllLinkageNames() const

Returns whether we should emit all DW_AT_[MIPS_]linkage_name.

void insertSectionLabel(const MCSymbol *S)

dwarf::Form getDwarfSectionOffsetForm() const

Returns a suitable DWARF form to represent a section offset, i.e.

bool useAppleExtensionAttributes() const

void setPrevCU(const DwarfCompileUnit *PrevCU)

const MachineFunction * getCurrentFunction() const

void addArangeLabel(SymbolCU SCU)

Add a label so that arange data can be generated for it.

AddressPool & getAddressPool()

bool useSectionsAsReferences() const

Returns whether to use sections as labels rather than temp symbols.

void terminateLineTable(const DwarfCompileUnit *CU)

Terminate the line table by adding the last range label.

DwarfCompileUnit * lookupCU(const DIE *Die)

Find the matching DwarfCompileUnit for the given CU DIE.

const MCSymbol * getSectionLabel(const MCSection *S)

static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)

bool useSplitDwarf() const

Returns whether or not to change the current debug info for the split dwarf proposal support.

bool useAddrOffsetExpressions() const

bool useRangesSection() const

Returns whether ranges section should be emitted.

void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)

bool isLexicalScopeDIENull(LexicalScope *Scope)

A helper function to check whether the DIE for a given Scope is going to be null.

AccelTableKind getAccelTableKind() const

Returns what kind (if any) of accelerator tables to emit.

void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)

Set the location (Loc) and DIExpression (DIExpr) to describe.

void addFragmentOffset(const DIExpression *Expr)

If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...

void setMemoryLocationKind()

Lock this down to become a memory location description.

std::optional< uint8_t > TagOffset

void setCallSiteParamValueFlag()

Lock this down to become a call site parameter location.

bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)

Emit a machine register location.

void addExpression(DIExpressionCursor &&Expr)

Emit all remaining operations in the DIExpressionCursor.

void addWasmLocation(unsigned Index, uint64_t Offset)

Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...

void beginEntryValueExpression(DIExpressionCursor &ExprCursor)

Begin emission of an entry value dwarf operation.

void addScopeLabel(LexicalScope *LS, DbgLabel *Label)

DenseMap< LexicalScope *, ScopeVars > & getScopeVariables()

DenseMap< LexicalScope *, LabelList > & getScopeLabels()

void addScopeVariable(LexicalScope *LS, DbgVariable *Var)

This dwarf writer support class manages information associated with a source file.

virtual DIE * getOrCreateTypeDIE(const MDNode *TyNode)

Find existing DIE or create new DIE for the given type.

DwarfDebug & getDwarfDebug() const

void addAnnotation(DIE &Buffer, DINodeArray Annotations)

Add DW_TAG_LLVM_annotation.

void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc)

Add block data.

void addTemplateParams(DIE &Buffer, DINodeArray TParams)

Add template parameters in buffer.

virtual DIE * getOrCreateContextDIE(const DIScope *Context)

Get context owner's DIE.

void addAttribute(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, T &&Value)

void addOpAddress(DIELoc &Die, const MCSymbol *Sym)

Add a dwarf op address data and value using the form given and an op of either DW_FORM_addr or DW_FOR...

void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)

Add an unsigned integer attribute data and value.

void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)

Add a string attribute data and value.

void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty)

Add constant value entry in variable DIE.

DIE * getOrCreateNameSpace(const DINamespace *NS)

void insertDIE(const DINode *Desc, DIE *D)

Insert DIE into the map.

void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)

addSectionDelta - Add a label delta attribute data and value.

const DICompileUnit * CUNode

MDNode for the compile unit.

DIE * getDIE(const DINode *D) const

Returns the DIE map slot for the specified debug variable.

MCSymbol * LabelBegin

The start of the unit within its section.

void addSInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, int64_t Integer)

Add an signed integer attribute data and value.

void addLabelDelta(DIEValueList &Die, dwarf::Attribute Attribute, const MCSymbol *Hi, const MCSymbol *Lo)

Add a label delta attribute data and value.

void addLinkageName(DIE &Die, StringRef LinkageName)

Add a linkage name, if it isn't empty.

std::string getParentContextString(const DIScope *Context) const

Get string containing language specific context for a global name.

void addSourceLine(DIE &Die, unsigned Line, const DIFile *File)

Add location information to specified debug information entry.

void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT)

Emit the common part of the header for this unit.

BumpPtrAllocator DIEValueAllocator

DIE * getOrCreateModule(const DIModule *M)

const DICompileUnit * getCUNode() const

DIE & createAndAddDIE(dwarf::Tag Tag, DIE &Parent, const DINode *N=nullptr)

Create a DIE with the given Tag, add the DIE to its parent, and call insertDIE if MD is not null.

DIE * getOrCreateStaticMemberDIE(const DIDerivedType *DT)

Create new static data member DIE.

void addLabel(DIEValueList &Die, dwarf::Attribute Attribute, dwarf::Form Form, const MCSymbol *Label)

Add a Dwarf label attribute data and value.

void addConstantFPValue(DIE &Die, const ConstantFP *CFP)

Add constant value entry in variable DIE.

DIE * getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal=false)

void addSectionLabel(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Label, const MCSymbol *Sec)

Add a Dwarf section label attribute data and value.

void addPoolOpAddress(DIEValueList &Die, const MCSymbol *Label)

void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy)

MCSymbol * EndLabel

Emitted at the end of the CU and used to compute the CU Length field.

void addFlag(DIE &Die, dwarf::Attribute Attribute)

Add a flag that is true to the DIE.

AsmPrinter * Asm

Target of Dwarf emission.

unsigned getUniqueID() const

Gets Unique ID for this unit.

void addType(DIE &Entity, const DIType *Ty, dwarf::Attribute Attribute=dwarf::DW_AT_type)

Add a new type attribute to the specified entity.

void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, bool SkipSPAttributes=false)

void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry)

Add a DIE attribute data and value.

LexicalScope - This class is used to track scope information.

Multi-value location description.

unsigned getDebugLocListIndex() const

std::optional< uint8_t > getDebugLocListTagOffset() const

Single value location description.

unsigned getCodePointerSize() const

Get the code pointer size in bytes.

Base class for the full range of assembler expressions which are needed for parsing.

MCSection * getDwarfRangesSection() const

MCSection * getDwarfAddrSection() const

MCSection * getDwarfLineSection() const

virtual int64_t getDwarfRegNum(MCRegister RegNum, bool isEH) const

Map a target register to an equivalent dwarf register number.

MCSymbol * getBeginSymbol()

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

bool isDefined() const

isDefined - Check if this symbol is defined (i.e., it has an address).

bool sameSection(const MachineBasicBlock *MBB) const

Returns true if this and MBB belong to the same section.

MBBSectionID getSectionID() const

Returns the section ID of this basic block.

bool isEndSection() const

Returns true if this block ends any section.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

A Module instance is used to store all the information related to an LLVM module.

StringRef getName() const

Get a short "name" for the module.

Wrapper class representing virtual and physical registers.

static constexpr bool isPhysicalRegister(unsigned Reg)

Return true if the specified register number is in the physical register namespace.

bool empty() const

Determine if the SetVector is empty or not.

bool insert(const value_type &X)

Insert a new element into the SetVector.

Implements a dense probed hash-table based set with some number of buckets stored inline.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StackOffset holds a fixed and a scalable offset in bytes.

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

constexpr bool empty() const

empty - Check if the string is empty.

Information about stack frame layout on the target.

virtual DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const

Return the frame base information to be encoded in the DWARF subprogram debug info.

virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const

getFrameIndexReference - This method should return the base register and offset used to reference a f...

virtual MCRegister getStaticBase() const

Returns the register used as static base in RWPI variants.

static SectionKind getKindForGlobal(const GlobalObject *GO, const TargetMachine &TM)

Classify the specified global variable into a set of target independent categories embodied in Sectio...

bool supportDebugThreadLocalLocation() const

Target supports TLS offset relocation in debug section?

virtual const MCExpr * getIndirectSymViaRWPI(const MCSymbol *Sym) const

Get the target specific RWPI relocation.

virtual const MCExpr * getDebugThreadLocalSymbol(const MCSymbol *Sym) const

Create a symbol reference to describe the given TLS variable when emitting the address in debug info.

const Triple & getTargetTriple() const

bool useEmulatedTLS() const

Returns true if this target uses emulated TLS.

Reloc::Model getRelocationModel() const

Returns the code generation relocation model.

const MCRegisterInfo * getMCRegisterInfo() const

bool DisableFramePointerElim(const MachineFunction &MF) const

DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetRegisterInfo * getRegisterInfo() const

getRegisterInfo - If register information is available, return it.

virtual const TargetFrameLowering * getFrameLowering() const

bool isNVPTX() const

Tests whether the target is NVPTX (32- or 64-bit).

bool isWasm() const

Tests whether the target is wasm (32- and 64-bit).

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

StringRef toStringRef(SmallVectorImpl< char > &Out) const

This returns the twine as a single StringRef if it can be represented as such.

std::pair< iterator, bool > insert(const ValueT &V)

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

A DeclContext is a named program scope that is used for ODR uniquing of types.

NodeTy * getNextNode()

Get the next node, or nullptr for the list tail.

StringRef AttributeEncodingString(unsigned Encoding)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

initializer< Ty > init(const Ty &Val)

UnitType

Constants for unit types in DWARF v5.

@ WASM_SYMBOL_TYPE_GLOBAL

This is an optimization pass for GlobalISel generic memory operations.

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

auto reverse(ContainerTy &&C)

@ Apple

.apple_names, .apple_namespaces, .apple_types, .apple_objc.

@ Global

Append to llvm.global_dtors.

constexpr T divideCeil(U Numerator, V Denominator)

Returns the integer ceil(Numerator / Denominator).

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

DWARFExpression::Operation Op

std::pair< const MachineInstr *, const MachineInstr * > InsnRange

InsnRange - This is used to track range of instructions with identical lexical scope.

DISubprogram * getDISubprogram(const MDNode *Scope)

Find subprogram that is enclosing this scope.

Single location defined by (potentially multiple) EntryValueInfo.

std::set< EntryValueInfo > EntryValues

Single location defined by (potentially multiple) MMI entries.

const std::set< FrameIndexExpr > & getFrameIndexExprs() const

Get the FI entries, sorted by fragment offset.

Helper used to pair up a symbol and its DWARF compile unit.

union llvm::TargetFrameLowering::DwarfFrameBase::@248 Location

enum llvm::TargetFrameLowering::DwarfFrameBase::FrameBaseKind Kind

struct WasmFrameBase WasmLoc

This struct describes target specific location.