LLVM 24.0.0git
DebugInfoMetadata.cpp
Go to the documentation of this file.
1//===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the debug info Metadata classes.
10//
11//===----------------------------------------------------------------------===//
12
14#include "LLVMContextImpl.h"
15#include "MetadataImpl.h"
16#include "llvm/ADT/DenseSet.h"
17#include "llvm/ADT/SetVector.h"
21#include "llvm/IR/Function.h"
23#include "llvm/IR/Type.h"
24#include "llvm/IR/Value.h"
27
28#include <numeric>
29#include <optional>
30#include <tuple>
31
32using namespace llvm;
33
34namespace llvm {
35// Use FS-AFDO discriminator.
37 "enable-fs-discriminator", cl::Hidden,
38 cl::desc("Enable adding flow sensitive discriminators"));
39
40// When true, preserves line and column number by picking one of the merged
41// location info in a deterministic manner to assist sample based PGO.
43 "pick-merged-source-locations", cl::init(false), cl::Hidden,
44 cl::desc("Preserve line and column number when merging locations."));
45} // namespace llvm
46
48 return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32);
49}
50
51const DIExpression::FragmentInfo DebugVariable::DefaultFragment = {
52 std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};
53
55 : Variable(DVR->getVariable()),
56 Fragment(DVR->getExpression()->getFragmentInfo()),
57 InlinedAt(DVR->getDebugLoc().getInlinedAt()) {}
58
62
63DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
64 unsigned Column, uint64_t AtomGroup, uint8_t AtomRank,
65 bool HasIRLayers, ArrayRef<Metadata *> MDs,
66 bool ImplicitCode)
67 : MDNode(C, DILocationKind, Storage, MDs), AtomGroup(AtomGroup),
68 AtomRank(AtomRank), HasIRLayers(HasIRLayers) {
69 assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits");
70 assert(AtomGroup < (1ULL << 60) && "AtomGroup number should fit in 60 bits");
71 if (AtomGroup)
72 C.updateDILocationAtomGroupWaterline(AtomGroup + 1);
73
74 assert(MDs.size() >= 1 && MDs.size() <= 3 &&
75 "Expected a scope and optional inlined-at + irlayers");
76 // Set line and column.
77 assert(Column < (1u << 16) && "Expected 16-bit column");
78
79 SubclassData32 = Line;
80 SubclassData16 = Column;
81
82 setImplicitCode(ImplicitCode);
83}
84
85static void adjustColumn(unsigned &Column) {
86 // Set to unknown on overflow. We only have 16 bits to play with here.
87 if (Column >= (1u << 16))
88 Column = 0;
89}
90
91DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
92 unsigned Column, Metadata *Scope,
93 Metadata *InlinedAt, bool ImplicitCode,
94 uint64_t AtomGroup, uint8_t AtomRank,
95 Metadata *IRLayers, StorageType Storage,
96 bool ShouldCreate) {
97 // Fixup column.
99
100 // Clamp rather than truncate, which would wrap into a different valid group.
101 if (AtomGroup >= (1ULL << 60))
102 AtomGroup = 0;
103
104 if (Storage == Uniqued) {
105 if (auto *N = getUniqued(
106 Context.pImpl->DILocations,
107 DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt, ImplicitCode,
108 AtomGroup, AtomRank, IRLayers)))
109 return N;
110 if (!ShouldCreate)
111 return nullptr;
112 } else {
113 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
114 }
115
117 Ops.push_back(Scope);
118 if (InlinedAt)
119 Ops.push_back(InlinedAt);
120 if (IRLayers)
121 Ops.push_back(IRLayers);
122 return storeImpl(new (Ops.size(), Storage) DILocation(
123 Context, Storage, Line, Column, AtomGroup, AtomRank,
124 /*HasIRLayers=*/IRLayers != nullptr, Ops, ImplicitCode),
125 Storage, Context.pImpl->DILocations);
126}
127
128DILayerLoc *DILayerLoc::getImpl(LLVMContext &Context, MDString *Kind,
129 Metadata *File, unsigned Line, unsigned Column,
130 StorageType Storage, bool ShouldCreate) {
131 // Clamp an out-of-range column to 0 (the 16-bit SubclassData limit), as
132 // DILocation::getImpl does; the ctor otherwise asserts and release builds
133 // truncate.
134 adjustColumn(Column);
135 if (Storage == Uniqued) {
136 if (auto *N = getUniqued(Context.pImpl->DILayerLocs,
137 DILayerLocInfo::KeyTy(Kind, File, Line, Column)))
138 return N;
139 if (!ShouldCreate)
140 return nullptr;
141 }
142 Metadata *Ops[] = {Kind, File};
143 return storeImpl(new (std::size(Ops), Storage)
144 DILayerLoc(Context, Storage, Line, Column, Ops),
145 Storage, Context.pImpl->DILayerLocs);
146}
147
148DILayerLocList *DILayerLocList::getImpl(LLVMContext &Context,
150 StorageType Storage,
151 bool ShouldCreate) {
152 unsigned Hash = 0;
153 if (Storage == Uniqued) {
154 DILayerLocListInfo::KeyTy Key(Layers);
155 if (auto *N = getUniqued(Context.pImpl->DILayerLocLists, Key))
156 return N;
157 if (!ShouldCreate)
158 return nullptr;
159 Hash = Key.getHash();
160 } else {
161 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
162 }
163 return storeImpl(new (Layers.size(), Storage)
164 DILayerLocList(Context, Storage, Hash, Layers),
165 Storage, Context.pImpl->DILayerLocLists);
166}
167
168void DILayerLocList::recalculateHash() {
169 setHash(DILayerLocListInfo::KeyTy::calculateHash(this));
170}
171
173 if (Locs.empty())
174 return nullptr;
175 if (Locs.size() == 1)
176 return Locs[0];
177 auto *Merged = Locs[0];
178 for (DILocation *L : llvm::drop_begin(Locs)) {
179 Merged = getMergedLocation(Merged, L);
180 if (Merged == nullptr)
181 break;
182 }
183 return Merged;
184}
185
187 DIScope *NewParent) {
188 TempMDNode ClonedScope = LBB->clone();
189 cast<DILexicalBlockBase>(*ClonedScope).replaceScope(NewParent);
191 MDNode::replaceWithUniqued(std::move(ClonedScope)));
192}
193
194using LineColumn = std::pair<unsigned /* Line */, unsigned /* Column */>;
195
196/// Returns the location of DILocalScope, if present, or a default value.
198 assert(isa<DILocalScope>(S) && "Expected DILocalScope.");
199
201 return Default;
202 if (auto *LB = dyn_cast<DILexicalBlock>(S))
203 return {LB->getLine(), LB->getColumn()};
204 if (auto *SP = dyn_cast<DISubprogram>(S))
205 return {SP->getLine(), 0u};
206
207 llvm_unreachable("Unhandled type of DILocalScope.");
208}
209
210// Returns the nearest matching scope inside a subprogram.
211template <typename MatcherT>
212static std::pair<DIScope *, LineColumn>
214 MatcherT Matcher;
215
216 DIScope *S1 = L1->getScope();
217 DIScope *S2 = L2->getScope();
218
219 LineColumn Loc1(L1->getLine(), L1->getColumn());
220 for (; S1; S1 = S1->getScope()) {
221 Loc1 = getLocalScopeLocationOr(S1, Loc1);
222 Matcher.insert(S1, Loc1);
224 break;
225 }
226
227 LineColumn Loc2(L2->getLine(), L2->getColumn());
228 for (; S2; S2 = S2->getScope()) {
229 Loc2 = getLocalScopeLocationOr(S2, Loc2);
230
231 if (DIScope *S = Matcher.match(S2, Loc2))
232 return std::make_pair(S, Loc2);
233
234 if (isa<DISubprogram>(S2))
235 break;
236 }
237 return std::make_pair(nullptr, LineColumn(L2->getLine(), L2->getColumn()));
238}
239
240// Matches equal scopes.
243
244 void insert(DIScope *S, LineColumn Loc) { Scopes.insert(S); }
245
247 return Scopes.contains(S) ? S : nullptr;
248 }
249};
250
251// Matches scopes with the same location.
254 8>
256
258 Scopes[{S->getFile(), Loc}].insert(S);
259 }
260
262 auto ScopesAtLoc = Scopes.find({S->getFile(), Loc});
263 // No scope found with the given location.
264 if (ScopesAtLoc == Scopes.end())
265 return nullptr;
266
267 // Prefer S over other scopes with the same location.
268 if (ScopesAtLoc->second.contains(S))
269 return S;
270
271 if (!ScopesAtLoc->second.empty())
272 return *ScopesAtLoc->second.begin();
273
274 llvm_unreachable("Scopes must not have empty entries.");
275 }
276};
277
278// Returns a uniqued DILayerLocList holding the intersection of LocA's and
279// LocB's layer sets, or null if either has no layers or they share none.
280// Entries keep LocA's relative order: LLVM assigns no meaning to layer order,
281// but it is part of a list's identity and visible to consumers, so preserve
282// rather than sort.
284 const DILocation *LocB) {
285 DILayerLocList *LA = LocA->getIRLayers();
286 DILayerLocList *LB = LocB->getIRLayers();
287 if (!LA || !LB)
288 return nullptr;
289 // Entries match on their fields rather than by pointer: DILayerLocs are
290 // uniqued, but `distinct` ones are legal and must not look disjoint. Keying
291 // on the fields also keeps the intersection linear in the two list lengths.
292 using LayerKey = std::tuple<Metadata *, Metadata *, unsigned, unsigned>;
293 auto keyOf = [](const DILayerLoc *L) {
294 return LayerKey(L->getRawKind(), L->getRawFile(), L->getLine(),
295 L->getColumn());
296 };
298 for (const MDOperand &Op : LB->layers())
299 BLayers.insert(keyOf(cast<DILayerLoc>(Op.get())));
301 for (const MDOperand &Op : LA->layers()) {
302 auto *L = cast<DILayerLoc>(Op.get());
303 if (BLayers.contains(keyOf(L)))
304 Keep.push_back(L);
305 }
306 if (Keep.empty())
307 return nullptr;
308 return DILayerLocList::get(C, Keep);
309}
310
311DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) {
312 if (LocA == LocB)
313 return LocA;
314
315 // For some use cases (SamplePGO), it is important to retain distinct source
316 // locations. When this flag is set, we choose arbitrarily between A and B,
317 // rather than computing a merged location using line 0, which is typically
318 // not useful for PGO. If one of them is null, then try to return one which is
319 // valid.
321 if (!LocA || !LocB)
322 return LocA ? LocA : LocB;
323
324 auto A = std::make_tuple(LocA->getLine(), LocA->getColumn(),
325 LocA->getDiscriminator(), LocA->getFilename(),
326 LocA->getDirectory());
327 auto B = std::make_tuple(LocB->getLine(), LocB->getColumn(),
328 LocB->getDiscriminator(), LocB->getFilename(),
329 LocB->getDirectory());
330 return A < B ? LocA : LocB;
331 }
332
333 if (!LocA || !LocB)
334 return nullptr;
335
336 LLVMContext &C = LocA->getContext();
337
338 using LocVec = SmallVector<const DILocation *>;
339 LocVec ALocs;
340 LocVec BLocs;
342 4>
343 ALookup;
344
345 // Walk through LocA and its inlined-at locations, populate them in ALocs and
346 // save the index for the subprogram and inlined-at pair, which we use to find
347 // a matching starting location in LocB's chain.
348 for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) {
349 ALocs.push_back(L);
350 auto Res = ALookup.try_emplace(
351 {L->getScope()->getSubprogram(), L->getInlinedAt()}, I);
352 assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?");
353 (void)Res;
354 }
355
356 LocVec::reverse_iterator ARIt = ALocs.rend();
357 LocVec::reverse_iterator BRIt = BLocs.rend();
358
359 // Populate BLocs and look for a matching starting location, the first
360 // location with the same subprogram and inlined-at location as in LocA's
361 // chain. Since the two locations have the same inlined-at location we do
362 // not need to look at those parts of the chains.
363 for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) {
364 BLocs.push_back(L);
365
366 if (ARIt != ALocs.rend())
367 // We have already found a matching starting location.
368 continue;
369
370 auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()});
371 if (IT == ALookup.end())
372 continue;
373
374 // The + 1 is to account for the &*rev_it = &(it - 1) relationship.
375 ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1);
376 BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1);
377
378 // If we have found a matching starting location we do not need to add more
379 // locations to BLocs, since we will only look at location pairs preceding
380 // the matching starting location, and adding more elements to BLocs could
381 // invalidate the iterator that we initialized here.
382 break;
383 }
384
385 // Merge the two locations if possible, using the supplied
386 // inlined-at location for the created location.
387 auto *LocAIA = LocA->getInlinedAt();
388 auto *LocBIA = LocB->getInlinedAt();
389 auto MergeLocPair = [&C, LocAIA,
390 LocBIA](const DILocation *L1, const DILocation *L2,
391 DILocation *InlinedAt) -> DILocation * {
392 if (L1 == L2)
393 return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(),
394 InlinedAt, L1->isImplicitCode(),
395 L1->getAtomGroup(), L1->getAtomRank(),
396 L1->getRawIRLayers());
397
398 // If the locations originate from different subprograms we can't produce
399 // a common location.
400 if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())
401 return nullptr;
402
403 // Each merged location keeps the intersection of the two inputs'
404 // intermediate-IR layer sets, so a layer common to both survives.
405 Metadata *MergedLayers = mergeIRLayers(C, L1, L2);
406
407 // Find nearest common scope inside subprogram.
409 assert(Scope && "No common scope in the same subprogram?");
410
411 // Try using the nearest scope with common location if files are different.
412 if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile()) {
413 auto [CommonLocScope, CommonLoc] =
415
416 // If CommonLocScope is a DILexicalBlockBase, clone it and locate
417 // a new scope inside the nearest common scope to preserve
418 // lexical blocks structure.
419 if (auto *LBB = dyn_cast<DILexicalBlockBase>(CommonLocScope);
420 LBB && LBB != Scope)
421 CommonLocScope = cloneAndReplaceParentScope(LBB, Scope);
422
423 Scope = CommonLocScope;
424
425 // If files are still different, assume that L1 and L2 were "included"
426 // from CommonLoc. Use it as merged location.
427 if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile())
428 return DILocation::get(C, CommonLoc.first, CommonLoc.second,
429 CommonLocScope, InlinedAt,
430 /*ImplicitCode=*/false, /*AtomGroup=*/0,
431 /*AtomRank=*/0, MergedLayers);
432 }
433
434 bool SameLine = L1->getLine() == L2->getLine();
435 bool SameCol = L1->getColumn() == L2->getColumn();
436 unsigned Line = SameLine ? L1->getLine() : 0;
437 unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;
438 bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode();
439
440 // Discard source location atom if the line becomes 0. And there's nothing
441 // further to do if neither location has an atom number.
442 if (!SameLine || !(L1->getAtomGroup() || L2->getAtomGroup()))
443 return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
444 /*AtomGroup*/ 0, /*AtomRank*/ 0, MergedLayers);
445
446 uint64_t Group = 0;
447 uint64_t Rank = 0;
448 // If we're preserving the same matching inlined-at field we can
449 // preserve the atom.
450 if (LocBIA == LocAIA && InlinedAt == LocBIA) {
451 // Deterministically keep the lowest non-zero ranking atom group
452 // number.
453 // FIXME: It would be nice if we could track that an instruction
454 // belongs to two source atoms.
455 bool UseL1Atom = [L1, L2]() {
456 if (L1->getAtomRank() == L2->getAtomRank()) {
457 // Arbitrarily choose the lowest non-zero group number.
458 if (!L1->getAtomGroup() || !L2->getAtomGroup())
459 return !L2->getAtomGroup();
460 return L1->getAtomGroup() < L2->getAtomGroup();
461 }
462 // Choose the lowest non-zero rank.
463 if (!L1->getAtomRank() || !L2->getAtomRank())
464 return !L2->getAtomRank();
465 return L1->getAtomRank() < L2->getAtomRank();
466 }();
467 Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup();
468 Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank();
469 } else {
470 // If either instruction is part of a source atom, reassign it a new
471 // atom group. This essentially regresses to non-key-instructions
472 // behaviour (now that it's the only instruction in its group it'll
473 // probably get is_stmt applied).
474 Group = C.incNextDILocationAtomGroup();
475 Rank = 1;
476 }
477 return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
478 Group, Rank, MergedLayers);
479 };
480
481 DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr;
482
483 // If we have found a common starting location, walk up the inlined-at chains
484 // and try to produce common locations.
485 for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {
486 DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);
487
488 if (!Tmp)
489 // We have walked up to a point in the chains where the two locations
490 // are irreconsilable. At this point Result contains the nearest common
491 // location in the inlined-at chains of LocA and LocB, so we break here.
492 break;
493
494 Result = Tmp;
495 }
496
497 if (Result)
498 return Result;
499
500 // We ended up with LocA and LocB as irreconsilable locations. Produce a
501 // location at 0:0 with one of the locations' scope. The function has
502 // historically picked A's scope, and a nullptr inlined-at location, so that
503 // behavior is mimicked here but I am not sure if this is always the correct
504 // way to handle this.
505 // Key Instructions: it's fine to drop atom group and rank here, as line 0
506 // is a nonsensical is_stmt location.
507 return DILocation::get(C, 0, 0, LocA->getScope(), nullptr, false,
508 /*AtomGroup*/ 0, /*AtomRank*/ 0);
509}
510
511std::optional<unsigned>
512DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
513 std::array<unsigned, 3> Components = {BD, DF, CI};
514 uint64_t RemainingWork = 0U;
515 // We use RemainingWork to figure out if we have no remaining components to
516 // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
517 // encode anything for the latter 2.
518 // Since any of the input components is at most 32 bits, their sum will be
519 // less than 34 bits, and thus RemainingWork won't overflow.
520 RemainingWork =
521 std::accumulate(Components.begin(), Components.end(), RemainingWork);
522
523 int I = 0;
524 unsigned Ret = 0;
525 unsigned NextBitInsertionIndex = 0;
526 while (RemainingWork > 0) {
527 unsigned C = Components[I++];
528 RemainingWork -= C;
529 unsigned EC = encodeComponent(C);
530 Ret |= (EC << NextBitInsertionIndex);
531 NextBitInsertionIndex += encodingBits(C);
532 }
533
534 // Encoding may be unsuccessful because of overflow. We determine success by
535 // checking equivalence of components before & after encoding. Alternatively,
536 // we could determine Success during encoding, but the current alternative is
537 // simpler.
538 unsigned TBD, TDF, TCI = 0;
539 decodeDiscriminator(Ret, TBD, TDF, TCI);
540 if (TBD == BD && TDF == DF && TCI == CI)
541 return Ret;
542 return std::nullopt;
543}
544
553
555 return StringSwitch<DIFlags>(Flag)
556#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
557#include "llvm/IR/DebugInfoFlags.def"
558 .Default(DINode::FlagZero);
559}
560
562 switch (Flag) {
563#define HANDLE_DI_FLAG(ID, NAME) \
564 case Flag##NAME: \
565 return "DIFlag" #NAME;
566#include "llvm/IR/DebugInfoFlags.def"
567 }
568 return "";
569}
570
572 SmallVectorImpl<DIFlags> &SplitFlags) {
573 // Flags that are packed together need to be specially handled, so
574 // that, for example, we emit "DIFlagPublic" and not
575 // "DIFlagPrivate | DIFlagProtected".
576 if (DIFlags A = Flags & FlagAccessibility) {
577 if (A == FlagPrivate)
578 SplitFlags.push_back(FlagPrivate);
579 else if (A == FlagProtected)
580 SplitFlags.push_back(FlagProtected);
581 else
582 SplitFlags.push_back(FlagPublic);
583 Flags &= ~A;
584 }
585 if (DIFlags R = Flags & FlagPtrToMemberRep) {
586 if (R == FlagSingleInheritance)
587 SplitFlags.push_back(FlagSingleInheritance);
588 else if (R == FlagMultipleInheritance)
589 SplitFlags.push_back(FlagMultipleInheritance);
590 else
591 SplitFlags.push_back(FlagVirtualInheritance);
592 Flags &= ~R;
593 }
594 if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
595 Flags &= ~FlagIndirectVirtualBase;
596 SplitFlags.push_back(FlagIndirectVirtualBase);
597 }
598
599#define HANDLE_DI_FLAG(ID, NAME) \
600 if (DIFlags Bit = Flags & Flag##NAME) { \
601 SplitFlags.push_back(Bit); \
602 Flags &= ~Bit; \
603 }
604#include "llvm/IR/DebugInfoFlags.def"
605 return Flags;
606}
607
609 if (auto *T = dyn_cast<DIType>(this))
610 return T->getScope();
611
612 if (auto *SP = dyn_cast<DISubprogram>(this))
613 return SP->getScope();
614
615 if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
616 return LB->getScope();
617
618 if (auto *NS = dyn_cast<DINamespace>(this))
619 return NS->getScope();
620
621 if (auto *CB = dyn_cast<DICommonBlock>(this))
622 return CB->getScope();
623
624 if (auto *M = dyn_cast<DIModule>(this))
625 return M->getScope();
626
627 assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
628 "Unhandled type of scope.");
629 return nullptr;
630}
631
633 if (auto *T = dyn_cast<DIType>(this))
634 return T->getName();
635 if (auto *SP = dyn_cast<DISubprogram>(this))
636 return SP->getName();
637 if (auto *NS = dyn_cast<DINamespace>(this))
638 return NS->getName();
639 if (auto *CB = dyn_cast<DICommonBlock>(this))
640 return CB->getName();
641 if (auto *M = dyn_cast<DIModule>(this))
642 return M->getName();
644 isa<DICompileUnit>(this)) &&
645 "Unhandled type of scope.");
646 return "";
647}
648
649#ifndef NDEBUG
650static bool isCanonical(const MDString *S) {
651 return !S || !S->getString().empty();
652}
653#endif
654
656GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
657 MDString *Header,
658 ArrayRef<Metadata *> DwarfOps,
659 StorageType Storage, bool ShouldCreate) {
660 unsigned Hash = 0;
661 if (Storage == Uniqued) {
662 GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);
663 if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))
664 return N;
665 if (!ShouldCreate)
666 return nullptr;
667 Hash = Key.getHash();
668 } else {
669 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
670 }
671
672 // Use a nullptr for empty headers.
673 assert(isCanonical(Header) && "Expected canonical MDString");
674 Metadata *PreOps[] = {Header};
675 return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(
676 Context, Storage, Hash, Tag, PreOps, DwarfOps),
677 Storage, Context.pImpl->GenericDINodes);
678}
679
680void GenericDINode::recalculateHash() {
681 setHash(GenericDINodeInfo::KeyTy::calculateHash(this));
682}
683
684#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
685#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
686#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \
687 do { \
688 if (Storage == Uniqued) { \
689 if (auto *N = getUniqued(Context.pImpl->CLASS##s, \
690 CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \
691 return N; \
692 if (!ShouldCreate) \
693 return nullptr; \
694 } else { \
695 assert(ShouldCreate && \
696 "Expected non-uniqued nodes to always be created"); \
697 } \
698 } while (false)
699#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \
700 return storeImpl(new (std::size(OPS), Storage) \
701 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
702 Storage, Context.pImpl->CLASS##s)
703#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \
704 return storeImpl(new (0u, Storage) \
705 CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
706 Storage, Context.pImpl->CLASS##s)
707#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \
708 return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \
709 Storage, Context.pImpl->CLASS##s)
710#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \
711 return storeImpl(new (NUM_OPS, Storage) \
712 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
713 Storage, Context.pImpl->CLASS##s)
714
715DISubrange::DISubrange(LLVMContext &C, StorageType Storage,
717 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
718DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
719 StorageType Storage, bool ShouldCreate) {
722 auto *LB = ConstantAsMetadata::get(
724 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
725 ShouldCreate);
726}
727
728DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
729 int64_t Lo, StorageType Storage,
730 bool ShouldCreate) {
731 auto *LB = ConstantAsMetadata::get(
733 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
734 ShouldCreate);
735}
736
737DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
738 Metadata *LB, Metadata *UB, Metadata *Stride,
739 StorageType Storage, bool ShouldCreate) {
740 DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride));
741 Metadata *Ops[] = {CountNode, LB, UB, Stride};
743}
744
745DISubrange::BoundType DISubrange::getCount() const {
746 Metadata *CB = getRawCountNode();
747 if (!CB)
748 return BoundType();
749
751 isa<DIExpression>(CB)) &&
752 "Count must be signed constant or DIVariable or DIExpression");
753
754 if (auto *MD = dyn_cast<ConstantAsMetadata>(CB))
755 return BoundType(cast<ConstantInt>(MD->getValue()));
756
757 if (auto *MD = dyn_cast<DIVariable>(CB))
758 return BoundType(MD);
759
760 if (auto *MD = dyn_cast<DIExpression>(CB))
761 return BoundType(MD);
762
763 return BoundType();
764}
765
766DISubrange::BoundType DISubrange::getLowerBound() const {
767 Metadata *LB = getRawLowerBound();
768 if (!LB)
769 return BoundType();
770
772 isa<DIExpression>(LB)) &&
773 "LowerBound must be signed constant or DIVariable or DIExpression");
774
775 if (auto *MD = dyn_cast<ConstantAsMetadata>(LB))
776 return BoundType(cast<ConstantInt>(MD->getValue()));
777
778 if (auto *MD = dyn_cast<DIVariable>(LB))
779 return BoundType(MD);
780
781 if (auto *MD = dyn_cast<DIExpression>(LB))
782 return BoundType(MD);
783
784 return BoundType();
785}
786
787DISubrange::BoundType DISubrange::getUpperBound() const {
788 Metadata *UB = getRawUpperBound();
789 if (!UB)
790 return BoundType();
791
793 isa<DIExpression>(UB)) &&
794 "UpperBound must be signed constant or DIVariable or DIExpression");
795
796 if (auto *MD = dyn_cast<ConstantAsMetadata>(UB))
797 return BoundType(cast<ConstantInt>(MD->getValue()));
798
799 if (auto *MD = dyn_cast<DIVariable>(UB))
800 return BoundType(MD);
801
802 if (auto *MD = dyn_cast<DIExpression>(UB))
803 return BoundType(MD);
804
805 return BoundType();
806}
807
808DISubrange::BoundType DISubrange::getStride() const {
809 Metadata *ST = getRawStride();
810 if (!ST)
811 return BoundType();
812
814 isa<DIExpression>(ST)) &&
815 "Stride must be signed constant or DIVariable or DIExpression");
816
817 if (auto *MD = dyn_cast<ConstantAsMetadata>(ST))
818 return BoundType(cast<ConstantInt>(MD->getValue()));
819
820 if (auto *MD = dyn_cast<DIVariable>(ST))
821 return BoundType(MD);
822
823 if (auto *MD = dyn_cast<DIExpression>(ST))
824 return BoundType(MD);
825
826 return BoundType();
827}
828DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,
830 : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
831 Ops) {}
832
833DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
834 Metadata *CountNode, Metadata *LB,
835 Metadata *UB, Metadata *Stride,
836 StorageType Storage,
837 bool ShouldCreate) {
838 DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
839 Metadata *Ops[] = {CountNode, LB, UB, Stride};
841}
842
845 if (!CB)
846 return BoundType();
847
849 "Count must be signed constant or DIVariable or DIExpression");
850
851 if (auto *MD = dyn_cast<DIVariable>(CB))
852 return BoundType(MD);
853
854 if (auto *MD = dyn_cast<DIExpression>(CB))
855 return BoundType(MD);
856
857 return BoundType();
858}
859
862 if (!LB)
863 return BoundType();
864
866 "LowerBound must be signed constant or DIVariable or DIExpression");
867
868 if (auto *MD = dyn_cast<DIVariable>(LB))
869 return BoundType(MD);
870
871 if (auto *MD = dyn_cast<DIExpression>(LB))
872 return BoundType(MD);
873
874 return BoundType();
875}
876
879 if (!UB)
880 return BoundType();
881
883 "UpperBound must be signed constant or DIVariable or DIExpression");
884
885 if (auto *MD = dyn_cast<DIVariable>(UB))
886 return BoundType(MD);
887
888 if (auto *MD = dyn_cast<DIExpression>(UB))
889 return BoundType(MD);
890
891 return BoundType();
892}
893
895 Metadata *ST = getRawStride();
896 if (!ST)
897 return BoundType();
898
900 "Stride must be signed constant or DIVariable or DIExpression");
901
902 if (auto *MD = dyn_cast<DIVariable>(ST))
903 return BoundType(MD);
904
905 if (auto *MD = dyn_cast<DIExpression>(ST))
906 return BoundType(MD);
907
908 return BoundType();
909}
910
911DISubrangeType::DISubrangeType(LLVMContext &C, StorageType Storage,
912 unsigned Line, uint32_t AlignInBits,
913 DIFlags Flags, ArrayRef<Metadata *> Ops)
914 : DIType(C, DISubrangeTypeKind, Storage, dwarf::DW_TAG_subrange_type, Line,
915 AlignInBits, 0, Flags, Ops) {}
916
917DISubrangeType *DISubrangeType::getImpl(
918 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
919 Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags,
920 Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
921 Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate) {
922 assert(isCanonical(Name) && "Expected canonical MDString");
924 AlignInBits, Flags, BaseType,
926 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr,
928 DEFINE_GETIMPL_STORE(DISubrangeType, (Line, AlignInBits, Flags), Ops);
929}
930
932DISubrangeType::convertRawToBound(Metadata *IN) const {
933 if (!IN)
934 return BoundType();
935
938
939 if (auto *MD = dyn_cast<ConstantAsMetadata>(IN))
940 return BoundType(cast<ConstantInt>(MD->getValue()));
941
942 if (auto *MD = dyn_cast<DIVariable>(IN))
943 return BoundType(MD);
944
945 if (auto *MD = dyn_cast<DIExpression>(IN))
946 return BoundType(MD);
947
948 if (auto *DT = dyn_cast<DIDerivedType>(IN))
949 return BoundType(DT);
950
951 return BoundType();
952}
953
954DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,
955 const APInt &Value, bool IsUnsigned,
957 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
958 Value(Value) {
959 SubclassData32 = IsUnsigned;
960}
961DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
962 bool IsUnsigned, MDString *Name,
963 StorageType Storage, bool ShouldCreate) {
964 assert(isCanonical(Name) && "Expected canonical MDString");
965 DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
966 Metadata *Ops[] = {Name};
967 DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
968}
969
972 unsigned LineNo, Metadata *Scope,
974 unsigned Encoding,
976 uint32_t DataSizeInBits, DIFlags Flags,
977 StorageType Storage, bool ShouldCreate) {
978 assert(isCanonical(Name) && "Expected canonical MDString");
981 Encoding, NumExtraInhabitants, DataSizeInBits, Flags));
982 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr};
985 DataSizeInBits, Flags),
986 Ops);
987}
988
989std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
990 switch (getEncoding()) {
991 case dwarf::DW_ATE_signed:
992 case dwarf::DW_ATE_signed_char:
993 case dwarf::DW_ATE_signed_fixed:
994 return Signedness::Signed;
995 case dwarf::DW_ATE_unsigned:
996 case dwarf::DW_ATE_unsigned_char:
997 case dwarf::DW_ATE_unsigned_fixed:
999 default:
1000 return std::nullopt;
1001 }
1002}
1003
1005DIFixedPointType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
1006 Metadata *File, unsigned LineNo, Metadata *Scope,
1007 Metadata *SizeInBits, uint32_t AlignInBits,
1008 unsigned Encoding, DIFlags Flags, unsigned Kind,
1009 int Factor, APInt Numerator, APInt Denominator,
1010 StorageType Storage, bool ShouldCreate) {
1012 (Tag, Name, File, LineNo, Scope, SizeInBits,
1013 AlignInBits, Encoding, Flags, Kind, Factor, Numerator,
1014 Denominator));
1015 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr};
1017 (Tag, LineNo, AlignInBits, Encoding, Flags, Kind, Factor,
1019 Ops);
1020}
1021
1023 return getEncoding() == dwarf::DW_ATE_signed_fixed;
1024}
1025
1026std::optional<DIFixedPointType::FixedPointKind>
1029 .Case("Binary", FixedPointBinary)
1030 .Case("Decimal", FixedPointDecimal)
1031 .Case("Rational", FixedPointRational)
1032 .Default(std::nullopt);
1033}
1034
1036 switch (V) {
1037 case FixedPointBinary:
1038 return "Binary";
1039 case FixedPointDecimal:
1040 return "Decimal";
1041 case FixedPointRational:
1042 return "Rational";
1043 }
1044 return nullptr;
1045}
1046
1047DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
1048 MDString *Name, Metadata *StringLength,
1049 Metadata *StringLengthExp,
1050 Metadata *StringLocationExp,
1051 Metadata *SizeInBits, uint32_t AlignInBits,
1052 unsigned Encoding, Metadata *CharType,
1053 StorageType Storage, bool ShouldCreate) {
1054 assert(isCanonical(Name) && "Expected canonical MDString");
1057 AlignInBits, Encoding, CharType));
1058 Metadata *Ops[] = {nullptr, nullptr, Name,
1059 SizeInBits, nullptr, StringLength,
1062}
1064 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
1066}
1067
1068// Helper function to extract ConstantAsMetadata from ExtraData,
1069// handling extra data MDTuple unwrapping if needed.
1071 Metadata *ED = ExtraData;
1072 if (auto *Tuple = dyn_cast_or_null<MDTuple>(ED)) {
1073 if (Tuple->getNumOperands() != 1)
1074 return nullptr;
1075 ED = Tuple->getOperand(0);
1076 }
1078}
1079
1081 assert(getTag() == dwarf::DW_TAG_inheritance);
1082 if (auto *CM = extractConstantMetadata(getExtraData()))
1083 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
1084 return static_cast<uint32_t>(CI->getZExtValue());
1085 return 0;
1086}
1088 assert(getTag() == dwarf::DW_TAG_member && isBitField());
1089 if (auto *C = extractConstantMetadata(getExtraData()))
1090 return C->getValue();
1091 return nullptr;
1092}
1093
1095 assert((getTag() == dwarf::DW_TAG_member ||
1096 getTag() == dwarf::DW_TAG_variable) &&
1097 isStaticMember());
1098 if (auto *C = extractConstantMetadata(getExtraData()))
1099 return C->getValue();
1100 return nullptr;
1101}
1103 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
1104 if (auto *C = extractConstantMetadata(getExtraData()))
1105 return C->getValue();
1106 return nullptr;
1107}
1108
1109DIDerivedType *DIDerivedType::getImpl(
1110 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1111 unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
1112 uint32_t AlignInBits, Metadata *OffsetInBits,
1113 std::optional<unsigned> DWARFAddressSpace,
1114 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData,
1115 Metadata *Annotations, StorageType Storage, bool ShouldCreate) {
1116 assert(isCanonical(Name) && "Expected canonical MDString");
1118 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1120 PtrAuthData, Flags, ExtraData, Annotations));
1121 Metadata *Ops[] = {File, Scope, Name, SizeInBits,
1122 OffsetInBits, BaseType, ExtraData, Annotations};
1125 (Tag, Line, AlignInBits, DWARFAddressSpace, PtrAuthData, Flags), Ops);
1126}
1127
1128std::optional<DIDerivedType::PtrAuthData>
1129DIDerivedType::getPtrAuthData() const {
1130 return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type
1131 ? std::make_optional<PtrAuthData>(SubclassData32)
1132 : std::nullopt;
1133}
1134
1135DICompositeType *DICompositeType::getImpl(
1136 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1137 unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
1138 uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags,
1139 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1140 Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
1141 Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
1142 Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
1143 Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride,
1144 StorageType Storage, bool ShouldCreate) {
1145 assert(isCanonical(Name) && "Expected canonical MDString");
1146
1147 // Keep this in sync with buildODRType.
1149 DICompositeType,
1159 DEFINE_GETIMPL_STORE(DICompositeType,
1160 (Tag, Line, RuntimeLang, AlignInBits,
1161 NumExtraInhabitants, EnumKind, Flags),
1162 Ops);
1163}
1164
1166 LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
1170 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1174 assert(!Identifier.getString().empty() && "Expected valid identifier");
1175 if (!Context.isODRUniquingDebugTypes())
1176 return nullptr;
1177 auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
1178 if (!CT)
1179 return CT = DICompositeType::getDistinct(
1180 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1181 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
1185 if (CT->getTag() != Tag)
1186 return nullptr;
1187
1188 // Only mutate CT if it's a forward declaration and the new operands aren't.
1189 assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
1190 if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))
1191 return CT;
1192
1193 // Mutate CT in place. Keep this in sync with getImpl.
1194 CT->mutate(Tag, Line, RuntimeLang, AlignInBits, NumExtraInhabitants, EnumKind,
1195 Flags);
1201 assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
1202 "Mismatched number of operands");
1203 for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
1204 if (Ops[I] != CT->getOperand(I))
1205 CT->setOperand(I, Ops[I]);
1206 return CT;
1207}
1208
1209DICompositeType *DICompositeType::getODRType(
1210 LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
1211 Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
1212 Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
1213 Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
1214 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1215 Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
1216 Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1217 Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
1218 assert(!Identifier.getString().empty() && "Expected valid identifier");
1219 if (!Context.isODRUniquingDebugTypes())
1220 return nullptr;
1221 auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
1222 if (!CT) {
1224 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1229 } else {
1230 if (CT->getTag() != Tag)
1231 return nullptr;
1232 }
1233 return CT;
1234}
1235
1238 assert(!Identifier.getString().empty() && "Expected valid identifier");
1239 if (!Context.isODRUniquingDebugTypes())
1240 return nullptr;
1241 return Context.pImpl->DITypeMap->lookup(&Identifier);
1242}
1243DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
1244 DIFlags Flags, uint8_t CC,
1246 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
1247 0, 0, Flags, Ops),
1248 CC(CC) {}
1249
1250DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
1251 uint8_t CC, Metadata *TypeArray,
1252 StorageType Storage,
1253 bool ShouldCreate) {
1255 Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr, nullptr, TypeArray};
1256 DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
1257}
1258
1259DIFile::DIFile(LLVMContext &C, StorageType Storage,
1260 std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,
1262 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
1263 Checksum(CS), Source(Src) {}
1264
1265// FIXME: Implement this string-enum correspondence with a .def file and macros,
1266// so that the association is explicit rather than implied.
1267static const char *ChecksumKindName[DIFile::CSK_Last] = {
1268 "CSK_MD5",
1269 "CSK_SHA1",
1270 "CSK_SHA256",
1271};
1272
1273StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
1274 assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
1275 // The first space was originally the CSK_None variant, which is now
1276 // obsolete, but the space is still reserved in ChecksumKind, so we account
1277 // for it here.
1278 return ChecksumKindName[CSKind - 1];
1279}
1280
1281std::optional<DIFile::ChecksumKind>
1284 .Case("CSK_MD5", DIFile::CSK_MD5)
1285 .Case("CSK_SHA1", DIFile::CSK_SHA1)
1286 .Case("CSK_SHA256", DIFile::CSK_SHA256)
1287 .Default(std::nullopt);
1288}
1289
1290DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
1291 MDString *Directory,
1292 std::optional<DIFile::ChecksumInfo<MDString *>> CS,
1293 MDString *Source, StorageType Storage,
1294 bool ShouldCreate) {
1295 assert(isCanonical(Filename) && "Expected canonical MDString");
1296 assert(isCanonical(Directory) && "Expected canonical MDString");
1297 assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
1298 // We do *NOT* expect Source to be a canonical MDString because nullptr
1299 // means none, so we need something to represent the empty file.
1301 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source};
1303}
1304DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
1305 DISourceLanguageName SourceLanguage,
1306 bool IsOptimized, unsigned RuntimeVersion,
1307 unsigned EmissionKind, uint64_t DWOId,
1308 bool SplitDebugInlining,
1309 bool DebugInfoForProfiling, unsigned NameTableKind,
1310 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
1311 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
1312 SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion),
1314 IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),
1315 DebugInfoForProfiling(DebugInfoForProfiling),
1316 RangesBaseAddress(RangesBaseAddress) {
1318}
1319
1320DICompileUnit *DICompileUnit::getImpl(
1321 LLVMContext &Context, DISourceLanguageName SourceLanguage, Metadata *File,
1322 MDString *Producer, bool IsOptimized, MDString *Flags,
1323 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1324 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1325 Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
1326 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1327 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
1328 MDString *SDK, StorageType Storage, bool ShouldCreate) {
1329 assert(Storage != Uniqued && "Cannot unique DICompileUnit");
1330 assert(isCanonical(Producer) && "Expected canonical MDString");
1331 assert(isCanonical(Flags) && "Expected canonical MDString");
1332 assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
1333
1334 Metadata *Ops[] = {File,
1335 Producer,
1336 Flags,
1338 EnumTypes,
1342 Macros,
1343 SysRoot,
1344 SDK};
1345 return storeImpl(new (std::size(Ops), Storage) DICompileUnit(
1346 Context, Storage, SourceLanguage, IsOptimized,
1347 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
1348 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
1349 Ops),
1350 Storage);
1351}
1352
1353std::optional<DICompileUnit::DebugEmissionKind>
1356 .Case("NoDebug", NoDebug)
1357 .Case("FullDebug", FullDebug)
1358 .Case("LineTablesOnly", LineTablesOnly)
1359 .Case("DebugDirectivesOnly", DebugDirectivesOnly)
1360 .Default(std::nullopt);
1361}
1362
1363std::optional<DICompileUnit::DebugNameTableKind>
1372
1374 switch (EK) {
1375 case NoDebug:
1376 return "NoDebug";
1377 case FullDebug:
1378 return "FullDebug";
1379 case LineTablesOnly:
1380 return "LineTablesOnly";
1382 return "DebugDirectivesOnly";
1383 }
1384 return nullptr;
1385}
1386
1388 switch (NTK) {
1390 return nullptr;
1392 return "GNU";
1394 return "Apple";
1396 return "None";
1397 }
1398 return nullptr;
1399}
1400DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
1401 unsigned ScopeLine, unsigned VirtualIndex,
1402 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
1403 bool UsesKeyInstructions, ArrayRef<Metadata *> Ops)
1404 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
1405 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
1406 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
1407 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
1408 SubclassData1 = UsesKeyInstructions;
1409}
1411DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
1412 unsigned Virtuality, bool IsMainSubprogram) {
1413 // We're assuming virtuality is the low-order field.
1414 static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
1415 int(SPFlagPureVirtual) ==
1416 int(dwarf::DW_VIRTUALITY_pure_virtual),
1417 "Virtuality constant mismatch");
1418 return static_cast<DISPFlags>(
1419 (Virtuality & SPFlagVirtuality) |
1420 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1421 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
1422 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1423 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
1424}
1425
1427 if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
1428 return Block->getScope()->getSubprogram();
1429 return const_cast<DISubprogram *>(cast<DISubprogram>(this));
1430}
1431
1433 if (auto *File = dyn_cast<DILexicalBlockFile>(this))
1434 return File->getScope()->getNonLexicalBlockFileScope();
1435 return const_cast<DILocalScope *>(this);
1436}
1437
1439 DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx,
1441 SmallVector<DIScope *> ScopeChain;
1442 DIScope *CachedResult = nullptr;
1443
1444 for (DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope);
1445 Scope = Scope->getScope()) {
1446 if (auto It = Cache.find(Scope); It != Cache.end()) {
1447 CachedResult = cast<DIScope>(It->second);
1448 break;
1449 }
1450 ScopeChain.push_back(Scope);
1451 }
1452
1453 // Recreate the scope chain, bottom-up, starting at the new subprogram (or a
1454 // cached result).
1455 DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;
1456 for (DIScope *ScopeToUpdate : reverse(ScopeChain)) {
1457 UpdatedScope = cloneAndReplaceParentScope(
1458 cast<DILexicalBlockBase>(ScopeToUpdate), UpdatedScope);
1459 Cache[ScopeToUpdate] = UpdatedScope;
1460 }
1461
1462 return cast<DILocalScope>(UpdatedScope);
1463}
1464
1466 return StringSwitch<DISPFlags>(Flag)
1467#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
1468#include "llvm/IR/DebugInfoFlags.def"
1469 .Default(SPFlagZero);
1470}
1471
1473 switch (Flag) {
1474 // Appease a warning.
1475 case SPFlagVirtuality:
1476 return "";
1477#define HANDLE_DISP_FLAG(ID, NAME) \
1478 case SPFlag##NAME: \
1479 return "DISPFlag" #NAME;
1480#include "llvm/IR/DebugInfoFlags.def"
1481 }
1482 return "";
1483}
1484
1487 SmallVectorImpl<DISPFlags> &SplitFlags) {
1488 // Multi-bit fields can require special handling. In our case, however, the
1489 // only multi-bit field is virtuality, and all its values happen to be
1490 // single-bit values, so the right behavior just falls out.
1491#define HANDLE_DISP_FLAG(ID, NAME) \
1492 if (DISPFlags Bit = Flags & SPFlag##NAME) { \
1493 SplitFlags.push_back(Bit); \
1494 Flags &= ~Bit; \
1495 }
1496#include "llvm/IR/DebugInfoFlags.def"
1497 return Flags;
1498}
1499
1500DISubprogram *DISubprogram::getImpl(
1501 LLVMContext &Context, Metadata *Scope, MDString *Name,
1502 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1503 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
1504 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1505 Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
1506 Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
1507 bool UsesKeyInstructions, StorageType Storage, bool ShouldCreate) {
1508 assert(isCanonical(Name) && "Expected canonical MDString");
1509 assert(isCanonical(LinkageName) && "Expected canonical MDString");
1510 assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
1512 (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
1514 SPFlags, Unit, TemplateParams, Declaration,
1518 File, Scope, Name, LinkageName,
1519 Type, Unit, Declaration, RetainedNodes,
1522 if (!TargetFuncName) {
1523 Ops.pop_back();
1524 if (!Annotations) {
1525 Ops.pop_back();
1526 if (!ThrownTypes) {
1527 Ops.pop_back();
1528 if (!TemplateParams) {
1529 Ops.pop_back();
1530 if (!ContainingType)
1531 Ops.pop_back();
1532 }
1533 }
1534 }
1535 }
1536 DEFINE_GETIMPL_STORE_N(DISubprogram,
1537 (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags,
1538 SPFlags, UsesKeyInstructions),
1539 Ops, Ops.size());
1540}
1541
1543 assert(F && "Invalid function");
1544 return F->getSubprogram() == this;
1545}
1546
1547template <typename ScopeT, typename NodeT>
1548static ScopeT getRawRetainedNodeScopeInternal(NodeT *N) {
1549 auto getScopeLambda = [](auto *N) { return getScope(N); };
1550 return DISubprogram::visitRetainedNode<ScopeT>(
1551 N, getScopeLambda, getScopeLambda, getScopeLambda, getScopeLambda,
1552 getScopeLambda, [](auto *N) { return nullptr; });
1553}
1554
1558
1562
1566
1569}
1570
1572 // Checks if a metadata node from retainedTypes is a type belonging to
1573 // this subprogram.
1574 auto IsTypeInSP = [this](Metadata *N) {
1575 auto *T = dyn_cast_or_null<DIType>(N);
1576 if (!T)
1577 return true;
1578
1579 DISubprogram *TypeSP = nullptr;
1580 // The type might have been global in the previously loaded IR modules.
1581 if (auto *LS = dyn_cast_or_null<DILocalScope>(T->getScope()))
1582 TypeSP = LS->getSubprogram();
1583
1584 return this == TypeSP;
1585 };
1586
1587 cleanupRetainedNodesIf(IsTypeInSP);
1588}
1589
1594
1595DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
1596 Metadata *File, unsigned Line,
1597 unsigned Column, StorageType Storage,
1598 bool ShouldCreate) {
1599 // Fixup column.
1601
1602 assert(Scope && "Expected scope");
1604 Metadata *Ops[] = {File, Scope};
1606}
1607
1608DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
1609 Metadata *Scope, Metadata *File,
1610 unsigned Discriminator,
1611 StorageType Storage,
1612 bool ShouldCreate) {
1613 assert(Scope && "Expected scope");
1614 DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator));
1615 Metadata *Ops[] = {File, Scope};
1616 DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);
1617}
1618
1619DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
1620 bool ExportSymbols, ArrayRef<Metadata *> Ops)
1621 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {
1622 SubclassData1 = ExportSymbols;
1623}
1624DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
1625 MDString *Name, bool ExportSymbols,
1626 StorageType Storage, bool ShouldCreate) {
1627 assert(isCanonical(Name) && "Expected canonical MDString");
1629 // The nullptr is for DIScope's File operand. This should be refactored.
1630 Metadata *Ops[] = {nullptr, Scope, Name};
1631 DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
1632}
1633
1634DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
1635 unsigned LineNo, ArrayRef<Metadata *> Ops)
1636 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
1637 Ops) {
1638 SubclassData32 = LineNo;
1639}
1640DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
1641 Metadata *Decl, MDString *Name,
1642 Metadata *File, unsigned LineNo,
1643 StorageType Storage, bool ShouldCreate) {
1644 assert(isCanonical(Name) && "Expected canonical MDString");
1645 DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo));
1646 // The nullptr is for DIScope's File operand. This should be refactored.
1647 Metadata *Ops[] = {Scope, Decl, Name, File};
1648 DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops);
1649}
1650
1651DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
1652 bool IsDecl, ArrayRef<Metadata *> Ops)
1653 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {
1654 SubclassData1 = IsDecl;
1655 SubclassData32 = LineNo;
1656}
1657DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
1658 Metadata *Scope, MDString *Name,
1659 MDString *ConfigurationMacros,
1660 MDString *IncludePath, MDString *APINotesFile,
1661 unsigned LineNo, bool IsDecl, StorageType Storage,
1662 bool ShouldCreate) {
1663 assert(isCanonical(Name) && "Expected canonical MDString");
1665 IncludePath, APINotesFile, LineNo, IsDecl));
1668 DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
1669}
1670DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,
1671 StorageType Storage,
1672 bool IsDefault,
1674 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
1675 dwarf::DW_TAG_template_type_parameter, IsDefault,
1676 Ops) {}
1677
1679DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,
1680 Metadata *Type, bool isDefault,
1681 StorageType Storage, bool ShouldCreate) {
1682 assert(isCanonical(Name) && "Expected canonical MDString");
1683 DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault));
1684 Metadata *Ops[] = {Name, Type};
1685 DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops);
1686}
1687
1688DITemplateValueParameter *DITemplateValueParameter::getImpl(
1689 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,
1690 bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {
1691 assert(isCanonical(Name) && "Expected canonical MDString");
1692 DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter,
1693 (Tag, Name, Type, isDefault, Value));
1694 Metadata *Ops[] = {Name, Type, Value};
1695 DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops);
1696}
1697
1699DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1700 MDString *LinkageName, Metadata *File, unsigned Line,
1701 Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
1702 Metadata *StaticDataMemberDeclaration,
1703 Metadata *TemplateParams, uint32_t AlignInBits,
1704 Metadata *Annotations, StorageType Storage,
1705 bool ShouldCreate) {
1706 assert(isCanonical(Name) && "Expected canonical MDString");
1707 assert(isCanonical(LinkageName) && "Expected canonical MDString");
1709 DIGlobalVariable,
1710 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
1712 Metadata *Ops[] = {Scope,
1713 Name,
1714 File,
1715 Type,
1716 Name,
1720 Annotations};
1721 DEFINE_GETIMPL_STORE(DIGlobalVariable,
1722 (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
1723}
1724
1726DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1727 Metadata *File, unsigned Line, Metadata *Type,
1728 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
1729 Metadata *Annotations, StorageType Storage,
1730 bool ShouldCreate) {
1731 // 64K ought to be enough for any frontend.
1732 assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");
1733
1734 assert(Scope && "Expected scope");
1735 assert(isCanonical(Name) && "Expected canonical MDString");
1736 DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg,
1737 Flags, AlignInBits, Annotations));
1739 DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
1740}
1741
1743 signed Line, ArrayRef<Metadata *> Ops,
1744 uint32_t AlignInBits)
1745 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {
1746 SubclassData32 = AlignInBits;
1747}
1748std::optional<uint64_t> DIVariable::getSizeInBits() const {
1749 // This is used by the Verifier so be mindful of broken types.
1750 const Metadata *RawType = getRawType();
1751 while (RawType) {
1752 // Try to get the size directly.
1753 if (auto *T = dyn_cast<DIType>(RawType))
1754 if (uint64_t Size = T->getSizeInBits())
1755 return Size;
1756
1757 if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
1758 // Look at the base type.
1759 RawType = DT->getRawBaseType();
1760 continue;
1761 }
1762
1763 // Missing type or size.
1764 break;
1765 }
1766
1767 // Fail gracefully.
1768 return std::nullopt;
1769}
1770
1771DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
1772 unsigned Column, bool IsArtificial,
1773 std::optional<unsigned> CoroSuspendIdx,
1775 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {
1776 this->SubclassData32 = Line;
1777 this->Column = Column;
1778 this->IsArtificial = IsArtificial;
1779 this->CoroSuspendIdx = CoroSuspendIdx;
1780}
1781DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1782 Metadata *File, unsigned Line, unsigned Column,
1783 bool IsArtificial,
1784 std::optional<unsigned> CoroSuspendIdx,
1785 StorageType Storage, bool ShouldCreate) {
1786 assert(Scope && "Expected scope");
1787 assert(isCanonical(Name) && "Expected canonical MDString");
1789 DILabel, (Scope, Name, File, Line, Column, IsArtificial, CoroSuspendIdx));
1790 Metadata *Ops[] = {Scope, Name, File};
1791 DEFINE_GETIMPL_STORE(DILabel, (Line, Column, IsArtificial, CoroSuspendIdx),
1792 Ops);
1793}
1794
1795DIExpression *DIExpression::getImpl(LLVMContext &Context,
1796 ArrayRef<uint64_t> Elements,
1797 StorageType Storage, bool ShouldCreate) {
1798 DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
1799 DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
1800}
1802 if (auto singleLocElts = getSingleLocationExpressionElements()) {
1803 return singleLocElts->size() > 0 &&
1804 (*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value;
1805 }
1806 return false;
1807}
1809 if (auto singleLocElts = getSingleLocationExpressionElements())
1810 return singleLocElts->size() > 0 &&
1811 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1812 return false;
1813}
1815 if (auto singleLocElts = getSingleLocationExpressionElements())
1816 return singleLocElts->size() == 1 &&
1817 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1818 return false;
1819}
1820
1821DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage,
1822 bool ShouldCreate) {
1823 // Uniqued DIAssignID are not supported as the instance address *is* the ID.
1824 assert(Storage != StorageType::Uniqued && "uniqued DIAssignID unsupported");
1825 return storeImpl(new (0u, Storage) DIAssignID(Context, Storage), Storage);
1826}
1827
1829 uint64_t Op = getOp();
1830
1831 if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)
1832 return 2;
1833
1834 switch (Op) {
1839 case dwarf::DW_OP_bregx:
1840 return 3;
1841 case dwarf::DW_OP_constu:
1842 case dwarf::DW_OP_consts:
1843 case dwarf::DW_OP_deref_size:
1844 case dwarf::DW_OP_xderef_size:
1845 case dwarf::DW_OP_plus_uconst:
1849 case dwarf::DW_OP_regx:
1850 return 2;
1851 default:
1852 return 1;
1853 }
1854}
1855
1859
1861 return Op->is(dwarf::DW_OP_LLVM_arg);
1862}
1863
1867
1872
1876
1880
1884
1888
1890 return Op->is(dwarf::DW_OP_constu);
1891}
1892
1894 return Op->is(dwarf::DW_OP_plus_uconst);
1895}
1896
1898 return Op >= dwarf::DW_OP_lit0 && Op <= dwarf::DW_OP_lit31;
1899}
1900
1902 for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
1903 // Check that there's space for the operand.
1904 if (I->getSize() > static_cast<uint64_t>(E->get() - I->get()))
1905 return false;
1906
1907 uint64_t Op = I->getOp();
1908 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
1909 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31) || isLitOp(Op))
1910 continue;
1911
1912 // Check that the operand is valid.
1913 switch (Op) {
1914 default:
1915 return false;
1917 // A fragment operator must appear at the end.
1918 return I->get() + I->getSize() == E->get();
1919 case dwarf::DW_OP_stack_value: {
1920 // Must be the last one or followed by a DW_OP_LLVM_fragment.
1921 if (I->get() + I->getSize() == E->get())
1922 break;
1923 auto J = I;
1924 if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
1925 return false;
1926 break;
1927 }
1928 case dwarf::DW_OP_swap: {
1929 // Must be more than one implicit element on the stack.
1930
1931 // FIXME: A better way to implement this would be to add a local variable
1932 // that keeps track of the stack depth and introduce something like a
1933 // DW_LLVM_OP_implicit_location as a placeholder for the location this
1934 // DIExpression is attached to, or else pass the number of implicit stack
1935 // elements into isValid.
1936 if (getNumElements() == 1)
1937 return false;
1938 break;
1939 }
1941 // An entry value operator must appear at the beginning or immediately
1942 // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
1943 // currently only be 1, because we support only entry values of a simple
1944 // register location. One reason for this is that we currently can't
1945 // calculate the size of the resulting DWARF block for other expressions.
1946 auto FirstOp = expr_op_begin();
1947 if (auto Arg = dyn_cast<ArgOp>(*FirstOp); Arg && Arg.getIndex() == 0)
1948 ++FirstOp;
1949 if (I->get() != FirstOp->get() ||
1950 cast<EntryValueOp>(*I).getNumOperations() != 1)
1951 return false;
1952 break;
1953 }
1954 case dwarf::DW_OP_deref_size:
1955 case dwarf::DW_OP_xderef_size:
1956 // The size operand is encoded as a single byte.
1957 if (!isUInt<8>(I->getArg(0)))
1958 return false;
1959 break;
1966 case dwarf::DW_OP_constu:
1967 case dwarf::DW_OP_plus_uconst:
1968 case dwarf::DW_OP_plus:
1969 case dwarf::DW_OP_minus:
1970 case dwarf::DW_OP_mul:
1971 case dwarf::DW_OP_div:
1972 case dwarf::DW_OP_mod:
1973 case dwarf::DW_OP_or:
1974 case dwarf::DW_OP_and:
1975 case dwarf::DW_OP_xor:
1976 case dwarf::DW_OP_shl:
1977 case dwarf::DW_OP_shr:
1978 case dwarf::DW_OP_shra:
1979 case dwarf::DW_OP_deref:
1980 case dwarf::DW_OP_xderef:
1981 case dwarf::DW_OP_not:
1982 case dwarf::DW_OP_dup:
1983 case dwarf::DW_OP_regx:
1984 case dwarf::DW_OP_bregx:
1985 case dwarf::DW_OP_push_object_address:
1986 case dwarf::DW_OP_over:
1987 case dwarf::DW_OP_rot:
1988 case dwarf::DW_OP_consts:
1989 case dwarf::DW_OP_eq:
1990 case dwarf::DW_OP_ne:
1991 case dwarf::DW_OP_gt:
1992 case dwarf::DW_OP_ge:
1993 case dwarf::DW_OP_lt:
1994 case dwarf::DW_OP_le:
1995 case dwarf::DW_OP_neg:
1996 case dwarf::DW_OP_abs:
1997 break;
1998 }
1999 }
2000 return true;
2001}
2002
2004 if (!isValid())
2005 return false;
2006
2007 if (getNumElements() == 0)
2008 return false;
2009
2010 for (const auto &It : expr_ops()) {
2011 switch (It.getOp()) {
2012 default:
2013 break;
2014 case dwarf::DW_OP_stack_value:
2015 return true;
2016 }
2017 }
2018
2019 return false;
2020}
2021
2023 if (!isValid())
2024 return false;
2025
2026 if (getNumElements() == 0)
2027 return false;
2028
2029 // Tag offsets are non-emitting. They, fragments, and location operands don't
2030 // perform a computation by themselves.
2031 for (const auto &It : expr_ops()) {
2032 if (It.isNonEmitting())
2033 continue;
2034 switch (It.getOp()) {
2037 continue;
2038 default:
2039 return true;
2040 }
2041 }
2042
2043 return false;
2044}
2045
2047 if (!isValid())
2048 return false;
2049
2050 if (getNumElements() == 0)
2051 return true;
2052
2053 auto ExprOpBegin = expr_ops().begin();
2054 auto ExprOpEnd = expr_ops().end();
2055 if (auto Arg = dyn_cast<ArgOp>(*ExprOpBegin)) {
2056 if (Arg.getIndex() != 0)
2057 return false;
2058 ++ExprOpBegin;
2059 }
2060
2061 return !std::any_of(ExprOpBegin, ExprOpEnd,
2062 [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); });
2063}
2064
2065std::optional<ArrayRef<uint64_t>>
2067 // Check for `isValid` covered by `isSingleLocationExpression`.
2069 return std::nullopt;
2070
2071 // An empty expression is already non-variadic.
2072 if (!getNumElements())
2073 return ArrayRef<uint64_t>();
2074
2075 // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do
2076 // anything.
2078 return getElements().drop_front(2);
2079 return getElements();
2080}
2081
2082const DIExpression *
2084 SmallVector<uint64_t, 3> UndefOps;
2085 if (auto FragmentInfo = Expr->getFragmentInfo()) {
2086 UndefOps.append({dwarf::DW_OP_LLVM_fragment, FragmentInfo->OffsetInBits,
2087 FragmentInfo->SizeInBits});
2088 }
2089 return DIExpression::get(Expr->getContext(), UndefOps);
2090}
2091
2092const DIExpression *
2094 if (any_of(Expr->expr_ops(), [](auto ExprOp) {
2095 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
2096 }))
2097 return Expr;
2098 SmallVector<uint64_t> NewOps;
2099 NewOps.reserve(Expr->getNumElements() + 2);
2100 NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
2101 NewOps.append(Expr->elements_begin(), Expr->elements_end());
2102 return DIExpression::get(Expr->getContext(), NewOps);
2103}
2104
2105std::optional<const DIExpression *>
2107 if (!Expr)
2108 return std::nullopt;
2109
2110 if (auto Elts = Expr->getSingleLocationExpressionElements())
2111 return DIExpression::get(Expr->getContext(), *Elts);
2112
2113 return std::nullopt;
2114}
2115
2117 const DIExpression *Expr,
2118 bool IsIndirect) {
2119 // If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0`
2120 // to the existing expression ops.
2121 if (none_of(Expr->expr_ops(), [](auto ExprOp) {
2122 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
2123 }))
2124 Ops.append({dwarf::DW_OP_LLVM_arg, 0});
2125 // If Expr is not indirect, we only need to insert the expression elements and
2126 // we're done.
2127 if (!IsIndirect) {
2128 Ops.append(Expr->elements_begin(), Expr->elements_end());
2129 return;
2130 }
2131 // If Expr is indirect, insert the implied DW_OP_deref at the end of the
2132 // expression but before DW_OP_{stack_value, LLVM_fragment} if they are
2133 // present.
2134 for (auto Op : Expr->expr_ops()) {
2135 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2136 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2137 Ops.push_back(dwarf::DW_OP_deref);
2138 IsIndirect = false;
2139 }
2140 Op.appendToVector(Ops);
2141 }
2142 if (IsIndirect)
2143 Ops.push_back(dwarf::DW_OP_deref);
2144}
2145
2146bool DIExpression::isEqualExpression(const DIExpression *FirstExpr,
2147 bool FirstIndirect,
2148 const DIExpression *SecondExpr,
2149 bool SecondIndirect) {
2150 SmallVector<uint64_t> FirstOps;
2151 DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect);
2152 SmallVector<uint64_t> SecondOps;
2153 DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr,
2154 SecondIndirect);
2155 return FirstOps == SecondOps;
2156}
2157
2158std::optional<DIExpression::FragmentInfo>
2160 for (auto I = Start; I != End; ++I)
2161 if (auto Fragment = dyn_cast<FragmentOp>(*I))
2162 return FragmentInfo{Fragment.getSizeInBits(), Fragment.getOffsetInBits()};
2163 return std::nullopt;
2164}
2165
2166std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) {
2167 std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();
2168 std::optional<uint64_t> ActiveBits = InitialActiveBits;
2169 auto NarrowActiveBits = [&](uint64_t SizeInBits) {
2170 ActiveBits = ActiveBits ? std::min(*ActiveBits, SizeInBits) : SizeInBits;
2171 };
2172
2173 for (auto Op : expr_ops()) {
2174 switch (Op.getOp()) {
2175 default:
2176 // We assume the worst case for anything we don't currently handle and
2177 // revert to the initial active bits.
2178 ActiveBits = InitialActiveBits;
2179 break;
2182 auto Extract = cast<ExtractBitsOp>(Op);
2183 // We can't handle an extract whose sign doesn't match that of the
2184 // variable.
2185 std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness();
2186 bool VarSigned = (VarSign == DIBasicType::Signedness::Signed);
2187 if (!VarSign || VarSigned != Extract.isSigned()) {
2188 ActiveBits = InitialActiveBits;
2189 break;
2190 }
2191 NarrowActiveBits(Extract.getSizeInBits());
2192 break;
2193 }
2195 NarrowActiveBits(cast<FragmentOp>(Op).getSizeInBits());
2196 break;
2197 }
2198 }
2199 return ActiveBits;
2200}
2201
2203 int64_t Offset) {
2204 if (Offset > 0) {
2205 Ops.push_back(dwarf::DW_OP_plus_uconst);
2206 Ops.push_back(Offset);
2207 } else if (Offset < 0) {
2208 Ops.push_back(dwarf::DW_OP_constu);
2209 // Avoid UB when encountering LLONG_MIN, because in 2's complement
2210 // abs(LLONG_MIN) is LLONG_MAX+1.
2211 uint64_t AbsMinusOne = -(Offset+1);
2212 Ops.push_back(AbsMinusOne + 1);
2213 Ops.push_back(dwarf::DW_OP_minus);
2214 }
2215}
2216
2218 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2219 if (!SingleLocEltsOpt)
2220 return false;
2221 auto SingleLocElts = *SingleLocEltsOpt;
2222
2223 if (SingleLocElts.size() == 0) {
2224 Offset = 0;
2225 return true;
2226 }
2227
2228 if (SingleLocElts.size() == 2 &&
2229 SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
2230 Offset = SingleLocElts[1];
2231 return true;
2232 }
2233
2234 if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
2235 if (SingleLocElts[2] == dwarf::DW_OP_plus) {
2236 Offset = SingleLocElts[1];
2237 return true;
2238 }
2239 if (SingleLocElts[2] == dwarf::DW_OP_minus) {
2240 Offset = -SingleLocElts[1];
2241 return true;
2242 }
2243 }
2244
2245 return false;
2246}
2247
2249 ArrayRef<uint64_t> Ops, int64_t &OffsetInBytes,
2250 SmallVectorImpl<uint64_t> &RemainingOps) {
2251 OffsetInBytes = 0;
2252 RemainingOps.clear();
2253
2254 auto ExprOpEnd = expr_op_iterator(Ops.end());
2255 auto ExprOpIt = expr_op_iterator(Ops.begin());
2256 while (ExprOpIt != ExprOpEnd) {
2257 uint64_t Op = ExprOpIt->getOp();
2258 if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||
2259 Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment ||
2262 break;
2263 } else if (auto PlusUconst = dyn_cast<PlusUconstOp>(*ExprOpIt)) {
2264 OffsetInBytes += PlusUconst.getOffset();
2265 } else if (auto Constant = dyn_cast<ConstuOp>(*ExprOpIt)) {
2266 uint64_t Value = Constant.getValue();
2267 ++ExprOpIt;
2268 if (ExprOpIt->getOp() == dwarf::DW_OP_plus)
2269 OffsetInBytes += Value;
2270 else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)
2271 OffsetInBytes -= Value;
2272 else
2273 return false;
2274 } else {
2275 // Not a const plus/minus operation or deref.
2276 return false;
2277 }
2278 ++ExprOpIt;
2279 }
2280 RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());
2281 return true;
2282}
2283
2285 int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const {
2286 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2287 if (!SingleLocEltsOpt) {
2288 OffsetInBytes = 0;
2289 RemainingOps.clear();
2290 return false;
2291 }
2292
2293 return extractLeadingOffset(*SingleLocEltsOpt, OffsetInBytes, RemainingOps);
2294}
2295
2298 for (auto ExprOp : expr_ops())
2299 if (auto Arg = dyn_cast<ArgOp>(ExprOp))
2300 SeenOps.insert(Arg.getIndex());
2301 for (uint64_t Idx = 0; Idx < N; ++Idx)
2302 if (!SeenOps.contains(Idx))
2303 return false;
2304 return true;
2305}
2306
2307const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,
2308 unsigned &AddrClass) {
2309 if (!Expr->isValid())
2310 return Expr;
2311 auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements();
2312 if (!SingleLocEltsOpt)
2313 return Expr;
2314 ArrayRef<uint64_t> SingleLocElts = *SingleLocEltsOpt;
2315
2316 // Walk the operations, rather than the raw elements, so that operands are
2317 // never mistaken for opcodes.
2319 expr_op_iterator(SingleLocElts.end()));
2320 if (Ops.size() < 3)
2321 return Expr;
2322 const ExprOperand &AddrSpaceOp = Ops[Ops.size() - 3];
2323 const ExprOperand &SwapOp = Ops[Ops.size() - 2];
2324 const ExprOperand &XDerefOp = Ops[Ops.size() - 1];
2325 if (!SwapOp.is(dwarf::DW_OP_swap) || !(XDerefOp.is(dwarf::DW_OP_xderef) ||
2326 XDerefOp.is(dwarf::DW_OP_xderef_size)))
2327 return Expr;
2328
2329 uint64_t Op = AddrSpaceOp.getOp();
2330 if (Op == dwarf::DW_OP_constu)
2331 AddrClass = AddrSpaceOp.getArg(0);
2332 else if (isLitOp(Op))
2333 AddrClass = Op - dwarf::DW_OP_lit0;
2334 else
2335 return Expr;
2336
2337 if (AddrSpaceOp.get() == SingleLocElts.begin())
2338 return nullptr;
2339 return DIExpression::get(Expr->getContext(),
2340 ArrayRef(SingleLocElts.begin(), AddrSpaceOp.get()));
2341}
2342
2343DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,
2344 int64_t Offset) {
2346 if (Flags & DIExpression::DerefBefore)
2347 Ops.push_back(dwarf::DW_OP_deref);
2348
2350 if (Flags & DIExpression::DerefAfter)
2351 Ops.push_back(dwarf::DW_OP_deref);
2352
2353 bool StackValue = Flags & DIExpression::StackValue;
2354 bool EntryValue = Flags & DIExpression::EntryValue;
2355
2356 return prependOpcodes(Expr, Ops, StackValue, EntryValue);
2357}
2358
2359DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
2361 unsigned ArgNo, bool StackValue) {
2362 assert(Expr && "Can't add ops to this expression");
2363
2364 // Handle non-variadic intrinsics by prepending the opcodes.
2365 if (!any_of(Expr->expr_ops(),
2366 [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); })) {
2367 assert(ArgNo == 0 &&
2368 "Location Index must be 0 for a non-variadic expression.");
2370 return DIExpression::prependOpcodes(Expr, NewOps, StackValue);
2371 }
2372
2374 for (auto Op : Expr->expr_ops()) {
2375 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2376 if (StackValue) {
2377 if (Op.getOp() == dwarf::DW_OP_stack_value)
2378 StackValue = false;
2379 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2380 NewOps.push_back(dwarf::DW_OP_stack_value);
2381 StackValue = false;
2382 }
2383 }
2384 Op.appendToVector(NewOps);
2385 if (auto Arg = dyn_cast<ArgOp>(Op); Arg && Arg.getIndex() == ArgNo)
2386 llvm::append_range(NewOps, Ops);
2387 }
2388 if (StackValue)
2389 NewOps.push_back(dwarf::DW_OP_stack_value);
2390
2391 return DIExpression::get(Expr->getContext(), NewOps);
2392}
2393
2394DIExpression *DIExpression::replaceArg(const DIExpression *Expr,
2395 uint64_t OldArg, uint64_t NewArg) {
2396 assert(Expr && "Can't replace args in this expression");
2397
2399
2400 for (auto Op : Expr->expr_ops()) {
2401 auto Arg = dyn_cast<ArgOp>(Op);
2402 if (!Arg || Arg.getIndex() < OldArg) {
2403 Op.appendToVector(NewOps);
2404 continue;
2405 }
2407 uint64_t ArgIndex = Arg.getIndex() == OldArg ? NewArg : Arg.getIndex();
2408 // OldArg has been deleted from the Op list, so decrement all indices
2409 // greater than it.
2410 if (ArgIndex > OldArg)
2411 --ArgIndex;
2412 NewOps.push_back(ArgIndex);
2413 }
2414 return DIExpression::get(Expr->getContext(), NewOps);
2415}
2416
2417DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
2419 bool StackValue, bool EntryValue) {
2420 assert(Expr && "Can't prepend ops to this expression");
2421
2422 if (EntryValue) {
2424 // Use a block size of 1 for the target register operand. The
2425 // DWARF backend currently cannot emit entry values with a block
2426 // size > 1.
2427 Ops.push_back(1);
2428 }
2429
2430 // If there are no ops to prepend, do not even add the DW_OP_stack_value.
2431 if (Ops.empty())
2432 StackValue = false;
2433 for (auto Op : Expr->expr_ops()) {
2434 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2435 if (StackValue) {
2436 if (Op.getOp() == dwarf::DW_OP_stack_value)
2437 StackValue = false;
2438 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2439 Ops.push_back(dwarf::DW_OP_stack_value);
2440 StackValue = false;
2441 }
2442 }
2443 Op.appendToVector(Ops);
2444 }
2445 if (StackValue)
2446 Ops.push_back(dwarf::DW_OP_stack_value);
2447 return DIExpression::get(Expr->getContext(), Ops);
2448}
2449
2450DIExpression *DIExpression::append(const DIExpression *Expr,
2452 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2453
2454 // Copy Expr's current op list.
2456 for (auto Op : Expr->expr_ops()) {
2457 // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
2458 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2459 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2460 NewOps.append(Ops.begin(), Ops.end());
2461
2462 // Ensure that the new opcodes are only appended once.
2463 Ops = {};
2464 }
2465 Op.appendToVector(NewOps);
2466 }
2467 NewOps.append(Ops.begin(), Ops.end());
2468 auto *result =
2469 DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath();
2470 assert(result->isValid() && "concatenated expression is not valid");
2471 return result;
2472}
2473
2474DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
2476 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2477 assert(std::none_of(expr_op_iterator(Ops.begin()),
2478 expr_op_iterator(Ops.end()),
2479 [](auto Op) {
2480 return Op.getOp() == dwarf::DW_OP_stack_value ||
2481 Op.getOp() == dwarf::DW_OP_LLVM_fragment;
2482 }) &&
2483 "Can't append this op");
2484
2485 // DIExpression stores opcodes and their arguments in a flat array. Walk the
2486 // parsed operations to find the last opcode that determines whether the
2487 // expression already ends in DW_OP_stack_value.
2488 std::optional<uint64_t> LastValueOp;
2489 for (auto Op : Expr->expr_ops()) {
2490 if (Op.isNonEmitting() || Op.getOp() == dwarf::DW_OP_LLVM_fragment)
2491 continue;
2492 LastValueOp = Op.getOp();
2493 }
2494 bool NeedsDeref = LastValueOp && *LastValueOp != dwarf::DW_OP_stack_value;
2495 bool NeedsStackValue = NeedsDeref || !LastValueOp;
2496
2497 // Append a DW_OP_deref after Expr's current op list if needed, then append
2498 // the new ops, and finally ensure that a single DW_OP_stack_value is present.
2500 if (NeedsDeref)
2501 NewOps.push_back(dwarf::DW_OP_deref);
2502 NewOps.append(Ops.begin(), Ops.end());
2503 if (NeedsStackValue)
2504 NewOps.push_back(dwarf::DW_OP_stack_value);
2505 return DIExpression::append(Expr, NewOps);
2506}
2507
2508std::optional<DIExpression *> DIExpression::createFragmentExpression(
2509 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
2511 // Track whether it's safe to split the value at the top of the DWARF stack,
2512 // assuming that it'll be used as an implicit location value.
2513 bool CanSplitValue = true;
2514 // Track whether we need to add a fragment expression to the end of Expr.
2515 bool EmitFragment = true;
2516 // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
2517 if (Expr) {
2518 for (auto Op : Expr->expr_ops()) {
2519 switch (Op.getOp()) {
2520 default:
2521 break;
2522 case dwarf::DW_OP_shr:
2523 case dwarf::DW_OP_shra:
2524 case dwarf::DW_OP_shl:
2525 case dwarf::DW_OP_plus:
2526 case dwarf::DW_OP_plus_uconst:
2527 case dwarf::DW_OP_minus:
2528 // We can't safely split arithmetic or shift operations into multiple
2529 // fragments because we can't express carry-over between fragments.
2530 //
2531 // FIXME: We *could* preserve the lowest fragment of a constant offset
2532 // operation if the offset fits into SizeInBits.
2533 CanSplitValue = false;
2534 break;
2535 case dwarf::DW_OP_deref:
2536 case dwarf::DW_OP_deref_size:
2537 case dwarf::DW_OP_deref_type:
2538 case dwarf::DW_OP_xderef:
2539 case dwarf::DW_OP_xderef_size:
2540 case dwarf::DW_OP_xderef_type:
2541 // Preceeding arithmetic operations have been applied to compute an
2542 // address. It's okay to split the value loaded from that address.
2543 CanSplitValue = true;
2544 break;
2545 case dwarf::DW_OP_stack_value:
2546 // Bail if this expression computes a value that cannot be split.
2547 if (!CanSplitValue)
2548 return std::nullopt;
2549 break;
2552 // If we've decided we don't need a fragment then give up if we see that
2553 // there's already a fragment expression.
2554 // FIXME: We could probably do better here
2555 if (!EmitFragment)
2556 return std::nullopt;
2557 // Make the new offset point into the existing fragment.
2558 uint64_t FragmentOffsetInBits = Fragment.getOffsetInBits();
2559 uint64_t FragmentSizeInBits = Fragment.getSizeInBits();
2560 (void)FragmentSizeInBits;
2561 assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
2562 "new fragment outside of original fragment");
2563 OffsetInBits += FragmentOffsetInBits;
2564 continue;
2565 }
2568 auto Extract = cast<ExtractBitsOp>(Op);
2569 // If we're extracting bits from inside of the fragment that we're
2570 // creating then we don't have a fragment after all, and just need to
2571 // adjust the offset that we're extracting from.
2572 uint64_t ExtractOffsetInBits = Extract.getOffsetInBits();
2573 uint64_t ExtractSizeInBits = Extract.getSizeInBits();
2574 if (ExtractOffsetInBits >= OffsetInBits &&
2575 ExtractOffsetInBits + ExtractSizeInBits <=
2576 OffsetInBits + SizeInBits) {
2577 Ops.push_back(Op.getOp());
2578 Ops.push_back(ExtractOffsetInBits - OffsetInBits);
2579 Ops.push_back(ExtractSizeInBits);
2580 EmitFragment = false;
2581 continue;
2582 }
2583 // If the extracted bits aren't fully contained within the fragment then
2584 // give up.
2585 // FIXME: We could probably do better here
2586 return std::nullopt;
2587 }
2588 }
2589 Op.appendToVector(Ops);
2590 }
2591 }
2592 assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");
2593 assert(Expr && "Unknown DIExpression");
2594 if (EmitFragment) {
2596 Ops.push_back(OffsetInBits);
2597 Ops.push_back(SizeInBits);
2598 }
2599 return DIExpression::get(Expr->getContext(), Ops);
2600}
2601
2602/// See declaration for more info.
2604 const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits,
2605 uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,
2606 int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag,
2607 std::optional<DIExpression::FragmentInfo> &Result,
2608 int64_t &OffsetFromLocationInBits) {
2609
2610 if (VarFrag.SizeInBits == 0)
2611 return false; // Variable size is unknown.
2612
2613 // Difference between mem slice start and the dbg location start.
2614 // 0 4 8 12 16 ...
2615 // | |
2616 // dbg location start
2617 // |
2618 // mem slice start
2619 // Here MemStartRelToDbgStartInBits is 8. Note this can be negative.
2620 int64_t MemStartRelToDbgStartInBits;
2621 {
2622 auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL);
2623 if (!MemOffsetFromDbgInBytes)
2624 return false; // Can't calculate difference in addresses.
2625 // Difference between the pointers.
2626 MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;
2627 // Add the difference of the offsets.
2628 MemStartRelToDbgStartInBits +=
2629 SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);
2630 }
2631
2632 // Out-param. Invert offset to get offset from debug location.
2633 OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;
2634
2635 // Check if the variable fragment sits outside (before) this memory slice.
2636 int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;
2637 if (MemEndRelToDbgStart < 0) {
2638 Result = {0, 0}; // Out-param.
2639 return true;
2640 }
2641
2642 // Work towards creating SliceOfVariable which is the bits of the variable
2643 // that the memory region covers.
2644 // 0 4 8 12 16 ...
2645 // | |
2646 // dbg location start with VarFrag offset=32
2647 // |
2648 // mem slice start: SliceOfVariable offset=40
2649 int64_t MemStartRelToVarInBits =
2650 MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;
2651 int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;
2652 // If the memory region starts before the debug location the fragment
2653 // offset would be negative, which we can't encode. Limit those to 0. This
2654 // is fine because those bits necessarily don't overlap with the existing
2655 // variable fragment.
2656 int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);
2657 int64_t MemFragSize =
2658 std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);
2659 DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart);
2660
2661 // Intersect the memory region fragment with the variable location fragment.
2662 DIExpression::FragmentInfo TrimmedSliceOfVariable =
2663 DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);
2664 if (TrimmedSliceOfVariable == VarFrag)
2665 Result = std::nullopt; // Out-param.
2666 else
2667 Result = TrimmedSliceOfVariable; // Out-param.
2668 return true;
2669}
2670
2671std::pair<DIExpression *, const ConstantInt *>
2673 // Copy the APInt so we can modify it.
2674 APInt NewInt = CI->getValue();
2676
2677 // Fold operators only at the beginning of the expression.
2678 bool First = true;
2679 bool Changed = false;
2680 for (auto Op : expr_ops()) {
2681 switch (Op.getOp()) {
2682 default:
2683 // We fold only the leading part of the expression; if we get to a part
2684 // that we're going to copy unchanged, and haven't done any folding,
2685 // then the entire expression is unchanged and we can return early.
2686 if (!Changed)
2687 return {this, CI};
2688 First = false;
2689 break;
2691 if (!First)
2692 break;
2693 Changed = true;
2694 auto Convert = cast<ConvertOp>(Op);
2695 if (Convert.getEncoding() == dwarf::DW_ATE_signed)
2696 NewInt = NewInt.sextOrTrunc(Convert.getBitSize());
2697 else {
2698 assert(Convert.getEncoding() == dwarf::DW_ATE_unsigned &&
2699 "Unexpected operand");
2700 NewInt = NewInt.zextOrTrunc(Convert.getBitSize());
2701 }
2702 continue;
2703 }
2704 }
2705 Op.appendToVector(Ops);
2706 }
2707 if (!Changed)
2708 return {this, CI};
2709 return {DIExpression::get(getContext(), Ops),
2710 ConstantInt::get(getContext(), NewInt)};
2711}
2712
2714 uint64_t Result = 0;
2715 for (auto ExprOp : expr_ops())
2716 if (auto Arg = dyn_cast<ArgOp>(ExprOp))
2717 Result = std::max(Result, Arg.getIndex() + 1);
2718 assert(hasAllLocationOps(Result) &&
2719 "Expression is missing one or more location operands.");
2720 return Result;
2721}
2722
2723std::optional<DIExpression::SignedOrUnsignedConstant>
2725
2726 // Recognize signed and unsigned constants.
2727 // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value
2728 // (DW_OP_LLVM_fragment of Len).
2729 // An unsigned constant can be represented as
2730 // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len), or as
2731 // DW_OP_lit<C> DW_OP_stack_value (DW_OP_LLVM_fragment of Len).
2732
2733 if (getNumElements() == 0)
2734 return std::nullopt;
2735 uint64_t Op = getElement(0);
2736 if (Op != dwarf::DW_OP_consts && Op != dwarf::DW_OP_constu && !isLitOp(Op))
2737 return std::nullopt;
2738
2739 // The number of elements used by the constant: DW_OP_lit<C> encodes its
2740 // value in the opcode, while DW_OP_constu/DW_OP_consts take an operand.
2741 unsigned ConstSize = expr_op_begin()->getSize();
2742 unsigned NumElements = getNumElements();
2743 // The constant may be followed by DW_OP_stack_value (1 element), and then
2744 // by DW_OP_LLVM_fragment, offset, size (3 more elements).
2745 if (NumElements != ConstSize && NumElements != ConstSize + 1 &&
2746 NumElements != ConstSize + 4)
2747 return std::nullopt;
2748
2749 if (NumElements == ConstSize && Op == dwarf::DW_OP_consts)
2751
2752 if ((NumElements == ConstSize + 1 &&
2753 getElement(ConstSize) != dwarf::DW_OP_stack_value) ||
2754 (NumElements == ConstSize + 4 &&
2755 (getElement(ConstSize) != dwarf::DW_OP_stack_value ||
2756 getElement(ConstSize + 1) != dwarf::DW_OP_LLVM_fragment)))
2757 return std::nullopt;
2758 return Op == dwarf::DW_OP_consts ? SignedOrUnsignedConstant::SignedConstant
2760}
2761
2763 assert(isConstant() && "Expression is not a constant");
2764 uint64_t Op = getElement(0);
2765 if (isLitOp(Op))
2766 return Op - dwarf::DW_OP_lit0;
2767 return getElement(1);
2768}
2769
2770DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
2771 bool Signed) {
2772 dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
2774 dwarf::DW_OP_LLVM_convert, ToSize, TK}};
2775 return Ops;
2776}
2777
2778DIExpression *DIExpression::appendExt(const DIExpression *Expr,
2779 unsigned FromSize, unsigned ToSize,
2780 bool Signed) {
2781 return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
2782}
2783
2785DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
2787 bool ShouldCreate) {
2789 Metadata *Ops[] = {Variable, Expression};
2791}
2792DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
2793 unsigned Line, unsigned Attributes,
2795 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
2797
2798DIObjCProperty *DIObjCProperty::getImpl(
2799 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
2800 MDString *GetterName, MDString *SetterName, unsigned Attributes,
2801 Metadata *Type, StorageType Storage, bool ShouldCreate) {
2802 assert(isCanonical(Name) && "Expected canonical MDString");
2803 assert(isCanonical(GetterName) && "Expected canonical MDString");
2804 assert(isCanonical(SetterName) && "Expected canonical MDString");
2805 DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,
2806 SetterName, Attributes, Type));
2808 DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
2809}
2810
2811DIProperty::DIProperty(LLVMContext &C, StorageType Storage, unsigned Line,
2813 : DINode(C, DIPropertyKind, Storage, dwarf::DW_TAG_property, Ops),
2814 Line(Line) {}
2815
2816DIProperty *DIProperty::getImpl(LLVMContext &Context, MDString *Name,
2817 Metadata *File, unsigned Line, Metadata *Type,
2818 Metadata *BackingStorage, StorageType Storage,
2819 bool ShouldCreate) {
2820 assert(isCanonical(Name) && "Expected canonical MDString");
2821 DEFINE_GETIMPL_LOOKUP(DIProperty, (Name, File, Line, Type, BackingStorage));
2823 DEFINE_GETIMPL_STORE(DIProperty, (Line), Ops);
2824}
2825
2826DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
2827 Metadata *Scope, Metadata *Entity,
2828 Metadata *File, unsigned Line,
2829 MDString *Name, Metadata *Elements,
2830 StorageType Storage,
2831 bool ShouldCreate) {
2832 assert(isCanonical(Name) && "Expected canonical MDString");
2833 DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
2834 (Tag, Scope, Entity, File, Line, Name, Elements));
2836 DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
2837}
2838
2839DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2840 MDString *Name, MDString *Value, StorageType Storage,
2841 bool ShouldCreate) {
2842 assert(isCanonical(Name) && "Expected canonical MDString");
2844 Metadata *Ops[] = {Name, Value};
2845 DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
2846}
2847
2848DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
2849 unsigned Line, Metadata *File,
2850 Metadata *Elements, StorageType Storage,
2851 bool ShouldCreate) {
2852 DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements));
2853 Metadata *Ops[] = {File, Elements};
2854 DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
2855}
2856
2857DIArgList *DIArgList::get(LLVMContext &Context,
2859 auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));
2860 if (ExistingIt != Context.pImpl->DIArgLists.end())
2861 return *ExistingIt;
2862 DIArgList *NewArgList = new DIArgList(Context, Args);
2863 Context.pImpl->DIArgLists.insert(NewArgList);
2864 return NewArgList;
2865}
2866
2868 ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);
2869 assert((!New || isa<ValueAsMetadata>(New)) &&
2870 "DIArgList must be passed a ValueAsMetadata");
2871 untrack();
2872 // We need to update the set storage once the Args are updated since they
2873 // form the key to the DIArgLists store.
2874 getContext().pImpl->DIArgLists.erase(this);
2876 for (ValueAsMetadata *&VM : Args) {
2877 if (&VM == OldVMPtr) {
2878 if (NewVM)
2879 VM = NewVM;
2880 else
2881 VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));
2882 }
2883 }
2884 // We've changed the contents of this DIArgList, and the set storage may
2885 // already contain a DIArgList with our new set of args; if it does, then we
2886 // must RAUW this with the existing DIArgList, otherwise we simply insert this
2887 // back into the set storage.
2888 DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);
2889 if (ExistingArgList) {
2890 replaceAllUsesWith(ExistingArgList);
2891 // Clear this here so we don't try to untrack in the destructor.
2892 Args.clear();
2893 delete this;
2894 return;
2895 }
2896 getContext().pImpl->DIArgLists.insert(this);
2897 track();
2898}
2899void DIArgList::track() {
2900 for (ValueAsMetadata *&VAM : Args)
2901 if (VAM)
2902 MetadataTracking::track(&VAM, *VAM, *this);
2903}
2904void DIArgList::untrack() {
2905 for (ValueAsMetadata *&VAM : Args)
2906 if (VAM)
2907 MetadataTracking::untrack(&VAM, *VAM);
2908}
2909void DIArgList::dropAllReferences(bool Untrack) {
2910 if (Untrack)
2911 untrack();
2912 Args.clear();
2913 ReplaceableUses::resolveAllUses(/* ResolveUsers */ false);
2914}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
constexpr LLT S1
AMDGPU Kernel Attributes
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
static Metadata * mergeIRLayers(LLVMContext &C, const DILocation *LocA, const DILocation *LocB)
static ConstantAsMetadata * extractConstantMetadata(Metadata *ExtraData)
static const char * ChecksumKindName[DIFile::CSK_Last]
#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS)
static void adjustColumn(unsigned &Column)
#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS)
static std::pair< DIScope *, LineColumn > getNearestMatchingScope(const DILocation *L1, const DILocation *L2)
static LineColumn getLocalScopeLocationOr(DIScope *S, LineColumn Default)
Returns the location of DILocalScope, if present, or a default value.
std::pair< unsigned, unsigned > LineColumn
static ScopeT getRawRetainedNodeScopeInternal(NodeT *N)
static bool isCanonical(const MDString *S)
#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS)
#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS)
#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS)
static DILexicalBlockBase * cloneAndReplaceParentScope(DILexicalBlockBase *LBB, DIScope *NewParent)
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file defines the DenseSet and SmallDenseSet classes.
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.
@ Default
This file contains constants used for implementing Dwarf debug support.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
#define T
static constexpr StringLiteral Filename
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file implements a set that has insertion order iteration characteristics.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Class for arbitrary precision integers.
Definition APInt.h:78
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition APInt.cpp:1078
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition APInt.cpp:1086
Annotations lets you mark points and ranges inside source code, for tests:
Definition Annotations.h:67
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition ArrayRef.h:194
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:548
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This is an important base class in LLVM.
Definition Constant.h:43
LLVM_ABI void handleChangedOperand(void *Ref, Metadata *New)
static LLVM_ABI DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)
DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned LineNo, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, DIFlags Flags, ArrayRef< Metadata * > Ops)
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t DIFlags Flags unsigned StringRef DIFile * File
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t DIFlags Flags unsigned StringRef DIFile unsigned DIScope * Scope
unsigned StringRef uint64_t SizeInBits
LLVM_ABI 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
static DIBasicType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, unsigned LineNo, DIScope *Scope, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, DIFlags Flags, StorageType Storage, bool ShouldCreate=true)
unsigned StringRef Name
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t AlignInBits
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t DIFlags Flags unsigned StringRef DIFile unsigned LineNo
Debug common block.
Metadata Metadata * Decl
Metadata Metadata MDString Metadata unsigned LineNo
Metadata Metadata MDString * Name
Metadata Metadata MDString Metadata * File
static LLVM_ABI const char * nameTableKindString(DebugNameTableKind PK)
static LLVM_ABI const char * emissionKindString(DebugEmissionKind EK)
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString * SysRoot
DISourceLanguageName Metadata MDString bool MDString * Flags
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString MDString * SDK
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata * GlobalVariables
DebugEmissionKind getEmissionKind() const
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata * EnumTypes
DISourceLanguageName Metadata MDString * Producer
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata * RetainedTypes
DISourceLanguageName Metadata MDString bool MDString unsigned MDString * SplitDebugFilename
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata * ImportedEntities
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata * Macros
DebugNameTableKind getNameTableKind() const
DISourceLanguageName Metadata * File
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t AlignInBits
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > EnumKind
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata * DataLocation
static LLVM_ABI DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional< uint32_t > EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations, Metadata *BitStride)
Build a DICompositeType with the given ODR identifier.
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 RuntimeLang
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > 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 std::optional< uint32_t > Metadata Metadata MDString * Identifier
static LLVM_ABI DICompositeType * getODRTypeIfExists(LLVMContext &Context, MDString &Identifier)
unsigned MDString * Name
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata * Discriminator
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata * TemplateParams
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 * 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 std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata * Allocated
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > 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 std::optional< uint32_t > Metadata * VTableHolder
unsigned MDString Metadata unsigned Metadata Metadata uint64_t SizeInBits
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata * Associated
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > 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 std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata * Rank
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata Metadata uint32_t Metadata * BitStride
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata * OffsetInBits
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t AlignInBits
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata std::optional< unsigned > std::optional< PtrAuthData > PtrAuthData
Metadata * getExtraData() const
Get extra data associated with this derived type.
unsigned StringRef DIFile * File
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata std::optional< unsigned > DWARFAddressSpace
LLVM_ABI DIType * getClassType() const
Get casted version of extra data.
LLVM_ABI Constant * getConstant() const
unsigned StringRef DIFile unsigned DIScope DIType Metadata * SizeInBits
LLVM_ABI Constant * getStorageOffsetInBits() const
LLVM_ABI Constant * getDiscriminantValue() const
unsigned StringRef Name
LLVM_ABI uint32_t getVBPtrOffset() const
Enumeration value.
int64_t bool MDString * Name
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
A lightweight wrapper around an expression operand.
LLVM_ABI bool isNonEmitting() const
Return true if CodeGen handles this operand without adding bytes to the DWARF expression.
LLVM_ABI unsigned getSize() const
Return the size of the operand.
uint64_t getArg(unsigned I) const
Get an argument to the operand.
bool is(uint64_t Opcode) const
Return true if this is Opcode.
uint64_t getOp() const
Get the operand code.
static LLVM_ABI bool classof(const ExprOperand *Op)
LLVM_ABI bool isSigned() const
Return whether the extracted value is sign-extended.
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
An iterator for expression operands.
DWARF expression.
element_iterator elements_end() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
iterator_range< expr_op_iterator > expr_ops() const
static LLVM_ABI 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 LLVM_ABI bool isLitOp(uint64_t Op)
Return true if Op is one of DW_OP_lit0 through DW_OP_lit31.
static LLVM_ABI 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.
LLVM_ABI bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
DbgVariableFragmentInfo FragmentInfo
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
static LLVM_ABI 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
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI 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
LLVM_ABI 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 LLVM_ABI 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...
LLVM_ABI uint64_t getConstantValue() const
Return the value of a constant expression, as recognized by isConstant().
LLVM_ABI bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
LLVM_ABI std::pair< DIExpression *, const ConstantInt * > constantFold(const ConstantInt *CI)
Try to shorten an expression with an initial constant operand.
LLVM_ABI bool isDeref() const
Return whether there is exactly one operator and it is a DW_OP_deref;.
static LLVM_ABI const DIExpression * convertToVariadicExpression(const DIExpression *Expr)
If Expr is a non-variadic expression (i.e.
LLVM_ABI 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 LLVM_ABI 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,...
LLVM_ABI std::optional< uint64_t > getActiveBits(DIVariable *Var)
Return the number of bits that have an active value, i.e.
static LLVM_ABI 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 LLVM_ABI bool extractLeadingOffset(ArrayRef< uint64_t > Ops, int64_t &OffsetInBytes, SmallVectorImpl< uint64_t > &RemainingOps)
static LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI 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 LLVM_ABI DIExpression * appendExt(const DIExpression *Expr, unsigned FromSize, unsigned ToSize, bool Signed)
Append a zero- or sign-extension to Expr.
LLVM_ABI std::optional< ArrayRef< uint64_t > > getSingleLocationExpressionElements() const
Returns a reference to the elements contained in this expression, skipping past the leading DW_OP_LLV...
LLVM_ABI bool isSingleLocationExpression() const
Return whether the evaluated expression makes use of a single location at the start of the expression...
LLVM_ABI std::optional< SignedOrUnsignedConstant > isConstant() const
Determine whether this represents a constant value, if so.
LLVM_ABI bool isValid() const
static LLVM_ABI const DIExpression * extractAddressClass(const DIExpression *Expr, unsigned &AddrClass)
Checks if the expression ends with <DWARF Address Space> DW_OP_swap DW_OP_xderef[_size],...
static LLVM_ABI 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
MDString MDString std::optional< ChecksumInfo< MDString * > > MDString * Source
static LLVM_ABI std::optional< ChecksumKind > getChecksumKind(StringRef CSKindStr)
MDString MDString std::optional< ChecksumInfo< MDString * > > CS
static LLVM_ABI std::optional< FixedPointKind > getFixedPointKind(StringRef Str)
static LLVM_ABI const char * fixedPointKindString(FixedPointKind)
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned DIFlags unsigned int APInt Numerator
unsigned StringRef DIFile unsigned LineNo
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned Encoding
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned DIFlags unsigned int APInt APInt Denominator
unsigned StringRef DIFile unsigned DIScope uint64_t SizeInBits
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t AlignInBits
LLVM_ABI bool isSigned() const
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned DIFlags unsigned int Factor
@ FixedPointBinary
Scale factor 2^Factor.
@ FixedPointDecimal
Scale factor 10^Factor.
@ FixedPointRational
Arbitrary rational scale factor.
unsigned StringRef DIFile * File
Metadata * getRawLowerBound() const
Metadata * getRawCountNode() const
Metadata * getRawStride() const
LLVM_ABI BoundType getLowerBound() const
Metadata * getRawUpperBound() const
LLVM_ABI BoundType getCount() const
LLVM_ABI BoundType getUpperBound() const
PointerUnion< DIVariable *, DIExpression * > BoundType
LLVM_ABI 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 Metadata uint32_t Metadata * Annotations
Metadata MDString * Name
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 unsigned bool std::optional< unsigned > CoroSuspendIdx
Metadata MDString Metadata unsigned unsigned Column
Metadata MDString Metadata unsigned unsigned bool IsArtificial
Metadata MDString Metadata unsigned Line
Metadata MDString * Name
Metadata MDString Metadata * File
A sequence of DILayerLoc entries.
iterator_range< layer_iterator > layers() const
A single intermediate-IR layer location.
LLVM_ABI DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef< Metadata * > Ops)
Metadata Metadata unsigned Discriminator
Debug lexical block.
Metadata Metadata unsigned unsigned Column
Metadata Metadata * File
A scope for locals.
LLVM_ABI DISubprogram * getSubprogram() const
Get the subprogram for this scope.
LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
DILocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef< Metadata * > Ops)
static LLVM_ABI 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 * Name
Metadata MDString Metadata unsigned Line
Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t Metadata * Annotations
Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t AlignInBits
unsigned unsigned DILocalScope * Scope
static LLVM_ABI DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)
Try to combine the vector of locations passed as input in a single one.
DILayerLocList * getIRLayers() const
unsigned unsigned DILocalScope DILocation bool uint64_t uint8_t Metadata * IRLayers
static LLVM_ABI std::optional< unsigned > encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI)
Raw encoding of the discriminator.
unsigned unsigned DILocalScope DILocation bool ImplicitCode
static LLVM_ABI void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, unsigned &CI)
Raw decoder for values in an encoded discriminator D.
static LLVM_ABI DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
Attempts to merge LocA and LocB into a single location; see DebugLoc::getMergedLocation for more deta...
unsigned unsigned Column
unsigned unsigned DILocalScope DILocation * InlinedAt
unsigned unsigned Metadata * File
unsigned unsigned Line
unsigned unsigned Metadata Metadata * Elements
unsigned unsigned MDString MDString * Value
unsigned unsigned MDString * Name
unsigned unsigned Line
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
Debug lexical block.
Metadata MDString bool ExportSymbols
Metadata MDString * Name
Tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
static LLVM_ABI DIFlags getFlag(StringRef Flag)
static LLVM_ABI DIFlags splitFlags(DIFlags Flags, SmallVectorImpl< DIFlags > &SplitFlags)
Split up a flags bitfield.
DINode(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef< Metadata * > Ops1, ArrayRef< Metadata * > Ops2={})
static LLVM_ABI StringRef getFlagString(DIFlags Flag)
DIFlags
Debug info flags.
MDString Metadata * File
MDString Metadata unsigned MDString MDString unsigned Metadata * Type
MDString Metadata unsigned MDString * GetterName
MDString Metadata unsigned MDString MDString * SetterName
A property of a class or structure.
MDString Metadata unsigned Metadata * Type
MDString Metadata unsigned Metadata Metadata * BackingStorage
MDString Metadata * File
Base class for scope-like contexts.
LLVM_ABI StringRef getName() const
DIFile * getFile() const
LLVM_ABI DIScope * getScope() const
DIScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, ArrayRef< Metadata * > Ops)
Wrapper structure that holds source language identity metadata that includes language name,...
String type, Fortran CHARACTER(n)
unsigned MDString * Name
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 Metadata Metadata uint64_t uint32_t unsigned Encoding
unsigned MDString Metadata * StringLength
Subprogram description. Uses SubclassData1.
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata MDString bool UsesKeyInstructions
LLVM_ABI void cleanupRetainedNodes()
When IR modules are merged, typically during LTO, the merged module may contain several types having ...
Metadata MDString MDString Metadata unsigned Metadata unsigned ScopeLine
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags SPFlags
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata * ContainingType
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata * TemplateParams
static LLVM_ABI DILocalScope * getRetainedNodeScope(MDNode *N)
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata MDString * TargetFuncName
static LLVM_ABI DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)
static LLVM_ABI const DIScope * getRawRetainedNodeScope(const MDNode *N)
void cleanupRetainedNodesIf(T &&Pred)
Metadata MDString * Name
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata * ThrownTypes
static LLVM_ABI DISPFlags getFlag(StringRef Flag)
Metadata MDString MDString Metadata * File
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned VirtualIndex
static LLVM_ABI DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)
Split up a flags bitfield for easier printing.
static LLVM_ABI StringRef getFlagString(DISPFlags Flag)
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata * RetainedNodes
DISPFlags
Debug info subprogram flags.
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int ThisAdjustment
LLVM_ABI bool describes(const Function *F) const
Check if this subprogram describes the given function.
StringRef DIFile unsigned Line
StringRef DIFile unsigned DIScope uint64_t uint32_t DIFlags DIType Metadata Metadata * UpperBound
StringRef DIFile unsigned DIScope uint64_t uint32_t DIFlags DIType Metadata Metadata Metadata Metadata * Bias
StringRef DIFile unsigned DIScope uint64_t uint32_t DIFlags DIType Metadata Metadata Metadata * Stride
StringRef DIFile unsigned DIScope uint64_t SizeInBits
StringRef DIFile * File
PointerUnion< ConstantInt *, DIVariable *, DIExpression *, DIDerivedType * > BoundType
StringRef DIFile unsigned DIScope uint64_t uint32_t AlignInBits
StringRef DIFile unsigned DIScope uint64_t uint32_t DIFlags DIType Metadata * LowerBound
StringRef DIFile unsigned DIScope uint64_t uint32_t DIFlags Flags
Array subrange.
LLVM_ABI BoundType getUpperBound() const
LLVM_ABI BoundType getStride() const
LLVM_ABI BoundType getLowerBound() const
LLVM_ABI BoundType getCount() const
Type array for a subprogram.
DIFlags uint8_t Metadata * TypeArray
Base class for template parameters.
unsigned MDString Metadata * Type
unsigned MDString Metadata bool Metadata * Value
Base class for types.
bool isBitField() const
bool isStaticMember() const
DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, unsigned Line, uint32_t AlignInBits, uint32_t NumExtraInhabitants, DIFlags Flags, ArrayRef< Metadata * > Ops)
LLVM_ABI 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...
LLVM_ABI std::optional< uint64_t > getSizeInBits() const
Determines the size of the variable's type.
Metadata * getRawType() const
LLVM_ABI DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line, ArrayRef< Metadata * > Ops, uint32_t AlignInBits=0)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI DebugVariableAggregate(const DbgVariableRecord *DVR)
const DILocation * getInlinedAt() const
const DILocalVariable * getVariable() const
LLVM_ABI DebugVariable(const DbgVariableRecord *DVR)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:767
iterator end()
Definition DenseMap.h:687
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:857
Class representing an expression and its matching format.
Generic tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
unsigned MDString * Header
unsigned MDString ArrayRef< Metadata * > DwarfOps
DenseSet< DIArgList *, DIArgListInfo > DIArgLists
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVMContextImpl *const pImpl
Definition LLVMContext.h:70
Metadata node.
Definition Metadata.h:1081
friend class DIAssignID
Definition Metadata.h:1084
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1587
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
LLVM_ABI TempMDNode clone() const
Create a (temporary) clone of this.
Definition Metadata.cpp:670
static T * storeImpl(T *N, StorageType Storage, StoreT &Store)
LLVMContext & getContext() const
Definition Metadata.h:1245
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.
Definition Metadata.h:1312
Tracking metadata reference owned by Metadata.
Definition Metadata.h:902
A single uniqued string.
Definition Metadata.h:733
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:615
static void untrack(Metadata *&MD)
Stop tracking a reference to metadata.
Definition Metadata.h:360
static bool track(Metadata *&MD)
Track the reference to metadata.
Definition Metadata.h:326
Root of the metadata hierarchy.
Definition Metadata.h:64
StorageType
Active type of storage.
Definition Metadata.h:72
unsigned short SubclassData16
Definition Metadata.h:78
unsigned SubclassData32
Definition Metadata.h:79
unsigned char Storage
Storage flag for non-uniqued, otherwise unowned, metadata.
Definition Metadata.h:75
unsigned char SubclassData1
Definition Metadata.h:77
Metadata(unsigned ID, StorageType Storage)
Definition Metadata.h:88
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
LLVMContext & getContext() const
Definition Metadata.h:460
LLVM_ABI void resolveAllUses(bool ResolveUsers=true)
Resolve all uses of this.
Definition Metadata.cpp:430
LLVM_ABI void replaceAllUsesWith(Metadata *MD)
Replace all uses of this with MD.
Definition Metadata.cpp:377
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition DenseSet.h:293
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
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.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
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.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
Value wrapper in the Metadata hierarchy.
Definition Metadata.h:471
static LLVM_ABI ValueAsMetadata * get(Value *V)
Definition Metadata.cpp:514
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI 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.
Definition Value.cpp:1098
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
@ DW_OP_LLVM_entry_value
Only used in LLVM metadata.
Definition Dwarf.h:147
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
Definition Dwarf.h:148
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
Definition Dwarf.h:151
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition Dwarf.h:146
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Definition Dwarf.h:144
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
Definition Dwarf.h:149
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Definition Dwarf.h:145
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
Definition Dwarf.h:150
@ DW_VIRTUALITY_max
Definition Dwarf.h:200
@ NameTableKind
Definition LLToken.h:520
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.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:577
static T * getUniqued(DenseSet< T *, InfoT > &Store, const typename InfoT::KeyTy &Key)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
auto cast_or_null(const Y &Val)
Definition Casting.h:714
static const DIScope * getScope(const NodeT *N)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI cl::opt< bool > PickMergedSourceLocations("pick-merged-source-locations", cl::init(false), cl::Hidden, cl::desc("Preserve line and column number when merging locations."))
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
@ Keep
No function return thunk.
Definition CodeGen.h:317
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
SmallPtrSet< DIScope *, 8 > Scopes
void insert(DIScope *S, LineColumn Loc)
DIScope * match(DIScope *S, LineColumn Loc)
void insert(DIScope *S, LineColumn Loc)
DIScope * match(DIScope *S, LineColumn Loc)
SmallMapVector< std::pair< DIFile *, LineColumn >, SmallSetVector< DIScope *, 8 >, 8 > Scopes
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.
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342