LLVM: lib/IR/DebugInfoMetadata.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

24

25#include

26#include

27

28using namespace llvm;

29

30namespace llvm {

31

33 "enable-fs-discriminator", cl::Hidden,

34 cl::desc("Enable adding flow sensitive discriminators"));

35}

36

39}

40

42 std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};

43

45 : Variable(DII->getVariable()),

46 Fragment(DII->getExpression()->getFragmentInfo()),

47 InlinedAt(DII->getDebugLoc().getInlinedAt()) {}

48

50 : Variable(DVR->getVariable()),

51 Fragment(DVR->getExpression()->getFragmentInfo()),

52 InlinedAt(DVR->getDebugLoc().getInlinedAt()) {}

53

57

58DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,

60 bool ImplicitCode)

61 : MDNode(C, DILocationKind, Storage, MDs) {

63 "Expected a scope and optional inlined-at");

64

65

66 assert(Column < (1u << 16) && "Expected 16-bit column");

67

68 SubclassData32 = Line;

69 SubclassData16 = Column;

70

71 setImplicitCode(ImplicitCode);

72}

73

75

76 if (Column >= (1u << 16))

77 Column = 0;

78}

79

81 unsigned Column, Metadata *Scope,

82 Metadata *InlinedAt, bool ImplicitCode,

83 StorageType Storage, bool ShouldCreate) {

84

86

91 return N;

92 if (!ShouldCreate)

93 return nullptr;

94 } else {

95 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");

96 }

97

105}

106

108 if (Locs.empty())

109 return nullptr;

110 if (Locs.size() == 1)

111 return Locs[0];

112 auto *Merged = Locs[0];

115 if (Merged == nullptr)

116 break;

117 }

118 return Merged;

119}

120

122 if (!LocA || !LocB)

123 return nullptr;

124

125 if (LocA == LocB)

126 return LocA;

127

129

131 LocVec ALocs;

132 LocVec BLocs;

134 4>

135 ALookup;

136

137

138

139

140 for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) {

141 ALocs.push_back(L);

143 {L->getScope()->getSubprogram(), L->getInlinedAt()}, I);

144 assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?");

145 (void)Res;

146 }

147

148 LocVec::reverse_iterator ARIt = ALocs.rend();

149 LocVec::reverse_iterator BRIt = BLocs.rend();

150

151

152

153

154

155 for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) {

156 BLocs.push_back(L);

157

158 if (ARIt != ALocs.rend())

159

160 continue;

161

162 auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()});

163 if (IT == ALookup.end())

164 continue;

165

166

167 ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1);

168 BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1);

169

170

171

172

173

174 break;

175 }

176

177

178

181 if (L1 == L2)

182 return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(),

184

185

186

187 if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())

188 return nullptr;

189

190

193 for (; S1; S1 = S1->getScope()) {

194 Scopes.insert(S1);

195 if (isa(S1))

196 break;

197 }

198

199 for (; S2; S2 = S2->getScope()) {

200 if (Scopes.count(S2))

201 return S2;

202 if (isa(S2))

203 break;

204 }

205

206 return nullptr;

207 };

208

209 auto Scope = GetNearestCommonScope(L1->getScope(), L2->getScope());

210 assert(Scope && "No common scope in the same subprogram?");

211

212 bool SameLine = L1->getLine() == L2->getLine();

213 bool SameCol = L1->getColumn() == L2->getColumn();

214 unsigned Line = SameLine ? L1->getLine() : 0;

215 unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;

216

218 };

219

220 DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr;

221

222

223

224 for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {

225 DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);

226

227 if (!Tmp)

228

229

230

231 break;

232

233 Result = Tmp;

234 }

235

236 if (Result)

237 return Result;

238

239

240

241

242

243

245}

246

247std::optional

249 std::array<unsigned, 3> Components = {BD, DF, CI};

251

252

253

254

255

256 RemainingWork =

257 std::accumulate(Components.begin(), Components.end(), RemainingWork);

258

259 int I = 0;

260 unsigned Ret = 0;

261 unsigned NextBitInsertionIndex = 0;

262 while (RemainingWork > 0) {

263 unsigned C = Components[I++];

264 RemainingWork -= C;

266 Ret |= (EC << NextBitInsertionIndex);

268 }

269

270

271

272

273

274 unsigned TBD, TDF, TCI = 0;

276 if (TBD == BD && TDF == DF && TCI == CI)

277 return Ret;

278 return std::nullopt;

279}

280

282 unsigned &CI) {

287}

289

292#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)

293#include "llvm/IR/DebugInfoFlags.def"

294 .Default(DINode::FlagZero);

295}

296

298 switch (Flag) {

299#define HANDLE_DI_FLAG(ID, NAME) \

300 case Flag##NAME: \

301 return "DIFlag" #NAME;

302#include "llvm/IR/DebugInfoFlags.def"

303 }

304 return "";

305}

306

309

310

311

313 if (A == FlagPrivate)

314 SplitFlags.push_back(FlagPrivate);

315 else if (A == FlagProtected)

316 SplitFlags.push_back(FlagProtected);

317 else

318 SplitFlags.push_back(FlagPublic);

319 Flags &= ~A;

320 }

322 if (R == FlagSingleInheritance)

323 SplitFlags.push_back(FlagSingleInheritance);

324 else if (R == FlagMultipleInheritance)

325 SplitFlags.push_back(FlagMultipleInheritance);

326 else

327 SplitFlags.push_back(FlagVirtualInheritance);

328 Flags &= ~R;

329 }

330 if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {

331 Flags &= ~FlagIndirectVirtualBase;

332 SplitFlags.push_back(FlagIndirectVirtualBase);

333 }

334

335#define HANDLE_DI_FLAG(ID, NAME) \

336 if (DIFlags Bit = Flags & Flag##NAME) { \

337 SplitFlags.push_back(Bit); \

338 Flags &= ~Bit; \

339 }

340#include "llvm/IR/DebugInfoFlags.def"

341 return Flags;

342}

343

345 if (auto *T = dyn_cast(this))

346 return T->getScope();

347

348 if (auto *SP = dyn_cast(this))

349 return SP->getScope();

350

351 if (auto *LB = dyn_cast(this))

352 return LB->getScope();

353

354 if (auto *NS = dyn_cast(this))

355 return NS->getScope();

356

357 if (auto *CB = dyn_cast(this))

358 return CB->getScope();

359

360 if (auto *M = dyn_cast(this))

361 return M->getScope();

362

363 assert((isa(this) || isa(this)) &&

364 "Unhandled type of scope.");

365 return nullptr;

366}

367

369 if (auto *T = dyn_cast(this))

370 return T->getName();

371 if (auto *SP = dyn_cast(this))

372 return SP->getName();

373 if (auto *NS = dyn_cast(this))

374 return NS->getName();

375 if (auto *CB = dyn_cast(this))

376 return CB->getName();

377 if (auto *M = dyn_cast(this))

378 return M->getName();

379 assert((isa(this) || isa(this) ||

380 isa(this)) &&

381 "Unhandled type of scope.");

382 return "";

383}

384

385#ifndef NDEBUG

388}

389#endif

390

395 StorageType Storage, bool ShouldCreate) {

396 unsigned Hash = 0;

399 if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))

400 return N;

401 if (!ShouldCreate)

402 return nullptr;

403 Hash = Key.getHash();

404 } else {

405 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");

406 }

407

408

414}

415

416void GenericDINode::recalculateHash() {

417 setHash(GenericDINodeInfo::KeyTy::calculateHash(this));

418}

419

420#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__

421#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS

422#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \

423 do { \

424 if (Storage == Uniqued) { \

425 if (auto *N = getUniqued(Context.pImpl->CLASS##s, \

426 CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \

427 return N; \

428 if (!ShouldCreate) \

429 return nullptr; \

430 } else { \

431 assert(ShouldCreate && \

432 "Expected non-uniqued nodes to always be created"); \

433 } \

434 } while (false)

435#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \

436 return storeImpl(new (std::size(OPS), Storage) \

437 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \

438 Storage, Context.pImpl->CLASS##s)

439#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \

440 return storeImpl(new (0u, Storage) \

441 CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \

442 Storage, Context.pImpl->CLASS##s)

443#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \

444 return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \

445 Storage, Context.pImpl->CLASS##s)

446#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \

447 return storeImpl(new (NUM_OPS, Storage) \

448 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \

449 Storage, Context.pImpl->CLASS##s)

450

451DISubrange::DISubrange(LLVMContext &C, StorageType Storage,

453 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}

455 StorageType Storage, bool ShouldCreate) {

460 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,

461 ShouldCreate);

462}

463

465 int64_t Lo, StorageType Storage,

466 bool ShouldCreate) {

469 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,

470 ShouldCreate);

471}

472

475 StorageType Storage, bool ShouldCreate) {

479}

480

482 Metadata *CB = getRawCountNode();

483 if (!CB)

484 return BoundType();

485

486 assert((isa(CB) || isa(CB) ||

487 isa(CB)) &&

488 "Count must be signed constant or DIVariable or DIExpression");

489

490 if (auto *MD = dyn_cast(CB))

491 return BoundType(cast(MD->getValue()));

492

493 if (auto *MD = dyn_cast(CB))

494 return BoundType(MD);

495

496 if (auto *MD = dyn_cast(CB))

497 return BoundType(MD);

498

499 return BoundType();

500}

501

503 Metadata *LB = getRawLowerBound();

504 if (!LB)

505 return BoundType();

506

507 assert((isa(LB) || isa(LB) ||

508 isa(LB)) &&

509 "LowerBound must be signed constant or DIVariable or DIExpression");

510

511 if (auto *MD = dyn_cast(LB))

512 return BoundType(cast(MD->getValue()));

513

514 if (auto *MD = dyn_cast(LB))

515 return BoundType(MD);

516

517 if (auto *MD = dyn_cast(LB))

518 return BoundType(MD);

519

520 return BoundType();

521}

522

524 Metadata *UB = getRawUpperBound();

525 if (!UB)

526 return BoundType();

527

528 assert((isa(UB) || isa(UB) ||

529 isa(UB)) &&

530 "UpperBound must be signed constant or DIVariable or DIExpression");

531

532 if (auto *MD = dyn_cast(UB))

533 return BoundType(cast(MD->getValue()));

534

535 if (auto *MD = dyn_cast(UB))

536 return BoundType(MD);

537

538 if (auto *MD = dyn_cast(UB))

539 return BoundType(MD);

540

541 return BoundType();

542}

543

545 Metadata *ST = getRawStride();

546 if (!ST)

547 return BoundType();

548

549 assert((isa(ST) || isa(ST) ||

550 isa(ST)) &&

551 "Stride must be signed constant or DIVariable or DIExpression");

552

553 if (auto *MD = dyn_cast(ST))

554 return BoundType(cast(MD->getValue()));

555

556 if (auto *MD = dyn_cast(ST))

557 return BoundType(MD);

558

559 if (auto *MD = dyn_cast(ST))

560 return BoundType(MD);

561

562 return BoundType();

563}

564DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,

566 : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,

567 Ops) {}

568

572 StorageType Storage,

573 bool ShouldCreate) {

575 Metadata *Ops[] = {CountNode, LB, UB, Stride};

577}

578

581 if (!CB)

583

584 assert((isa(CB) || isa(CB)) &&

585 "Count must be signed constant or DIVariable or DIExpression");

586

587 if (auto *MD = dyn_cast(CB))

589

590 if (auto *MD = dyn_cast(CB))

592

594}

595

598 if (!LB)

600

601 assert((isa(LB) || isa(LB)) &&

602 "LowerBound must be signed constant or DIVariable or DIExpression");

603

604 if (auto *MD = dyn_cast(LB))

606

607 if (auto *MD = dyn_cast(LB))

609

611}

612

615 if (!UB)

617

618 assert((isa(UB) || isa(UB)) &&

619 "UpperBound must be signed constant or DIVariable or DIExpression");

620

621 if (auto *MD = dyn_cast(UB))

623

624 if (auto *MD = dyn_cast(UB))

626

628}

629

632 if (!ST)

634

635 assert((isa(ST) || isa(ST)) &&

636 "Stride must be signed constant or DIVariable or DIExpression");

637

638 if (auto *MD = dyn_cast(ST))

640

641 if (auto *MD = dyn_cast(ST))

643

645}

646

647DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,

650 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),

653}

656 StorageType Storage, bool ShouldCreate) {

661}

662

665 uint32_t AlignInBits, unsigned Encoding,

666 uint32_t NumExtraInhabitants, DIFlags Flags,

667 StorageType Storage, bool ShouldCreate) {

675 Ops);

676}

677

680 case dwarf::DW_ATE_signed:

681 case dwarf::DW_ATE_signed_char:

683 case dwarf::DW_ATE_unsigned:

684 case dwarf::DW_ATE_unsigned_char:

686 default:

687 return std::nullopt;

688 }

689}

690

696 unsigned Encoding, StorageType Storage,

697 bool ShouldCreate) {

705 Ops);

706}

708 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);

710}

712 assert(getTag() == dwarf::DW_TAG_inheritance);

713 if (auto *CM = cast_or_null(getExtraData()))

714 if (auto *CI = dyn_cast_or_null(CM->getValue()))

715 return static_cast<uint32_t>(CI->getZExtValue());

716 return 0;

717}

720 if (auto *C = cast_or_null(getExtraData()))

721 return C->getValue();

722 return nullptr;

723}

724

727 getTag() == dwarf::DW_TAG_variable) &&

729 if (auto *C = cast_or_null(getExtraData()))

730 return C->getValue();

731 return nullptr;

732}

735 if (auto *C = cast_or_null(getExtraData()))

736 return C->getValue();

737 return nullptr;

738}

739

744 std::optional DWARFAddressSpace,

745 std::optional PtrAuthData, DIFlags Flags, Metadata *ExtraData,

755 DWARFAddressSpace, PtrAuthData, Flags),

756 Ops);

757}

758

759std::optionalDIDerivedType::PtrAuthData

760DIDerivedType::getPtrAuthData() const {

761 return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type

762 ? std::optional(PtrAuthData(SubclassData32))

763 : std::nullopt;

764}

765

770 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,

774 uint32_t NumExtraInhabitants, StorageType Storage, bool ShouldCreate) {

776

777

791 Ops);

792}

793

799 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,

803 assert(Identifier.getString().empty() && "Expected valid identifier");

805 return nullptr;

807 if (!CT)

814 if (CT->getTag() != Tag)

815 return nullptr;

816

817

818 assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");

819 if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))

820 return CT;

821

822

829 assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&

830 "Mismatched number of operands");

831 for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)

832 if (Ops[I] != CT->getOperand(I))

833 CT->setOperand(I, Ops[I]);

834 return CT;

835}

836

841 Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,

842 Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,

846 assert(Identifier.getString().empty() && "Expected valid identifier");

848 return nullptr;

850 if (!CT) {

856 } else {

857 if (CT->getTag() != Tag)

858 return nullptr;

859 }

860 return CT;

861}

862

865 assert(Identifier.getString().empty() && "Expected valid identifier");

867 return nullptr;

869}

870DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,

873 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,

874 0, 0, 0, 0, Flags, Ops),

876

879 StorageType Storage,

880 bool ShouldCreate) {

884}

885

886DIFile::DIFile(LLVMContext &C, StorageType Storage,

887 std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,

889 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),

890 Checksum(CS), Source(Src) {}

891

892

893

895 "CSK_MD5",

896 "CSK_SHA1",

897 "CSK_SHA256",

898};

899

900StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {

902

903

904

906}

907

908std::optionalDIFile::ChecksumKind

915}

916

920 MDString *Source, StorageType Storage,

921 bool ShouldCreate) {

925

926

930}

931DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,

933 unsigned RuntimeVersion, unsigned EmissionKind,

934 uint64_t DWOId, bool SplitDebugInlining,

935 bool DebugInfoForProfiling, unsigned NameTableKind,

937 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),

940 IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),

941 DebugInfoForProfiling(DebugInfoForProfiling),

942 RangesBaseAddress(RangesBaseAddress) {

944}

945

949 unsigned RuntimeVersion, MDString *SplitDebugFilename,

950 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,

952 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,

953 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,

954 MDString *SDK, StorageType Storage, bool ShouldCreate) {

959

973 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,

974 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,

975 Ops),

977}

978

979std::optionalDICompileUnit::DebugEmissionKind

982 .Case("NoDebug", NoDebug)

987}

988

989std::optionalDICompileUnit::DebugNameTableKind

997}

998

1000 switch (EK) {

1002 return "NoDebug";

1004 return "FullDebug";

1006 return "LineTablesOnly";

1008 return "DebugDirectivesOnly";

1009 }

1010 return nullptr;

1011}

1012

1014 switch (NTK) {

1016 return nullptr;

1018 return "GNU";

1020 return "Apple";

1022 return "None";

1023 }

1024 return nullptr;

1025}

1026DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,

1027 unsigned ScopeLine, unsigned VirtualIndex,

1028 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,

1030 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),

1031 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),

1032 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {

1034}

1037 unsigned Virtuality, bool IsMainSubprogram) {

1038

1039 static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&

1040 int(SPFlagPureVirtual) ==

1041 int(dwarf::DW_VIRTUALITY_pure_virtual),

1042 "Virtuality constant mismatch");

1045 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |

1046 (IsDefinition ? SPFlagDefinition : SPFlagZero) |

1047 (IsOptimized ? SPFlagOptimized : SPFlagZero) |

1048 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));

1049}

1050

1052 if (auto *Block = dyn_cast(this))

1053 return Block->getScope()->getSubprogram();

1054 return const_cast<DISubprogram *>(cast(this));

1055}

1056

1058 if (auto *File = dyn_cast(this))

1059 return File->getScope()->getNonLexicalBlockFileScope();

1061}

1062

1067 DIScope *CachedResult = nullptr;

1068

1069 for (DIScope *Scope = &RootScope; !isa(Scope);

1070 Scope = Scope->getScope()) {

1071 if (auto It = Cache.find(Scope); It != Cache.end()) {

1072 CachedResult = cast(It->second);

1073 break;

1074 }

1076 }

1077

1078

1079

1080 DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;

1081 for (DIScope *ScopeToUpdate : reverse(ScopeChain)) {

1082 TempMDNode ClonedScope = ScopeToUpdate->clone();

1083 cast(*ClonedScope).replaceScope(UpdatedScope);

1084 UpdatedScope =

1086 Cache[ScopeToUpdate] = UpdatedScope;

1087 }

1088

1089 return cast(UpdatedScope);

1090}

1091

1094#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)

1095#include "llvm/IR/DebugInfoFlags.def"

1097}

1098

1100 switch (Flag) {

1101

1103 return "";

1104#define HANDLE_DISP_FLAG(ID, NAME) \

1105 case SPFlag##NAME: \

1106 return "DISPFlag" #NAME;

1107#include "llvm/IR/DebugInfoFlags.def"

1108 }

1109 return "";

1110}

1111

1115

1116

1117

1118#define HANDLE_DISP_FLAG(ID, NAME) \

1119 if (DISPFlags Bit = Flags & SPFlag##NAME) { \

1120 SplitFlags.push_back(Bit); \

1121 Flags &= ~Bit; \

1122 }

1123#include "llvm/IR/DebugInfoFlags.def"

1124 return Flags;

1125}

1126

1130 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,

1131 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,

1134 StorageType Storage, bool ShouldCreate) {

1140 ContainingType, VirtualIndex, ThisAdjustment, Flags,

1159 }

1160 }

1161 }

1162 }

1165 (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,

1166 Ops.size());

1167}

1168

1169bool DISubprogram::describes(const Function *F) const {

1170 assert(F && "Invalid function");

1171 return F->getSubprogram() == this;

1172}

1176 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}

1177

1179 Metadata *File, unsigned Line,

1180 unsigned Column, StorageType Storage,

1181 bool ShouldCreate) {

1182

1184

1189}

1190

1193 unsigned Discriminator,

1194 StorageType Storage,

1195 bool ShouldCreate) {

1200}

1201

1202DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,

1204 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {

1206}

1209 StorageType Storage, bool ShouldCreate) {

1212

1215}

1216

1217DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,

1219 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,

1220 Ops) {

1222}

1225 Metadata *File, unsigned LineNo,

1226 StorageType Storage, bool ShouldCreate) {

1229

1232}

1233

1234DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,

1236 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {

1239}

1242 MDString *ConfigurationMacros,

1244 unsigned LineNo, bool IsDecl, StorageType Storage,

1245 bool ShouldCreate) {

1252}

1253DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,

1254 StorageType Storage,

1255 bool IsDefault,

1258 dwarf::DW_TAG_template_type_parameter, IsDefault,

1259 Ops) {}

1260

1264 StorageType Storage, bool ShouldCreate) {

1269}

1270

1273 bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {

1279}

1280

1284 Metadata *Type, bool IsLocalToUnit, bool IsDefinition,

1285 Metadata *StaticDataMemberDeclaration,

1288 bool ShouldCreate) {

1306}

1307

1311 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,

1313 bool ShouldCreate) {

1314

1315 assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");

1316

1323}

1324

1328 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {

1330}

1332

1334 while (RawType) {

1335

1336 if (auto *T = dyn_cast(RawType))

1338 return Size;

1339

1340 if (auto *DT = dyn_cast(RawType)) {

1341

1342 RawType = DT->getRawBaseType();

1343 continue;

1344 }

1345

1346

1347 break;

1348 }

1349

1350

1351 return std::nullopt;

1352}

1353

1354DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,

1356 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {

1358}

1360 Metadata *File, unsigned Line, StorageType Storage,

1361 bool ShouldCreate) {

1367}

1368

1371 StorageType Storage, bool ShouldCreate) {

1374}

1377 return singleLocElts->size() > 0 &&

1379 }

1380 return false;

1381}

1384 return singleLocElts->size() > 0 &&

1385 (*singleLocElts)[0] == dwarf::DW_OP_deref;

1386 return false;

1387}

1390 return singleLocElts->size() == 1 &&

1391 (*singleLocElts)[0] == dwarf::DW_OP_deref;

1392 return false;

1393}

1394

1396 bool ShouldCreate) {

1397

1400}

1401

1404

1405 if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)

1406 return 2;

1407

1408 switch (Op) {

1413 case dwarf::DW_OP_bregx:

1414 return 3;

1415 case dwarf::DW_OP_constu:

1416 case dwarf::DW_OP_consts:

1417 case dwarf::DW_OP_deref_size:

1418 case dwarf::DW_OP_plus_uconst:

1422 case dwarf::DW_OP_regx:

1423 return 2;

1424 default:

1425 return 1;

1426 }

1427}

1428

1431

1432 if (I->get() + I->getSize() > E->get())

1433 return false;

1434

1436 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||

1437 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))

1438 return true;

1439

1440

1441 switch (Op) {

1442 default:

1443 return false;

1445

1446 return I->get() + I->getSize() == E->get();

1447 case dwarf::DW_OP_stack_value: {

1448

1449 if (I->get() + I->getSize() == E->get())

1450 break;

1451 auto J = I;

1453 return false;

1454 break;

1455 }

1456 case dwarf::DW_OP_swap: {

1457

1458

1459

1460

1461

1462

1463

1465 return false;

1466 break;

1467 }

1469

1470

1471

1472

1473

1476 ++FirstOp;

1477 return I->get() == FirstOp->get() && I->getArg(0) == 1;

1478 }

1485 case dwarf::DW_OP_constu:

1486 case dwarf::DW_OP_plus_uconst:

1487 case dwarf::DW_OP_plus:

1488 case dwarf::DW_OP_minus:

1489 case dwarf::DW_OP_mul:

1490 case dwarf::DW_OP_div:

1491 case dwarf::DW_OP_mod:

1492 case dwarf::DW_OP_or:

1493 case dwarf::DW_OP_and:

1494 case dwarf::DW_OP_xor:

1495 case dwarf::DW_OP_shl:

1496 case dwarf::DW_OP_shr:

1497 case dwarf::DW_OP_shra:

1498 case dwarf::DW_OP_deref:

1499 case dwarf::DW_OP_deref_size:

1500 case dwarf::DW_OP_xderef:

1501 case dwarf::DW_OP_lit0:

1502 case dwarf::DW_OP_not:

1503 case dwarf::DW_OP_dup:

1504 case dwarf::DW_OP_regx:

1505 case dwarf::DW_OP_bregx:

1506 case dwarf::DW_OP_push_object_address:

1507 case dwarf::DW_OP_over:

1508 case dwarf::DW_OP_consts:

1509 case dwarf::DW_OP_eq:

1510 case dwarf::DW_OP_ne:

1511 case dwarf::DW_OP_gt:

1512 case dwarf::DW_OP_ge:

1513 case dwarf::DW_OP_lt:

1514 case dwarf::DW_OP_le:

1515 break;

1516 }

1517 }

1518 return true;

1519}

1520

1523 return false;

1524

1526 return false;

1527

1528 for (const auto &It : expr_ops()) {

1529 switch (It.getOp()) {

1530 default:

1531 break;

1532 case dwarf::DW_OP_stack_value:

1533 return true;

1534 }

1535 }

1536

1537 return false;

1538}

1539

1542 return false;

1543

1545 return false;

1546

1547

1548

1549 for (const auto &It : expr_ops()) {

1550 switch (It.getOp()) {

1554 continue;

1555 default:

1556 return true;

1557 }

1558 }

1559

1560 return false;

1561}

1562

1565 return false;

1566

1568 return true;

1569

1570 auto ExprOpBegin = expr_ops().begin();

1571 auto ExprOpEnd = expr_ops().end();

1573 if (ExprOpBegin->getArg(0) != 0)

1574 return false;

1575 ++ExprOpBegin;

1576 }

1577

1578 return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) {

1580 });

1581}

1582

1583std::optional<ArrayRef<uint64_t>>

1585

1587 return std::nullopt;

1588

1589

1592

1593

1594

1598}

1599

1606 }

1608}

1609

1613 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;

1614 }))

1615 return Expr;

1621}

1622

1623std::optional<const DIExpression *>

1625 if (!Expr)

1626 return std::nullopt;

1627

1630

1631 return std::nullopt;

1632}

1633

1636 bool IsIndirect) {

1637

1638

1640 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;

1641 }))

1643

1644

1645 if (!IsIndirect) {

1647 return;

1648 }

1649

1650

1651

1653 if (Op.getOp() == dwarf::DW_OP_stack_value ||

1655 Ops.push_back(dwarf::DW_OP_deref);

1656 IsIndirect = false;

1657 }

1658 Op.appendToVector(Ops);

1659 }

1660 if (IsIndirect)

1661 Ops.push_back(dwarf::DW_OP_deref);

1662}

1663

1665 bool FirstIndirect,

1667 bool SecondIndirect) {

1672 SecondIndirect);

1673 return FirstOps == SecondOps;

1674}

1675

1676std::optionalDIExpression::FragmentInfo

1678 for (auto I = Start; I != End; ++I)

1681 return Info;

1682 }

1683 return std::nullopt;

1684}

1685

1687 std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();

1688 std::optional<uint64_t> ActiveBits = InitialActiveBits;

1690 switch (Op.getOp()) {

1691 default:

1692

1693

1694 ActiveBits = InitialActiveBits;

1695 break;

1698

1699

1700 std::optionalDIBasicType::Signedness VarSign = Var->getSignedness();

1703 if (!VarSign || VarSigned != OpSigned) {

1704 ActiveBits = InitialActiveBits;

1705 break;

1706 }

1707 [[fallthrough]];

1708 }

1710

1711 if (ActiveBits)

1712 ActiveBits = std::min(*ActiveBits, Op.getArg(1));

1713 else

1714 ActiveBits = Op.getArg(1);

1715 break;

1716 }

1717 }

1718 return ActiveBits;

1719}

1720

1724 Ops.push_back(dwarf::DW_OP_plus_uconst);

1726 } else if (Offset < 0) {

1727 Ops.push_back(dwarf::DW_OP_constu);

1728

1729

1732 Ops.push_back(dwarf::DW_OP_minus);

1733 }

1734}

1735

1738 if (!SingleLocEltsOpt)

1739 return false;

1740 auto SingleLocElts = *SingleLocEltsOpt;

1741

1742 if (SingleLocElts.size() == 0) {

1744 return true;

1745 }

1746

1747 if (SingleLocElts.size() == 2 &&

1748 SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {

1749 Offset = SingleLocElts[1];

1750 return true;

1751 }

1752

1753 if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {

1754 if (SingleLocElts[2] == dwarf::DW_OP_plus) {

1755 Offset = SingleLocElts[1];

1756 return true;

1757 }

1758 if (SingleLocElts[2] == dwarf::DW_OP_minus) {

1759 Offset = -SingleLocElts[1];

1760 return true;

1761 }

1762 }

1763

1764 return false;

1765}

1766

1769 OffsetInBytes = 0;

1770 RemainingOps.clear();

1771

1773 if (!SingleLocEltsOpt)

1774 return false;

1775

1777 auto ExprOpIt = expr_op_iterator(SingleLocEltsOpt->begin());

1778 while (ExprOpIt != ExprOpEnd) {

1780 if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||

1784 break;

1785 } else if (Op == dwarf::DW_OP_plus_uconst) {

1786 OffsetInBytes += ExprOpIt->getArg(0);

1787 } else if (Op == dwarf::DW_OP_constu) {

1789 ++ExprOpIt;

1790 if (ExprOpIt->getOp() == dwarf::DW_OP_plus)

1791 OffsetInBytes += Value;

1792 else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)

1793 OffsetInBytes -= Value;

1794 else

1795 return false;

1796 } else {

1797

1798 return false;

1799 }

1800 ++ExprOpIt;

1801 }

1802 RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());

1803 return true;

1804}

1805

1808 for (auto ExprOp : expr_ops())

1810 SeenOps.insert(ExprOp.getArg(0));

1813 return false;

1814 return true;

1815}

1816

1818 unsigned &AddrClass) {

1819

1820

1822 if (!SingleLocEltsOpt)

1823 return nullptr;

1824 auto SingleLocElts = *SingleLocEltsOpt;

1825

1826 const unsigned PatternSize = 4;

1827 if (SingleLocElts.size() >= PatternSize &&

1828 SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu &&

1829 SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap &&

1830 SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) {

1831 AddrClass = SingleLocElts[PatternSize - 3];

1832

1833 if (SingleLocElts.size() == PatternSize)

1834 return nullptr;

1837 ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize));

1838 }

1839 return Expr;

1840}

1841

1846 Ops.push_back(dwarf::DW_OP_deref);

1847

1850 Ops.push_back(dwarf::DW_OP_deref);

1851

1854

1856}

1857

1861 assert(Expr && "Can't add ops to this expression");

1862

1863

1865 [](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) {

1866 assert(ArgNo == 0 &&

1867 "Location Index must be 0 for a non-variadic expression.");

1870 }

1871

1874

1876 if (Op.getOp() == dwarf::DW_OP_stack_value)

1879 NewOps.push_back(dwarf::DW_OP_stack_value);

1881 }

1882 }

1883 Op.appendToVector(NewOps);

1886 }

1888 NewOps.push_back(dwarf::DW_OP_stack_value);

1889

1891}

1892

1895 assert(Expr && "Can't replace args in this expression");

1896

1898

1901 Op.appendToVector(NewOps);

1902 continue;

1903 }

1905 uint64_t Arg = Op.getArg(0) == OldArg ? NewArg : Op.getArg(0);

1906

1907

1908 if (Arg > OldArg)

1909 --Arg;

1911 }

1913}

1914

1918 assert(Expr && "Can't prepend ops to this expression");

1919

1922

1923

1924

1926 }

1927

1928

1929 if (Ops.empty())

1932

1934 if (Op.getOp() == dwarf::DW_OP_stack_value)

1937 Ops.push_back(dwarf::DW_OP_stack_value);

1939 }

1940 }

1941 Op.appendToVector(Ops);

1942 }

1944 Ops.push_back(dwarf::DW_OP_stack_value);

1946}

1947

1950 assert(Expr && !Ops.empty() && "Can't append ops to this expression");

1951

1952

1955

1956 if (Op.getOp() == dwarf::DW_OP_stack_value ||

1959

1960

1961 Ops = {};

1962 }

1963 Op.appendToVector(NewOps);

1964 }

1966 auto *result =

1968 assert(result->isValid() && "concatenated expression is not valid");

1969 return result;

1970}

1971

1974 assert(Expr && !Ops.empty() && "Can't append ops to this expression");

1977 [](auto Op) {

1978 return Op.getOp() == dwarf::DW_OP_stack_value ||

1979 Op.getOp() == dwarf::DW_OP_LLVM_fragment;

1980 }) &&

1981 "Can't append this op");

1982

1983

1984

1985

1986

1987 std::optional FI = Expr->getFragmentInfo();

1988 unsigned DropUntilStackValue = FI ? 3 : 0;

1991 bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) &&

1992 (ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value);

1993 bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty();

1994

1995

1996

1998 if (NeedsDeref)

1999 NewOps.push_back(dwarf::DW_OP_deref);

2001 if (NeedsStackValue)

2002 NewOps.push_back(dwarf::DW_OP_stack_value);

2004}

2005

2007 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {

2009

2010

2011 bool CanSplitValue = true;

2012

2013 bool EmitFragment = true;

2014

2015 if (Expr) {

2017 switch (Op.getOp()) {

2018 default:

2019 break;

2020 case dwarf::DW_OP_shr:

2021 case dwarf::DW_OP_shra:

2022 case dwarf::DW_OP_shl:

2023 case dwarf::DW_OP_plus:

2024 case dwarf::DW_OP_plus_uconst:

2025 case dwarf::DW_OP_minus:

2026

2027

2028

2029

2030

2031 CanSplitValue = false;

2032 break;

2033 case dwarf::DW_OP_deref:

2034 case dwarf::DW_OP_deref_size:

2035 case dwarf::DW_OP_deref_type:

2036 case dwarf::DW_OP_xderef:

2037 case dwarf::DW_OP_xderef_size:

2038 case dwarf::DW_OP_xderef_type:

2039

2040

2041 CanSplitValue = true;

2042 break;

2043 case dwarf::DW_OP_stack_value:

2044

2045 if (!CanSplitValue)

2046 return std::nullopt;

2047 break;

2049

2050

2051

2052 if (!EmitFragment)

2053 return std::nullopt;

2054

2055 uint64_t FragmentOffsetInBits = Op.getArg(0);

2056 uint64_t FragmentSizeInBits = Op.getArg(1);

2057 (void)FragmentSizeInBits;

2058 assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&

2059 "new fragment outside of original fragment");

2060 OffsetInBits += FragmentOffsetInBits;

2061 continue;

2062 }

2065

2066

2067

2068 uint64_t ExtractOffsetInBits = Op.getArg(0);

2069 uint64_t ExtractSizeInBits = Op.getArg(1);

2070 if (ExtractOffsetInBits >= OffsetInBits &&

2071 ExtractOffsetInBits + ExtractSizeInBits <=

2072 OffsetInBits + SizeInBits) {

2074 Ops.push_back(ExtractOffsetInBits - OffsetInBits);

2075 Ops.push_back(ExtractSizeInBits);

2076 EmitFragment = false;

2077 continue;

2078 }

2079

2080

2081

2082 return std::nullopt;

2083 }

2084 }

2085 Op.appendToVector(Ops);

2086 }

2087 }

2088 assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");

2089 assert(Expr && "Unknown DIExpression");

2090 if (EmitFragment) {

2094 }

2096}

2097

2098

2101 uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,

2103 std::optionalDIExpression::FragmentInfo &Result,

2104 int64_t &OffsetFromLocationInBits) {

2105

2107 return false;

2108

2109

2110

2111

2112

2113

2114

2115

2116 int64_t MemStartRelToDbgStartInBits;

2117 {

2119 if (!MemOffsetFromDbgInBytes)

2120 return false;

2121

2122 MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;

2123

2124 MemStartRelToDbgStartInBits +=

2125 SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);

2126 }

2127

2128

2129 OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;

2130

2131

2132 int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;

2133 if (MemEndRelToDbgStart < 0) {

2134 Result = {0, 0};

2135 return true;

2136 }

2137

2138

2139

2140

2141

2142

2143

2144

2145 int64_t MemStartRelToVarInBits =

2146 MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;

2147 int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;

2148

2149

2150

2151

2152 int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);

2153 int64_t MemFragSize =

2154 std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);

2156

2157

2160 if (TrimmedSliceOfVariable == VarFrag)

2161 Result = std::nullopt;

2162 else

2163 Result = TrimmedSliceOfVariable;

2164 return true;

2165}

2166

2167std::pair<DIExpression *, const ConstantInt *>

2169

2172

2173

2174 bool First = true;

2175 bool Changed = false;

2177 switch (Op.getOp()) {

2178 default:

2179

2180

2181

2182 if (!Changed)

2183 return {this, CI};

2185 break;

2188 break;

2189 Changed = true;

2190 if (Op.getArg(1) == dwarf::DW_ATE_signed)

2192 else {

2193 assert(Op.getArg(1) == dwarf::DW_ATE_unsigned && "Unexpected operand");

2195 }

2196 continue;

2197 }

2198 Op.appendToVector(Ops);

2199 }

2200 if (!Changed)

2201 return {this, CI};

2203 ConstantInt::get(getContext(), NewInt)};

2204}

2205

2208 for (auto ExprOp : expr_ops())

2210 Result = std::max(Result, ExprOp.getArg(0) + 1);

2212 "Expression is missing one or more location operands.");

2213 return Result;

2214}

2215

2216std::optionalDIExpression::SignedOrUnsignedConstant

2218

2219

2220

2221

2222

2223

2224

2227 (getElement(0) != dwarf::DW_OP_consts &&

2228 getElement(0) != dwarf::DW_OP_constu))

2229 return std::nullopt;

2230

2233

2237 return std::nullopt;

2238 return getElement(0) == dwarf::DW_OP_constu

2241}

2242

2248 return Ops;

2249}

2250

2252 unsigned FromSize, unsigned ToSize,

2255}

2256

2258DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,

2260 bool ShouldCreate) {

2264}

2266 unsigned Line, unsigned Attributes,

2268 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),

2270

2273 MDString *GetterName, MDString *SetterName, unsigned Attributes,

2274 Metadata *Type, StorageType Storage, bool ShouldCreate) {

2282}

2283

2286 Metadata *File, unsigned Line,

2288 StorageType Storage,

2289 bool ShouldCreate) {

2295}

2296

2297DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,

2299 bool ShouldCreate) {

2304}

2305

2307 unsigned Line, Metadata *File,

2308 Metadata *Elements, StorageType Storage,

2309 bool ShouldCreate) {

2313}

2314

2319 return *ExistingIt;

2322 return NewArgList;

2323}

2324

2327 assert((!New || isa(New)) &&

2328 "DIArgList must be passed a ValueAsMetadata");

2329 untrack();

2330

2331

2333 ValueAsMetadata *NewVM = cast_or_null(New);

2335 if (&VM == OldVMPtr) {

2336 if (NewVM)

2337 VM = NewVM;

2338 else

2340 }

2341 }

2342

2343

2344

2345

2347 if (ExistingArgList) {

2349

2350 Args.clear();

2351 delete this;

2352 return;

2353 }

2355 track();

2356}

2357void DIArgList::track() {

2359 if (VAM)

2361}

2362void DIArgList::untrack() {

2364 if (VAM)

2366}

2367void DIArgList::dropAllReferences(bool Untrack) {

2368 if (Untrack)

2369 untrack();

2370 Args.clear();

2372}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))

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

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

Analysis containing CSE Info

static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)

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 RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")

static unsigned encodingBits(unsigned C)

static unsigned encodeComponent(unsigned C)

static unsigned getNextComponentInDiscriminator(unsigned D)

Returns the next component stored in discriminator.

static unsigned getUnsignedFromPrefixEncoding(unsigned U)

Reverse transformation as getPrefixEncodingFromUnsigned.

This file contains constants used for implementing Dwarf debug support.

static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)

Return the first found DebugLoc that has a DILocation, given a range of instructions.

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

This file defines the SmallPtrSet class.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

support::ulittle16_t & Lo

Class for arbitrary precision integers.

APInt zextOrTrunc(unsigned width) const

Zero extend or truncate to width.

APInt sextOrTrunc(unsigned width) const

Sign extend or truncate to width.

Annotations lets you mark points and ranges inside source code, for tests:

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

const T & back() const

back - Get the last element.

ArrayRef< T > drop_front(size_t N=1) const

Drop the first N elements of the array.

size_t size() const

size - Get the array size.

ArrayRef< T > drop_back(size_t N=1) const

Drop the last N elements of the array.

bool empty() const

empty - Check if the array is empty.

This is the shared class of boolean and integer constants.

static ConstantInt * getSigned(IntegerType *Ty, int64_t V)

Return a ConstantInt with the specified value for the specified type.

const APInt & getValue() const

Return the constant as an APInt value reference.

This is an important base class in LLVM.

List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.

void handleChangedOperand(void *Ref, Metadata *New)

static DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)

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

unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags

unsigned StringRef uint64_t SizeInBits

std::optional< Signedness > getSignedness() const

Return the signedness of this type, or std::nullopt if this type is neither signed nor unsigned.

unsigned getEncoding() const

unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t NumExtraInhabitants

unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t AlignInBits

Metadata Metadata MDString Metadata unsigned LineNo

Metadata Metadata MDString * Name

Metadata Metadata MDString Metadata * File

static const char * nameTableKindString(DebugNameTableKind PK)

static const char * emissionKindString(DebugEmissionKind EK)

DebugEmissionKind getEmissionKind() const

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata * Macros

unsigned Metadata MDString bool MDString * Flags

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata * EnumTypes

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata * RetainedTypes

DebugNameTableKind getNameTableKind() const

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata * GlobalVariables

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString MDString * SDK

unsigned Metadata MDString * Producer

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString * SysRoot

unsigned Metadata MDString bool MDString unsigned MDString * SplitDebugFilename

unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata * ImportedEntities

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t AlignInBits

unsigned MDString Metadata unsigned Line

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata * Elements

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata Metadata * Specification

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata * TemplateParams

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata Metadata uint32_t NumExtraInhabitants

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata * Rank

static DICompositeType * getODRTypeIfExists(LLVMContext &Context, MDString &Identifier)

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t OffsetInBits

unsigned MDString Metadata unsigned Metadata * Scope

unsigned MDString Metadata * File

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata * Allocated

unsigned MDString Metadata unsigned Metadata Metadata * BaseType

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Flags

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata * Discriminator

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata * Annotations

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata * DataLocation

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString * Identifier

unsigned MDString Metadata unsigned Metadata Metadata uint64_t SizeInBits

static DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations)

Build a DICompositeType with the given ODR identifier.

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata * Associated

unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata * VTableHolder

unsigned StringRef DIFile unsigned DIScope DIType * BaseType

unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Metadata * ExtraData

unsigned StringRef DIFile unsigned DIScope DIType uint64_t SizeInBits

Metadata * getExtraData() const

Get extra data associated with this derived type.

unsigned StringRef DIFile * File

unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t OffsetInBits

unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t AlignInBits

unsigned StringRef DIFile unsigned DIScope * Scope

DIType * getClassType() const

Get casted version of extra data.

Constant * getConstant() const

Constant * getStorageOffsetInBits() const

Constant * getDiscriminantValue() const

uint32_t getVBPtrOffset() const

unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Flags

unsigned StringRef DIFile unsigned Line

int64_t bool MDString * Name

unsigned getSize() const

Return the size of the operand.

uint64_t getOp() const

Get the operand code.

An iterator for expression operands.

element_iterator elements_end() const

bool isEntryValue() const

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

iterator_range< expr_op_iterator > expr_ops() const

static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)

Append the opcodes Ops to DIExpr.

std::array< uint64_t, 6 > ExtOps

unsigned getNumElements() const

static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed)

Returns the ops for a zero- or sign-extension in a DIExpression.

expr_op_iterator expr_op_begin() const

Visit the elements via ExprOperand wrappers.

bool extractIfOffset(int64_t &Offset) const

If this is a constant offset, extract it.

static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)

Append Ops with operations to apply the Offset.

bool startsWithDeref() const

Return whether the first element a DW_OP_deref.

static bool isEqualExpression(const DIExpression *FirstExpr, bool FirstIndirect, const DIExpression *SecondExpr, bool SecondIndirect)

Determines whether two debug values should produce equivalent DWARF expressions, using their DIExpres...

expr_op_iterator expr_op_end() const

bool isImplicit() const

Return whether this is an implicit location description.

static bool calculateFragmentIntersect(const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits, int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag, std::optional< DIExpression::FragmentInfo > &Result, int64_t &OffsetFromLocationInBits)

Computes a fragment, bit-extract operation if needed, and new constant offset to describe a part of a...

element_iterator elements_begin() const

bool hasAllLocationOps(unsigned N) const

Returns true iff this DIExpression contains at least one instance of DW_OP_LLVM_arg,...

std::optional< FragmentInfo > getFragmentInfo() const

Retrieve the details of this fragment expression.

static DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)

Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...

bool isComplex() const

Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...

static std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)

Retrieve the details of this fragment expression.

static std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)

If Expr is a valid single-location expression, i.e.

std::pair< DIExpression *, const ConstantInt * > constantFold(const ConstantInt *CI)

Try to shorten an expression with an initial constant operand.

bool isDeref() const

Return whether there is exactly one operator and it is a DW_OP_deref;.

static const DIExpression * convertToVariadicExpression(const DIExpression *Expr)

If Expr is a non-variadic expression (i.e.

uint64_t getNumLocationOperands() const

Return the number of unique location operands referred to (via DW_OP_LLVM_arg) in this expression; th...

ArrayRef< uint64_t > getElements() const

static DIExpression * replaceArg(const DIExpression *Expr, uint64_t OldArg, uint64_t NewArg)

Create a copy of Expr with each instance of DW_OP_LLVM_arg, \p OldArg replaced with DW_OP_LLVM_arg,...

std::optional< uint64_t > getActiveBits(DIVariable *Var)

Return the number of bits that have an active value, i.e.

static void canonicalizeExpressionOps(SmallVectorImpl< uint64_t > &Ops, const DIExpression *Expr, bool IsIndirect)

Inserts the elements of Expr into Ops modified to a canonical form, which uses DW_OP_LLVM_arg (i....

uint64_t getElement(unsigned I) const

static std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)

Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...

static const DIExpression * convertToUndefExpression(const DIExpression *Expr)

Removes all elements from Expr that do not apply to an undef debug value, which includes every operat...

static DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)

Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...

static DIExpression * appendToStack(const DIExpression *Expr, ArrayRef< uint64_t > Ops)

Convert DIExpr into a stack value if it isn't one already by appending DW_OP_deref if needed,...

static DIExpression * appendExt(const DIExpression *Expr, unsigned FromSize, unsigned ToSize, bool Signed)

Append a zero- or sign-extension to Expr.

std::optional< ArrayRef< uint64_t > > getSingleLocationExpressionElements() const

Returns a reference to the elements contained in this expression, skipping past the leading DW_OP_LLV...

bool isSingleLocationExpression() const

Return whether the evaluated expression makes use of a single location at the start of the expression...

bool extractLeadingOffset(int64_t &OffsetInBytes, SmallVectorImpl< uint64_t > &RemainingOps) const

Assuming that the expression operates on an address, extract a constant offset and the successive ops...

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_...

static DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)

Prepend DIExpr with the given opcodes and optionally turn it into a stack value.

MDString MDString * Directory

static std::optional< ChecksumKind > getChecksumKind(StringRef CSKindStr)

MDString MDString std::optional< ChecksumInfo< MDString * > > CS

Metadata * getRawLowerBound() const

Metadata * getRawCountNode() const

Metadata * getRawStride() const

BoundType getLowerBound() const

Metadata * getRawUpperBound() const

BoundType getCount() const

BoundType getUpperBound() const

PointerUnion< DIVariable *, DIExpression * > BoundType

BoundType getStride() const

A pair of DIGlobalVariable and DIExpression.

Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata * TemplateParams

Metadata MDString MDString Metadata unsigned Line

Metadata MDString MDString Metadata unsigned Metadata * Type

Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata * StaticDataMemberDeclaration

Metadata MDString MDString * LinkageName

Metadata MDString MDString Metadata * File

Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata uint32_t AlignInBits

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

unsigned Metadata Metadata * Entity

unsigned Metadata Metadata Metadata unsigned Line

unsigned Metadata Metadata Metadata unsigned MDString * Name

unsigned Metadata Metadata Metadata * File

unsigned Metadata * Scope

Metadata MDString Metadata unsigned Line

Metadata MDString Metadata * File

DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef< Metadata * > Ops)

Metadata Metadata unsigned Discriminator

Metadata Metadata unsigned Line

DISubprogram * getSubprogram() const

Get the subprogram for this scope.

DILocalScope * getNonLexicalBlockFileScope() const

Get the first non DILexicalBlockFile scope of this scope.

static DILocalScope * cloneScopeForSubprogram(DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)

Traverses the scope chain rooted at RootScope until it hits a Subprogram, recreating the chain with "...

Metadata MDString Metadata unsigned Metadata * Type

Metadata MDString Metadata * File

Metadata MDString Metadata unsigned Line

Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t AlignInBits

unsigned unsigned DILocalScope * Scope

static DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)

Try to combine the vector of locations passed as input in a single one.

static std::optional< unsigned > encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI)

Raw encoding of the discriminator.

unsigned unsigned DILocalScope DILocation bool ImplicitCode

static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, unsigned &CI)

Raw decoder for values in an encoded discriminator D.

static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)

When two instructions are combined into a single instruction we also need to combine the original loc...

unsigned unsigned DILocalScope DILocation * InlinedAt

unsigned unsigned Metadata * File

unsigned unsigned Metadata Metadata * Elements

unsigned unsigned MDString * Name

Represents a module in the programming language, for example, a Clang module, or a Fortran module.

Metadata Metadata * Scope

Metadata Metadata MDString * Name

Metadata Metadata MDString MDString MDString MDString * APINotesFile

Metadata Metadata MDString MDString MDString * IncludePath

Metadata Metadata MDString MDString * ConfigurationMacros

Metadata Metadata MDString MDString MDString MDString unsigned LineNo

Metadata MDString bool ExportSymbols

Tagged DWARF-like metadata node.

dwarf::Tag getTag() const

static DIFlags getFlag(StringRef Flag)

static DIFlags splitFlags(DIFlags Flags, SmallVectorImpl< DIFlags > &SplitFlags)

Split up a flags bitfield.

static StringRef getFlagString(DIFlags Flag)

MDString Metadata unsigned MDString * GetterName

MDString Metadata unsigned MDString MDString * SetterName

Base class for scope-like contexts.

StringRef getName() const

DIScope * getScope() const

String type, Fortran CHARACTER(n)

unsigned MDString Metadata Metadata Metadata uint64_t SizeInBits

unsigned MDString Metadata Metadata Metadata uint64_t uint32_t AlignInBits

unsigned MDString Metadata Metadata Metadata * StringLocationExp

unsigned MDString Metadata Metadata * StringLengthExp

unsigned MDString Metadata * StringLength

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata * Unit

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata * Annotations

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata * ContainingType

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata * TemplateParams

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata * Declaration

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata MDString * TargetFuncName

static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata * ThrownTypes

static DISPFlags getFlag(StringRef Flag)

Metadata MDString MDString Metadata * File

static DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)

Split up a flags bitfield for easier printing.

Metadata MDString MDString * LinkageName

static StringRef getFlagString(DISPFlags Flag)

Metadata MDString MDString Metadata unsigned Metadata * Type

Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata * RetainedNodes

DISPFlags

Debug info subprogram flags.

BoundType getUpperBound() const

BoundType getStride() const

BoundType getLowerBound() const

BoundType getCount() const

Type array for a subprogram.

DIFlags uint8_t Metadata * TypeArray

Base class for template parameters.

unsigned MDString Metadata * Type

bool isStaticMember() const

uint32_t getAlignInBits() const

Base class for variables.

std::optional< DIBasicType::Signedness > getSignedness() const

Return the signedness of this variable's type, or std::nullopt if this type is neither signed nor uns...

std::optional< uint64_t > getSizeInBits() const

Determines the size of the variable's type.

Metadata * getRawType() const

DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line, ArrayRef< Metadata * > Ops, uint32_t AlignInBits=0)

This class represents an Operation in the Expression.

A parsed version of the target data layout string in and methods for querying it.

This is the common base class for debug info intrinsics for variables.

Record of a variable value-assignment, aka a non instruction representation of the dbg....

DebugVariableAggregate(const DbgVariableIntrinsic *DVI)

Identifies a unique instance of a variable.

DebugVariable(const DbgVariableIntrinsic *DII)

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

Class representing an expression and its matching format.

Generic tagged DWARF-like metadata node.

dwarf::Tag getTag() const

unsigned MDString * Header

unsigned MDString ArrayRef< Metadata * > DwarfOps

DenseSet< DIArgList *, DIArgListInfo > DIArgLists

std::optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap

This is an important class for using LLVM in a threaded context.

bool isODRUniquingDebugTypes() const

Whether there is a string map for uniquing debug info identifiers across the context.

LLVMContextImpl *const pImpl

static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

TempMDNode clone() const

Create a (temporary) clone of this.

static T * storeImpl(T *N, StorageType Storage, StoreT &Store)

LLVMContext & getContext() const

static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithUniqued(std::unique_ptr< T, TempMDNodeDeleter > N)

Replace a temporary node with a uniqued one.

StringRef getString() const

A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...

static PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

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

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

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

void reserve(size_type N)

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

iterator insert(iterator I, T &&Elt)

void push_back(const T &Elt)

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

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

constexpr bool empty() const

empty - Check if the string is empty.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

The instances of the Type class are immutable: once they are created, they are never changed.

static IntegerType * getInt64Ty(LLVMContext &C)

LLVM Value Representation.

std::optional< int64_t > getPointerOffsetFrom(const Value *Other, const DataLayout &DL) const

If this ptr is provably equal to Other plus a constant offset, return that offset in bytes.

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

bool contains(const_arg_type_t< ValueT > V) const

Check if the set contains the given element.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

@ C

The default llvm calling convention, compatible with C.

@ DW_OP_LLVM_entry_value

Only used in LLVM metadata.

@ DW_OP_LLVM_implicit_pointer

Only used in LLVM metadata.

@ DW_OP_LLVM_extract_bits_zext

Only used in LLVM metadata.

@ DW_OP_LLVM_tag_offset

Only used in LLVM metadata.

@ DW_OP_LLVM_fragment

Only used in LLVM metadata.

@ DW_OP_LLVM_arg

Only used in LLVM metadata.

@ DW_OP_LLVM_convert

Only used in LLVM metadata.

@ DW_OP_LLVM_extract_bits_sext

Only used in LLVM metadata.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

static T * getUniqued(DenseSet< T *, InfoT > &Store, const typename InfoT::KeyTy &Key)

cl::opt< bool > EnableFSDiscriminator

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)

bool none_of(R &&Range, UnaryPredicate P)

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

@ Ref

The access may reference the value stored in memory.

@ First

Helpers to iterate all locations in the MemoryEffectsBase class.

Implement std::hash so that hash_code can be used in STL containers.

A single checksum, represented by a Kind and a Value (a string).

static DbgVariableFragmentInfo intersect(DbgVariableFragmentInfo A, DbgVariableFragmentInfo B)

Returns a zero-sized fragment if A and B don't intersect.