//===- DebugInfoMetadata.cpp - Implement debug info metadata --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the debug info Metadata classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DebugInfoMetadata.h"
#include "LLVMContextImpl.h"
#include "MetadataImpl.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"

#include <numeric>
#include <optional>
#include <tuple>

using namespace llvm;

namespace llvm {
// Use FS-AFDO discriminator.
cl::opt<bool> EnableFSDiscriminator(
    "enable-fs-discriminator", cl::Hidden,
    cl::desc("Enable adding flow sensitive discriminators"));

// When true, preserves line and column number by picking one of the merged
// location info in a deterministic manner to assist sample based PGO.
LLVM_ABI cl::opt<bool> PickMergedSourceLocations(
    "pick-merged-source-locations", cl::init(false), cl::Hidden,
    cl::desc("Preserve line and column number when merging locations."));
} // namespace llvm

uint32_t DIType::getAlignInBits() const {
  return (getTag() == dwarf::DW_TAG_LLVM_ptrauth_type ? 0 : SubclassData32);
}

const DIExpression::FragmentInfo DebugVariable::DefaultFragment = {
    std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::min()};

DebugVariable::DebugVariable(const DbgVariableRecord *DVR)
    : Variable(DVR->getVariable()),
      Fragment(DVR->getExpression()->getFragmentInfo()),
      InlinedAt(DVR->getDebugLoc().getInlinedAt()) {}

DebugVariableAggregate::DebugVariableAggregate(const DbgVariableRecord *DVR)
    : DebugVariable(DVR->getVariable(), std::nullopt,
                    DVR->getDebugLoc()->getInlinedAt()) {}

DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
                       unsigned Column, uint64_t AtomGroup, uint8_t AtomRank,
                       bool HasIRLayers, ArrayRef<Metadata *> MDs,
                       bool ImplicitCode)
    : MDNode(C, DILocationKind, Storage, MDs), AtomGroup(AtomGroup),
      AtomRank(AtomRank), HasIRLayers(HasIRLayers) {
  assert(AtomRank <= 7 && "AtomRank number should fit in 3 bits");
  assert(AtomGroup < (1ULL << 60) && "AtomGroup number should fit in 60 bits");
  if (AtomGroup)
    C.updateDILocationAtomGroupWaterline(AtomGroup + 1);

  assert(MDs.size() >= 1 && MDs.size() <= 3 &&
         "Expected a scope and optional inlined-at + irlayers");
  // Set line and column.
  assert(Column < (1u << 16) && "Expected 16-bit column");

  SubclassData32 = Line;
  SubclassData16 = Column;

  setImplicitCode(ImplicitCode);
}

static void adjustColumn(unsigned &Column) {
  // Set to unknown on overflow.  We only have 16 bits to play with here.
  if (Column >= (1u << 16))
    Column = 0;
}

DILocation *DILocation::getImpl(LLVMContext &Context, unsigned Line,
                                unsigned Column, Metadata *Scope,
                                Metadata *InlinedAt, bool ImplicitCode,
                                uint64_t AtomGroup, uint8_t AtomRank,
                                Metadata *IRLayers, StorageType Storage,
                                bool ShouldCreate) {
  // Fixup column.
  adjustColumn(Column);

  // Clamp rather than truncate, which would wrap into a different valid group.
  if (AtomGroup >= (1ULL << 60))
    AtomGroup = 0;

  if (Storage == Uniqued) {
    if (auto *N = getUniqued(
            Context.pImpl->DILocations,
            DILocationInfo::KeyTy(Line, Column, Scope, InlinedAt, ImplicitCode,
                                  AtomGroup, AtomRank, IRLayers)))
      return N;
    if (!ShouldCreate)
      return nullptr;
  } else {
    assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
  }

  SmallVector<Metadata *, 3> Ops;
  Ops.push_back(Scope);
  if (InlinedAt)
    Ops.push_back(InlinedAt);
  if (IRLayers)
    Ops.push_back(IRLayers);
  return storeImpl(new (Ops.size(), Storage) DILocation(
                       Context, Storage, Line, Column, AtomGroup, AtomRank,
                       /*HasIRLayers=*/IRLayers != nullptr, Ops, ImplicitCode),
                   Storage, Context.pImpl->DILocations);
}

DILayerLoc *DILayerLoc::getImpl(LLVMContext &Context, MDString *Kind,
                                Metadata *File, unsigned Line, unsigned Column,
                                StorageType Storage, bool ShouldCreate) {
  // Clamp an out-of-range column to 0 (the 16-bit SubclassData limit), as
  // DILocation::getImpl does; the ctor otherwise asserts and release builds
  // truncate.
  adjustColumn(Column);
  if (Storage == Uniqued) {
    if (auto *N = getUniqued(Context.pImpl->DILayerLocs,
                             DILayerLocInfo::KeyTy(Kind, File, Line, Column)))
      return N;
    if (!ShouldCreate)
      return nullptr;
  }
  Metadata *Ops[] = {Kind, File};
  return storeImpl(new (std::size(Ops), Storage)
                       DILayerLoc(Context, Storage, Line, Column, Ops),
                   Storage, Context.pImpl->DILayerLocs);
}

DILayerLocList *DILayerLocList::getImpl(LLVMContext &Context,
                                        ArrayRef<Metadata *> Layers,
                                        StorageType Storage,
                                        bool ShouldCreate) {
  unsigned Hash = 0;
  if (Storage == Uniqued) {
    DILayerLocListInfo::KeyTy Key(Layers);
    if (auto *N = getUniqued(Context.pImpl->DILayerLocLists, Key))
      return N;
    if (!ShouldCreate)
      return nullptr;
    Hash = Key.getHash();
  } else {
    assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
  }
  return storeImpl(new (Layers.size(), Storage)
                       DILayerLocList(Context, Storage, Hash, Layers),
                   Storage, Context.pImpl->DILayerLocLists);
}

void DILayerLocList::recalculateHash() {
  setHash(DILayerLocListInfo::KeyTy::calculateHash(this));
}

DILocation *DILocation::getMergedLocations(ArrayRef<DILocation *> Locs) {
  if (Locs.empty())
    return nullptr;
  if (Locs.size() == 1)
    return Locs[0];
  auto *Merged = Locs[0];
  for (DILocation *L : llvm::drop_begin(Locs)) {
    Merged = getMergedLocation(Merged, L);
    if (Merged == nullptr)
      break;
  }
  return Merged;
}

static DILexicalBlockBase *cloneAndReplaceParentScope(DILexicalBlockBase *LBB,
                                                      DIScope *NewParent) {
  TempMDNode ClonedScope = LBB->clone();
  cast<DILexicalBlockBase>(*ClonedScope).replaceScope(NewParent);
  return cast<DILexicalBlockBase>(
      MDNode::replaceWithUniqued(std::move(ClonedScope)));
}

using LineColumn = std::pair<unsigned /* Line */, unsigned /* Column */>;

/// Returns the location of DILocalScope, if present, or a default value.
static LineColumn getLocalScopeLocationOr(DIScope *S, LineColumn Default) {
  assert(isa<DILocalScope>(S) && "Expected DILocalScope.");

  if (isa<DILexicalBlockFile>(S))
    return Default;
  if (auto *LB = dyn_cast<DILexicalBlock>(S))
    return {LB->getLine(), LB->getColumn()};
  if (auto *SP = dyn_cast<DISubprogram>(S))
    return {SP->getLine(), 0u};

  llvm_unreachable("Unhandled type of DILocalScope.");
}

// Returns the nearest matching scope inside a subprogram.
template <typename MatcherT>
static std::pair<DIScope *, LineColumn>
getNearestMatchingScope(const DILocation *L1, const DILocation *L2) {
  MatcherT Matcher;

  DIScope *S1 = L1->getScope();
  DIScope *S2 = L2->getScope();

  LineColumn Loc1(L1->getLine(), L1->getColumn());
  for (; S1; S1 = S1->getScope()) {
    Loc1 = getLocalScopeLocationOr(S1, Loc1);
    Matcher.insert(S1, Loc1);
    if (isa<DISubprogram>(S1))
      break;
  }

  LineColumn Loc2(L2->getLine(), L2->getColumn());
  for (; S2; S2 = S2->getScope()) {
    Loc2 = getLocalScopeLocationOr(S2, Loc2);

    if (DIScope *S = Matcher.match(S2, Loc2))
      return std::make_pair(S, Loc2);

    if (isa<DISubprogram>(S2))
      break;
  }
  return std::make_pair(nullptr, LineColumn(L2->getLine(), L2->getColumn()));
}

// Matches equal scopes.
struct EqualScopesMatcher {
  SmallPtrSet<DIScope *, 8> Scopes;

  void insert(DIScope *S, LineColumn Loc) { Scopes.insert(S); }

  DIScope *match(DIScope *S, LineColumn Loc) {
    return Scopes.contains(S) ? S : nullptr;
  }
};

// Matches scopes with the same location.
struct ScopeLocationsMatcher {
  SmallMapVector<std::pair<DIFile *, LineColumn>, SmallSetVector<DIScope *, 8>,
                 8>
      Scopes;

  void insert(DIScope *S, LineColumn Loc) {
    Scopes[{S->getFile(), Loc}].insert(S);
  }

  DIScope *match(DIScope *S, LineColumn Loc) {
    auto ScopesAtLoc = Scopes.find({S->getFile(), Loc});
    // No scope found with the given location.
    if (ScopesAtLoc == Scopes.end())
      return nullptr;

    // Prefer S over other scopes with the same location.
    if (ScopesAtLoc->second.contains(S))
      return S;

    if (!ScopesAtLoc->second.empty())
      return *ScopesAtLoc->second.begin();

    llvm_unreachable("Scopes must not have empty entries.");
  }
};

// Returns a uniqued DILayerLocList holding the intersection of LocA's and
// LocB's layer sets, or null if either has no layers or they share none.
// Entries keep LocA's relative order: LLVM assigns no meaning to layer order,
// but it is part of a list's identity and visible to consumers, so preserve
// rather than sort.
static Metadata *mergeIRLayers(LLVMContext &C, const DILocation *LocA,
                               const DILocation *LocB) {
  DILayerLocList *LA = LocA->getIRLayers();
  DILayerLocList *LB = LocB->getIRLayers();
  if (!LA || !LB)
    return nullptr;
  // Entries match on their fields rather than by pointer: DILayerLocs are
  // uniqued, but `distinct` ones are legal and must not look disjoint. Keying
  // on the fields also keeps the intersection linear in the two list lengths.
  using LayerKey = std::tuple<Metadata *, Metadata *, unsigned, unsigned>;
  auto keyOf = [](const DILayerLoc *L) {
    return LayerKey(L->getRawKind(), L->getRawFile(), L->getLine(),
                    L->getColumn());
  };
  SmallDenseSet<LayerKey, 2> BLayers;
  for (const MDOperand &Op : LB->layers())
    BLayers.insert(keyOf(cast<DILayerLoc>(Op.get())));
  SmallVector<Metadata *, 2> Keep;
  for (const MDOperand &Op : LA->layers()) {
    auto *L = cast<DILayerLoc>(Op.get());
    if (BLayers.contains(keyOf(L)))
      Keep.push_back(L);
  }
  if (Keep.empty())
    return nullptr;
  return DILayerLocList::get(C, Keep);
}

DILocation *DILocation::getMergedLocation(DILocation *LocA, DILocation *LocB) {
  if (LocA == LocB)
    return LocA;

  // For some use cases (SamplePGO), it is important to retain distinct source
  // locations. When this flag is set, we choose arbitrarily between A and B,
  // rather than computing a merged location using line 0, which is typically
  // not useful for PGO. If one of them is null, then try to return one which is
  // valid.
  if (PickMergedSourceLocations) {
    if (!LocA || !LocB)
      return LocA ? LocA : LocB;

    auto A = std::make_tuple(LocA->getLine(), LocA->getColumn(),
                             LocA->getDiscriminator(), LocA->getFilename(),
                             LocA->getDirectory());
    auto B = std::make_tuple(LocB->getLine(), LocB->getColumn(),
                             LocB->getDiscriminator(), LocB->getFilename(),
                             LocB->getDirectory());
    return A < B ? LocA : LocB;
  }

  if (!LocA || !LocB)
    return nullptr;

  LLVMContext &C = LocA->getContext();

  using LocVec = SmallVector<const DILocation *>;
  LocVec ALocs;
  LocVec BLocs;
  SmallDenseMap<std::pair<const DISubprogram *, const DILocation *>, unsigned,
                4>
      ALookup;

  // Walk through LocA and its inlined-at locations, populate them in ALocs and
  // save the index for the subprogram and inlined-at pair, which we use to find
  // a matching starting location in LocB's chain.
  for (auto [L, I] = std::make_pair(LocA, 0U); L; L = L->getInlinedAt(), I++) {
    ALocs.push_back(L);
    auto Res = ALookup.try_emplace(
        {L->getScope()->getSubprogram(), L->getInlinedAt()}, I);
    assert(Res.second && "Multiple <SP, InlinedAt> pairs in a location chain?");
    (void)Res;
  }

  LocVec::reverse_iterator ARIt = ALocs.rend();
  LocVec::reverse_iterator BRIt = BLocs.rend();

  // Populate BLocs and look for a matching starting location, the first
  // location with the same subprogram and inlined-at location as in LocA's
  // chain. Since the two locations have the same inlined-at location we do
  // not need to look at those parts of the chains.
  for (auto [L, I] = std::make_pair(LocB, 0U); L; L = L->getInlinedAt(), I++) {
    BLocs.push_back(L);

    if (ARIt != ALocs.rend())
      // We have already found a matching starting location.
      continue;

    auto IT = ALookup.find({L->getScope()->getSubprogram(), L->getInlinedAt()});
    if (IT == ALookup.end())
      continue;

    // The + 1 is to account for the &*rev_it = &(it - 1) relationship.
    ARIt = LocVec::reverse_iterator(ALocs.begin() + IT->second + 1);
    BRIt = LocVec::reverse_iterator(BLocs.begin() + I + 1);

    // If we have found a matching starting location we do not need to add more
    // locations to BLocs, since we will only look at location pairs preceding
    // the matching starting location, and adding more elements to BLocs could
    // invalidate the iterator that we initialized here.
    break;
  }

  // Merge the two locations if possible, using the supplied
  // inlined-at location for the created location.
  auto *LocAIA = LocA->getInlinedAt();
  auto *LocBIA = LocB->getInlinedAt();
  auto MergeLocPair = [&C, LocAIA,
                       LocBIA](const DILocation *L1, const DILocation *L2,
                               DILocation *InlinedAt) -> DILocation * {
    if (L1 == L2)
      return DILocation::get(C, L1->getLine(), L1->getColumn(), L1->getScope(),
                             InlinedAt, L1->isImplicitCode(),
                             L1->getAtomGroup(), L1->getAtomRank(),
                             L1->getRawIRLayers());

    // If the locations originate from different subprograms we can't produce
    // a common location.
    if (L1->getScope()->getSubprogram() != L2->getScope()->getSubprogram())
      return nullptr;

    // Each merged location keeps the intersection of the two inputs'
    // intermediate-IR layer sets, so a layer common to both survives.
    Metadata *MergedLayers = mergeIRLayers(C, L1, L2);

    // Find nearest common scope inside subprogram.
    DIScope *Scope = getNearestMatchingScope<EqualScopesMatcher>(L1, L2).first;
    assert(Scope && "No common scope in the same subprogram?");

    // Try using the nearest scope with common location if files are different.
    if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile()) {
      auto [CommonLocScope, CommonLoc] =
          getNearestMatchingScope<ScopeLocationsMatcher>(L1, L2);

      // If CommonLocScope is a DILexicalBlockBase, clone it and locate
      // a new scope inside the nearest common scope to preserve
      // lexical blocks structure.
      if (auto *LBB = dyn_cast<DILexicalBlockBase>(CommonLocScope);
          LBB && LBB != Scope)
        CommonLocScope = cloneAndReplaceParentScope(LBB, Scope);

      Scope = CommonLocScope;

      // If files are still different, assume that L1 and L2 were "included"
      // from CommonLoc. Use it as merged location.
      if (Scope->getFile() != L1->getFile() || L1->getFile() != L2->getFile())
        return DILocation::get(C, CommonLoc.first, CommonLoc.second,
                               CommonLocScope, InlinedAt,
                               /*ImplicitCode=*/false, /*AtomGroup=*/0,
                               /*AtomRank=*/0, MergedLayers);
    }

    bool SameLine = L1->getLine() == L2->getLine();
    bool SameCol = L1->getColumn() == L2->getColumn();
    unsigned Line = SameLine ? L1->getLine() : 0;
    unsigned Col = SameLine && SameCol ? L1->getColumn() : 0;
    bool IsImplicitCode = L1->isImplicitCode() && L2->isImplicitCode();

    // Discard source location atom if the line becomes 0. And there's nothing
    // further to do if neither location has an atom number.
    if (!SameLine || !(L1->getAtomGroup() || L2->getAtomGroup()))
      return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
                             /*AtomGroup*/ 0, /*AtomRank*/ 0, MergedLayers);

    uint64_t Group = 0;
    uint64_t Rank = 0;
    // If we're preserving the same matching inlined-at field we can
    // preserve the atom.
    if (LocBIA == LocAIA && InlinedAt == LocBIA) {
      // Deterministically keep the lowest non-zero ranking atom group
      // number.
      // FIXME: It would be nice if we could track that an instruction
      // belongs to two source atoms.
      bool UseL1Atom = [L1, L2]() {
        if (L1->getAtomRank() == L2->getAtomRank()) {
          // Arbitrarily choose the lowest non-zero group number.
          if (!L1->getAtomGroup() || !L2->getAtomGroup())
            return !L2->getAtomGroup();
          return L1->getAtomGroup() < L2->getAtomGroup();
        }
        // Choose the lowest non-zero rank.
        if (!L1->getAtomRank() || !L2->getAtomRank())
          return !L2->getAtomRank();
        return L1->getAtomRank() < L2->getAtomRank();
      }();
      Group = UseL1Atom ? L1->getAtomGroup() : L2->getAtomGroup();
      Rank = UseL1Atom ? L1->getAtomRank() : L2->getAtomRank();
    } else {
      // If either instruction is part of a source atom, reassign it a new
      // atom group. This essentially regresses to non-key-instructions
      // behaviour (now that it's the only instruction in its group it'll
      // probably get is_stmt applied).
      Group = C.incNextDILocationAtomGroup();
      Rank = 1;
    }
    return DILocation::get(C, Line, Col, Scope, InlinedAt, IsImplicitCode,
                           Group, Rank, MergedLayers);
  };

  DILocation *Result = ARIt != ALocs.rend() ? (*ARIt)->getInlinedAt() : nullptr;

  // If we have found a common starting location, walk up the inlined-at chains
  // and try to produce common locations.
  for (; ARIt != ALocs.rend() && BRIt != BLocs.rend(); ++ARIt, ++BRIt) {
    DILocation *Tmp = MergeLocPair(*ARIt, *BRIt, Result);

    if (!Tmp)
      // We have walked up to a point in the chains where the two locations
      // are irreconsilable. At this point Result contains the nearest common
      // location in the inlined-at chains of LocA and LocB, so we break here.
      break;

    Result = Tmp;
  }

  if (Result)
    return Result;

  // We ended up with LocA and LocB as irreconsilable locations. Produce a
  // location at 0:0 with one of the locations' scope. The function has
  // historically picked A's scope, and a nullptr inlined-at location, so that
  // behavior is mimicked here but I am not sure if this is always the correct
  // way to handle this.
  // Key Instructions: it's fine to drop atom group and rank here, as line 0
  // is a nonsensical is_stmt location.
  return DILocation::get(C, 0, 0, LocA->getScope(), nullptr, false,
                         /*AtomGroup*/ 0, /*AtomRank*/ 0);
}

std::optional<unsigned>
DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
  std::array<unsigned, 3> Components = {BD, DF, CI};
  uint64_t RemainingWork = 0U;
  // We use RemainingWork to figure out if we have no remaining components to
  // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
  // encode anything for the latter 2.
  // Since any of the input components is at most 32 bits, their sum will be
  // less than 34 bits, and thus RemainingWork won't overflow.
  RemainingWork =
      std::accumulate(Components.begin(), Components.end(), RemainingWork);

  int I = 0;
  unsigned Ret = 0;
  unsigned NextBitInsertionIndex = 0;
  while (RemainingWork > 0) {
    unsigned C = Components[I++];
    RemainingWork -= C;
    unsigned EC = encodeComponent(C);
    Ret |= (EC << NextBitInsertionIndex);
    NextBitInsertionIndex += encodingBits(C);
  }

  // Encoding may be unsuccessful because of overflow. We determine success by
  // checking equivalence of components before & after encoding. Alternatively,
  // we could determine Success during encoding, but the current alternative is
  // simpler.
  unsigned TBD, TDF, TCI = 0;
  decodeDiscriminator(Ret, TBD, TDF, TCI);
  if (TBD == BD && TDF == DF && TCI == CI)
    return Ret;
  return std::nullopt;
}

void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
                                     unsigned &CI) {
  BD = getUnsignedFromPrefixEncoding(D);
  DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D));
  CI = getUnsignedFromPrefixEncoding(
      getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
}
dwarf::Tag DINode::getTag() const { return (dwarf::Tag)SubclassData16; }

DINode::DIFlags DINode::getFlag(StringRef Flag) {
  return StringSwitch<DIFlags>(Flag)
#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)
#include "llvm/IR/DebugInfoFlags.def"
      .Default(DINode::FlagZero);
}

StringRef DINode::getFlagString(DIFlags Flag) {
  switch (Flag) {
#define HANDLE_DI_FLAG(ID, NAME)                                               \
  case Flag##NAME:                                                             \
    return "DIFlag" #NAME;
#include "llvm/IR/DebugInfoFlags.def"
  }
  return "";
}

DINode::DIFlags DINode::splitFlags(DIFlags Flags,
                                   SmallVectorImpl<DIFlags> &SplitFlags) {
  // Flags that are packed together need to be specially handled, so
  // that, for example, we emit "DIFlagPublic" and not
  // "DIFlagPrivate | DIFlagProtected".
  if (DIFlags A = Flags & FlagAccessibility) {
    if (A == FlagPrivate)
      SplitFlags.push_back(FlagPrivate);
    else if (A == FlagProtected)
      SplitFlags.push_back(FlagProtected);
    else
      SplitFlags.push_back(FlagPublic);
    Flags &= ~A;
  }
  if (DIFlags R = Flags & FlagPtrToMemberRep) {
    if (R == FlagSingleInheritance)
      SplitFlags.push_back(FlagSingleInheritance);
    else if (R == FlagMultipleInheritance)
      SplitFlags.push_back(FlagMultipleInheritance);
    else
      SplitFlags.push_back(FlagVirtualInheritance);
    Flags &= ~R;
  }
  if ((Flags & FlagIndirectVirtualBase) == FlagIndirectVirtualBase) {
    Flags &= ~FlagIndirectVirtualBase;
    SplitFlags.push_back(FlagIndirectVirtualBase);
  }

#define HANDLE_DI_FLAG(ID, NAME)                                               \
  if (DIFlags Bit = Flags & Flag##NAME) {                                      \
    SplitFlags.push_back(Bit);                                                 \
    Flags &= ~Bit;                                                             \
  }
#include "llvm/IR/DebugInfoFlags.def"
  return Flags;
}

DIScope *DIScope::getScope() const {
  if (auto *T = dyn_cast<DIType>(this))
    return T->getScope();

  if (auto *SP = dyn_cast<DISubprogram>(this))
    return SP->getScope();

  if (auto *LB = dyn_cast<DILexicalBlockBase>(this))
    return LB->getScope();

  if (auto *NS = dyn_cast<DINamespace>(this))
    return NS->getScope();

  if (auto *CB = dyn_cast<DICommonBlock>(this))
    return CB->getScope();

  if (auto *M = dyn_cast<DIModule>(this))
    return M->getScope();

  assert((isa<DIFile>(this) || isa<DICompileUnit>(this)) &&
         "Unhandled type of scope.");
  return nullptr;
}

StringRef DIScope::getName() const {
  if (auto *T = dyn_cast<DIType>(this))
    return T->getName();
  if (auto *SP = dyn_cast<DISubprogram>(this))
    return SP->getName();
  if (auto *NS = dyn_cast<DINamespace>(this))
    return NS->getName();
  if (auto *CB = dyn_cast<DICommonBlock>(this))
    return CB->getName();
  if (auto *M = dyn_cast<DIModule>(this))
    return M->getName();
  assert((isa<DILexicalBlockBase>(this) || isa<DIFile>(this) ||
          isa<DICompileUnit>(this)) &&
         "Unhandled type of scope.");
  return "";
}

#ifndef NDEBUG
static bool isCanonical(const MDString *S) {
  return !S || !S->getString().empty();
}
#endif

dwarf::Tag GenericDINode::getTag() const { return (dwarf::Tag)SubclassData16; }
GenericDINode *GenericDINode::getImpl(LLVMContext &Context, unsigned Tag,
                                      MDString *Header,
                                      ArrayRef<Metadata *> DwarfOps,
                                      StorageType Storage, bool ShouldCreate) {
  unsigned Hash = 0;
  if (Storage == Uniqued) {
    GenericDINodeInfo::KeyTy Key(Tag, Header, DwarfOps);
    if (auto *N = getUniqued(Context.pImpl->GenericDINodes, Key))
      return N;
    if (!ShouldCreate)
      return nullptr;
    Hash = Key.getHash();
  } else {
    assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
  }

  // Use a nullptr for empty headers.
  assert(isCanonical(Header) && "Expected canonical MDString");
  Metadata *PreOps[] = {Header};
  return storeImpl(new (DwarfOps.size() + 1, Storage) GenericDINode(
                       Context, Storage, Hash, Tag, PreOps, DwarfOps),
                   Storage, Context.pImpl->GenericDINodes);
}

void GenericDINode::recalculateHash() {
  setHash(GenericDINodeInfo::KeyTy::calculateHash(this));
}

#define UNWRAP_ARGS_IMPL(...) __VA_ARGS__
#define UNWRAP_ARGS(ARGS) UNWRAP_ARGS_IMPL ARGS
#define DEFINE_GETIMPL_LOOKUP(CLASS, ARGS)                                     \
  do {                                                                         \
    if (Storage == Uniqued) {                                                  \
      if (auto *N = getUniqued(Context.pImpl->CLASS##s,                        \
                               CLASS##Info::KeyTy(UNWRAP_ARGS(ARGS))))         \
        return N;                                                              \
      if (!ShouldCreate)                                                       \
        return nullptr;                                                        \
    } else {                                                                   \
      assert(ShouldCreate &&                                                   \
             "Expected non-uniqued nodes to always be created");               \
    }                                                                          \
  } while (false)
#define DEFINE_GETIMPL_STORE(CLASS, ARGS, OPS)                                 \
  return storeImpl(new (std::size(OPS), Storage)                               \
                       CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS),        \
                   Storage, Context.pImpl->CLASS##s)
#define DEFINE_GETIMPL_STORE_NO_OPS(CLASS, ARGS)                               \
  return storeImpl(new (0u, Storage)                                           \
                       CLASS(Context, Storage, UNWRAP_ARGS(ARGS)),             \
                   Storage, Context.pImpl->CLASS##s)
#define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS)                   \
  return storeImpl(new (std::size(OPS), Storage) CLASS(Context, Storage, OPS), \
                   Storage, Context.pImpl->CLASS##s)
#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS)                      \
  return storeImpl(new (NUM_OPS, Storage)                                      \
                       CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS),        \
                   Storage, Context.pImpl->CLASS##s)

DISubrange::DISubrange(LLVMContext &C, StorageType Storage,
                       ArrayRef<Metadata *> Ops)
    : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo,
                                StorageType Storage, bool ShouldCreate) {
  auto *CountNode = ConstantAsMetadata::get(
      ConstantInt::getSigned(Type::getInt64Ty(Context), Count));
  auto *LB = ConstantAsMetadata::get(
      ConstantInt::getSigned(Type::getInt64Ty(Context), Lo));
  return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
                 ShouldCreate);
}

DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
                                int64_t Lo, StorageType Storage,
                                bool ShouldCreate) {
  auto *LB = ConstantAsMetadata::get(
      ConstantInt::getSigned(Type::getInt64Ty(Context), Lo));
  return getImpl(Context, CountNode, LB, nullptr, nullptr, Storage,
                 ShouldCreate);
}

DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
                                Metadata *LB, Metadata *UB, Metadata *Stride,
                                StorageType Storage, bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DISubrange, (CountNode, LB, UB, Stride));
  Metadata *Ops[] = {CountNode, LB, UB, Stride};
  DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DISubrange, Ops);
}

DISubrange::BoundType DISubrange::getCount() const {
  Metadata *CB = getRawCountNode();
  if (!CB)
    return BoundType();

  assert((isa<ConstantAsMetadata>(CB) || isa<DIVariable>(CB) ||
          isa<DIExpression>(CB)) &&
         "Count must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<ConstantAsMetadata>(CB))
    return BoundType(cast<ConstantInt>(MD->getValue()));

  if (auto *MD = dyn_cast<DIVariable>(CB))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(CB))
    return BoundType(MD);

  return BoundType();
}

DISubrange::BoundType DISubrange::getLowerBound() const {
  Metadata *LB = getRawLowerBound();
  if (!LB)
    return BoundType();

  assert((isa<ConstantAsMetadata>(LB) || isa<DIVariable>(LB) ||
          isa<DIExpression>(LB)) &&
         "LowerBound must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<ConstantAsMetadata>(LB))
    return BoundType(cast<ConstantInt>(MD->getValue()));

  if (auto *MD = dyn_cast<DIVariable>(LB))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(LB))
    return BoundType(MD);

  return BoundType();
}

DISubrange::BoundType DISubrange::getUpperBound() const {
  Metadata *UB = getRawUpperBound();
  if (!UB)
    return BoundType();

  assert((isa<ConstantAsMetadata>(UB) || isa<DIVariable>(UB) ||
          isa<DIExpression>(UB)) &&
         "UpperBound must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<ConstantAsMetadata>(UB))
    return BoundType(cast<ConstantInt>(MD->getValue()));

  if (auto *MD = dyn_cast<DIVariable>(UB))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(UB))
    return BoundType(MD);

  return BoundType();
}

DISubrange::BoundType DISubrange::getStride() const {
  Metadata *ST = getRawStride();
  if (!ST)
    return BoundType();

  assert((isa<ConstantAsMetadata>(ST) || isa<DIVariable>(ST) ||
          isa<DIExpression>(ST)) &&
         "Stride must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<ConstantAsMetadata>(ST))
    return BoundType(cast<ConstantInt>(MD->getValue()));

  if (auto *MD = dyn_cast<DIVariable>(ST))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(ST))
    return BoundType(MD);

  return BoundType();
}
DIGenericSubrange::DIGenericSubrange(LLVMContext &C, StorageType Storage,
                                     ArrayRef<Metadata *> Ops)
    : DINode(C, DIGenericSubrangeKind, Storage, dwarf::DW_TAG_generic_subrange,
             Ops) {}

DIGenericSubrange *DIGenericSubrange::getImpl(LLVMContext &Context,
                                              Metadata *CountNode, Metadata *LB,
                                              Metadata *UB, Metadata *Stride,
                                              StorageType Storage,
                                              bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DIGenericSubrange, (CountNode, LB, UB, Stride));
  Metadata *Ops[] = {CountNode, LB, UB, Stride};
  DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGenericSubrange, Ops);
}

DIGenericSubrange::BoundType DIGenericSubrange::getCount() const {
  Metadata *CB = getRawCountNode();
  if (!CB)
    return BoundType();

  assert((isa<DIVariable>(CB) || isa<DIExpression>(CB)) &&
         "Count must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<DIVariable>(CB))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(CB))
    return BoundType(MD);

  return BoundType();
}

DIGenericSubrange::BoundType DIGenericSubrange::getLowerBound() const {
  Metadata *LB = getRawLowerBound();
  if (!LB)
    return BoundType();

  assert((isa<DIVariable>(LB) || isa<DIExpression>(LB)) &&
         "LowerBound must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<DIVariable>(LB))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(LB))
    return BoundType(MD);

  return BoundType();
}

DIGenericSubrange::BoundType DIGenericSubrange::getUpperBound() const {
  Metadata *UB = getRawUpperBound();
  if (!UB)
    return BoundType();

  assert((isa<DIVariable>(UB) || isa<DIExpression>(UB)) &&
         "UpperBound must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<DIVariable>(UB))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(UB))
    return BoundType(MD);

  return BoundType();
}

DIGenericSubrange::BoundType DIGenericSubrange::getStride() const {
  Metadata *ST = getRawStride();
  if (!ST)
    return BoundType();

  assert((isa<DIVariable>(ST) || isa<DIExpression>(ST)) &&
         "Stride must be signed constant or DIVariable or DIExpression");

  if (auto *MD = dyn_cast<DIVariable>(ST))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(ST))
    return BoundType(MD);

  return BoundType();
}

DISubrangeType::DISubrangeType(LLVMContext &C, StorageType Storage,
                               unsigned Line, uint32_t AlignInBits,
                               DIFlags Flags, ArrayRef<Metadata *> Ops)
    : DIType(C, DISubrangeTypeKind, Storage, dwarf::DW_TAG_subrange_type, Line,
             AlignInBits, 0, Flags, Ops) {}

DISubrangeType *DISubrangeType::getImpl(
    LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
    Metadata *Scope, Metadata *SizeInBits, uint32_t AlignInBits, DIFlags Flags,
    Metadata *BaseType, Metadata *LowerBound, Metadata *UpperBound,
    Metadata *Stride, Metadata *Bias, StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DISubrangeType, (Name, File, Line, Scope, SizeInBits,
                                         AlignInBits, Flags, BaseType,
                                         LowerBound, UpperBound, Stride, Bias));
  Metadata *Ops[] = {File,     Scope,      Name,       SizeInBits, nullptr,
                     BaseType, LowerBound, UpperBound, Stride,     Bias};
  DEFINE_GETIMPL_STORE(DISubrangeType, (Line, AlignInBits, Flags), Ops);
}

DISubrangeType::BoundType
DISubrangeType::convertRawToBound(Metadata *IN) const {
  if (!IN)
    return BoundType();

  assert(isa<ConstantAsMetadata>(IN) || isa<DIVariable>(IN) ||
         isa<DIExpression>(IN) || isa<DIDerivedType>(IN));

  if (auto *MD = dyn_cast<ConstantAsMetadata>(IN))
    return BoundType(cast<ConstantInt>(MD->getValue()));

  if (auto *MD = dyn_cast<DIVariable>(IN))
    return BoundType(MD);

  if (auto *MD = dyn_cast<DIExpression>(IN))
    return BoundType(MD);

  if (auto *DT = dyn_cast<DIDerivedType>(IN))
    return BoundType(DT);

  return BoundType();
}

DIEnumerator::DIEnumerator(LLVMContext &C, StorageType Storage,
                           const APInt &Value, bool IsUnsigned,
                           ArrayRef<Metadata *> Ops)
    : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
      Value(Value) {
  SubclassData32 = IsUnsigned;
}
DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, const APInt &Value,
                                    bool IsUnsigned, MDString *Name,
                                    StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
  Metadata *Ops[] = {Name};
  DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
}

DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
                                  MDString *Name, Metadata *File,
                                  unsigned LineNo, Metadata *Scope,
                                  Metadata *SizeInBits, uint32_t AlignInBits,
                                  unsigned Encoding,
                                  uint32_t NumExtraInhabitants,
                                  uint32_t DataSizeInBits, DIFlags Flags,
                                  StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(
      DIBasicType, (Tag, Name, File, LineNo, Scope, SizeInBits, AlignInBits,
                    Encoding, NumExtraInhabitants, DataSizeInBits, Flags));
  Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr};
  DEFINE_GETIMPL_STORE(DIBasicType,
                       (Tag, LineNo, AlignInBits, Encoding, NumExtraInhabitants,
                        DataSizeInBits, Flags),
                       Ops);
}

std::optional<DIBasicType::Signedness> DIBasicType::getSignedness() const {
  switch (getEncoding()) {
  case dwarf::DW_ATE_signed:
  case dwarf::DW_ATE_signed_char:
  case dwarf::DW_ATE_signed_fixed:
    return Signedness::Signed;
  case dwarf::DW_ATE_unsigned:
  case dwarf::DW_ATE_unsigned_char:
  case dwarf::DW_ATE_unsigned_fixed:
    return Signedness::Unsigned;
  default:
    return std::nullopt;
  }
}

DIFixedPointType *
DIFixedPointType::getImpl(LLVMContext &Context, unsigned Tag, MDString *Name,
                          Metadata *File, unsigned LineNo, Metadata *Scope,
                          Metadata *SizeInBits, uint32_t AlignInBits,
                          unsigned Encoding, DIFlags Flags, unsigned Kind,
                          int Factor, APInt Numerator, APInt Denominator,
                          StorageType Storage, bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DIFixedPointType,
                        (Tag, Name, File, LineNo, Scope, SizeInBits,
                         AlignInBits, Encoding, Flags, Kind, Factor, Numerator,
                         Denominator));
  Metadata *Ops[] = {File, Scope, Name, SizeInBits, nullptr};
  DEFINE_GETIMPL_STORE(DIFixedPointType,
                       (Tag, LineNo, AlignInBits, Encoding, Flags, Kind, Factor,
                        Numerator, Denominator),
                       Ops);
}

bool DIFixedPointType::isSigned() const {
  return getEncoding() == dwarf::DW_ATE_signed_fixed;
}

std::optional<DIFixedPointType::FixedPointKind>
DIFixedPointType::getFixedPointKind(StringRef Str) {
  return StringSwitch<std::optional<FixedPointKind>>(Str)
      .Case("Binary", FixedPointBinary)
      .Case("Decimal", FixedPointDecimal)
      .Case("Rational", FixedPointRational)
      .Default(std::nullopt);
}

const char *DIFixedPointType::fixedPointKindString(FixedPointKind V) {
  switch (V) {
  case FixedPointBinary:
    return "Binary";
  case FixedPointDecimal:
    return "Decimal";
  case FixedPointRational:
    return "Rational";
  }
  return nullptr;
}

DIStringType *DIStringType::getImpl(LLVMContext &Context, unsigned Tag,
                                    MDString *Name, Metadata *StringLength,
                                    Metadata *StringLengthExp,
                                    Metadata *StringLocationExp,
                                    Metadata *SizeInBits, uint32_t AlignInBits,
                                    unsigned Encoding, Metadata *CharType,
                                    StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIStringType, (Tag, Name, StringLength, StringLengthExp,
                                       StringLocationExp, SizeInBits,
                                       AlignInBits, Encoding, CharType));
  Metadata *Ops[] = {nullptr,         nullptr,           Name,
                     SizeInBits,      nullptr,           StringLength,
                     StringLengthExp, StringLocationExp, CharType};
  DEFINE_GETIMPL_STORE(DIStringType, (Tag, AlignInBits, Encoding), Ops);
}
DIType *DIDerivedType::getClassType() const {
  assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
  return cast_or_null<DIType>(getExtraData());
}

// Helper function to extract ConstantAsMetadata from ExtraData,
// handling extra data MDTuple unwrapping if needed.
static ConstantAsMetadata *extractConstantMetadata(Metadata *ExtraData) {
  Metadata *ED = ExtraData;
  if (auto *Tuple = dyn_cast_or_null<MDTuple>(ED)) {
    if (Tuple->getNumOperands() != 1)
      return nullptr;
    ED = Tuple->getOperand(0);
  }
  return cast_or_null<ConstantAsMetadata>(ED);
}

uint32_t DIDerivedType::getVBPtrOffset() const {
  assert(getTag() == dwarf::DW_TAG_inheritance);
  if (auto *CM = extractConstantMetadata(getExtraData()))
    if (auto *CI = dyn_cast_or_null<ConstantInt>(CM->getValue()))
      return static_cast<uint32_t>(CI->getZExtValue());
  return 0;
}
Constant *DIDerivedType::getStorageOffsetInBits() const {
  assert(getTag() == dwarf::DW_TAG_member && isBitField());
  if (auto *C = extractConstantMetadata(getExtraData()))
    return C->getValue();
  return nullptr;
}

Constant *DIDerivedType::getConstant() const {
  assert((getTag() == dwarf::DW_TAG_member ||
          getTag() == dwarf::DW_TAG_variable) &&
         isStaticMember());
  if (auto *C = extractConstantMetadata(getExtraData()))
    return C->getValue();
  return nullptr;
}
Constant *DIDerivedType::getDiscriminantValue() const {
  assert(getTag() == dwarf::DW_TAG_member && !isStaticMember());
  if (auto *C = extractConstantMetadata(getExtraData()))
    return C->getValue();
  return nullptr;
}

DIDerivedType *DIDerivedType::getImpl(
    LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
    unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
    uint32_t AlignInBits, Metadata *OffsetInBits,
    std::optional<unsigned> DWARFAddressSpace,
    std::optional<PtrAuthData> PtrAuthData, DIFlags Flags, Metadata *ExtraData,
    Metadata *Annotations, StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIDerivedType,
                        (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
                         AlignInBits, OffsetInBits, DWARFAddressSpace,
                         PtrAuthData, Flags, ExtraData, Annotations));
  Metadata *Ops[] = {File,         Scope,    Name,      SizeInBits,
                     OffsetInBits, BaseType, ExtraData, Annotations};
  DEFINE_GETIMPL_STORE(
      DIDerivedType,
      (Tag, Line, AlignInBits, DWARFAddressSpace, PtrAuthData, Flags), Ops);
}

std::optional<DIDerivedType::PtrAuthData>
DIDerivedType::getPtrAuthData() const {
  return getTag() == dwarf::DW_TAG_LLVM_ptrauth_type
             ? std::make_optional<PtrAuthData>(SubclassData32)
             : std::nullopt;
}

DICompositeType *DICompositeType::getImpl(
    LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
    unsigned Line, Metadata *Scope, Metadata *BaseType, Metadata *SizeInBits,
    uint32_t AlignInBits, Metadata *OffsetInBits, DIFlags Flags,
    Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
    Metadata *VTableHolder, Metadata *TemplateParams, MDString *Identifier,
    Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated,
    Metadata *Allocated, Metadata *Rank, Metadata *Annotations,
    Metadata *Specification, uint32_t NumExtraInhabitants, Metadata *BitStride,
    StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");

  // Keep this in sync with buildODRType.
  DEFINE_GETIMPL_LOOKUP(
      DICompositeType,
      (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
       OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
       Identifier, Discriminator, DataLocation, Associated, Allocated, Rank,
       Annotations, Specification, NumExtraInhabitants, BitStride));
  Metadata *Ops[] = {File,           Scope,      Name,          SizeInBits,
                     OffsetInBits,   BaseType,   Elements,      VTableHolder,
                     TemplateParams, Identifier, Discriminator, DataLocation,
                     Associated,     Allocated,  Rank,          Annotations,
                     Specification,  BitStride};
  DEFINE_GETIMPL_STORE(DICompositeType,
                       (Tag, Line, RuntimeLang, AlignInBits,
                        NumExtraInhabitants, EnumKind, Flags),
                       Ops);
}

DICompositeType *DICompositeType::buildODRType(
    LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
    Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
    Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
    Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
    Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
    Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
    Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
    Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
  assert(!Identifier.getString().empty() && "Expected valid identifier");
  if (!Context.isODRUniquingDebugTypes())
    return nullptr;
  auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
  if (!CT)
    return CT = DICompositeType::getDistinct(
               Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
               AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
               EnumKind, VTableHolder, TemplateParams, &Identifier,
               Discriminator, DataLocation, Associated, Allocated, Rank,
               Annotations, Specification, NumExtraInhabitants, BitStride);
  if (CT->getTag() != Tag)
    return nullptr;

  // Only mutate CT if it's a forward declaration and the new operands aren't.
  assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
  if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl))
    return CT;

  // Mutate CT in place.  Keep this in sync with getImpl.
  CT->mutate(Tag, Line, RuntimeLang, AlignInBits, NumExtraInhabitants, EnumKind,
             Flags);
  Metadata *Ops[] = {File,           Scope,       Name,          SizeInBits,
                     OffsetInBits,   BaseType,    Elements,      VTableHolder,
                     TemplateParams, &Identifier, Discriminator, DataLocation,
                     Associated,     Allocated,   Rank,          Annotations,
                     Specification,  BitStride};
  assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
         "Mismatched number of operands");
  for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
    if (Ops[I] != CT->getOperand(I))
      CT->setOperand(I, Ops[I]);
  return CT;
}

DICompositeType *DICompositeType::getODRType(
    LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
    Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
    Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
    Metadata *Specification, uint32_t NumExtraInhabitants, DIFlags Flags,
    Metadata *Elements, unsigned RuntimeLang, std::optional<uint32_t> EnumKind,
    Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
    Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
    Metadata *Rank, Metadata *Annotations, Metadata *BitStride) {
  assert(!Identifier.getString().empty() && "Expected valid identifier");
  if (!Context.isODRUniquingDebugTypes())
    return nullptr;
  auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier];
  if (!CT) {
    CT = DICompositeType::getDistinct(
        Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
        AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, EnumKind,
        VTableHolder, TemplateParams, &Identifier, Discriminator, DataLocation,
        Associated, Allocated, Rank, Annotations, Specification,
        NumExtraInhabitants, BitStride);
  } else {
    if (CT->getTag() != Tag)
      return nullptr;
  }
  return CT;
}

DICompositeType *DICompositeType::getODRTypeIfExists(LLVMContext &Context,
                                                     MDString &Identifier) {
  assert(!Identifier.getString().empty() && "Expected valid identifier");
  if (!Context.isODRUniquingDebugTypes())
    return nullptr;
  return Context.pImpl->DITypeMap->lookup(&Identifier);
}
DISubroutineType::DISubroutineType(LLVMContext &C, StorageType Storage,
                                   DIFlags Flags, uint8_t CC,
                                   ArrayRef<Metadata *> Ops)
    : DIType(C, DISubroutineTypeKind, Storage, dwarf::DW_TAG_subroutine_type, 0,
             0, 0, Flags, Ops),
      CC(CC) {}

DISubroutineType *DISubroutineType::getImpl(LLVMContext &Context, DIFlags Flags,
                                            uint8_t CC, Metadata *TypeArray,
                                            StorageType Storage,
                                            bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DISubroutineType, (Flags, CC, TypeArray));
  Metadata *Ops[] = {nullptr, nullptr, nullptr, nullptr, nullptr, TypeArray};
  DEFINE_GETIMPL_STORE(DISubroutineType, (Flags, CC), Ops);
}

DIFile::DIFile(LLVMContext &C, StorageType Storage,
               std::optional<ChecksumInfo<MDString *>> CS, MDString *Src,
               ArrayRef<Metadata *> Ops)
    : DIScope(C, DIFileKind, Storage, dwarf::DW_TAG_file_type, Ops),
      Checksum(CS), Source(Src) {}

// FIXME: Implement this string-enum correspondence with a .def file and macros,
// so that the association is explicit rather than implied.
static const char *ChecksumKindName[DIFile::CSK_Last] = {
    "CSK_MD5",
    "CSK_SHA1",
    "CSK_SHA256",
};

StringRef DIFile::getChecksumKindAsString(ChecksumKind CSKind) {
  assert(CSKind <= DIFile::CSK_Last && "Invalid checksum kind");
  // The first space was originally the CSK_None variant, which is now
  // obsolete, but the space is still reserved in ChecksumKind, so we account
  // for it here.
  return ChecksumKindName[CSKind - 1];
}

std::optional<DIFile::ChecksumKind>
DIFile::getChecksumKind(StringRef CSKindStr) {
  return StringSwitch<std::optional<DIFile::ChecksumKind>>(CSKindStr)
      .Case("CSK_MD5", DIFile::CSK_MD5)
      .Case("CSK_SHA1", DIFile::CSK_SHA1)
      .Case("CSK_SHA256", DIFile::CSK_SHA256)
      .Default(std::nullopt);
}

DIFile *DIFile::getImpl(LLVMContext &Context, MDString *Filename,
                        MDString *Directory,
                        std::optional<DIFile::ChecksumInfo<MDString *>> CS,
                        MDString *Source, StorageType Storage,
                        bool ShouldCreate) {
  assert(isCanonical(Filename) && "Expected canonical MDString");
  assert(isCanonical(Directory) && "Expected canonical MDString");
  assert((!CS || isCanonical(CS->Value)) && "Expected canonical MDString");
  // We do *NOT* expect Source to be a canonical MDString because nullptr
  // means none, so we need something to represent the empty file.
  DEFINE_GETIMPL_LOOKUP(DIFile, (Filename, Directory, CS, Source));
  Metadata *Ops[] = {Filename, Directory, CS ? CS->Value : nullptr, Source};
  DEFINE_GETIMPL_STORE(DIFile, (CS, Source), Ops);
}
DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
                             DISourceLanguageName SourceLanguage,
                             bool IsOptimized, unsigned RuntimeVersion,
                             unsigned EmissionKind, uint64_t DWOId,
                             bool SplitDebugInlining,
                             bool DebugInfoForProfiling, unsigned NameTableKind,
                             bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
    : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
      SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion),
      DWOId(DWOId), EmissionKind(EmissionKind), NameTableKind(NameTableKind),
      IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),
      DebugInfoForProfiling(DebugInfoForProfiling),
      RangesBaseAddress(RangesBaseAddress) {
  assert(Storage != Uniqued);
}

DICompileUnit *DICompileUnit::getImpl(
    LLVMContext &Context, DISourceLanguageName SourceLanguage, Metadata *File,
    MDString *Producer, bool IsOptimized, MDString *Flags,
    unsigned RuntimeVersion, MDString *SplitDebugFilename,
    unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes,
    Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros,
    uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
    unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
    MDString *SDK, StorageType Storage, bool ShouldCreate) {
  assert(Storage != Uniqued && "Cannot unique DICompileUnit");
  assert(isCanonical(Producer) && "Expected canonical MDString");
  assert(isCanonical(Flags) && "Expected canonical MDString");
  assert(isCanonical(SplitDebugFilename) && "Expected canonical MDString");

  Metadata *Ops[] = {File,
                     Producer,
                     Flags,
                     SplitDebugFilename,
                     EnumTypes,
                     RetainedTypes,
                     GlobalVariables,
                     ImportedEntities,
                     Macros,
                     SysRoot,
                     SDK};
  return storeImpl(new (std::size(Ops), Storage) DICompileUnit(
                       Context, Storage, SourceLanguage, IsOptimized,
                       RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining,
                       DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
                       Ops),
                   Storage);
}

std::optional<DICompileUnit::DebugEmissionKind>
DICompileUnit::getEmissionKind(StringRef Str) {
  return StringSwitch<std::optional<DebugEmissionKind>>(Str)
      .Case("NoDebug", NoDebug)
      .Case("FullDebug", FullDebug)
      .Case("LineTablesOnly", LineTablesOnly)
      .Case("DebugDirectivesOnly", DebugDirectivesOnly)
      .Default(std::nullopt);
}

std::optional<DICompileUnit::DebugNameTableKind>
DICompileUnit::getNameTableKind(StringRef Str) {
  return StringSwitch<std::optional<DebugNameTableKind>>(Str)
      .Case("Default", DebugNameTableKind::Default)
      .Case("GNU", DebugNameTableKind::GNU)
      .Case("Apple", DebugNameTableKind::Apple)
      .Case("None", DebugNameTableKind::None)
      .Default(std::nullopt);
}

const char *DICompileUnit::emissionKindString(DebugEmissionKind EK) {
  switch (EK) {
  case NoDebug:
    return "NoDebug";
  case FullDebug:
    return "FullDebug";
  case LineTablesOnly:
    return "LineTablesOnly";
  case DebugDirectivesOnly:
    return "DebugDirectivesOnly";
  }
  return nullptr;
}

const char *DICompileUnit::nameTableKindString(DebugNameTableKind NTK) {
  switch (NTK) {
  case DebugNameTableKind::Default:
    return nullptr;
  case DebugNameTableKind::GNU:
    return "GNU";
  case DebugNameTableKind::Apple:
    return "Apple";
  case DebugNameTableKind::None:
    return "None";
  }
  return nullptr;
}
DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
                           unsigned ScopeLine, unsigned VirtualIndex,
                           int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags,
                           bool UsesKeyInstructions, ArrayRef<Metadata *> Ops)
    : DILocalScope(C, DISubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
      Line(Line), ScopeLine(ScopeLine), VirtualIndex(VirtualIndex),
      ThisAdjustment(ThisAdjustment), Flags(Flags), SPFlags(SPFlags) {
  static_assert(dwarf::DW_VIRTUALITY_max < 4, "Virtuality out of range");
  SubclassData1 = UsesKeyInstructions;
}
DISubprogram::DISPFlags
DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
                        unsigned Virtuality, bool IsMainSubprogram) {
  // We're assuming virtuality is the low-order field.
  static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
                    int(SPFlagPureVirtual) ==
                        int(dwarf::DW_VIRTUALITY_pure_virtual),
                "Virtuality constant mismatch");
  return static_cast<DISPFlags>(
      (Virtuality & SPFlagVirtuality) |
      (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
      (IsDefinition ? SPFlagDefinition : SPFlagZero) |
      (IsOptimized ? SPFlagOptimized : SPFlagZero) |
      (IsMainSubprogram ? SPFlagMainSubprogram : SPFlagZero));
}

DISubprogram *DILocalScope::getSubprogram() const {
  if (auto *Block = dyn_cast<DILexicalBlockBase>(this))
    return Block->getScope()->getSubprogram();
  return const_cast<DISubprogram *>(cast<DISubprogram>(this));
}

DILocalScope *DILocalScope::getNonLexicalBlockFileScope() const {
  if (auto *File = dyn_cast<DILexicalBlockFile>(this))
    return File->getScope()->getNonLexicalBlockFileScope();
  return const_cast<DILocalScope *>(this);
}

DILocalScope *DILocalScope::cloneScopeForSubprogram(
    DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx,
    DenseMap<const MDNode *, MDNode *> &Cache) {
  SmallVector<DIScope *> ScopeChain;
  DIScope *CachedResult = nullptr;

  for (DIScope *Scope = &RootScope; !isa<DISubprogram>(Scope);
       Scope = Scope->getScope()) {
    if (auto It = Cache.find(Scope); It != Cache.end()) {
      CachedResult = cast<DIScope>(It->second);
      break;
    }
    ScopeChain.push_back(Scope);
  }

  // Recreate the scope chain, bottom-up, starting at the new subprogram (or a
  // cached result).
  DIScope *UpdatedScope = CachedResult ? CachedResult : &NewSP;
  for (DIScope *ScopeToUpdate : reverse(ScopeChain)) {
    UpdatedScope = cloneAndReplaceParentScope(
        cast<DILexicalBlockBase>(ScopeToUpdate), UpdatedScope);
    Cache[ScopeToUpdate] = UpdatedScope;
  }

  return cast<DILocalScope>(UpdatedScope);
}

DISubprogram::DISPFlags DISubprogram::getFlag(StringRef Flag) {
  return StringSwitch<DISPFlags>(Flag)
#define HANDLE_DISP_FLAG(ID, NAME) .Case("DISPFlag" #NAME, SPFlag##NAME)
#include "llvm/IR/DebugInfoFlags.def"
      .Default(SPFlagZero);
}

StringRef DISubprogram::getFlagString(DISPFlags Flag) {
  switch (Flag) {
  // Appease a warning.
  case SPFlagVirtuality:
    return "";
#define HANDLE_DISP_FLAG(ID, NAME)                                             \
  case SPFlag##NAME:                                                           \
    return "DISPFlag" #NAME;
#include "llvm/IR/DebugInfoFlags.def"
  }
  return "";
}

DISubprogram::DISPFlags
DISubprogram::splitFlags(DISPFlags Flags,
                         SmallVectorImpl<DISPFlags> &SplitFlags) {
  // Multi-bit fields can require special handling. In our case, however, the
  // only multi-bit field is virtuality, and all its values happen to be
  // single-bit values, so the right behavior just falls out.
#define HANDLE_DISP_FLAG(ID, NAME)                                             \
  if (DISPFlags Bit = Flags & SPFlag##NAME) {                                  \
    SplitFlags.push_back(Bit);                                                 \
    Flags &= ~Bit;                                                             \
  }
#include "llvm/IR/DebugInfoFlags.def"
  return Flags;
}

DISubprogram *DISubprogram::getImpl(
    LLVMContext &Context, Metadata *Scope, MDString *Name,
    MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
    unsigned ScopeLine, Metadata *ContainingType, unsigned VirtualIndex,
    int ThisAdjustment, DIFlags Flags, DISPFlags SPFlags, Metadata *Unit,
    Metadata *TemplateParams, Metadata *Declaration, Metadata *RetainedNodes,
    Metadata *ThrownTypes, Metadata *Annotations, MDString *TargetFuncName,
    bool UsesKeyInstructions, StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  assert(isCanonical(LinkageName) && "Expected canonical MDString");
  assert(isCanonical(TargetFuncName) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DISubprogram,
                        (Scope, Name, LinkageName, File, Line, Type, ScopeLine,
                         ContainingType, VirtualIndex, ThisAdjustment, Flags,
                         SPFlags, Unit, TemplateParams, Declaration,
                         RetainedNodes, ThrownTypes, Annotations,
                         TargetFuncName, UsesKeyInstructions));
  SmallVector<Metadata *, 13> Ops = {
      File,           Scope,          Name,        LinkageName,
      Type,           Unit,           Declaration, RetainedNodes,
      ContainingType, TemplateParams, ThrownTypes, Annotations,
      TargetFuncName};
  if (!TargetFuncName) {
    Ops.pop_back();
    if (!Annotations) {
      Ops.pop_back();
      if (!ThrownTypes) {
        Ops.pop_back();
        if (!TemplateParams) {
          Ops.pop_back();
          if (!ContainingType)
            Ops.pop_back();
        }
      }
    }
  }
  DEFINE_GETIMPL_STORE_N(DISubprogram,
                         (Line, ScopeLine, VirtualIndex, ThisAdjustment, Flags,
                          SPFlags, UsesKeyInstructions),
                         Ops, Ops.size());
}

bool DISubprogram::describes(const Function *F) const {
  assert(F && "Invalid function");
  return F->getSubprogram() == this;
}

template <typename ScopeT, typename NodeT>
static ScopeT getRawRetainedNodeScopeInternal(NodeT *N) {
  auto getScopeLambda = [](auto *N) { return getScope(N); };
  return DISubprogram::visitRetainedNode<ScopeT>(
      N, getScopeLambda, getScopeLambda, getScopeLambda, getScopeLambda,
      getScopeLambda, [](auto *N) { return nullptr; });
}

const DIScope *DISubprogram::getRawRetainedNodeScope(const MDNode *N) {
  return getRawRetainedNodeScopeInternal<const DIScope *>(N);
}

DIScope *DISubprogram::getRawRetainedNodeScope(MDNode *N) {
  return getRawRetainedNodeScopeInternal<DIScope *>(N);
}

const DILocalScope *DISubprogram::getRetainedNodeScope(const MDNode *N) {
  return cast<DILocalScope>(getRawRetainedNodeScope(N));
}

DILocalScope *DISubprogram::getRetainedNodeScope(MDNode *N) {
  return cast<DILocalScope>(getRawRetainedNodeScope(N));
}

void DISubprogram::cleanupRetainedNodes() {
  // Checks if a metadata node from retainedTypes is a type belonging to
  // this subprogram.
  auto IsTypeInSP = [this](Metadata *N) {
    auto *T = dyn_cast_or_null<DIType>(N);
    if (!T)
      return true;

    DISubprogram *TypeSP = nullptr;
    // The type might have been global in the previously loaded IR modules.
    if (auto *LS = dyn_cast_or_null<DILocalScope>(T->getScope()))
      TypeSP = LS->getSubprogram();

    return this == TypeSP;
  };

  cleanupRetainedNodesIf(IsTypeInSP);
}

DILexicalBlockBase::DILexicalBlockBase(LLVMContext &C, unsigned ID,
                                       StorageType Storage,
                                       ArrayRef<Metadata *> Ops)
    : DILocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}

DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
                                        Metadata *File, unsigned Line,
                                        unsigned Column, StorageType Storage,
                                        bool ShouldCreate) {
  // Fixup column.
  adjustColumn(Column);

  assert(Scope && "Expected scope");
  DEFINE_GETIMPL_LOOKUP(DILexicalBlock, (Scope, File, Line, Column));
  Metadata *Ops[] = {File, Scope};
  DEFINE_GETIMPL_STORE(DILexicalBlock, (Line, Column), Ops);
}

DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
                                                Metadata *Scope, Metadata *File,
                                                unsigned Discriminator,
                                                StorageType Storage,
                                                bool ShouldCreate) {
  assert(Scope && "Expected scope");
  DEFINE_GETIMPL_LOOKUP(DILexicalBlockFile, (Scope, File, Discriminator));
  Metadata *Ops[] = {File, Scope};
  DEFINE_GETIMPL_STORE(DILexicalBlockFile, (Discriminator), Ops);
}

DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
                         bool ExportSymbols, ArrayRef<Metadata *> Ops)
    : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {
  SubclassData1 = ExportSymbols;
}
DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
                                  MDString *Name, bool ExportSymbols,
                                  StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DINamespace, (Scope, Name, ExportSymbols));
  // The nullptr is for DIScope's File operand. This should be refactored.
  Metadata *Ops[] = {nullptr, Scope, Name};
  DEFINE_GETIMPL_STORE(DINamespace, (ExportSymbols), Ops);
}

DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
                             unsigned LineNo, ArrayRef<Metadata *> Ops)
    : DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
              Ops) {
  SubclassData32 = LineNo;
}
DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
                                      Metadata *Decl, MDString *Name,
                                      Metadata *File, unsigned LineNo,
                                      StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DICommonBlock, (Scope, Decl, Name, File, LineNo));
  // The nullptr is for DIScope's File operand. This should be refactored.
  Metadata *Ops[] = {Scope, Decl, Name, File};
  DEFINE_GETIMPL_STORE(DICommonBlock, (LineNo), Ops);
}

DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
                   bool IsDecl, ArrayRef<Metadata *> Ops)
    : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {
  SubclassData1 = IsDecl;
  SubclassData32 = LineNo;
}
DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
                            Metadata *Scope, MDString *Name,
                            MDString *ConfigurationMacros,
                            MDString *IncludePath, MDString *APINotesFile,
                            unsigned LineNo, bool IsDecl, StorageType Storage,
                            bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIModule, (File, Scope, Name, ConfigurationMacros,
                                   IncludePath, APINotesFile, LineNo, IsDecl));
  Metadata *Ops[] = {File,        Scope,       Name, ConfigurationMacros,
                     IncludePath, APINotesFile};
  DEFINE_GETIMPL_STORE(DIModule, (LineNo, IsDecl), Ops);
}
DITemplateTypeParameter::DITemplateTypeParameter(LLVMContext &Context,
                                                 StorageType Storage,
                                                 bool IsDefault,
                                                 ArrayRef<Metadata *> Ops)
    : DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
                          dwarf::DW_TAG_template_type_parameter, IsDefault,
                          Ops) {}

DITemplateTypeParameter *
DITemplateTypeParameter::getImpl(LLVMContext &Context, MDString *Name,
                                 Metadata *Type, bool isDefault,
                                 StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DITemplateTypeParameter, (Name, Type, isDefault));
  Metadata *Ops[] = {Name, Type};
  DEFINE_GETIMPL_STORE(DITemplateTypeParameter, (isDefault), Ops);
}

DITemplateValueParameter *DITemplateValueParameter::getImpl(
    LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *Type,
    bool isDefault, Metadata *Value, StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DITemplateValueParameter,
                        (Tag, Name, Type, isDefault, Value));
  Metadata *Ops[] = {Name, Type, Value};
  DEFINE_GETIMPL_STORE(DITemplateValueParameter, (Tag, isDefault), Ops);
}

DIGlobalVariable *
DIGlobalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
                          MDString *LinkageName, Metadata *File, unsigned Line,
                          Metadata *Type, bool IsLocalToUnit, bool IsDefinition,
                          Metadata *StaticDataMemberDeclaration,
                          Metadata *TemplateParams, uint32_t AlignInBits,
                          Metadata *Annotations, StorageType Storage,
                          bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  assert(isCanonical(LinkageName) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(
      DIGlobalVariable,
      (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
       StaticDataMemberDeclaration, TemplateParams, AlignInBits, Annotations));
  Metadata *Ops[] = {Scope,
                     Name,
                     File,
                     Type,
                     Name,
                     LinkageName,
                     StaticDataMemberDeclaration,
                     TemplateParams,
                     Annotations};
  DEFINE_GETIMPL_STORE(DIGlobalVariable,
                       (Line, IsLocalToUnit, IsDefinition, AlignInBits), Ops);
}

DILocalVariable *
DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
                         Metadata *File, unsigned Line, Metadata *Type,
                         unsigned Arg, DIFlags Flags, uint32_t AlignInBits,
                         Metadata *Annotations, StorageType Storage,
                         bool ShouldCreate) {
  // 64K ought to be enough for any frontend.
  assert(Arg <= UINT16_MAX && "Expected argument number to fit in 16-bits");

  assert(Scope && "Expected scope");
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DILocalVariable, (Scope, Name, File, Line, Type, Arg,
                                          Flags, AlignInBits, Annotations));
  Metadata *Ops[] = {Scope, Name, File, Type, Annotations};
  DEFINE_GETIMPL_STORE(DILocalVariable, (Line, Arg, Flags, AlignInBits), Ops);
}

DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage,
                       signed Line, ArrayRef<Metadata *> Ops,
                       uint32_t AlignInBits)
    : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {
  SubclassData32 = AlignInBits;
}
std::optional<uint64_t> DIVariable::getSizeInBits() const {
  // This is used by the Verifier so be mindful of broken types.
  const Metadata *RawType = getRawType();
  while (RawType) {
    // Try to get the size directly.
    if (auto *T = dyn_cast<DIType>(RawType))
      if (uint64_t Size = T->getSizeInBits())
        return Size;

    if (auto *DT = dyn_cast<DIDerivedType>(RawType)) {
      // Look at the base type.
      RawType = DT->getRawBaseType();
      continue;
    }

    // Missing type or size.
    break;
  }

  // Fail gracefully.
  return std::nullopt;
}

DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
                 unsigned Column, bool IsArtificial,
                 std::optional<unsigned> CoroSuspendIdx,
                 ArrayRef<Metadata *> Ops)
    : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {
  this->SubclassData32 = Line;
  this->Column = Column;
  this->IsArtificial = IsArtificial;
  this->CoroSuspendIdx = CoroSuspendIdx;
}
DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
                          Metadata *File, unsigned Line, unsigned Column,
                          bool IsArtificial,
                          std::optional<unsigned> CoroSuspendIdx,
                          StorageType Storage, bool ShouldCreate) {
  assert(Scope && "Expected scope");
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(
      DILabel, (Scope, Name, File, Line, Column, IsArtificial, CoroSuspendIdx));
  Metadata *Ops[] = {Scope, Name, File};
  DEFINE_GETIMPL_STORE(DILabel, (Line, Column, IsArtificial, CoroSuspendIdx),
                       Ops);
}

DIExpression *DIExpression::getImpl(LLVMContext &Context,
                                    ArrayRef<uint64_t> Elements,
                                    StorageType Storage, bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DIExpression, (Elements));
  DEFINE_GETIMPL_STORE_NO_OPS(DIExpression, (Elements));
}
bool DIExpression::isEntryValue() const {
  if (auto singleLocElts = getSingleLocationExpressionElements()) {
    return singleLocElts->size() > 0 &&
           (*singleLocElts)[0] == dwarf::DW_OP_LLVM_entry_value;
  }
  return false;
}
bool DIExpression::startsWithDeref() const {
  if (auto singleLocElts = getSingleLocationExpressionElements())
    return singleLocElts->size() > 0 &&
           (*singleLocElts)[0] == dwarf::DW_OP_deref;
  return false;
}
bool DIExpression::isDeref() const {
  if (auto singleLocElts = getSingleLocationExpressionElements())
    return singleLocElts->size() == 1 &&
           (*singleLocElts)[0] == dwarf::DW_OP_deref;
  return false;
}

DIAssignID *DIAssignID::getImpl(LLVMContext &Context, StorageType Storage,
                                bool ShouldCreate) {
  // Uniqued DIAssignID are not supported as the instance address *is* the ID.
  assert(Storage != StorageType::Uniqued && "uniqued DIAssignID unsupported");
  return storeImpl(new (0u, Storage) DIAssignID(Context, Storage), Storage);
}

unsigned DIExpression::ExprOperand::getSize() const {
  uint64_t Op = getOp();

  if (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31)
    return 2;

  switch (Op) {
  case dwarf::DW_OP_LLVM_convert:
  case dwarf::DW_OP_LLVM_fragment:
  case dwarf::DW_OP_LLVM_extract_bits_sext:
  case dwarf::DW_OP_LLVM_extract_bits_zext:
  case dwarf::DW_OP_bregx:
    return 3;
  case dwarf::DW_OP_constu:
  case dwarf::DW_OP_consts:
  case dwarf::DW_OP_deref_size:
  case dwarf::DW_OP_xderef_size:
  case dwarf::DW_OP_plus_uconst:
  case dwarf::DW_OP_LLVM_tag_offset:
  case dwarf::DW_OP_LLVM_entry_value:
  case dwarf::DW_OP_LLVM_arg:
  case dwarf::DW_OP_regx:
    return 2;
  default:
    return 1;
  }
}

bool DIExpression::ExprOperand::isNonEmitting() const {
  return getOp() == dwarf::DW_OP_LLVM_tag_offset;
}

bool DIExpression::ArgOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_LLVM_arg);
}

bool DIExpression::FragmentOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_LLVM_fragment);
}

bool DIExpression::ExtractBitsOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_LLVM_extract_bits_sext) ||
         Op->is(dwarf::DW_OP_LLVM_extract_bits_zext);
}

bool DIExpression::ExtractBitsOp::isSigned() const {
  return is(dwarf::DW_OP_LLVM_extract_bits_sext);
}

bool DIExpression::ConvertOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_LLVM_convert);
}

bool DIExpression::EntryValueOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_LLVM_entry_value);
}

bool DIExpression::TagOffsetOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_LLVM_tag_offset);
}

bool DIExpression::ConstuOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_constu);
}

bool DIExpression::PlusUconstOp::classof(const ExprOperand *Op) {
  return Op->is(dwarf::DW_OP_plus_uconst);
}

bool DIExpression::isLitOp(uint64_t Op) {
  return Op >= dwarf::DW_OP_lit0 && Op <= dwarf::DW_OP_lit31;
}

bool DIExpression::isValid() const {
  for (auto I = expr_op_begin(), E = expr_op_end(); I != E; ++I) {
    // Check that there's space for the operand.
    if (I->getSize() > static_cast<uint64_t>(E->get() - I->get()))
      return false;

    uint64_t Op = I->getOp();
    if ((Op >= dwarf::DW_OP_reg0 && Op <= dwarf::DW_OP_reg31) ||
        (Op >= dwarf::DW_OP_breg0 && Op <= dwarf::DW_OP_breg31) || isLitOp(Op))
      continue;

    // Check that the operand is valid.
    switch (Op) {
    default:
      return false;
    case dwarf::DW_OP_LLVM_fragment:
      // A fragment operator must appear at the end.
      return I->get() + I->getSize() == E->get();
    case dwarf::DW_OP_stack_value: {
      // Must be the last one or followed by a DW_OP_LLVM_fragment.
      if (I->get() + I->getSize() == E->get())
        break;
      auto J = I;
      if ((++J)->getOp() != dwarf::DW_OP_LLVM_fragment)
        return false;
      break;
    }
    case dwarf::DW_OP_swap: {
      // Must be more than one implicit element on the stack.

      // FIXME: A better way to implement this would be to add a local variable
      // that keeps track of the stack depth and introduce something like a
      // DW_LLVM_OP_implicit_location as a placeholder for the location this
      // DIExpression is attached to, or else pass the number of implicit stack
      // elements into isValid.
      if (getNumElements() == 1)
        return false;
      break;
    }
    case dwarf::DW_OP_LLVM_entry_value: {
      // An entry value operator must appear at the beginning or immediately
      // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
      // currently only be 1, because we support only entry values of a simple
      // register location. One reason for this is that we currently can't
      // calculate the size of the resulting DWARF block for other expressions.
      auto FirstOp = expr_op_begin();
      if (auto Arg = dyn_cast<ArgOp>(*FirstOp); Arg && Arg.getIndex() == 0)
        ++FirstOp;
      if (I->get() != FirstOp->get() ||
          cast<EntryValueOp>(*I).getNumOperations() != 1)
        return false;
      break;
    }
    case dwarf::DW_OP_deref_size:
    case dwarf::DW_OP_xderef_size:
      // The size operand is encoded as a single byte.
      if (!isUInt<8>(I->getArg(0)))
        return false;
      break;
    case dwarf::DW_OP_LLVM_implicit_pointer:
    case dwarf::DW_OP_LLVM_convert:
    case dwarf::DW_OP_LLVM_arg:
    case dwarf::DW_OP_LLVM_tag_offset:
    case dwarf::DW_OP_LLVM_extract_bits_sext:
    case dwarf::DW_OP_LLVM_extract_bits_zext:
    case dwarf::DW_OP_constu:
    case dwarf::DW_OP_plus_uconst:
    case dwarf::DW_OP_plus:
    case dwarf::DW_OP_minus:
    case dwarf::DW_OP_mul:
    case dwarf::DW_OP_div:
    case dwarf::DW_OP_mod:
    case dwarf::DW_OP_or:
    case dwarf::DW_OP_and:
    case dwarf::DW_OP_xor:
    case dwarf::DW_OP_shl:
    case dwarf::DW_OP_shr:
    case dwarf::DW_OP_shra:
    case dwarf::DW_OP_deref:
    case dwarf::DW_OP_xderef:
    case dwarf::DW_OP_not:
    case dwarf::DW_OP_dup:
    case dwarf::DW_OP_regx:
    case dwarf::DW_OP_bregx:
    case dwarf::DW_OP_push_object_address:
    case dwarf::DW_OP_over:
    case dwarf::DW_OP_rot:
    case dwarf::DW_OP_consts:
    case dwarf::DW_OP_eq:
    case dwarf::DW_OP_ne:
    case dwarf::DW_OP_gt:
    case dwarf::DW_OP_ge:
    case dwarf::DW_OP_lt:
    case dwarf::DW_OP_le:
    case dwarf::DW_OP_neg:
    case dwarf::DW_OP_abs:
      break;
    }
  }
  return true;
}

bool DIExpression::isImplicit() const {
  if (!isValid())
    return false;

  if (getNumElements() == 0)
    return false;

  for (const auto &It : expr_ops()) {
    switch (It.getOp()) {
    default:
      break;
    case dwarf::DW_OP_stack_value:
      return true;
    }
  }

  return false;
}

bool DIExpression::isComplex() const {
  if (!isValid())
    return false;

  if (getNumElements() == 0)
    return false;

  // Tag offsets are non-emitting. They, fragments, and location operands don't
  // perform a computation by themselves.
  for (const auto &It : expr_ops()) {
    if (It.isNonEmitting())
      continue;
    switch (It.getOp()) {
    case dwarf::DW_OP_LLVM_fragment:
    case dwarf::DW_OP_LLVM_arg:
      continue;
    default:
      return true;
    }
  }

  return false;
}

bool DIExpression::isSingleLocationExpression() const {
  if (!isValid())
    return false;

  if (getNumElements() == 0)
    return true;

  auto ExprOpBegin = expr_ops().begin();
  auto ExprOpEnd = expr_ops().end();
  if (auto Arg = dyn_cast<ArgOp>(*ExprOpBegin)) {
    if (Arg.getIndex() != 0)
      return false;
    ++ExprOpBegin;
  }

  return !std::any_of(ExprOpBegin, ExprOpEnd,
                      [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); });
}

std::optional<ArrayRef<uint64_t>>
DIExpression::getSingleLocationExpressionElements() const {
  // Check for `isValid` covered by `isSingleLocationExpression`.
  if (!isSingleLocationExpression())
    return std::nullopt;

  // An empty expression is already non-variadic.
  if (!getNumElements())
    return ArrayRef<uint64_t>();

  // If Expr does not have a leading DW_OP_LLVM_arg then we don't need to do
  // anything.
  if (getElements()[0] == dwarf::DW_OP_LLVM_arg)
    return getElements().drop_front(2);
  return getElements();
}

const DIExpression *
DIExpression::convertToUndefExpression(const DIExpression *Expr) {
  SmallVector<uint64_t, 3> UndefOps;
  if (auto FragmentInfo = Expr->getFragmentInfo()) {
    UndefOps.append({dwarf::DW_OP_LLVM_fragment, FragmentInfo->OffsetInBits,
                     FragmentInfo->SizeInBits});
  }
  return DIExpression::get(Expr->getContext(), UndefOps);
}

const DIExpression *
DIExpression::convertToVariadicExpression(const DIExpression *Expr) {
  if (any_of(Expr->expr_ops(), [](auto ExprOp) {
        return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
      }))
    return Expr;
  SmallVector<uint64_t> NewOps;
  NewOps.reserve(Expr->getNumElements() + 2);
  NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
  NewOps.append(Expr->elements_begin(), Expr->elements_end());
  return DIExpression::get(Expr->getContext(), NewOps);
}

std::optional<const DIExpression *>
DIExpression::convertToNonVariadicExpression(const DIExpression *Expr) {
  if (!Expr)
    return std::nullopt;

  if (auto Elts = Expr->getSingleLocationExpressionElements())
    return DIExpression::get(Expr->getContext(), *Elts);

  return std::nullopt;
}

void DIExpression::canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops,
                                             const DIExpression *Expr,
                                             bool IsIndirect) {
  // If Expr is not already variadic, insert the implied `DW_OP_LLVM_arg 0`
  // to the existing expression ops.
  if (none_of(Expr->expr_ops(), [](auto ExprOp) {
        return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
      }))
    Ops.append({dwarf::DW_OP_LLVM_arg, 0});
  // If Expr is not indirect, we only need to insert the expression elements and
  // we're done.
  if (!IsIndirect) {
    Ops.append(Expr->elements_begin(), Expr->elements_end());
    return;
  }
  // If Expr is indirect, insert the implied DW_OP_deref at the end of the
  // expression but before DW_OP_{stack_value, LLVM_fragment} if they are
  // present.
  for (auto Op : Expr->expr_ops()) {
    if (Op.getOp() == dwarf::DW_OP_stack_value ||
        Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
      Ops.push_back(dwarf::DW_OP_deref);
      IsIndirect = false;
    }
    Op.appendToVector(Ops);
  }
  if (IsIndirect)
    Ops.push_back(dwarf::DW_OP_deref);
}

bool DIExpression::isEqualExpression(const DIExpression *FirstExpr,
                                     bool FirstIndirect,
                                     const DIExpression *SecondExpr,
                                     bool SecondIndirect) {
  SmallVector<uint64_t> FirstOps;
  DIExpression::canonicalizeExpressionOps(FirstOps, FirstExpr, FirstIndirect);
  SmallVector<uint64_t> SecondOps;
  DIExpression::canonicalizeExpressionOps(SecondOps, SecondExpr,
                                          SecondIndirect);
  return FirstOps == SecondOps;
}

std::optional<DIExpression::FragmentInfo>
DIExpression::getFragmentInfo(expr_op_iterator Start, expr_op_iterator End) {
  for (auto I = Start; I != End; ++I)
    if (auto Fragment = dyn_cast<FragmentOp>(*I))
      return FragmentInfo{Fragment.getSizeInBits(), Fragment.getOffsetInBits()};
  return std::nullopt;
}

std::optional<uint64_t> DIExpression::getActiveBits(DIVariable *Var) {
  std::optional<uint64_t> InitialActiveBits = Var->getSizeInBits();
  std::optional<uint64_t> ActiveBits = InitialActiveBits;
  auto NarrowActiveBits = [&](uint64_t SizeInBits) {
    ActiveBits = ActiveBits ? std::min(*ActiveBits, SizeInBits) : SizeInBits;
  };

  for (auto Op : expr_ops()) {
    switch (Op.getOp()) {
    default:
      // We assume the worst case for anything we don't currently handle and
      // revert to the initial active bits.
      ActiveBits = InitialActiveBits;
      break;
    case dwarf::DW_OP_LLVM_extract_bits_zext:
    case dwarf::DW_OP_LLVM_extract_bits_sext: {
      auto Extract = cast<ExtractBitsOp>(Op);
      // We can't handle an extract whose sign doesn't match that of the
      // variable.
      std::optional<DIBasicType::Signedness> VarSign = Var->getSignedness();
      bool VarSigned = (VarSign == DIBasicType::Signedness::Signed);
      if (!VarSign || VarSigned != Extract.isSigned()) {
        ActiveBits = InitialActiveBits;
        break;
      }
      NarrowActiveBits(Extract.getSizeInBits());
      break;
    }
    case dwarf::DW_OP_LLVM_fragment:
      NarrowActiveBits(cast<FragmentOp>(Op).getSizeInBits());
      break;
    }
  }
  return ActiveBits;
}

void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,
                                int64_t Offset) {
  if (Offset > 0) {
    Ops.push_back(dwarf::DW_OP_plus_uconst);
    Ops.push_back(Offset);
  } else if (Offset < 0) {
    Ops.push_back(dwarf::DW_OP_constu);
    // Avoid UB when encountering LLONG_MIN, because in 2's complement
    // abs(LLONG_MIN) is LLONG_MAX+1.
    uint64_t AbsMinusOne = -(Offset+1);
    Ops.push_back(AbsMinusOne + 1);
    Ops.push_back(dwarf::DW_OP_minus);
  }
}

bool DIExpression::extractIfOffset(int64_t &Offset) const {
  auto SingleLocEltsOpt = getSingleLocationExpressionElements();
  if (!SingleLocEltsOpt)
    return false;
  auto SingleLocElts = *SingleLocEltsOpt;

  if (SingleLocElts.size() == 0) {
    Offset = 0;
    return true;
  }

  if (SingleLocElts.size() == 2 &&
      SingleLocElts[0] == dwarf::DW_OP_plus_uconst) {
    Offset = SingleLocElts[1];
    return true;
  }

  if (SingleLocElts.size() == 3 && SingleLocElts[0] == dwarf::DW_OP_constu) {
    if (SingleLocElts[2] == dwarf::DW_OP_plus) {
      Offset = SingleLocElts[1];
      return true;
    }
    if (SingleLocElts[2] == dwarf::DW_OP_minus) {
      Offset = -SingleLocElts[1];
      return true;
    }
  }

  return false;
}

bool DIExpression::extractLeadingOffset(
    ArrayRef<uint64_t> Ops, int64_t &OffsetInBytes,
    SmallVectorImpl<uint64_t> &RemainingOps) {
  OffsetInBytes = 0;
  RemainingOps.clear();

  auto ExprOpEnd = expr_op_iterator(Ops.end());
  auto ExprOpIt = expr_op_iterator(Ops.begin());
  while (ExprOpIt != ExprOpEnd) {
    uint64_t Op = ExprOpIt->getOp();
    if (Op == dwarf::DW_OP_deref || Op == dwarf::DW_OP_deref_size ||
        Op == dwarf::DW_OP_deref_type || Op == dwarf::DW_OP_LLVM_fragment ||
        Op == dwarf::DW_OP_LLVM_extract_bits_zext ||
        Op == dwarf::DW_OP_LLVM_extract_bits_sext) {
      break;
    } else if (auto PlusUconst = dyn_cast<PlusUconstOp>(*ExprOpIt)) {
      OffsetInBytes += PlusUconst.getOffset();
    } else if (auto Constant = dyn_cast<ConstuOp>(*ExprOpIt)) {
      uint64_t Value = Constant.getValue();
      ++ExprOpIt;
      if (ExprOpIt->getOp() == dwarf::DW_OP_plus)
        OffsetInBytes += Value;
      else if (ExprOpIt->getOp() == dwarf::DW_OP_minus)
        OffsetInBytes -= Value;
      else
        return false;
    } else {
      // Not a const plus/minus operation or deref.
      return false;
    }
    ++ExprOpIt;
  }
  RemainingOps.append(ExprOpIt.getBase(), ExprOpEnd.getBase());
  return true;
}

bool DIExpression::extractLeadingOffset(
    int64_t &OffsetInBytes, SmallVectorImpl<uint64_t> &RemainingOps) const {
  auto SingleLocEltsOpt = getSingleLocationExpressionElements();
  if (!SingleLocEltsOpt) {
    OffsetInBytes = 0;
    RemainingOps.clear();
    return false;
  }

  return extractLeadingOffset(*SingleLocEltsOpt, OffsetInBytes, RemainingOps);
}

bool DIExpression::hasAllLocationOps(unsigned N) const {
  SmallDenseSet<uint64_t, 4> SeenOps;
  for (auto ExprOp : expr_ops())
    if (auto Arg = dyn_cast<ArgOp>(ExprOp))
      SeenOps.insert(Arg.getIndex());
  for (uint64_t Idx = 0; Idx < N; ++Idx)
    if (!SeenOps.contains(Idx))
      return false;
  return true;
}

const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,
                                                      unsigned &AddrClass) {
  if (!Expr->isValid())
    return Expr;
  auto SingleLocEltsOpt = Expr->getSingleLocationExpressionElements();
  if (!SingleLocEltsOpt)
    return Expr;
  ArrayRef<uint64_t> SingleLocElts = *SingleLocEltsOpt;

  // Walk the operations, rather than the raw elements, so that operands are
  // never mistaken for opcodes.
  SmallVector<ExprOperand, 8> Ops(expr_op_iterator(SingleLocElts.begin()),
                                  expr_op_iterator(SingleLocElts.end()));
  if (Ops.size() < 3)
    return Expr;
  const ExprOperand &AddrSpaceOp = Ops[Ops.size() - 3];
  const ExprOperand &SwapOp = Ops[Ops.size() - 2];
  const ExprOperand &XDerefOp = Ops[Ops.size() - 1];
  if (!SwapOp.is(dwarf::DW_OP_swap) || !(XDerefOp.is(dwarf::DW_OP_xderef) ||
                                         XDerefOp.is(dwarf::DW_OP_xderef_size)))
    return Expr;

  uint64_t Op = AddrSpaceOp.getOp();
  if (Op == dwarf::DW_OP_constu)
    AddrClass = AddrSpaceOp.getArg(0);
  else if (isLitOp(Op))
    AddrClass = Op - dwarf::DW_OP_lit0;
  else
    return Expr;

  if (AddrSpaceOp.get() == SingleLocElts.begin())
    return nullptr;
  return DIExpression::get(Expr->getContext(),
                           ArrayRef(SingleLocElts.begin(), AddrSpaceOp.get()));
}

DIExpression *DIExpression::prepend(const DIExpression *Expr, uint8_t Flags,
                                    int64_t Offset) {
  SmallVector<uint64_t, 8> Ops;
  if (Flags & DIExpression::DerefBefore)
    Ops.push_back(dwarf::DW_OP_deref);

  appendOffset(Ops, Offset);
  if (Flags & DIExpression::DerefAfter)
    Ops.push_back(dwarf::DW_OP_deref);

  bool StackValue = Flags & DIExpression::StackValue;
  bool EntryValue = Flags & DIExpression::EntryValue;

  return prependOpcodes(Expr, Ops, StackValue, EntryValue);
}

DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
                                           ArrayRef<uint64_t> Ops,
                                           unsigned ArgNo, bool StackValue) {
  assert(Expr && "Can't add ops to this expression");

  // Handle non-variadic intrinsics by prepending the opcodes.
  if (!any_of(Expr->expr_ops(),
              [](auto Op) { return Op.is(dwarf::DW_OP_LLVM_arg); })) {
    assert(ArgNo == 0 &&
           "Location Index must be 0 for a non-variadic expression.");
    SmallVector<uint64_t, 8> NewOps(Ops);
    return DIExpression::prependOpcodes(Expr, NewOps, StackValue);
  }

  SmallVector<uint64_t, 8> NewOps;
  for (auto Op : Expr->expr_ops()) {
    // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
    if (StackValue) {
      if (Op.getOp() == dwarf::DW_OP_stack_value)
        StackValue = false;
      else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
        NewOps.push_back(dwarf::DW_OP_stack_value);
        StackValue = false;
      }
    }
    Op.appendToVector(NewOps);
    if (auto Arg = dyn_cast<ArgOp>(Op); Arg && Arg.getIndex() == ArgNo)
      llvm::append_range(NewOps, Ops);
  }
  if (StackValue)
    NewOps.push_back(dwarf::DW_OP_stack_value);

  return DIExpression::get(Expr->getContext(), NewOps);
}

DIExpression *DIExpression::replaceArg(const DIExpression *Expr,
                                       uint64_t OldArg, uint64_t NewArg) {
  assert(Expr && "Can't replace args in this expression");

  SmallVector<uint64_t, 8> NewOps;

  for (auto Op : Expr->expr_ops()) {
    auto Arg = dyn_cast<ArgOp>(Op);
    if (!Arg || Arg.getIndex() < OldArg) {
      Op.appendToVector(NewOps);
      continue;
    }
    NewOps.push_back(dwarf::DW_OP_LLVM_arg);
    uint64_t ArgIndex = Arg.getIndex() == OldArg ? NewArg : Arg.getIndex();
    // OldArg has been deleted from the Op list, so decrement all indices
    // greater than it.
    if (ArgIndex > OldArg)
      --ArgIndex;
    NewOps.push_back(ArgIndex);
  }
  return DIExpression::get(Expr->getContext(), NewOps);
}

DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
                                           SmallVectorImpl<uint64_t> &Ops,
                                           bool StackValue, bool EntryValue) {
  assert(Expr && "Can't prepend ops to this expression");

  if (EntryValue) {
    Ops.push_back(dwarf::DW_OP_LLVM_entry_value);
    // Use a block size of 1 for the target register operand.  The
    // DWARF backend currently cannot emit entry values with a block
    // size > 1.
    Ops.push_back(1);
  }

  // If there are no ops to prepend, do not even add the DW_OP_stack_value.
  if (Ops.empty())
    StackValue = false;
  for (auto Op : Expr->expr_ops()) {
    // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
    if (StackValue) {
      if (Op.getOp() == dwarf::DW_OP_stack_value)
        StackValue = false;
      else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
        Ops.push_back(dwarf::DW_OP_stack_value);
        StackValue = false;
      }
    }
    Op.appendToVector(Ops);
  }
  if (StackValue)
    Ops.push_back(dwarf::DW_OP_stack_value);
  return DIExpression::get(Expr->getContext(), Ops);
}

DIExpression *DIExpression::append(const DIExpression *Expr,
                                   ArrayRef<uint64_t> Ops) {
  assert(Expr && !Ops.empty() && "Can't append ops to this expression");

  // Copy Expr's current op list.
  SmallVector<uint64_t, 16> NewOps;
  for (auto Op : Expr->expr_ops()) {
    // Append new opcodes before DW_OP_{stack_value, LLVM_fragment}.
    if (Op.getOp() == dwarf::DW_OP_stack_value ||
        Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
      NewOps.append(Ops.begin(), Ops.end());

      // Ensure that the new opcodes are only appended once.
      Ops = {};
    }
    Op.appendToVector(NewOps);
  }
  NewOps.append(Ops.begin(), Ops.end());
  auto *result =
      DIExpression::get(Expr->getContext(), NewOps)->foldConstantMath();
  assert(result->isValid() && "concatenated expression is not valid");
  return result;
}

DIExpression *DIExpression::appendToStack(const DIExpression *Expr,
                                          ArrayRef<uint64_t> Ops) {
  assert(Expr && !Ops.empty() && "Can't append ops to this expression");
  assert(std::none_of(expr_op_iterator(Ops.begin()),
                      expr_op_iterator(Ops.end()),
                      [](auto Op) {
                        return Op.getOp() == dwarf::DW_OP_stack_value ||
                               Op.getOp() == dwarf::DW_OP_LLVM_fragment;
                      }) &&
         "Can't append this op");

  // DIExpression stores opcodes and their arguments in a flat array. Walk the
  // parsed operations to find the last opcode that determines whether the
  // expression already ends in DW_OP_stack_value.
  std::optional<uint64_t> LastValueOp;
  for (auto Op : Expr->expr_ops()) {
    if (Op.isNonEmitting() || Op.getOp() == dwarf::DW_OP_LLVM_fragment)
      continue;
    LastValueOp = Op.getOp();
  }
  bool NeedsDeref = LastValueOp && *LastValueOp != dwarf::DW_OP_stack_value;
  bool NeedsStackValue = NeedsDeref || !LastValueOp;

  // Append a DW_OP_deref after Expr's current op list if needed, then append
  // the new ops, and finally ensure that a single DW_OP_stack_value is present.
  SmallVector<uint64_t, 16> NewOps;
  if (NeedsDeref)
    NewOps.push_back(dwarf::DW_OP_deref);
  NewOps.append(Ops.begin(), Ops.end());
  if (NeedsStackValue)
    NewOps.push_back(dwarf::DW_OP_stack_value);
  return DIExpression::append(Expr, NewOps);
}

std::optional<DIExpression *> DIExpression::createFragmentExpression(
    const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
  SmallVector<uint64_t, 8> Ops;
  // Track whether it's safe to split the value at the top of the DWARF stack,
  // assuming that it'll be used as an implicit location value.
  bool CanSplitValue = true;
  // Track whether we need to add a fragment expression to the end of Expr.
  bool EmitFragment = true;
  // Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
  if (Expr) {
    for (auto Op : Expr->expr_ops()) {
      switch (Op.getOp()) {
      default:
        break;
      case dwarf::DW_OP_shr:
      case dwarf::DW_OP_shra:
      case dwarf::DW_OP_shl:
      case dwarf::DW_OP_plus:
      case dwarf::DW_OP_plus_uconst:
      case dwarf::DW_OP_minus:
        // We can't safely split arithmetic or shift operations into multiple
        // fragments because we can't express carry-over between fragments.
        //
        // FIXME: We *could* preserve the lowest fragment of a constant offset
        // operation if the offset fits into SizeInBits.
        CanSplitValue = false;
        break;
      case dwarf::DW_OP_deref:
      case dwarf::DW_OP_deref_size:
      case dwarf::DW_OP_deref_type:
      case dwarf::DW_OP_xderef:
      case dwarf::DW_OP_xderef_size:
      case dwarf::DW_OP_xderef_type:
        // Preceeding arithmetic operations have been applied to compute an
        // address. It's okay to split the value loaded from that address.
        CanSplitValue = true;
        break;
      case dwarf::DW_OP_stack_value:
        // Bail if this expression computes a value that cannot be split.
        if (!CanSplitValue)
          return std::nullopt;
        break;
      case dwarf::DW_OP_LLVM_fragment: {
        auto Fragment = cast<FragmentOp>(Op);
        // If we've decided we don't need a fragment then give up if we see that
        // there's already a fragment expression.
        // FIXME: We could probably do better here
        if (!EmitFragment)
          return std::nullopt;
        // Make the new offset point into the existing fragment.
        uint64_t FragmentOffsetInBits = Fragment.getOffsetInBits();
        uint64_t FragmentSizeInBits = Fragment.getSizeInBits();
        (void)FragmentSizeInBits;
        assert((OffsetInBits + SizeInBits <= FragmentSizeInBits) &&
               "new fragment outside of original fragment");
        OffsetInBits += FragmentOffsetInBits;
        continue;
      }
      case dwarf::DW_OP_LLVM_extract_bits_zext:
      case dwarf::DW_OP_LLVM_extract_bits_sext: {
        auto Extract = cast<ExtractBitsOp>(Op);
        // If we're extracting bits from inside of the fragment that we're
        // creating then we don't have a fragment after all, and just need to
        // adjust the offset that we're extracting from.
        uint64_t ExtractOffsetInBits = Extract.getOffsetInBits();
        uint64_t ExtractSizeInBits = Extract.getSizeInBits();
        if (ExtractOffsetInBits >= OffsetInBits &&
            ExtractOffsetInBits + ExtractSizeInBits <=
                OffsetInBits + SizeInBits) {
          Ops.push_back(Op.getOp());
          Ops.push_back(ExtractOffsetInBits - OffsetInBits);
          Ops.push_back(ExtractSizeInBits);
          EmitFragment = false;
          continue;
        }
        // If the extracted bits aren't fully contained within the fragment then
        // give up.
        // FIXME: We could probably do better here
        return std::nullopt;
      }
      }
      Op.appendToVector(Ops);
    }
  }
  assert((!Expr->isImplicit() || CanSplitValue) && "Expr can't be split");
  assert(Expr && "Unknown DIExpression");
  if (EmitFragment) {
    Ops.push_back(dwarf::DW_OP_LLVM_fragment);
    Ops.push_back(OffsetInBits);
    Ops.push_back(SizeInBits);
  }
  return DIExpression::get(Expr->getContext(), Ops);
}

/// See declaration for more info.
bool DIExpression::calculateFragmentIntersect(
    const DataLayout &DL, const Value *SliceStart, uint64_t SliceOffsetInBits,
    uint64_t SliceSizeInBits, const Value *DbgPtr, int64_t DbgPtrOffsetInBits,
    int64_t DbgExtractOffsetInBits, DIExpression::FragmentInfo VarFrag,
    std::optional<DIExpression::FragmentInfo> &Result,
    int64_t &OffsetFromLocationInBits) {

  if (VarFrag.SizeInBits == 0)
    return false; // Variable size is unknown.

  // Difference between mem slice start and the dbg location start.
  // 0   4   8   12   16 ...
  // |       |
  // dbg location start
  //         |
  //         mem slice start
  // Here MemStartRelToDbgStartInBits is 8. Note this can be negative.
  int64_t MemStartRelToDbgStartInBits;
  {
    auto MemOffsetFromDbgInBytes = SliceStart->getPointerOffsetFrom(DbgPtr, DL);
    if (!MemOffsetFromDbgInBytes)
      return false; // Can't calculate difference in addresses.
    // Difference between the pointers.
    MemStartRelToDbgStartInBits = *MemOffsetFromDbgInBytes * 8;
    // Add the difference of the offsets.
    MemStartRelToDbgStartInBits +=
        SliceOffsetInBits - (DbgPtrOffsetInBits + DbgExtractOffsetInBits);
  }

  // Out-param. Invert offset to get offset from debug location.
  OffsetFromLocationInBits = -MemStartRelToDbgStartInBits;

  // Check if the variable fragment sits outside (before) this memory slice.
  int64_t MemEndRelToDbgStart = MemStartRelToDbgStartInBits + SliceSizeInBits;
  if (MemEndRelToDbgStart < 0) {
    Result = {0, 0}; // Out-param.
    return true;
  }

  // Work towards creating SliceOfVariable which is the bits of the variable
  // that the memory region covers.
  // 0   4   8   12   16 ...
  // |       |
  // dbg location start with VarFrag offset=32
  //         |
  //         mem slice start: SliceOfVariable offset=40
  int64_t MemStartRelToVarInBits =
      MemStartRelToDbgStartInBits + VarFrag.OffsetInBits;
  int64_t MemEndRelToVarInBits = MemStartRelToVarInBits + SliceSizeInBits;
  // If the memory region starts before the debug location the fragment
  // offset would be negative, which we can't encode. Limit those to 0. This
  // is fine because those bits necessarily don't overlap with the existing
  // variable fragment.
  int64_t MemFragStart = std::max<int64_t>(0, MemStartRelToVarInBits);
  int64_t MemFragSize =
      std::max<int64_t>(0, MemEndRelToVarInBits - MemFragStart);
  DIExpression::FragmentInfo SliceOfVariable(MemFragSize, MemFragStart);

  // Intersect the memory region fragment with the variable location fragment.
  DIExpression::FragmentInfo TrimmedSliceOfVariable =
      DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);
  if (TrimmedSliceOfVariable == VarFrag)
    Result = std::nullopt; // Out-param.
  else
    Result = TrimmedSliceOfVariable; // Out-param.
  return true;
}

std::pair<DIExpression *, const ConstantInt *>
DIExpression::constantFold(const ConstantInt *CI) {
  // Copy the APInt so we can modify it.
  APInt NewInt = CI->getValue();
  SmallVector<uint64_t, 8> Ops;

  // Fold operators only at the beginning of the expression.
  bool First = true;
  bool Changed = false;
  for (auto Op : expr_ops()) {
    switch (Op.getOp()) {
    default:
      // We fold only the leading part of the expression; if we get to a part
      // that we're going to copy unchanged, and haven't done any folding,
      // then the entire expression is unchanged and we can return early.
      if (!Changed)
        return {this, CI};
      First = false;
      break;
    case dwarf::DW_OP_LLVM_convert: {
      if (!First)
        break;
      Changed = true;
      auto Convert = cast<ConvertOp>(Op);
      if (Convert.getEncoding() == dwarf::DW_ATE_signed)
        NewInt = NewInt.sextOrTrunc(Convert.getBitSize());
      else {
        assert(Convert.getEncoding() == dwarf::DW_ATE_unsigned &&
               "Unexpected operand");
        NewInt = NewInt.zextOrTrunc(Convert.getBitSize());
      }
      continue;
    }
    }
    Op.appendToVector(Ops);
  }
  if (!Changed)
    return {this, CI};
  return {DIExpression::get(getContext(), Ops),
          ConstantInt::get(getContext(), NewInt)};
}

uint64_t DIExpression::getNumLocationOperands() const {
  uint64_t Result = 0;
  for (auto ExprOp : expr_ops())
    if (auto Arg = dyn_cast<ArgOp>(ExprOp))
      Result = std::max(Result, Arg.getIndex() + 1);
  assert(hasAllLocationOps(Result) &&
         "Expression is missing one or more location operands.");
  return Result;
}

std::optional<DIExpression::SignedOrUnsignedConstant>
DIExpression::isConstant() const {

  // Recognize signed and unsigned constants.
  // An signed constants can be represented as DW_OP_consts C DW_OP_stack_value
  // (DW_OP_LLVM_fragment of Len).
  // An unsigned constant can be represented as
  // DW_OP_constu C DW_OP_stack_value (DW_OP_LLVM_fragment of Len), or as
  // DW_OP_lit<C> DW_OP_stack_value (DW_OP_LLVM_fragment of Len).

  if (getNumElements() == 0)
    return std::nullopt;
  uint64_t Op = getElement(0);
  if (Op != dwarf::DW_OP_consts && Op != dwarf::DW_OP_constu && !isLitOp(Op))
    return std::nullopt;

  // The number of elements used by the constant: DW_OP_lit<C> encodes its
  // value in the opcode, while DW_OP_constu/DW_OP_consts take an operand.
  unsigned ConstSize = expr_op_begin()->getSize();
  unsigned NumElements = getNumElements();
  // The constant may be followed by DW_OP_stack_value (1 element), and then
  // by DW_OP_LLVM_fragment, offset, size (3 more elements).
  if (NumElements != ConstSize && NumElements != ConstSize + 1 &&
      NumElements != ConstSize + 4)
    return std::nullopt;

  if (NumElements == ConstSize && Op == dwarf::DW_OP_consts)
    return SignedOrUnsignedConstant::SignedConstant;

  if ((NumElements == ConstSize + 1 &&
       getElement(ConstSize) != dwarf::DW_OP_stack_value) ||
      (NumElements == ConstSize + 4 &&
       (getElement(ConstSize) != dwarf::DW_OP_stack_value ||
        getElement(ConstSize + 1) != dwarf::DW_OP_LLVM_fragment)))
    return std::nullopt;
  return Op == dwarf::DW_OP_consts ? SignedOrUnsignedConstant::SignedConstant
                                   : SignedOrUnsignedConstant::UnsignedConstant;
}

uint64_t DIExpression::getConstantValue() const {
  assert(isConstant() && "Expression is not a constant");
  uint64_t Op = getElement(0);
  if (isLitOp(Op))
    return Op - dwarf::DW_OP_lit0;
  return getElement(1);
}

DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
                                             bool Signed) {
  dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
  DIExpression::ExtOps Ops{{dwarf::DW_OP_LLVM_convert, FromSize, TK,
                            dwarf::DW_OP_LLVM_convert, ToSize, TK}};
  return Ops;
}

DIExpression *DIExpression::appendExt(const DIExpression *Expr,
                                      unsigned FromSize, unsigned ToSize,
                                      bool Signed) {
  return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
}

DIGlobalVariableExpression *
DIGlobalVariableExpression::getImpl(LLVMContext &Context, Metadata *Variable,
                                    Metadata *Expression, StorageType Storage,
                                    bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DIGlobalVariableExpression, (Variable, Expression));
  Metadata *Ops[] = {Variable, Expression};
  DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(DIGlobalVariableExpression, Ops);
}
DIObjCProperty::DIObjCProperty(LLVMContext &C, StorageType Storage,
                               unsigned Line, unsigned Attributes,
                               ArrayRef<Metadata *> Ops)
    : DINode(C, DIObjCPropertyKind, Storage, dwarf::DW_TAG_APPLE_property, Ops),
      Line(Line), Attributes(Attributes) {}

DIObjCProperty *DIObjCProperty::getImpl(
    LLVMContext &Context, MDString *Name, Metadata *File, unsigned Line,
    MDString *GetterName, MDString *SetterName, unsigned Attributes,
    Metadata *Type, StorageType Storage, bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  assert(isCanonical(GetterName) && "Expected canonical MDString");
  assert(isCanonical(SetterName) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIObjCProperty, (Name, File, Line, GetterName,
                                         SetterName, Attributes, Type));
  Metadata *Ops[] = {Name, File, GetterName, SetterName, Type};
  DEFINE_GETIMPL_STORE(DIObjCProperty, (Line, Attributes), Ops);
}

DIProperty::DIProperty(LLVMContext &C, StorageType Storage, unsigned Line,
                       ArrayRef<Metadata *> Ops)
    : DINode(C, DIPropertyKind, Storage, dwarf::DW_TAG_property, Ops),
      Line(Line) {}

DIProperty *DIProperty::getImpl(LLVMContext &Context, MDString *Name,
                                Metadata *File, unsigned Line, Metadata *Type,
                                Metadata *BackingStorage, StorageType Storage,
                                bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIProperty, (Name, File, Line, Type, BackingStorage));
  Metadata *Ops[] = {Name, File, Type, BackingStorage};
  DEFINE_GETIMPL_STORE(DIProperty, (Line), Ops);
}

DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
                                            Metadata *Scope, Metadata *Entity,
                                            Metadata *File, unsigned Line,
                                            MDString *Name, Metadata *Elements,
                                            StorageType Storage,
                                            bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
                        (Tag, Scope, Entity, File, Line, Name, Elements));
  Metadata *Ops[] = {Scope, Entity, Name, File, Elements};
  DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
}

DIMacro *DIMacro::getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
                          MDString *Name, MDString *Value, StorageType Storage,
                          bool ShouldCreate) {
  assert(isCanonical(Name) && "Expected canonical MDString");
  DEFINE_GETIMPL_LOOKUP(DIMacro, (MIType, Line, Name, Value));
  Metadata *Ops[] = {Name, Value};
  DEFINE_GETIMPL_STORE(DIMacro, (MIType, Line), Ops);
}

DIMacroFile *DIMacroFile::getImpl(LLVMContext &Context, unsigned MIType,
                                  unsigned Line, Metadata *File,
                                  Metadata *Elements, StorageType Storage,
                                  bool ShouldCreate) {
  DEFINE_GETIMPL_LOOKUP(DIMacroFile, (MIType, Line, File, Elements));
  Metadata *Ops[] = {File, Elements};
  DEFINE_GETIMPL_STORE(DIMacroFile, (MIType, Line), Ops);
}

DIArgList *DIArgList::get(LLVMContext &Context,
                          ArrayRef<ValueAsMetadata *> Args) {
  auto ExistingIt = Context.pImpl->DIArgLists.find_as(DIArgListKeyInfo(Args));
  if (ExistingIt != Context.pImpl->DIArgLists.end())
    return *ExistingIt;
  DIArgList *NewArgList = new DIArgList(Context, Args);
  Context.pImpl->DIArgLists.insert(NewArgList);
  return NewArgList;
}

void DIArgList::handleChangedOperand(void *Ref, Metadata *New) {
  ValueAsMetadata **OldVMPtr = static_cast<ValueAsMetadata **>(Ref);
  assert((!New || isa<ValueAsMetadata>(New)) &&
         "DIArgList must be passed a ValueAsMetadata");
  untrack();
  // We need to update the set storage once the Args are updated since they
  // form the key to the DIArgLists store.
  getContext().pImpl->DIArgLists.erase(this);
  ValueAsMetadata *NewVM = cast_or_null<ValueAsMetadata>(New);
  for (ValueAsMetadata *&VM : Args) {
    if (&VM == OldVMPtr) {
      if (NewVM)
        VM = NewVM;
      else
        VM = ValueAsMetadata::get(PoisonValue::get(VM->getValue()->getType()));
    }
  }
  // We've changed the contents of this DIArgList, and the set storage may
  // already contain a DIArgList with our new set of args; if it does, then we
  // must RAUW this with the existing DIArgList, otherwise we simply insert this
  // back into the set storage.
  DIArgList *ExistingArgList = getUniqued(getContext().pImpl->DIArgLists, this);
  if (ExistingArgList) {
    replaceAllUsesWith(ExistingArgList);
    // Clear this here so we don't try to untrack in the destructor.
    Args.clear();
    delete this;
    return;
  }
  getContext().pImpl->DIArgLists.insert(this);
  track();
}
void DIArgList::track() {
  for (ValueAsMetadata *&VAM : Args)
    if (VAM)
      MetadataTracking::track(&VAM, *VAM, *this);
}
void DIArgList::untrack() {
  for (ValueAsMetadata *&VAM : Args)
    if (VAM)
      MetadataTracking::untrack(&VAM, *VAM);
}
void DIArgList::dropAllReferences(bool Untrack) {
  if (Untrack)
    untrack();
  Args.clear();
  ReplaceableUses::resolveAllUses(/* ResolveUsers */ false);
}
