Path: blob/main/contrib/llvm-project/llvm/lib/IR/DebugInfoMetadata.cpp
35234 views
//===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the debug info Metadata classes.9//10//===----------------------------------------------------------------------===//1112#include "llvm/IR/DebugInfoMetadata.h"13#include "LLVMContextImpl.h"14#include "MetadataImpl.h"15#include "llvm/ADT/SmallPtrSet.h"16#include "llvm/ADT/StringSwitch.h"17#include "llvm/BinaryFormat/Dwarf.h"18#include "llvm/IR/DebugProgramInstruction.h"19#include "llvm/IR/Function.h"20#include "llvm/IR/IntrinsicInst.h"21#include "llvm/IR/Type.h"22#include "llvm/IR/Value.h"2324#include <numeric>25#include <optional>2627using namespace llvm;2829namespace llvm {30// Use FS-AFDO discriminator.31cl::opt<bool> EnableFSDiscriminator(32"enable-fs-discriminator", cl::Hidden,33cl::desc("Enable adding flow sensitive discriminators"));34} // namespace llvm3536uint32_t DIType::getAlignInBits() const {37return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32);38}3940const DIExpression::FragmentInfo DebugVariable::DefaultFragment = {41std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};4243DebugVariable::DebugVariable(const DbgVariableIntrinsic *DII)44: Variable(DII->getVariable()),45Fragment(DII->getExpression()->getFragmentInfo()),46InlinedAt(DII->getDebugLoc().getInlinedAt()) {}4748DebugVariable::DebugVariable(const DbgVariableRecord *DVR)49: Variable(DVR->getVariable()),50Fragment(DVR->getExpression()->getFragmentInfo()),51InlinedAt(DVR->getDebugLoc().getInlinedAt()) {}5253DebugVariableAggregate::DebugVariableAggregate(const DbgVariableIntrinsic *DVI)54: DebugVariable(DVI->getVariable(), std::nullopt,55DVI->getDebugLoc()->getInlinedAt()) {}5657DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,58unsigned Column, ArrayRef<Metadata *> MDs,59bool ImplicitCode)60: MDNode(C, DILocationKind, Storage, MDs) {61assert((MDs.size() == 1 || MDs.size() == 2) &&62"Expected a scope and optional inlined-at");6364// Set line and column.65assert(Column < (1u << 16) && "Expected 16-bit column");6667SubclassData32 = Line;68SubclassData16 = Column;6970setImplicitCode(ImplicitCode);71}7273static void adjustColumn(unsigned &Column) {74// Set to unknown on overflow. We only have 16 bits to play with here.75if (Column >= (1u << 16))76Column = 0;77}7879DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,80unsigned Column, Metadata *Scope,81Metadata *InlinedAt, bool ImplicitCode,82StorageType Storage, bool ShouldCreate) {83// Fixup column.84adjustColumn(Column);8586if (Storage == Uniqued) {87if (auto *N = getUniqued(Context.pImpl->DILocations,88DILocationInfo::KeyTy(Line, Column, Scope,89InlinedAt, ImplicitCode)))90return N;91if (!ShouldCreate)92return nullptr;93} else {94assert(ShouldCreate && "Expected non-uniqued nodes to always be created");95}9697SmallVector<Metadata *, 2> Ops;98Ops.push_back(Scope);99if (InlinedAt)100Ops.push_back(InlinedAt);101return storeImpl(new (Ops.size(), Storage) DILocation(102Context, Storage, Line, Column, Ops, ImplicitCode),103Storage, Context.pImpl->DILocations);104}105106DILocation *DILocation::getMergedLocations(ArrayRef<DILocation *> Locs) {107if (Locs.empty())108return nullptr;109if (Locs.size() == 1)110return Locs[0];111auto *Merged = Locs[0];112for (DILocation *L : llvm::drop_begin(Locs)) {113Merged = getMergedLocation(Merged, L);114if (Merged == nullptr)115break;116}117return Merged;118}119120DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) {121if (!LocA || !LocB)122return nullptr;123124if (LocA == LocB)125return LocA;126127LLVMContext &C = LocA->getContext();128129using LocVec = SmallVector<const DILocation *>;130LocVec ALocs;131LocVec BLocs;132SmallDenseMap<std::pair<const DISubprogram *, const DILocation *>, unsigned,1334>134ALookup;135136// Walk through LocA and its inlined-at locations, populate them in ALocs and137// save the index for the subprogram and inlined-at pair, which we use to find138// a matching starting location in LocB's chain.139for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) {140ALocs.push_back(L);141auto Res = ALookup.try_emplace(142{L->getScope()->getSubprogram(), L->getInlinedAt()}, I);143assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?");144(void)Res;145}146147LocVec::reverse_iterator ARIt = ALocs.rend();148LocVec::reverse_iterator BRIt = BLocs.rend();149150// Populate BLocs and look for a matching starting location, the first151// location with the same subprogram and inlined-at location as in LocA's152// chain. Since the two locations have the same inlined-at location we do153// not need to look at those parts of the chains.154for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) {155BLocs.push_back(L);156157if (ARIt != ALocs.rend())158// We have already found a matching starting location.159continue;160161auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()});162if (IT == ALookup.end())163continue;164165// The + 1 is to account for the &*rev_it = &(it - 1) relationship.166ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1);167BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1);168169// If we have found a matching starting location we do not need to add more170// locations to BLocs, since we will only look at location pairs preceding171// the matching starting location, and adding more elements to BLocs could172// invalidate the iterator that we initialized here.173break;174}175176// Merge the two locations if possible, using the supplied177// inlined-at location for the created location.178auto MergeLocPair = [&C](const DILocation *L1, const DILocation *L2,179DILocation *InlinedAt) -> DILocation * {180if (L1 == L2)181return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(),182InlinedAt);183184// If the locations originate from different subprograms we can't produce185// a common location.186if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())187return nullptr;188189// Return the nearest common scope inside a subprogram.190auto GetNearestCommonScope = [](DIScope *S1, DIScope *S2) -> DIScope * {191SmallPtrSet<DIScope *, 8> Scopes;192for (; S1; S1 = S1->getScope()) {193Scopes.insert(S1);194if (isa<DISubprogram>(S1))195break;196}197198for (; S2; S2 = S2->getScope()) {199if (Scopes.count(S2))200return S2;201if (isa<DISubprogram>(S2))202break;203}204205return nullptr;206};207208auto Scope = GetNearestCommonScope(L1->getScope(), L2->getScope());209assert(Scope && "No common scope in the same subprogram?");210211bool SameLine = L1->getLine() == L2->getLine();212bool SameCol = L1->getColumn() == L2->getColumn();213unsigned Line = SameLine ? L1->getLine() : 0;214unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;215216return DILocation::get(C, Line, Col, Scope, InlinedAt);217};218219DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr;220221// If we have found a common starting location, walk up the inlined-at chains222// and try to produce common locations.223for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {224DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);225226if (!Tmp)227// We have walked up to a point in the chains where the two locations228// are irreconsilable. At this point Result contains the nearest common229// location in the inlined-at chains of LocA and LocB, so we break here.230break;231232Result = Tmp;233}234235if (Result)236return Result;237238// We ended up with LocA and LocB as irreconsilable locations. Produce a239// location at 0:0 with one of the locations' scope. The function has240// historically picked A's scope, and a nullptr inlined-at location, so that241// behavior is mimicked here but I am not sure if this is always the correct242// way to handle this.243return DILocation::get(C, 0, 0, LocA->getScope(), nullptr);244}245246std::optional<unsigned>247DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {248std::array<unsigned, 3> Components = {BD, DF, CI};249uint64_t RemainingWork = 0U;250// We use RemainingWork to figure out if we have no remaining components to251// encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to252// encode anything for the latter 2.253// Since any of the input components is at most 32 bits, their sum will be254// less than 34 bits, and thus RemainingWork won't overflow.255RemainingWork =256std::accumulate(Components.begin(), Components.end(), RemainingWork);257258int I = 0;259unsigned Ret = 0;260unsigned NextBitInsertionIndex = 0;261while (RemainingWork > 0) {262unsigned C = Components[I++];263RemainingWork -= C;264unsigned EC = encodeComponent(C);265Ret |= (EC << NextBitInsertionIndex);266NextBitInsertionIndex += encodingBits(C);267}268269// Encoding may be unsuccessful because of overflow. We determine success by270// checking equivalence of components before & after encoding. Alternatively,271// we could determine Success during encoding, but the current alternative is272// simpler.273unsigned TBD, TDF, TCI = 0;274decodeDiscriminator(Ret, TBD, TDF, TCI);275if (TBD == BD && TDF == DF && TCI == CI)276return Ret;277return std::nullopt;278}279280void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,281unsigned &CI) {282BD = getUnsignedFromPrefixEncoding(D);283DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D));284CI = getUnsignedFromPrefixEncoding(285getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));286}287dwarf::Tag DINode::getTag() const { return (dwarf::Tag)SubclassData16; }288289DINode::DIFlags DINode::getFlag(StringRef Flag) {290return StringSwitch<DIFlags>(Flag)291#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)292#include "llvm/IR/DebugInfoFlags.def"293.Default(DINode::FlagZero);294}295296StringRef DINode::getFlagString(DIFlags Flag) {297switch (Flag) {298#define HANDLE_DI_FLAG(ID, NAME) \299case Flag##NAME: \300return "DIFlag" #NAME;301#include "llvm/IR/DebugInfoFlags.def"302}303return "";304}305306DINode::DIFlags DINode::splitFlags(DIFlags Flags,307SmallVectorImpl<DIFlags> &SplitFlags) {308// Flags that are packed together need to be specially handled, so309// that, for example, we emit "DIFlagPublic" and not310// "DIFlagPrivate | DIFlagProtected".311if (DIFlags A = Flags & FlagAccessibility) {312if (A == FlagPrivate)313SplitFlags.push_back(FlagPrivate);314else if (A == FlagProtected)315SplitFlags.push_back(FlagProtected);316else317SplitFlags.push_back(FlagPublic);318Flags &= ~A;319}320if (DIFlags R = Flags & FlagPtrToMemberRep) {321if (R == FlagSingleInheritance)322SplitFlags.push_back(FlagSingleInheritance);323else if (R == FlagMultipleInheritance)324SplitFlags.push_back(FlagMultipleInheritance);325else326SplitFlags.push_back(FlagVirtualInheritance);327Flags &= ~R;328}329if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {330Flags &= ~FlagIndirectVirtualBase;331SplitFlags.push_back(FlagIndirectVirtualBase);332}333334#define HANDLE_DI_FLAG(ID, NAME) \335if (DIFlags Bit = Flags & Flag##NAME) { \336SplitFlags.push_back(Bit); \337Flags &= ~Bit; \338}339#include "llvm/IR/DebugInfoFlags.def"340return Flags;341}342343DIScope *DIScope::getScope() const {344if (auto *T = dyn_cast<DIType>(this))345return T->getScope();346347if (auto *SP = dyn_cast<DISubprogram>(this))348return SP->getScope();349350if (auto *LB = dyn_cast<DILexicalBlockBase>(this))351return LB->getScope();352353if (auto *NS = dyn_cast<DINamespace>(this))354return NS->getScope();355356if (auto *CB = dyn_cast<DICommonBlock>(this))357return CB->getScope();358359if (auto *M = dyn_cast<DIModule>(this))360return M->getScope();361362assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&363"Unhandled type of scope.");364return nullptr;365}366367StringRef DIScope::getName() const {368if (auto *T = dyn_cast<DIType>(this))369return T->getName();370if (auto *SP = dyn_cast<DISubprogram>(this))371return SP->getName();372if (auto *NS = dyn_cast<DINamespace>(this))373return NS->getName();374if (auto *CB = dyn_cast<DICommonBlock>(this))375return CB->getName();376if (auto *M = dyn_cast<DIModule>(this))377return M->getName();378assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||379isa<DICompileUnit>(this)) &&380"Unhandled type of scope.");381return "";382}383384#ifndef NDEBUG385static bool isCanonical(const MDString *S) {386return !S || !S->getString().empty();387}388#endif389390dwarf::Tag GenericDINode::getTag() const { return (dwarf::Tag)SubclassData16; }391GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,392MDString *Header,393ArrayRef<Metadata *> DwarfOps,394StorageType Storage, bool ShouldCreate) {395unsigned Hash = 0;396if (Storage == Uniqued) {397GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);398if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))399return N;400if (!ShouldCreate)401return nullptr;402Hash = Key.getHash();403} else {404assert(ShouldCreate && "Expected non-uniqued nodes to always be created");405}406407// Use a nullptr for empty headers.408assert(isCanonical(Header) && "Expected canonical MDString");409Metadata *PreOps[] = {Header};410return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(411Context, Storage, Hash, Tag, PreOps, DwarfOps),412Storage, Context.pImpl->GenericDINodes);413}414415void GenericDINode::recalculateHash() {416setHash(GenericDINodeInfo::KeyTy::calculateHash(this));417}418419#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__420#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS421#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS) \422do { \423if (Storage == Uniqued) { \424if (auto *N = getUniqued(Context.pImpl->CLASS##s, \425CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS)))) \426return N; \427if (!ShouldCreate) \428return nullptr; \429} else { \430assert(ShouldCreate && \431"Expected non-uniqued nodes to always be created"); \432} \433} while (false)434#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS) \435return storeImpl(new (std::size(OPS), Storage) \436CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \437Storage, Context.pImpl->CLASS##s)438#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS) \439return storeImpl(new (0u, Storage) \440CLASS(Context, Storage, UNWRAP_ARGS(ARGS)), \441Storage, Context.pImpl->CLASS##s)442#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \443return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \444Storage, Context.pImpl->CLASS##s)445#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \446return storeImpl(new (NUM_OPS, Storage) \447CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \448Storage, Context.pImpl->CLASS##s)449450DISubrange::DISubrange(LLVMContext &C, StorageType Storage,451ArrayRef<Metadata *> Ops)452: DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}453DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,454StorageType Storage, bool ShouldCreate) {455auto *CountNode = ConstantAsMetadata::get(456ConstantInt::getSigned(Type::getInt64Ty(Context), Count));457auto *LB = ConstantAsMetadata::get(458ConstantInt::getSigned(Type::getInt64Ty(Context), Lo));459return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,460ShouldCreate);461}462463DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,464int64_t Lo, StorageType Storage,465bool ShouldCreate) {466auto *LB = ConstantAsMetadata::get(467ConstantInt::getSigned(Type::getInt64Ty(Context), Lo));468return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,469ShouldCreate);470}471472DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,473Metadata *LB, Metadata *UB, Metadata *Stride,474StorageType Storage, bool ShouldCreate) {475DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride));476Metadata *Ops[] = {CountNode, LB, UB, Stride};477DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DISubrange, Ops);478}479480DISubrange::BoundType DISubrange::getCount() const {481Metadata *CB = getRawCountNode();482if (!CB)483return BoundType();484485assert((isa<ConstantAsMetadata>(CB) || isa<DIVariable>(CB) ||486isa<DIExpression>(CB)) &&487"Count must be signed constant or DIVariable or DIExpression");488489if (auto *MD = dyn_cast<ConstantAsMetadata>(CB))490return BoundType(cast<ConstantInt>(MD->getValue()));491492if (auto *MD = dyn_cast<DIVariable>(CB))493return BoundType(MD);494495if (auto *MD = dyn_cast<DIExpression>(CB))496return BoundType(MD);497498return BoundType();499}500501DISubrange::BoundType DISubrange::getLowerBound() const {502Metadata *LB = getRawLowerBound();503if (!LB)504return BoundType();505506assert((isa<ConstantAsMetadata>(LB) || isa<DIVariable>(LB) ||507isa<DIExpression>(LB)) &&508"LowerBound must be signed constant or DIVariable or DIExpression");509510if (auto *MD = dyn_cast<ConstantAsMetadata>(LB))511return BoundType(cast<ConstantInt>(MD->getValue()));512513if (auto *MD = dyn_cast<DIVariable>(LB))514return BoundType(MD);515516if (auto *MD = dyn_cast<DIExpression>(LB))517return BoundType(MD);518519return BoundType();520}521522DISubrange::BoundType DISubrange::getUpperBound() const {523Metadata *UB = getRawUpperBound();524if (!UB)525return BoundType();526527assert((isa<ConstantAsMetadata>(UB) || isa<DIVariable>(UB) ||528isa<DIExpression>(UB)) &&529"UpperBound must be signed constant or DIVariable or DIExpression");530531if (auto *MD = dyn_cast<ConstantAsMetadata>(UB))532return BoundType(cast<ConstantInt>(MD->getValue()));533534if (auto *MD = dyn_cast<DIVariable>(UB))535return BoundType(MD);536537if (auto *MD = dyn_cast<DIExpression>(UB))538return BoundType(MD);539540return BoundType();541}542543DISubrange::BoundType DISubrange::getStride() const {544Metadata *ST = getRawStride();545if (!ST)546return BoundType();547548assert((isa<ConstantAsMetadata>(ST) || isa<DIVariable>(ST) ||549isa<DIExpression>(ST)) &&550"Stride must be signed constant or DIVariable or DIExpression");551552if (auto *MD = dyn_cast<ConstantAsMetadata>(ST))553return BoundType(cast<ConstantInt>(MD->getValue()));554555if (auto *MD = dyn_cast<DIVariable>(ST))556return BoundType(MD);557558if (auto *MD = dyn_cast<DIExpression>(ST))559return BoundType(MD);560561return BoundType();562}563DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,564ArrayRef<Metadata *> Ops)565: DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,566Ops) {}567568DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,569Metadata *CountNode, Metadata *LB,570Metadata *UB, Metadata *Stride,571StorageType Storage,572bool ShouldCreate) {573DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));574Metadata *Ops[] = {CountNode, LB, UB, Stride};575DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGenericSubrange, Ops);576}577578DIGenericSubrange::BoundType DIGenericSubrange::getCount() const {579Metadata *CB = getRawCountNode();580if (!CB)581return BoundType();582583assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&584"Count must be signed constant or DIVariable or DIExpression");585586if (auto *MD = dyn_cast<DIVariable>(CB))587return BoundType(MD);588589if (auto *MD = dyn_cast<DIExpression>(CB))590return BoundType(MD);591592return BoundType();593}594595DIGenericSubrange::BoundType DIGenericSubrange::getLowerBound() const {596Metadata *LB = getRawLowerBound();597if (!LB)598return BoundType();599600assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&601"LowerBound must be signed constant or DIVariable or DIExpression");602603if (auto *MD = dyn_cast<DIVariable>(LB))604return BoundType(MD);605606if (auto *MD = dyn_cast<DIExpression>(LB))607return BoundType(MD);608609return BoundType();610}611612DIGenericSubrange::BoundType DIGenericSubrange::getUpperBound() const {613Metadata *UB = getRawUpperBound();614if (!UB)615return BoundType();616617assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&618"UpperBound must be signed constant or DIVariable or DIExpression");619620if (auto *MD = dyn_cast<DIVariable>(UB))621return BoundType(MD);622623if (auto *MD = dyn_cast<DIExpression>(UB))624return BoundType(MD);625626return BoundType();627}628629DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {630Metadata *ST = getRawStride();631if (!ST)632return BoundType();633634assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&635"Stride must be signed constant or DIVariable or DIExpression");636637if (auto *MD = dyn_cast<DIVariable>(ST))638return BoundType(MD);639640if (auto *MD = dyn_cast<DIExpression>(ST))641return BoundType(MD);642643return BoundType();644}645646DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,647const APInt &Value, bool IsUnsigned,648ArrayRef<Metadata *> Ops)649: DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),650Value(Value) {651SubclassData32 = IsUnsigned;652}653DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,654bool IsUnsigned, MDString *Name,655StorageType Storage, bool ShouldCreate) {656assert(isCanonical(Name) && "Expected canonical MDString");657DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));658Metadata *Ops[] = {Name};659DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);660}661662DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,663MDString *Name, uint64_t SizeInBits,664uint32_t AlignInBits, unsigned Encoding,665DIFlags Flags, StorageType Storage,666bool ShouldCreate) {667assert(isCanonical(Name) && "Expected canonical MDString");668DEFINE_GETIMPL_LOOKUP(DIBasicType,669(Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));670Metadata *Ops[] = {nullptr, nullptr, Name};671DEFINE_GETIMPL_STORE(DIBasicType,672(Tag, SizeInBits, AlignInBits, Encoding, Flags), Ops);673}674675std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {676switch (getEncoding()) {677case dwarf::DW_ATE_signed:678case dwarf::DW_ATE_signed_char:679return Signedness::Signed;680case dwarf::DW_ATE_unsigned:681case dwarf::DW_ATE_unsigned_char:682return Signedness::Unsigned;683default:684return std::nullopt;685}686}687688DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,689MDString *Name, Metadata *StringLength,690Metadata *StringLengthExp,691Metadata *StringLocationExp,692uint64_t SizeInBits, uint32_t AlignInBits,693unsigned Encoding, StorageType Storage,694bool ShouldCreate) {695assert(isCanonical(Name) && "Expected canonical MDString");696DEFINE_GETIMPL_LOOKUP(DIStringType,697(Tag, Name, StringLength, StringLengthExp,698StringLocationExp, SizeInBits, AlignInBits, Encoding));699Metadata *Ops[] = {nullptr, nullptr, Name,700StringLength, StringLengthExp, StringLocationExp};701DEFINE_GETIMPL_STORE(DIStringType, (Tag, SizeInBits, AlignInBits, Encoding),702Ops);703}704DIType *DIDerivedType::getClassType() const {705assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);706return cast_or_null<DIType>(getExtraData());707}708uint32_t DIDerivedType::getVBPtrOffset() const {709assert(getTag() == dwarf::DW_TAG_inheritance);710if (auto *CM = cast_or_null<ConstantAsMetadata>(getExtraData()))711if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))712return static_cast<uint32_t>(CI->getZExtValue());713return 0;714}715Constant *DIDerivedType::getStorageOffsetInBits() const {716assert(getTag() == dwarf::DW_TAG_member && isBitField());717if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))718return C->getValue();719return nullptr;720}721722Constant *DIDerivedType::getConstant() const {723assert((getTag() == dwarf::DW_TAG_member ||724getTag() == dwarf::DW_TAG_variable) &&725isStaticMember());726if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))727return C->getValue();728return nullptr;729}730Constant *DIDerivedType::getDiscriminantValue() const {731assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());732if (auto *C = cast_or_null<ConstantAsMetadata>(getExtraData()))733return C->getValue();734return nullptr;735}736737DIDerivedType *DIDerivedType::getImpl(738LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,739unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,740uint32_t AlignInBits, uint64_t OffsetInBits,741std::optional<unsigned> DWARFAddressSpace,742std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData,743Metadata *Annotations, StorageType Storage, bool ShouldCreate) {744assert(isCanonical(Name) && "Expected canonical MDString");745DEFINE_GETIMPL_LOOKUP(DIDerivedType,746(Tag, Name, File, Line, Scope, BaseType, SizeInBits,747AlignInBits, OffsetInBits, DWARFAddressSpace,748PtrAuthData, Flags, ExtraData, Annotations));749Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData, Annotations};750DEFINE_GETIMPL_STORE(DIDerivedType,751(Tag, Line, SizeInBits, AlignInBits, OffsetInBits,752DWARFAddressSpace, PtrAuthData, Flags),753Ops);754}755756std::optional<DIDerivedType::PtrAuthData>757DIDerivedType::getPtrAuthData() const {758return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type759? std::optional<PtrAuthData>(PtrAuthData(SubclassData32))760: std::nullopt;761}762763DICompositeType *DICompositeType::getImpl(764LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,765unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,766uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,767Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,768Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,769Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,770Metadata *Rank, Metadata *Annotations, StorageType Storage,771bool ShouldCreate) {772assert(isCanonical(Name) && "Expected canonical MDString");773774// Keep this in sync with buildODRType.775DEFINE_GETIMPL_LOOKUP(DICompositeType,776(Tag, Name, File, Line, Scope, BaseType, SizeInBits,777AlignInBits, OffsetInBits, Flags, Elements,778RuntimeLang, VTableHolder, TemplateParams, Identifier,779Discriminator, DataLocation, Associated, Allocated,780Rank, Annotations));781Metadata *Ops[] = {File, Scope, Name, BaseType,782Elements, VTableHolder, TemplateParams, Identifier,783Discriminator, DataLocation, Associated, Allocated,784Rank, Annotations};785DEFINE_GETIMPL_STORE(786DICompositeType,787(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, Flags),788Ops);789}790791DICompositeType *DICompositeType::buildODRType(792LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,793Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,794uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,795DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,796Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,797Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,798Metadata *Rank, Metadata *Annotations) {799assert(!Identifier.getString().empty() && "Expected valid identifier");800if (!Context.isODRUniquingDebugTypes())801return nullptr;802auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];803if (!CT)804return CT = DICompositeType::getDistinct(805Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,806AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,807VTableHolder, TemplateParams, &Identifier, Discriminator,808DataLocation, Associated, Allocated, Rank, Annotations);809810if (CT->getTag() != Tag)811return nullptr;812813// Only mutate CT if it's a forward declaration and the new operands aren't.814assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");815if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))816return CT;817818// Mutate CT in place. Keep this in sync with getImpl.819CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,820Flags);821Metadata *Ops[] = {File, Scope, Name, BaseType,822Elements, VTableHolder, TemplateParams, &Identifier,823Discriminator, DataLocation, Associated, Allocated,824Rank, Annotations};825assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&826"Mismatched number of operands");827for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)828if (Ops[I] != CT->getOperand(I))829CT->setOperand(I, Ops[I]);830return CT;831}832833DICompositeType *DICompositeType::getODRType(834LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,835Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,836uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,837DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,838Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,839Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,840Metadata *Rank, Metadata *Annotations) {841assert(!Identifier.getString().empty() && "Expected valid identifier");842if (!Context.isODRUniquingDebugTypes())843return nullptr;844auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];845if (!CT) {846CT = DICompositeType::getDistinct(847Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,848AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,849TemplateParams, &Identifier, Discriminator, DataLocation, Associated,850Allocated, Rank, Annotations);851} else {852if (CT->getTag() != Tag)853return nullptr;854}855return CT;856}857858DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context,859MDString &Identifier) {860assert(!Identifier.getString().empty() && "Expected valid identifier");861if (!Context.isODRUniquingDebugTypes())862return nullptr;863return Context.pImpl->DITypeMap->lookup(&Identifier);864}865DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,866DIFlags Flags, uint8_t CC,867ArrayRef<Metadata *> Ops)868: DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,8690, 0, 0, Flags, Ops),870CC(CC) {}871872DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,873uint8_t CC, Metadata *TypeArray,874StorageType Storage,875bool ShouldCreate) {876DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray));877Metadata *Ops[] = {nullptr, nullptr, nullptr, TypeArray};878DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);879}880881DIFile::DIFile(LLVMContext &C, StorageType Storage,882std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,883ArrayRef<Metadata *> Ops)884: DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),885Checksum(CS), Source(Src) {}886887// FIXME: Implement this string-enum correspondence with a .def file and macros,888// so that the association is explicit rather than implied.889static const char *ChecksumKindName[DIFile::CSK_Last] = {890"CSK_MD5",891"CSK_SHA1",892"CSK_SHA256",893};894895StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {896assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");897// The first space was originally the CSK_None variant, which is now898// obsolete, but the space is still reserved in ChecksumKind, so we account899// for it here.900return ChecksumKindName[CSKind - 1];901}902903std::optional<DIFile::ChecksumKind>904DIFile::getChecksumKind(StringRef CSKindStr) {905return StringSwitch<std::optional<DIFile::ChecksumKind>>(CSKindStr)906.Case("CSK_MD5", DIFile::CSK_MD5)907.Case("CSK_SHA1", DIFile::CSK_SHA1)908.Case("CSK_SHA256", DIFile::CSK_SHA256)909.Default(std::nullopt);910}911912DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,913MDString *Directory,914std::optional<DIFile::ChecksumInfo<MDString *>> CS,915MDString *Source, StorageType Storage,916bool ShouldCreate) {917assert(isCanonical(Filename) && "Expected canonical MDString");918assert(isCanonical(Directory) && "Expected canonical MDString");919assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");920// We do *NOT* expect Source to be a canonical MDString because nullptr921// means none, so we need something to represent the empty file.922DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source));923Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source};924DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);925}926DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,927unsigned SourceLanguage, bool IsOptimized,928unsigned RuntimeVersion, unsigned EmissionKind,929uint64_t DWOId, bool SplitDebugInlining,930bool DebugInfoForProfiling, unsigned NameTableKind,931bool RangesBaseAddress, ArrayRef<Metadata *> Ops)932: DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),933SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion),934DWOId(DWOId), EmissionKind(EmissionKind), NameTableKind(NameTableKind),935IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),936DebugInfoForProfiling(DebugInfoForProfiling),937RangesBaseAddress(RangesBaseAddress) {938assert(Storage != Uniqued);939}940941DICompileUnit *DICompileUnit::getImpl(942LLVMContext &Context, unsigned SourceLanguage, Metadata *File,943MDString *Producer, bool IsOptimized, MDString *Flags,944unsigned RuntimeVersion, MDString *SplitDebugFilename,945unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,946Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,947uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,948unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,949MDString *SDK, StorageType Storage, bool ShouldCreate) {950assert(Storage != Uniqued && "Cannot unique DICompileUnit");951assert(isCanonical(Producer) && "Expected canonical MDString");952assert(isCanonical(Flags) && "Expected canonical MDString");953assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");954955Metadata *Ops[] = {File,956Producer,957Flags,958SplitDebugFilename,959EnumTypes,960RetainedTypes,961GlobalVariables,962ImportedEntities,963Macros,964SysRoot,965SDK};966return storeImpl(new (std::size(Ops), Storage) DICompileUnit(967Context, Storage, SourceLanguage, IsOptimized,968RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,969DebugInfoForProfiling, NameTableKind, RangesBaseAddress,970Ops),971Storage);972}973974std::optional<DICompileUnit::DebugEmissionKind>975DICompileUnit::getEmissionKind(StringRef Str) {976return StringSwitch<std::optional<DebugEmissionKind>>(Str)977.Case("NoDebug", NoDebug)978.Case("FullDebug", FullDebug)979.Case("LineTablesOnly", LineTablesOnly)980.Case("DebugDirectivesOnly", DebugDirectivesOnly)981.Default(std::nullopt);982}983984std::optional<DICompileUnit::DebugNameTableKind>985DICompileUnit::getNameTableKind(StringRef Str) {986return StringSwitch<std::optional<DebugNameTableKind>>(Str)987.Case("Default", DebugNameTableKind::Default)988.Case("GNU", DebugNameTableKind::GNU)989.Case("Apple", DebugNameTableKind::Apple)990.Case("None", DebugNameTableKind::None)991.Default(std::nullopt);992}993994const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) {995switch (EK) {996case NoDebug:997return "NoDebug";998case FullDebug:999return "FullDebug";1000case LineTablesOnly:1001return "LineTablesOnly";1002case DebugDirectivesOnly:1003return "DebugDirectivesOnly";1004}1005return nullptr;1006}10071008const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {1009switch (NTK) {1010case DebugNameTableKind::Default:1011return nullptr;1012case DebugNameTableKind::GNU:1013return "GNU";1014case DebugNameTableKind::Apple:1015return "Apple";1016case DebugNameTableKind::None:1017return "None";1018}1019return nullptr;1020}1021DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,1022unsigned ScopeLine, unsigned VirtualIndex,1023int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,1024ArrayRef<Metadata *> Ops)1025: DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),1026Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),1027ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {1028static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");1029}1030DISubprogram::DISPFlags1031DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,1032unsigned Virtuality, bool IsMainSubprogram) {1033// We're assuming virtuality is the low-order field.1034static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&1035int(SPFlagPureVirtual) ==1036int(dwarf::DW_VIRTUALITY_pure_virtual),1037"Virtuality constant mismatch");1038return static_cast<DISPFlags>(1039(Virtuality & SPFlagVirtuality) |1040(IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |1041(IsDefinition ? SPFlagDefinition : SPFlagZero) |1042(IsOptimized ? SPFlagOptimized : SPFlagZero) |1043(IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));1044}10451046DISubprogram *DILocalScope::getSubprogram() const {1047if (auto *Block = dyn_cast<DILexicalBlockBase>(this))1048return Block->getScope()->getSubprogram();1049return const_cast<DISubprogram *>(cast<DISubprogram>(this));1050}10511052DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {1053if (auto *File = dyn_cast<DILexicalBlockFile>(this))1054return File->getScope()->getNonLexicalBlockFileScope();1055return const_cast<DILocalScope *>(this);1056}10571058DILocalScope *DILocalScope::cloneScopeForSubprogram(1059DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx,1060DenseMap<const MDNode *, MDNode *> &Cache) {1061SmallVector<DIScope *> ScopeChain;1062DIScope *CachedResult = nullptr;10631064for (DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope);1065Scope = Scope->getScope()) {1066if (auto It = Cache.find(Scope); It != Cache.end()) {1067CachedResult = cast<DIScope>(It->second);1068break;1069}1070ScopeChain.push_back(Scope);1071}10721073// Recreate the scope chain, bottom-up, starting at the new subprogram (or a1074// cached result).1075DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;1076for (DIScope *ScopeToUpdate : reverse(ScopeChain)) {1077TempMDNode ClonedScope = ScopeToUpdate->clone();1078cast<DILexicalBlockBase>(*ClonedScope).replaceScope(UpdatedScope);1079UpdatedScope =1080cast<DIScope>(MDNode::replaceWithUniqued(std::move(ClonedScope)));1081Cache[ScopeToUpdate] = UpdatedScope;1082}10831084return cast<DILocalScope>(UpdatedScope);1085}10861087DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) {1088return StringSwitch<DISPFlags>(Flag)1089#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)1090#include "llvm/IR/DebugInfoFlags.def"1091.Default(SPFlagZero);1092}10931094StringRef DISubprogram::getFlagString(DISPFlags Flag) {1095switch (Flag) {1096// Appease a warning.1097case SPFlagVirtuality:1098return "";1099#define HANDLE_DISP_FLAG(ID, NAME) \1100case SPFlag##NAME: \1101return "DISPFlag" #NAME;1102#include "llvm/IR/DebugInfoFlags.def"1103}1104return "";1105}11061107DISubprogram::DISPFlags1108DISubprogram::splitFlags(DISPFlags Flags,1109SmallVectorImpl<DISPFlags> &SplitFlags) {1110// Multi-bit fields can require special handling. In our case, however, the1111// only multi-bit field is virtuality, and all its values happen to be1112// single-bit values, so the right behavior just falls out.1113#define HANDLE_DISP_FLAG(ID, NAME) \1114if (DISPFlags Bit = Flags & SPFlag##NAME) { \1115SplitFlags.push_back(Bit); \1116Flags &= ~Bit; \1117}1118#include "llvm/IR/DebugInfoFlags.def"1119return Flags;1120}11211122DISubprogram *DISubprogram::getImpl(1123LLVMContext &Context, Metadata *Scope, MDString *Name,1124MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,1125unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,1126int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,1127Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,1128Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,1129StorageType Storage, bool ShouldCreate) {1130assert(isCanonical(Name) && "Expected canonical MDString");1131assert(isCanonical(LinkageName) && "Expected canonical MDString");1132assert(isCanonical(TargetFuncName) && "Expected canonical MDString");1133DEFINE_GETIMPL_LOOKUP(DISubprogram,1134(Scope, Name, LinkageName, File, Line, Type, ScopeLine,1135ContainingType, VirtualIndex, ThisAdjustment, Flags,1136SPFlags, Unit, TemplateParams, Declaration,1137RetainedNodes, ThrownTypes, Annotations,1138TargetFuncName));1139SmallVector<Metadata *, 13> Ops = {1140File, Scope, Name, LinkageName,1141Type, Unit, Declaration, RetainedNodes,1142ContainingType, TemplateParams, ThrownTypes, Annotations,1143TargetFuncName};1144if (!TargetFuncName) {1145Ops.pop_back();1146if (!Annotations) {1147Ops.pop_back();1148if (!ThrownTypes) {1149Ops.pop_back();1150if (!TemplateParams) {1151Ops.pop_back();1152if (!ContainingType)1153Ops.pop_back();1154}1155}1156}1157}1158DEFINE_GETIMPL_STORE_N(1159DISubprogram,1160(Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags, SPFlags), Ops,1161Ops.size());1162}11631164bool DISubprogram::describes(const Function *F) const {1165assert(F && "Invalid function");1166return F->getSubprogram() == this;1167}1168DILexicalBlockBase::DILexicalBlockBase(LLVMContext &C, unsigned ID,1169StorageType Storage,1170ArrayRef<Metadata *> Ops)1171: DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}11721173DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,1174Metadata *File, unsigned Line,1175unsigned Column, StorageType Storage,1176bool ShouldCreate) {1177// Fixup column.1178adjustColumn(Column);11791180assert(Scope && "Expected scope");1181DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column));1182Metadata *Ops[] = {File, Scope};1183DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops);1184}11851186DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,1187Metadata *Scope, Metadata *File,1188unsigned Discriminator,1189StorageType Storage,1190bool ShouldCreate) {1191assert(Scope && "Expected scope");1192DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator));1193Metadata *Ops[] = {File, Scope};1194DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);1195}11961197DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,1198bool ExportSymbols, ArrayRef<Metadata *> Ops)1199: DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {1200SubclassData1 = ExportSymbols;1201}1202DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,1203MDString *Name, bool ExportSymbols,1204StorageType Storage, bool ShouldCreate) {1205assert(isCanonical(Name) && "Expected canonical MDString");1206DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, Name, ExportSymbols));1207// The nullptr is for DIScope's File operand. This should be refactored.1208Metadata *Ops[] = {nullptr, Scope, Name};1209DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);1210}12111212DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,1213unsigned LineNo, ArrayRef<Metadata *> Ops)1214: DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,1215Ops) {1216SubclassData32 = LineNo;1217}1218DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,1219Metadata *Decl, MDString *Name,1220Metadata *File, unsigned LineNo,1221StorageType Storage, bool ShouldCreate) {1222assert(isCanonical(Name) && "Expected canonical MDString");1223DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo));1224// The nullptr is for DIScope's File operand. This should be refactored.1225Metadata *Ops[] = {Scope, Decl, Name, File};1226DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops);1227}12281229DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,1230bool IsDecl, ArrayRef<Metadata *> Ops)1231: DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {1232SubclassData1 = IsDecl;1233SubclassData32 = LineNo;1234}1235DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,1236Metadata *Scope, MDString *Name,1237MDString *ConfigurationMacros,1238MDString *IncludePath, MDString *APINotesFile,1239unsigned LineNo, bool IsDecl, StorageType Storage,1240bool ShouldCreate) {1241assert(isCanonical(Name) && "Expected canonical MDString");1242DEFINE_GETIMPL_LOOKUP(DIModule, (File, Scope, Name, ConfigurationMacros,1243IncludePath, APINotesFile, LineNo, IsDecl));1244Metadata *Ops[] = {File, Scope, Name, ConfigurationMacros,1245IncludePath, APINotesFile};1246DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);1247}1248DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,1249StorageType Storage,1250bool IsDefault,1251ArrayRef<Metadata *> Ops)1252: DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,1253dwarf::DW_TAG_template_type_parameter, IsDefault,1254Ops) {}12551256DITemplateTypeParameter *1257DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,1258Metadata *Type, bool isDefault,1259StorageType Storage, bool ShouldCreate) {1260assert(isCanonical(Name) && "Expected canonical MDString");1261DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault));1262Metadata *Ops[] = {Name, Type};1263DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops);1264}12651266DITemplateValueParameter *DITemplateValueParameter::getImpl(1267LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,1268bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {1269assert(isCanonical(Name) && "Expected canonical MDString");1270DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter,1271(Tag, Name, Type, isDefault, Value));1272Metadata *Ops[] = {Name, Type, Value};1273DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops);1274}12751276DIGlobalVariable *1277DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,1278MDString *LinkageName, Metadata *File, unsigned Line,1279Metadata *Type, bool IsLocalToUnit, bool IsDefinition,1280Metadata *StaticDataMemberDeclaration,1281Metadata *TemplateParams, uint32_t AlignInBits,1282Metadata *Annotations, StorageType Storage,1283bool ShouldCreate) {1284assert(isCanonical(Name) && "Expected canonical MDString");1285assert(isCanonical(LinkageName) && "Expected canonical MDString");1286DEFINE_GETIMPL_LOOKUP(1287DIGlobalVariable,1288(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,1289StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations));1290Metadata *Ops[] = {Scope,1291Name,1292File,1293Type,1294Name,1295LinkageName,1296StaticDataMemberDeclaration,1297TemplateParams,1298Annotations};1299DEFINE_GETIMPL_STORE(DIGlobalVariable,1300(Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);1301}13021303DILocalVariable *1304DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,1305Metadata *File, unsigned Line, Metadata *Type,1306unsigned Arg, DIFlags Flags, uint32_t AlignInBits,1307Metadata *Annotations, StorageType Storage,1308bool ShouldCreate) {1309// 64K ought to be enough for any frontend.1310assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");13111312assert(Scope && "Expected scope");1313assert(isCanonical(Name) && "Expected canonical MDString");1314DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg,1315Flags, AlignInBits, Annotations));1316Metadata *Ops[] = {Scope, Name, File, Type, Annotations};1317DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);1318}13191320DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage,1321signed Line, ArrayRef<Metadata *> Ops,1322uint32_t AlignInBits)1323: DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {1324SubclassData32 = AlignInBits;1325}1326std::optional<uint64_t> DIVariable::getSizeInBits() const {1327// This is used by the Verifier so be mindful of broken types.1328const Metadata *RawType = getRawType();1329while (RawType) {1330// Try to get the size directly.1331if (auto *T = dyn_cast<DIType>(RawType))1332if (uint64_t Size = T->getSizeInBits())1333return Size;13341335if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {1336// Look at the base type.1337RawType = DT->getRawBaseType();1338continue;1339}13401341// Missing type or size.1342break;1343}13441345// Fail gracefully.1346return std::nullopt;1347}13481349DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,1350ArrayRef<Metadata *> Ops)1351: DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {1352SubclassData32 = Line;1353}1354DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,1355Metadata *File, unsigned Line, StorageType Storage,1356bool ShouldCreate) {1357assert(Scope && "Expected scope");1358assert(isCanonical(Name) && "Expected canonical MDString");1359DEFINE_GETIMPL_LOOKUP(DILabel, (Scope, Name, File, Line));1360Metadata *Ops[] = {Scope, Name, File};1361DEFINE_GETIMPL_STORE(DILabel, (Line), Ops);1362}13631364DIExpression *DIExpression::getImpl(LLVMContext &Context,1365ArrayRef<uint64_t> Elements,1366StorageType Storage, bool ShouldCreate) {1367DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));1368DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));1369}1370bool DIExpression::isEntryValue() const {1371if (auto singleLocElts = getSingleLocationExpressionElements()) {1372return singleLocElts->size() > 0 &&1373(*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value;1374}1375return false;1376}1377bool DIExpression::startsWithDeref() const {1378if (auto singleLocElts = getSingleLocationExpressionElements())1379return singleLocElts->size() > 0 &&1380(*singleLocElts)[0] == dwarf::DW_OP_deref;1381return false;1382}1383bool DIExpression::isDeref() const {1384if (auto singleLocElts = getSingleLocationExpressionElements())1385return singleLocElts->size() == 1 &&1386(*singleLocElts)[0] == dwarf::DW_OP_deref;1387return false;1388}13891390DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage,1391bool ShouldCreate) {1392// Uniqued DIAssignID are not supported as the instance address *is* the ID.1393assert(Storage != StorageType::Uniqued && "uniqued DIAssignID unsupported");1394return storeImpl(new (0u, Storage) DIAssignID(Context, Storage), Storage);1395}13961397unsigned DIExpression::ExprOperand::getSize() const {1398uint64_t Op = getOp();13991400if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)1401return 2;14021403switch (Op) {1404case dwarf::DW_OP_LLVM_convert:1405case dwarf::DW_OP_LLVM_fragment:1406case dwarf::DW_OP_LLVM_extract_bits_sext:1407case dwarf::DW_OP_LLVM_extract_bits_zext:1408case dwarf::DW_OP_bregx:1409return 3;1410case dwarf::DW_OP_constu:1411case dwarf::DW_OP_consts:1412case dwarf::DW_OP_deref_size:1413case dwarf::DW_OP_plus_uconst:1414case dwarf::DW_OP_LLVM_tag_offset:1415case dwarf::DW_OP_LLVM_entry_value:1416case dwarf::DW_OP_LLVM_arg:1417case dwarf::DW_OP_regx:1418return 2;1419default:1420return 1;1421}1422}14231424bool DIExpression::isValid() const {1425for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {1426// Check that there's space for the operand.1427if (I->get() + I->getSize() > E->get())1428return false;14291430uint64_t Op = I->getOp();1431if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||1432(Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31))1433return true;14341435// Check that the operand is valid.1436switch (Op) {1437default:1438return false;1439case dwarf::DW_OP_LLVM_fragment:1440// A fragment operator must appear at the end.1441return I->get() + I->getSize() == E->get();1442case dwarf::DW_OP_stack_value: {1443// Must be the last one or followed by a DW_OP_LLVM_fragment.1444if (I->get() + I->getSize() == E->get())1445break;1446auto J = I;1447if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)1448return false;1449break;1450}1451case dwarf::DW_OP_swap: {1452// Must be more than one implicit element on the stack.14531454// FIXME: A better way to implement this would be to add a local variable1455// that keeps track of the stack depth and introduce something like a1456// DW_LLVM_OP_implicit_location as a placeholder for the location this1457// DIExpression is attached to, or else pass the number of implicit stack1458// elements into isValid.1459if (getNumElements() == 1)1460return false;1461break;1462}1463case dwarf::DW_OP_LLVM_entry_value: {1464// An entry value operator must appear at the beginning or immediately1465// following `DW_OP_LLVM_arg 0`, and the number of operations it cover can1466// currently only be 1, because we support only entry values of a simple1467// register location. One reason for this is that we currently can't1468// calculate the size of the resulting DWARF block for other expressions.1469auto FirstOp = expr_op_begin();1470if (FirstOp->getOp() == dwarf::DW_OP_LLVM_arg && FirstOp->getArg(0) == 0)1471++FirstOp;1472return I->get() == FirstOp->get() && I->getArg(0) == 1;1473}1474case dwarf::DW_OP_LLVM_implicit_pointer:1475case dwarf::DW_OP_LLVM_convert:1476case dwarf::DW_OP_LLVM_arg:1477case dwarf::DW_OP_LLVM_tag_offset:1478case dwarf::DW_OP_LLVM_extract_bits_sext:1479case dwarf::DW_OP_LLVM_extract_bits_zext:1480case dwarf::DW_OP_constu:1481case dwarf::DW_OP_plus_uconst:1482case dwarf::DW_OP_plus:1483case dwarf::DW_OP_minus:1484case dwarf::DW_OP_mul:1485case dwarf::DW_OP_div:1486case dwarf::DW_OP_mod:1487case dwarf::DW_OP_or:1488case dwarf::DW_OP_and:1489case dwarf::DW_OP_xor:1490case dwarf::DW_OP_shl:1491case dwarf::DW_OP_shr:1492case dwarf::DW_OP_shra:1493case dwarf::DW_OP_deref:1494case dwarf::DW_OP_deref_size:1495case dwarf::DW_OP_xderef:1496case dwarf::DW_OP_lit0:1497case dwarf::DW_OP_not:1498case dwarf::DW_OP_dup:1499case dwarf::DW_OP_regx:1500case dwarf::DW_OP_bregx:1501case dwarf::DW_OP_push_object_address:1502case dwarf::DW_OP_over:1503case dwarf::DW_OP_consts:1504case dwarf::DW_OP_eq:1505case dwarf::DW_OP_ne:1506case dwarf::DW_OP_gt:1507case dwarf::DW_OP_ge:1508case dwarf::DW_OP_lt:1509case dwarf::DW_OP_le:1510break;1511}1512}1513return true;1514}15151516bool DIExpression::isImplicit() const {1517if (!isValid())1518return false;15191520if (getNumElements() == 0)1521return false;15221523for (const auto &It : expr_ops()) {1524switch (It.getOp()) {1525default:1526break;1527case dwarf::DW_OP_stack_value:1528return true;1529}1530}15311532return false;1533}15341535bool DIExpression::isComplex() const {1536if (!isValid())1537return false;15381539if (getNumElements() == 0)1540return false;15411542// If there are any elements other than fragment or tag_offset, then some1543// kind of complex computation occurs.1544for (const auto &It : expr_ops()) {1545switch (It.getOp()) {1546case dwarf::DW_OP_LLVM_tag_offset:1547case dwarf::DW_OP_LLVM_fragment:1548case dwarf::DW_OP_LLVM_arg:1549continue;1550default:1551return true;1552}1553}15541555return false;1556}15571558bool DIExpression::isSingleLocationExpression() const {1559if (!isValid())1560return false;15611562if (getNumElements() == 0)1563return true;15641565auto ExprOpBegin = expr_ops().begin();1566auto ExprOpEnd = expr_ops().end();1567if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg) {1568if (ExprOpBegin->getArg(0) != 0)1569return false;1570++ExprOpBegin;1571}15721573return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) {1574return Op.getOp() == dwarf::DW_OP_LLVM_arg;1575});1576}15771578std::optional<ArrayRef<uint64_t>>1579DIExpression::getSingleLocationExpressionElements() const {1580// Check for `isValid` covered by `isSingleLocationExpression`.1581if (!isSingleLocationExpression())1582return std::nullopt;15831584// An empty expression is already non-variadic.1585if (!getNumElements())1586return ArrayRef<uint64_t>();15871588// If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do1589// anything.1590if (getElements()[0] == dwarf::DW_OP_LLVM_arg)1591return getElements().drop_front(2);1592return getElements();1593}15941595const DIExpression *1596DIExpression::convertToUndefExpression(const DIExpression *Expr) {1597SmallVector<uint64_t, 3> UndefOps;1598if (auto FragmentInfo = Expr->getFragmentInfo()) {1599UndefOps.append({dwarf::DW_OP_LLVM_fragment, FragmentInfo->OffsetInBits,1600FragmentInfo->SizeInBits});1601}1602return DIExpression::get(Expr->getContext(), UndefOps);1603}16041605const DIExpression *1606DIExpression::convertToVariadicExpression(const DIExpression *Expr) {1607if (any_of(Expr->expr_ops(), [](auto ExprOp) {1608return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;1609}))1610return Expr;1611SmallVector<uint64_t> NewOps;1612NewOps.reserve(Expr->getNumElements() + 2);1613NewOps.append({dwarf::DW_OP_LLVM_arg, 0});1614NewOps.append(Expr->elements_begin(), Expr->elements_end());1615return DIExpression::get(Expr->getContext(), NewOps);1616}16171618std::optional<const DIExpression *>1619DIExpression::convertToNonVariadicExpression(const DIExpression *Expr) {1620if (!Expr)1621return std::nullopt;16221623if (auto Elts = Expr->getSingleLocationExpressionElements())1624return DIExpression::get(Expr->getContext(), *Elts);16251626return std::nullopt;1627}16281629void DIExpression::canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops,1630const DIExpression *Expr,1631bool IsIndirect) {1632// If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0`1633// to the existing expression ops.1634if (none_of(Expr->expr_ops(), [](auto ExprOp) {1635return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;1636}))1637Ops.append({dwarf::DW_OP_LLVM_arg, 0});1638// If Expr is not indirect, we only need to insert the expression elements and1639// we're done.1640if (!IsIndirect) {1641Ops.append(Expr->elements_begin(), Expr->elements_end());1642return;1643}1644// If Expr is indirect, insert the implied DW_OP_deref at the end of the1645// expression but before DW_OP_{stack_value, LLVM_fragment} if they are1646// present.1647for (auto Op : Expr->expr_ops()) {1648if (Op.getOp() == dwarf::DW_OP_stack_value ||1649Op.getOp() == dwarf::DW_OP_LLVM_fragment) {1650Ops.push_back(dwarf::DW_OP_deref);1651IsIndirect = false;1652}1653Op.appendToVector(Ops);1654}1655if (IsIndirect)1656Ops.push_back(dwarf::DW_OP_deref);1657}16581659bool DIExpression::isEqualExpression(const DIExpression *FirstExpr,1660bool FirstIndirect,1661const DIExpression *SecondExpr,1662bool SecondIndirect) {1663SmallVector<uint64_t> FirstOps;1664DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect);1665SmallVector<uint64_t> SecondOps;1666DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr,1667SecondIndirect);1668return FirstOps == SecondOps;1669}16701671std::optional<DIExpression::FragmentInfo>1672DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {1673for (auto I = Start; I != End; ++I)1674if (I->getOp() == dwarf::DW_OP_LLVM_fragment) {1675DIExpression::FragmentInfo Info = {I->getArg(1), I->getArg(0)};1676return Info;1677}1678return std::nullopt;1679}16801681std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) {1682std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();1683std::optional<uint64_t> ActiveBits = InitialActiveBits;1684for (auto Op : expr_ops()) {1685switch (Op.getOp()) {1686default:1687// We assume the worst case for anything we don't currently handle and1688// revert to the initial active bits.1689ActiveBits = InitialActiveBits;1690break;1691case dwarf::DW_OP_LLVM_extract_bits_zext:1692case dwarf::DW_OP_LLVM_extract_bits_sext: {1693// We can't handle an extract whose sign doesn't match that of the1694// variable.1695std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness();1696bool VarSigned = (VarSign == DIBasicType::Signedness::Signed);1697bool OpSigned = (Op.getOp() == dwarf::DW_OP_LLVM_extract_bits_sext);1698if (!VarSign || VarSigned != OpSigned) {1699ActiveBits = InitialActiveBits;1700break;1701}1702[[fallthrough]];1703}1704case dwarf::DW_OP_LLVM_fragment:1705// Extract or fragment narrows the active bits1706if (ActiveBits)1707ActiveBits = std::min(*ActiveBits, Op.getArg(1));1708else1709ActiveBits = Op.getArg(1);1710break;1711}1712}1713return ActiveBits;1714}17151716void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,1717int64_t Offset) {1718if (Offset > 0) {1719Ops.push_back(dwarf::DW_OP_plus_uconst);1720Ops.push_back(Offset);1721} else if (Offset < 0) {1722Ops.push_back(dwarf::DW_OP_constu);1723// Avoid UB when encountering LLONG_MIN, because in 2's complement1724// abs(LLONG_MIN) is LLONG_MAX+1.1725uint64_t AbsMinusOne = -(Offset+1);1726Ops.push_back(AbsMinusOne + 1);1727Ops.push_back(dwarf::DW_OP_minus);1728}1729}17301731bool DIExpression::extractIfOffset(int64_t &Offset) const {1732auto SingleLocEltsOpt = getSingleLocationExpressionElements();1733if (!SingleLocEltsOpt)1734return false;1735auto SingleLocElts = *SingleLocEltsOpt;17361737if (SingleLocElts.size() == 0) {1738Offset = 0;1739return true;1740}17411742if (SingleLocElts.size() == 2 &&1743SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {1744Offset = SingleLocElts[1];1745return true;1746}17471748if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {1749if (SingleLocElts[2] == dwarf::DW_OP_plus) {1750Offset = SingleLocElts[1];1751return true;1752}1753if (SingleLocElts[2] == dwarf::DW_OP_minus) {1754Offset = -SingleLocElts[1];1755return true;1756}1757}17581759return false;1760}17611762bool DIExpression::extractLeadingOffset(1763int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const {1764OffsetInBytes = 0;1765RemainingOps.clear();17661767auto SingleLocEltsOpt = getSingleLocationExpressionElements();1768if (!SingleLocEltsOpt)1769return false;17701771auto ExprOpEnd = expr_op_iterator(SingleLocEltsOpt->end());1772auto ExprOpIt = expr_op_iterator(SingleLocEltsOpt->begin());1773while (ExprOpIt != ExprOpEnd) {1774uint64_t Op = ExprOpIt->getOp();1775if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||1776Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment ||1777Op == dwarf::DW_OP_LLVM_extract_bits_zext ||1778Op == dwarf::DW_OP_LLVM_extract_bits_sext) {1779break;1780} else if (Op == dwarf::DW_OP_plus_uconst) {1781OffsetInBytes += ExprOpIt->getArg(0);1782} else if (Op == dwarf::DW_OP_constu) {1783uint64_t Value = ExprOpIt->getArg(0);1784++ExprOpIt;1785if (ExprOpIt->getOp() == dwarf::DW_OP_plus)1786OffsetInBytes += Value;1787else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)1788OffsetInBytes -= Value;1789else1790return false;1791} else {1792// Not a const plus/minus operation or deref.1793return false;1794}1795++ExprOpIt;1796}1797RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());1798return true;1799}18001801bool DIExpression::hasAllLocationOps(unsigned N) const {1802SmallDenseSet<uint64_t, 4> SeenOps;1803for (auto ExprOp : expr_ops())1804if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)1805SeenOps.insert(ExprOp.getArg(0));1806for (uint64_t Idx = 0; Idx < N; ++Idx)1807if (!SeenOps.contains(Idx))1808return false;1809return true;1810}18111812const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,1813unsigned &AddrClass) {1814// FIXME: This seems fragile. Nothing that verifies that these elements1815// actually map to ops and not operands.1816auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements();1817if (!SingleLocEltsOpt)1818return nullptr;1819auto SingleLocElts = *SingleLocEltsOpt;18201821const unsigned PatternSize = 4;1822if (SingleLocElts.size() >= PatternSize &&1823SingleLocElts[PatternSize - 4] == dwarf::DW_OP_constu &&1824SingleLocElts[PatternSize - 2] == dwarf::DW_OP_swap &&1825SingleLocElts[PatternSize - 1] == dwarf::DW_OP_xderef) {1826AddrClass = SingleLocElts[PatternSize - 3];18271828if (SingleLocElts.size() == PatternSize)1829return nullptr;1830return DIExpression::get(1831Expr->getContext(),1832ArrayRef(&*SingleLocElts.begin(), SingleLocElts.size() - PatternSize));1833}1834return Expr;1835}18361837DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,1838int64_t Offset) {1839SmallVector<uint64_t, 8> Ops;1840if (Flags & DIExpression::DerefBefore)1841Ops.push_back(dwarf::DW_OP_deref);18421843appendOffset(Ops, Offset);1844if (Flags & DIExpression::DerefAfter)1845Ops.push_back(dwarf::DW_OP_deref);18461847bool StackValue = Flags & DIExpression::StackValue;1848bool EntryValue = Flags & DIExpression::EntryValue;18491850return prependOpcodes(Expr, Ops, StackValue, EntryValue);1851}18521853DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,1854ArrayRef<uint64_t> Ops,1855unsigned ArgNo, bool StackValue) {1856assert(Expr && "Can't add ops to this expression");18571858// Handle non-variadic intrinsics by prepending the opcodes.1859if (!any_of(Expr->expr_ops(),1860[](auto Op) { return Op.getOp() == dwarf::DW_OP_LLVM_arg; })) {1861assert(ArgNo == 0 &&1862"Location Index must be 0 for a non-variadic expression.");1863SmallVector<uint64_t, 8> NewOps(Ops.begin(), Ops.end());1864return DIExpression::prependOpcodes(Expr, NewOps, StackValue);1865}18661867SmallVector<uint64_t, 8> NewOps;1868for (auto Op : Expr->expr_ops()) {1869// A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.1870if (StackValue) {1871if (Op.getOp() == dwarf::DW_OP_stack_value)1872StackValue = false;1873else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {1874NewOps.push_back(dwarf::DW_OP_stack_value);1875StackValue = false;1876}1877}1878Op.appendToVector(NewOps);1879if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo)1880NewOps.insert(NewOps.end(), Ops.begin(), Ops.end());1881}1882if (StackValue)1883NewOps.push_back(dwarf::DW_OP_stack_value);18841885return DIExpression::get(Expr->getContext(), NewOps);1886}18871888DIExpression *DIExpression::replaceArg(const DIExpression *Expr,1889uint64_t OldArg, uint64_t NewArg) {1890assert(Expr && "Can't replace args in this expression");18911892SmallVector<uint64_t, 8> NewOps;18931894for (auto Op : Expr->expr_ops()) {1895if (Op.getOp() != dwarf::DW_OP_LLVM_arg || Op.getArg(0) < OldArg) {1896Op.appendToVector(NewOps);1897continue;1898}1899NewOps.push_back(dwarf::DW_OP_LLVM_arg);1900uint64_t Arg = Op.getArg(0) == OldArg ? NewArg : Op.getArg(0);1901// OldArg has been deleted from the Op list, so decrement all indices1902// greater than it.1903if (Arg > OldArg)1904--Arg;1905NewOps.push_back(Arg);1906}1907return DIExpression::get(Expr->getContext(), NewOps);1908}19091910DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,1911SmallVectorImpl<uint64_t> &Ops,1912bool StackValue, bool EntryValue) {1913assert(Expr && "Can't prepend ops to this expression");19141915if (EntryValue) {1916Ops.push_back(dwarf::DW_OP_LLVM_entry_value);1917// Use a block size of 1 for the target register operand. The1918// DWARF backend currently cannot emit entry values with a block1919// size > 1.1920Ops.push_back(1);1921}19221923// If there are no ops to prepend, do not even add the DW_OP_stack_value.1924if (Ops.empty())1925StackValue = false;1926for (auto Op : Expr->expr_ops()) {1927// A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.1928if (StackValue) {1929if (Op.getOp() == dwarf::DW_OP_stack_value)1930StackValue = false;1931else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {1932Ops.push_back(dwarf::DW_OP_stack_value);1933StackValue = false;1934}1935}1936Op.appendToVector(Ops);1937}1938if (StackValue)1939Ops.push_back(dwarf::DW_OP_stack_value);1940return DIExpression::get(Expr->getContext(), Ops);1941}19421943DIExpression *DIExpression::append(const DIExpression *Expr,1944ArrayRef<uint64_t> Ops) {1945assert(Expr && !Ops.empty() && "Can't append ops to this expression");19461947// Copy Expr's current op list.1948SmallVector<uint64_t, 16> NewOps;1949for (auto Op : Expr->expr_ops()) {1950// Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.1951if (Op.getOp() == dwarf::DW_OP_stack_value ||1952Op.getOp() == dwarf::DW_OP_LLVM_fragment) {1953NewOps.append(Ops.begin(), Ops.end());19541955// Ensure that the new opcodes are only appended once.1956Ops = std::nullopt;1957}1958Op.appendToVector(NewOps);1959}1960NewOps.append(Ops.begin(), Ops.end());1961auto *result =1962DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath();1963assert(result->isValid() && "concatenated expression is not valid");1964return result;1965}19661967DIExpression *DIExpression::appendToStack(const DIExpression *Expr,1968ArrayRef<uint64_t> Ops) {1969assert(Expr && !Ops.empty() && "Can't append ops to this expression");1970assert(std::none_of(expr_op_iterator(Ops.begin()),1971expr_op_iterator(Ops.end()),1972[](auto Op) {1973return Op.getOp() == dwarf::DW_OP_stack_value ||1974Op.getOp() == dwarf::DW_OP_LLVM_fragment;1975}) &&1976"Can't append this op");19771978// Append a DW_OP_deref after Expr's current op list if it's non-empty and1979// has no DW_OP_stack_value.1980//1981// Match .* DW_OP_stack_value (DW_OP_LLVM_fragment A B)?.1982std::optional<FragmentInfo> FI = Expr->getFragmentInfo();1983unsigned DropUntilStackValue = FI ? 3 : 0;1984ArrayRef<uint64_t> ExprOpsBeforeFragment =1985Expr->getElements().drop_back(DropUntilStackValue);1986bool NeedsDeref = (Expr->getNumElements() > DropUntilStackValue) &&1987(ExprOpsBeforeFragment.back() != dwarf::DW_OP_stack_value);1988bool NeedsStackValue = NeedsDeref || ExprOpsBeforeFragment.empty();19891990// Append a DW_OP_deref after Expr's current op list if needed, then append1991// the new ops, and finally ensure that a single DW_OP_stack_value is present.1992SmallVector<uint64_t, 16> NewOps;1993if (NeedsDeref)1994NewOps.push_back(dwarf::DW_OP_deref);1995NewOps.append(Ops.begin(), Ops.end());1996if (NeedsStackValue)1997NewOps.push_back(dwarf::DW_OP_stack_value);1998return DIExpression::append(Expr, NewOps);1999}20002001std::optional<DIExpression *> DIExpression::createFragmentExpression(2002const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {2003SmallVector<uint64_t, 8> Ops;2004// Track whether it's safe to split the value at the top of the DWARF stack,2005// assuming that it'll be used as an implicit location value.2006bool CanSplitValue = true;2007// Track whether we need to add a fragment expression to the end of Expr.2008bool EmitFragment = true;2009// Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.2010if (Expr) {2011for (auto Op : Expr->expr_ops()) {2012switch (Op.getOp()) {2013default:2014break;2015case dwarf::DW_OP_shr:2016case dwarf::DW_OP_shra:2017case dwarf::DW_OP_shl:2018case dwarf::DW_OP_plus:2019case dwarf::DW_OP_plus_uconst:2020case dwarf::DW_OP_minus:2021// We can't safely split arithmetic or shift operations into multiple2022// fragments because we can't express carry-over between fragments.2023//2024// FIXME: We *could* preserve the lowest fragment of a constant offset2025// operation if the offset fits into SizeInBits.2026CanSplitValue = false;2027break;2028case dwarf::DW_OP_deref:2029case dwarf::DW_OP_deref_size:2030case dwarf::DW_OP_deref_type:2031case dwarf::DW_OP_xderef:2032case dwarf::DW_OP_xderef_size:2033case dwarf::DW_OP_xderef_type:2034// Preceeding arithmetic operations have been applied to compute an2035// address. It's okay to split the value loaded from that address.2036CanSplitValue = true;2037break;2038case dwarf::DW_OP_stack_value:2039// Bail if this expression computes a value that cannot be split.2040if (!CanSplitValue)2041return std::nullopt;2042break;2043case dwarf::DW_OP_LLVM_fragment: {2044// If we've decided we don't need a fragment then give up if we see that2045// there's already a fragment expression.2046// FIXME: We could probably do better here2047if (!EmitFragment)2048return std::nullopt;2049// Make the new offset point into the existing fragment.2050uint64_t FragmentOffsetInBits = Op.getArg(0);2051uint64_t FragmentSizeInBits = Op.getArg(1);2052(void)FragmentSizeInBits;2053assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&2054"new fragment outside of original fragment");2055OffsetInBits += FragmentOffsetInBits;2056continue;2057}2058case dwarf::DW_OP_LLVM_extract_bits_zext:2059case dwarf::DW_OP_LLVM_extract_bits_sext: {2060// If we're extracting bits from inside of the fragment that we're2061// creating then we don't have a fragment after all, and just need to2062// adjust the offset that we're extracting from.2063uint64_t ExtractOffsetInBits = Op.getArg(0);2064uint64_t ExtractSizeInBits = Op.getArg(1);2065if (ExtractOffsetInBits >= OffsetInBits &&2066ExtractOffsetInBits + ExtractSizeInBits <=2067OffsetInBits + SizeInBits) {2068Ops.push_back(Op.getOp());2069Ops.push_back(ExtractOffsetInBits - OffsetInBits);2070Ops.push_back(ExtractSizeInBits);2071EmitFragment = false;2072continue;2073}2074// If the extracted bits aren't fully contained within the fragment then2075// give up.2076// FIXME: We could probably do better here2077return std::nullopt;2078}2079}2080Op.appendToVector(Ops);2081}2082}2083assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");2084assert(Expr && "Unknown DIExpression");2085if (EmitFragment) {2086Ops.push_back(dwarf::DW_OP_LLVM_fragment);2087Ops.push_back(OffsetInBits);2088Ops.push_back(SizeInBits);2089}2090return DIExpression::get(Expr->getContext(), Ops);2091}20922093/// See declaration for more info.2094bool DIExpression::calculateFragmentIntersect(2095const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits,2096uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,2097int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag,2098std::optional<DIExpression::FragmentInfo> &Result,2099int64_t &OffsetFromLocationInBits) {21002101if (VarFrag.SizeInBits == 0)2102return false; // Variable size is unknown.21032104// Difference between mem slice start and the dbg location start.2105// 0 4 8 12 16 ...2106// | |2107// dbg location start2108// |2109// mem slice start2110// Here MemStartRelToDbgStartInBits is 8. Note this can be negative.2111int64_t MemStartRelToDbgStartInBits;2112{2113auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL);2114if (!MemOffsetFromDbgInBytes)2115return false; // Can't calculate difference in addresses.2116// Difference between the pointers.2117MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;2118// Add the difference of the offsets.2119MemStartRelToDbgStartInBits +=2120SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);2121}21222123// Out-param. Invert offset to get offset from debug location.2124OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;21252126// Check if the variable fragment sits outside (before) this memory slice.2127int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;2128if (MemEndRelToDbgStart < 0) {2129Result = {0, 0}; // Out-param.2130return true;2131}21322133// Work towards creating SliceOfVariable which is the bits of the variable2134// that the memory region covers.2135// 0 4 8 12 16 ...2136// | |2137// dbg location start with VarFrag offset=322138// |2139// mem slice start: SliceOfVariable offset=402140int64_t MemStartRelToVarInBits =2141MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;2142int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;2143// If the memory region starts before the debug location the fragment2144// offset would be negative, which we can't encode. Limit those to 0. This2145// is fine because those bits necessarily don't overlap with the existing2146// variable fragment.2147int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);2148int64_t MemFragSize =2149std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);2150DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart);21512152// Intersect the memory region fragment with the variable location fragment.2153DIExpression::FragmentInfo TrimmedSliceOfVariable =2154DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);2155if (TrimmedSliceOfVariable == VarFrag)2156Result = std::nullopt; // Out-param.2157else2158Result = TrimmedSliceOfVariable; // Out-param.2159return true;2160}21612162std::pair<DIExpression *, const ConstantInt *>2163DIExpression::constantFold(const ConstantInt *CI) {2164// Copy the APInt so we can modify it.2165APInt NewInt = CI->getValue();2166SmallVector<uint64_t, 8> Ops;21672168// Fold operators only at the beginning of the expression.2169bool First = true;2170bool Changed = false;2171for (auto Op : expr_ops()) {2172switch (Op.getOp()) {2173default:2174// We fold only the leading part of the expression; if we get to a part2175// that we're going to copy unchanged, and haven't done any folding,2176// then the entire expression is unchanged and we can return early.2177if (!Changed)2178return {this, CI};2179First = false;2180break;2181case dwarf::DW_OP_LLVM_convert:2182if (!First)2183break;2184Changed = true;2185if (Op.getArg(1) == dwarf::DW_ATE_signed)2186NewInt = NewInt.sextOrTrunc(Op.getArg(0));2187else {2188assert(Op.getArg(1) == dwarf::DW_ATE_unsigned && "Unexpected operand");2189NewInt = NewInt.zextOrTrunc(Op.getArg(0));2190}2191continue;2192}2193Op.appendToVector(Ops);2194}2195if (!Changed)2196return {this, CI};2197return {DIExpression::get(getContext(), Ops),2198ConstantInt::get(getContext(), NewInt)};2199}22002201uint64_t DIExpression::getNumLocationOperands() const {2202uint64_t Result = 0;2203for (auto ExprOp : expr_ops())2204if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)2205Result = std::max(Result, ExprOp.getArg(0) + 1);2206assert(hasAllLocationOps(Result) &&2207"Expression is missing one or more location operands.");2208return Result;2209}22102211std::optional<DIExpression::SignedOrUnsignedConstant>2212DIExpression::isConstant() const {22132214// Recognize signed and unsigned constants.2215// An signed constants can be represented as DW_OP_consts C DW_OP_stack_value2216// (DW_OP_LLVM_fragment of Len).2217// An unsigned constant can be represented as2218// DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len).22192220if ((getNumElements() != 2 && getNumElements() != 3 &&2221getNumElements() != 6) ||2222(getElement(0) != dwarf::DW_OP_consts &&2223getElement(0) != dwarf::DW_OP_constu))2224return std::nullopt;22252226if (getNumElements() == 2 && getElement(0) == dwarf::DW_OP_consts)2227return SignedOrUnsignedConstant::SignedConstant;22282229if ((getNumElements() == 3 && getElement(2) != dwarf::DW_OP_stack_value) ||2230(getNumElements() == 6 && (getElement(2) != dwarf::DW_OP_stack_value ||2231getElement(3) != dwarf::DW_OP_LLVM_fragment)))2232return std::nullopt;2233return getElement(0) == dwarf::DW_OP_constu2234? SignedOrUnsignedConstant::UnsignedConstant2235: SignedOrUnsignedConstant::SignedConstant;2236}22372238DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,2239bool Signed) {2240dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;2241DIExpression::ExtOps Ops{{dwarf::DW_OP_LLVM_convert, FromSize, TK,2242dwarf::DW_OP_LLVM_convert, ToSize, TK}};2243return Ops;2244}22452246DIExpression *DIExpression::appendExt(const DIExpression *Expr,2247unsigned FromSize, unsigned ToSize,2248bool Signed) {2249return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));2250}22512252DIGlobalVariableExpression *2253DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,2254Metadata *Expression, StorageType Storage,2255bool ShouldCreate) {2256DEFINE_GETIMPL_LOOKUP(DIGlobalVariableExpression, (Variable, Expression));2257Metadata *Ops[] = {Variable, Expression};2258DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops);2259}2260DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,2261unsigned Line, unsigned Attributes,2262ArrayRef<Metadata *> Ops)2263: DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),2264Line(Line), Attributes(Attributes) {}22652266DIObjCProperty *DIObjCProperty::getImpl(2267LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,2268MDString *GetterName, MDString *SetterName, unsigned Attributes,2269Metadata *Type, StorageType Storage, bool ShouldCreate) {2270assert(isCanonical(Name) && "Expected canonical MDString");2271assert(isCanonical(GetterName) && "Expected canonical MDString");2272assert(isCanonical(SetterName) && "Expected canonical MDString");2273DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,2274SetterName, Attributes, Type));2275Metadata *Ops[] = {Name, File, GetterName, SetterName, Type};2276DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);2277}22782279DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,2280Metadata *Scope, Metadata *Entity,2281Metadata *File, unsigned Line,2282MDString *Name, Metadata *Elements,2283StorageType Storage,2284bool ShouldCreate) {2285assert(isCanonical(Name) && "Expected canonical MDString");2286DEFINE_GETIMPL_LOOKUP(DIImportedEntity,2287(Tag, Scope, Entity, File, Line, Name, Elements));2288Metadata *Ops[] = {Scope, Entity, Name, File, Elements};2289DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);2290}22912292DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,2293MDString *Name, MDString *Value, StorageType Storage,2294bool ShouldCreate) {2295assert(isCanonical(Name) && "Expected canonical MDString");2296DEFINE_GETIMPL_LOOKUP(DIMacro, (MIType, Line, Name, Value));2297Metadata *Ops[] = {Name, Value};2298DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);2299}23002301DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,2302unsigned Line, Metadata *File,2303Metadata *Elements, StorageType Storage,2304bool ShouldCreate) {2305DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements));2306Metadata *Ops[] = {File, Elements};2307DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);2308}23092310DIArgList *DIArgList::get(LLVMContext &Context,2311ArrayRef<ValueAsMetadata *> Args) {2312auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));2313if (ExistingIt != Context.pImpl->DIArgLists.end())2314return *ExistingIt;2315DIArgList *NewArgList = new DIArgList(Context, Args);2316Context.pImpl->DIArgLists.insert(NewArgList);2317return NewArgList;2318}23192320void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {2321ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);2322assert((!New || isa<ValueAsMetadata>(New)) &&2323"DIArgList must be passed a ValueAsMetadata");2324untrack();2325// We need to update the set storage once the Args are updated since they2326// form the key to the DIArgLists store.2327getContext().pImpl->DIArgLists.erase(this);2328ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New);2329for (ValueAsMetadata *&VM : Args) {2330if (&VM == OldVMPtr) {2331if (NewVM)2332VM = NewVM;2333else2334VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));2335}2336}2337// We've changed the contents of this DIArgList, and the set storage may2338// already contain a DIArgList with our new set of args; if it does, then we2339// must RAUW this with the existing DIArgList, otherwise we simply insert this2340// back into the set storage.2341DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);2342if (ExistingArgList) {2343replaceAllUsesWith(ExistingArgList);2344// Clear this here so we don't try to untrack in the destructor.2345Args.clear();2346delete this;2347return;2348}2349getContext().pImpl->DIArgLists.insert(this);2350track();2351}2352void DIArgList::track() {2353for (ValueAsMetadata *&VAM : Args)2354if (VAM)2355MetadataTracking::track(&VAM, *VAM, *this);2356}2357void DIArgList::untrack() {2358for (ValueAsMetadata *&VAM : Args)2359if (VAM)2360MetadataTracking::untrack(&VAM, *VAM);2361}2362void DIArgList::dropAllReferences(bool Untrack) {2363if (Untrack)2364untrack();2365Args.clear();2366ReplaceableMetadataImpl::resolveAllUses(/* ResolveUsers */ false);2367}236823692370