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_plus_uconst:
1848 case dwarf::DW_OP_regx:
1849 return 2;
1850 default:
1851 return 1;
1852 }
1853}
1854
1858
1860 return Op->is(dwarf::DW_OP_LLVM_arg);
1861}
1862
1866
1871
1875
1879
1883
1887
1889 return Op->is(dwarf::DW_OP_constu);
1890}
1891
1893 return Op->is(dwarf::DW_OP_plus_uconst);
1894}
1895
1897 for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
1898 // Check that there's space for the operand.
1899 if (I->get() + I->getSize() > E->get())
1900 return false;
1901
1902 uint64_t Op = I->getOp();
1903 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
1904 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))
1905 continue;
1906
1907 // Check that the operand is valid.
1908 switch (Op) {
1909 default:
1910 return false;
1912 // A fragment operator must appear at the end.
1913 return I->get() + I->getSize() == E->get();
1914 case dwarf::DW_OP_stack_value: {
1915 // Must be the last one or followed by a DW_OP_LLVM_fragment.
1916 if (I->get() + I->getSize() == E->get())
1917 break;
1918 auto J = I;
1919 if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
1920 return false;
1921 break;
1922 }
1923 case dwarf::DW_OP_swap: {
1924 // Must be more than one implicit element on the stack.
1925
1926 // FIXME: A better way to implement this would be to add a local variable
1927 // that keeps track of the stack depth and introduce something like a
1928 // DW_LLVM_OP_implicit_location as a placeholder for the location this
1929 // DIExpression is attached to, or else pass the number of implicit stack
1930 // elements into isValid.
1931 if (getNumElements() == 1)
1932 return false;
1933 break;
1934 }
1936 // An entry value operator must appear at the beginning or immediately
1937 // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
1938 // currently only be 1, because we support only entry values of a simple
1939 // register location. One reason for this is that we currently can't
1940 // calculate the size of the resulting DWARF block for other expressions.
1941 auto FirstOp = expr_op_begin();
1942 if (auto Arg = dyn_cast<ArgOp>(*FirstOp); Arg && Arg.getIndex() == 0)
1943 ++FirstOp;
1944 if (I->get() != FirstOp->get() ||
1945 cast<EntryValueOp>(*I).getNumOperations() != 1)
1946 return false;
1947 break;
1948 }
1955 case dwarf::DW_OP_constu:
1956 case dwarf::DW_OP_plus_uconst:
1957 case dwarf::DW_OP_plus:
1958 case dwarf::DW_OP_minus:
1959 case dwarf::DW_OP_mul:
1960 case dwarf::DW_OP_div:
1961 case dwarf::DW_OP_mod:
1962 case dwarf::DW_OP_or:
1963 case dwarf::DW_OP_and:
1964 case dwarf::DW_OP_xor:
1965 case dwarf::DW_OP_shl:
1966 case dwarf::DW_OP_shr:
1967 case dwarf::DW_OP_shra:
1968 case dwarf::DW_OP_deref:
1969 case dwarf::DW_OP_deref_size:
1970 case dwarf::DW_OP_xderef:
1971 case dwarf::DW_OP_lit0:
1972 case dwarf::DW_OP_not:
1973 case dwarf::DW_OP_dup:
1974 case dwarf::DW_OP_regx:
1975 case dwarf::DW_OP_bregx:
1976 case dwarf::DW_OP_push_object_address:
1977 case dwarf::DW_OP_over:
1978 case dwarf::DW_OP_rot:
1979 case dwarf::DW_OP_consts:
1980 case dwarf::DW_OP_eq:
1981 case dwarf::DW_OP_ne:
1982 case dwarf::DW_OP_gt:
1983 case dwarf::DW_OP_ge:
1984 case dwarf::DW_OP_lt:
1985 case dwarf::DW_OP_le:
1986 case dwarf::DW_OP_neg:
1987 case dwarf::DW_OP_abs:
1988 break;
1989 }
1990 }
1991 return true;
1992}
1993
1995 if (!isValid())
1996 return false;
1997
1998 if (getNumElements() == 0)
1999 return false;
2000
2001 for (const auto &It : expr_ops()) {
2002 switch (It.getOp()) {
2003 default:
2004 break;
2005 case dwarf::DW_OP_stack_value:
2006 return true;
2007 }
2008 }
2009
2010 return false;
2011}
2012
2014 if (!isValid())
2015 return false;
2016
2017 if (getNumElements() == 0)
2018 return false;
2019
2020 // Tag offsets are non-emitting. They, fragments, and location operands don't
2021 // perform a computation by themselves.
2022 for (const auto &It : expr_ops()) {
2023 if (It.isNonEmitting())
2024 continue;
2025 switch (It.getOp()) {
2028 continue;
2029 default:
2030 return true;
2031 }
2032 }
2033
2034 return false;
2035}
2036
2038 if (!isValid())
2039 return false;
2040
2041 if (getNumElements() == 0)
2042 return true;
2043
2044 auto ExprOpBegin = expr_ops().begin();
2045 auto ExprOpEnd = expr_ops().end();
2046 if (auto Arg = dyn_cast<ArgOp>(*ExprOpBegin)) {
2047 if (Arg.getIndex() != 0)
2048 return false;
2049 ++ExprOpBegin;
2050 }
2051
2052 return !std::any_of(ExprOpBegin, ExprOpEnd,
2053 [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); });
2054}
2055
2056std::optional<ArrayRef<uint64_t>>
2058 // Check for `isValid` covered by `isSingleLocationExpression`.
2060 return std::nullopt;
2061
2062 // An empty expression is already non-variadic.
2063 if (!getNumElements())
2064 return ArrayRef<uint64_t>();
2065
2066 // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do
2067 // anything.
2069 return getElements().drop_front(2);
2070 return getElements();
2071}
2072
2073const DIExpression *
2075 SmallVector<uint64_t, 3> UndefOps;
2076 if (auto FragmentInfo = Expr->getFragmentInfo()) {
2077 UndefOps.append({dwarf::DW_OP_LLVM_fragment, FragmentInfo->OffsetInBits,
2078 FragmentInfo->SizeInBits});
2079 }
2080 return DIExpression::get(Expr->getContext(), UndefOps);
2081}
2082
2083const DIExpression *
2085 if (any_of(Expr->expr_ops(), [](auto ExprOp) {
2086 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
2087 }))
2088 return Expr;
2089 SmallVector<uint64_t> NewOps;
2090 NewOps.reserve(Expr->getNumElements() + 2);
2091 NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
2092 NewOps.append(Expr->elements_begin(), Expr->elements_end());
2093 return DIExpression::get(Expr->getContext(), NewOps);
2094}
2095
2096std::optional<const DIExpression *>
2098 if (!Expr)
2099 return std::nullopt;
2100
2101 if (auto Elts = Expr->getSingleLocationExpressionElements())
2102 return DIExpression::get(Expr->getContext(), *Elts);
2103
2104 return std::nullopt;
2105}
2106
2108 const DIExpression *Expr,
2109 bool IsIndirect) {
2110 // If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0`
2111 // to the existing expression ops.
2112 if (none_of(Expr->expr_ops(), [](auto ExprOp) {
2113 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
2114 }))
2115 Ops.append({dwarf::DW_OP_LLVM_arg, 0});
2116 // If Expr is not indirect, we only need to insert the expression elements and
2117 // we're done.
2118 if (!IsIndirect) {
2119 Ops.append(Expr->elements_begin(), Expr->elements_end());
2120 return;
2121 }
2122 // If Expr is indirect, insert the implied DW_OP_deref at the end of the
2123 // expression but before DW_OP_{stack_value, LLVM_fragment} if they are
2124 // present.
2125 for (auto Op : Expr->expr_ops()) {
2126 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2127 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2128 Ops.push_back(dwarf::DW_OP_deref);
2129 IsIndirect = false;
2130 }
2131 Op.appendToVector(Ops);
2132 }
2133 if (IsIndirect)
2134 Ops.push_back(dwarf::DW_OP_deref);
2135}
2136
2137bool DIExpression::isEqualExpression(const DIExpression *FirstExpr,
2138 bool FirstIndirect,
2139 const DIExpression *SecondExpr,
2140 bool SecondIndirect) {
2141 SmallVector<uint64_t> FirstOps;
2142 DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect);
2143 SmallVector<uint64_t> SecondOps;
2144 DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr,
2145 SecondIndirect);
2146 return FirstOps == SecondOps;
2147}
2148
2149std::optional<DIExpression::FragmentInfo>
2151 for (auto I = Start; I != End; ++I)
2152 if (auto Fragment = dyn_cast<FragmentOp>(*I))
2153 return FragmentInfo{Fragment.getSizeInBits(), Fragment.getOffsetInBits()};
2154 return std::nullopt;
2155}
2156
2157std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) {
2158 std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();
2159 std::optional<uint64_t> ActiveBits = InitialActiveBits;
2160 auto NarrowActiveBits = [&](uint64_t SizeInBits) {
2161 ActiveBits = ActiveBits ? std::min(*ActiveBits, SizeInBits) : SizeInBits;
2162 };
2163
2164 for (auto Op : expr_ops()) {
2165 switch (Op.getOp()) {
2166 default:
2167 // We assume the worst case for anything we don't currently handle and
2168 // revert to the initial active bits.
2169 ActiveBits = InitialActiveBits;
2170 break;
2173 auto Extract = cast<ExtractBitsOp>(Op);
2174 // We can't handle an extract whose sign doesn't match that of the
2175 // variable.
2176 std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness();
2177 bool VarSigned = (VarSign == DIBasicType::Signedness::Signed);
2178 if (!VarSign || VarSigned != Extract.isSigned()) {
2179 ActiveBits = InitialActiveBits;
2180 break;
2181 }
2182 NarrowActiveBits(Extract.getSizeInBits());
2183 break;
2184 }
2186 NarrowActiveBits(cast<FragmentOp>(Op).getSizeInBits());
2187 break;
2188 }
2189 }
2190 return ActiveBits;
2191}
2192
2194 int64_t Offset) {
2195 if (Offset > 0) {
2196 Ops.push_back(dwarf::DW_OP_plus_uconst);
2197 Ops.push_back(Offset);
2198 } else if (Offset < 0) {
2199 Ops.push_back(dwarf::DW_OP_constu);
2200 // Avoid UB when encountering LLONG_MIN, because in 2's complement
2201 // abs(LLONG_MIN) is LLONG_MAX+1.
2202 uint64_t AbsMinusOne = -(Offset+1);
2203 Ops.push_back(AbsMinusOne + 1);
2204 Ops.push_back(dwarf::DW_OP_minus);
2205 }
2206}
2207
2209 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2210 if (!SingleLocEltsOpt)
2211 return false;
2212 auto SingleLocElts = *SingleLocEltsOpt;
2213
2214 if (SingleLocElts.size() == 0) {
2215 Offset = 0;
2216 return true;
2217 }
2218
2219 if (SingleLocElts.size() == 2 &&
2220 SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
2221 Offset = SingleLocElts[1];
2222 return true;
2223 }
2224
2225 if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
2226 if (SingleLocElts[2] == dwarf::DW_OP_plus) {
2227 Offset = SingleLocElts[1];
2228 return true;
2229 }
2230 if (SingleLocElts[2] == dwarf::DW_OP_minus) {
2231 Offset = -SingleLocElts[1];
2232 return true;
2233 }
2234 }
2235
2236 return false;
2237}
2238
2240 ArrayRef<uint64_t> Ops, int64_t &OffsetInBytes,
2241 SmallVectorImpl<uint64_t> &RemainingOps) {
2242 OffsetInBytes = 0;
2243 RemainingOps.clear();
2244
2245 auto ExprOpEnd = expr_op_iterator(Ops.end());
2246 auto ExprOpIt = expr_op_iterator(Ops.begin());
2247 while (ExprOpIt != ExprOpEnd) {
2248 uint64_t Op = ExprOpIt->getOp();
2249 if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||
2250 Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment ||
2253 break;
2254 } else if (auto PlusUconst = dyn_cast<PlusUconstOp>(*ExprOpIt)) {
2255 OffsetInBytes += PlusUconst.getOffset();
2256 } else if (auto Constant = dyn_cast<ConstuOp>(*ExprOpIt)) {
2257 uint64_t Value = Constant.getValue();
2258 ++ExprOpIt;
2259 if (ExprOpIt->getOp() == dwarf::DW_OP_plus)
2260 OffsetInBytes += Value;
2261 else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)
2262 OffsetInBytes -= Value;
2263 else
2264 return false;
2265 } else {
2266 // Not a const plus/minus operation or deref.
2267 return false;
2268 }
2269 ++ExprOpIt;
2270 }
2271 RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());
2272 return true;
2273}
2274
2276 int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const {
2277 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2278 if (!SingleLocEltsOpt) {
2279 OffsetInBytes = 0;
2280 RemainingOps.clear();
2281 return false;
2282 }
2283
2284 return extractLeadingOffset(*SingleLocEltsOpt, OffsetInBytes, RemainingOps);
2285}
2286
2289 for (auto ExprOp : expr_ops())
2290 if (auto Arg = dyn_cast<ArgOp>(ExprOp))
2291 SeenOps.insert(Arg.getIndex());
2292 for (uint64_t Idx = 0; Idx < N; ++Idx)
2293 if (!SeenOps.contains(Idx))
2294 return false;
2295 return true;
2296}
2297
2298const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,
2299 unsigned &AddrClass) {
2300 // FIXME: This seems fragile. Nothing that verifies that these elements
2301 // actually map to ops and not operands.
2302 auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements();
2303 if (!SingleLocEltsOpt)
2304 return nullptr;
2305 auto SingleLocElts = *SingleLocEltsOpt;
2306
2307 const unsigned PatternSize = 4;
2308 if (SingleLocElts.size() >= PatternSize &&
2309 SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu &&
2310 SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap &&
2311 SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) {
2312 AddrClass = SingleLocElts[PatternSize - 3];
2313
2314 if (SingleLocElts.size() == PatternSize)
2315 return nullptr;
2316 return DIExpression::get(
2317 Expr->getContext(),
2318 ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize));
2319 }
2320 return Expr;
2321}
2322
2323DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,
2324 int64_t Offset) {
2326 if (Flags & DIExpression::DerefBefore)
2327 Ops.push_back(dwarf::DW_OP_deref);
2328
2330 if (Flags & DIExpression::DerefAfter)
2331 Ops.push_back(dwarf::DW_OP_deref);
2332
2333 bool StackValue = Flags & DIExpression::StackValue;
2334 bool EntryValue = Flags & DIExpression::EntryValue;
2335
2336 return prependOpcodes(Expr, Ops, StackValue, EntryValue);
2337}
2338
2339DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
2341 unsigned ArgNo, bool StackValue) {
2342 assert(Expr && "Can't add ops to this expression");
2343
2344 // Handle non-variadic intrinsics by prepending the opcodes.
2345 if (!any_of(Expr->expr_ops(),
2346 [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); })) {
2347 assert(ArgNo == 0 &&
2348 "Location Index must be 0 for a non-variadic expression.");
2350 return DIExpression::prependOpcodes(Expr, NewOps, StackValue);
2351 }
2352
2354 for (auto Op : Expr->expr_ops()) {
2355 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2356 if (StackValue) {
2357 if (Op.getOp() == dwarf::DW_OP_stack_value)
2358 StackValue = false;
2359 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2360 NewOps.push_back(dwarf::DW_OP_stack_value);
2361 StackValue = false;
2362 }
2363 }
2364 Op.appendToVector(NewOps);
2365 if (auto Arg = dyn_cast<ArgOp>(Op); Arg && Arg.getIndex() == ArgNo)
2366 llvm::append_range(NewOps, Ops);
2367 }
2368 if (StackValue)
2369 NewOps.push_back(dwarf::DW_OP_stack_value);
2370
2371 return DIExpression::get(Expr->getContext(), NewOps);
2372}
2373
2374DIExpression *DIExpression::replaceArg(const DIExpression *Expr,
2375 uint64_t OldArg, uint64_t NewArg) {
2376 assert(Expr && "Can't replace args in this expression");
2377
2379
2380 for (auto Op : Expr->expr_ops()) {
2381 auto Arg = dyn_cast<ArgOp>(Op);
2382 if (!Arg || Arg.getIndex() < OldArg) {
2383 Op.appendToVector(NewOps);
2384 continue;
2385 }
2387 uint64_t ArgIndex = Arg.getIndex() == OldArg ? NewArg : Arg.getIndex();
2388 // OldArg has been deleted from the Op list, so decrement all indices
2389 // greater than it.
2390 if (ArgIndex > OldArg)
2391 --ArgIndex;
2392 NewOps.push_back(ArgIndex);
2393 }
2394 return DIExpression::get(Expr->getContext(), NewOps);
2395}
2396
2397DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
2399 bool StackValue, bool EntryValue) {
2400 assert(Expr && "Can't prepend ops to this expression");
2401
2402 if (EntryValue) {
2404 // Use a block size of 1 for the target register operand. The
2405 // DWARF backend currently cannot emit entry values with a block
2406 // size > 1.
2407 Ops.push_back(1);
2408 }
2409
2410 // If there are no ops to prepend, do not even add the DW_OP_stack_value.
2411 if (Ops.empty())
2412 StackValue = false;
2413 for (auto Op : Expr->expr_ops()) {
2414 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2415 if (StackValue) {
2416 if (Op.getOp() == dwarf::DW_OP_stack_value)
2417 StackValue = false;
2418 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2419 Ops.push_back(dwarf::DW_OP_stack_value);
2420 StackValue = false;
2421 }
2422 }
2423 Op.appendToVector(Ops);
2424 }
2425 if (StackValue)
2426 Ops.push_back(dwarf::DW_OP_stack_value);
2427 return DIExpression::get(Expr->getContext(), Ops);
2428}
2429
2430DIExpression *DIExpression::append(const DIExpression *Expr,
2432 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2433
2434 // Copy Expr's current op list.
2436 for (auto Op : Expr->expr_ops()) {
2437 // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
2438 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2439 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2440 NewOps.append(Ops.begin(), Ops.end());
2441
2442 // Ensure that the new opcodes are only appended once.
2443 Ops = {};
2444 }
2445 Op.appendToVector(NewOps);
2446 }
2447 NewOps.append(Ops.begin(), Ops.end());
2448 auto *result =
2449 DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath();
2450 assert(result->isValid() && "concatenated expression is not valid");
2451 return result;
2452}
2453
2454DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
2456 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2457 assert(std::none_of(expr_op_iterator(Ops.begin()),
2458 expr_op_iterator(Ops.end()),
2459 [](auto Op) {
2460 return Op.getOp() == dwarf::DW_OP_stack_value ||
2461 Op.getOp() == dwarf::DW_OP_LLVM_fragment;
2462 }) &&
2463 "Can't append this op");
2464
2465 // DIExpression stores opcodes and their arguments in a flat array. Walk the
2466 // parsed operations to find the last opcode that determines whether the
2467 // expression already ends in DW_OP_stack_value.
2468 std::optional<uint64_t> LastValueOp;
2469 for (auto Op : Expr->expr_ops()) {
2470 if (Op.isNonEmitting() || Op.getOp() == dwarf::DW_OP_LLVM_fragment)
2471 continue;
2472 LastValueOp = Op.getOp();
2473 }
2474 bool NeedsDeref = LastValueOp && *LastValueOp != dwarf::DW_OP_stack_value;
2475 bool NeedsStackValue = NeedsDeref || !LastValueOp;
2476
2477 // Append a DW_OP_deref after Expr's current op list if needed, then append
2478 // the new ops, and finally ensure that a single DW_OP_stack_value is present.
2480 if (NeedsDeref)
2481 NewOps.push_back(dwarf::DW_OP_deref);
2482 NewOps.append(Ops.begin(), Ops.end());
2483 if (NeedsStackValue)
2484 NewOps.push_back(dwarf::DW_OP_stack_value);
2485 return DIExpression::append(Expr, NewOps);
2486}
2487
2488std::optional<DIExpression *> DIExpression::createFragmentExpression(
2489 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
2491 // Track whether it's safe to split the value at the top of the DWARF stack,
2492 // assuming that it'll be used as an implicit location value.
2493 bool CanSplitValue = true;
2494 // Track whether we need to add a fragment expression to the end of Expr.
2495 bool EmitFragment = true;
2496 // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
2497 if (Expr) {
2498 for (auto Op : Expr->expr_ops()) {
2499 switch (Op.getOp()) {
2500 default:
2501 break;
2502 case dwarf::DW_OP_shr:
2503 case dwarf::DW_OP_shra:
2504 case dwarf::DW_OP_shl:
2505 case dwarf::DW_OP_plus:
2506 case dwarf::DW_OP_plus_uconst:
2507 case dwarf::DW_OP_minus:
2508 // We can't safely split arithmetic or shift operations into multiple
2509 // fragments because we can't express carry-over between fragments.
2510 //
2511 // FIXME: We *could* preserve the lowest fragment of a constant offset
2512 // operation if the offset fits into SizeInBits.
2513 CanSplitValue = false;
2514 break;
2515 case dwarf::DW_OP_deref:
2516 case dwarf::DW_OP_deref_size:
2517 case dwarf::DW_OP_deref_type:
2518 case dwarf::DW_OP_xderef:
2519 case dwarf::DW_OP_xderef_size:
2520 case dwarf::DW_OP_xderef_type:
2521 // Preceeding arithmetic operations have been applied to compute an
2522 // address. It's okay to split the value loaded from that address.
2523 CanSplitValue = true;
2524 break;
2525 case dwarf::DW_OP_stack_value:
2526 // Bail if this expression computes a value that cannot be split.
2527 if (!CanSplitValue)
2528 return std::nullopt;
2529 break;
2532 // If we've decided we don't need a fragment then give up if we see that
2533 // there's already a fragment expression.
2534 // FIXME: We could probably do better here
2535 if (!EmitFragment)
2536 return std::nullopt;
2537 // Make the new offset point into the existing fragment.
2538 uint64_t FragmentOffsetInBits = Fragment.getOffsetInBits();
2539 uint64_t FragmentSizeInBits = Fragment.getSizeInBits();
2540 (void)FragmentSizeInBits;
2541 assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
2542 "new fragment outside of original fragment");
2543 OffsetInBits += FragmentOffsetInBits;
2544 continue;
2545 }
2548 auto Extract = cast<ExtractBitsOp>(Op);
2549 // If we're extracting bits from inside of the fragment that we're
2550 // creating then we don't have a fragment after all, and just need to
2551 // adjust the offset that we're extracting from.
2552 uint64_t ExtractOffsetInBits = Extract.getOffsetInBits();
2553 uint64_t ExtractSizeInBits = Extract.getSizeInBits();
2554 if (ExtractOffsetInBits >= OffsetInBits &&
2555 ExtractOffsetInBits + ExtractSizeInBits <=
2556 OffsetInBits + SizeInBits) {
2557 Ops.push_back(Op.getOp());
2558 Ops.push_back(ExtractOffsetInBits - OffsetInBits);
2559 Ops.push_back(ExtractSizeInBits);
2560 EmitFragment = false;
2561 continue;
2562 }
2563 // If the extracted bits aren't fully contained within the fragment then
2564 // give up.
2565 // FIXME: We could probably do better here
2566 return std::nullopt;
2567 }
2568 }
2569 Op.appendToVector(Ops);
2570 }
2571 }
2572 assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");
2573 assert(Expr && "Unknown DIExpression");
2574 if (EmitFragment) {
2576 Ops.push_back(OffsetInBits);
2577 Ops.push_back(SizeInBits);
2578 }
2579 return DIExpression::get(Expr->getContext(), Ops);
2580}
2581
2582/// See declaration for more info.
2584 const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits,
2585 uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,
2586 int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag,
2587 std::optional<DIExpression::FragmentInfo> &Result,
2588 int64_t &OffsetFromLocationInBits) {
2589
2590 if (VarFrag.SizeInBits == 0)
2591 return false; // Variable size is unknown.
2592
2593 // Difference between mem slice start and the dbg location start.
2594 // 0 4 8 12 16 ...
2595 // | |
2596 // dbg location start
2597 // |
2598 // mem slice start
2599 // Here MemStartRelToDbgStartInBits is 8. Note this can be negative.
2600 int64_t MemStartRelToDbgStartInBits;
2601 {
2602 auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL);
2603 if (!MemOffsetFromDbgInBytes)
2604 return false; // Can't calculate difference in addresses.
2605 // Difference between the pointers.
2606 MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;
2607 // Add the difference of the offsets.
2608 MemStartRelToDbgStartInBits +=
2609 SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);
2610 }
2611
2612 // Out-param. Invert offset to get offset from debug location.
2613 OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;
2614
2615 // Check if the variable fragment sits outside (before) this memory slice.
2616 int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;
2617 if (MemEndRelToDbgStart < 0) {
2618 Result = {0, 0}; // Out-param.
2619 return true;
2620 }
2621
2622 // Work towards creating SliceOfVariable which is the bits of the variable
2623 // that the memory region covers.
2624 // 0 4 8 12 16 ...
2625 // | |
2626 // dbg location start with VarFrag offset=32
2627 // |
2628 // mem slice start: SliceOfVariable offset=40
2629 int64_t MemStartRelToVarInBits =
2630 MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;
2631 int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;
2632 // If the memory region starts before the debug location the fragment
2633 // offset would be negative, which we can't encode. Limit those to 0. This
2634 // is fine because those bits necessarily don't overlap with the existing
2635 // variable fragment.
2636 int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);
2637 int64_t MemFragSize =
2638 std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);
2639 DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart);
2640
2641 // Intersect the memory region fragment with the variable location fragment.
2642 DIExpression::FragmentInfo TrimmedSliceOfVariable =
2643 DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);
2644 if (TrimmedSliceOfVariable == VarFrag)
2645 Result = std::nullopt; // Out-param.
2646 else
2647 Result = TrimmedSliceOfVariable; // Out-param.
2648 return true;
2649}
2650
2651std::pair<DIExpression *, const ConstantInt *>
2653 // Copy the APInt so we can modify it.
2654 APInt NewInt = CI->getValue();
2656
2657 // Fold operators only at the beginning of the expression.
2658 bool First = true;
2659 bool Changed = false;
2660 for (auto Op : expr_ops()) {
2661 switch (Op.getOp()) {
2662 default:
2663 // We fold only the leading part of the expression; if we get to a part
2664 // that we're going to copy unchanged, and haven't done any folding,
2665 // then the entire expression is unchanged and we can return early.
2666 if (!Changed)
2667 return {this, CI};
2668 First = false;
2669 break;
2671 if (!First)
2672 break;
2673 Changed = true;
2674 auto Convert = cast<ConvertOp>(Op);
2675 if (Convert.getEncoding() == dwarf::DW_ATE_signed)
2676 NewInt = NewInt.sextOrTrunc(Convert.getBitSize());
2677 else {
2678 assert(Convert.getEncoding() == dwarf::DW_ATE_unsigned &&
2679 "Unexpected operand");
2680 NewInt = NewInt.zextOrTrunc(Convert.getBitSize());
2681 }
2682 continue;
2683 }
2684 }
2685 Op.appendToVector(Ops);
2686 }
2687 if (!Changed)
2688 return {this, CI};
2689 return {DIExpression::get(getContext(), Ops),
2690 ConstantInt::get(getContext(), NewInt)};
2691}
2692
2694 uint64_t Result = 0;
2695 for (auto ExprOp : expr_ops())
2696 if (auto Arg = dyn_cast<ArgOp>(ExprOp))
2697 Result = std::max(Result, Arg.getIndex() + 1);
2698 assert(hasAllLocationOps(Result) &&
2699 "Expression is missing one or more location operands.");
2700 return Result;
2701}
2702
2703std::optional<DIExpression::SignedOrUnsignedConstant>
2705
2706 // Recognize signed and unsigned constants.
2707 // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value
2708 // (DW_OP_LLVM_fragment of Len).
2709 // An unsigned constant can be represented as
2710 // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len).
2711
2712 if ((getNumElements() != 2 && getNumElements() != 3 &&
2713 getNumElements() != 6) ||
2714 (getElement(0) != dwarf::DW_OP_consts &&
2715 getElement(0) != dwarf::DW_OP_constu))
2716 return std::nullopt;
2717
2718 if (getNumElements() == 2 && getElement(0) == dwarf::DW_OP_consts)
2720
2721 if ((getNumElements() == 3 && getElement(2) != dwarf::DW_OP_stack_value) ||
2722 (getNumElements() == 6 && (getElement(2) != dwarf::DW_OP_stack_value ||
2724 return std::nullopt;
2725 return getElement(0) == dwarf::DW_OP_constu
2728}
2729
2730DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
2731 bool Signed) {
2732 dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
2734 dwarf::DW_OP_LLVM_convert, ToSize, TK}};
2735 return Ops;
2736}
2737
2738DIExpression *DIExpression::appendExt(const DIExpression *Expr,
2739 unsigned FromSize, unsigned ToSize,
2740 bool Signed) {
2741 return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
2742}
2743
2745DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
2747 bool ShouldCreate) {
2749 Metadata *Ops[] = {Variable, Expression};
2751}
2752DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
2753 unsigned Line, unsigned Attributes,
2755 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
2757
2758DIObjCProperty *DIObjCProperty::getImpl(
2759 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
2760 MDString *GetterName, MDString *SetterName, unsigned Attributes,
2761 Metadata *Type, StorageType Storage, bool ShouldCreate) {
2762 assert(isCanonical(Name) && "Expected canonical MDString");
2763 assert(isCanonical(GetterName) && "Expected canonical MDString");
2764 assert(isCanonical(SetterName) && "Expected canonical MDString");
2765 DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,
2766 SetterName, Attributes, Type));
2768 DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
2769}
2770
2771DIProperty::DIProperty(LLVMContext &C, StorageType Storage, unsigned Line,
2773 : DINode(C, DIPropertyKind, Storage, dwarf::DW_TAG_property, Ops),
2774 Line(Line) {}
2775
2776DIProperty *DIProperty::getImpl(LLVMContext &Context, MDString *Name,
2777 Metadata *File, unsigned Line, Metadata *Type,
2778 Metadata *BackingStorage, StorageType Storage,
2779 bool ShouldCreate) {
2780 assert(isCanonical(Name) && "Expected canonical MDString");
2781 DEFINE_GETIMPL_LOOKUP(DIProperty, (Name, File, Line, Type, BackingStorage));
2783 DEFINE_GETIMPL_STORE(DIProperty, (Line), Ops);
2784}
2785
2786DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
2787 Metadata *Scope, Metadata *Entity,
2788 Metadata *File, unsigned Line,
2789 MDString *Name, Metadata *Elements,
2790 StorageType Storage,
2791 bool ShouldCreate) {
2792 assert(isCanonical(Name) && "Expected canonical MDString");
2793 DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
2794 (Tag, Scope, Entity, File, Line, Name, Elements));
2796 DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
2797}
2798
2799DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2800 MDString *Name, MDString *Value, StorageType Storage,
2801 bool ShouldCreate) {
2802 assert(isCanonical(Name) && "Expected canonical MDString");
2804 Metadata *Ops[] = {Name, Value};
2805 DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
2806}
2807
2808DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
2809 unsigned Line, Metadata *File,
2810 Metadata *Elements, StorageType Storage,
2811 bool ShouldCreate) {
2812 DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements));
2813 Metadata *Ops[] = {File, Elements};
2814 DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
2815}
2816
2817DIArgList *DIArgList::get(LLVMContext &Context,
2819 auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));
2820 if (ExistingIt != Context.pImpl->DIArgLists.end())
2821 return *ExistingIt;
2822 DIArgList *NewArgList = new DIArgList(Context, Args);
2823 Context.pImpl->DIArgLists.insert(NewArgList);
2824 return NewArgList;
2825}
2826
2828 ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);
2829 assert((!New || isa<ValueAsMetadata>(New)) &&
2830 "DIArgList must be passed a ValueAsMetadata");
2831 untrack();
2832 // We need to update the set storage once the Args are updated since they
2833 // form the key to the DIArgLists store.
2834 getContext().pImpl->DIArgLists.erase(this);
2836 for (ValueAsMetadata *&VM : Args) {
2837 if (&VM == OldVMPtr) {
2838 if (NewVM)
2839 VM = NewVM;
2840 else
2841 VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));
2842 }
2843 }
2844 // We've changed the contents of this DIArgList, and the set storage may
2845 // already contain a DIArgList with our new set of args; if it does, then we
2846 // must RAUW this with the existing DIArgList, otherwise we simply insert this
2847 // back into the set storage.
2848 DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);
2849 if (ExistingArgList) {
2850 replaceAllUsesWith(ExistingArgList);
2851 // Clear this here so we don't try to untrack in the destructor.
2852 Args.clear();
2853 delete this;
2854 return;
2855 }
2856 getContext().pImpl->DIArgLists.insert(this);
2857 track();
2858}
2859void DIArgList::track() {
2860 for (ValueAsMetadata *&VAM : Args)
2861 if (VAM)
2862 MetadataTracking::track(&VAM, *VAM, *this);
2863}
2864void DIArgList::untrack() {
2865 for (ValueAsMetadata *&VAM : Args)
2866 if (VAM)
2867 MetadataTracking::untrack(&VAM, *VAM);
2868}
2869void DIArgList::dropAllReferences(bool Untrack) {
2870 if (Untrack)
2871 untrack();
2872 Args.clear();
2873 ReplaceableUses::resolveAllUses(/* ResolveUsers */ false);
2874}
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
size_t size() const
Get the array size.
Definition ArrayRef.h:141
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)
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.
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 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 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 last 4 elements of the expression are DW_OP_constu <DWARFAddress Space> DW_OP_swap DW_O...
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
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."))
@ Keep
No function return thunk.
Definition CodeGen.h:307
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