brintos

brintos / llvm-project-archived public Read only

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