1//===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===// 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 7//===----------------------------------------------------------------------===// 9// This file implements the debug info Metadata classes. 11//===----------------------------------------------------------------------===// 31// Use FS-AFDO discriminator. 34cl::desc(
"Enable adding flow sensitive discriminators"));
42 std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};
45 : Variable(DII->getVariable()),
46 Fragment(DII->getExpression()->getFragmentInfo()),
50 : Variable(DVR->getVariable()),
51 Fragment(DVR->getExpression()->getFragmentInfo()),
58DILocation::DILocation(
LLVMContext &
C, StorageType Storage,
unsigned Line,
61 :
MDNode(
C, DILocationKind, Storage, MDs) {
63"Expected a scope and optional inlined-at");
65// Set line and column. 66assert(Column < (1u << 16) &&
"Expected 16-bit column");
68 SubclassData32 = Line;
69 SubclassData16 = Column;
71 setImplicitCode(ImplicitCode);
75// Set to unknown on overflow. We only have 16 bits to play with here. 76if (Column >= (1u << 16))
82Metadata *InlinedAt,
bool ImplicitCode,
83 StorageType Storage,
bool ShouldCreate) {
95assert(ShouldCreate &&
"Expected non-uniqued nodes to always be created");
112auto *Merged = Locs[0];
137// Walk through LocA and its inlined-at locations, populate them in ALocs and 138// save the index for the subprogram and inlined-at pair, which we use to find 139// a matching starting location in LocB's chain. 140for (
auto [L,
I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(),
I++) {
144assert(Res.second &&
"Multiple <SP, InlinedAt> pairs in a location chain?");
148 LocVec::reverse_iterator ARIt = ALocs.rend();
149 LocVec::reverse_iterator BRIt = BLocs.rend();
151// Populate BLocs and look for a matching starting location, the first 152// location with the same subprogram and inlined-at location as in LocA's 153// chain. Since the two locations have the same inlined-at location we do 154// not need to look at those parts of the chains. 155for (
auto [L,
I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(),
I++) {
158if (ARIt != ALocs.rend())
159// We have already found a matching starting location. 162autoIT = ALookup.
find({L->getScope()->getSubprogram(), L->getInlinedAt()});
163if (
IT == ALookup.
end())
166// The + 1 is to account for the &*rev_it = &(it - 1) relationship. 167 ARIt = LocVec::reverse_iterator(ALocs.begin() +
IT->second + 1);
168 BRIt = LocVec::reverse_iterator(BLocs.begin() +
I + 1);
170// If we have found a matching starting location we do not need to add more 171// locations to BLocs, since we will only look at location pairs preceding 172// the matching starting location, and adding more elements to BLocs could 173// invalidate the iterator that we initialized here. 177// Merge the two locations if possible, using the supplied 178// inlined-at location for the created location. 185// If the locations originate from different subprograms we can't produce 187if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())
190// Return the nearest common scope inside a subprogram. 193for (;
S1;
S1 =
S1->getScope()) {
195if (isa<DISubprogram>(
S1))
199for (; S2; S2 = S2->getScope()) {
202if (isa<DISubprogram>(S2))
209autoScope = GetNearestCommonScope(L1->getScope(), L2->getScope());
210assert(
Scope &&
"No common scope in the same subprogram?");
212bool SameLine = L1->getLine() == L2->getLine();
213bool SameCol = L1->getColumn() == L2->getColumn();
214unsignedLine = SameLine ? L1->getLine() : 0;
215unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;
220DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() :
nullptr;
222// If we have found a common starting location, walk up the inlined-at chains 223// and try to produce common locations. 224for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {
225DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);
228// We have walked up to a point in the chains where the two locations 229// are irreconsilable. At this point Result contains the nearest common 230// location in the inlined-at chains of LocA and LocB, so we break here. 239// We ended up with LocA and LocB as irreconsilable locations. Produce a 240// location at 0:0 with one of the locations' scope. The function has 241// historically picked A's scope, and a nullptr inlined-at location, so that 242// behavior is mimicked here but I am not sure if this is always the correct 243// way to handle this. 247std::optional<unsigned>
249 std::array<unsigned, 3> Components = {BD,
DF, CI};
251// We use RemainingWork to figure out if we have no remaining components to 252// encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to 253// encode anything for the latter 2. 254// Since any of the input components is at most 32 bits, their sum will be 255// less than 34 bits, and thus RemainingWork won't overflow. 257 std::accumulate(Components.begin(), Components.end(), RemainingWork);
261unsigned NextBitInsertionIndex = 0;
262while (RemainingWork > 0) {
263unsignedC = Components[
I++];
266 Ret |= (EC << NextBitInsertionIndex);
270// Encoding may be unsuccessful because of overflow. We determine success by 271// checking equivalence of components before & after encoding. Alternatively, 272// we could determine Success during encoding, but the current alternative is 274unsigned TBD, TDF, TCI = 0;
276if (TBD == BD && TDF ==
DF && TCI == CI)
292#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
293#include "llvm/IR/DebugInfoFlags.def" 299#define HANDLE_DI_FLAG(ID, NAME) \ 301 return "DIFlag" #NAME;
302#include "llvm/IR/DebugInfoFlags.def" 309// Flags that are packed together need to be specially handled, so 310// that, for example, we emit "DIFlagPublic" and not 311// "DIFlagPrivate | DIFlagProtected". 315elseif (
A == FlagProtected)
322if (R == FlagSingleInheritance)
323 SplitFlags.
push_back(FlagSingleInheritance);
324elseif (R == FlagMultipleInheritance)
325 SplitFlags.
push_back(FlagMultipleInheritance);
327 SplitFlags.
push_back(FlagVirtualInheritance);
330if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
331 Flags &= ~FlagIndirectVirtualBase;
332 SplitFlags.
push_back(FlagIndirectVirtualBase);
335#define HANDLE_DI_FLAG(ID, NAME) \ 336 if (DIFlags Bit = Flags & Flag##NAME) { \ 337 SplitFlags.push_back(Bit); \ 340#include "llvm/IR/DebugInfoFlags.def" 345if (
auto *
T = dyn_cast<DIType>(
this))
348if (
auto *SP = dyn_cast<DISubprogram>(
this))
349return SP->getScope();
351if (
auto *LB = dyn_cast<DILexicalBlockBase>(
this))
352return LB->getScope();
354if (
auto *NS = dyn_cast<DINamespace>(
this))
355return NS->getScope();
357if (
auto *CB = dyn_cast<DICommonBlock>(
this))
358return CB->getScope();
360if (
auto *M = dyn_cast<DIModule>(
this))
363assert((isa<DIFile>(
this) || isa<DICompileUnit>(
this)) &&
364"Unhandled type of scope.");
369if (
auto *
T = dyn_cast<DIType>(
this))
371if (
auto *SP = dyn_cast<DISubprogram>(
this))
373if (
auto *NS = dyn_cast<DINamespace>(
this))
375if (
auto *CB = dyn_cast<DICommonBlock>(
this))
377if (
auto *M = dyn_cast<DIModule>(
this))
379assert((isa<DILexicalBlockBase>(
this) || isa<DIFile>(
this) ||
380 isa<DICompileUnit>(
this)) &&
381"Unhandled type of scope.");
395 StorageType Storage,
bool ShouldCreate) {
403 Hash = Key.getHash();
405assert(ShouldCreate &&
"Expected non-uniqued nodes to always be created");
408// Use a nullptr for empty headers. 416void GenericDINode::recalculateHash() {
417 setHash(GenericDINodeInfo::KeyTy::calculateHash(
this));
420#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__ 421#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS 422#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \ 424 if (Storage == Uniqued) { \ 425 if (auto *N = getUniqued(Context.pImpl->CLASS##s, \ 426 CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \ 431 assert(ShouldCreate && \ 432 "Expected non-uniqued nodes to always be created"); \
435#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \ 436 return storeImpl(new (std::size(OPS), Storage) \ 437 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \ 438 Storage, Context.pImpl->CLASS##s) 439#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \ 440 return storeImpl(new (0u, Storage) \ 441 CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \ 442 Storage, Context.pImpl->CLASS##s) 443#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \ 444 return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \ 445 Storage, Context.pImpl->CLASS##s) 446#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \ 447 return storeImpl(new (NUM_OPS, Storage) \ 448 CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \ 449 Storage, Context.pImpl->CLASS##s) 451DISubrange::DISubrange(
LLVMContext &
C, StorageType Storage,
453 :
DINode(
C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
455 StorageType Storage,
bool ShouldCreate) {
465 int64_t
Lo, StorageType Storage,
475 StorageType Storage,
bool ShouldCreate) {
486assert((isa<ConstantAsMetadata>(CB) || isa<DIVariable>(CB) ||
487 isa<DIExpression>(CB)) &&
488"Count must be signed constant or DIVariable or DIExpression");
490if (
auto *MD = dyn_cast<ConstantAsMetadata>(CB))
491return BoundType(cast<ConstantInt>(MD->getValue()));
493if (
auto *MD = dyn_cast<DIVariable>(CB))
496if (
auto *MD = dyn_cast<DIExpression>(CB))
507assert((isa<ConstantAsMetadata>(LB) || isa<DIVariable>(LB) ||
508 isa<DIExpression>(LB)) &&
509"LowerBound must be signed constant or DIVariable or DIExpression");
511if (
auto *MD = dyn_cast<ConstantAsMetadata>(LB))
512return BoundType(cast<ConstantInt>(MD->getValue()));
514if (
auto *MD = dyn_cast<DIVariable>(LB))
517if (
auto *MD = dyn_cast<DIExpression>(LB))
528assert((isa<ConstantAsMetadata>(UB) || isa<DIVariable>(UB) ||
529 isa<DIExpression>(UB)) &&
530"UpperBound must be signed constant or DIVariable or DIExpression");
532if (
auto *MD = dyn_cast<ConstantAsMetadata>(UB))
533return BoundType(cast<ConstantInt>(MD->getValue()));
535if (
auto *MD = dyn_cast<DIVariable>(UB))
538if (
auto *MD = dyn_cast<DIExpression>(UB))
549assert((isa<ConstantAsMetadata>(ST) || isa<DIVariable>(ST) ||
550 isa<DIExpression>(ST)) &&
551"Stride must be signed constant or DIVariable or DIExpression");
553if (
auto *MD = dyn_cast<ConstantAsMetadata>(ST))
554return BoundType(cast<ConstantInt>(MD->getValue()));
556if (
auto *MD = dyn_cast<DIVariable>(ST))
559if (
auto *MD = dyn_cast<DIExpression>(ST))
564DIGenericSubrange::DIGenericSubrange(
LLVMContext &
C, StorageType Storage,
566 :
DINode(
C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
575Metadata *Ops[] = {CountNode, LB, UB, Stride};
584assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&
585"Count must be signed constant or DIVariable or DIExpression");
587if (
auto *MD = dyn_cast<DIVariable>(CB))
590if (
auto *MD = dyn_cast<DIExpression>(CB))
601assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&
602"LowerBound must be signed constant or DIVariable or DIExpression");
604if (
auto *MD = dyn_cast<DIVariable>(LB))
607if (
auto *MD = dyn_cast<DIExpression>(LB))
618assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&
619"UpperBound must be signed constant or DIVariable or DIExpression");
621if (
auto *MD = dyn_cast<DIVariable>(UB))
624if (
auto *MD = dyn_cast<DIExpression>(UB))
635assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&
636"Stride must be signed constant or DIVariable or DIExpression");
638if (
auto *MD = dyn_cast<DIVariable>(ST))
641if (
auto *MD = dyn_cast<DIExpression>(ST))
647DIEnumerator::DIEnumerator(
LLVMContext &
C, StorageType Storage,
650 :
DINode(
C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
656 StorageType Storage,
bool ShouldCreate) {
665uint32_t AlignInBits,
unsigned Encoding,
666uint32_t NumExtraInhabitants, DIFlags Flags,
667 StorageType Storage,
bool ShouldCreate) {
680case dwarf::DW_ATE_signed:
681case dwarf::DW_ATE_signed_char:
683case dwarf::DW_ATE_unsigned:
684case dwarf::DW_ATE_unsigned_char:
696unsigned Encoding, StorageType Storage,
713if (
auto *CM = cast_or_null<ConstantAsMetadata>(
getExtraData()))
714if (
auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
715returnstatic_cast<uint32_t>(CI->getZExtValue());
720if (
auto *
C = cast_or_null<ConstantAsMetadata>(
getExtraData()))
727getTag() == dwarf::DW_TAG_variable) &&
729if (
auto *
C = cast_or_null<ConstantAsMetadata>(
getExtraData()))
735if (
auto *
C = cast_or_null<ConstantAsMetadata>(
getExtraData()))
744 std::optional<unsigned> DWARFAddressSpace,
745 std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
Metadata *ExtraData,
755 DWARFAddressSpace, PtrAuthData,
Flags),
759std::optional<DIDerivedType::PtrAuthData>
760DIDerivedType::getPtrAuthData()
const{
761returngetTag() == dwarf::DW_TAG_LLVM_ptrauth_type
774uint32_t NumExtraInhabitants, StorageType Storage,
bool ShouldCreate) {
777// Keep this in sync with buildODRType. 814if (CT->getTag() !=
Tag)
817// Only mutate CT if it's a forward declaration and the new operands aren't. 819if (!CT->isForwardDecl() || (
Flags & DINode::FlagFwdDecl))
822// Mutate CT in place. Keep this in sync with getImpl. 829assert((std::end(Ops) - std::begin(Ops)) == (
int)CT->getNumOperands() &&
830"Mismatched number of operands");
831for (
unsignedI = 0, E = CT->getNumOperands();
I != E; ++
I)
832if (Ops[
I] != CT->getOperand(
I))
833 CT->setOperand(
I, Ops[
I]);
857if (CT->getTag() !=
Tag)
870DISubroutineType::DISubroutineType(
LLVMContext &
C, StorageType Storage,
873 :
DIType(
C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
874 0, 0, 0, 0, Flags, Ops),
887 std::optional<ChecksumInfo<MDString *>> CS,
MDString *Src,
889 :
DIScope(
C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
890 Checksum(CS),
Source(Src) {}
892// FIXME: Implement this string-enum correspondence with a .def file and macros, 893// so that the association is explicit rather than implied. 900StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
902// The first space was originally the CSK_None variant, which is now 903// obsolete, but the space is still reserved in ChecksumKind, so we account 908std::optional<DIFile::ChecksumKind>
920MDString *Source, StorageType Storage,
925// We do *NOT* expect Source to be a canonical MDString because nullptr 926// means none, so we need something to represent the empty file. 931DICompileUnit::DICompileUnit(
LLVMContext &
C, StorageType Storage,
933unsigned RuntimeVersion,
unsigned EmissionKind,
934uint64_t DWOId,
bool SplitDebugInlining,
935bool DebugInfoForProfiling,
unsigned NameTableKind,
937 :
DIScope(
C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
940 IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),
941 DebugInfoForProfiling(DebugInfoForProfiling),
942 RangesBaseAddress(RangesBaseAddress) {
949unsigned RuntimeVersion,
MDString *SplitDebugFilename,
952uint64_t DWOId,
bool SplitDebugInlining,
bool DebugInfoForProfiling,
953unsigned NameTableKind,
bool RangesBaseAddress,
MDString *SysRoot,
954MDString *SDK, StorageType Storage,
bool ShouldCreate) {
973 RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
974 DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
979std::optional<DICompileUnit::DebugEmissionKind>
989std::optional<DICompileUnit::DebugNameTableKind>
1006return"LineTablesOnly";
1008return"DebugDirectivesOnly";
1026DISubprogram::DISubprogram(
LLVMContext &
C, StorageType Storage,
unsigned Line,
1027unsigned ScopeLine,
unsigned VirtualIndex,
1028int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
1030 :
DILocalScope(
C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
1031 Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
1032 ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
1037unsigned Virtuality,
bool IsMainSubprogram) {
1038// We're assuming virtuality is the low-order field. 1039static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
1040 int(SPFlagPureVirtual) ==
1041 int(dwarf::DW_VIRTUALITY_pure_virtual),
1042"Virtuality constant mismatch");
1045 (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
1046 (IsDefinition ? SPFlagDefinition : SPFlagZero) |
1047 (IsOptimized ? SPFlagOptimized : SPFlagZero) |
1048 (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
1052if (
auto *
Block = dyn_cast<DILexicalBlockBase>(
this))
1053returnBlock->getScope()->getSubprogram();
1054returnconst_cast<DISubprogram *
>(cast<DISubprogram>(
this));
1058if (
auto *File = dyn_cast<DILexicalBlockFile>(
this))
1059return File->getScope()->getNonLexicalBlockFileScope();
1067DIScope *CachedResult =
nullptr;
1069for (
DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope);
1070 Scope = Scope->getScope()) {
1071if (
auto It = Cache.
find(Scope); It != Cache.
end()) {
1072 CachedResult = cast<DIScope>(It->second);
1078// Recreate the scope chain, bottom-up, starting at the new subprogram (or a 1080DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;
1082 TempMDNode ClonedScope = ScopeToUpdate->
clone();
1083 cast<DILexicalBlockBase>(*ClonedScope).replaceScope(UpdatedScope);
1086 Cache[ScopeToUpdate] = UpdatedScope;
1089return cast<DILocalScope>(UpdatedScope);
1094#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
1095#include "llvm/IR/DebugInfoFlags.def" 1101// Appease a warning. 1104#define HANDLE_DISP_FLAG(ID, NAME) \ 1105 case SPFlag##NAME: \ 1106 return "DISPFlag" #NAME;
1107#include "llvm/IR/DebugInfoFlags.def" 1115// Multi-bit fields can require special handling. In our case, however, the 1116// only multi-bit field is virtuality, and all its values happen to be 1117// single-bit values, so the right behavior just falls out. 1118#define HANDLE_DISP_FLAG(ID, NAME) \ 1119 if (DISPFlags Bit = Flags & SPFlag##NAME) { \ 1120 SplitFlags.push_back(Bit); \ 1123#include "llvm/IR/DebugInfoFlags.def" 1130unsigned ScopeLine,
Metadata *ContainingType,
unsigned VirtualIndex,
1131int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
Metadata *Unit,
1134 StorageType Storage,
bool ShouldCreate) {
1165 (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,
1169bool DISubprogram::describes(
constFunction *
F)
const{
1170assert(
F &&
"Invalid function");
1171returnF->getSubprogram() ==
this;
1180unsigned Column, StorageType Storage,
1193unsigned Discriminator,
1194 StorageType Storage,
1202DINamespace::DINamespace(
LLVMContext &Context, StorageType Storage,
1204 :
DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {
1209 StorageType Storage,
bool ShouldCreate) {
1212// The nullptr is for DIScope's File operand. This should be refactored. 1217DICommonBlock::DICommonBlock(
LLVMContext &Context, StorageType Storage,
1219 :
DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
1226 StorageType Storage,
bool ShouldCreate) {
1229// The nullptr is for DIScope's File operand. This should be refactored. 1234DIModule::DIModule(
LLVMContext &Context, StorageType Storage,
unsigned LineNo,
1236 :
DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {
1244unsigned LineNo,
bool IsDecl, StorageType Storage,
1253DITemplateTypeParameter::DITemplateTypeParameter(
LLVMContext &Context,
1254 StorageType Storage,
1258 dwarf::DW_TAG_template_type_parameter, IsDefault,
1264 StorageType Storage,
bool ShouldCreate) {
1273bool isDefault,
Metadata *
Value, StorageType Storage,
bool ShouldCreate) {
1285Metadata *StaticDataMemberDeclaration,
1311unsigned Arg, DIFlags Flags,
uint32_t AlignInBits,
1314// 64K ought to be enough for any frontend. 1315assert(Arg <= UINT16_MAX &&
"Expected argument number to fit in 16-bits");
1328 :
DINode(
C,
ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {
1332// This is used by the Verifier so be mindful of broken types. 1335// Try to get the size directly. 1336if (
auto *
T = dyn_cast<DIType>(RawType))
1340if (
auto *DT = dyn_cast<DIDerivedType>(RawType)) {
1341// Look at the base type. 1342 RawType = DT->getRawBaseType();
1346// Missing type or size. 1354DILabel::DILabel(
LLVMContext &
C, StorageType Storage,
unsigned Line,
1356 :
DINode(
C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {
1360Metadata *File,
unsigned Line, StorageType Storage,
1371 StorageType Storage,
bool ShouldCreate) {
1377return singleLocElts->size() > 0 &&
1384return singleLocElts->size() > 0 &&
1385 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1390return singleLocElts->size() == 1 &&
1391 (*singleLocElts)[0] == dwarf::DW_OP_deref;
1397// Uniqued DIAssignID are not supported as the instance address *is* the ID. 1405if (
Op >= dwarf::DW_OP_breg0 &&
Op <= dwarf::DW_OP_breg31)
1413case dwarf::DW_OP_bregx:
1415case dwarf::DW_OP_constu:
1416case dwarf::DW_OP_consts:
1417case dwarf::DW_OP_deref_size:
1418case dwarf::DW_OP_plus_uconst:
1422case dwarf::DW_OP_regx:
1431// Check that there's space for the operand. 1432if (
I->get() +
I->getSize() > E->get())
1436if ((
Op >= dwarf::DW_OP_reg0 &&
Op <= dwarf::DW_OP_reg31) ||
1437 (
Op >= dwarf::DW_OP_breg0 &&
Op <= dwarf::DW_OP_breg31))
1440// Check that the operand is valid. 1445// A fragment operator must appear at the end. 1446returnI->get() +
I->getSize() == E->get();
1447case dwarf::DW_OP_stack_value: {
1448// Must be the last one or followed by a DW_OP_LLVM_fragment. 1449if (
I->get() +
I->getSize() == E->get())
1456case dwarf::DW_OP_swap: {
1457// Must be more than one implicit element on the stack. 1459// FIXME: A better way to implement this would be to add a local variable 1460// that keeps track of the stack depth and introduce something like a 1461// DW_LLVM_OP_implicit_location as a placeholder for the location this 1462// DIExpression is attached to, or else pass the number of implicit stack 1463// elements into isValid. 1469// An entry value operator must appear at the beginning or immediately 1470// following `DW_OP_LLVM_arg 0`, and the number of operations it cover can 1471// currently only be 1, because we support only entry values of a simple 1472// register location. One reason for this is that we currently can't 1473// calculate the size of the resulting DWARF block for other expressions. 1477returnI->get() == FirstOp->get() &&
I->getArg(0) == 1;
1485case dwarf::DW_OP_constu:
1486case dwarf::DW_OP_plus_uconst:
1487case dwarf::DW_OP_plus:
1488case dwarf::DW_OP_minus:
1489case dwarf::DW_OP_mul:
1490case dwarf::DW_OP_div:
1491case dwarf::DW_OP_mod:
1492case dwarf::DW_OP_or:
1493case dwarf::DW_OP_and:
1494case dwarf::DW_OP_xor:
1495case dwarf::DW_OP_shl:
1496case dwarf::DW_OP_shr:
1497case dwarf::DW_OP_shra:
1498case dwarf::DW_OP_deref:
1499case dwarf::DW_OP_deref_size:
1500case dwarf::DW_OP_xderef:
1501case dwarf::DW_OP_lit0:
1502case dwarf::DW_OP_not:
1503case dwarf::DW_OP_dup:
1504case dwarf::DW_OP_regx:
1505case dwarf::DW_OP_bregx:
1506case dwarf::DW_OP_push_object_address:
1507case dwarf::DW_OP_over:
1508case dwarf::DW_OP_consts:
1509case dwarf::DW_OP_eq:
1510case dwarf::DW_OP_ne:
1511case dwarf::DW_OP_gt:
1512case dwarf::DW_OP_ge:
1513case dwarf::DW_OP_lt:
1514case dwarf::DW_OP_le:
1529switch (It.getOp()) {
1532case dwarf::DW_OP_stack_value:
1547// If there are any elements other than fragment or tag_offset, then some 1548// kind of complex computation occurs. 1550switch (It.getOp()) {
1570auto ExprOpBegin =
expr_ops().begin();
1573if (ExprOpBegin->getArg(0) != 0)
1578return !std::any_of(ExprOpBegin, ExprOpEnd, [](
autoOp) {
1583std::optional<ArrayRef<uint64_t>>
1585// Check for `isValid` covered by `isSingleLocationExpression`. 1589// An empty expression is already non-variadic. 1593// If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do 1613 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
1623std::optional<const DIExpression *>
1637// If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0` 1638// to the existing expression ops. 1640 return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
1643// If Expr is not indirect, we only need to insert the expression elements and 1649// If Expr is indirect, insert the implied DW_OP_deref at the end of the 1650// expression but before DW_OP_{stack_value, LLVM_fragment} if they are 1653if (
Op.getOp() == dwarf::DW_OP_stack_value ||
1658Op.appendToVector(Ops);
1667bool SecondIndirect) {
1673return FirstOps == SecondOps;
1676std::optional<DIExpression::FragmentInfo>
1678for (
autoI = Start;
I !=
End; ++
I)
1687 std::optional<uint64_t> InitialActiveBits = Var->
getSizeInBits();
1688 std::optional<uint64_t> ActiveBits = InitialActiveBits;
1690switch (
Op.getOp()) {
1692// We assume the worst case for anything we don't currently handle and 1693// revert to the initial active bits. 1694 ActiveBits = InitialActiveBits;
1698// We can't handle an extract whose sign doesn't match that of the 1700 std::optional<DIBasicType::Signedness> VarSign = Var->
getSignedness();
1703if (!VarSign || VarSigned != OpSigned) {
1704 ActiveBits = InitialActiveBits;
1710// Extract or fragment narrows the active bits 1712 ActiveBits = std::min(*ActiveBits,
Op.getArg(1));
1714 ActiveBits =
Op.getArg(1);
1724 Ops.
push_back(dwarf::DW_OP_plus_uconst);
1728// Avoid UB when encountering LLONG_MIN, because in 2's complement 1729// abs(LLONG_MIN) is LLONG_MAX+1. 1738if (!SingleLocEltsOpt)
1740auto SingleLocElts = *SingleLocEltsOpt;
1742if (SingleLocElts.size() == 0) {
1747if (SingleLocElts.size() == 2 &&
1748 SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
1749Offset = SingleLocElts[1];
1753if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
1754if (SingleLocElts[2] == dwarf::DW_OP_plus) {
1755Offset = SingleLocElts[1];
1758if (SingleLocElts[2] == dwarf::DW_OP_minus) {
1759Offset = -SingleLocElts[1];
1770 RemainingOps.
clear();
1773if (!SingleLocEltsOpt)
1778while (ExprOpIt != ExprOpEnd) {
1780if (
Op == dwarf::DW_OP_deref ||
Op == dwarf::DW_OP_deref_size ||
1785 }
elseif (
Op == dwarf::DW_OP_plus_uconst) {
1786 OffsetInBytes += ExprOpIt->getArg(0);
1787 }
elseif (
Op == dwarf::DW_OP_constu) {
1790if (ExprOpIt->getOp() == dwarf::DW_OP_plus)
1791 OffsetInBytes +=
Value;
1792elseif (ExprOpIt->getOp() == dwarf::DW_OP_minus)
1793 OffsetInBytes -=
Value;
1797// Not a const plus/minus operation or deref. 1802 RemainingOps.
append(ExprOpIt.getBase(), ExprOpEnd.getBase());
1810 SeenOps.
insert(ExprOp.getArg(0));
1818unsigned &AddrClass) {
1819// FIXME: This seems fragile. Nothing that verifies that these elements 1820// actually map to ops and not operands. 1822if (!SingleLocEltsOpt)
1824auto SingleLocElts = *SingleLocEltsOpt;
1826constunsigned PatternSize = 4;
1827if (SingleLocElts.size() >= PatternSize &&
1828 SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu &&
1829 SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap &&
1830 SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) {
1831 AddrClass = SingleLocElts[PatternSize - 3];
1833if (SingleLocElts.size() == PatternSize)
1837ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize));
1861assert(Expr &&
"Can't add ops to this expression");
1863// Handle non-variadic intrinsics by prepending the opcodes. 1865 [](
autoOp) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) {
1867"Location Index must be 0 for a non-variadic expression.");
1874// A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. 1876if (
Op.getOp() == dwarf::DW_OP_stack_value)
1879 NewOps.
push_back(dwarf::DW_OP_stack_value);
1883Op.appendToVector(NewOps);
1888 NewOps.
push_back(dwarf::DW_OP_stack_value);
1895assert(Expr &&
"Can't replace args in this expression");
1901Op.appendToVector(NewOps);
1905uint64_t Arg =
Op.getArg(0) == OldArg ? NewArg :
Op.getArg(0);
1906// OldArg has been deleted from the Op list, so decrement all indices 1918assert(Expr &&
"Can't prepend ops to this expression");
1922// Use a block size of 1 for the target register operand. The 1923// DWARF backend currently cannot emit entry values with a block 1928// If there are no ops to prepend, do not even add the DW_OP_stack_value. 1932// A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment. 1934if (
Op.getOp() == dwarf::DW_OP_stack_value)
1937 Ops.
push_back(dwarf::DW_OP_stack_value);
1941Op.appendToVector(Ops);
1944 Ops.
push_back(dwarf::DW_OP_stack_value);
1950assert(Expr && !Ops.
empty() &&
"Can't append ops to this expression");
1952// Copy Expr's current op list. 1955// Append new opcodes before DW_OP_{stack_value, LLVM_fragment}. 1956if (
Op.getOp() == dwarf::DW_OP_stack_value ||
1960// Ensure that the new opcodes are only appended once. 1963Op.appendToVector(NewOps);
1968assert(result->isValid() &&
"concatenated expression is not valid");
1974assert(Expr && !Ops.
empty() &&
"Can't append ops to this expression");
1978 return Op.getOp() == dwarf::DW_OP_stack_value ||
1979 Op.getOp() == dwarf::DW_OP_LLVM_fragment;
1981"Can't append this op");
1983// Append a DW_OP_deref after Expr's current op list if it's non-empty and 1984// has no DW_OP_stack_value. 1986// Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?. 1988unsigned DropUntilStackValue = FI ? 3 : 0;
1991bool NeedsDeref = (Expr->
getNumElements() > DropUntilStackValue) &&
1992 (ExprOpsBeforeFragment.
back() != dwarf::DW_OP_stack_value);
1993bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.
empty();
1995// Append a DW_OP_deref after Expr's current op list if needed, then append 1996// the new ops, and finally ensure that a single DW_OP_stack_value is present. 2002 NewOps.
push_back(dwarf::DW_OP_stack_value);
2007constDIExpression *Expr,
unsigned OffsetInBits,
unsigned SizeInBits) {
2009// Track whether it's safe to split the value at the top of the DWARF stack, 2010// assuming that it'll be used as an implicit location value. 2011bool CanSplitValue =
true;
2012// Track whether we need to add a fragment expression to the end of Expr. 2013bool EmitFragment =
true;
2014// Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment. 2017switch (
Op.getOp()) {
2020case dwarf::DW_OP_shr:
2021case dwarf::DW_OP_shra:
2022case dwarf::DW_OP_shl:
2023case dwarf::DW_OP_plus:
2024case dwarf::DW_OP_plus_uconst:
2025case dwarf::DW_OP_minus:
2026// We can't safely split arithmetic or shift operations into multiple 2027// fragments because we can't express carry-over between fragments. 2029// FIXME: We *could* preserve the lowest fragment of a constant offset 2030// operation if the offset fits into SizeInBits. 2031 CanSplitValue =
false;
2033case dwarf::DW_OP_deref:
2034case dwarf::DW_OP_deref_size:
2035case dwarf::DW_OP_deref_type:
2036case dwarf::DW_OP_xderef:
2037case dwarf::DW_OP_xderef_size:
2038case dwarf::DW_OP_xderef_type:
2039// Preceeding arithmetic operations have been applied to compute an 2040// address. It's okay to split the value loaded from that address. 2041 CanSplitValue =
true;
2043case dwarf::DW_OP_stack_value:
2044// Bail if this expression computes a value that cannot be split. 2049// If we've decided we don't need a fragment then give up if we see that 2050// there's already a fragment expression. 2051// FIXME: We could probably do better here 2054// Make the new offset point into the existing fragment. 2057 (void)FragmentSizeInBits;
2058assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
2059"new fragment outside of original fragment");
2060 OffsetInBits += FragmentOffsetInBits;
2065// If we're extracting bits from inside of the fragment that we're 2066// creating then we don't have a fragment after all, and just need to 2067// adjust the offset that we're extracting from. 2070if (ExtractOffsetInBits >= OffsetInBits &&
2071 ExtractOffsetInBits + ExtractSizeInBits <=
2072 OffsetInBits + SizeInBits) {
2074 Ops.
push_back(ExtractOffsetInBits - OffsetInBits);
2076 EmitFragment =
false;
2079// If the extracted bits aren't fully contained within the fragment then 2081// FIXME: We could probably do better here 2085Op.appendToVector(Ops);
2089assert(Expr &&
"Unknown DIExpression");
2098/// See declaration for more info. 2101uint64_t SliceSizeInBits,
constValue *DbgPtr, int64_t DbgPtrOffsetInBits,
2103 std::optional<DIExpression::FragmentInfo> &Result,
2104 int64_t &OffsetFromLocationInBits) {
2107returnfalse;
// Variable size is unknown. 2109// Difference between mem slice start and the dbg location start. 2112// dbg location start 2115// Here MemStartRelToDbgStartInBits is 8. Note this can be negative. 2116 int64_t MemStartRelToDbgStartInBits;
2119if (!MemOffsetFromDbgInBytes)
2120returnfalse;
// Can't calculate difference in addresses. 2121// Difference between the pointers. 2122 MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;
2123// Add the difference of the offsets. 2124 MemStartRelToDbgStartInBits +=
2125 SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);
2128// Out-param. Invert offset to get offset from debug location. 2129 OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;
2131// Check if the variable fragment sits outside (before) this memory slice. 2132 int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;
2133if (MemEndRelToDbgStart < 0) {
2134 Result = {0, 0};
// Out-param. 2138// Work towards creating SliceOfVariable which is the bits of the variable 2139// that the memory region covers. 2142// dbg location start with VarFrag offset=32 2144// mem slice start: SliceOfVariable offset=40 2145 int64_t MemStartRelToVarInBits =
2147 int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;
2148// If the memory region starts before the debug location the fragment 2149// offset would be negative, which we can't encode. Limit those to 0. This 2150// is fine because those bits necessarily don't overlap with the existing 2151// variable fragment. 2152 int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);
2153 int64_t MemFragSize =
2154 std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);
2157// Intersect the memory region fragment with the variable location fragment. 2160if (TrimmedSliceOfVariable == VarFrag)
2161 Result = std::nullopt;
// Out-param. 2163 Result = TrimmedSliceOfVariable;
// Out-param. 2167std::pair<DIExpression *, const ConstantInt *>
2169// Copy the APInt so we can modify it. 2173// Fold operators only at the beginning of the expression. 2177switch (
Op.getOp()) {
2179// We fold only the leading part of the expression; if we get to a part 2180// that we're going to copy unchanged, and haven't done any folding, 2181// then the entire expression is unchanged and we can return early. 2190if (
Op.getArg(1) == dwarf::DW_ATE_signed)
2193assert(
Op.getArg(1) == dwarf::DW_ATE_unsigned &&
"Unexpected operand");
2198Op.appendToVector(Ops);
2210 Result = std::max(Result, ExprOp.getArg(0) + 1);
2212"Expression is missing one or more location operands.");
2216std::optional<DIExpression::SignedOrUnsignedConstant>
2219// Recognize signed and unsigned constants. 2220// An signed constants can be represented as DW_OP_consts C DW_OP_stack_value 2221// (DW_OP_LLVM_fragment of Len). 2222// An unsigned constant can be represented as 2223// DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len). 2252unsigned FromSize,
unsigned ToSize,
2266unsigned Line,
unsigned Attributes,
2268 :
DINode(
C, DIObjCPropertyKind,
Storage, dwarf::DW_TAG_APPLE_property, Ops),
2274Metadata *
Type, StorageType Storage,
bool ShouldCreate) {
2288 StorageType Storage,
2308Metadata *Elements, StorageType Storage,
2327assert((!New || isa<ValueAsMetadata>(New)) &&
2328"DIArgList must be passed a ValueAsMetadata");
2330// We need to update the set storage once the Args are updated since they 2331// form the key to the DIArgLists store. 2335if (&VM == OldVMPtr) {
2342// We've changed the contents of this DIArgList, and the set storage may 2343// already contain a DIArgList with our new set of args; if it does, then we 2344// must RAUW this with the existing DIArgList, otherwise we simply insert this 2345// back into the set storage. 2347if (ExistingArgList) {
2349// Clear this here so we don't try to untrack in the destructor. 2357void DIArgList::track() {
2362void DIArgList::untrack() {
2367void DIArgList::dropAllReferences(
bool Untrack) {
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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
static DISubprogram * getSubprogram(bool IsDistinct, Ts &&...Args)
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 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 RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
static unsigned encodingBits(unsigned C)
static unsigned encodeComponent(unsigned C)
static unsigned getNextComponentInDiscriminator(unsigned D)
Returns the next component stored in discriminator.
static unsigned getUnsignedFromPrefixEncoding(unsigned U)
Reverse transformation as getPrefixEncodingFromUnsigned.
This file contains constants used for implementing Dwarf debug support.
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
support::ulittle16_t & Lo
Class for arbitrary precision integers.
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Annotations lets you mark points and ranges inside source code, for tests:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - Get the last element.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
size_t size() const
size - Get the array size.
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
bool empty() const
empty - Check if the array is empty.
static ConstantAsMetadata * get(Constant *C)
This is the shared class of boolean and integer constants.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
void handleChangedOperand(void *Ref, Metadata *New)
static DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)
Basic type, like 'int' or 'float'.
unsigned StringRef uint64_t FlagZero unsigned StringRef uint64_t uint32_t unsigned DIFlags Flags
unsigned StringRef uint64_t SizeInBits
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 uint64_t FlagZero unsigned StringRef uint64_t uint32_t AlignInBits
Metadata Metadata MDString Metadata unsigned LineNo
Metadata Metadata MDString * Name
Metadata Metadata MDString Metadata * File
static const char * nameTableKindString(DebugNameTableKind PK)
static const char * emissionKindString(DebugEmissionKind EK)
DebugEmissionKind getEmissionKind() const
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 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 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 Metadata Metadata * TemplateParams
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned 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 Metadata Metadata MDString Metadata Metadata Metadata Metadata Metadata * Rank
static DICompositeType * getODRTypeIfExists(LLVMContext &Context, MDString &Identifier)
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 uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata Metadata * Allocated
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 Metadata Metadata MDString Metadata * Discriminator
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned 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 Metadata Metadata MDString Metadata Metadata * DataLocation
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString * Identifier
unsigned MDString Metadata unsigned Metadata Metadata uint64_t SizeInBits
static DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
Build a DICompositeType with the given ODR identifier.
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata Metadata MDString Metadata Metadata Metadata * Associated
unsigned MDString Metadata unsigned Metadata Metadata uint64_t uint32_t uint64_t DIFlags Metadata unsigned Metadata * VTableHolder
unsigned StringRef DIFile unsigned DIScope DIType * BaseType
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Metadata * ExtraData
unsigned StringRef DIFile unsigned DIScope DIType uint64_t SizeInBits
Metadata * getExtraData() const
Get extra data associated with this derived type.
unsigned StringRef DIFile * File
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t OffsetInBits
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t AlignInBits
unsigned StringRef DIFile unsigned DIScope * Scope
DIType * getClassType() const
Get casted version of extra data.
Constant * getConstant() const
Constant * getStorageOffsetInBits() const
Constant * getDiscriminantValue() const
uint32_t getVBPtrOffset() const
unsigned StringRef DIFile unsigned DIScope DIType uint64_t uint32_t uint64_t std::optional< unsigned > std::optional< PtrAuthData > DIFlags Flags
unsigned StringRef DIFile unsigned Line
int64_t bool MDString * Name
unsigned getSize() const
Return the size of the operand.
uint64_t getOp() const
Get the operand code.
An iterator for expression operands.
element_iterator elements_end() const
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
iterator_range< expr_op_iterator > expr_ops() const
static 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 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.
bool extractIfOffset(int64_t &Offset) const
If this is a constant offset, extract it.
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
static 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
bool isImplicit() const
Return whether this is an implicit location description.
static 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
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 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...
bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
static std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
std::pair< DIExpression *, const ConstantInt * > constantFold(const ConstantInt *CI)
Try to shorten an expression with an initial constant operand.
bool isDeref() const
Return whether there is exactly one operator and it is a DW_OP_deref;.
static const DIExpression * convertToVariadicExpression(const DIExpression *Expr)
If Expr is a non-variadic expression (i.e.
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 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,...
std::optional< uint64_t > getActiveBits(DIVariable *Var)
Return the number of bits that have an active value, i.e.
static 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 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 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 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 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 DIExpression * appendExt(const DIExpression *Expr, unsigned FromSize, unsigned ToSize, bool Signed)
Append a zero- or sign-extension to Expr.
std::optional< ArrayRef< uint64_t > > getSingleLocationExpressionElements() const
Returns a reference to the elements contained in this expression, skipping past the leading DW_OP_LLV...
bool isSingleLocationExpression() const
Return whether the evaluated expression makes use of a single location at the start of the expression...
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...
std::optional< SignedOrUnsignedConstant > isConstant() const
Determine whether this represents a constant value, if so.
static 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 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
static std::optional< ChecksumKind > getChecksumKind(StringRef CSKindStr)
MDString MDString std::optional< ChecksumInfo< MDString * > > CS
Metadata * getRawLowerBound() const
Metadata * getRawCountNode() const
Metadata * getRawStride() const
BoundType getLowerBound() const
Metadata * getRawUpperBound() const
BoundType getCount() const
BoundType getUpperBound() const
PointerUnion< DIVariable *, DIExpression * > BoundType
BoundType getStride() const
A pair of DIGlobalVariable and DIExpression.
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata Metadata * TemplateParams
Metadata MDString MDString Metadata unsigned Line
Metadata MDString MDString Metadata unsigned Metadata * Type
Metadata MDString MDString Metadata unsigned Metadata bool bool Metadata * 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 Metadata * File
DILexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage, ArrayRef< Metadata * > Ops)
Metadata Metadata unsigned Discriminator
Metadata Metadata unsigned Line
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
static 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 Metadata unsigned Line
Metadata MDString Metadata unsigned Metadata unsigned DIFlags uint32_t AlignInBits
unsigned unsigned DILocalScope * Scope
static DILocation * getMergedLocations(ArrayRef< DILocation * > Locs)
Try to combine the vector of locations passed as input in a single one.
static std::optional< unsigned > encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI)
Raw encoding of the discriminator.
unsigned unsigned DILocalScope DILocation bool ImplicitCode
static void decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF, unsigned &CI)
Raw decoder for values in an encoded discriminator D.
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
unsigned unsigned DILocalScope DILocation * InlinedAt
unsigned unsigned Metadata * File
unsigned unsigned Metadata Metadata * Elements
unsigned unsigned MDString * Name
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
Metadata MDString bool ExportSymbols
Tagged DWARF-like metadata node.
dwarf::Tag getTag() const
static DIFlags getFlag(StringRef Flag)
static DIFlags splitFlags(DIFlags Flags, SmallVectorImpl< DIFlags > &SplitFlags)
Split up a flags bitfield.
static StringRef getFlagString(DIFlags Flag)
MDString Metadata unsigned MDString * GetterName
MDString Metadata unsigned MDString MDString * SetterName
Base class for scope-like contexts.
StringRef getName() const
DIScope * getScope() const
String type, Fortran CHARACTER(n)
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
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 * 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 DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)
Metadata MDString MDString Metadata unsigned Metadata unsigned Metadata unsigned int DIFlags DISPFlags Metadata Metadata Metadata Metadata Metadata * ThrownTypes
static DISPFlags getFlag(StringRef Flag)
Metadata MDString MDString Metadata * File
static DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)
Split up a flags bitfield for easier printing.
Metadata MDString MDString * LinkageName
static 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.
BoundType getUpperBound() const
BoundType getStride() const
BoundType getLowerBound() const
BoundType getCount() const
Type array for a subprogram.
DIFlags uint8_t Metadata * TypeArray
Base class for template parameters.
unsigned MDString Metadata * Type
bool isStaticMember() const
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...
std::optional< uint64_t > getSizeInBits() const
Determines the size of the variable's type.
Metadata * getRawType() const
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.
This is the common base class for debug info intrinsics for variables.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
DebugVariableAggregate(const DbgVariableIntrinsic *DVI)
Identifies a unique instance of a variable.
DebugVariable(const DbgVariableIntrinsic *DII)
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Class representing an expression and its matching format.
Generic tagged DWARF-like metadata node.
dwarf::Tag getTag() const
unsigned MDString * Header
unsigned MDString ArrayRef< Metadata * > DwarfOps
DenseSet< DIArgList *, DIArgListInfo > DIArgLists
std::optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap
This is an important class for using LLVM in a threaded context.
bool isODRUniquingDebugTypes() const
Whether there is a string map for uniquing debug info identifiers across the context.
LLVMContextImpl *const pImpl
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
TempMDNode clone() const
Create a (temporary) clone of this.
static T * storeImpl(T *N, StorageType Storage, StoreT &Store)
LLVMContext & getContext() const
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.
StringRef getString() const
static void untrack(Metadata *&MD)
Stop tracking a reference to metadata.
static bool track(Metadata *&MD)
Track the reference to metadata.
Root of the metadata hierarchy.
StorageType
Active type of storage.
unsigned short SubclassData16
unsigned char Storage
Storage flag for non-uniqued, otherwise unowned, metadata.
unsigned char SubclassData1
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
void replaceAllUsesWith(Metadata *MD)
Replace all uses of this with MD.
LLVMContext & getContext() const
void resolveAllUses(bool ResolveUsers=true)
Resolve all uses of this.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt64Ty(LLVMContext &C)
Value wrapper in the Metadata hierarchy.
static ValueAsMetadata * get(Value *V)
LLVM Value Representation.
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.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
@ DW_OP_LLVM_entry_value
Only used in LLVM metadata.
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
static T * getUniqued(DenseSet< T *, InfoT > &Store, const typename InfoT::KeyTy &Key)
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.
auto reverse(ContainerTy &&C)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
@ Ref
The access may reference the value stored in memory.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Implement std::hash so that hash_code can be used in STL containers.
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.