LLVM 24.0.0git
DebugInfoMetadata.cpp
Go to the documentation of this file.
1//===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the debug info Metadata classes.
10//
11//===----------------------------------------------------------------------===//
12
14#include "LLVMContextImpl.h"
15#include "MetadataImpl.h"
16#include "llvm/ADT/SetVector.h"
20#include "llvm/IR/Function.h"
22#include "llvm/IR/Type.h"
23#include "llvm/IR/Value.h"
26
27#include <numeric>
28#include <optional>
29
30using namespace llvm;
31
32namespace llvm {
33// Use FS-AFDO discriminator.
35 "enable-fs-discriminator", cl::Hidden,
36 cl::desc("Enable adding flow sensitive discriminators"));
37
38// When true, preserves line and column number by picking one of the merged
39// location info in a deterministic manner to assist sample based PGO.
41 "pick-merged-source-locations", cl::init(false), cl::Hidden,
42 cl::desc("Preserve line and column number when merging locations."));
43} // namespace llvm
44
46 return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32);
47}
48
49const DIExpression::FragmentInfo DebugVariable::DefaultFragment = {
50 std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};
51
53 : Variable(DVR->getVariable()),
54 Fragment(DVR->getExpression()->getFragmentInfo()),
55 InlinedAt(DVR->getDebugLoc().getInlinedAt()) {}
56
60
61DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
62 unsigned Column, uint64_t AtomGroup, uint8_t AtomRank,
63 ArrayRef<Metadata *> MDs, bool ImplicitCode)
64 : MDNode(C, DILocationKind, Storage, MDs), AtomGroup(AtomGroup),
65 AtomRank(AtomRank) {
66 assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits");
67 if (AtomGroup)
68 C.updateDILocationAtomGroupWaterline(AtomGroup + 1);
69
70 assert((MDs.size() == 1 || MDs.size() == 2) &&
71 "Expected a scope and optional inlined-at");
72 // Set line and column.
73 assert(Column < (1u << 16) && "Expected 16-bit column");
74
75 SubclassData32 = Line;
76 SubclassData16 = Column;
77
78 setImplicitCode(ImplicitCode);
79}
80
81static void adjustColumn(unsigned &Column) {
82 // Set to unknown on overflow. We only have 16 bits to play with here.
83 if (Column >= (1u << 16))
84 Column = 0;
85}
86
87DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
88 unsigned Column, Metadata *Scope,
89 Metadata *InlinedAt, bool ImplicitCode,
90 uint64_t AtomGroup, uint8_t AtomRank,
91 StorageType Storage, bool ShouldCreate) {
92 // Fixup column.
94
95 if (Storage == Uniqued) {
96 if (auto *N = getUniqued(Context.pImpl->DILocations,
97 DILocationInfo::KeyTy(Line, Column, Scope,
99 AtomGroup, AtomRank)))
100 return N;
101 if (!ShouldCreate)
102 return nullptr;
103 } else {
104 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
105 }
106
108 Ops.push_back(Scope);
109 if (InlinedAt)
110 Ops.push_back(InlinedAt);
111 return storeImpl(new (Ops.size(), Storage)
112 DILocation(Context, Storage, Line, Column, AtomGroup,
113 AtomRank, Ops, ImplicitCode),
114 Storage, Context.pImpl->DILocations);
115}
116
118 if (Locs.empty())
119 return nullptr;
120 if (Locs.size() == 1)
121 return Locs[0];
122 auto *Merged = Locs[0];
123 for (DILocation *L : llvm::drop_begin(Locs)) {
124 Merged = getMergedLocation(Merged, L);
125 if (Merged == nullptr)
126 break;
127 }
128 return Merged;
129}
130
132 DIScope *NewParent) {
133 TempMDNode ClonedScope = LBB->clone();
134 cast<DILexicalBlockBase>(*ClonedScope).replaceScope(NewParent);
136 MDNode::replaceWithUniqued(std::move(ClonedScope)));
137}
138
139using LineColumn = std::pair<unsigned /* Line */, unsigned /* Column */>;
140
141/// Returns the location of DILocalScope, if present, or a default value.
143 assert(isa<DILocalScope>(S) && "Expected DILocalScope.");
144
146 return Default;
147 if (auto *LB = dyn_cast<DILexicalBlock>(S))
148 return {LB->getLine(), LB->getColumn()};
149 if (auto *SP = dyn_cast<DISubprogram>(S))
150 return {SP->getLine(), 0u};
151
152 llvm_unreachable("Unhandled type of DILocalScope.");
153}
154
155// Returns the nearest matching scope inside a subprogram.
156template <typename MatcherT>
157static std::pair<DIScope *, LineColumn>
159 MatcherT Matcher;
160
161 DIScope *S1 = L1->getScope();
162 DIScope *S2 = L2->getScope();
163
164 LineColumn Loc1(L1->getLine(), L1->getColumn());
165 for (; S1; S1 = S1->getScope()) {
166 Loc1 = getLocalScopeLocationOr(S1, Loc1);
167 Matcher.insert(S1, Loc1);
169 break;
170 }
171
172 LineColumn Loc2(L2->getLine(), L2->getColumn());
173 for (; S2; S2 = S2->getScope()) {
174 Loc2 = getLocalScopeLocationOr(S2, Loc2);
175
176 if (DIScope *S = Matcher.match(S2, Loc2))
177 return std::make_pair(S, Loc2);
178
179 if (isa<DISubprogram>(S2))
180 break;
181 }
182 return std::make_pair(nullptr, LineColumn(L2->getLine(), L2->getColumn()));
183}
184
185// Matches equal scopes.
188
189 void insert(DIScope *S, LineColumn Loc) { Scopes.insert(S); }
190
192 return Scopes.contains(S) ? S : nullptr;
193 }
194};
195
196// Matches scopes with the same location.
199 8>
201
203 Scopes[{S->getFile(), Loc}].insert(S);
204 }
205
207 auto ScopesAtLoc = Scopes.find({S->getFile(), Loc});
208 // No scope found with the given location.
209 if (ScopesAtLoc == Scopes.end())
210 return nullptr;
211
212 // Prefer S over other scopes with the same location.
213 if (ScopesAtLoc->second.contains(S))
214 return S;
215
216 if (!ScopesAtLoc->second.empty())
217 return *ScopesAtLoc->second.begin();
218
219 llvm_unreachable("Scopes must not have empty entries.");
220 }
221};
222
223DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) {
224 if (LocA == LocB)
225 return LocA;
226
227 // For some use cases (SamplePGO), it is important to retain distinct source
228 // locations. When this flag is set, we choose arbitrarily between A and B,
229 // rather than computing a merged location using line 0, which is typically
230 // not useful for PGO. If one of them is null, then try to return one which is
231 // valid.
233 if (!LocA || !LocB)
234 return LocA ? LocA : LocB;
235
236 auto A = std::make_tuple(LocA->getLine(), LocA->getColumn(),
237 LocA->getDiscriminator(), LocA->getFilename(),
238 LocA->getDirectory());
239 auto B = std::make_tuple(LocB->getLine(), LocB->getColumn(),
240 LocB->getDiscriminator(), LocB->getFilename(),
241 LocB->getDirectory());
242 return A < B ? LocA : LocB;
243 }
244
245 if (!LocA || !LocB)
246 return nullptr;
247
248 LLVMContext &C = LocA->getContext();
249
250 using LocVec = SmallVector<const DILocation *>;
251 LocVec ALocs;
252 LocVec BLocs;
254 4>
255 ALookup;
256
257 // Walk through LocA and its inlined-at locations, populate them in ALocs and
258 // save the index for the subprogram and inlined-at pair, which we use to find
259 // a matching starting location in LocB's chain.
260 for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) {
261 ALocs.push_back(L);
262 auto Res = ALookup.try_emplace(
263 {L->getScope()->getSubprogram(), L->getInlinedAt()}, I);
264 assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?");
265 (void)Res;
266 }
267
268 LocVec::reverse_iterator ARIt = ALocs.rend();
269 LocVec::reverse_iterator BRIt = BLocs.rend();
270
271 // Populate BLocs and look for a matching starting location, the first
272 // location with the same subprogram and inlined-at location as in LocA's
273 // chain. Since the two locations have the same inlined-at location we do
274 // not need to look at those parts of the chains.
275 for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) {
276 BLocs.push_back(L);
277
278 if (ARIt != ALocs.rend())
279 // We have already found a matching starting location.
280 continue;
281
282 auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()});
283 if (IT == ALookup.end())
284 continue;
285
286 // The + 1 is to account for the &*rev_it = &(it - 1) relationship.
287 ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1);
288 BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1);
289
290 // If we have found a matching starting location we do not need to add more
291 // locations to BLocs, since we will only look at location pairs preceding
292 // the matching starting location, and adding more elements to BLocs could
293 // invalidate the iterator that we initialized here.
294 break;
295 }
296
297 // Merge the two locations if possible, using the supplied
298 // inlined-at location for the created location.
299 auto *LocAIA = LocA->getInlinedAt();
300 auto *LocBIA = LocB->getInlinedAt();
301 auto MergeLocPair = [&C, LocAIA,
302 LocBIA](const DILocation *L1, const DILocation *L2,
303 DILocation *InlinedAt) -> DILocation * {
304 if (L1 == L2)
305 return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(),
306 InlinedAt, L1->isImplicitCode(),
307 L1->getAtomGroup(), L1->getAtomRank());
308
309 // If the locations originate from different subprograms we can't produce
310 // a common location.
311 if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())
312 return nullptr;
313
314 // Find nearest common scope inside subprogram.
316 assert(Scope && "No common scope in the same subprogram?");
317
318 // Try using the nearest scope with common location if files are different.
319 if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile()) {
320 auto [CommonLocScope, CommonLoc] =
322
323 // If CommonLocScope is a DILexicalBlockBase, clone it and locate
324 // a new scope inside the nearest common scope to preserve
325 // lexical blocks structure.
326 if (auto *LBB = dyn_cast<DILexicalBlockBase>(CommonLocScope);
327 LBB && LBB != Scope)
328 CommonLocScope = cloneAndReplaceParentScope(LBB, Scope);
329
330 Scope = CommonLocScope;
331
332 // If files are still different, assume that L1 and L2 were "included"
333 // from CommonLoc. Use it as merged location.
334 if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile())
335 return DILocation::get(C, CommonLoc.first, CommonLoc.second,
336 CommonLocScope, InlinedAt);
337 }
338
339 bool SameLine = L1->getLine() == L2->getLine();
340 bool SameCol = L1->getColumn() == L2->getColumn();
341 unsigned Line = SameLine ? L1->getLine() : 0;
342 unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;
343 bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode();
344
345 // Discard source location atom if the line becomes 0. And there's nothing
346 // further to do if neither location has an atom number.
347 if (!SameLine || !(L1->getAtomGroup() || L2->getAtomGroup()))
348 return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
349 /*AtomGroup*/ 0, /*AtomRank*/ 0);
350
351 uint64_t Group = 0;
352 uint64_t Rank = 0;
353 // If we're preserving the same matching inlined-at field we can
354 // preserve the atom.
355 if (LocBIA == LocAIA && InlinedAt == LocBIA) {
356 // Deterministically keep the lowest non-zero ranking atom group
357 // number.
358 // FIXME: It would be nice if we could track that an instruction
359 // belongs to two source atoms.
360 bool UseL1Atom = [L1, L2]() {
361 if (L1->getAtomRank() == L2->getAtomRank()) {
362 // Arbitrarily choose the lowest non-zero group number.
363 if (!L1->getAtomGroup() || !L2->getAtomGroup())
364 return !L2->getAtomGroup();
365 return L1->getAtomGroup() < L2->getAtomGroup();
366 }
367 // Choose the lowest non-zero rank.
368 if (!L1->getAtomRank() || !L2->getAtomRank())
369 return !L2->getAtomRank();
370 return L1->getAtomRank() < L2->getAtomRank();
371 }();
372 Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup();
373 Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank();
374 } else {
375 // If either instruction is part of a source atom, reassign it a new
376 // atom group. This essentially regresses to non-key-instructions
377 // behaviour (now that it's the only instruction in its group it'll
378 // probably get is_stmt applied).
379 Group = C.incNextDILocationAtomGroup();
380 Rank = 1;
381 }
382 return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
383 Group, Rank);
384 };
385
386 DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr;
387
388 // If we have found a common starting location, walk up the inlined-at chains
389 // and try to produce common locations.
390 for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {
391 DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);
392
393 if (!Tmp)
394 // We have walked up to a point in the chains where the two locations
395 // are irreconsilable. At this point Result contains the nearest common
396 // location in the inlined-at chains of LocA and LocB, so we break here.
397 break;
398
399 Result = Tmp;
400 }
401
402 if (Result)
403 return Result;
404
405 // We ended up with LocA and LocB as irreconsilable locations. Produce a
406 // location at 0:0 with one of the locations' scope. The function has
407 // historically picked A's scope, and a nullptr inlined-at location, so that
408 // behavior is mimicked here but I am not sure if this is always the correct
409 // way to handle this.
410 // Key Instructions: it's fine to drop atom group and rank here, as line 0
411 // is a nonsensical is_stmt location.
412 return DILocation::get(C, 0, 0, LocA->getScope(), nullptr, false,
413 /*AtomGroup*/ 0, /*AtomRank*/ 0);
414}
415
416std::optional<unsigned>
417DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
418 std::array<unsigned, 3> Components = {BD, DF, CI};
419 uint64_t RemainingWork = 0U;
420 // We use RemainingWork to figure out if we have no remaining components to
421 // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
422 // encode anything for the latter 2.
423 // Since any of the input components is at most 32 bits, their sum will be
424 // less than 34 bits, and thus RemainingWork won't overflow.
425 RemainingWork =
426 std::accumulate(Components.begin(), Components.end(), RemainingWork);
427
428 int I = 0;
429 unsigned Ret = 0;
430 unsigned NextBitInsertionIndex = 0;
431 while (RemainingWork > 0) {
432 unsigned C = Components[I++];
433 RemainingWork -= C;
434 unsigned EC = encodeComponent(C);
435 Ret |= (EC << NextBitInsertionIndex);
436 NextBitInsertionIndex += encodingBits(C);
437 }
438
439 // Encoding may be unsuccessful because of overflow. We determine success by
440 // checking equivalence of components before & after encoding. Alternatively,
441 // we could determine Success during encoding, but the current alternative is
442 // simpler.
443 unsigned TBD, TDF, TCI = 0;
444 decodeDiscriminator(Ret, TBD, TDF, TCI);
445 if (TBD == BD && TDF == DF && TCI == CI)
446 return Ret;
447 return std::nullopt;
448}
449
458
460 return StringSwitch<DIFlags>(Flag)
461#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
462#include "llvm/IR/DebugInfoFlags.def"
463 .Default(DINode::FlagZero);
464}
465
467 switch (Flag) {
468#define HANDLE_DI_FLAG(ID, NAME) \
469 case Flag##NAME: \
470 return "DIFlag" #NAME;
471#include "llvm/IR/DebugInfoFlags.def"
472 }
473 return "";
474}
475
477 SmallVectorImpl<DIFlags> &SplitFlags) {
478 // Flags that are packed together need to be specially handled, so
479 // that, for example, we emit "DIFlagPublic" and not
480 // "DIFlagPrivate | DIFlagProtected".
481 if (DIFlags A = Flags & FlagAccessibility) {
482 if (A == FlagPrivate)
483 SplitFlags.push_back(FlagPrivate);
484 else if (A == FlagProtected)
485 SplitFlags.push_back(FlagProtected);
486 else
487 SplitFlags.push_back(FlagPublic);
488 Flags &= ~A;
489 }
490 if (DIFlags R = Flags & FlagPtrToMemberRep) {
491 if (R == FlagSingleInheritance)
492 SplitFlags.push_back(FlagSingleInheritance);
493 else if (R == FlagMultipleInheritance)
494 SplitFlags.push_back(FlagMultipleInheritance);
495 else
496 SplitFlags.push_back(FlagVirtualInheritance);
497 Flags &= ~R;
498 }
499 if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
500 Flags &= ~FlagIndirectVirtualBase;
501 SplitFlags.push_back(FlagIndirectVirtualBase);
502 }
503
504#define HANDLE_DI_FLAG(ID, NAME) \
505 if (DIFlags Bit = Flags & Flag##NAME) { \
506 SplitFlags.push_back(Bit); \
507 Flags &= ~Bit; \
508 }
509#include "llvm/IR/DebugInfoFlags.def"
510 return Flags;
511}
512
514 if (auto *T = dyn_cast<DIType>(this))
515 return T->getScope();
516
517 if (auto *SP = dyn_cast<DISubprogram>(this))
518 return SP->getScope();
519
520 if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
521 return LB->getScope();
522
523 if (auto *NS = dyn_cast<DINamespace>(this))
524 return NS->getScope();
525
526 if (auto *CB = dyn_cast<DICommonBlock>(this))
527 return CB->getScope();
528
529 if (auto *M = dyn_cast<DIModule>(this))
530 return M->getScope();
531
532 assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
533 "Unhandled type of scope.");
534 return nullptr;
535}
536
538 if (auto *T = dyn_cast<DIType>(this))
539 return T->getName();
540 if (auto *SP = dyn_cast<DISubprogram>(this))
541 return SP->getName();
542 if (auto *NS = dyn_cast<DINamespace>(this))
543 return NS->getName();
544 if (auto *CB = dyn_cast<DICommonBlock>(this))
545 return CB->getName();
546 if (auto *M = dyn_cast<DIModule>(this))
547 return M->getName();
549 isa<DICompileUnit>(this)) &&
550 "Unhandled type of scope.");
551 return "";
552}
553
554#ifndef NDEBUG
555static bool isCanonical(const MDString *S) {
556 return !S || !S->getString().empty();
557}
558#endif
559
561GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
562 MDString *Header,
563 ArrayRef<Metadata *> DwarfOps,
564 StorageType Storage, bool ShouldCreate) {
565 unsigned Hash = 0;
566 if (Storage == Uniqued) {
567 GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);
568 if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))
569 return N;
570 if (!ShouldCreate)
571 return nullptr;
572 Hash = Key.getHash();
573 } else {
574 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
575 }
576
577 // Use a nullptr for empty headers.
578 assert(isCanonical(Header) && "Expected canonical MDString");
579 Metadata *PreOps[] = {Header};
580 return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(
581 Context, Storage, Hash, Tag, PreOps, DwarfOps),
582 Storage, Context.pImpl->GenericDINodes);
583}
584
585void GenericDINode::recalculateHash() {
586 setHash(GenericDINodeInfo::KeyTy::calculateHash(this));
587}
588
589#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
590#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
591#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \
592 do { \
593 if (Storage == Uniqued) { \
594 if (auto *N = getUniqued(Context.pImpl->CLASS##s, \
595 CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \
596 return N; \
597 if (!ShouldCreate) \
598 return nullptr; \
599 } else { \
600 assert(ShouldCreate && \
601 "Expected non-uniqued nodes to always be created"); \
602 } \
603 } while (false)
604#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \
605 return storeImpl(new (std::size(OPS), Storage) \
606 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
607 Storage, Context.pImpl->CLASS##s)
608#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \
609 return storeImpl(new (0u, Storage) \
610 CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
611 Storage, Context.pImpl->CLASS##s)
612#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \
613 return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \
614 Storage, Context.pImpl->CLASS##s)
615#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \
616 return storeImpl(new (NUM_OPS, Storage) \
617 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
618 Storage, Context.pImpl->CLASS##s)
619
620DISubrange::DISubrange(LLVMContext &C, StorageType Storage,
622 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
623DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
624 StorageType Storage, bool ShouldCreate) {
627 auto *LB = ConstantAsMetadata::get(
629 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
630 ShouldCreate);
631}
632
633DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
634 int64_t Lo, StorageType Storage,
635 bool ShouldCreate) {
636 auto *LB = ConstantAsMetadata::get(
638 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
639 ShouldCreate);
640}
641
642DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
643 Metadata *LB, Metadata *UB, Metadata *Stride,
644 StorageType Storage, bool ShouldCreate) {
645 DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride));
646 Metadata *Ops[] = {CountNode, LB, UB, Stride};
648}
649
650DISubrange::BoundType DISubrange::getCount() const {
651 Metadata *CB = getRawCountNode();
652 if (!CB)
653 return BoundType();
654
656 isa<DIExpression>(CB)) &&
657 "Count must be signed constant or DIVariable or DIExpression");
658
659 if (auto *MD = dyn_cast<ConstantAsMetadata>(CB))
660 return BoundType(cast<ConstantInt>(MD->getValue()));
661
662 if (auto *MD = dyn_cast<DIVariable>(CB))
663 return BoundType(MD);
664
665 if (auto *MD = dyn_cast<DIExpression>(CB))
666 return BoundType(MD);
667
668 return BoundType();
669}
670
671DISubrange::BoundType DISubrange::getLowerBound() const {
672 Metadata *LB = getRawLowerBound();
673 if (!LB)
674 return BoundType();
675
677 isa<DIExpression>(LB)) &&
678 "LowerBound must be signed constant or DIVariable or DIExpression");
679
680 if (auto *MD = dyn_cast<ConstantAsMetadata>(LB))
681 return BoundType(cast<ConstantInt>(MD->getValue()));
682
683 if (auto *MD = dyn_cast<DIVariable>(LB))
684 return BoundType(MD);
685
686 if (auto *MD = dyn_cast<DIExpression>(LB))
687 return BoundType(MD);
688
689 return BoundType();
690}
691
692DISubrange::BoundType DISubrange::getUpperBound() const {
693 Metadata *UB = getRawUpperBound();
694 if (!UB)
695 return BoundType();
696
698 isa<DIExpression>(UB)) &&
699 "UpperBound must be signed constant or DIVariable or DIExpression");
700
701 if (auto *MD = dyn_cast<ConstantAsMetadata>(UB))
702 return BoundType(cast<ConstantInt>(MD->getValue()));
703
704 if (auto *MD = dyn_cast<DIVariable>(UB))
705 return BoundType(MD);
706
707 if (auto *MD = dyn_cast<DIExpression>(UB))
708 return BoundType(MD);
709
710 return BoundType();
711}
712
713DISubrange::BoundType DISubrange::getStride() const {
714 Metadata *ST = getRawStride();
715 if (!ST)
716 return BoundType();
717
719 isa<DIExpression>(ST)) &&
720 "Stride must be signed constant or DIVariable or DIExpression");
721
722 if (auto *MD = dyn_cast<ConstantAsMetadata>(ST))
723 return BoundType(cast<ConstantInt>(MD->getValue()));
724
725 if (auto *MD = dyn_cast<DIVariable>(ST))
726 return BoundType(MD);
727
728 if (auto *MD = dyn_cast<DIExpression>(ST))
729 return BoundType(MD);
730
731 return BoundType();
732}
733DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,
735 : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
736 Ops) {}
737
738DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
739 Metadata *CountNode, Metadata *LB,
740 Metadata *UB, Metadata *Stride,
741 StorageType Storage,
742 bool ShouldCreate) {
743 DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
744 Metadata *Ops[] = {CountNode, LB, UB, Stride};
746}
747
750 if (!CB)
751 return BoundType();
752
754 "Count must be signed constant or DIVariable or DIExpression");
755
756 if (auto *MD = dyn_cast<DIVariable>(CB))
757 return BoundType(MD);
758
759 if (auto *MD = dyn_cast<DIExpression>(CB))
760 return BoundType(MD);
761
762 return BoundType();
763}
764
767 if (!LB)
768 return BoundType();
769
771 "LowerBound must be signed constant or DIVariable or DIExpression");
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
784 if (!UB)
785 return BoundType();
786
788 "UpperBound must be signed constant or DIVariable or DIExpression");
789
790 if (auto *MD = dyn_cast<DIVariable>(UB))
791 return BoundType(MD);
792
793 if (auto *MD = dyn_cast<DIExpression>(UB))
794 return BoundType(MD);
795
796 return BoundType();
797}
798
800 Metadata *ST = getRawStride();
801 if (!ST)
802 return BoundType();
803
805 "Stride must be signed constant or DIVariable or DIExpression");
806
807 if (auto *MD = dyn_cast<DIVariable>(ST))
808 return BoundType(MD);
809
810 if (auto *MD = dyn_cast<DIExpression>(ST))
811 return BoundType(MD);
812
813 return BoundType();
814}
815
816DISubrangeType::DISubrangeType(LLVMContext &C, StorageType Storage,
817 unsigned Line, uint32_t AlignInBits,
818 DIFlags Flags, ArrayRef<Metadata *> Ops)
819 : DIType(C, DISubrangeTypeKind, Storage, dwarf::DW_TAG_subrange_type, Line,
820 AlignInBits, 0, Flags, Ops) {}
821
822DISubrangeType *DISubrangeType::getImpl(
823 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
824 Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags,
825 Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
826 Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate) {
827 assert(isCanonical(Name) && "Expected canonical MDString");
829 AlignInBits, Flags, BaseType,
831 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr,
833 DEFINE_GETIMPL_STORE(DISubrangeType, (Line, AlignInBits, Flags), Ops);
834}
835
837DISubrangeType::convertRawToBound(Metadata *IN) const {
838 if (!IN)
839 return BoundType();
840
843
844 if (auto *MD = dyn_cast<ConstantAsMetadata>(IN))
845 return BoundType(cast<ConstantInt>(MD->getValue()));
846
847 if (auto *MD = dyn_cast<DIVariable>(IN))
848 return BoundType(MD);
849
850 if (auto *MD = dyn_cast<DIExpression>(IN))
851 return BoundType(MD);
852
853 if (auto *DT = dyn_cast<DIDerivedType>(IN))
854 return BoundType(DT);
855
856 return BoundType();
857}
858
859DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,
860 const APInt &Value, bool IsUnsigned,
862 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
863 Value(Value) {
864 SubclassData32 = IsUnsigned;
865}
866DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
867 bool IsUnsigned, MDString *Name,
868 StorageType Storage, bool ShouldCreate) {
869 assert(isCanonical(Name) && "Expected canonical MDString");
870 DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
871 Metadata *Ops[] = {Name};
872 DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
873}
874
877 unsigned LineNo, Metadata *Scope,
879 unsigned Encoding,
881 uint32_t DataSizeInBits, DIFlags Flags,
882 StorageType Storage, bool ShouldCreate) {
883 assert(isCanonical(Name) && "Expected canonical MDString");
886 Encoding, NumExtraInhabitants, DataSizeInBits, Flags));
887 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr};
890 DataSizeInBits, Flags),
891 Ops);
892}
893
894std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
895 switch (getEncoding()) {
896 case dwarf::DW_ATE_signed:
897 case dwarf::DW_ATE_signed_char:
898 case dwarf::DW_ATE_signed_fixed:
899 return Signedness::Signed;
900 case dwarf::DW_ATE_unsigned:
901 case dwarf::DW_ATE_unsigned_char:
902 case dwarf::DW_ATE_unsigned_fixed:
904 default:
905 return std::nullopt;
906 }
907}
908
910DIFixedPointType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
911 Metadata *File, unsigned LineNo, Metadata *Scope,
912 Metadata *SizeInBits, uint32_t AlignInBits,
913 unsigned Encoding, DIFlags Flags, unsigned Kind,
914 int Factor, APInt Numerator, APInt Denominator,
915 StorageType Storage, bool ShouldCreate) {
917 (Tag, Name, File, LineNo, Scope, SizeInBits,
918 AlignInBits, Encoding, Flags, Kind, Factor, Numerator,
919 Denominator));
920 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr};
922 (Tag, LineNo, AlignInBits, Encoding, Flags, Kind, Factor,
924 Ops);
925}
926
928 return getEncoding() == dwarf::DW_ATE_signed_fixed;
929}
930
931std::optional<DIFixedPointType::FixedPointKind>
934 .Case("Binary", FixedPointBinary)
935 .Case("Decimal", FixedPointDecimal)
936 .Case("Rational", FixedPointRational)
937 .Default(std::nullopt);
938}
939
941 switch (V) {
942 case FixedPointBinary:
943 return "Binary";
945 return "Decimal";
947 return "Rational";
948 }
949 return nullptr;
950}
951
952DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
953 MDString *Name, Metadata *StringLength,
954 Metadata *StringLengthExp,
955 Metadata *StringLocationExp,
956 Metadata *SizeInBits, uint32_t AlignInBits,
957 unsigned Encoding, StorageType Storage,
958 bool ShouldCreate) {
959 assert(isCanonical(Name) && "Expected canonical MDString");
963 Metadata *Ops[] = {nullptr, nullptr, Name,
964 SizeInBits, nullptr, StringLength,
967}
969 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
971}
972
973// Helper function to extract ConstantAsMetadata from ExtraData,
974// handling extra data MDTuple unwrapping if needed.
976 Metadata *ED = ExtraData;
977 if (auto *Tuple = dyn_cast_or_null<MDTuple>(ED)) {
978 if (Tuple->getNumOperands() != 1)
979 return nullptr;
980 ED = Tuple->getOperand(0);
981 }
983}
984
986 assert(getTag() == dwarf::DW_TAG_inheritance);
987 if (auto *CM = extractConstantMetadata(getExtraData()))
988 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
989 return static_cast<uint32_t>(CI->getZExtValue());
990 return 0;
991}
993 assert(getTag() == dwarf::DW_TAG_member && isBitField());
995 return C->getValue();
996 return nullptr;
997}
998
1000 assert((getTag() == dwarf::DW_TAG_member ||
1001 getTag() == dwarf::DW_TAG_variable) &&
1002 isStaticMember());
1003 if (auto *C = extractConstantMetadata(getExtraData()))
1004 return C->getValue();
1005 return nullptr;
1006}
1008 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
1009 if (auto *C = extractConstantMetadata(getExtraData()))
1010 return C->getValue();
1011 return nullptr;
1012}
1013
1014DIDerivedType *DIDerivedType::getImpl(
1015 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1016 unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
1017 uint32_t AlignInBits, Metadata *OffsetInBits,
1018 std::optional<unsigned> DWARFAddressSpace,
1019 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData,
1020 Metadata *Annotations, StorageType Storage, bool ShouldCreate) {
1021 assert(isCanonical(Name) && "Expected canonical MDString");
1023 (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1025 PtrAuthData, Flags, ExtraData, Annotations));
1026 Metadata *Ops[] = {File, Scope, Name, SizeInBits,
1027 OffsetInBits, BaseType, ExtraData, Annotations};
1030 (Tag, Line, AlignInBits, DWARFAddressSpace, PtrAuthData, Flags), Ops);
1031}
1032
1033std::optional<DIDerivedType::PtrAuthData>
1034DIDerivedType::getPtrAuthData() const {
1035 return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type
1036 ? std::make_optional<PtrAuthData>(SubclassData32)
1037 : std::nullopt;
1038}
1039
1040DICompositeType *DICompositeType::getImpl(
1041 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1042 unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
1043 uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags,
1044 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1045 Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
1046 Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
1047 Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
1048 Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride,
1049 StorageType Storage, bool ShouldCreate) {
1050 assert(isCanonical(Name) && "Expected canonical MDString");
1051
1052 // Keep this in sync with buildODRType.
1054 DICompositeType,
1064 DEFINE_GETIMPL_STORE(DICompositeType,
1065 (Tag, Line, RuntimeLang, AlignInBits,
1066 NumExtraInhabitants, EnumKind, Flags),
1067 Ops);
1068}
1069
1071 LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
1075 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1079 assert(!Identifier.getString().empty() && "Expected valid identifier");
1080 if (!Context.isODRUniquingDebugTypes())
1081 return nullptr;
1082 auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
1083 if (!CT)
1084 return CT = DICompositeType::getDistinct(
1085 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1086 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
1090 if (CT->getTag() != Tag)
1091 return nullptr;
1092
1093 // Only mutate CT if it's a forward declaration and the new operands aren't.
1094 assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
1095 if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))
1096 return CT;
1097
1098 // Mutate CT in place. Keep this in sync with getImpl.
1099 CT->mutate(Tag, Line, RuntimeLang, AlignInBits, NumExtraInhabitants, EnumKind,
1100 Flags);
1106 assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
1107 "Mismatched number of operands");
1108 for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
1109 if (Ops[I] != CT->getOperand(I))
1110 CT->setOperand(I, Ops[I]);
1111 return CT;
1112}
1113
1114DICompositeType *DICompositeType::getODRType(
1115 LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
1116 Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
1117 Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
1118 Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
1119 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1120 Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
1121 Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1122 Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
1123 assert(!Identifier.getString().empty() && "Expected valid identifier");
1124 if (!Context.isODRUniquingDebugTypes())
1125 return nullptr;
1126 auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
1127 if (!CT) {
1129 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1134 } else {
1135 if (CT->getTag() != Tag)
1136 return nullptr;
1137 }
1138 return CT;
1139}
1140
1143 assert(!Identifier.getString().empty() && "Expected valid identifier");
1144 if (!Context.isODRUniquingDebugTypes())
1145 return nullptr;
1146 return Context.pImpl->DITypeMap->lookup(&Identifier);
1147}
1148DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
1149 DIFlags Flags, uint8_t CC,
1151 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
1152 0, 0, Flags, Ops),
1153 CC(CC) {}
1154
1155DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
1156 uint8_t CC, Metadata *TypeArray,
1157 StorageType Storage,
1158 bool ShouldCreate) {
1160 Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr, nullptr, TypeArray};
1161 DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
1162}
1163
1164DIFile::DIFile(LLVMContext &C, StorageType Storage,
1165 std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,
1167 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
1168 Checksum(CS), Source(Src) {}
1169
1170// FIXME: Implement this string-enum correspondence with a .def file and macros,
1171// so that the association is explicit rather than implied.
1172static const char *ChecksumKindName[DIFile::CSK_Last] = {
1173 "CSK_MD5",
1174 "CSK_SHA1",
1175 "CSK_SHA256",
1176};
1177
1178StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
1179 assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
1180 // The first space was originally the CSK_None variant, which is now
1181 // obsolete, but the space is still reserved in ChecksumKind, so we account
1182 // for it here.
1183 return ChecksumKindName[CSKind - 1];
1184}
1185
1186std::optional<DIFile::ChecksumKind>
1189 .Case("CSK_MD5", DIFile::CSK_MD5)
1190 .Case("CSK_SHA1", DIFile::CSK_SHA1)
1191 .Case("CSK_SHA256", DIFile::CSK_SHA256)
1192 .Default(std::nullopt);
1193}
1194
1195DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
1196 MDString *Directory,
1197 std::optional<DIFile::ChecksumInfo<MDString *>> CS,
1198 MDString *Source, StorageType Storage,
1199 bool ShouldCreate) {
1200 assert(isCanonical(Filename) && "Expected canonical MDString");
1201 assert(isCanonical(Directory) && "Expected canonical MDString");
1202 assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
1203 // We do *NOT* expect Source to be a canonical MDString because nullptr
1204 // means none, so we need something to represent the empty file.
1206 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source};
1208}
1209DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
1210 DISourceLanguageName SourceLanguage,
1211 bool IsOptimized, unsigned RuntimeVersion,
1212 unsigned EmissionKind, uint64_t DWOId,
1213 bool SplitDebugInlining,
1214 bool DebugInfoForProfiling, unsigned NameTableKind,
1215 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
1216 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
1217 SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion),
1219 IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),
1220 DebugInfoForProfiling(DebugInfoForProfiling),
1221 RangesBaseAddress(RangesBaseAddress) {
1223}
1224
1225DICompileUnit *DICompileUnit::getImpl(
1226 LLVMContext &Context, DISourceLanguageName SourceLanguage, Metadata *File,
1227 MDString *Producer, bool IsOptimized, MDString *Flags,
1228 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1229 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1230 Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
1231 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1232 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
1233 MDString *SDK, StorageType Storage, bool ShouldCreate) {
1234 assert(Storage != Uniqued && "Cannot unique DICompileUnit");
1235 assert(isCanonical(Producer) && "Expected canonical MDString");
1236 assert(isCanonical(Flags) && "Expected canonical MDString");
1237 assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
1238
1239 Metadata *Ops[] = {File,
1240 Producer,
1241 Flags,
1243 EnumTypes,
1247 Macros,
1248 SysRoot,
1249 SDK};
1250 return storeImpl(new (std::size(Ops), Storage) DICompileUnit(
1251 Context, Storage, SourceLanguage, IsOptimized,
1252 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
1253 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
1254 Ops),
1255 Storage);
1256}
1257
1258std::optional<DICompileUnit::DebugEmissionKind>
1261 .Case("NoDebug", NoDebug)
1262 .Case("FullDebug", FullDebug)
1263 .Case("LineTablesOnly", LineTablesOnly)
1264 .Case("DebugDirectivesOnly", DebugDirectivesOnly)
1265 .Default(std::nullopt);
1266}
1267
1268std::optional<DICompileUnit::DebugNameTableKind>
1277
1279 switch (EK) {
1280 case NoDebug:
1281 return "NoDebug";
1282 case FullDebug:
1283 return "FullDebug";
1284 case LineTablesOnly:
1285 return "LineTablesOnly";
1287 return "DebugDirectivesOnly";
1288 }
1289 return nullptr;
1290}
1291
1293 switch (NTK) {
1295 return nullptr;
1297 return "GNU";
1299 return "Apple";
1301 return "None";
1302 }
1303 return nullptr;
1304}
1305DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
1306 unsigned ScopeLine, unsigned VirtualIndex,
1307 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
1308 bool UsesKeyInstructions, ArrayRef<Metadata *> Ops)
1309 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
1310 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
1311 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
1312 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
1313 SubclassData1 = UsesKeyInstructions;
1314}
1316DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
1317 unsigned Virtuality, bool IsMainSubprogram) {
1318 // We're assuming virtuality is the low-order field.
1319 static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
1320 int(SPFlagPureVirtual) ==
1321 int(dwarf::DW_VIRTUALITY_pure_virtual),
1322 "Virtuality constant mismatch");
1323 return static_cast<DISPFlags>(
1324 (Virtuality & SPFlagVirtuality) |
1325 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1326 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
1327 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1328 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
1329}
1330
1332 if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
1333 return Block->getScope()->getSubprogram();
1334 return const_cast<DISubprogram *>(cast<DISubprogram>(this));
1335}
1336
1338 if (auto *File = dyn_cast<DILexicalBlockFile>(this))
1339 return File->getScope()->getNonLexicalBlockFileScope();
1340 return const_cast<DILocalScope *>(this);
1341}
1342
1344 DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx,
1346 SmallVector<DIScope *> ScopeChain;
1347 DIScope *CachedResult = nullptr;
1348
1349 for (DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope);
1350 Scope = Scope->getScope()) {
1351 if (auto It = Cache.find(Scope); It != Cache.end()) {
1352 CachedResult = cast<DIScope>(It->second);
1353 break;
1354 }
1355 ScopeChain.push_back(Scope);
1356 }
1357
1358 // Recreate the scope chain, bottom-up, starting at the new subprogram (or a
1359 // cached result).
1360 DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;
1361 for (DIScope *ScopeToUpdate : reverse(ScopeChain)) {
1362 UpdatedScope = cloneAndReplaceParentScope(
1363 cast<DILexicalBlockBase>(ScopeToUpdate), UpdatedScope);
1364 Cache[ScopeToUpdate] = UpdatedScope;
1365 }
1366
1367 return cast<DILocalScope>(UpdatedScope);
1368}
1369
1371 return StringSwitch<DISPFlags>(Flag)
1372#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
1373#include "llvm/IR/DebugInfoFlags.def"
1374 .Default(SPFlagZero);
1375}
1376
1378 switch (Flag) {
1379 // Appease a warning.
1380 case SPFlagVirtuality:
1381 return "";
1382#define HANDLE_DISP_FLAG(ID, NAME) \
1383 case SPFlag##NAME: \
1384 return "DISPFlag" #NAME;
1385#include "llvm/IR/DebugInfoFlags.def"
1386 }
1387 return "";
1388}
1389
1392 SmallVectorImpl<DISPFlags> &SplitFlags) {
1393 // Multi-bit fields can require special handling. In our case, however, the
1394 // only multi-bit field is virtuality, and all its values happen to be
1395 // single-bit values, so the right behavior just falls out.
1396#define HANDLE_DISP_FLAG(ID, NAME) \
1397 if (DISPFlags Bit = Flags & SPFlag##NAME) { \
1398 SplitFlags.push_back(Bit); \
1399 Flags &= ~Bit; \
1400 }
1401#include "llvm/IR/DebugInfoFlags.def"
1402 return Flags;
1403}
1404
1405DISubprogram *DISubprogram::getImpl(
1406 LLVMContext &Context, Metadata *Scope, MDString *Name,
1407 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1408 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
1409 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1410 Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
1411 Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
1412 bool UsesKeyInstructions, StorageType Storage, bool ShouldCreate) {
1413 assert(isCanonical(Name) && "Expected canonical MDString");
1414 assert(isCanonical(LinkageName) && "Expected canonical MDString");
1415 assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
1417 (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
1423 File, Scope, Name, LinkageName,
1427 if (!TargetFuncName) {
1428 Ops.pop_back();
1429 if (!Annotations) {
1430 Ops.pop_back();
1431 if (!ThrownTypes) {
1432 Ops.pop_back();
1433 if (!TemplateParams) {
1434 Ops.pop_back();
1435 if (!ContainingType)
1436 Ops.pop_back();
1437 }
1438 }
1439 }
1440 }
1441 DEFINE_GETIMPL_STORE_N(DISubprogram,
1442 (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags,
1443 SPFlags, UsesKeyInstructions),
1444 Ops, Ops.size());
1445}
1446
1448 assert(F && "Invalid function");
1449 return F->getSubprogram() == this;
1450}
1451
1452template <typename ScopeT, typename NodeT>
1453static ScopeT getRawRetainedNodeScopeInternal(NodeT *N) {
1454 auto getScopeLambda = [](auto *N) { return getScope(N); };
1455 return DISubprogram::visitRetainedNode<ScopeT>(
1456 N, getScopeLambda, getScopeLambda, getScopeLambda, getScopeLambda,
1457 getScopeLambda, [](auto *N) { return nullptr; });
1458}
1459
1463
1467
1471
1474}
1475
1477 // Checks if a metadata node from retainedTypes is a type belonging to
1478 // this subprogram.
1479 auto IsTypeInSP = [this](Metadata *N) {
1480 auto *T = dyn_cast_or_null<DIType>(N);
1481 if (!T)
1482 return true;
1483
1484 DISubprogram *TypeSP = nullptr;
1485 // The type might have been global in the previously loaded IR modules.
1486 if (auto *LS = dyn_cast_or_null<DILocalScope>(T->getScope()))
1487 TypeSP = LS->getSubprogram();
1488
1489 return this == TypeSP;
1490 };
1491
1492 cleanupRetainedNodesIf(IsTypeInSP);
1493}
1494
1499
1500DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
1501 Metadata *File, unsigned Line,
1502 unsigned Column, StorageType Storage,
1503 bool ShouldCreate) {
1504 // Fixup column.
1506
1507 assert(Scope && "Expected scope");
1509 Metadata *Ops[] = {File, Scope};
1511}
1512
1513DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
1514 Metadata *Scope, Metadata *File,
1515 unsigned Discriminator,
1516 StorageType Storage,
1517 bool ShouldCreate) {
1518 assert(Scope && "Expected scope");
1519 DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator));
1520 Metadata *Ops[] = {File, Scope};
1521 DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);
1522}
1523
1524DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
1525 bool ExportSymbols, ArrayRef<Metadata *> Ops)
1526 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {
1527 SubclassData1 = ExportSymbols;
1528}
1529DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
1530 MDString *Name, bool ExportSymbols,
1531 StorageType Storage, bool ShouldCreate) {
1532 assert(isCanonical(Name) && "Expected canonical MDString");
1534 // The nullptr is for DIScope's File operand. This should be refactored.
1535 Metadata *Ops[] = {nullptr, Scope, Name};
1536 DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
1537}
1538
1539DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
1540 unsigned LineNo, ArrayRef<Metadata *> Ops)
1541 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
1542 Ops) {
1543 SubclassData32 = LineNo;
1544}
1545DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
1546 Metadata *Decl, MDString *Name,
1547 Metadata *File, unsigned LineNo,
1548 StorageType Storage, bool ShouldCreate) {
1549 assert(isCanonical(Name) && "Expected canonical MDString");
1550 DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo));
1551 // The nullptr is for DIScope's File operand. This should be refactored.
1552 Metadata *Ops[] = {Scope, Decl, Name, File};
1553 DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops);
1554}
1555
1556DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
1557 bool IsDecl, ArrayRef<Metadata *> Ops)
1558 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {
1559 SubclassData1 = IsDecl;
1560 SubclassData32 = LineNo;
1561}
1562DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
1563 Metadata *Scope, MDString *Name,
1564 MDString *ConfigurationMacros,
1565 MDString *IncludePath, MDString *APINotesFile,
1566 unsigned LineNo, bool IsDecl, StorageType Storage,
1567 bool ShouldCreate) {
1568 assert(isCanonical(Name) && "Expected canonical MDString");
1570 IncludePath, APINotesFile, LineNo, IsDecl));
1573 DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
1574}
1575DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,
1576 StorageType Storage,
1577 bool IsDefault,
1579 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
1580 dwarf::DW_TAG_template_type_parameter, IsDefault,
1581 Ops) {}
1582
1584DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,
1585 Metadata *Type, bool isDefault,
1586 StorageType Storage, bool ShouldCreate) {
1587 assert(isCanonical(Name) && "Expected canonical MDString");
1588 DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault));
1589 Metadata *Ops[] = {Name, Type};
1590 DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops);
1591}
1592
1593DITemplateValueParameter *DITemplateValueParameter::getImpl(
1594 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,
1595 bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {
1596 assert(isCanonical(Name) && "Expected canonical MDString");
1597 DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter,
1598 (Tag, Name, Type, isDefault, Value));
1599 Metadata *Ops[] = {Name, Type, Value};
1600 DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops);
1601}
1602
1604DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1605 MDString *LinkageName, Metadata *File, unsigned Line,
1606 Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
1607 Metadata *StaticDataMemberDeclaration,
1608 Metadata *TemplateParams, uint32_t AlignInBits,
1609 Metadata *Annotations, StorageType Storage,
1610 bool ShouldCreate) {
1611 assert(isCanonical(Name) && "Expected canonical MDString");
1612 assert(isCanonical(LinkageName) && "Expected canonical MDString");
1614 DIGlobalVariable,
1615 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
1617 Metadata *Ops[] = {Scope,
1618 Name,
1619 File,
1620 Type,
1621 Name,
1625 Annotations};
1626 DEFINE_GETIMPL_STORE(DIGlobalVariable,
1627 (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
1628}
1629
1631DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1632 Metadata *File, unsigned Line, Metadata *Type,
1633 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
1634 Metadata *Annotations, StorageType Storage,
1635 bool ShouldCreate) {
1636 // 64K ought to be enough for any frontend.
1637 assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");
1638
1639 assert(Scope && "Expected scope");
1640 assert(isCanonical(Name) && "Expected canonical MDString");
1641 DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg,
1642 Flags, AlignInBits, Annotations));
1644 DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
1645}
1646
1648 signed Line, ArrayRef<Metadata *> Ops,
1649 uint32_t AlignInBits)
1650 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {
1651 SubclassData32 = AlignInBits;
1652}
1653std::optional<uint64_t> DIVariable::getSizeInBits() const {
1654 // This is used by the Verifier so be mindful of broken types.
1655 const Metadata *RawType = getRawType();
1656 while (RawType) {
1657 // Try to get the size directly.
1658 if (auto *T = dyn_cast<DIType>(RawType))
1659 if (uint64_t Size = T->getSizeInBits())
1660 return Size;
1661
1662 if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
1663 // Look at the base type.
1664 RawType = DT->getRawBaseType();
1665 continue;
1666 }
1667
1668 // Missing type or size.
1669 break;
1670 }
1671
1672 // Fail gracefully.
1673 return std::nullopt;
1674}
1675
1676DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
1677 unsigned Column, bool IsArtificial,
1678 std::optional<unsigned> CoroSuspendIdx,
1680 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {
1681 this->SubclassData32 = Line;
1682 this->Column = Column;
1683 this->IsArtificial = IsArtificial;
1684 this->CoroSuspendIdx = CoroSuspendIdx;
1685}
1686DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1687 Metadata *File, unsigned Line, unsigned Column,
1688 bool IsArtificial,
1689 std::optional<unsigned> CoroSuspendIdx,
1690 StorageType Storage, bool ShouldCreate) {
1691 assert(Scope && "Expected scope");
1692 assert(isCanonical(Name) && "Expected canonical MDString");
1694 DILabel, (Scope, Name, File, Line, Column, IsArtificial, CoroSuspendIdx));
1695 Metadata *Ops[] = {Scope, Name, File};
1696 DEFINE_GETIMPL_STORE(DILabel, (Line, Column, IsArtificial, CoroSuspendIdx),
1697 Ops);
1698}
1699
1700DIExpression *DIExpression::getImpl(LLVMContext &Context,
1701 ArrayRef<uint64_t> Elements,
1702 StorageType Storage, bool ShouldCreate) {
1703 DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
1704 DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
1705}
1707 if (auto singleLocElts = getSingleLocationExpressionElements()) {
1708 return singleLocElts->size() > 0 &&
1709 (*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value;
1710 }
1711 return false;
1712}
1714 if (auto singleLocElts = getSingleLocationExpressionElements())
1715 return singleLocElts->size() > 0 &&
1716 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1717 return false;
1718}
1720 if (auto singleLocElts = getSingleLocationExpressionElements())
1721 return singleLocElts->size() == 1 &&
1722 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1723 return false;
1724}
1725
1726DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage,
1727 bool ShouldCreate) {
1728 // Uniqued DIAssignID are not supported as the instance address *is* the ID.
1729 assert(Storage != StorageType::Uniqued && "uniqued DIAssignID unsupported");
1730 return storeImpl(new (0u, Storage) DIAssignID(Context, Storage), Storage);
1731}
1732
1734 uint64_t Op = getOp();
1735
1736 if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)
1737 return 2;
1738
1739 switch (Op) {
1744 case dwarf::DW_OP_bregx:
1745 return 3;
1746 case dwarf::DW_OP_constu:
1747 case dwarf::DW_OP_consts:
1748 case dwarf::DW_OP_deref_size:
1749 case dwarf::DW_OP_plus_uconst:
1753 case dwarf::DW_OP_regx:
1754 return 2;
1755 default:
1756 return 1;
1757 }
1758}
1759
1763
1765 return Op->is(dwarf::DW_OP_LLVM_arg);
1766}
1767
1771
1776
1780
1784
1788
1792
1794 return Op->is(dwarf::DW_OP_constu);
1795}
1796
1798 return Op->is(dwarf::DW_OP_plus_uconst);
1799}
1800
1802 for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
1803 // Check that there's space for the operand.
1804 if (I->get() + I->getSize() > E->get())
1805 return false;
1806
1807 uint64_t Op = I->getOp();
1808 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
1809 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))
1810 continue;
1811
1812 // Check that the operand is valid.
1813 switch (Op) {
1814 default:
1815 return false;
1817 // A fragment operator must appear at the end.
1818 return I->get() + I->getSize() == E->get();
1819 case dwarf::DW_OP_stack_value: {
1820 // Must be the last one or followed by a DW_OP_LLVM_fragment.
1821 if (I->get() + I->getSize() == E->get())
1822 break;
1823 auto J = I;
1824 if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
1825 return false;
1826 break;
1827 }
1828 case dwarf::DW_OP_swap: {
1829 // Must be more than one implicit element on the stack.
1830
1831 // FIXME: A better way to implement this would be to add a local variable
1832 // that keeps track of the stack depth and introduce something like a
1833 // DW_LLVM_OP_implicit_location as a placeholder for the location this
1834 // DIExpression is attached to, or else pass the number of implicit stack
1835 // elements into isValid.
1836 if (getNumElements() == 1)
1837 return false;
1838 break;
1839 }
1841 // An entry value operator must appear at the beginning or immediately
1842 // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
1843 // currently only be 1, because we support only entry values of a simple
1844 // register location. One reason for this is that we currently can't
1845 // calculate the size of the resulting DWARF block for other expressions.
1846 auto FirstOp = expr_op_begin();
1847 if (auto Arg = dyn_cast<ArgOp>(*FirstOp); Arg && Arg.getIndex() == 0)
1848 ++FirstOp;
1849 if (I->get() != FirstOp->get() ||
1850 cast<EntryValueOp>(*I).getNumOperations() != 1)
1851 return false;
1852 break;
1853 }
1860 case dwarf::DW_OP_constu:
1861 case dwarf::DW_OP_plus_uconst:
1862 case dwarf::DW_OP_plus:
1863 case dwarf::DW_OP_minus:
1864 case dwarf::DW_OP_mul:
1865 case dwarf::DW_OP_div:
1866 case dwarf::DW_OP_mod:
1867 case dwarf::DW_OP_or:
1868 case dwarf::DW_OP_and:
1869 case dwarf::DW_OP_xor:
1870 case dwarf::DW_OP_shl:
1871 case dwarf::DW_OP_shr:
1872 case dwarf::DW_OP_shra:
1873 case dwarf::DW_OP_deref:
1874 case dwarf::DW_OP_deref_size:
1875 case dwarf::DW_OP_xderef:
1876 case dwarf::DW_OP_lit0:
1877 case dwarf::DW_OP_not:
1878 case dwarf::DW_OP_dup:
1879 case dwarf::DW_OP_regx:
1880 case dwarf::DW_OP_bregx:
1881 case dwarf::DW_OP_push_object_address:
1882 case dwarf::DW_OP_over:
1883 case dwarf::DW_OP_rot:
1884 case dwarf::DW_OP_consts:
1885 case dwarf::DW_OP_eq:
1886 case dwarf::DW_OP_ne:
1887 case dwarf::DW_OP_gt:
1888 case dwarf::DW_OP_ge:
1889 case dwarf::DW_OP_lt:
1890 case dwarf::DW_OP_le:
1891 case dwarf::DW_OP_neg:
1892 case dwarf::DW_OP_abs:
1893 break;
1894 }
1895 }
1896 return true;
1897}
1898
1900 if (!isValid())
1901 return false;
1902
1903 if (getNumElements() == 0)
1904 return false;
1905
1906 for (const auto &It : expr_ops()) {
1907 switch (It.getOp()) {
1908 default:
1909 break;
1910 case dwarf::DW_OP_stack_value:
1911 return true;
1912 }
1913 }
1914
1915 return false;
1916}
1917
1919 if (!isValid())
1920 return false;
1921
1922 if (getNumElements() == 0)
1923 return false;
1924
1925 // Tag offsets are non-emitting. They, fragments, and location operands don't
1926 // perform a computation by themselves.
1927 for (const auto &It : expr_ops()) {
1928 if (It.isNonEmitting())
1929 continue;
1930 switch (It.getOp()) {
1933 continue;
1934 default:
1935 return true;
1936 }
1937 }
1938
1939 return false;
1940}
1941
1943 if (!isValid())
1944 return false;
1945
1946 if (getNumElements() == 0)
1947 return true;
1948
1949 auto ExprOpBegin = expr_ops().begin();
1950 auto ExprOpEnd = expr_ops().end();
1951 if (auto Arg = dyn_cast<ArgOp>(*ExprOpBegin)) {
1952 if (Arg.getIndex() != 0)
1953 return false;
1954 ++ExprOpBegin;
1955 }
1956
1957 return !std::any_of(ExprOpBegin, ExprOpEnd,
1958 [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); });
1959}
1960
1961std::optional<ArrayRef<uint64_t>>
1963 // Check for `isValid` covered by `isSingleLocationExpression`.
1965 return std::nullopt;
1966
1967 // An empty expression is already non-variadic.
1968 if (!getNumElements())
1969 return ArrayRef<uint64_t>();
1970
1971 // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do
1972 // anything.
1974 return getElements().drop_front(2);
1975 return getElements();
1976}
1977
1978const DIExpression *
1980 SmallVector<uint64_t, 3> UndefOps;
1981 if (auto FragmentInfo = Expr->getFragmentInfo()) {
1982 UndefOps.append({dwarf::DW_OP_LLVM_fragment, FragmentInfo->OffsetInBits,
1983 FragmentInfo->SizeInBits});
1984 }
1985 return DIExpression::get(Expr->getContext(), UndefOps);
1986}
1987
1988const DIExpression *
1990 if (any_of(Expr->expr_ops(), [](auto ExprOp) {
1991 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
1992 }))
1993 return Expr;
1994 SmallVector<uint64_t> NewOps;
1995 NewOps.reserve(Expr->getNumElements() + 2);
1996 NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
1997 NewOps.append(Expr->elements_begin(), Expr->elements_end());
1998 return DIExpression::get(Expr->getContext(), NewOps);
1999}
2000
2001std::optional<const DIExpression *>
2003 if (!Expr)
2004 return std::nullopt;
2005
2006 if (auto Elts = Expr->getSingleLocationExpressionElements())
2007 return DIExpression::get(Expr->getContext(), *Elts);
2008
2009 return std::nullopt;
2010}
2011
2013 const DIExpression *Expr,
2014 bool IsIndirect) {
2015 // If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0`
2016 // to the existing expression ops.
2017 if (none_of(Expr->expr_ops(), [](auto ExprOp) {
2018 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
2019 }))
2020 Ops.append({dwarf::DW_OP_LLVM_arg, 0});
2021 // If Expr is not indirect, we only need to insert the expression elements and
2022 // we're done.
2023 if (!IsIndirect) {
2024 Ops.append(Expr->elements_begin(), Expr->elements_end());
2025 return;
2026 }
2027 // If Expr is indirect, insert the implied DW_OP_deref at the end of the
2028 // expression but before DW_OP_{stack_value, LLVM_fragment} if they are
2029 // present.
2030 for (auto Op : Expr->expr_ops()) {
2031 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2032 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2033 Ops.push_back(dwarf::DW_OP_deref);
2034 IsIndirect = false;
2035 }
2036 Op.appendToVector(Ops);
2037 }
2038 if (IsIndirect)
2039 Ops.push_back(dwarf::DW_OP_deref);
2040}
2041
2042bool DIExpression::isEqualExpression(const DIExpression *FirstExpr,
2043 bool FirstIndirect,
2044 const DIExpression *SecondExpr,
2045 bool SecondIndirect) {
2046 SmallVector<uint64_t> FirstOps;
2047 DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect);
2048 SmallVector<uint64_t> SecondOps;
2049 DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr,
2050 SecondIndirect);
2051 return FirstOps == SecondOps;
2052}
2053
2054std::optional<DIExpression::FragmentInfo>
2056 for (auto I = Start; I != End; ++I)
2057 if (auto Fragment = dyn_cast<FragmentOp>(*I))
2058 return FragmentInfo{Fragment.getSizeInBits(), Fragment.getOffsetInBits()};
2059 return std::nullopt;
2060}
2061
2062std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) {
2063 std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();
2064 std::optional<uint64_t> ActiveBits = InitialActiveBits;
2065 auto NarrowActiveBits = [&](uint64_t SizeInBits) {
2066 ActiveBits = ActiveBits ? std::min(*ActiveBits, SizeInBits) : SizeInBits;
2067 };
2068
2069 for (auto Op : expr_ops()) {
2070 switch (Op.getOp()) {
2071 default:
2072 // We assume the worst case for anything we don't currently handle and
2073 // revert to the initial active bits.
2074 ActiveBits = InitialActiveBits;
2075 break;
2078 auto Extract = cast<ExtractBitsOp>(Op);
2079 // We can't handle an extract whose sign doesn't match that of the
2080 // variable.
2081 std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness();
2082 bool VarSigned = (VarSign == DIBasicType::Signedness::Signed);
2083 if (!VarSign || VarSigned != Extract.isSigned()) {
2084 ActiveBits = InitialActiveBits;
2085 break;
2086 }
2087 NarrowActiveBits(Extract.getSizeInBits());
2088 break;
2089 }
2091 NarrowActiveBits(cast<FragmentOp>(Op).getSizeInBits());
2092 break;
2093 }
2094 }
2095 return ActiveBits;
2096}
2097
2099 int64_t Offset) {
2100 if (Offset > 0) {
2101 Ops.push_back(dwarf::DW_OP_plus_uconst);
2102 Ops.push_back(Offset);
2103 } else if (Offset < 0) {
2104 Ops.push_back(dwarf::DW_OP_constu);
2105 // Avoid UB when encountering LLONG_MIN, because in 2's complement
2106 // abs(LLONG_MIN) is LLONG_MAX+1.
2107 uint64_t AbsMinusOne = -(Offset+1);
2108 Ops.push_back(AbsMinusOne + 1);
2109 Ops.push_back(dwarf::DW_OP_minus);
2110 }
2111}
2112
2114 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2115 if (!SingleLocEltsOpt)
2116 return false;
2117 auto SingleLocElts = *SingleLocEltsOpt;
2118
2119 if (SingleLocElts.size() == 0) {
2120 Offset = 0;
2121 return true;
2122 }
2123
2124 if (SingleLocElts.size() == 2 &&
2125 SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
2126 Offset = SingleLocElts[1];
2127 return true;
2128 }
2129
2130 if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
2131 if (SingleLocElts[2] == dwarf::DW_OP_plus) {
2132 Offset = SingleLocElts[1];
2133 return true;
2134 }
2135 if (SingleLocElts[2] == dwarf::DW_OP_minus) {
2136 Offset = -SingleLocElts[1];
2137 return true;
2138 }
2139 }
2140
2141 return false;
2142}
2143
2145 ArrayRef<uint64_t> Ops, int64_t &OffsetInBytes,
2146 SmallVectorImpl<uint64_t> &RemainingOps) {
2147 OffsetInBytes = 0;
2148 RemainingOps.clear();
2149
2150 auto ExprOpEnd = expr_op_iterator(Ops.end());
2151 auto ExprOpIt = expr_op_iterator(Ops.begin());
2152 while (ExprOpIt != ExprOpEnd) {
2153 uint64_t Op = ExprOpIt->getOp();
2154 if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||
2155 Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment ||
2158 break;
2159 } else if (auto PlusUconst = dyn_cast<PlusUconstOp>(*ExprOpIt)) {
2160 OffsetInBytes += PlusUconst.getOffset();
2161 } else if (auto Constant = dyn_cast<ConstuOp>(*ExprOpIt)) {
2162 uint64_t Value = Constant.getValue();
2163 ++ExprOpIt;
2164 if (ExprOpIt->getOp() == dwarf::DW_OP_plus)
2165 OffsetInBytes += Value;
2166 else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)
2167 OffsetInBytes -= Value;
2168 else
2169 return false;
2170 } else {
2171 // Not a const plus/minus operation or deref.
2172 return false;
2173 }
2174 ++ExprOpIt;
2175 }
2176 RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());
2177 return true;
2178}
2179
2181 int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const {
2182 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2183 if (!SingleLocEltsOpt) {
2184 OffsetInBytes = 0;
2185 RemainingOps.clear();
2186 return false;
2187 }
2188
2189 return extractLeadingOffset(*SingleLocEltsOpt, OffsetInBytes, RemainingOps);
2190}
2191
2194 for (auto ExprOp : expr_ops())
2195 if (auto Arg = dyn_cast<ArgOp>(ExprOp))
2196 SeenOps.insert(Arg.getIndex());
2197 for (uint64_t Idx = 0; Idx < N; ++Idx)
2198 if (!SeenOps.contains(Idx))
2199 return false;
2200 return true;
2201}
2202
2203const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,
2204 unsigned &AddrClass) {
2205 // FIXME: This seems fragile. Nothing that verifies that these elements
2206 // actually map to ops and not operands.
2207 auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements();
2208 if (!SingleLocEltsOpt)
2209 return nullptr;
2210 auto SingleLocElts = *SingleLocEltsOpt;
2211
2212 const unsigned PatternSize = 4;
2213 if (SingleLocElts.size() >= PatternSize &&
2214 SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu &&
2215 SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap &&
2216 SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) {
2217 AddrClass = SingleLocElts[PatternSize - 3];
2218
2219 if (SingleLocElts.size() == PatternSize)
2220 return nullptr;
2221 return DIExpression::get(
2222 Expr->getContext(),
2223 ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize));
2224 }
2225 return Expr;
2226}
2227
2228DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,
2229 int64_t Offset) {
2231 if (Flags & DIExpression::DerefBefore)
2232 Ops.push_back(dwarf::DW_OP_deref);
2233
2235 if (Flags & DIExpression::DerefAfter)
2236 Ops.push_back(dwarf::DW_OP_deref);
2237
2238 bool StackValue = Flags & DIExpression::StackValue;
2239 bool EntryValue = Flags & DIExpression::EntryValue;
2240
2241 return prependOpcodes(Expr, Ops, StackValue, EntryValue);
2242}
2243
2244DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
2246 unsigned ArgNo, bool StackValue) {
2247 assert(Expr && "Can't add ops to this expression");
2248
2249 // Handle non-variadic intrinsics by prepending the opcodes.
2250 if (!any_of(Expr->expr_ops(),
2251 [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); })) {
2252 assert(ArgNo == 0 &&
2253 "Location Index must be 0 for a non-variadic expression.");
2255 return DIExpression::prependOpcodes(Expr, NewOps, StackValue);
2256 }
2257
2259 for (auto Op : Expr->expr_ops()) {
2260 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2261 if (StackValue) {
2262 if (Op.getOp() == dwarf::DW_OP_stack_value)
2263 StackValue = false;
2264 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2265 NewOps.push_back(dwarf::DW_OP_stack_value);
2266 StackValue = false;
2267 }
2268 }
2269 Op.appendToVector(NewOps);
2270 if (auto Arg = dyn_cast<ArgOp>(Op); Arg && Arg.getIndex() == ArgNo)
2271 llvm::append_range(NewOps, Ops);
2272 }
2273 if (StackValue)
2274 NewOps.push_back(dwarf::DW_OP_stack_value);
2275
2276 return DIExpression::get(Expr->getContext(), NewOps);
2277}
2278
2279DIExpression *DIExpression::replaceArg(const DIExpression *Expr,
2280 uint64_t OldArg, uint64_t NewArg) {
2281 assert(Expr && "Can't replace args in this expression");
2282
2284
2285 for (auto Op : Expr->expr_ops()) {
2286 auto Arg = dyn_cast<ArgOp>(Op);
2287 if (!Arg || Arg.getIndex() < OldArg) {
2288 Op.appendToVector(NewOps);
2289 continue;
2290 }
2292 uint64_t ArgIndex = Arg.getIndex() == OldArg ? NewArg : Arg.getIndex();
2293 // OldArg has been deleted from the Op list, so decrement all indices
2294 // greater than it.
2295 if (ArgIndex > OldArg)
2296 --ArgIndex;
2297 NewOps.push_back(ArgIndex);
2298 }
2299 return DIExpression::get(Expr->getContext(), NewOps);
2300}
2301
2302DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
2304 bool StackValue, bool EntryValue) {
2305 assert(Expr && "Can't prepend ops to this expression");
2306
2307 if (EntryValue) {
2309 // Use a block size of 1 for the target register operand. The
2310 // DWARF backend currently cannot emit entry values with a block
2311 // size > 1.
2312 Ops.push_back(1);
2313 }
2314
2315 // If there are no ops to prepend, do not even add the DW_OP_stack_value.
2316 if (Ops.empty())
2317 StackValue = false;
2318 for (auto Op : Expr->expr_ops()) {
2319 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2320 if (StackValue) {
2321 if (Op.getOp() == dwarf::DW_OP_stack_value)
2322 StackValue = false;
2323 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2324 Ops.push_back(dwarf::DW_OP_stack_value);
2325 StackValue = false;
2326 }
2327 }
2328 Op.appendToVector(Ops);
2329 }
2330 if (StackValue)
2331 Ops.push_back(dwarf::DW_OP_stack_value);
2332 return DIExpression::get(Expr->getContext(), Ops);
2333}
2334
2335DIExpression *DIExpression::append(const DIExpression *Expr,
2337 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2338
2339 // Copy Expr's current op list.
2341 for (auto Op : Expr->expr_ops()) {
2342 // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
2343 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2344 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2345 NewOps.append(Ops.begin(), Ops.end());
2346
2347 // Ensure that the new opcodes are only appended once.
2348 Ops = {};
2349 }
2350 Op.appendToVector(NewOps);
2351 }
2352 NewOps.append(Ops.begin(), Ops.end());
2353 auto *result =
2354 DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath();
2355 assert(result->isValid() && "concatenated expression is not valid");
2356 return result;
2357}
2358
2359DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
2361 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2362 assert(std::none_of(expr_op_iterator(Ops.begin()),
2363 expr_op_iterator(Ops.end()),
2364 [](auto Op) {
2365 return Op.getOp() == dwarf::DW_OP_stack_value ||
2366 Op.getOp() == dwarf::DW_OP_LLVM_fragment;
2367 }) &&
2368 "Can't append this op");
2369
2370 // DIExpression stores opcodes and their arguments in a flat array. Walk the
2371 // parsed operations to find the last opcode that determines whether the
2372 // expression already ends in DW_OP_stack_value.
2373 std::optional<uint64_t> LastValueOp;
2374 for (auto Op : Expr->expr_ops()) {
2375 if (Op.isNonEmitting() || Op.getOp() == dwarf::DW_OP_LLVM_fragment)
2376 continue;
2377 LastValueOp = Op.getOp();
2378 }
2379 bool NeedsDeref = LastValueOp && *LastValueOp != dwarf::DW_OP_stack_value;
2380 bool NeedsStackValue = NeedsDeref || !LastValueOp;
2381
2382 // Append a DW_OP_deref after Expr's current op list if needed, then append
2383 // the new ops, and finally ensure that a single DW_OP_stack_value is present.
2385 if (NeedsDeref)
2386 NewOps.push_back(dwarf::DW_OP_deref);
2387 NewOps.append(Ops.begin(), Ops.end());
2388 if (NeedsStackValue)
2389 NewOps.push_back(dwarf::DW_OP_stack_value);
2390 return DIExpression::append(Expr, NewOps);
2391}
2392
2393std::optional<DIExpression *> DIExpression::createFragmentExpression(
2394 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
2396 // Track whether it's safe to split the value at the top of the DWARF stack,
2397 // assuming that it'll be used as an implicit location value.
2398 bool CanSplitValue = true;
2399 // Track whether we need to add a fragment expression to the end of Expr.
2400 bool EmitFragment = true;
2401 // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
2402 if (Expr) {
2403 for (auto Op : Expr->expr_ops()) {
2404 switch (Op.getOp()) {
2405 default:
2406 break;
2407 case dwarf::DW_OP_shr:
2408 case dwarf::DW_OP_shra:
2409 case dwarf::DW_OP_shl:
2410 case dwarf::DW_OP_plus:
2411 case dwarf::DW_OP_plus_uconst:
2412 case dwarf::DW_OP_minus:
2413 // We can't safely split arithmetic or shift operations into multiple
2414 // fragments because we can't express carry-over between fragments.
2415 //
2416 // FIXME: We *could* preserve the lowest fragment of a constant offset
2417 // operation if the offset fits into SizeInBits.
2418 CanSplitValue = false;
2419 break;
2420 case dwarf::DW_OP_deref:
2421 case dwarf::DW_OP_deref_size:
2422 case dwarf::DW_OP_deref_type:
2423 case dwarf::DW_OP_xderef:
2424 case dwarf::DW_OP_xderef_size:
2425 case dwarf::DW_OP_xderef_type:
2426 // Preceeding arithmetic operations have been applied to compute an
2427 // address. It's okay to split the value loaded from that address.
2428 CanSplitValue = true;
2429 break;
2430 case dwarf::DW_OP_stack_value:
2431 // Bail if this expression computes a value that cannot be split.
2432 if (!CanSplitValue)
2433 return std::nullopt;
2434 break;
2436 auto Fragment = cast<FragmentOp>(Op);
2437 // If we've decided we don't need a fragment then give up if we see that
2438 // there's already a fragment expression.
2439 // FIXME: We could probably do better here
2440 if (!EmitFragment)
2441 return std::nullopt;
2442 // Make the new offset point into the existing fragment.
2443 uint64_t FragmentOffsetInBits = Fragment.getOffsetInBits();
2444 uint64_t FragmentSizeInBits = Fragment.getSizeInBits();
2445 (void)FragmentSizeInBits;
2446 assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
2447 "new fragment outside of original fragment");
2448 OffsetInBits += FragmentOffsetInBits;
2449 continue;
2450 }
2453 auto Extract = cast<ExtractBitsOp>(Op);
2454 // If we're extracting bits from inside of the fragment that we're
2455 // creating then we don't have a fragment after all, and just need to
2456 // adjust the offset that we're extracting from.
2457 uint64_t ExtractOffsetInBits = Extract.getOffsetInBits();
2458 uint64_t ExtractSizeInBits = Extract.getSizeInBits();
2459 if (ExtractOffsetInBits >= OffsetInBits &&
2460 ExtractOffsetInBits + ExtractSizeInBits <=
2461 OffsetInBits + SizeInBits) {
2462 Ops.push_back(Op.getOp());
2463 Ops.push_back(ExtractOffsetInBits - OffsetInBits);
2464 Ops.push_back(ExtractSizeInBits);
2465 EmitFragment = false;
2466 continue;
2467 }
2468 // If the extracted bits aren't fully contained within the fragment then
2469 // give up.
2470 // FIXME: We could probably do better here
2471 return std::nullopt;
2472 }
2473 }
2474 Op.appendToVector(Ops);
2475 }
2476 }
2477 assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");
2478 assert(Expr && "Unknown DIExpression");
2479 if (EmitFragment) {
2481 Ops.push_back(OffsetInBits);
2482 Ops.push_back(SizeInBits);
2483 }
2484 return DIExpression::get(Expr->getContext(), Ops);
2485}
2486
2487/// See declaration for more info.
2489 const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits,
2490 uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,
2491 int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag,
2492 std::optional<DIExpression::FragmentInfo> &Result,
2493 int64_t &OffsetFromLocationInBits) {
2494
2495 if (VarFrag.SizeInBits == 0)
2496 return false; // Variable size is unknown.
2497
2498 // Difference between mem slice start and the dbg location start.
2499 // 0 4 8 12 16 ...
2500 // | |
2501 // dbg location start
2502 // |
2503 // mem slice start
2504 // Here MemStartRelToDbgStartInBits is 8. Note this can be negative.
2505 int64_t MemStartRelToDbgStartInBits;
2506 {
2507 auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL);
2508 if (!MemOffsetFromDbgInBytes)
2509 return false; // Can't calculate difference in addresses.
2510 // Difference between the pointers.
2511 MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;
2512 // Add the difference of the offsets.
2513 MemStartRelToDbgStartInBits +=
2514 SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);
2515 }
2516
2517 // Out-param. Invert offset to get offset from debug location.
2518 OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;
2519
2520 // Check if the variable fragment sits outside (before) this memory slice.
2521 int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;
2522 if (MemEndRelToDbgStart < 0) {
2523 Result = {0, 0}; // Out-param.
2524 return true;
2525 }
2526
2527 // Work towards creating SliceOfVariable which is the bits of the variable
2528 // that the memory region covers.
2529 // 0 4 8 12 16 ...
2530 // | |
2531 // dbg location start with VarFrag offset=32
2532 // |
2533 // mem slice start: SliceOfVariable offset=40
2534 int64_t MemStartRelToVarInBits =
2535 MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;
2536 int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;
2537 // If the memory region starts before the debug location the fragment
2538 // offset would be negative, which we can't encode. Limit those to 0. This
2539 // is fine because those bits necessarily don't overlap with the existing
2540 // variable fragment.
2541 int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);
2542 int64_t MemFragSize =
2543 std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);
2544 DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart);
2545
2546 // Intersect the memory region fragment with the variable location fragment.
2547 DIExpression::FragmentInfo TrimmedSliceOfVariable =
2548 DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);
2549 if (TrimmedSliceOfVariable == VarFrag)
2550 Result = std::nullopt; // Out-param.
2551 else
2552 Result = TrimmedSliceOfVariable; // Out-param.
2553 return true;
2554}
2555
2556std::pair<DIExpression *, const ConstantInt *>
2558 // Copy the APInt so we can modify it.
2559 APInt NewInt = CI->getValue();
2561
2562 // Fold operators only at the beginning of the expression.
2563 bool First = true;
2564 bool Changed = false;
2565 for (auto Op : expr_ops()) {
2566 switch (Op.getOp()) {
2567 default:
2568 // We fold only the leading part of the expression; if we get to a part
2569 // that we're going to copy unchanged, and haven't done any folding,
2570 // then the entire expression is unchanged and we can return early.
2571 if (!Changed)
2572 return {this, CI};
2573 First = false;
2574 break;
2576 if (!First)
2577 break;
2578 Changed = true;
2579 auto Convert = cast<ConvertOp>(Op);
2580 if (Convert.getEncoding() == dwarf::DW_ATE_signed)
2581 NewInt = NewInt.sextOrTrunc(Convert.getBitSize());
2582 else {
2583 assert(Convert.getEncoding() == dwarf::DW_ATE_unsigned &&
2584 "Unexpected operand");
2585 NewInt = NewInt.zextOrTrunc(Convert.getBitSize());
2586 }
2587 continue;
2588 }
2589 }
2590 Op.appendToVector(Ops);
2591 }
2592 if (!Changed)
2593 return {this, CI};
2594 return {DIExpression::get(getContext(), Ops),
2595 ConstantInt::get(getContext(), NewInt)};
2596}
2597
2599 uint64_t Result = 0;
2600 for (auto ExprOp : expr_ops())
2601 if (auto Arg = dyn_cast<ArgOp>(ExprOp))
2602 Result = std::max(Result, Arg.getIndex() + 1);
2603 assert(hasAllLocationOps(Result) &&
2604 "Expression is missing one or more location operands.");
2605 return Result;
2606}
2607
2608std::optional<DIExpression::SignedOrUnsignedConstant>
2610
2611 // Recognize signed and unsigned constants.
2612 // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value
2613 // (DW_OP_LLVM_fragment of Len).
2614 // An unsigned constant can be represented as
2615 // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len).
2616
2617 if ((getNumElements() != 2 && getNumElements() != 3 &&
2618 getNumElements() != 6) ||
2619 (getElement(0) != dwarf::DW_OP_consts &&
2620 getElement(0) != dwarf::DW_OP_constu))
2621 return std::nullopt;
2622
2623 if (getNumElements() == 2 && getElement(0) == dwarf::DW_OP_consts)
2625
2626 if ((getNumElements() == 3 && getElement(2) != dwarf::DW_OP_stack_value) ||
2627 (getNumElements() == 6 && (getElement(2) != dwarf::DW_OP_stack_value ||
2629 return std::nullopt;
2630 return getElement(0) == dwarf::DW_OP_constu
2633}
2634
2635DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
2636 bool Signed) {
2637 dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
2639 dwarf::DW_OP_LLVM_convert, ToSize, TK}};
2640 return Ops;
2641}
2642
2643DIExpression *DIExpression::appendExt(const DIExpression *Expr,
2644 unsigned FromSize, unsigned ToSize,
2645 bool Signed) {
2646 return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
2647}
2648
2650DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
2652 bool ShouldCreate) {
2654 Metadata *Ops[] = {Variable, Expression};
2656}
2657DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
2658 unsigned Line, unsigned Attributes,
2660 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
2662
2663DIObjCProperty *DIObjCProperty::getImpl(
2664 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
2665 MDString *GetterName, MDString *SetterName, unsigned Attributes,
2666 Metadata *Type, StorageType Storage, bool ShouldCreate) {
2667 assert(isCanonical(Name) && "Expected canonical MDString");
2668 assert(isCanonical(GetterName) && "Expected canonical MDString");
2669 assert(isCanonical(SetterName) && "Expected canonical MDString");
2670 DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,
2671 SetterName, Attributes, Type));
2673 DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
2674}
2675
2676DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
2677 Metadata *Scope, Metadata *Entity,
2678 Metadata *File, unsigned Line,
2679 MDString *Name, Metadata *Elements,
2680 StorageType Storage,
2681 bool ShouldCreate) {
2682 assert(isCanonical(Name) && "Expected canonical MDString");
2683 DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
2684 (Tag, Scope, Entity, File, Line, Name, Elements));
2686 DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
2687}
2688
2689DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2690 MDString *Name, MDString *Value, StorageType Storage,
2691 bool ShouldCreate) {
2692 assert(isCanonical(Name) && "Expected canonical MDString");
2694 Metadata *Ops[] = {Name, Value};
2695 DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
2696}
2697
2698DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
2699 unsigned Line, Metadata *File,
2700 Metadata *Elements, StorageType Storage,
2701 bool ShouldCreate) {
2702 DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements));
2703 Metadata *Ops[] = {File, Elements};
2704 DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
2705}
2706
2707DIArgList *DIArgList::get(LLVMContext &Context,
2709 auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));
2710 if (ExistingIt != Context.pImpl->DIArgLists.end())
2711 return *ExistingIt;
2712 DIArgList *NewArgList = new DIArgList(Context, Args);
2713 Context.pImpl->DIArgLists.insert(NewArgList);
2714 return NewArgList;
2715}
2716
2718 ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);
2719 assert((!New || isa<ValueAsMetadata>(New)) &&
2720 "DIArgList must be passed a ValueAsMetadata");
2721 untrack();
2722 // We need to update the set storage once the Args are updated since they
2723 // form the key to the DIArgLists store.
2724 getContext().pImpl->DIArgLists.erase(this);
2726 for (ValueAsMetadata *&VM : Args) {
2727 if (&VM == OldVMPtr) {
2728 if (NewVM)
2729 VM = NewVM;
2730 else
2731 VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));
2732 }
2733 }
2734 // We've changed the contents of this DIArgList, and the set storage may
2735 // already contain a DIArgList with our new set of args; if it does, then we
2736 // must RAUW this with the existing DIArgList, otherwise we simply insert this
2737 // back into the set storage.
2738 DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);
2739 if (ExistingArgList) {
2740 replaceAllUsesWith(ExistingArgList);
2741 // Clear this here so we don't try to untrack in the destructor.
2742 Args.clear();
2743 delete this;
2744 return;
2745 }
2746 getContext().pImpl->DIArgLists.insert(this);
2747 track();
2748}
2749void DIArgList::track() {
2750 for (ValueAsMetadata *&VAM : Args)
2751 if (VAM)
2752 MetadataTracking::track(&VAM, *VAM, *this);
2753}
2754void DIArgList::untrack() {
2755 for (ValueAsMetadata *&VAM : Args)
2756 if (VAM)
2757 MetadataTracking::untrack(&VAM, *VAM);
2758}
2759void DIArgList::dropAllReferences(bool Untrack) {
2760 if (Untrack)
2761 untrack();
2762 Args.clear();
2763 ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false);
2764}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT S1
AMDGPU Kernel Attributes
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
static 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")
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:1076
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition APInt.cpp:1084
Annotations lets you mark points and ranges inside source code, for tests:
Definition Annotations.h:67
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition ArrayRef.h:194
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This is an important base class in LLVM.
Definition Constant.h:43
LLVM_ABI void handleChangedOperand(void *Ref, Metadata *New)
static LLVM_ABI DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)
DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag, unsigned LineNo, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, DIFlags Flags, ArrayRef< Metadata * > Ops)
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t DIFlags Flags unsigned StringRef DIFile * File
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t DIFlags Flags unsigned StringRef DIFile unsigned DIScope * Scope
unsigned StringRef uint64_t SizeInBits
LLVM_ABI std::optional< Signedness > getSignedness() const
Return the signedness of this type, or std::nullopt if this type is neither signed nor unsigned.
unsigned getEncoding() const
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t NumExtraInhabitants
static DIBasicType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, DIFile *File, unsigned LineNo, DIScope *Scope, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, uint32_t DataSizeInBits, DIFlags Flags, StorageType Storage, bool ShouldCreate=true)
unsigned StringRef Name
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t AlignInBits
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags unsigned StringRef uint64_t uint32_t unsigned uint32_t DIFlags Flags unsigned StringRef DIFile unsigned LineNo
Debug common block.
Metadata Metadata * Decl
Metadata Metadata MDString Metadata unsigned LineNo
Metadata Metadata MDString * Name
Metadata Metadata MDString Metadata * File
static LLVM_ABI const char * nameTableKindString(DebugNameTableKind PK)
static LLVM_ABI const char * emissionKindString(DebugEmissionKind EK)
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString * SysRoot
DISourceLanguageName Metadata MDString bool MDString * Flags
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString MDString * SDK
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata * GlobalVariables
DebugEmissionKind getEmissionKind() const
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata * EnumTypes
DISourceLanguageName Metadata MDString * Producer
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata * RetainedTypes
DISourceLanguageName Metadata MDString bool MDString unsigned MDString * SplitDebugFilename
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata * ImportedEntities
DISourceLanguageName Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata * Macros
DebugNameTableKind getNameTableKind() const
DISourceLanguageName Metadata * File
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t AlignInBits
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > EnumKind
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata * DataLocation
static LLVM_ABI DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, std::optional< uint32_t > EnumKind, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations, Metadata *BitStride)
Build a DICompositeType with the given ODR identifier.
unsigned MDString Metadata unsigned Line
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata * Elements
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned RuntimeLang
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata * Annotations
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString * Identifier
static LLVM_ABI DICompositeType * getODRTypeIfExists(LLVMContext &Context, MDString &Identifier)
unsigned MDString * Name
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata * Discriminator
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata * TemplateParams
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t OffsetInBits
unsigned MDString Metadata unsigned Metadata * Scope
unsigned MDString Metadata * File
unsigned MDString Metadata unsigned Metadata Metadata * BaseType
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Flags
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata * Allocated
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata Metadata * Specification
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata * VTableHolder
unsigned MDString Metadata unsigned Metadata Metadata uint64_t SizeInBits
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata * Associated
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata Metadata uint32_t NumExtraInhabitants
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata * Rank
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned std::optional< uint32_t > Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata Metadata Metadata uint32_t Metadata * BitStride
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata * OffsetInBits
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t AlignInBits
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata std::optional< unsigned > std::optional< PtrAuthData > PtrAuthData
Metadata * getExtraData() const
Get extra data associated with this derived type.
unsigned StringRef DIFile * File
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata std::optional< unsigned > DWARFAddressSpace
LLVM_ABI DIType * getClassType() const
Get casted version of extra data.
LLVM_ABI Constant * getConstant() const
unsigned StringRef DIFile unsigned DIScope DIType Metadata * SizeInBits
LLVM_ABI Constant * getStorageOffsetInBits() const
LLVM_ABI Constant * getDiscriminantValue() const
unsigned StringRef Name
LLVM_ABI uint32_t getVBPtrOffset() const
Enumeration value.
int64_t bool MDString * Name
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
LLVM_ABI bool isNonEmitting() const
Return true if CodeGen handles this operand without adding bytes to the DWARF expression.
LLVM_ABI unsigned getSize() const
Return the size of the operand.
bool is(uint64_t Opcode) const
Return true if this is Opcode.
uint64_t getOp() const
Get the operand code.
static LLVM_ABI bool classof(const ExprOperand *Op)
LLVM_ABI bool isSigned() const
Return whether the extracted value is sign-extended.
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
static LLVM_ABI bool classof(const ExprOperand *Op)
An iterator for expression operands.
DWARF expression.
element_iterator elements_end() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
iterator_range< expr_op_iterator > expr_ops() const
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
std::array< uint64_t, 6 > ExtOps
unsigned getNumElements() const
static LLVM_ABI ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed)
Returns the ops for a zero- or sign-extension in a DIExpression.
expr_op_iterator expr_op_begin() const
Visit the elements via ExprOperand wrappers.
LLVM_ABI bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
DbgVariableFragmentInfo FragmentInfo
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
static LLVM_ABI bool isEqualExpression(const DIExpression *FirstExpr, bool FirstIndirect, const DIExpression *SecondExpr, bool SecondIndirect)
Determines whether two debug values should produce equivalent DWARF expressions, using their DIExpres...
expr_op_iterator expr_op_end() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static LLVM_ABI bool calculateFragmentIntersect(const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits, uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits, int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag, std::optional< DIExpression::FragmentInfo > &Result, int64_t &OffsetFromLocationInBits)
Computes a fragment, bit-extract operation if needed, and new constant offset to describe a part of a...
element_iterator elements_begin() const
LLVM_ABI bool hasAllLocationOps(unsigned N) const
Returns true iff this DIExpression contains at least one instance of DW_OP_LLVM_arg,...
std::optional< FragmentInfo > getFragmentInfo() const
Retrieve the details of this fragment expression.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
LLVM_ABI bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
LLVM_ABI std::pair< DIExpression *, const ConstantInt * > constantFold(const ConstantInt *CI)
Try to shorten an expression with an initial constant operand.
LLVM_ABI bool isDeref() const
Return whether there is exactly one operator and it is a DW_OP_deref;.
static LLVM_ABI const DIExpression * convertToVariadicExpression(const DIExpression *Expr)
If Expr is a non-variadic expression (i.e.
LLVM_ABI uint64_t getNumLocationOperands() const
Return the number of unique location operands referred to (via DW_OP_LLVM_arg) in this expression; th...
ArrayRef< uint64_t > getElements() const
static LLVM_ABI DIExpression * replaceArg(const DIExpression *Expr, uint64_t OldArg, uint64_t NewArg)
Create a copy of Expr with each instance of DW_OP_LLVM_arg, \p OldArg replaced with DW_OP_LLVM_arg,...
LLVM_ABI std::optional< uint64_t > getActiveBits(DIVariable *Var)
Return the number of bits that have an active value, i.e.
static LLVM_ABI void canonicalizeExpressionOps(SmallVectorImpl< uint64_t > &Ops, const DIExpression *Expr, bool IsIndirect)
Inserts the elements of Expr into Ops modified to a canonical form, which uses DW_OP_LLVM_arg (i....
uint64_t getElement(unsigned I) const
static LLVM_ABI bool extractLeadingOffset(ArrayRef< uint64_t > Ops, int64_t &OffsetInBytes, SmallVectorImpl< uint64_t > &RemainingOps)
static LLVM_ABI std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
static LLVM_ABI const DIExpression * convertToUndefExpression(const DIExpression *Expr)
Removes all elements from Expr that do not apply to an undef debug value, which includes every operat...
static LLVM_ABI DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
static LLVM_ABI DIExpression * appendToStack(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Convert DIExpr into a stack value if it isn't one already by appending DW_OP_deref if needed,...
static LLVM_ABI DIExpression * appendExt(const DIExpression *Expr, unsigned FromSize, unsigned ToSize, bool Signed)
Append a zero- or sign-extension to Expr.
LLVM_ABI std::optional< ArrayRef< uint64_t > > getSingleLocationExpressionElements() const
Returns a reference to the elements contained in this expression, skipping past the leading DW_OP_LLV...
LLVM_ABI bool isSingleLocationExpression() const
Return whether the evaluated expression makes use of a single location at the start of the expression...
LLVM_ABI std::optional< SignedOrUnsignedConstant > isConstant() const
Determine whether this represents a constant value, if so.
LLVM_ABI bool isValid() const
static LLVM_ABI const DIExpression * extractAddressClass(const DIExpression *Expr, unsigned &AddrClass)
Checks if the last 4 elements of the expression are DW_OP_constu <DWARFAddress Space> DW_OP_swap DW_O...
static LLVM_ABI DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
MDString MDString * Directory
MDString MDString std::optional< ChecksumInfo< MDString * > > MDString * Source
static LLVM_ABI std::optional< ChecksumKind > getChecksumKind(StringRef CSKindStr)
MDString MDString std::optional< ChecksumInfo< MDString * > > CS
static LLVM_ABI std::optional< FixedPointKind > getFixedPointKind(StringRef Str)
static LLVM_ABI const char * fixedPointKindString(FixedPointKind)
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned DIFlags unsigned int APInt Numerator
unsigned StringRef DIFile unsigned LineNo
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned Encoding
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned DIFlags unsigned int APInt APInt Denominator
unsigned StringRef DIFile unsigned DIScope uint64_t SizeInBits
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t AlignInBits
LLVM_ABI bool isSigned() const
unsigned StringRef DIFile unsigned DIScope uint64_t uint32_t unsigned DIFlags unsigned int Factor
@ FixedPointBinary
Scale factor 2^Factor.
@ FixedPointDecimal
Scale factor 10^Factor.
@ FixedPointRational
Arbitrary rational scale factor.
unsigned StringRef DIFile * File
Metadata * getRawLowerBound() const
Metadata * getRawCountNode() const
Metadata * getRawStride() const
LLVM_ABI BoundType getLowerBound() const
Metadata * getRawUpperBound() const
LLVM_ABI BoundType getCount() const
LLVM_ABI BoundType getUpperBound() const
PointerUnion< DIVariable *, DIExpression * > BoundType
LLVM_ABI BoundType getStride() const
A pair of DIGlobalVariable and DIExpression.
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata * TemplateParams
Metadata MDString MDString Metadata unsigned Line
Metadata MDString MDString Metadata unsigned Metadata * Type
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata uint32_t Metadata * Annotations
Metadata MDString * Name
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata * StaticDataMemberDeclaration
Metadata MDString MDString * LinkageName
Metadata MDString MDString Metadata * File
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata uint32_t AlignInBits
An imported module (C++ using directive or similar).
unsigned Metadata Metadata * Entity
unsigned Metadata Metadata Metadata unsigned Line
unsigned Metadata Metadata Metadata unsigned MDString * Name
unsigned Metadata Metadata Metadata * File
unsigned Metadata * Scope
Metadata MDString Metadata unsigned unsigned bool std::optional< unsigned > CoroSuspendIdx
Metadata MDString Metadata unsigned unsigned Column
Metadata MDString Metadata unsigned unsigned bool IsArtificial
Metadata MDString Metadata unsigned Line
Metadata MDString * Name
Metadata MDString Metadata * File
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.
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
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
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata * Declaration
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:223
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:299
iterator end()
Definition DenseMap.h:141
Class representing an expression and its matching format.
Generic tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
unsigned MDString * Header
unsigned MDString ArrayRef< Metadata * > DwarfOps
DenseSet< DIArgList *, DIArgListInfo > DIArgLists
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
LLVMContextImpl *const pImpl
Definition LLVMContext.h:70
Metadata node.
Definition Metadata.h:1069
friend class DIAssignID
Definition Metadata.h:1072
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1575
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1567
LLVM_ABI TempMDNode clone() const
Create a (temporary) clone of this.
Definition Metadata.cpp:684
static T * storeImpl(T *N, StorageType Storage, StoreT &Store)
LLVMContext & getContext() const
Definition Metadata.h:1233
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:1301
A single uniqued string.
Definition Metadata.h:722
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:633
static void untrack(Metadata *&MD)
Stop tracking a reference to metadata.
Definition Metadata.h:358
static bool track(Metadata *&MD)
Track the reference to metadata.
Definition Metadata.h:324
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.
LLVM_ABI void replaceAllUsesWith(Metadata *MD)
Replace all uses of this with MD.
Definition Metadata.cpp:376
LLVMContext & getContext() const
Definition Metadata.h:409
LLVM_ABI void resolveAllUses(bool ResolveUsers=true)
Resolve all uses of this.
Definition Metadata.cpp:429
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:310
Value wrapper in the Metadata hierarchy.
Definition Metadata.h:459
static LLVM_ABI ValueAsMetadata * get(Value *V)
Definition Metadata.cpp:510
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:1089
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
Calculates the starting offsets for various sections within the .debug_names section.
Definition Dwarf.h:35
@ DW_OP_LLVM_entry_value
Only used in LLVM metadata.
Definition Dwarf.h:147
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
Definition Dwarf.h:148
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
Definition Dwarf.h:151
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition Dwarf.h:146
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Definition Dwarf.h:144
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
Definition Dwarf.h:149
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Definition Dwarf.h:145
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
Definition Dwarf.h:150
@ DW_VIRTUALITY_max
Definition Dwarf.h:200
@ NameTableKind
Definition LLToken.h:518
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:315
@ Offset
Definition DWP.cpp:578
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:2208
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:1746
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
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:1753
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI cl::opt< bool > PickMergedSourceLocations("pick-merged-source-locations", cl::init(false), cl::Hidden, cl::desc("Preserve line and column number when merging locations."))
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