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