LLVM 22.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
57DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
58 unsigned Column, uint64_t AtomGroup, uint8_t AtomRank,
59 ArrayRef<Metadata *> MDs, bool ImplicitCode)
60 : MDNode(C, DILocationKind, Storage, MDs), AtomGroup(AtomGroup),
61 AtomRank(AtomRank) {
62 assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits");
63 if (AtomGroup)
64 C.updateDILocationAtomGroupWaterline(AtomGroup + 1);
65
66 assert((MDs.size() == 1 || MDs.size() == 2) &&
67 "Expected a scope and optional inlined-at");
68 // Set line and column.
69 assert(Column < (1u << 16) && "Expected 16-bit column");
70
71 SubclassData32 = Line;
72 SubclassData16 = Column;
73
74 setImplicitCode(ImplicitCode);
75}
76
77static void adjustColumn(unsigned &Column) {
78 // Set to unknown on overflow. We only have 16 bits to play with here.
79 if (Column >= (1u << 16))
80 Column = 0;
81}
82
83DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
84 unsigned Column, Metadata *Scope,
85 Metadata *InlinedAt, bool ImplicitCode,
86 uint64_t AtomGroup, uint8_t AtomRank,
87 StorageType Storage, bool ShouldCreate) {
88 // Fixup column.
90
91 if (Storage == Uniqued) {
92 if (auto *N = getUniqued(Context.pImpl->DILocations,
93 DILocationInfo::KeyTy(Line, Column, Scope,
95 AtomGroup, AtomRank)))
96 return N;
97 if (!ShouldCreate)
98 return nullptr;
99 } else {
100 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
101 }
102
104 Ops.push_back(Scope);
105 if (InlinedAt)
106 Ops.push_back(InlinedAt);
107 return storeImpl(new (Ops.size(), Storage)
108 DILocation(Context, Storage, Line, Column, AtomGroup,
109 AtomRank, Ops, ImplicitCode),
110 Storage, Context.pImpl->DILocations);
111}
112
114 if (Locs.empty())
115 return nullptr;
116 if (Locs.size() == 1)
117 return Locs[0];
118 auto *Merged = Locs[0];
119 for (DILocation *L : llvm::drop_begin(Locs)) {
120 Merged = getMergedLocation(Merged, L);
121 if (Merged == nullptr)
122 break;
123 }
124 return Merged;
125}
126
128 DIScope *NewParent) {
129 TempMDNode ClonedScope = LBB->clone();
130 cast<DILexicalBlockBase>(*ClonedScope).replaceScope(NewParent);
131 return cast<DILexicalBlockBase>(
132 MDNode::replaceWithUniqued(std::move(ClonedScope)));
133}
134
135using LineColumn = std::pair<unsigned /* Line */, unsigned /* Column */>;
136
137/// Returns the location of DILocalScope, if present, or a default value.
139 assert(isa<DILocalScope>(S) && "Expected DILocalScope.");
140
141 if (isa<DILexicalBlockFile>(S))
142 return Default;
143 if (auto *LB = dyn_cast<DILexicalBlock>(S))
144 return {LB->getLine(), LB->getColumn()};
145 if (auto *SP = dyn_cast<DISubprogram>(S))
146 return {SP->getLine(), 0u};
147
148 llvm_unreachable("Unhandled type of DILocalScope.");
149}
150
151// Returns the nearest matching scope inside a subprogram.
152template <typename MatcherT>
153static std::pair<DIScope *, LineColumn>
155 MatcherT Matcher;
156
157 DIScope *S1 = L1->getScope();
158 DIScope *S2 = L2->getScope();
159
160 LineColumn Loc1(L1->getLine(), L1->getColumn());
161 for (; S1; S1 = S1->getScope()) {
162 Loc1 = getLocalScopeLocationOr(S1, Loc1);
163 Matcher.insert(S1, Loc1);
164 if (isa<DISubprogram>(S1))
165 break;
166 }
167
168 LineColumn Loc2(L2->getLine(), L2->getColumn());
169 for (; S2; S2 = S2->getScope()) {
170 Loc2 = getLocalScopeLocationOr(S2, Loc2);
171
172 if (DIScope *S = Matcher.match(S2, Loc2))
173 return std::make_pair(S, Loc2);
174
175 if (isa<DISubprogram>(S2))
176 break;
177 }
178 return std::make_pair(nullptr, LineColumn(L2->getLine(), L2->getColumn()));
179}
180
181// Matches equal scopes.
184
185 void insert(DIScope *S, LineColumn Loc) { Scopes.insert(S); }
186
188 return Scopes.contains(S) ? S : nullptr;
189 }
190};
191
192// Matches scopes with the same location.
195 8>
197
198 void insert(DIScope *S, LineColumn Loc) {
199 Scopes[{S->getFile(), Loc}].insert(S);
200 }
201
203 auto ScopesAtLoc = Scopes.find({S->getFile(), Loc});
204 // No scope found with the given location.
205 if (ScopesAtLoc == Scopes.end())
206 return nullptr;
207
208 // Prefer S over other scopes with the same location.
209 if (ScopesAtLoc->second.contains(S))
210 return S;
211
212 if (!ScopesAtLoc->second.empty())
213 return *ScopesAtLoc->second.begin();
214
215 llvm_unreachable("Scopes must not have empty entries.");
216 }
217};
218
220 if (LocA == LocB)
221 return LocA;
222
223 // For some use cases (SamplePGO), it is important to retain distinct source
224 // locations. When this flag is set, we choose arbitrarily between A and B,
225 // rather than computing a merged location using line 0, which is typically
226 // not useful for PGO. If one of them is null, then try to return one which is
227 // valid.
229 if (!LocA || !LocB)
230 return LocA ? LocA : LocB;
231
232 auto A = std::make_tuple(LocA->getLine(), LocA->getColumn(),
233 LocA->getDiscriminator(), LocA->getFilename(),
234 LocA->getDirectory());
235 auto B = std::make_tuple(LocB->getLine(), LocB->getColumn(),
236 LocB->getDiscriminator(), LocB->getFilename(),
237 LocB->getDirectory());
238 return A < B ? LocA : LocB;
239 }
240
241 if (!LocA || !LocB)
242 return nullptr;
243
244 LLVMContext &C = LocA->getContext();
245
246 using LocVec = SmallVector<const DILocation *>;
247 LocVec ALocs;
248 LocVec BLocs;
250 4>
251 ALookup;
252
253 // Walk through LocA and its inlined-at locations, populate them in ALocs and
254 // save the index for the subprogram and inlined-at pair, which we use to find
255 // a matching starting location in LocB's chain.
256 for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) {
257 ALocs.push_back(L);
258 auto Res = ALookup.try_emplace(
259 {L->getScope()->getSubprogram(), L->getInlinedAt()}, I);
260 assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?");
261 (void)Res;
262 }
263
264 LocVec::reverse_iterator ARIt = ALocs.rend();
265 LocVec::reverse_iterator BRIt = BLocs.rend();
266
267 // Populate BLocs and look for a matching starting location, the first
268 // location with the same subprogram and inlined-at location as in LocA's
269 // chain. Since the two locations have the same inlined-at location we do
270 // not need to look at those parts of the chains.
271 for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) {
272 BLocs.push_back(L);
273
274 if (ARIt != ALocs.rend())
275 // We have already found a matching starting location.
276 continue;
277
278 auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()});
279 if (IT == ALookup.end())
280 continue;
281
282 // The + 1 is to account for the &*rev_it = &(it - 1) relationship.
283 ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1);
284 BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1);
285
286 // If we have found a matching starting location we do not need to add more
287 // locations to BLocs, since we will only look at location pairs preceding
288 // the matching starting location, and adding more elements to BLocs could
289 // invalidate the iterator that we initialized here.
290 break;
291 }
292
293 // Merge the two locations if possible, using the supplied
294 // inlined-at location for the created location.
295 auto *LocAIA = LocA->getInlinedAt();
296 auto *LocBIA = LocB->getInlinedAt();
297 auto MergeLocPair = [&C, LocAIA,
298 LocBIA](const DILocation *L1, const DILocation *L2,
300 if (L1 == L2)
301 return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(),
302 InlinedAt, L1->isImplicitCode(),
303 L1->getAtomGroup(), L1->getAtomRank());
304
305 // If the locations originate from different subprograms we can't produce
306 // a common location.
307 if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())
308 return nullptr;
309
310 // Find nearest common scope inside subprogram.
311 DIScope *Scope = getNearestMatchingScope<EqualScopesMatcher>(L1, L2).first;
312 assert(Scope && "No common scope in the same subprogram?");
313
314 // Try using the nearest scope with common location if files are different.
315 if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile()) {
316 auto [CommonLocScope, CommonLoc] =
317 getNearestMatchingScope<ScopeLocationsMatcher>(L1, L2);
318
319 // If CommonLocScope is a DILexicalBlockBase, clone it and locate
320 // a new scope inside the nearest common scope to preserve
321 // lexical blocks structure.
322 if (auto *LBB = dyn_cast<DILexicalBlockBase>(CommonLocScope);
323 LBB && LBB != Scope)
324 CommonLocScope = cloneAndReplaceParentScope(LBB, Scope);
325
326 Scope = CommonLocScope;
327
328 // If files are still different, assume that L1 and L2 were "included"
329 // from CommonLoc. Use it as merged location.
330 if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile())
331 return DILocation::get(C, CommonLoc.first, CommonLoc.second,
332 CommonLocScope, InlinedAt);
333 }
334
335 bool SameLine = L1->getLine() == L2->getLine();
336 bool SameCol = L1->getColumn() == L2->getColumn();
337 unsigned Line = SameLine ? L1->getLine() : 0;
338 unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;
339 bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode();
340
341 // Discard source location atom if the line becomes 0. And there's nothing
342 // further to do if neither location has an atom number.
343 if (!SameLine || !(L1->getAtomGroup() || L2->getAtomGroup()))
344 return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
345 /*AtomGroup*/ 0, /*AtomRank*/ 0);
346
347 uint64_t Group = 0;
348 uint64_t Rank = 0;
349 // If we're preserving the same matching inlined-at field we can
350 // preserve the atom.
351 if (LocBIA == LocAIA && InlinedAt == LocBIA) {
352 // Deterministically keep the lowest non-zero ranking atom group
353 // number.
354 // FIXME: It would be nice if we could track that an instruction
355 // belongs to two source atoms.
356 bool UseL1Atom = [L1, L2]() {
357 if (L1->getAtomRank() == L2->getAtomRank()) {
358 // Arbitrarily choose the lowest non-zero group number.
359 if (!L1->getAtomGroup() || !L2->getAtomGroup())
360 return !L2->getAtomGroup();
361 return L1->getAtomGroup() < L2->getAtomGroup();
362 }
363 // Choose the lowest non-zero rank.
364 if (!L1->getAtomRank() || !L2->getAtomRank())
365 return !L2->getAtomRank();
366 return L1->getAtomRank() < L2->getAtomRank();
367 }();
368 Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup();
369 Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank();
370 } else {
371 // If either instruction is part of a source atom, reassign it a new
372 // atom group. This essentially regresses to non-key-instructions
373 // behaviour (now that it's the only instruction in its group it'll
374 // probably get is_stmt applied).
375 Group = C.incNextDILocationAtomGroup();
376 Rank = 1;
377 }
378 return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
379 Group, Rank);
380 };
381
382 DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr;
383
384 // If we have found a common starting location, walk up the inlined-at chains
385 // and try to produce common locations.
386 for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {
387 DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);
388
389 if (!Tmp)
390 // We have walked up to a point in the chains where the two locations
391 // are irreconsilable. At this point Result contains the nearest common
392 // location in the inlined-at chains of LocA and LocB, so we break here.
393 break;
394
395 Result = Tmp;
396 }
397
398 if (Result)
399 return Result;
400
401 // We ended up with LocA and LocB as irreconsilable locations. Produce a
402 // location at 0:0 with one of the locations' scope. The function has
403 // historically picked A's scope, and a nullptr inlined-at location, so that
404 // behavior is mimicked here but I am not sure if this is always the correct
405 // way to handle this.
406 // Key Instructions: it's fine to drop atom group and rank here, as line 0
407 // is a nonsensical is_stmt location.
408 return DILocation::get(C, 0, 0, LocA->getScope(), nullptr, false,
409 /*AtomGroup*/ 0, /*AtomRank*/ 0);
410}
411
412std::optional<unsigned>
413DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
414 std::array<unsigned, 3> Components = {BD, DF, CI};
415 uint64_t RemainingWork = 0U;
416 // We use RemainingWork to figure out if we have no remaining components to
417 // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
418 // encode anything for the latter 2.
419 // Since any of the input components is at most 32 bits, their sum will be
420 // less than 34 bits, and thus RemainingWork won't overflow.
421 RemainingWork =
422 std::accumulate(Components.begin(), Components.end(), RemainingWork);
423
424 int I = 0;
425 unsigned Ret = 0;
426 unsigned NextBitInsertionIndex = 0;
427 while (RemainingWork > 0) {
428 unsigned C = Components[I++];
429 RemainingWork -= C;
430 unsigned EC = encodeComponent(C);
431 Ret |= (EC << NextBitInsertionIndex);
432 NextBitInsertionIndex += encodingBits(C);
433 }
434
435 // Encoding may be unsuccessful because of overflow. We determine success by
436 // checking equivalence of components before & after encoding. Alternatively,
437 // we could determine Success during encoding, but the current alternative is
438 // simpler.
439 unsigned TBD, TDF, TCI = 0;
440 decodeDiscriminator(Ret, TBD, TDF, TCI);
441 if (TBD == BD && TDF == DF && TCI == CI)
442 return Ret;
443 return std::nullopt;
444}
445
446void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
447 unsigned &CI) {
452}
454
456 return StringSwitch<DIFlags>(Flag)
457#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
458#include "llvm/IR/DebugInfoFlags.def"
459 .Default(DINode::FlagZero);
460}
461
463 switch (Flag) {
464#define HANDLE_DI_FLAG(ID, NAME) \
465 case Flag##NAME: \
466 return "DIFlag" #NAME;
467#include "llvm/IR/DebugInfoFlags.def"
468 }
469 return "";
470}
471
473 SmallVectorImpl<DIFlags> &SplitFlags) {
474 // Flags that are packed together need to be specially handled, so
475 // that, for example, we emit "DIFlagPublic" and not
476 // "DIFlagPrivate | DIFlagProtected".
477 if (DIFlags A = Flags & FlagAccessibility) {
478 if (A == FlagPrivate)
479 SplitFlags.push_back(FlagPrivate);
480 else if (A == FlagProtected)
481 SplitFlags.push_back(FlagProtected);
482 else
483 SplitFlags.push_back(FlagPublic);
484 Flags &= ~A;
485 }
486 if (DIFlags R = Flags & FlagPtrToMemberRep) {
487 if (R == FlagSingleInheritance)
488 SplitFlags.push_back(FlagSingleInheritance);
489 else if (R == FlagMultipleInheritance)
490 SplitFlags.push_back(FlagMultipleInheritance);
491 else
492 SplitFlags.push_back(FlagVirtualInheritance);
493 Flags &= ~R;
494 }
495 if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
496 Flags &= ~FlagIndirectVirtualBase;
497 SplitFlags.push_back(FlagIndirectVirtualBase);
498 }
499
500#define HANDLE_DI_FLAG(ID, NAME) \
501 if (DIFlags Bit = Flags & Flag##NAME) { \
502 SplitFlags.push_back(Bit); \
503 Flags &= ~Bit; \
504 }
505#include "llvm/IR/DebugInfoFlags.def"
506 return Flags;
507}
508
510 if (auto *T = dyn_cast<DIType>(this))
511 return T->getScope();
512
513 if (auto *SP = dyn_cast<DISubprogram>(this))
514 return SP->getScope();
515
516 if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
517 return LB->getScope();
518
519 if (auto *NS = dyn_cast<DINamespace>(this))
520 return NS->getScope();
521
522 if (auto *CB = dyn_cast<DICommonBlock>(this))
523 return CB->getScope();
524
525 if (auto *M = dyn_cast<DIModule>(this))
526 return M->getScope();
527
528 assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
529 "Unhandled type of scope.");
530 return nullptr;
531}
532
534 if (auto *T = dyn_cast<DIType>(this))
535 return T->getName();
536 if (auto *SP = dyn_cast<DISubprogram>(this))
537 return SP->getName();
538 if (auto *NS = dyn_cast<DINamespace>(this))
539 return NS->getName();
540 if (auto *CB = dyn_cast<DICommonBlock>(this))
541 return CB->getName();
542 if (auto *M = dyn_cast<DIModule>(this))
543 return M->getName();
544 assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
545 isa<DICompileUnit>(this)) &&
546 "Unhandled type of scope.");
547 return "";
548}
549
550#ifndef NDEBUG
551static bool isCanonical(const MDString *S) {
552 return !S || !S->getString().empty();
553}
554#endif
555
557GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
558 MDString *Header,
559 ArrayRef<Metadata *> DwarfOps,
560 StorageType Storage, bool ShouldCreate) {
561 unsigned Hash = 0;
562 if (Storage == Uniqued) {
563 GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);
564 if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))
565 return N;
566 if (!ShouldCreate)
567 return nullptr;
568 Hash = Key.getHash();
569 } else {
570 assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
571 }
572
573 // Use a nullptr for empty headers.
574 assert(isCanonical(Header) && "Expected canonical MDString");
575 Metadata *PreOps[] = {Header};
576 return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(
577 Context, Storage, Hash, Tag, PreOps, DwarfOps),
578 Storage, Context.pImpl->GenericDINodes);
579}
580
581void GenericDINode::recalculateHash() {
582 setHash(GenericDINodeInfo::KeyTy::calculateHash(this));
583}
584
585#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
586#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
587#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \
588 do { \
589 if (Storage == Uniqued) { \
590 if (auto *N = getUniqued(Context.pImpl->CLASS##s, \
591 CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \
592 return N; \
593 if (!ShouldCreate) \
594 return nullptr; \
595 } else { \
596 assert(ShouldCreate && \
597 "Expected non-uniqued nodes to always be created"); \
598 } \
599 } while (false)
600#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \
601 return storeImpl(new (std::size(OPS), Storage) \
602 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
603 Storage, Context.pImpl->CLASS##s)
604#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \
605 return storeImpl(new (0u, Storage) \
606 CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \
607 Storage, Context.pImpl->CLASS##s)
608#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \
609 return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \
610 Storage, Context.pImpl->CLASS##s)
611#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \
612 return storeImpl(new (NUM_OPS, Storage) \
613 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \
614 Storage, Context.pImpl->CLASS##s)
615
616DISubrange::DISubrange(LLVMContext &C, StorageType Storage,
618 : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
619DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
620 StorageType Storage, bool ShouldCreate) {
623 auto *LB = ConstantAsMetadata::get(
625 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
626 ShouldCreate);
627}
628
629DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
630 int64_t Lo, StorageType Storage,
631 bool ShouldCreate) {
632 auto *LB = ConstantAsMetadata::get(
634 return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
635 ShouldCreate);
636}
637
638DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
639 Metadata *LB, Metadata *UB, Metadata *Stride,
640 StorageType Storage, bool ShouldCreate) {
641 DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride));
642 Metadata *Ops[] = {CountNode, LB, UB, Stride};
644}
645
646DISubrange::BoundType DISubrange::getCount() const {
647 Metadata *CB = getRawCountNode();
648 if (!CB)
649 return BoundType();
650
651 assert((isa<ConstantAsMetadata>(CB) || isa<DIVariable>(CB) ||
652 isa<DIExpression>(CB)) &&
653 "Count must be signed constant or DIVariable or DIExpression");
654
655 if (auto *MD = dyn_cast<ConstantAsMetadata>(CB))
656 return BoundType(cast<ConstantInt>(MD->getValue()));
657
658 if (auto *MD = dyn_cast<DIVariable>(CB))
659 return BoundType(MD);
660
661 if (auto *MD = dyn_cast<DIExpression>(CB))
662 return BoundType(MD);
663
664 return BoundType();
665}
666
667DISubrange::BoundType DISubrange::getLowerBound() const {
668 Metadata *LB = getRawLowerBound();
669 if (!LB)
670 return BoundType();
671
672 assert((isa<ConstantAsMetadata>(LB) || isa<DIVariable>(LB) ||
673 isa<DIExpression>(LB)) &&
674 "LowerBound must be signed constant or DIVariable or DIExpression");
675
676 if (auto *MD = dyn_cast<ConstantAsMetadata>(LB))
677 return BoundType(cast<ConstantInt>(MD->getValue()));
678
679 if (auto *MD = dyn_cast<DIVariable>(LB))
680 return BoundType(MD);
681
682 if (auto *MD = dyn_cast<DIExpression>(LB))
683 return BoundType(MD);
684
685 return BoundType();
686}
687
688DISubrange::BoundType DISubrange::getUpperBound() const {
689 Metadata *UB = getRawUpperBound();
690 if (!UB)
691 return BoundType();
692
693 assert((isa<ConstantAsMetadata>(UB) || isa<DIVariable>(UB) ||
694 isa<DIExpression>(UB)) &&
695 "UpperBound must be signed constant or DIVariable or DIExpression");
696
697 if (auto *MD = dyn_cast<ConstantAsMetadata>(UB))
698 return BoundType(cast<ConstantInt>(MD->getValue()));
699
700 if (auto *MD = dyn_cast<DIVariable>(UB))
701 return BoundType(MD);
702
703 if (auto *MD = dyn_cast<DIExpression>(UB))
704 return BoundType(MD);
705
706 return BoundType();
707}
708
709DISubrange::BoundType DISubrange::getStride() const {
710 Metadata *ST = getRawStride();
711 if (!ST)
712 return BoundType();
713
714 assert((isa<ConstantAsMetadata>(ST) || isa<DIVariable>(ST) ||
715 isa<DIExpression>(ST)) &&
716 "Stride must be signed constant or DIVariable or DIExpression");
717
718 if (auto *MD = dyn_cast<ConstantAsMetadata>(ST))
719 return BoundType(cast<ConstantInt>(MD->getValue()));
720
721 if (auto *MD = dyn_cast<DIVariable>(ST))
722 return BoundType(MD);
723
724 if (auto *MD = dyn_cast<DIExpression>(ST))
725 return BoundType(MD);
726
727 return BoundType();
728}
729DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,
731 : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
732 Ops) {}
733
734DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
735 Metadata *CountNode, Metadata *LB,
736 Metadata *UB, Metadata *Stride,
737 StorageType Storage,
738 bool ShouldCreate) {
739 DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
740 Metadata *Ops[] = {CountNode, LB, UB, Stride};
742}
743
746 if (!CB)
747 return BoundType();
748
749 assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&
750 "Count must be signed constant or DIVariable or DIExpression");
751
752 if (auto *MD = dyn_cast<DIVariable>(CB))
753 return BoundType(MD);
754
755 if (auto *MD = dyn_cast<DIExpression>(CB))
756 return BoundType(MD);
757
758 return BoundType();
759}
760
763 if (!LB)
764 return BoundType();
765
766 assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&
767 "LowerBound must be signed constant or DIVariable or DIExpression");
768
769 if (auto *MD = dyn_cast<DIVariable>(LB))
770 return BoundType(MD);
771
772 if (auto *MD = dyn_cast<DIExpression>(LB))
773 return BoundType(MD);
774
775 return BoundType();
776}
777
780 if (!UB)
781 return BoundType();
782
783 assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&
784 "UpperBound must be signed constant or DIVariable or DIExpression");
785
786 if (auto *MD = dyn_cast<DIVariable>(UB))
787 return BoundType(MD);
788
789 if (auto *MD = dyn_cast<DIExpression>(UB))
790 return BoundType(MD);
791
792 return BoundType();
793}
794
796 Metadata *ST = getRawStride();
797 if (!ST)
798 return BoundType();
799
800 assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&
801 "Stride must be signed constant or DIVariable or DIExpression");
802
803 if (auto *MD = dyn_cast<DIVariable>(ST))
804 return BoundType(MD);
805
806 if (auto *MD = dyn_cast<DIExpression>(ST))
807 return BoundType(MD);
808
809 return BoundType();
810}
811
812DISubrangeType::DISubrangeType(LLVMContext &C, StorageType Storage,
813 unsigned Line, uint32_t AlignInBits,
814 DIFlags Flags, ArrayRef<Metadata *> Ops)
815 : DIType(C, DISubrangeTypeKind, Storage, dwarf::DW_TAG_subrange_type, Line,
816 AlignInBits, 0, Flags, Ops) {}
817
818DISubrangeType *DISubrangeType::getImpl(
819 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
820 Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags,
821 Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
822 Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate) {
823 assert(isCanonical(Name) && "Expected canonical MDString");
827 Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr,
830}
831
833DISubrangeType::convertRawToBound(Metadata *IN) const {
834 if (!IN)
835 return BoundType();
836
837 assert(isa<ConstantAsMetadata>(IN) || isa<DIVariable>(IN) ||
838 isa<DIExpression>(IN));
839
840 if (auto *MD = dyn_cast<ConstantAsMetadata>(IN))
841 return BoundType(cast<ConstantInt>(MD->getValue()));
842
843 if (auto *MD = dyn_cast<DIVariable>(IN))
844 return BoundType(MD);
845
846 if (auto *MD = dyn_cast<DIExpression>(IN))
847 return BoundType(MD);
848
849 return BoundType();
850}
851
852DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,
853 const APInt &Value, bool IsUnsigned,
855 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
856 Value(Value) {
857 SubclassData32 = IsUnsigned;
858}
859DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
860 bool IsUnsigned, MDString *Name,
861 StorageType Storage, bool ShouldCreate) {
862 assert(isCanonical(Name) && "Expected canonical MDString");
864 Metadata *Ops[] = {Name};
866}
867
869 MDString *Name, Metadata *SizeInBits,
870 uint32_t AlignInBits, unsigned Encoding,
871 uint32_t NumExtraInhabitants, DIFlags Flags,
872 StorageType Storage, bool ShouldCreate) {
873 assert(isCanonical(Name) && "Expected canonical MDString");
875 Encoding, NumExtraInhabitants, Flags));
876 Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr};
879 Ops);
880}
881
882std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
883 switch (getEncoding()) {
884 case dwarf::DW_ATE_signed:
885 case dwarf::DW_ATE_signed_char:
886 case dwarf::DW_ATE_signed_fixed:
887 return Signedness::Signed;
888 case dwarf::DW_ATE_unsigned:
889 case dwarf::DW_ATE_unsigned_char:
890 case dwarf::DW_ATE_unsigned_fixed:
892 default:
893 return std::nullopt;
894 }
895}
896
898DIFixedPointType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
899 Metadata *SizeInBits, uint32_t AlignInBits,
900 unsigned Encoding, DIFlags Flags, unsigned Kind,
901 int Factor, APInt Numerator, APInt Denominator,
902 StorageType Storage, bool ShouldCreate) {
905 Kind, Factor, Numerator, Denominator));
906 Metadata *Ops[] = {nullptr, nullptr, Name, SizeInBits, nullptr};
909 (Tag, AlignInBits, Encoding, Flags, Kind, Factor, Numerator, Denominator),
910 Ops);
911}
912
914 return getEncoding() == dwarf::DW_ATE_signed_fixed;
915}
916
917std::optional<DIFixedPointType::FixedPointKind>
920 .Case("Binary", FixedPointBinary)
921 .Case("Decimal", FixedPointDecimal)
922 .Case("Rational", FixedPointRational)
923 .Default(std::nullopt);
924}
925
927 switch (V) {
928 case FixedPointBinary:
929 return "Binary";
931 return "Decimal";
933 return "Rational";
934 }
935 return nullptr;
936}
937
938DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
939 MDString *Name, Metadata *StringLength,
940 Metadata *StringLengthExp,
941 Metadata *StringLocationExp,
942 Metadata *SizeInBits, uint32_t AlignInBits,
943 unsigned Encoding, StorageType Storage,
944 bool ShouldCreate) {
945 assert(isCanonical(Name) && "Expected canonical MDString");
949 Metadata *Ops[] = {nullptr, nullptr, Name,
950 SizeInBits, nullptr, StringLength,
953}
955 assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
956 return cast_or_null<DIType>(getExtraData());
957}
959 assert(getTag() == dwarf::DW_TAG_inheritance);
960 if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))
961 if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
962 return static_cast<uint32_t>(CI->getZExtValue());
963 return 0;
964}
966 assert(getTag() == dwarf::DW_TAG_member && isBitField());
967 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
968 return C->getValue();
969 return nullptr;
970}
971
973 assert((getTag() == dwarf::DW_TAG_member ||
974 getTag() == dwarf::DW_TAG_variable) &&
976 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
977 return C->getValue();
978 return nullptr;
979}
981 assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
982 if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))
983 return C->getValue();
984 return nullptr;
985}
986
987DIDerivedType *DIDerivedType::getImpl(
988 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
989 unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
990 uint32_t AlignInBits, Metadata *OffsetInBits,
991 std::optional<unsigned> DWARFAddressSpace,
992 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData,
993 Metadata *Annotations, StorageType Storage, bool ShouldCreate) {
994 assert(isCanonical(Name) && "Expected canonical MDString");
997 AlignInBits, OffsetInBits, DWARFAddressSpace,
998 PtrAuthData, Flags, ExtraData, Annotations));
999 Metadata *Ops[] = {File, Scope, Name, SizeInBits,
1003 (Tag, Line, AlignInBits, DWARFAddressSpace, PtrAuthData, Flags), Ops);
1004}
1005
1006std::optional<DIDerivedType::PtrAuthData>
1007DIDerivedType::getPtrAuthData() const {
1008 return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type
1009 ? std::make_optional<PtrAuthData>(SubclassData32)
1010 : std::nullopt;
1011}
1012
1013DICompositeType *DICompositeType::getImpl(
1014 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
1015 unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
1016 uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags,
1017 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1018 Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
1019 Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
1020 Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
1021 Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride,
1022 StorageType Storage, bool ShouldCreate) {
1023 assert(isCanonical(Name) && "Expected canonical MDString");
1024
1025 // Keep this in sync with buildODRType.
1032 Metadata *Ops[] = {File, Scope, Name, SizeInBits,
1038 (Tag, Line, RuntimeLang, AlignInBits,
1039 NumExtraInhabitants, EnumKind, Flags),
1040 Ops);
1041}
1042
1044 LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
1045 Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
1046 Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
1047 Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
1048 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1049 Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
1050 Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1051 Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
1052 assert(!Identifier.getString().empty() && "Expected valid identifier");
1053 if (!Context.isODRUniquingDebugTypes())
1054 return nullptr;
1055 auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
1056 if (!CT)
1057 return CT = DICompositeType::getDistinct(
1059 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
1063 if (CT->getTag() != Tag)
1064 return nullptr;
1065
1066 // Only mutate CT if it's a forward declaration and the new operands aren't.
1067 assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
1068 if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))
1069 return CT;
1070
1071 // Mutate CT in place. Keep this in sync with getImpl.
1072 CT->mutate(Tag, Line, RuntimeLang, AlignInBits, NumExtraInhabitants, EnumKind,
1073 Flags);
1074 Metadata *Ops[] = {File, Scope, Name, SizeInBits,
1079 assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
1080 "Mismatched number of operands");
1081 for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
1082 if (Ops[I] != CT->getOperand(I))
1083 CT->setOperand(I, Ops[I]);
1084 return CT;
1085}
1086
1087DICompositeType *DICompositeType::getODRType(
1088 LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
1089 Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
1090 Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
1091 Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
1092 Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
1093 Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
1094 Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
1095 Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
1096 assert(!Identifier.getString().empty() && "Expected valid identifier");
1097 if (!Context.isODRUniquingDebugTypes())
1098 return nullptr;
1099 auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
1100 if (!CT) {
1102 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
1103 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
1107 } else {
1108 if (CT->getTag() != Tag)
1109 return nullptr;
1110 }
1111 return CT;
1112}
1113
1115 MDString &Identifier) {
1116 assert(!Identifier.getString().empty() && "Expected valid identifier");
1117 if (!Context.isODRUniquingDebugTypes())
1118 return nullptr;
1119 return Context.pImpl->DITypeMap->lookup(&Identifier);
1120}
1121DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
1122 DIFlags Flags, uint8_t CC,
1124 : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
1125 0, 0, Flags, Ops),
1126 CC(CC) {}
1127
1128DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
1129 uint8_t CC, Metadata *TypeArray,
1130 StorageType Storage,
1131 bool ShouldCreate) {
1133 Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr, nullptr, TypeArray};
1135}
1136
1137DIFile::DIFile(LLVMContext &C, StorageType Storage,
1138 std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,
1140 : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
1141 Checksum(CS), Source(Src) {}
1142
1143// FIXME: Implement this string-enum correspondence with a .def file and macros,
1144// so that the association is explicit rather than implied.
1145static const char *ChecksumKindName[DIFile::CSK_Last] = {
1146 "CSK_MD5",
1147 "CSK_SHA1",
1148 "CSK_SHA256",
1149};
1150
1151StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
1152 assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
1153 // The first space was originally the CSK_None variant, which is now
1154 // obsolete, but the space is still reserved in ChecksumKind, so we account
1155 // for it here.
1156 return ChecksumKindName[CSKind - 1];
1157}
1158
1159std::optional<DIFile::ChecksumKind>
1162 .Case("CSK_MD5", DIFile::CSK_MD5)
1163 .Case("CSK_SHA1", DIFile::CSK_SHA1)
1164 .Case("CSK_SHA256", DIFile::CSK_SHA256)
1165 .Default(std::nullopt);
1166}
1167
1168DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
1169 MDString *Directory,
1170 std::optional<DIFile::ChecksumInfo<MDString *>> CS,
1171 MDString *Source, StorageType Storage,
1172 bool ShouldCreate) {
1173 assert(isCanonical(Filename) && "Expected canonical MDString");
1174 assert(isCanonical(Directory) && "Expected canonical MDString");
1175 assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
1176 // We do *NOT* expect Source to be a canonical MDString because nullptr
1177 // means none, so we need something to represent the empty file.
1179 Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source};
1180 DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);
1181}
1182DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
1183 unsigned SourceLanguage, bool IsOptimized,
1184 unsigned RuntimeVersion, unsigned EmissionKind,
1185 uint64_t DWOId, bool SplitDebugInlining,
1186 bool DebugInfoForProfiling, unsigned NameTableKind,
1187 bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
1188 : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
1189 SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion),
1191 IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),
1192 DebugInfoForProfiling(DebugInfoForProfiling),
1193 RangesBaseAddress(RangesBaseAddress) {
1195}
1196
1197DICompileUnit *DICompileUnit::getImpl(
1198 LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
1199 MDString *Producer, bool IsOptimized, MDString *Flags,
1200 unsigned RuntimeVersion, MDString *SplitDebugFilename,
1201 unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
1202 Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
1203 uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
1204 unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
1205 MDString *SDK, StorageType Storage, bool ShouldCreate) {
1206 assert(Storage != Uniqued && "Cannot unique DICompileUnit");
1207 assert(isCanonical(Producer) && "Expected canonical MDString");
1208 assert(isCanonical(Flags) && "Expected canonical MDString");
1209 assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");
1210
1211 Metadata *Ops[] = {File,
1212 Producer,
1213 Flags,
1215 EnumTypes,
1219 Macros,
1220 SysRoot,
1221 SDK};
1222 return storeImpl(new (std::size(Ops), Storage) DICompileUnit(
1223 Context, Storage, SourceLanguage, IsOptimized,
1224 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
1225 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
1226 Ops),
1227 Storage);
1228}
1229
1230std::optional<DICompileUnit::DebugEmissionKind>
1233 .Case("NoDebug", NoDebug)
1234 .Case("FullDebug", FullDebug)
1235 .Case("LineTablesOnly", LineTablesOnly)
1236 .Case("DebugDirectivesOnly", DebugDirectivesOnly)
1237 .Default(std::nullopt);
1238}
1239
1240std::optional<DICompileUnit::DebugNameTableKind>
1243 .Case("Default", DebugNameTableKind::Default)
1247 .Default(std::nullopt);
1248}
1249
1251 switch (EK) {
1252 case NoDebug:
1253 return "NoDebug";
1254 case FullDebug:
1255 return "FullDebug";
1256 case LineTablesOnly:
1257 return "LineTablesOnly";
1259 return "DebugDirectivesOnly";
1260 }
1261 return nullptr;
1262}
1263
1265 switch (NTK) {
1267 return nullptr;
1269 return "GNU";
1271 return "Apple";
1273 return "None";
1274 }
1275 return nullptr;
1276}
1277DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
1278 unsigned ScopeLine, unsigned VirtualIndex,
1279 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
1280 bool UsesKeyInstructions, ArrayRef<Metadata *> Ops)
1281 : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
1282 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
1283 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
1284 static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
1285 SubclassData1 = UsesKeyInstructions;
1286}
1288DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
1289 unsigned Virtuality, bool IsMainSubprogram) {
1290 // We're assuming virtuality is the low-order field.
1291 static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
1292 int(SPFlagPureVirtual) ==
1293 int(dwarf::DW_VIRTUALITY_pure_virtual),
1294 "Virtuality constant mismatch");
1295 return static_cast<DISPFlags>(
1296 (Virtuality & SPFlagVirtuality) |
1297 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1298 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
1299 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1300 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
1301}
1302
1304 if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
1305 return Block->getScope()->getSubprogram();
1306 return const_cast<DISubprogram *>(cast<DISubprogram>(this));
1307}
1308
1310 if (auto *File = dyn_cast<DILexicalBlockFile>(this))
1311 return File->getScope()->getNonLexicalBlockFileScope();
1312 return const_cast<DILocalScope *>(this);
1313}
1314
1316 DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx,
1318 SmallVector<DIScope *> ScopeChain;
1319 DIScope *CachedResult = nullptr;
1320
1321 for (DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope);
1322 Scope = Scope->getScope()) {
1323 if (auto It = Cache.find(Scope); It != Cache.end()) {
1324 CachedResult = cast<DIScope>(It->second);
1325 break;
1326 }
1327 ScopeChain.push_back(Scope);
1328 }
1329
1330 // Recreate the scope chain, bottom-up, starting at the new subprogram (or a
1331 // cached result).
1332 DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;
1333 for (DIScope *ScopeToUpdate : reverse(ScopeChain)) {
1334 UpdatedScope = cloneAndReplaceParentScope(
1335 cast<DILexicalBlockBase>(ScopeToUpdate), UpdatedScope);
1336 Cache[ScopeToUpdate] = UpdatedScope;
1337 }
1338
1339 return cast<DILocalScope>(UpdatedScope);
1340}
1341
1343 return StringSwitch<DISPFlags>(Flag)
1344#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
1345#include "llvm/IR/DebugInfoFlags.def"
1346 .Default(SPFlagZero);
1347}
1348
1350 switch (Flag) {
1351 // Appease a warning.
1352 case SPFlagVirtuality:
1353 return "";
1354#define HANDLE_DISP_FLAG(ID, NAME) \
1355 case SPFlag##NAME: \
1356 return "DISPFlag" #NAME;
1357#include "llvm/IR/DebugInfoFlags.def"
1358 }
1359 return "";
1360}
1361
1364 SmallVectorImpl<DISPFlags> &SplitFlags) {
1365 // Multi-bit fields can require special handling. In our case, however, the
1366 // only multi-bit field is virtuality, and all its values happen to be
1367 // single-bit values, so the right behavior just falls out.
1368#define HANDLE_DISP_FLAG(ID, NAME) \
1369 if (DISPFlags Bit = Flags & SPFlag##NAME) { \
1370 SplitFlags.push_back(Bit); \
1371 Flags &= ~Bit; \
1372 }
1373#include "llvm/IR/DebugInfoFlags.def"
1374 return Flags;
1375}
1376
1377DISubprogram *DISubprogram::getImpl(
1378 LLVMContext &Context, Metadata *Scope, MDString *Name,
1379 MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
1380 unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
1381 int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
1382 Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
1383 Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
1384 bool UsesKeyInstructions, StorageType Storage, bool ShouldCreate) {
1385 assert(isCanonical(Name) && "Expected canonical MDString");
1386 assert(isCanonical(LinkageName) && "Expected canonical MDString");
1387 assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
1389 (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
1390 ContainingType, VirtualIndex, ThisAdjustment, Flags,
1391 SPFlags, Unit, TemplateParams, Declaration,
1399 if (!TargetFuncName) {
1400 Ops.pop_back();
1401 if (!Annotations) {
1402 Ops.pop_back();
1403 if (!ThrownTypes) {
1404 Ops.pop_back();
1405 if (!TemplateParams) {
1406 Ops.pop_back();
1407 if (!ContainingType)
1408 Ops.pop_back();
1409 }
1410 }
1411 }
1412 }
1414 (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags,
1415 SPFlags, UsesKeyInstructions),
1416 Ops, Ops.size());
1417}
1418
1419bool DISubprogram::describes(const Function *F) const {
1420 assert(F && "Invalid function");
1421 return F->getSubprogram() == this;
1422}
1424 StorageType Storage,
1426 : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
1427
1428DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
1429 Metadata *File, unsigned Line,
1430 unsigned Column, StorageType Storage,
1431 bool ShouldCreate) {
1432 // Fixup column.
1433 adjustColumn(Column);
1434
1435 assert(Scope && "Expected scope");
1437 Metadata *Ops[] = {File, Scope};
1438 DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops);
1439}
1440
1441DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
1442 Metadata *Scope, Metadata *File,
1443 unsigned Discriminator,
1444 StorageType Storage,
1445 bool ShouldCreate) {
1446 assert(Scope && "Expected scope");
1448 Metadata *Ops[] = {File, Scope};
1450}
1451
1452DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
1453 bool ExportSymbols, ArrayRef<Metadata *> Ops)
1454 : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {
1455 SubclassData1 = ExportSymbols;
1456}
1457DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
1458 MDString *Name, bool ExportSymbols,
1459 StorageType Storage, bool ShouldCreate) {
1460 assert(isCanonical(Name) && "Expected canonical MDString");
1462 // The nullptr is for DIScope's File operand. This should be refactored.
1463 Metadata *Ops[] = {nullptr, Scope, Name};
1465}
1466
1467DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
1468 unsigned LineNo, ArrayRef<Metadata *> Ops)
1469 : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
1470 Ops) {
1471 SubclassData32 = LineNo;
1472}
1473DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
1474 Metadata *Decl, MDString *Name,
1475 Metadata *File, unsigned LineNo,
1476 StorageType Storage, bool ShouldCreate) {
1477 assert(isCanonical(Name) && "Expected canonical MDString");
1479 // The nullptr is for DIScope's File operand. This should be refactored.
1480 Metadata *Ops[] = {Scope, Decl, Name, File};
1482}
1483
1484DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
1485 bool IsDecl, ArrayRef<Metadata *> Ops)
1486 : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {
1487 SubclassData1 = IsDecl;
1488 SubclassData32 = LineNo;
1489}
1490DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
1491 Metadata *Scope, MDString *Name,
1492 MDString *ConfigurationMacros,
1493 MDString *IncludePath, MDString *APINotesFile,
1494 unsigned LineNo, bool IsDecl, StorageType Storage,
1495 bool ShouldCreate) {
1496 assert(isCanonical(Name) && "Expected canonical MDString");
1498 IncludePath, APINotesFile, LineNo, IsDecl));
1501 DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
1502}
1503DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,
1504 StorageType Storage,
1505 bool IsDefault,
1507 : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
1508 dwarf::DW_TAG_template_type_parameter, IsDefault,
1509 Ops) {}
1510
1512DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,
1513 Metadata *Type, bool isDefault,
1514 StorageType Storage, bool ShouldCreate) {
1515 assert(isCanonical(Name) && "Expected canonical MDString");
1517 Metadata *Ops[] = {Name, Type};
1519}
1520
1521DITemplateValueParameter *DITemplateValueParameter::getImpl(
1522 LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,
1523 bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {
1524 assert(isCanonical(Name) && "Expected canonical MDString");
1526 (Tag, Name, Type, isDefault, Value));
1527 Metadata *Ops[] = {Name, Type, Value};
1529}
1530
1532DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1533 MDString *LinkageName, Metadata *File, unsigned Line,
1534 Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
1535 Metadata *StaticDataMemberDeclaration,
1536 Metadata *TemplateParams, uint32_t AlignInBits,
1537 Metadata *Annotations, StorageType Storage,
1538 bool ShouldCreate) {
1539 assert(isCanonical(Name) && "Expected canonical MDString");
1540 assert(isCanonical(LinkageName) && "Expected canonical MDString");
1543 (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
1545 Metadata *Ops[] = {Scope,
1546 Name,
1547 File,
1548 Type,
1549 Name,
1553 Annotations};
1555 (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
1556}
1557
1559DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1560 Metadata *File, unsigned Line, Metadata *Type,
1561 unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
1562 Metadata *Annotations, StorageType Storage,
1563 bool ShouldCreate) {
1564 // 64K ought to be enough for any frontend.
1565 assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");
1566
1567 assert(Scope && "Expected scope");
1568 assert(isCanonical(Name) && "Expected canonical MDString");
1570 Flags, AlignInBits, Annotations));
1571 Metadata *Ops[] = {Scope, Name, File, Type, Annotations};
1573}
1574
1576 signed Line, ArrayRef<Metadata *> Ops,
1577 uint32_t AlignInBits)
1578 : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {
1579 SubclassData32 = AlignInBits;
1580}
1581std::optional<uint64_t> DIVariable::getSizeInBits() const {
1582 // This is used by the Verifier so be mindful of broken types.
1583 const Metadata *RawType = getRawType();
1584 while (RawType) {
1585 // Try to get the size directly.
1586 if (auto *T = dyn_cast<DIType>(RawType))
1587 if (uint64_t Size = T->getSizeInBits())
1588 return Size;
1589
1590 if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
1591 // Look at the base type.
1592 RawType = DT->getRawBaseType();
1593 continue;
1594 }
1595
1596 // Missing type or size.
1597 break;
1598 }
1599
1600 // Fail gracefully.
1601 return std::nullopt;
1602}
1603
1604DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
1605 unsigned Column, bool IsArtificial,
1606 std::optional<unsigned> CoroSuspendIdx,
1608 : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {
1609 this->SubclassData32 = Line;
1610 this->Column = Column;
1611 this->IsArtificial = IsArtificial;
1612 this->CoroSuspendIdx = CoroSuspendIdx;
1613}
1614DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
1615 Metadata *File, unsigned Line, unsigned Column,
1616 bool IsArtificial,
1617 std::optional<unsigned> CoroSuspendIdx,
1618 StorageType Storage, bool ShouldCreate) {
1619 assert(Scope && "Expected scope");
1620 assert(isCanonical(Name) && "Expected canonical MDString");
1622 DILabel, (Scope, Name, File, Line, Column, IsArtificial, CoroSuspendIdx));
1623 Metadata *Ops[] = {Scope, Name, File};
1624 DEFINE_GETIMPL_STORE(DILabel, (Line, Column, IsArtificial, CoroSuspendIdx),
1625 Ops);
1626}
1627
1628DIExpression *DIExpression::getImpl(LLVMContext &Context,
1629 ArrayRef<uint64_t> Elements,
1630 StorageType Storage, bool ShouldCreate) {
1633}
1635 if (auto singleLocElts = getSingleLocationExpressionElements()) {
1636 return singleLocElts->size() > 0 &&
1637 (*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value;
1638 }
1639 return false;
1640}
1642 if (auto singleLocElts = getSingleLocationExpressionElements())
1643 return singleLocElts->size() > 0 &&
1644 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1645 return false;
1646}
1648 if (auto singleLocElts = getSingleLocationExpressionElements())
1649 return singleLocElts->size() == 1 &&
1650 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1651 return false;
1652}
1653
1654DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage,
1655 bool ShouldCreate) {
1656 // Uniqued DIAssignID are not supported as the instance address *is* the ID.
1657 assert(Storage != StorageType::Uniqued && "uniqued DIAssignID unsupported");
1658 return storeImpl(new (0u, Storage) DIAssignID(Context, Storage), Storage);
1659}
1660
1662 uint64_t Op = getOp();
1663
1664 if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)
1665 return 2;
1666
1667 switch (Op) {
1672 case dwarf::DW_OP_bregx:
1673 return 3;
1674 case dwarf::DW_OP_constu:
1675 case dwarf::DW_OP_consts:
1676 case dwarf::DW_OP_deref_size:
1677 case dwarf::DW_OP_plus_uconst:
1681 case dwarf::DW_OP_regx:
1682 return 2;
1683 default:
1684 return 1;
1685 }
1686}
1687
1689 for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
1690 // Check that there's space for the operand.
1691 if (I->get() + I->getSize() > E->get())
1692 return false;
1693
1694 uint64_t Op = I->getOp();
1695 if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
1696 (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))
1697 return true;
1698
1699 // Check that the operand is valid.
1700 switch (Op) {
1701 default:
1702 return false;
1704 // A fragment operator must appear at the end.
1705 return I->get() + I->getSize() == E->get();
1706 case dwarf::DW_OP_stack_value: {
1707 // Must be the last one or followed by a DW_OP_LLVM_fragment.
1708 if (I->get() + I->getSize() == E->get())
1709 break;
1710 auto J = I;
1711 if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
1712 return false;
1713 break;
1714 }
1715 case dwarf::DW_OP_swap: {
1716 // Must be more than one implicit element on the stack.
1717
1718 // FIXME: A better way to implement this would be to add a local variable
1719 // that keeps track of the stack depth and introduce something like a
1720 // DW_LLVM_OP_implicit_location as a placeholder for the location this
1721 // DIExpression is attached to, or else pass the number of implicit stack
1722 // elements into isValid.
1723 if (getNumElements() == 1)
1724 return false;
1725 break;
1726 }
1728 // An entry value operator must appear at the beginning or immediately
1729 // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
1730 // currently only be 1, because we support only entry values of a simple
1731 // register location. One reason for this is that we currently can't
1732 // calculate the size of the resulting DWARF block for other expressions.
1733 auto FirstOp = expr_op_begin();
1734 if (FirstOp->getOp() == dwarf::DW_OP_LLVM_arg && FirstOp->getArg(0) == 0)
1735 ++FirstOp;
1736 return I->get() == FirstOp->get() && I->getArg(0) == 1;
1737 }
1744 case dwarf::DW_OP_constu:
1745 case dwarf::DW_OP_plus_uconst:
1746 case dwarf::DW_OP_plus:
1747 case dwarf::DW_OP_minus:
1748 case dwarf::DW_OP_mul:
1749 case dwarf::DW_OP_div:
1750 case dwarf::DW_OP_mod:
1751 case dwarf::DW_OP_or:
1752 case dwarf::DW_OP_and:
1753 case dwarf::DW_OP_xor:
1754 case dwarf::DW_OP_shl:
1755 case dwarf::DW_OP_shr:
1756 case dwarf::DW_OP_shra:
1757 case dwarf::DW_OP_deref:
1758 case dwarf::DW_OP_deref_size:
1759 case dwarf::DW_OP_xderef:
1760 case dwarf::DW_OP_lit0:
1761 case dwarf::DW_OP_not:
1762 case dwarf::DW_OP_dup:
1763 case dwarf::DW_OP_regx:
1764 case dwarf::DW_OP_bregx:
1765 case dwarf::DW_OP_push_object_address:
1766 case dwarf::DW_OP_over:
1767 case dwarf::DW_OP_consts:
1768 case dwarf::DW_OP_eq:
1769 case dwarf::DW_OP_ne:
1770 case dwarf::DW_OP_gt:
1771 case dwarf::DW_OP_ge:
1772 case dwarf::DW_OP_lt:
1773 case dwarf::DW_OP_le:
1774 break;
1775 }
1776 }
1777 return true;
1778}
1779
1781 if (!isValid())
1782 return false;
1783
1784 if (getNumElements() == 0)
1785 return false;
1786
1787 for (const auto &It : expr_ops()) {
1788 switch (It.getOp()) {
1789 default:
1790 break;
1791 case dwarf::DW_OP_stack_value:
1792 return true;
1793 }
1794 }
1795
1796 return false;
1797}
1798
1800 if (!isValid())
1801 return false;
1802
1803 if (getNumElements() == 0)
1804 return false;
1805
1806 // If there are any elements other than fragment or tag_offset, then some
1807 // kind of complex computation occurs.
1808 for (const auto &It : expr_ops()) {
1809 switch (It.getOp()) {
1813 continue;
1814 default:
1815 return true;
1816 }
1817 }
1818
1819 return false;
1820}
1821
1823 if (!isValid())
1824 return false;
1825
1826 if (getNumElements() == 0)
1827 return true;
1828
1829 auto ExprOpBegin = expr_ops().begin();
1830 auto ExprOpEnd = expr_ops().end();
1831 if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg) {
1832 if (ExprOpBegin->getArg(0) != 0)
1833 return false;
1834 ++ExprOpBegin;
1835 }
1836
1837 return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) {
1838 return Op.getOp() == dwarf::DW_OP_LLVM_arg;
1839 });
1840}
1841
1842std::optional<ArrayRef<uint64_t>>
1844 // Check for `isValid` covered by `isSingleLocationExpression`.
1846 return std::nullopt;
1847
1848 // An empty expression is already non-variadic.
1849 if (!getNumElements())
1850 return ArrayRef<uint64_t>();
1851
1852 // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do
1853 // anything.
1855 return getElements().drop_front(2);
1856 return getElements();
1857}
1858
1859const DIExpression *
1861 SmallVector<uint64_t, 3> UndefOps;
1862 if (auto FragmentInfo = Expr->getFragmentInfo()) {
1865 }
1866 return DIExpression::get(Expr->getContext(), UndefOps);
1867}
1868
1869const DIExpression *
1871 if (any_of(Expr->expr_ops(), [](auto ExprOp) {
1872 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
1873 }))
1874 return Expr;
1875 SmallVector<uint64_t> NewOps;
1876 NewOps.reserve(Expr->getNumElements() + 2);
1877 NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
1878 NewOps.append(Expr->elements_begin(), Expr->elements_end());
1879 return DIExpression::get(Expr->getContext(), NewOps);
1880}
1881
1882std::optional<const DIExpression *>
1884 if (!Expr)
1885 return std::nullopt;
1886
1887 if (auto Elts = Expr->getSingleLocationExpressionElements())
1888 return DIExpression::get(Expr->getContext(), *Elts);
1889
1890 return std::nullopt;
1891}
1892
1894 const DIExpression *Expr,
1895 bool IsIndirect) {
1896 // If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0`
1897 // to the existing expression ops.
1898 if (none_of(Expr->expr_ops(), [](auto ExprOp) {
1899 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
1900 }))
1901 Ops.append({dwarf::DW_OP_LLVM_arg, 0});
1902 // If Expr is not indirect, we only need to insert the expression elements and
1903 // we're done.
1904 if (!IsIndirect) {
1905 Ops.append(Expr->elements_begin(), Expr->elements_end());
1906 return;
1907 }
1908 // If Expr is indirect, insert the implied DW_OP_deref at the end of the
1909 // expression but before DW_OP_{stack_value, LLVM_fragment} if they are
1910 // present.
1911 for (auto Op : Expr->expr_ops()) {
1912 if (Op.getOp() == dwarf::DW_OP_stack_value ||
1913 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
1914 Ops.push_back(dwarf::DW_OP_deref);
1915 IsIndirect = false;
1916 }
1917 Op.appendToVector(Ops);
1918 }
1919 if (IsIndirect)
1920 Ops.push_back(dwarf::DW_OP_deref);
1921}
1922
1924 bool FirstIndirect,
1925 const DIExpression *SecondExpr,
1926 bool SecondIndirect) {
1927 SmallVector<uint64_t> FirstOps;
1928 DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect);
1929 SmallVector<uint64_t> SecondOps;
1930 DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr,
1931 SecondIndirect);
1932 return FirstOps == SecondOps;
1933}
1934
1935std::optional<DIExpression::FragmentInfo>
1937 for (auto I = Start; I != End; ++I)
1938 if (I->getOp() == dwarf::DW_OP_LLVM_fragment) {
1939 DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)};
1940 return Info;
1941 }
1942 return std::nullopt;
1943}
1944
1945std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) {
1946 std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();
1947 std::optional<uint64_t> ActiveBits = InitialActiveBits;
1948 for (auto Op : expr_ops()) {
1949 switch (Op.getOp()) {
1950 default:
1951 // We assume the worst case for anything we don't currently handle and
1952 // revert to the initial active bits.
1953 ActiveBits = InitialActiveBits;
1954 break;
1957 // We can't handle an extract whose sign doesn't match that of the
1958 // variable.
1959 std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness();
1960 bool VarSigned = (VarSign == DIBasicType::Signedness::Signed);
1961 bool OpSigned = (Op.getOp() == dwarf::DW_OP_LLVM_extract_bits_sext);
1962 if (!VarSign || VarSigned != OpSigned) {
1963 ActiveBits = InitialActiveBits;
1964 break;
1965 }
1966 [[fallthrough]];
1967 }
1969 // Extract or fragment narrows the active bits
1970 if (ActiveBits)
1971 ActiveBits = std::min(*ActiveBits, Op.getArg(1));
1972 else
1973 ActiveBits = Op.getArg(1);
1974 break;
1975 }
1976 }
1977 return ActiveBits;
1978}
1979
1981 int64_t Offset) {
1982 if (Offset > 0) {
1983 Ops.push_back(dwarf::DW_OP_plus_uconst);
1984 Ops.push_back(Offset);
1985 } else if (Offset < 0) {
1986 Ops.push_back(dwarf::DW_OP_constu);
1987 // Avoid UB when encountering LLONG_MIN, because in 2's complement
1988 // abs(LLONG_MIN) is LLONG_MAX+1.
1989 uint64_t AbsMinusOne = -(Offset+1);
1990 Ops.push_back(AbsMinusOne + 1);
1991 Ops.push_back(dwarf::DW_OP_minus);
1992 }
1993}
1994
1996 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
1997 if (!SingleLocEltsOpt)
1998 return false;
1999 auto SingleLocElts = *SingleLocEltsOpt;
2000
2001 if (SingleLocElts.size() == 0) {
2002 Offset = 0;
2003 return true;
2004 }
2005
2006 if (SingleLocElts.size() == 2 &&
2007 SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
2008 Offset = SingleLocElts[1];
2009 return true;
2010 }
2011
2012 if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
2013 if (SingleLocElts[2] == dwarf::DW_OP_plus) {
2014 Offset = SingleLocElts[1];
2015 return true;
2016 }
2017 if (SingleLocElts[2] == dwarf::DW_OP_minus) {
2018 Offset = -SingleLocElts[1];
2019 return true;
2020 }
2021 }
2022
2023 return false;
2024}
2025
2027 int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const {
2028 OffsetInBytes = 0;
2029 RemainingOps.clear();
2030
2031 auto SingleLocEltsOpt = getSingleLocationExpressionElements();
2032 if (!SingleLocEltsOpt)
2033 return false;
2034
2035 auto ExprOpEnd = expr_op_iterator(SingleLocEltsOpt->end());
2036 auto ExprOpIt = expr_op_iterator(SingleLocEltsOpt->begin());
2037 while (ExprOpIt != ExprOpEnd) {
2038 uint64_t Op = ExprOpIt->getOp();
2039 if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||
2040 Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment ||
2043 break;
2044 } else if (Op == dwarf::DW_OP_plus_uconst) {
2045 OffsetInBytes += ExprOpIt->getArg(0);
2046 } else if (Op == dwarf::DW_OP_constu) {
2047 uint64_t Value = ExprOpIt->getArg(0);
2048 ++ExprOpIt;
2049 if (ExprOpIt->getOp() == dwarf::DW_OP_plus)
2050 OffsetInBytes += Value;
2051 else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)
2052 OffsetInBytes -= Value;
2053 else
2054 return false;
2055 } else {
2056 // Not a const plus/minus operation or deref.
2057 return false;
2058 }
2059 ++ExprOpIt;
2060 }
2061 RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());
2062 return true;
2063}
2064
2067 for (auto ExprOp : expr_ops())
2068 if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)
2069 SeenOps.insert(ExprOp.getArg(0));
2070 for (uint64_t Idx = 0; Idx < N; ++Idx)
2071 if (!SeenOps.contains(Idx))
2072 return false;
2073 return true;
2074}
2075
2077 unsigned &AddrClass) {
2078 // FIXME: This seems fragile. Nothing that verifies that these elements
2079 // actually map to ops and not operands.
2080 auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements();
2081 if (!SingleLocEltsOpt)
2082 return nullptr;
2083 auto SingleLocElts = *SingleLocEltsOpt;
2084
2085 const unsigned PatternSize = 4;
2086 if (SingleLocElts.size() >= PatternSize &&
2087 SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu &&
2088 SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap &&
2089 SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) {
2090 AddrClass = SingleLocElts[PatternSize - 3];
2091
2092 if (SingleLocElts.size() == PatternSize)
2093 return nullptr;
2094 return DIExpression::get(
2095 Expr->getContext(),
2096 ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize));
2097 }
2098 return Expr;
2099}
2100
2102 int64_t Offset) {
2104 if (Flags & DIExpression::DerefBefore)
2105 Ops.push_back(dwarf::DW_OP_deref);
2106
2107 appendOffset(Ops, Offset);
2108 if (Flags & DIExpression::DerefAfter)
2109 Ops.push_back(dwarf::DW_OP_deref);
2110
2111 bool StackValue = Flags & DIExpression::StackValue;
2112 bool EntryValue = Flags & DIExpression::EntryValue;
2113
2114 return prependOpcodes(Expr, Ops, StackValue, EntryValue);
2115}
2116
2119 unsigned ArgNo, bool StackValue) {
2120 assert(Expr && "Can't add ops to this expression");
2121
2122 // Handle non-variadic intrinsics by prepending the opcodes.
2123 if (!any_of(Expr->expr_ops(),
2124 [](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) {
2125 assert(ArgNo == 0 &&
2126 "Location Index must be 0 for a non-variadic expression.");
2127 SmallVector<uint64_t, 8> NewOps(Ops);
2128 return DIExpression::prependOpcodes(Expr, NewOps, StackValue);
2129 }
2130
2132 for (auto Op : Expr->expr_ops()) {
2133 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2134 if (StackValue) {
2135 if (Op.getOp() == dwarf::DW_OP_stack_value)
2136 StackValue = false;
2137 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2138 NewOps.push_back(dwarf::DW_OP_stack_value);
2139 StackValue = false;
2140 }
2141 }
2142 Op.appendToVector(NewOps);
2143 if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo)
2144 llvm::append_range(NewOps, Ops);
2145 }
2146 if (StackValue)
2147 NewOps.push_back(dwarf::DW_OP_stack_value);
2148
2149 return DIExpression::get(Expr->getContext(), NewOps);
2150}
2151
2153 uint64_t OldArg, uint64_t NewArg) {
2154 assert(Expr && "Can't replace args in this expression");
2155
2157
2158 for (auto Op : Expr->expr_ops()) {
2159 if (Op.getOp() != dwarf::DW_OP_LLVM_arg || Op.getArg(0) < OldArg) {
2160 Op.appendToVector(NewOps);
2161 continue;
2162 }
2164 uint64_t Arg = Op.getArg(0) == OldArg ? NewArg : Op.getArg(0);
2165 // OldArg has been deleted from the Op list, so decrement all indices
2166 // greater than it.
2167 if (Arg > OldArg)
2168 --Arg;
2169 NewOps.push_back(Arg);
2170 }
2171 return DIExpression::get(Expr->getContext(), NewOps);
2172}
2173
2176 bool StackValue, bool EntryValue) {
2177 assert(Expr && "Can't prepend ops to this expression");
2178
2179 if (EntryValue) {
2181 // Use a block size of 1 for the target register operand. The
2182 // DWARF backend currently cannot emit entry values with a block
2183 // size > 1.
2184 Ops.push_back(1);
2185 }
2186
2187 // If there are no ops to prepend, do not even add the DW_OP_stack_value.
2188 if (Ops.empty())
2189 StackValue = false;
2190 for (auto Op : Expr->expr_ops()) {
2191 // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
2192 if (StackValue) {
2193 if (Op.getOp() == dwarf::DW_OP_stack_value)
2194 StackValue = false;
2195 else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2196 Ops.push_back(dwarf::DW_OP_stack_value);
2197 StackValue = false;
2198 }
2199 }
2200 Op.appendToVector(Ops);
2201 }
2202 if (StackValue)
2203 Ops.push_back(dwarf::DW_OP_stack_value);
2204 return DIExpression::get(Expr->getContext(), Ops);
2205}
2206
2208 ArrayRef<uint64_t> Ops) {
2209 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2210
2211 // Copy Expr's current op list.
2213 for (auto Op : Expr->expr_ops()) {
2214 // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
2215 if (Op.getOp() == dwarf::DW_OP_stack_value ||
2216 Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
2217 NewOps.append(Ops.begin(), Ops.end());
2218
2219 // Ensure that the new opcodes are only appended once.
2220 Ops = {};
2221 }
2222 Op.appendToVector(NewOps);
2223 }
2224 NewOps.append(Ops.begin(), Ops.end());
2225 auto *result =
2226 DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath();
2227 assert(result->isValid() && "concatenated expression is not valid");
2228 return result;
2229}
2230
2232 ArrayRef<uint64_t> Ops) {
2233 assert(Expr && !Ops.empty() && "Can't append ops to this expression");
2234 assert(std::none_of(expr_op_iterator(Ops.begin()),
2235 expr_op_iterator(Ops.end()),
2236 [](auto Op) {
2237 return Op.getOp() == dwarf::DW_OP_stack_value ||
2238 Op.getOp() == dwarf::DW_OP_LLVM_fragment;
2239 }) &&
2240 "Can't append this op");
2241
2242 // Append a DW_OP_deref after Expr's current op list if it's non-empty and
2243 // has no DW_OP_stack_value.
2244 //
2245 // Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?.
2246 std::optional<FragmentInfo> FI = Expr->getFragmentInfo();
2247 unsigned DropUntilStackValue = FI ? 3 : 0;
2248 ArrayRef<uint64_t> ExprOpsBeforeFragment =
2249 Expr->getElements().drop_back(DropUntilStackValue);
2250 bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) &&
2251 (ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value);
2252 bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty();
2253
2254 // Append a DW_OP_deref after Expr's current op list if needed, then append
2255 // the new ops, and finally ensure that a single DW_OP_stack_value is present.
2257 if (NeedsDeref)
2258 NewOps.push_back(dwarf::DW_OP_deref);
2259 NewOps.append(Ops.begin(), Ops.end());
2260 if (NeedsStackValue)
2261 NewOps.push_back(dwarf::DW_OP_stack_value);
2262 return DIExpression::append(Expr, NewOps);
2263}
2264
2265std::optional<DIExpression *> DIExpression::createFragmentExpression(
2266 const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
2268 // Track whether it's safe to split the value at the top of the DWARF stack,
2269 // assuming that it'll be used as an implicit location value.
2270 bool CanSplitValue = true;
2271 // Track whether we need to add a fragment expression to the end of Expr.
2272 bool EmitFragment = true;
2273 // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
2274 if (Expr) {
2275 for (auto Op : Expr->expr_ops()) {
2276 switch (Op.getOp()) {
2277 default:
2278 break;
2279 case dwarf::DW_OP_shr:
2280 case dwarf::DW_OP_shra:
2281 case dwarf::DW_OP_shl:
2282 case dwarf::DW_OP_plus:
2283 case dwarf::DW_OP_plus_uconst:
2284 case dwarf::DW_OP_minus:
2285 // We can't safely split arithmetic or shift operations into multiple
2286 // fragments because we can't express carry-over between fragments.
2287 //
2288 // FIXME: We *could* preserve the lowest fragment of a constant offset
2289 // operation if the offset fits into SizeInBits.
2290 CanSplitValue = false;
2291 break;
2292 case dwarf::DW_OP_deref:
2293 case dwarf::DW_OP_deref_size:
2294 case dwarf::DW_OP_deref_type:
2295 case dwarf::DW_OP_xderef:
2296 case dwarf::DW_OP_xderef_size:
2297 case dwarf::DW_OP_xderef_type:
2298 // Preceeding arithmetic operations have been applied to compute an
2299 // address. It's okay to split the value loaded from that address.
2300 CanSplitValue = true;
2301 break;
2302 case dwarf::DW_OP_stack_value:
2303 // Bail if this expression computes a value that cannot be split.
2304 if (!CanSplitValue)
2305 return std::nullopt;
2306 break;
2308 // If we've decided we don't need a fragment then give up if we see that
2309 // there's already a fragment expression.
2310 // FIXME: We could probably do better here
2311 if (!EmitFragment)
2312 return std::nullopt;
2313 // Make the new offset point into the existing fragment.
2314 uint64_t FragmentOffsetInBits = Op.getArg(0);
2315 uint64_t FragmentSizeInBits = Op.getArg(1);
2316 (void)FragmentSizeInBits;
2317 assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
2318 "new fragment outside of original fragment");
2319 OffsetInBits += FragmentOffsetInBits;
2320 continue;
2321 }
2324 // If we're extracting bits from inside of the fragment that we're
2325 // creating then we don't have a fragment after all, and just need to
2326 // adjust the offset that we're extracting from.
2327 uint64_t ExtractOffsetInBits = Op.getArg(0);
2328 uint64_t ExtractSizeInBits = Op.getArg(1);
2329 if (ExtractOffsetInBits >= OffsetInBits &&
2330 ExtractOffsetInBits + ExtractSizeInBits <=
2331 OffsetInBits + SizeInBits) {
2332 Ops.push_back(Op.getOp());
2333 Ops.push_back(ExtractOffsetInBits - OffsetInBits);
2334 Ops.push_back(ExtractSizeInBits);
2335 EmitFragment = false;
2336 continue;
2337 }
2338 // If the extracted bits aren't fully contained within the fragment then
2339 // give up.
2340 // FIXME: We could probably do better here
2341 return std::nullopt;
2342 }
2343 }
2344 Op.appendToVector(Ops);
2345 }
2346 }
2347 assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");
2348 assert(Expr && "Unknown DIExpression");
2349 if (EmitFragment) {
2351 Ops.push_back(OffsetInBits);
2352 Ops.push_back(SizeInBits);
2353 }
2354 return DIExpression::get(Expr->getContext(), Ops);
2355}
2356
2357/// See declaration for more info.
2359 const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits,
2360 uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,
2361 int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag,
2362 std::optional<DIExpression::FragmentInfo> &Result,
2363 int64_t &OffsetFromLocationInBits) {
2364
2365 if (VarFrag.SizeInBits == 0)
2366 return false; // Variable size is unknown.
2367
2368 // Difference between mem slice start and the dbg location start.
2369 // 0 4 8 12 16 ...
2370 // | |
2371 // dbg location start
2372 // |
2373 // mem slice start
2374 // Here MemStartRelToDbgStartInBits is 8. Note this can be negative.
2375 int64_t MemStartRelToDbgStartInBits;
2376 {
2377 auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL);
2378 if (!MemOffsetFromDbgInBytes)
2379 return false; // Can't calculate difference in addresses.
2380 // Difference between the pointers.
2381 MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;
2382 // Add the difference of the offsets.
2383 MemStartRelToDbgStartInBits +=
2384 SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);
2385 }
2386
2387 // Out-param. Invert offset to get offset from debug location.
2388 OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;
2389
2390 // Check if the variable fragment sits outside (before) this memory slice.
2391 int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;
2392 if (MemEndRelToDbgStart < 0) {
2393 Result = {0, 0}; // Out-param.
2394 return true;
2395 }
2396
2397 // Work towards creating SliceOfVariable which is the bits of the variable
2398 // that the memory region covers.
2399 // 0 4 8 12 16 ...
2400 // | |
2401 // dbg location start with VarFrag offset=32
2402 // |
2403 // mem slice start: SliceOfVariable offset=40
2404 int64_t MemStartRelToVarInBits =
2405 MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;
2406 int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;
2407 // If the memory region starts before the debug location the fragment
2408 // offset would be negative, which we can't encode. Limit those to 0. This
2409 // is fine because those bits necessarily don't overlap with the existing
2410 // variable fragment.
2411 int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);
2412 int64_t MemFragSize =
2413 std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);
2414 DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart);
2415
2416 // Intersect the memory region fragment with the variable location fragment.
2417 DIExpression::FragmentInfo TrimmedSliceOfVariable =
2418 DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);
2419 if (TrimmedSliceOfVariable == VarFrag)
2420 Result = std::nullopt; // Out-param.
2421 else
2422 Result = TrimmedSliceOfVariable; // Out-param.
2423 return true;
2424}
2425
2426std::pair<DIExpression *, const ConstantInt *>
2428 // Copy the APInt so we can modify it.
2429 APInt NewInt = CI->getValue();
2431
2432 // Fold operators only at the beginning of the expression.
2433 bool First = true;
2434 bool Changed = false;
2435 for (auto Op : expr_ops()) {
2436 switch (Op.getOp()) {
2437 default:
2438 // We fold only the leading part of the expression; if we get to a part
2439 // that we're going to copy unchanged, and haven't done any folding,
2440 // then the entire expression is unchanged and we can return early.
2441 if (!Changed)
2442 return {this, CI};
2443 First = false;
2444 break;
2446 if (!First)
2447 break;
2448 Changed = true;
2449 if (Op.getArg(1) == dwarf::DW_ATE_signed)
2450 NewInt = NewInt.sextOrTrunc(Op.getArg(0));
2451 else {
2452 assert(Op.getArg(1) == dwarf::DW_ATE_unsigned && "Unexpected operand");
2453 NewInt = NewInt.zextOrTrunc(Op.getArg(0));
2454 }
2455 continue;
2456 }
2457 Op.appendToVector(Ops);
2458 }
2459 if (!Changed)
2460 return {this, CI};
2461 return {DIExpression::get(getContext(), Ops),
2462 ConstantInt::get(getContext(), NewInt)};
2463}
2464
2466 uint64_t Result = 0;
2467 for (auto ExprOp : expr_ops())
2468 if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)
2469 Result = std::max(Result, ExprOp.getArg(0) + 1);
2470 assert(hasAllLocationOps(Result) &&
2471 "Expression is missing one or more location operands.");
2472 return Result;
2473}
2474
2475std::optional<DIExpression::SignedOrUnsignedConstant>
2477
2478 // Recognize signed and unsigned constants.
2479 // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value
2480 // (DW_OP_LLVM_fragment of Len).
2481 // An unsigned constant can be represented as
2482 // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len).
2483
2484 if ((getNumElements() != 2 && getNumElements() != 3 &&
2485 getNumElements() != 6) ||
2486 (getElement(0) != dwarf::DW_OP_consts &&
2487 getElement(0) != dwarf::DW_OP_constu))
2488 return std::nullopt;
2489
2490 if (getNumElements() == 2 && getElement(0) == dwarf::DW_OP_consts)
2492
2493 if ((getNumElements() == 3 && getElement(2) != dwarf::DW_OP_stack_value) ||
2494 (getNumElements() == 6 && (getElement(2) != dwarf::DW_OP_stack_value ||
2496 return std::nullopt;
2497 return getElement(0) == dwarf::DW_OP_constu
2500}
2501
2502DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
2503 bool Signed) {
2504 dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
2506 dwarf::DW_OP_LLVM_convert, ToSize, TK}};
2507 return Ops;
2508}
2509
2511 unsigned FromSize, unsigned ToSize,
2512 bool Signed) {
2513 return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
2514}
2515
2517DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
2519 bool ShouldCreate) {
2521 Metadata *Ops[] = {Variable, Expression};
2523}
2524DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
2525 unsigned Line, unsigned Attributes,
2527 : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
2529
2530DIObjCProperty *DIObjCProperty::getImpl(
2531 LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
2532 MDString *GetterName, MDString *SetterName, unsigned Attributes,
2533 Metadata *Type, StorageType Storage, bool ShouldCreate) {
2534 assert(isCanonical(Name) && "Expected canonical MDString");
2535 assert(isCanonical(GetterName) && "Expected canonical MDString");
2536 assert(isCanonical(SetterName) && "Expected canonical MDString");
2538 SetterName, Attributes, Type));
2539 Metadata *Ops[] = {Name, File, GetterName, SetterName, Type};
2540 DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
2541}
2542
2543DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
2544 Metadata *Scope, Metadata *Entity,
2545 Metadata *File, unsigned Line,
2546 MDString *Name, Metadata *Elements,
2547 StorageType Storage,
2548 bool ShouldCreate) {
2549 assert(isCanonical(Name) && "Expected canonical MDString");
2551 (Tag, Scope, Entity, File, Line, Name, Elements));
2552 Metadata *Ops[] = {Scope, Entity, Name, File, Elements};
2554}
2555
2556DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
2557 MDString *Name, MDString *Value, StorageType Storage,
2558 bool ShouldCreate) {
2559 assert(isCanonical(Name) && "Expected canonical MDString");
2561 Metadata *Ops[] = {Name, Value};
2563}
2564
2565DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
2566 unsigned Line, Metadata *File,
2567 Metadata *Elements, StorageType Storage,
2568 bool ShouldCreate) {
2570 Metadata *Ops[] = {File, Elements};
2572}
2573
2576 auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));
2577 if (ExistingIt != Context.pImpl->DIArgLists.end())
2578 return *ExistingIt;
2579 DIArgList *NewArgList = new DIArgList(Context, Args);
2580 Context.pImpl->DIArgLists.insert(NewArgList);
2581 return NewArgList;
2582}
2583
2585 ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);
2586 assert((!New || isa<ValueAsMetadata>(New)) &&
2587 "DIArgList must be passed a ValueAsMetadata");
2588 untrack();
2589 // We need to update the set storage once the Args are updated since they
2590 // form the key to the DIArgLists store.
2591 getContext().pImpl->DIArgLists.erase(this);
2592 ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New);
2593 for (ValueAsMetadata *&VM : Args) {
2594 if (&VM == OldVMPtr) {
2595 if (NewVM)
2596 VM = NewVM;
2597 else
2598 VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));
2599 }
2600 }
2601 // We've changed the contents of this DIArgList, and the set storage may
2602 // already contain a DIArgList with our new set of args; if it does, then we
2603 // must RAUW this with the existing DIArgList, otherwise we simply insert this
2604 // back into the set storage.
2605 DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);
2606 if (ExistingArgList) {
2607 replaceAllUsesWith(ExistingArgList);
2608 // Clear this here so we don't try to untrack in the destructor.
2609 Args.clear();
2610 delete this;
2611 return;
2612 }
2613 getContext().pImpl->DIArgLists.insert(this);
2614 track();
2615}
2616void DIArgList::track() {
2617 for (ValueAsMetadata *&VAM : Args)
2618 if (VAM)
2619 MetadataTracking::track(&VAM, *VAM, *this);
2620}
2621void DIArgList::untrack() {
2622 for (ValueAsMetadata *&VAM : Args)
2623 if (VAM)
2624 MetadataTracking::untrack(&VAM, *VAM);
2625}
2626void DIArgList::dropAllReferences(bool Untrack) {
2627 if (Untrack)
2628 untrack();
2629 Args.clear();
2630 ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false);
2631}
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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_ABI
Definition: Compiler.h:213
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)
Definition: DIBuilder.cpp:971
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static 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 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)
Definition: Discriminator.h:49
static unsigned encodeComponent(unsigned C)
Definition: Discriminator.h:45
static unsigned getNextComponentInDiscriminator(unsigned D)
Returns the next component stored in discriminator.
Definition: Discriminator.h:38
static unsigned getUnsignedFromPrefixEncoding(unsigned U)
Reverse transformation as getPrefixEncodingFromUnsigned.
Definition: Discriminator.h:30
This file contains constants used for implementing Dwarf debug support.
std::string Name
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, given a range of instructions.
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...
support::ulittle16_t & Lo
Definition: aarch32.cpp:205
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:1033
LLVM_ABI APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition: APInt.cpp:1041
Annotations lets you mark points and ranges inside source code, for tests:
Definition: Annotations.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:156
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:200
iterator end() const
Definition: ArrayRef.h:136
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
Definition: ArrayRef.h:206
iterator begin() const
Definition: ArrayRef.h:135
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:142
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Definition: Constants.h:131
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:154
This is an important base class in LLVM.
Definition: Constant.h:43
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
LLVM_ABI void handleChangedOperand(void *Ref, Metadata *New)
static LLVM_ABI DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)
Assignment ID.
Basic type, like 'int' or 'float'.
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags
static DIBasicType * getImpl(LLVMContext &Context, unsigned Tag, StringRef Name, uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding, uint32_t NumExtraInhabitants, DIFlags Flags, StorageType Storage, bool ShouldCreate=true)
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
unsigned StringRef Name
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t AlignInBits
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)
DebugEmissionKind getEmissionKind() const
unsigned Metadata * File
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata * Macros
unsigned Metadata MDString bool MDString * Flags
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata * EnumTypes
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata * RetainedTypes
DebugNameTableKind getNameTableKind() const
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata * GlobalVariables
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString MDString * SDK
unsigned Metadata MDString * Producer
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata Metadata uint64_t bool bool unsigned bool MDString * SysRoot
unsigned Metadata MDString bool MDString unsigned MDString * SplitDebugFilename
unsigned Metadata MDString bool MDString unsigned MDString unsigned Metadata Metadata Metadata Metadata * ImportedEntities
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t AlignInBits
unsigned MDString Metadata unsigned 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 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 * BaseType
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata * OffsetInBits
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata std::optional< unsigned > std::optional< PtrAuthData > DIFlags Flags
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t AlignInBits
Metadata * getExtraData() const
Get extra data associated with this derived type.
unsigned StringRef DIFile * File
unsigned StringRef DIFile unsigned DIScope * Scope
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
unsigned StringRef DIFile unsigned DIScope DIType Metadata uint32_t Metadata std::optional< unsigned > std::optional< PtrAuthData > DIFlags Metadata * ExtraData
unsigned StringRef DIFile unsigned Line
Enumeration value.
int64_t bool MDString * Name
LLVM_ABI unsigned getSize() const
Return the size of the operand.
uint64_t getOp() const
Get the operand code.
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.
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 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 bool extractLeadingOffset(int64_t &OffsetInBytes, SmallVectorImpl< uint64_t > &RemainingOps) const
Assuming that the expression operates on an address, extract a constant offset and the successive ops...
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 <DWARF Address Space> DW_OP_swap DW_...
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 * Filename
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 uint64_t uint32_t unsigned Encoding
unsigned StringRef Name
unsigned StringRef uint64_t uint32_t AlignInBits
LLVM_ABI bool isSigned() const
@ FixedPointBinary
Scale factor 2^Factor.
@ FixedPointDecimal
Scale factor 10^Factor.
@ FixedPointRational
Arbitrary rational scale factor.
unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags
unsigned StringRef uint64_t SizeInBits
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 * 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 Line
Metadata MDString * Name
Metadata MDString Metadata * File
LLVM_ABI DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef< Metadata * > Ops)
Metadata Metadata unsigned Discriminator
Metadata Metadata * File
Debug lexical block.
Metadata Metadata unsigned Line
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.
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 AlignInBits
Debug location.
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 * 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.
static LLVM_ABI StringRef getFlagString(DIFlags Flag)
DIFlags
Debug info flags.
MDString Metadata * File
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
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 * StringLength
Subprogram description. Uses SubclassData1.
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata * Unit
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata MDString bool UsesKeyInstructions
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata * Annotations
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata * ContainingType
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata * TemplateParams
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata * Declaration
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata Metadata MDString * TargetFuncName
static LLVM_ABI DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)
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
static LLVM_ABI DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)
Split up a flags bitfield for easier printing.
Metadata MDString MDString * LinkageName
static LLVM_ABI StringRef getFlagString(DISPFlags Flag)
Metadata MDString MDString Metadata unsigned Metadata * Type
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata * RetainedNodes
DISPFlags
Debug info subprogram flags.
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 * BaseType
PointerUnion< ConstantInt *, DIVariable *, DIExpression * > BoundType
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
StringRef DIFile unsigned DIScope * Scope
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
Base class for types.
bool isBitField() const
bool isStaticMember() const
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)
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LLVM_ABI DebugVariable(const DbgVariableRecord *DVR)
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:245
iterator end()
Definition: DenseMap.h:87
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:1077
friend class DIAssignID
Definition: Metadata.h:1080
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1573
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
LLVM_ABI TempMDNode clone() const
Create a (temporary) clone of this.
Definition: Metadata.cpp:668
static T * storeImpl(T *N, StorageType Storage, StoreT &Store)
Definition: MetadataImpl.h:42
LLVMContext & getContext() const
Definition: Metadata.h:1241
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:1316
A single uniqued string.
Definition: Metadata.h:720
LLVM_ABI StringRef getString() const
Definition: Metadata.cpp:617
static void untrack(Metadata *&MD)
Stop tracking a reference to metadata.
Definition: Metadata.h:356
static bool track(Metadata *&MD)
Track the reference to metadata.
Definition: Metadata.h:322
Root of the metadata hierarchy.
Definition: Metadata.h:63
StorageType
Active type of storage.
Definition: Metadata.h:71
unsigned short SubclassData16
Definition: Metadata.h:77
unsigned SubclassData32
Definition: Metadata.h:78
unsigned char Storage
Storage flag for non-uniqued, otherwise unowned, metadata.
Definition: Metadata.h:74
unsigned char SubclassData1
Definition: Metadata.h:76
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Definition: PointerUnion.h:118
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1885
LLVM_ABI void replaceAllUsesWith(Metadata *MD)
Replace all uses of this with MD.
Definition: Metadata.cpp:368
LLVMContext & getContext() const
Definition: Metadata.h:407
LLVM_ABI void resolveAllUses(bool ResolveUsers=true)
Resolve all uses of this.
Definition: Metadata.cpp:421
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition: DenseSet.h:283
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void reserve(size_type N)
Definition: SmallVector.h:664
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:684
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
R Default(T Value)
Definition: StringSwitch.h:177
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Value wrapper in the Metadata hierarchy.
Definition: Metadata.h:457
static LLVM_ABI ValueAsMetadata * get(Value *V)
Definition: Metadata.cpp:502
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:1051
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:169
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
@ DW_OP_LLVM_entry_value
Only used in LLVM metadata.
Definition: Dwarf.h:146
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
Definition: Dwarf.h:147
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
Definition: Dwarf.h:150
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition: Dwarf.h:145
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Definition: Dwarf.h:143
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
Definition: Dwarf.h:148
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Definition: Dwarf.h:144
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
Definition: Dwarf.h:149
@ DW_VIRTUALITY_max
Definition: Dwarf.h:199
@ NameTableKind
Definition: LLToken.h:500
@ EmissionKind
Definition: LLToken.h:499
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
@ Offset
Definition: DWP.cpp:477
static T * getUniqued(DenseSet< T *, InfoT > &Store, const typename InfoT::KeyTy &Key)
Definition: MetadataImpl.h:22
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1751
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
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:1758
@ Ref
The access may reference the value stored in memory.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
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."))
@ Default
The result values are uniform if and only if all operands are uniform.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#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:249