LLVM: lib/MC/MCDwarf.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17#include "llvm/Config/config.h"

35#include

36#include

37#include

38#include

39#include

40#include

41

42using namespace llvm;

43

51 }

60 S.AddComment("Segment selector size");

62 return End;

63}

64

67 if (MinInsnLength == 1)

68 return AddrDelta;

69 if (AddrDelta % MinInsnLength != 0) {

70

71 ;

72 }

73 return AddrDelta / MinInsnLength;

74}

75

78 if (UseRelocs) {

81 assert(DwarfLineStrSection && "DwarfLineStrSection must not be NULL");

83 }

84}

85

86

87

88

89

90

93 return;

94

95

97

99

100

102

103

105

106

108

109

114}

115

116

117

118

122 int IntVal) {

129 return Res3;

130}

131

132

133

134

135static inline const MCExpr *

141 return Res;

142}

143

146

147

148

149

150

151

152

153 auto I = MCLineDivisions.find(Sec);

154 if (I != MCLineDivisions.end()) {

155 auto &Entries = I->second;

156 auto EndEntry = Entries.back();

157 EndEntry.setEndLabel(EndLabel);

158 Entries.push_back(EndEntry);

159 }

160}

161

162

163

164

165

169

170 unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;

171 bool IsAtStartSeq;

173 auto init = [&]() {

174 FileNum = 1;

175 LastLine = 1;

176 Column = 0;

178 Isa = 0;

179 Discriminator = 0;

180 LastLabel = nullptr;

181 IsAtStartSeq = true;

182 };

183 init();

184

185

186 bool EndEntryEmitted = false;

188 MCSymbol *Label = LineEntry.getLabel();

190

191 if (LineEntry.LineStreamLabel) {

192 if (!IsAtStartSeq) {

194 LastLabel);

195 init();

196 }

197 MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);

198 continue;

199 }

200

201 if (LineEntry.IsEndEntry) {

204 init();

205 EndEntryEmitted = true;

206 continue;

207 }

208

209 int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;

210

211 if (FileNum != LineEntry.getFileNum()) {

212 FileNum = LineEntry.getFileNum();

213 MCOS->emitInt8(dwarf::DW_LNS_set_file);

215 }

216 if (Column != LineEntry.getColumn()) {

217 Column = LineEntry.getColumn();

218 MCOS->emitInt8(dwarf::DW_LNS_set_column);

220 }

221 if (Discriminator != LineEntry.getDiscriminator() &&

223 Discriminator = LineEntry.getDiscriminator();

225 MCOS->emitInt8(dwarf::DW_LNS_extended_op);

227 MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);

229 }

230 if (Isa != LineEntry.getIsa()) {

231 Isa = LineEntry.getIsa();

232 MCOS->emitInt8(dwarf::DW_LNS_set_isa);

234 }

236 Flags = LineEntry.getFlags();

237 MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);

238 }

240 MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);

242 MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);

244 MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);

245

246

247

248

251

252 Discriminator = 0;

253 LastLine = LineEntry.getLine();

254 LastLabel = Label;

255 IsAtStartSeq = false;

256 }

257

258

259

260

261

262

263 if (!EndEntryEmitted && !IsAtStartSeq)

265}

266

272 auto *LineSym = ctx.createTempSymbol();

274 const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();

275

276

277

278

279 MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);

281}

282

283

284

285

288

290

291

292

293 if (LineTables.empty())

294 return;

295

296

297 std::optional LineStr;

299 LineStr.emplace(context);

300

301

303

304

305 for (const auto &CUIDTablePair : LineTables) {

306 CUIDTablePair.second.emitCU(MCOS, Params, LineStr);

307 }

308

309 if (LineStr)

310 LineStr->emitSection(MCOS);

311}

312

315 if (!HasSplitLineTable)

316 return;

317 std::optional NoLineStr(std::nullopt);

319 MCOS.emitLabel(Header.Emit(&MCOS, Params, {}, NoLineStr).second);

320}

321

322std::pair<MCSymbol *, MCSymbol *>

324 std::optional &LineStr) const {

325 static const char StandardOpcodeLengths[] = {

326 0,

327 1,

328 1,

329 1,

330 1,

331 0,

332 0,

333 0,

334 1,

335 0,

336 0,

337 1

338 };

339 assert(std::size(StandardOpcodeLengths) >=

341 return Emit(MCOS, Params,

343 LineStr);

344}

345

348 assert(!isa(Expr));

350 return Expr;

351

352

354 OS.emitAssignment(ABS, Expr);

356}

357

360 OS.emitValue(ABS, Size);

361}

362

364

369}

370

372

379}

380

382 return LineStrings.add(Path);

383}

384

386 int RefSize =

389 if (UseRelocs) {

393 } else {

395 RefSize);

396 }

397 } else

399}

400

401void MCDwarfLineTableHeader::emitV2FileDirTables(MCStreamer *MCOS) const {

402

404 MCOS->emitBytes(Dir);

406 }

407 MCOS->emitInt8(0);

408

409

410 for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {

415 MCOS->emitInt8(0);

416 MCOS->emitInt8(0);

417 }

418 MCOS->emitInt8(0);

419}

420

422 bool EmitMD5, bool HasAnySource,

423 std::optional &LineStr) {

425 if (LineStr)

426 LineStr->emitRef(MCOS, DwarfFile.Name);

427 else {

430 }

432 if (EmitMD5) {

435 StringRef(reinterpret_cast<const char *>(Cksum.data()), Cksum.size()));

436 }

437 if (HasAnySource) {

438 if (LineStr)

440 else {

443 }

444 }

445}

446

447void MCDwarfLineTableHeader::emitV5FileDirTables(

448 MCStreamer *MCOS, std::optional &LineStr) const {

449

450

451

455 : dwarf::DW_FORM_string);

457

463 CompDir = Dir.str();

464 if (LineStr)

465 CompDir = LineStr->getSaver().save(CompDir);

466 }

467 if (LineStr) {

468

469 LineStr->emitRef(MCOS, CompDir);

471 LineStr->emitRef(MCOS, Dir);

472 } else {

473

477 MCOS->emitBytes(Dir);

479 }

480 }

481

482

483

484

486 if (HasAllMD5)

487 Entries += 1;

489 Entries += 1;

493 : dwarf::DW_FORM_string);

496 if (HasAllMD5) {

499 }

503 : dwarf::DW_FORM_string);

504 }

505

506

507

508

510

511

513 "No root file and no .file directives");

516 for (unsigned i = 1; i < MCDwarfFiles.size(); ++i)

518}

519

520std::pair<MCSymbol *, MCSymbol *>

523 std::optional &LineStr) const {

525

526

528 if (!LineStartSym)

530

531

533

535

537

538

540 MCOS->emitInt16(LineTableVersion);

541

542

543 if (LineTableVersion >= 5) {

545 MCOS->emitInt8(0);

546 }

547

548

551

552

553

555

557

558

560

561

562

563 if (LineTableVersion >= 4)

568 MCOS->emitInt8(StandardOpcodeLengths.size() + 1);

569

570

571 for (char Length : StandardOpcodeLengths)

573

574

575

576 if (LineTableVersion >= 5)

577 emitV5FileDirTables(MCOS, LineStr);

578 else

579 emitV2FileDirTables(MCOS);

580

581

582

584

585 return std::make_pair(LineStartSym, LineEndSym);

586}

587

589 std::optional &LineStr) const {

590 MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;

591

592

593 for (const auto &LineSec : MCLineSections.getMCLineEntries())

594 emitOne(MCOS, LineSec.first, LineSec.second);

595

596

597

599}

600

603 std::optionalMD5::MD5Result Checksum,

604 std::optional Source,

605 uint16_t DwarfVersion, unsigned FileNumber) {

606 return Header.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,

607 FileNumber);

608}

609

612 std::optionalMD5::MD5Result Checksum) {

613 if (RootFile.Name.empty() || StringRef(RootFile.Name) != FileName)

614 return false;

615 return RootFile.Checksum == Checksum;

616}

617

620 std::optionalMD5::MD5Result Checksum,

621 std::optional Source,

622 uint16_t DwarfVersion, unsigned FileNumber) {

624 Directory = "";

625 if (FileName.empty()) {

626 FileName = "";

627 Directory = "";

628 }

630

631

635 }

636 if (DwarfVersion >= 5 && isRootFile(RootFile, Directory, FileName, Checksum))

637 return 0;

638 if (FileNumber == 0) {

639

640

644 std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer),

645 FileNumber));

646 if (!IterBool.second)

647 return IterBool.first->second;

648 }

649

652

653

655

656

657 if (!File.Name.empty())

658 return make_error("file number already allocated",

660

661 if (Directory.empty()) {

662

664 if (!tFileName.empty()) {

666 if (!Directory.empty())

667 FileName = tFileName;

668 }

669 }

670

671

672

673 unsigned DirIndex;

674 if (Directory.empty()) {

675

676 DirIndex = 0;

677 } else {

681

682

683

684

685 DirIndex++;

686 }

687

688 File.Name = std::string(FileName);

689 File.DirIndex = DirIndex;

690 File.Checksum = Checksum;

692 File.Source = Source;

693 if (Source.has_value())

695

696

697 return FileNumber;

698}

699

700

702 int64_t LineDelta, uint64_t AddrDelta) {

707}

708

709

710

713}

714

715

717 int64_t LineDelta, uint64_t AddrDelta,

721 bool NeedCopy = false;

722

723

725

726

728

729

730

731

733 if (AddrDelta == MaxSpecialAddrDelta)

734 Out.push_back(dwarf::DW_LNS_const_add_pc);

735 else if (AddrDelta) {

736 Out.push_back(dwarf::DW_LNS_advance_pc);

738 }

739 Out.push_back(dwarf::DW_LNS_extended_op);

741 Out.push_back(dwarf::DW_LNE_end_sequence);

742 return;

743 }

744

745

747

748

749

752 Out.push_back(dwarf::DW_LNS_advance_line);

754

755 LineDelta = 0;

757 NeedCopy = true;

758 }

759

760

761 if (LineDelta == 0 && AddrDelta == 0) {

762 Out.push_back(dwarf::DW_LNS_copy);

763 return;

764 }

765

766

768

769

770 if (AddrDelta < 256 + MaxSpecialAddrDelta) {

771

773 if (Opcode <= 255) {

775 return;

776 }

777

778

779 Opcode = Temp + (AddrDelta - MaxSpecialAddrDelta) * Params.DWARF2LineRange;

780 if (Opcode <= 255) {

781 Out.push_back(dwarf::DW_LNS_const_add_pc);

783 return;

784 }

785 }

786

787

788 Out.push_back(dwarf::DW_LNS_advance_pc);

790

791 if (NeedCopy)

792 Out.push_back(dwarf::DW_LNS_copy);

793 else {

794 assert(Temp <= 255 && "Buggy special opcode encoding.");

796 }

797}

798

799

803}

804

805

806

810

811

817 ? dwarf::DW_FORM_sec_offset

819 : dwarf::DW_FORM_data4);

820 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm);

823 EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm);

824 } else {

825 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);

826 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);

827 }

828 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);

830 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);

832 if (!DwarfDebugFlags.empty())

833 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);

834 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);

835 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);

837

838

842 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);

843 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);

844 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);

845 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);

847

848

850}

851

852

853

854

855

857 const MCSymbol *InfoSectionSymbol) {

859

861

863

864 unsigned UnitLengthBytes =

867

868

869

870 int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1;

871

872

873

876 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));

877 if (Pad == 2 * AddrSize)

878 Pad = 0;

880

881

882

883 Length += 2 * AddrSize * Sections.size();

884

885 Length += 2 * AddrSize;

886

887

889

891

892

894

896

897

898 if (InfoSectionSymbol)

901 else

903

905

907

908 for(int i = 0; i < Pad; i++)

910

911

912

913 for (MCSection *Sec : Sections) {

914 const MCSymbol *StartSymbol = Sec->getBeginSymbol();

915 MCSymbol *EndSymbol = Sec->getEndSymbol(context);

916 assert(StartSymbol && "StartSymbol must not be NULL");

917 assert(EndSymbol && "EndSymbol must not be NULL");

918

925 }

926

927

930}

931

932

933

934

936 const MCSymbol *AbbrevSectionSymbol,

937 const MCSymbol *LineSectionSymbol,

938 const MCSymbol *RangesSymbol) {

940

942

943

944

948

949

950

951 unsigned UnitLengthBytes =

954

956

958

959

960

964

965

967

968

969

973 MCOS->emitInt8(dwarf::DW_UT_compile);

975 }

976

977

978 if (AbbrevSectionSymbol)

981 else

982

986

987

988

989

991

992

993

994 if (LineSectionSymbol)

997 else

998

1000

1001 if (RangesSymbol) {

1002

1003

1004

1006 } else {

1007

1008

1009

1010

1012 const auto TextSection = Sections.begin();

1013 assert(TextSection != Sections.end() && "No text section found");

1014

1015 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();

1016 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);

1017 assert(StartSymbol && "StartSymbol must not be NULL");

1018 assert(EndSymbol && "EndSymbol must not be NULL");

1019

1020

1023 MCOS->emitValue(Start, AddrSize);

1024

1025

1029 }

1030

1031

1032

1034 if (MCDwarfDirs.size() > 0) {

1035 MCOS->emitBytes(MCDwarfDirs[0]);

1037 }

1039

1040

1041 assert(MCDwarfFiles.empty() || MCDwarfFiles.size() >= 2);

1043 MCDwarfFiles.empty()

1045 : MCDwarfFiles[1];

1047 MCOS->emitInt8(0);

1048

1049

1052 MCOS->emitInt8(0);

1053 }

1054

1055

1057 if (!DwarfDebugFlags.empty()){

1058 MCOS->emitBytes(DwarfDebugFlags);

1059 MCOS->emitInt8(0);

1060 }

1061

1062

1064 if (!DwarfDebugProducer.empty())

1065 MCOS->emitBytes(DwarfDebugProducer);

1066 else

1067 MCOS->emitBytes(StringRef("llvm-mc (based on LLVM " PACKAGE_VERSION ")"));

1068 MCOS->emitInt8(0);

1069

1070

1071

1072 MCOS->emitInt16(dwarf::DW_LANG_Mips_Assembler);

1073

1074

1075

1076

1077 const std::vector &Entries =

1079 for (const auto &Entry : Entries) {

1080

1082

1083

1084 MCOS->emitBytes(Entry.getName());

1085 MCOS->emitInt8(0);

1086

1087

1088 MCOS->emitInt32(Entry.getFileNumber());

1089

1090

1091 MCOS->emitInt32(Entry.getLineNumber());

1092

1093

1096 MCOS->emitValue(AT_low_pc, AddrSize);

1097 }

1098

1099

1101

1102

1104}

1105

1106

1107

1108

1112

1116

1120 MCOS->AddComment("Offset entry count");

1122 RangesSymbol = context.createTempSymbol("debug_rnglist0_start");

1124 for (MCSection *Sec : Sections) {

1125 const MCSymbol *StartSymbol = Sec->getBeginSymbol();

1126 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);

1129 const MCExpr *SectionSize =

1131 MCOS->emitInt8(dwarf::DW_RLE_start_length);

1132 MCOS->emitValue(SectionStartAddr, AddrSize);

1134 }

1135 MCOS->emitInt8(dwarf::DW_RLE_end_of_list);

1137 } else {

1139 RangesSymbol = context.createTempSymbol("debug_ranges_start");

1141 for (MCSection *Sec : Sections) {

1142 const MCSymbol *StartSymbol = Sec->getBeginSymbol();

1143 const MCSymbol *EndSymbol = Sec->getEndSymbol(context);

1144

1145

1148 MCOS->emitFill(AddrSize, 0xFF);

1149 MCOS->emitValue(SectionStartAddr, AddrSize);

1150

1151

1152 const MCExpr *SectionSize =

1156 }

1157

1158

1161 }

1162

1163 return RangesSymbol;

1164}

1165

1166

1167

1168

1169

1172

1173

1175 bool CreateDwarfSectionSymbols =

1177 MCSymbol *LineSectionSymbol = nullptr;

1178 if (CreateDwarfSectionSymbols)

1180 MCSymbol *AbbrevSectionSymbol = nullptr;

1181 MCSymbol *InfoSectionSymbol = nullptr;

1182 MCSymbol *RangesSymbol = nullptr;

1183

1184

1186

1187

1188

1190 return;

1191

1192

1193

1194 const bool UseRangesSection =

1197 CreateDwarfSectionSymbols |= UseRangesSection;

1198

1200 if (CreateDwarfSectionSymbols) {

1202 MCOS->emitLabel(InfoSectionSymbol);

1203 }

1205 if (CreateDwarfSectionSymbols) {

1207 MCOS->emitLabel(AbbrevSectionSymbol);

1208 }

1209

1211

1212

1214

1215 if (UseRangesSection) {

1217 assert(RangesSymbol);

1218 }

1219

1220

1222

1223

1224 EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);

1225}

1226

1227

1228

1229

1230

1231

1232

1235

1236 if (Symbol->isTemporary())

1237 return;

1239

1240

1242 return;

1243

1244

1245

1246 StringRef Name = Symbol->getName();

1247 if (Name.starts_with("_"))

1248 Name = Name.substr(1, Name.size()-1);

1249

1250

1252

1253

1254

1257

1258

1259

1260

1261

1264

1265

1268}

1269

1275 return size;

1276 else

1277 return -size;

1278}

1279

1281 unsigned symbolEncoding) {

1283 unsigned format = symbolEncoding & 0x0f;

1291 return 2;

1294 return 4;

1297 return 8;

1298 }

1299}

1300

1302 unsigned symbolEncoding, bool isEH) {

1306 symbolEncoding,

1307 streamer);

1311 else

1313}

1314

1316 unsigned symbolEncoding) {

1320 symbolEncoding,

1321 streamer);

1324}

1325

1326namespace {

1327

1328class FrameEmitterImpl {

1329 int64_t CFAOffset = 0;

1330 int64_t InitialCFAOffset = 0;

1331 bool IsEH;

1333

1334public:

1336 : IsEH(IsEH), Streamer(Streamer) {}

1337

1338

1340

1343 bool LastInSection, const MCSymbol &SectionStart);

1347};

1348

1349}

1350

1352 Streamer.emitInt8(Encoding);

1353}

1354

1355void FrameEmitterImpl::emitCFIInstruction(const MCCFIInstruction &Instr) {

1357 auto *MRI = Streamer.getContext().getRegisterInfo();

1358

1359 switch (Instr.getOperation()) {

1361 unsigned Reg1 = Instr.getRegister();

1362 unsigned Reg2 = Instr.getRegister2();

1363 if (!IsEH) {

1364 Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1);

1365 Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2);

1366 }

1367 Streamer.emitInt8(dwarf::DW_CFA_register);

1368 Streamer.emitULEB128IntValue(Reg1);

1369 Streamer.emitULEB128IntValue(Reg2);

1370 return;

1371 }

1373 Streamer.emitInt8(dwarf::DW_CFA_GNU_window_save);

1374 return;

1375

1377 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state);

1378 return;

1379

1381 Streamer.emitInt8(dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc);

1382 return;

1383

1385 unsigned Reg = Instr.getRegister();

1386 Streamer.emitInt8(dwarf::DW_CFA_undefined);

1387 Streamer.emitULEB128IntValue(Reg);

1388 return;

1389 }

1392 const bool IsRelative =

1394

1395 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_offset);

1396

1397 if (IsRelative)

1398 CFAOffset += Instr.getOffset();

1399 else

1400 CFAOffset = Instr.getOffset();

1401

1402 Streamer.emitULEB128IntValue(CFAOffset);

1403

1404 return;

1405 }

1407 unsigned Reg = Instr.getRegister();

1408 if (!IsEH)

1409 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);

1410 Streamer.emitInt8(dwarf::DW_CFA_def_cfa);

1411 Streamer.emitULEB128IntValue(Reg);

1412 CFAOffset = Instr.getOffset();

1413 Streamer.emitULEB128IntValue(CFAOffset);

1414

1415 return;

1416 }

1418 unsigned Reg = Instr.getRegister();

1419 if (!IsEH)

1420 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);

1421 Streamer.emitInt8(dwarf::DW_CFA_def_cfa_register);

1422 Streamer.emitULEB128IntValue(Reg);

1423

1424 return;

1425 }

1426

1428 unsigned Reg = Instr.getRegister();

1429 if (!IsEH)

1430 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);

1431 Streamer.emitIntValue(dwarf::DW_CFA_LLVM_def_aspace_cfa, 1);

1432 Streamer.emitULEB128IntValue(Reg);

1433 CFAOffset = Instr.getOffset();

1434 Streamer.emitULEB128IntValue(CFAOffset);

1435 Streamer.emitULEB128IntValue(Instr.getAddressSpace());

1436

1437 return;

1438 }

1441 const bool IsRelative =

1443

1444 unsigned Reg = Instr.getRegister();

1445 if (!IsEH)

1446 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);

1447

1449 if (IsRelative)

1450 Offset -= CFAOffset;

1452

1454 Streamer.emitInt8(dwarf::DW_CFA_offset_extended_sf);

1455 Streamer.emitULEB128IntValue(Reg);

1456 Streamer.emitSLEB128IntValue(Offset);

1457 } else if (Reg < 64) {

1458 Streamer.emitInt8(dwarf::DW_CFA_offset + Reg);

1459 Streamer.emitULEB128IntValue(Offset);

1460 } else {

1461 Streamer.emitInt8(dwarf::DW_CFA_offset_extended);

1462 Streamer.emitULEB128IntValue(Reg);

1463 Streamer.emitULEB128IntValue(Offset);

1464 }

1465 return;

1466 }

1468 Streamer.emitInt8(dwarf::DW_CFA_remember_state);

1469 return;

1471 Streamer.emitInt8(dwarf::DW_CFA_restore_state);

1472 return;

1474 unsigned Reg = Instr.getRegister();

1475 Streamer.emitInt8(dwarf::DW_CFA_same_value);

1476 Streamer.emitULEB128IntValue(Reg);

1477 return;

1478 }

1480 unsigned Reg = Instr.getRegister();

1481 if (!IsEH)

1482 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);

1483 if (Reg < 64) {

1484 Streamer.emitInt8(dwarf::DW_CFA_restore | Reg);

1485 } else {

1486 Streamer.emitInt8(dwarf::DW_CFA_restore_extended);

1487 Streamer.emitULEB128IntValue(Reg);

1488 }

1489 return;

1490 }

1492 Streamer.emitInt8(dwarf::DW_CFA_GNU_args_size);

1493 Streamer.emitULEB128IntValue(Instr.getOffset());

1494 return;

1495

1497 Streamer.emitBytes(Instr.getValues());

1498 return;

1500 Streamer.emitLabel(Instr.getCfiLabel(), Instr.getLoc());

1501 return;

1503 unsigned Reg = Instr.getRegister();

1504 if (!IsEH)

1505 Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);

1506

1509

1511 Streamer.emitInt8(dwarf::DW_CFA_val_offset_sf);

1512 Streamer.emitULEB128IntValue(Reg);

1513 Streamer.emitSLEB128IntValue(Offset);

1514 } else {

1515 Streamer.emitInt8(dwarf::DW_CFA_val_offset);

1516 Streamer.emitULEB128IntValue(Reg);

1517 Streamer.emitULEB128IntValue(Offset);

1518 }

1519 return;

1520 }

1521 }

1523}

1524

1525

1530

1531 if (Label && Label->isDefined()) continue;

1532

1533

1534 if (BaseLabel && Label) {

1536 if (ThisSym != BaseLabel) {

1537 Streamer.emitDwarfAdvanceFrameAddr(BaseLabel, ThisSym, Instr.getLoc());

1538 BaseLabel = ThisSym;

1539 }

1540 }

1541

1542 emitCFIInstruction(Instr);

1543 }

1544}

1545

1546

1547void FrameEmitterImpl::EmitCompactUnwind(const MCDwarfFrameInfo &Frame) {

1548 MCContext &Context = Streamer.getContext();

1550

1551

1552

1553

1554

1555

1556

1557

1558

1559

1560

1561

1562

1563

1564

1565

1566

1567

1568

1569

1570

1571

1572

1574 if (!Encoding) return;

1576

1577

1578 if (!DwarfEHFrameOnly && Frame.Lsda)

1579 Encoding |= 0x40000000;

1580

1581

1584 Streamer.emitSymbolValue(Frame.Begin, Size);

1585

1586

1590

1591

1593 Streamer.emitIntValue(Encoding, Size);

1594

1595

1597 if (!DwarfEHFrameOnly && Frame.Personality)

1599 else

1600 Streamer.emitIntValue(0, Size);

1601

1602

1604 if (!DwarfEHFrameOnly && Frame.Lsda)

1605 Streamer.emitSymbolValue(Frame.Lsda, Size);

1606 else

1607 Streamer.emitIntValue(0, Size);

1608}

1609

1610static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {

1611 if (IsEH)

1612 return 1;

1613 switch (DwarfVersion) {

1614 case 2:

1615 return 1;

1616 case 3:

1617 return 3;

1618 case 4:

1619 case 5:

1620 return 4;

1621 }

1623}

1624

1626 MCContext &context = Streamer.getContext();

1629

1631 Streamer.emitLabel(sectionStart);

1632

1634

1639

1640 if (IsDwarf64)

1641

1643

1644

1646 *sectionEnd, UnitLengthBytes);

1648

1649

1652 Streamer.emitIntValue(CIE_ID, OffsetSize);

1653

1654

1656 Streamer.emitInt8(CIEVersion);

1657

1658 if (IsEH) {

1660 Augmentation += "z";

1662 Augmentation += "P";

1663 if (Frame.Lsda)

1664 Augmentation += "L";

1665 Augmentation += "R";

1667 Augmentation += "S";

1669 Augmentation += "B";

1671 Augmentation += "G";

1672 Streamer.emitBytes(Augmentation);

1673 }

1674 Streamer.emitInt8(0);

1675

1676 if (CIEVersion >= 4) {

1677

1679

1680

1681 Streamer.emitInt8(0);

1682 }

1683

1684

1686

1687

1689

1690

1692 if (RAReg == static_cast<unsigned>(INT_MAX))

1693 RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);

1694

1695 if (CIEVersion == 1) {

1697 "DWARF 2 encodes return_address_register in one byte");

1698 Streamer.emitInt8(RAReg);

1699 } else {

1700 Streamer.emitULEB128IntValue(RAReg);

1701 }

1702

1703

1704 unsigned augmentationLength = 0;

1705 if (IsEH) {

1707

1708 augmentationLength += 1;

1709

1710 augmentationLength +=

1712 }

1713 if (Frame.Lsda)

1714 augmentationLength += 1;

1715

1716 augmentationLength += 1;

1717

1718 Streamer.emitULEB128IntValue(augmentationLength);

1719

1720

1722

1724

1726 }

1727

1728 if (Frame.Lsda)

1730

1731

1733 }

1734

1735

1736

1739 const std::vector &Instructions =

1741 emitCFIInstructions(Instructions, nullptr);

1742 }

1743

1744 InitialCFAOffset = CFAOffset;

1745

1746

1748

1749 Streamer.emitLabel(sectionEnd);

1750 return *sectionStart;

1751}

1752

1753void FrameEmitterImpl::EmitFDE(const MCSymbol &cieStart,

1755 bool LastInSection,

1756 const MCSymbol &SectionStart) {

1757 MCContext &context = Streamer.getContext();

1761

1762 CFAOffset = InitialCFAOffset;

1763

1766

1768

1770

1771

1774

1775 Streamer.emitLabel(fdeStart);

1776

1777

1779 if (IsEH) {

1780 const MCExpr *offset =

1784 const MCExpr *offset =

1787 } else {

1788 Streamer.emitSymbolValue(&cieStart, OffsetSize,

1790 }

1791

1792

1793 unsigned PCEncoding =

1797

1798

1802

1803 if (IsEH) {

1804

1805 unsigned augmentationLength = 0;

1806

1807 if (frame.Lsda)

1809

1810 Streamer.emitULEB128IntValue(augmentationLength);

1811

1812

1813 if (frame.Lsda)

1815 }

1816

1817

1819

1820

1821

1822

1823

1824 unsigned Alignment = LastInSection ? asmInfo->getCodePointerSize() : PCSize;

1825 Streamer.emitValueToAlignment(Align(Alignment));

1826

1827 Streamer.emitLabel(fdeEnd);

1828}

1829

1830namespace {

1831

1832struct CIEKey {

1833 CIEKey() = default;

1834

1836 : Personality(Frame.Personality),

1837 PersonalityEncoding(Frame.PersonalityEncoding),

1838 LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),

1839 IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),

1840 IsBKeyFrame(Frame.IsBKeyFrame),

1841 IsMTETaggedFrame(Frame.IsMTETaggedFrame) {}

1842

1843 StringRef PersonalityName() const {

1844 if (!Personality)

1846 return Personality->getName();

1847 }

1848

1850 return std::make_tuple(PersonalityName(), PersonalityEncoding, LsdaEncoding,

1851 IsSignalFrame, IsSimple, RAReg, IsBKeyFrame,

1852 IsMTETaggedFrame) <

1853 std::make_tuple(Other.PersonalityName(), Other.PersonalityEncoding,

1854 Other.LsdaEncoding, Other.IsSignalFrame,

1856 Other.IsMTETaggedFrame);

1857 }

1858

1860 return Personality == Other.Personality &&

1861 PersonalityEncoding == Other.PersonalityEncoding &&

1862 LsdaEncoding == Other.LsdaEncoding &&

1863 IsSignalFrame == Other.IsSignalFrame && IsSimple == Other.IsSimple &&

1864 RAReg == Other.RAReg && IsBKeyFrame == Other.IsBKeyFrame &&

1865 IsMTETaggedFrame == Other.IsMTETaggedFrame;

1866 }

1868

1869 const MCSymbol *Personality = nullptr;

1870 unsigned PersonalityEncoding = 0;

1871 unsigned LsdaEncoding = -1;

1872 bool IsSignalFrame = false;

1873 bool IsSimple = false;

1874 unsigned RAReg = static_cast<unsigned>(UINT_MAX);

1875 bool IsBKeyFrame = false;

1876 bool IsMTETaggedFrame = false;

1877};

1878

1879}

1880

1882 bool IsEH) {

1886 FrameEmitterImpl Emitter(IsEH, Streamer);

1888

1889

1893 bool SectionEmitted = false;

1896 if (!SectionEmitted) {

1899 SectionEmitted = true;

1900 }

1901 NeedsEHFrameSection |=

1904 Emitter.EmitCompactUnwind(Frame);

1905 }

1906 }

1907

1908

1909

1910

1911

1912 if (!NeedsEHFrameSection && IsEH) return;

1913

1915 IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection()

1917

1920 Streamer.emitLabel(SectionStart);

1921

1923

1924

1925

1926

1927 std::vector FrameArrayX(FrameArray.begin(), FrameArray.end());

1930 return CIEKey(X) < CIEKey(Y);

1931 });

1932 CIEKey LastKey;

1933 const MCSymbol *LastCIEStart = nullptr;

1934 for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {

1936 ++I;

1939

1940

1941

1942

1943

1944

1945 continue;

1946

1947 CIEKey Key(Frame);

1948 if (!LastCIEStart || (IsEH && Key != LastKey)) {

1949 LastKey = Key;

1950 LastCIEStart = &Emitter.EmitCIE(Frame);

1951 }

1952

1953 Emitter.EmitFDE(*LastCIEStart, Frame, I == E, *SectionStart);

1954 }

1955}

1956

1960

1962 if (AddrDelta == 0)

1963 return;

1964

1968

1969 if (isUIntN(6, AddrDelta)) {

1970 uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;

1972 } else if (isUInt<8>(AddrDelta)) {

1973 Out.push_back(dwarf::DW_CFA_advance_loc1);

1975 } else if (isUInt<16>(AddrDelta)) {

1976 Out.push_back(dwarf::DW_CFA_advance_loc2);

1977 support::endian::write<uint16_t>(Out, AddrDelta, E);

1978 } else {

1979 assert(isUInt<32>(AddrDelta));

1980 Out.push_back(dwarf::DW_CFA_advance_loc4);

1981 support::endian::write<uint32_t>(Out, AddrDelta, E);

1982 }

1983}

unsigned const MachineRegisterInfo * MRI

dxil DXContainer Global Emitter

This file contains constants used for implementing Dwarf debug support.

std::optional< std::vector< StOtherPiece > > Other

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH)

static uint64_t SpecialAddr(MCDwarfLineTableParams Params, uint64_t op)

Given a special op, return the address skip amount (in units of DWARF2_LINE_MIN_INSN_LENGTH).

static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)

static bool isRootFile(const MCDwarfFile &RootFile, StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum)

static uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta)

static const MCExpr * forceExpAbs(MCStreamer &OS, const MCExpr *Expr)

static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)

static void emitOneV5FileEntry(MCStreamer *MCOS, const MCDwarfFile &DwarfFile, bool EmitMD5, bool HasAnySource, std::optional< MCDwarfLineStr > &LineStr)

static const MCExpr * makeEndMinusStartExpr(MCContext &Ctx, const MCSymbol &Start, const MCSymbol &End, int IntVal)

static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion)

static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSymbol)

static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)

static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)

static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)

static int getDataAlignmentFactor(MCStreamer &streamer)

static MCSymbol * emitGenDwarfRanges(MCStreamer *MCOS)

static const MCExpr * makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal)

static void EmitGenDwarfAbbrev(MCStreamer *MCOS)

static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)

#define DWARF2_FLAG_IS_STMT

#define DWARF2_FLAG_BASIC_BLOCK

#define DWARF2_LINE_DEFAULT_IS_STMT

#define DWARF2_FLAG_PROLOGUE_END

#define DWARF2_FLAG_EPILOGUE_BEGIN

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

static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")

static constexpr Register RAReg

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

This file defines the SmallString class.

This file defines the SmallVector class.

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

size_t size() const

size - Get the array size.

Tagged union holding either a T or a Error.

Generic interface to target specific assembler backends.

This class is intended to be used as a base class for asm properties and features specific to the tar...

bool isLittleEndian() const

True if the target is little endian.

unsigned getMinInstAlignment() const

const std::vector< MCCFIInstruction > & getInitialFrameState() const

bool needsDwarfSectionOffsetDirective() const

bool doesSetDirectiveSuppressReloc() const

bool doesDwarfUseRelocationsAcrossSections() const

virtual const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const

bool isStackGrowthDirectionUp() const

True if target stack grow up.

unsigned getCalleeSaveStackSlotSize() const

Get the callee-saved register stack slot size in bytes.

bool doDwarfFDESymbolsUseAbsDiff() const

virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const

unsigned getCodePointerSize() const

Get the code pointer size in bytes.

static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

const MCObjectFileInfo * getObjectFileInfo() const

void remapDebugPath(SmallVectorImpl< char > &Path)

Remap one path in-place as per the debug prefix map.

const SetVector< MCSection * > & getGenDwarfSectionSyms()

const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)

StringRef getDwarfDebugProducer()

StringRef getDwarfDebugFlags()

MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

StringRef getCompilationDir() const

Get the compilation directory for DW_AT_comp_dir The compilation directory should be set with setComp...

MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)

unsigned getDwarfCompileUnitID()

const MCRegisterInfo * getRegisterInfo() const

const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)

const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const

unsigned getGenDwarfFileNumber()

uint16_t getDwarfVersion() const

const MCAsmInfo * getAsmInfo() const

void finalizeDwarfSections(MCStreamer &MCOS)

Remove empty sections from SectionsForRanges, to avoid generating useless debug info for them.

void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E)

MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

const MCDwarfLoc & getCurrentDwarfLoc()

dwarf::DwarfFormat getDwarfFormat() const

const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const

void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const

static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)

static void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)

static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)

Utility function to emit the encoding to a streamer.

static void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)

Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.

Instances of this class represent the line information for the dwarf line table entries.

static void make(MCStreamer *MCOS, MCSection *Section)

void emitSection(MCStreamer *MCOS)

Emit the .debug_line_str section if appropriate.

MCDwarfLineStr(MCContext &Ctx)

Construct an instance that can emit .debug_line_str (for use in a normal v5 line table).

SmallString< 0 > getFinalizedData()

Returns finalized section.

void emitRef(MCStreamer *MCOS, StringRef Path)

Emit a reference to the string.

size_t addString(StringRef Path)

Adds path Path to the line string.

void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc, StringRef Name)

MCDwarfFile & getRootFile()

const MCLineSection & getMCLineSections() const

static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)

static void emitOne(MCStreamer *MCOS, MCSection *Section, const MCLineSection::MCDwarfLineEntryCollection &LineEntries)

Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)

void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params, std::optional< MCDwarfLineStr > &LineStr) const

Instances of this class represent the information from a dwarf .loc directive.

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

static void Emit(MCStreamer *MCOS)

static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)

const MCLineDivisionMap & getMCLineEntries() const

void addEndEntry(MCSymbol *EndLabel)

void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec)

std::vector< MCDwarfLineEntry > MCDwarfLineEntryCollection

MCSection * getDwarfRangesSection() const

bool getSupportsCompactUnwindWithoutEHFrame() const

MCSection * getDwarfLineStrSection() const

unsigned getCompactUnwindDwarfEHFrameOnly() const

MCSection * getDwarfRnglistsSection() const

MCSection * getDwarfLineSection() const

MCSection * getDwarfInfoSection() const

MCSection * getDwarfFrameSection() const

unsigned getFDEEncoding() const

MCSection * getDwarfAbbrevSection() const

bool getOmitDwarfIfHaveCompactUnwind() const

MCSection * getDwarfARangesSection() const

MCSection * getCompactUnwindSection() const

Streaming object file generation interface.

void emitValueToAlignment(Align Alignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0) override

Emit some number of copies of Value until the byte alignment ByteAlignment is reached.

void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override

Emit a label for Symbol into the current section.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Instances of this class represent a uniqued identifier for a section in the current translation unit.

MCSymbol * getBeginSymbol()

Streaming machine code generation interface.

void generateCompactUnwindEncodings(MCAsmBackend *MAB)

virtual void emitBinaryData(StringRef Data)

Functionally identical to EmitBytes.

virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)

Emit a unit length field.

MCContext & getContext() const

virtual void AddComment(const Twine &T, bool EOL=true)

Add a textual comment.

virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)

Emits a COFF section relative relocation.

void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())

void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)

Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.

virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)

Emit the debug line start label.

virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)

Emit the absolute difference between two symbols.

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

virtual void emitIntValue(uint64_t Value, unsigned Size)

Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.

virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)

If targets does not support representing debug line section by .loc/.file directives in assembly outp...

void emitInt16(uint64_t Value)

virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)

unsigned emitULEB128IntValue(uint64_t Value, unsigned PadTo=0)

Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...

virtual void emitULEB128Value(const MCExpr *Value)

ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const

virtual void switchSection(MCSection *Section, uint32_t Subsec=0)

Set the current section where code is being emitted to Section.

void emitInt32(uint64_t Value)

MCSection * getCurrentSectionOnly() const

virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)

Emit the debug line end entry.

void emitInt8(uint64_t Value)

void emitFill(uint64_t NumBytes, uint8_t FillValue)

Emit NumBytes bytes worth of the value specified by FillValue.

virtual void emitBytes(StringRef Data)

Emit the bytes in Data into the output.

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)

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

MCSection & getSection() const

Get the section associated with a defined, non-absolute symbol.

iterator find(const KeyT &Key)

Represents a location in source code.

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

StringRef str() const

Explicit conversion to StringRef.

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 owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.

unsigned FindBufferContainingLoc(SMLoc Loc) const

Return the ID of the buffer containing the specified location.

unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const

Find the line number for the specified location in the specified file.

bool insert(MapEntryTy *KeyValue)

insert - Insert the specified key/value pair into the map.

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

constexpr bool empty() const

empty - Check if the string is empty.

void finalizeInOrder()

Finalize the string table without reording it.

void write(raw_ostream &OS) const

size_t add(CachedHashStringRef S)

Add a string to the builder.

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

LLVM Value Representation.

#define llvm_unreachable(msg)

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

Reg

All possible values of the reg field in the ModR/M byte.

const uint32_t DW_CIE_ID

Special ID values that distinguish a CIE from a FDE in DWARF CFI.

uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)

Get the byte size of the unit length field depending on the DWARF format.

const uint64_t DW64_CIE_ID

DwarfFormat

Constants that define the DWARF format as 32 or 64 bit.

uint8_t getDwarfOffsetByteSize(DwarfFormat Format)

The size of a reference determined by the DWARF 32/64-bit format.

@ DW_LENGTH_DWARF64

Indicator of 64-bit DWARF format.

MCSymbol * emitListsTableHeaderStart(MCStreamer &S)

NodeAddr< InstrNode * > Instr

StringRef get_separator(Style style=Style::native)

Return the preferred separator for this platform.

StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get parent path.

StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Get filename.

This is an optimization pass for GlobalISel generic memory operations.

bool operator<(int64_t V1, const APSInt &V2)

void stable_sort(R &&Range)

auto find(R &&Range, const T &Val)

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

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

bool isUIntN(unsigned N, uint64_t x)

Checks if an unsigned integer fits into the given (dynamic) bit width.

std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

bool operator!=(uint64_t V1, const APInt &V2)

bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

unsigned getULEB128Size(uint64_t Value)

Utility function to get the size of the ULEB128-encoded value.

unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a SLEB128 value to an output stream.

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.

This struct is a compact representation of a valid (non-zero power of two) alignment.

Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...

std::optional< MD5::MD5Result > Checksum

The MD5 checksum, if there is one.

const MCSymbol * Personality

unsigned PersonalityEncoding

uint64_t CompactUnwindEncoding

std::vector< MCCFIInstruction > Instructions

uint8_t DWARF2LineOpcodeBase

First special line opcode - leave room for the standard opcodes.

uint8_t DWARF2LineRange

Range of line offsets in a special line info. opcode.

int8_t DWARF2LineBase

Minimum line offset in a special line info.