//===--- DIBuilder.cpp - Debug Information Builder ------------------------===//
//
// 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 DIBuilder.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/DIBuilder.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include <optional>

using namespace llvm;
using namespace llvm::dwarf;

DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)
    : M(m), VMContext(M.getContext()), CUNode(CU), DeclareFn(nullptr),
      ValueFn(nullptr), LabelFn(nullptr), AssignFn(nullptr),
      AllowUnresolvedNodes(AllowUnresolvedNodes) {
  if (CUNode) {
    if (const auto &ETs = CUNode->getEnumTypes())
      AllEnumTypes.assign(ETs.begin(), ETs.end());
    if (const auto &RTs = CUNode->getRetainedTypes())
      AllRetainTypes.assign(RTs.begin(), RTs.end());
    if (const auto &GVs = CUNode->getGlobalVariables())
      AllGVs.assign(GVs.begin(), GVs.end());
    if (const auto &IMs = CUNode->getImportedEntities())
      ImportedModules.assign(IMs.begin(), IMs.end());
    if (const auto &MNs = CUNode->getMacros())
      AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}});
  }
}

void DIBuilder::trackIfUnresolved(MDNode *N) {
  if (!N)
    return;
  if (N->isResolved())
    return;

  assert(AllowUnresolvedNodes && "Cannot handle unresolved nodes");
  UnresolvedNodes.emplace_back(N);
}

void DIBuilder::finalizeSubprogram(DISubprogram *SP) {
  auto PN = SubprogramTrackedNodes.find(SP);
  if (PN != SubprogramTrackedNodes.end())
    SP->replaceRetainedNodes(
        MDTuple::get(VMContext, SmallVector<Metadata *, 16>(PN->second.begin(),
                                                            PN->second.end())));
}

void DIBuilder::finalize() {
  if (!CUNode) {
    assert(!AllowUnresolvedNodes &&
           "creating type nodes without a CU is not supported");
    return;
  }

  if (!AllEnumTypes.empty())
    CUNode->replaceEnumTypes(MDTuple::get(
        VMContext, SmallVector<Metadata *, 16>(AllEnumTypes.begin(),
                                               AllEnumTypes.end())));

  SmallVector<Metadata *, 16> RetainValues;
  // Declarations and definitions of the same type may be retained. Some
  // clients RAUW these pairs, leaving duplicates in the retained types
  // list. Use a set to remove the duplicates while we transform the
  // TrackingVHs back into Values.
  SmallPtrSet<Metadata *, 16> RetainSet;
  for (const TrackingMDNodeRef &N : AllRetainTypes)
    if (RetainSet.insert(N).second)
      RetainValues.push_back(N);

  if (!RetainValues.empty())
    CUNode->replaceRetainedTypes(MDTuple::get(VMContext, RetainValues));

  for (auto *SP : AllSubprograms)
    finalizeSubprogram(SP);
  for (auto *N : RetainValues)
    if (auto *SP = dyn_cast<DISubprogram>(N))
      finalizeSubprogram(SP);

  if (!AllGVs.empty())
    CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs));

  if (!ImportedModules.empty())
    CUNode->replaceImportedEntities(MDTuple::get(
        VMContext, SmallVector<Metadata *, 16>(ImportedModules.begin(),
                                               ImportedModules.end())));

  for (const auto &I : AllMacrosPerParent) {
    // DIMacroNode's with nullptr parent are DICompileUnit direct children.
    if (!I.first) {
      CUNode->replaceMacros(MDTuple::get(VMContext, I.second.getArrayRef()));
      continue;
    }
    // Otherwise, it must be a temporary DIMacroFile that need to be resolved.
    auto *TMF = cast<DIMacroFile>(I.first);
    auto *MF = DIMacroFile::get(VMContext, dwarf::DW_MACINFO_start_file,
                                TMF->getLine(), TMF->getFile(),
                                getOrCreateMacroArray(I.second.getArrayRef()));
    replaceTemporary(llvm::TempDIMacroNode(TMF), MF);
  }

  // Now that all temp nodes have been replaced or deleted, resolve remaining
  // cycles.
  for (const auto &N : UnresolvedNodes)
    if (N && !N->isResolved())
      N->resolveCycles();
  UnresolvedNodes.clear();

  // Can't handle unresolved nodes anymore.
  AllowUnresolvedNodes = false;
}

/// If N is compile unit return NULL otherwise return N.
static DIScope *getNonCompileUnitScope(DIScope *N) {
  if (!N || isa<DICompileUnit>(N))
    return nullptr;
  return cast<DIScope>(N);
}

DICompileUnit *DIBuilder::createCompileUnit(
    unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized,
    StringRef Flags, unsigned RunTimeVer, StringRef SplitName,
    DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId,
    bool SplitDebugInlining, bool DebugInfoForProfiling,
    DICompileUnit::DebugNameTableKind NameTableKind, bool RangesBaseAddress,
    StringRef SysRoot, StringRef SDK) {

  assert(((Lang <= dwarf::DW_LANG_Metal && Lang >= dwarf::DW_LANG_C89) ||
          (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
         "Invalid Language tag");

  assert(!CUNode && "Can only make one compile unit per DIBuilder instance");
  CUNode = DICompileUnit::getDistinct(
      VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer,
      SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId,
      SplitDebugInlining, DebugInfoForProfiling, NameTableKind,
      RangesBaseAddress, SysRoot, SDK);

  // Create a named metadata so that it is easier to find cu in a module.
  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
  NMD->addOperand(CUNode);
  trackIfUnresolved(CUNode);
  return CUNode;
}

static DIImportedEntity *
createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,
                     Metadata *NS, DIFile *File, unsigned Line, StringRef Name,
                     DINodeArray Elements,
                     SmallVectorImpl<TrackingMDNodeRef> &ImportedModules) {
  if (Line)
    assert(File && "Source location has line number but no file");
  unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size();
  auto *M = DIImportedEntity::get(C, Tag, Context, cast_or_null<DINode>(NS),
                                  File, Line, Name, Elements);
  if (EntitiesCount < C.pImpl->DIImportedEntitys.size())
    // A new Imported Entity was just added to the context.
    // Add it to the Imported Modules list.
    ImportedModules.emplace_back(M);
  return M;
}

DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
                                                  DINamespace *NS, DIFile *File,
                                                  unsigned Line,
                                                  DINodeArray Elements) {
  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
                                Context, NS, File, Line, StringRef(), Elements,
                                getImportTrackingVector(Context));
}

DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
                                                  DIImportedEntity *NS,
                                                  DIFile *File, unsigned Line,
                                                  DINodeArray Elements) {
  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
                                Context, NS, File, Line, StringRef(), Elements,
                                getImportTrackingVector(Context));
}

DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,
                                                  DIFile *File, unsigned Line,
                                                  DINodeArray Elements) {
  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
                                Context, M, File, Line, StringRef(), Elements,
                                getImportTrackingVector(Context));
}

DIImportedEntity *
DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl,
                                     DIFile *File, unsigned Line,
                                     StringRef Name, DINodeArray Elements) {
  // Make sure to use the unique identifier based metadata reference for
  // types that have one.
  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,
                                Context, Decl, File, Line, Name, Elements,
                                getImportTrackingVector(Context));
}

DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory,
                              std::optional<DIFile::ChecksumInfo<StringRef>> CS,
                              std::optional<StringRef> Source) {
  return DIFile::get(VMContext, Filename, Directory, CS, Source);
}

DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber,
                                unsigned MacroType, StringRef Name,
                                StringRef Value) {
  assert(!Name.empty() && "Unable to create macro without name");
  assert((MacroType == dwarf::DW_MACINFO_undef ||
          MacroType == dwarf::DW_MACINFO_define) &&
         "Unexpected macro type");
  auto *M = DIMacro::get(VMContext, MacroType, LineNumber, Name, Value);
  AllMacrosPerParent[Parent].insert(M);
  return M;
}

DIMacroFile *DIBuilder::createTempMacroFile(DIMacroFile *Parent,
                                            unsigned LineNumber, DIFile *File) {
  auto *MF = DIMacroFile::getTemporary(VMContext, dwarf::DW_MACINFO_start_file,
                                       LineNumber, File, DIMacroNodeArray())
                 .release();
  AllMacrosPerParent[Parent].insert(MF);
  // Add the new temporary DIMacroFile to the macro per parent map as a parent.
  // This is needed to assure DIMacroFile with no children to have an entry in
  // the map. Otherwise, it will not be resolved in DIBuilder::finalize().
  AllMacrosPerParent.insert({MF, {}});
  return MF;
}

DIEnumerator *DIBuilder::createEnumerator(StringRef Name, uint64_t Val,
                                          bool IsUnsigned) {
  assert(!Name.empty() && "Unable to create enumerator without name");
  return DIEnumerator::get(VMContext, APInt(64, Val, !IsUnsigned), IsUnsigned,
                           Name);
}

DIEnumerator *DIBuilder::createEnumerator(StringRef Name, const APSInt &Value) {
  assert(!Name.empty() && "Unable to create enumerator without name");
  return DIEnumerator::get(VMContext, APInt(Value), Value.isUnsigned(), Name);
}

DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) {
  assert(!Name.empty() && "Unable to create type without name");
  return DIBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name);
}

DIBasicType *DIBuilder::createNullPtrType() {
  return createUnspecifiedType("decltype(nullptr)");
}

DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
                                        unsigned Encoding,
                                        DINode::DIFlags Flags,
                                        uint32_t NumExtraInhabitants) {
  assert(!Name.empty() && "Unable to create type without name");
  return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,
                          0, Encoding, NumExtraInhabitants, Flags);
}

DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) {
  assert(!Name.empty() && "Unable to create type without name");
  return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,
                           SizeInBits, 0);
}

DIStringType *DIBuilder::createStringType(StringRef Name,
                                          DIVariable *StringLength,
                                          DIExpression *StrLocationExp) {
  assert(!Name.empty() && "Unable to create type without name");
  return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,
                           StringLength, nullptr, StrLocationExp, 0, 0, 0);
}

DIStringType *DIBuilder::createStringType(StringRef Name,
                                          DIExpression *StringLengthExp,
                                          DIExpression *StrLocationExp) {
  assert(!Name.empty() && "Unable to create type without name");
  return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, nullptr,
                           StringLengthExp, StrLocationExp, 0, 0, 0);
}

DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {
  return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0,
                            0, 0, std::nullopt, std::nullopt, DINode::FlagZero);
}

DIDerivedType *DIBuilder::createPtrAuthQualifiedType(
    DIType *FromTy, unsigned Key, bool IsAddressDiscriminated,
    unsigned ExtraDiscriminator, bool IsaPointer,
    bool AuthenticatesNullValues) {
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "",
                            nullptr, 0, nullptr, FromTy, 0, 0, 0, std::nullopt,
                            std::optional<DIDerivedType::PtrAuthData>(
                                std::in_place, Key, IsAddressDiscriminated,
                                ExtraDiscriminator, IsaPointer,
                                AuthenticatesNullValues),
                            DINode::FlagZero);
}

DIDerivedType *
DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
                             uint32_t AlignInBits,
                             std::optional<unsigned> DWARFAddressSpace,
                             StringRef Name, DINodeArray Annotations) {
  // FIXME: Why is there a name here?
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name,
                            nullptr, 0, nullptr, PointeeTy, SizeInBits,
                            AlignInBits, 0, DWARFAddressSpace, std::nullopt,
                            DINode::FlagZero, nullptr, Annotations);
}

DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,
                                                  DIType *Base,
                                                  uint64_t SizeInBits,
                                                  uint32_t AlignInBits,
                                                  DINode::DIFlags Flags) {
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "",
                            nullptr, 0, nullptr, PointeeTy, SizeInBits,
                            AlignInBits, 0, std::nullopt, std::nullopt, Flags,
                            Base);
}

DIDerivedType *
DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits,
                               uint32_t AlignInBits,
                               std::optional<unsigned> DWARFAddressSpace) {
  assert(RTy && "Unable to create reference type");
  return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy,
                            SizeInBits, AlignInBits, 0, DWARFAddressSpace, {},
                            DINode::FlagZero);
}

DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,
                                        DIFile *File, unsigned LineNo,
                                        DIScope *Context, uint32_t AlignInBits,
                                        DINode::DIFlags Flags,
                                        DINodeArray Annotations) {
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,
                            LineNo, getNonCompileUnitScope(Context), Ty, 0,
                            AlignInBits, 0, std::nullopt, std::nullopt, Flags,
                            nullptr, Annotations);
}

DIDerivedType *
DIBuilder::createTemplateAlias(DIType *Ty, StringRef Name, DIFile *File,
                               unsigned LineNo, DIScope *Context,
                               DINodeArray TParams, uint32_t AlignInBits,
                               DINode::DIFlags Flags, DINodeArray Annotations) {
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_template_alias, Name, File,
                            LineNo, getNonCompileUnitScope(Context), Ty, 0,
                            AlignInBits, 0, std::nullopt, std::nullopt, Flags,
                            TParams.get(), Annotations);
}

DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) {
  assert(Ty && "Invalid type!");
  assert(FriendTy && "Invalid friend type!");
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty,
                            FriendTy, 0, 0, 0, std::nullopt, std::nullopt,
                            DINode::FlagZero);
}

DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy,
                                            uint64_t BaseOffset,
                                            uint32_t VBPtrOffset,
                                            DINode::DIFlags Flags) {
  assert(Ty && "Unable to create inheritance");
  Metadata *ExtraData = ConstantAsMetadata::get(
      ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset));
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr,
                            0, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt,
                            std::nullopt, Flags, ExtraData);
}

DIDerivedType *DIBuilder::createMemberType(
    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
    DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
                            LineNumber, getNonCompileUnitScope(Scope), Ty,
                            SizeInBits, AlignInBits, OffsetInBits, std::nullopt,
                            std::nullopt, Flags, nullptr, Annotations);
}

static ConstantAsMetadata *getConstantOrNull(Constant *C) {
  if (C)
    return ConstantAsMetadata::get(C);
  return nullptr;
}

DIDerivedType *DIBuilder::createVariantMemberType(
    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
    Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) {
  return DIDerivedType::get(
      VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
      getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits,
      std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant));
}

DIDerivedType *DIBuilder::createBitFieldMemberType(
    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits,
    DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {
  Flags |= DINode::FlagBitField;
  return DIDerivedType::get(
      VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
      getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0,
      OffsetInBits, std::nullopt, std::nullopt, Flags,
      ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64),
                                               StorageOffsetInBits)),
      Annotations);
}

DIDerivedType *
DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File,
                                  unsigned LineNumber, DIType *Ty,
                                  DINode::DIFlags Flags, llvm::Constant *Val,
                                  unsigned Tag, uint32_t AlignInBits) {
  Flags |= DINode::FlagStaticMember;
  return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber,
                            getNonCompileUnitScope(Scope), Ty, 0, AlignInBits,
                            0, std::nullopt, std::nullopt, Flags,
                            getConstantOrNull(Val));
}

DIDerivedType *
DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber,
                          uint64_t SizeInBits, uint32_t AlignInBits,
                          uint64_t OffsetInBits, DINode::DIFlags Flags,
                          DIType *Ty, MDNode *PropertyNode) {
  return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
                            LineNumber, getNonCompileUnitScope(File), Ty,
                            SizeInBits, AlignInBits, OffsetInBits, std::nullopt,
                            std::nullopt, Flags, PropertyNode);
}

DIObjCProperty *
DIBuilder::createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber,
                              StringRef GetterName, StringRef SetterName,
                              unsigned PropertyAttributes, DIType *Ty) {
  return DIObjCProperty::get(VMContext, Name, File, LineNumber, GetterName,
                             SetterName, PropertyAttributes, Ty);
}

DITemplateTypeParameter *
DIBuilder::createTemplateTypeParameter(DIScope *Context, StringRef Name,
                                       DIType *Ty, bool isDefault) {
  assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");
  return DITemplateTypeParameter::get(VMContext, Name, Ty, isDefault);
}

static DITemplateValueParameter *
createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag,
                                   DIScope *Context, StringRef Name, DIType *Ty,
                                   bool IsDefault, Metadata *MD) {
  assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");
  return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, IsDefault, MD);
}

DITemplateValueParameter *
DIBuilder::createTemplateValueParameter(DIScope *Context, StringRef Name,
                                        DIType *Ty, bool isDefault,
                                        Constant *Val) {
  return createTemplateValueParameterHelper(
      VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty,
      isDefault, getConstantOrNull(Val));
}

DITemplateValueParameter *
DIBuilder::createTemplateTemplateParameter(DIScope *Context, StringRef Name,
                                           DIType *Ty, StringRef Val,
                                           bool IsDefault) {
  return createTemplateValueParameterHelper(
      VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty,
      IsDefault, MDString::get(VMContext, Val));
}

DITemplateValueParameter *
DIBuilder::createTemplateParameterPack(DIScope *Context, StringRef Name,
                                       DIType *Ty, DINodeArray Val) {
  return createTemplateValueParameterHelper(
      VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty,
      false, Val.get());
}

DICompositeType *DIBuilder::createClassType(
    DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
    DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements,
    unsigned RunTimeLang, DIType *VTableHolder, MDNode *TemplateParams,
    StringRef UniqueIdentifier) {
  assert((!Context || isa<DIScope>(Context)) &&
         "createClassType should be called with a valid Context");

  auto *R = DICompositeType::get(
      VMContext, dwarf::DW_TAG_class_type, Name, File, LineNumber,
      getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits,
      OffsetInBits, Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt,
      VTableHolder, cast_or_null<MDTuple>(TemplateParams), UniqueIdentifier);
  trackIfUnresolved(R);
  return R;
}

DICompositeType *DIBuilder::createStructType(
    DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
    DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,
    DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification,
    uint32_t NumExtraInhabitants) {
  auto *R = DICompositeType::get(
      VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,
      getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,
      Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, VTableHolder,
      nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, nullptr,
      nullptr, Specification, NumExtraInhabitants);
  trackIfUnresolved(R);
  return R;
}

DICompositeType *DIBuilder::createUnionType(
    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
    DINodeArray Elements, unsigned RunTimeLang, StringRef UniqueIdentifier) {
  auto *R = DICompositeType::get(
      VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber,
      getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,
      Elements, RunTimeLang, /*EnumKind=*/std::nullopt, nullptr, nullptr,
      UniqueIdentifier);
  trackIfUnresolved(R);
  return R;
}

DICompositeType *
DIBuilder::createVariantPart(DIScope *Scope, StringRef Name, DIFile *File,
                             unsigned LineNumber, uint64_t SizeInBits,
                             uint32_t AlignInBits, DINode::DIFlags Flags,
                             DIDerivedType *Discriminator, DINodeArray Elements,
                             StringRef UniqueIdentifier) {
  auto *R = DICompositeType::get(
      VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber,
      getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,
      Elements, 0, /*EnumKind=*/std::nullopt, nullptr, nullptr,
      UniqueIdentifier, Discriminator);
  trackIfUnresolved(R);
  return R;
}

DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,
                                                  DINode::DIFlags Flags,
                                                  unsigned CC) {
  return DISubroutineType::get(VMContext, Flags, CC, ParameterTypes);
}

DICompositeType *DIBuilder::createEnumerationType(
    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
    uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,
    DIType *UnderlyingType, unsigned RunTimeLang, StringRef UniqueIdentifier,
    bool IsScoped, std::optional<uint32_t> EnumKind) {
  auto *CTy = DICompositeType::get(
      VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber,
      getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0,
      IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements,
      RunTimeLang, EnumKind, nullptr, nullptr, UniqueIdentifier);
  AllEnumTypes.emplace_back(CTy);
  trackIfUnresolved(CTy);
  return CTy;
}

DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name,
                                        DIFile *File, unsigned LineNo,
                                        uint64_t SizeInBits,
                                        uint32_t AlignInBits, DIType *Ty) {
  auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File,
                               LineNo, getNonCompileUnitScope(Scope), Ty,
                               SizeInBits, AlignInBits, 0, std::nullopt,
                               std::nullopt, DINode::FlagZero);
  trackIfUnresolved(R);
  return R;
}

DICompositeType *
DIBuilder::createArrayType(uint64_t Size, uint32_t AlignInBits, DIType *Ty,
                           DINodeArray Subscripts,
                           PointerUnion<DIExpression *, DIVariable *> DL,
                           PointerUnion<DIExpression *, DIVariable *> AS,
                           PointerUnion<DIExpression *, DIVariable *> AL,
                           PointerUnion<DIExpression *, DIVariable *> RK) {
  auto *R = DICompositeType::get(
      VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, nullptr, Ty, Size,
      AlignInBits, 0, DINode::FlagZero, Subscripts, 0,
      /*EnumKind=*/std::nullopt, nullptr, nullptr, "", nullptr,
      isa<DIExpression *>(DL) ? (Metadata *)cast<DIExpression *>(DL)
                              : (Metadata *)cast<DIVariable *>(DL),
      isa<DIExpression *>(AS) ? (Metadata *)cast<DIExpression *>(AS)
                              : (Metadata *)cast<DIVariable *>(AS),
      isa<DIExpression *>(AL) ? (Metadata *)cast<DIExpression *>(AL)
                              : (Metadata *)cast<DIVariable *>(AL),
      isa<DIExpression *>(RK) ? (Metadata *)cast<DIExpression *>(RK)
                              : (Metadata *)cast<DIVariable *>(RK));
  trackIfUnresolved(R);
  return R;
}

DICompositeType *DIBuilder::createVectorType(uint64_t Size,
                                             uint32_t AlignInBits, DIType *Ty,
                                             DINodeArray Subscripts) {
  auto *R = DICompositeType::get(VMContext, dwarf::DW_TAG_array_type, "",
                                 nullptr, 0, nullptr, Ty, Size, AlignInBits, 0,
                                 DINode::FlagVector, Subscripts, 0,
                                 /*EnumKind=*/std::nullopt, nullptr);
  trackIfUnresolved(R);
  return R;
}

DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) {
  auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial);
  return MDNode::replaceWithDistinct(std::move(NewSP));
}

static DIType *createTypeWithFlags(const DIType *Ty,
                                   DINode::DIFlags FlagsToSet) {
  auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet);
  return MDNode::replaceWithUniqued(std::move(NewTy));
}

DIType *DIBuilder::createArtificialType(DIType *Ty) {
  // FIXME: Restrict this to the nodes where it's valid.
  if (Ty->isArtificial())
    return Ty;
  return createTypeWithFlags(Ty, DINode::FlagArtificial);
}

DIType *DIBuilder::createObjectPointerType(DIType *Ty, bool Implicit) {
  // FIXME: Restrict this to the nodes where it's valid.
  if (Ty->isObjectPointer())
    return Ty;
  DINode::DIFlags Flags = DINode::FlagObjectPointer;

  if (Implicit)
    Flags |= DINode::FlagArtificial;

  return createTypeWithFlags(Ty, Flags);
}

void DIBuilder::retainType(DIScope *T) {
  assert(T && "Expected non-null type");
  assert((isa<DIType>(T) || (isa<DISubprogram>(T) &&
                             cast<DISubprogram>(T)->isDefinition() == false)) &&
         "Expected type or subprogram declaration");
  AllRetainTypes.emplace_back(T);
}

DIBasicType *DIBuilder::createUnspecifiedParameter() { return nullptr; }

DICompositeType *DIBuilder::createForwardDecl(
    unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,
    unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,
    StringRef UniqueIdentifier, std::optional<uint32_t> EnumKind) {
  // FIXME: Define in terms of createReplaceableForwardDecl() by calling
  // replaceWithUniqued().
  auto *RetTy = DICompositeType::get(
      VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr,
      SizeInBits, AlignInBits, 0, DINode::FlagFwdDecl, nullptr, RuntimeLang,
      /*EnumKind=*/EnumKind, nullptr, nullptr, UniqueIdentifier);
  trackIfUnresolved(RetTy);
  return RetTy;
}

DICompositeType *DIBuilder::createReplaceableCompositeType(
    unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,
    unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,
    DINode::DIFlags Flags, StringRef UniqueIdentifier, DINodeArray Annotations,
    std::optional<uint32_t> EnumKind) {
  auto *RetTy =
      DICompositeType::getTemporary(
          VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr,
          SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, EnumKind,
          nullptr, nullptr, UniqueIdentifier, nullptr, nullptr, nullptr,
          nullptr, nullptr, Annotations)
          .release();
  trackIfUnresolved(RetTy);
  return RetTy;
}

DINodeArray DIBuilder::getOrCreateArray(ArrayRef<Metadata *> Elements) {
  return MDTuple::get(VMContext, Elements);
}

DIMacroNodeArray
DIBuilder::getOrCreateMacroArray(ArrayRef<Metadata *> Elements) {
  return MDTuple::get(VMContext, Elements);
}

DITypeRefArray DIBuilder::getOrCreateTypeArray(ArrayRef<Metadata *> Elements) {
  SmallVector<llvm::Metadata *, 16> Elts;
  for (Metadata *E : Elements) {
    if (isa_and_nonnull<MDNode>(E))
      Elts.push_back(cast<DIType>(E));
    else
      Elts.push_back(E);
  }
  return DITypeRefArray(MDNode::get(VMContext, Elts));
}

DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
  auto *LB = ConstantAsMetadata::get(
      ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo));
  auto *CountNode = ConstantAsMetadata::get(
      ConstantInt::getSigned(Type::getInt64Ty(VMContext), Count));
  return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr);
}

DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, Metadata *CountNode) {
  auto *LB = ConstantAsMetadata::get(
      ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo));
  return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr);
}

DISubrange *DIBuilder::getOrCreateSubrange(Metadata *CountNode, Metadata *LB,
                                           Metadata *UB, Metadata *Stride) {
  return DISubrange::get(VMContext, CountNode, LB, UB, Stride);
}

DIGenericSubrange *DIBuilder::getOrCreateGenericSubrange(
    DIGenericSubrange::BoundType CountNode, DIGenericSubrange::BoundType LB,
    DIGenericSubrange::BoundType UB, DIGenericSubrange::BoundType Stride) {
  auto ConvToMetadata = [&](DIGenericSubrange::BoundType Bound) -> Metadata * {
    return isa<DIExpression *>(Bound) ? (Metadata *)cast<DIExpression *>(Bound)
                                      : (Metadata *)cast<DIVariable *>(Bound);
  };
  return DIGenericSubrange::get(VMContext, ConvToMetadata(CountNode),
                                ConvToMetadata(LB), ConvToMetadata(UB),
                                ConvToMetadata(Stride));
}

static void checkGlobalVariableScope(DIScope *Context) {
#ifndef NDEBUG
  if (auto *CT =
          dyn_cast_or_null<DICompositeType>(getNonCompileUnitScope(Context)))
    assert(CT->getIdentifier().empty() &&
           "Context of a global variable should not be a type with identifier");
#endif
}

DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(
    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
    unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined,
    DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams,
    uint32_t AlignInBits, DINodeArray Annotations) {
  checkGlobalVariableScope(Context);

  auto *GV = DIGlobalVariable::getDistinct(
      VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
      LineNumber, Ty, IsLocalToUnit, isDefined,
      cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,
      Annotations);
  if (!Expr)
    Expr = createExpression();
  auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);
  AllGVs.push_back(N);
  return N;
}

DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(
    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
    unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl,
    MDTuple *TemplateParams, uint32_t AlignInBits) {
  checkGlobalVariableScope(Context);

  return DIGlobalVariable::getTemporary(
             VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,
             LineNumber, Ty, IsLocalToUnit, false,
             cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,
             nullptr)
      .release();
}

static DILocalVariable *createLocalVariable(
    LLVMContext &VMContext,
    SmallVectorImpl<TrackingMDNodeRef> &PreservedNodes,
    DIScope *Context, StringRef Name, unsigned ArgNo, DIFile *File,
    unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,
    uint32_t AlignInBits, DINodeArray Annotations = nullptr) {
  // FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT
  // the only valid scopes)?
  auto *Scope = cast<DILocalScope>(Context);
  auto *Node = DILocalVariable::get(VMContext, Scope, Name, File, LineNo, Ty,
                                    ArgNo, Flags, AlignInBits, Annotations);
  if (AlwaysPreserve) {
    // The optimizer may remove local variables. If there is an interest
    // to preserve variable info in such situation then stash it in a
    // named mdnode.
    PreservedNodes.emplace_back(Node);
  }
  return Node;
}

DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name,
                                               DIFile *File, unsigned LineNo,
                                               DIType *Ty, bool AlwaysPreserve,
                                               DINode::DIFlags Flags,
                                               uint32_t AlignInBits) {
  assert(Scope && isa<DILocalScope>(Scope) &&
         "Unexpected scope for a local variable.");
  return createLocalVariable(
      VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name,
      /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, Flags, AlignInBits);
}

DILocalVariable *DIBuilder::createParameterVariable(
    DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,
    unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,
    DINodeArray Annotations) {
  assert(ArgNo && "Expected non-zero argument number for parameter");
  assert(Scope && isa<DILocalScope>(Scope) &&
         "Unexpected scope for a local variable.");
  return createLocalVariable(
      VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name, ArgNo,
      File, LineNo, Ty, AlwaysPreserve, Flags, /*AlignInBits=*/0, Annotations);
}

DILabel *DIBuilder::createLabel(DIScope *Context, StringRef Name, DIFile *File,
                                 unsigned LineNo, bool AlwaysPreserve) {
  auto *Scope = cast<DILocalScope>(Context);
  auto *Node = DILabel::get(VMContext, Scope, Name, File, LineNo);

  if (AlwaysPreserve) {
    /// The optimizer may remove labels. If there is an interest
    /// to preserve label info in such situation then append it to
    /// the list of retained nodes of the DISubprogram.
    getSubprogramNodesTrackingVector(Scope).emplace_back(Node);
  }
  return Node;
}

DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
  return DIExpression::get(VMContext, Addr);
}

template <class... Ts>
static DISubprogram *getSubprogram(bool IsDistinct, Ts &&...Args) {
  if (IsDistinct)
    return DISubprogram::getDistinct(std::forward<Ts>(Args)...);
  return DISubprogram::get(std::forward<Ts>(Args)...);
}

DISubprogram *DIBuilder::createFunction(
    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
    unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,
    DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,
    DITemplateParameterArray TParams, DISubprogram *Decl,
    DITypeArray ThrownTypes, DINodeArray Annotations,
    StringRef TargetFuncName) {
  bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;
  auto *Node = getSubprogram(
      /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context),
      Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags,
      SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr,
      ThrownTypes, Annotations, TargetFuncName);

  if (IsDefinition)
    AllSubprograms.push_back(Node);
  trackIfUnresolved(Node);
  return Node;
}

DISubprogram *DIBuilder::createTempFunctionFwdDecl(
    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
    unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,
    DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,
    DITemplateParameterArray TParams, DISubprogram *Decl,
    DITypeArray ThrownTypes) {
  bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;
  return DISubprogram::getTemporary(VMContext, getNonCompileUnitScope(Context),
                                    Name, LinkageName, File, LineNo, Ty,
                                    ScopeLine, nullptr, 0, 0, Flags, SPFlags,
                                    IsDefinition ? CUNode : nullptr, TParams,
                                    Decl, nullptr, ThrownTypes)
      .release();
}

DISubprogram *DIBuilder::createMethod(
    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
    unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment,
    DIType *VTableHolder, DINode::DIFlags Flags,
    DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams,
    DITypeArray ThrownTypes) {
  assert(getNonCompileUnitScope(Context) &&
         "Methods should have both a Context and a context that isn't "
         "the compile unit.");
  // FIXME: Do we want to use different scope/lines?
  bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;
  auto *SP = getSubprogram(
      /*IsDistinct=*/IsDefinition, VMContext, cast<DIScope>(Context), Name,
      LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment,
      Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr,
      nullptr, ThrownTypes);

  if (IsDefinition)
    AllSubprograms.push_back(SP);
  trackIfUnresolved(SP);
  return SP;
}

DICommonBlock *DIBuilder::createCommonBlock(DIScope *Scope,
                                            DIGlobalVariable *Decl,
                                            StringRef Name, DIFile *File,
                                            unsigned LineNo) {
  return DICommonBlock::get(VMContext, Scope, Decl, Name, File, LineNo);
}

DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name,
                                        bool ExportSymbols) {

  // It is okay to *not* make anonymous top-level namespaces distinct, because
  // all nodes that have an anonymous namespace as their parent scope are
  // guaranteed to be unique and/or are linked to their containing
  // DICompileUnit. This decision is an explicit tradeoff of link time versus
  // memory usage versus code simplicity and may get revisited in the future.
  return DINamespace::get(VMContext, getNonCompileUnitScope(Scope), Name,
                          ExportSymbols);
}

DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name,
                                  StringRef ConfigurationMacros,
                                  StringRef IncludePath, StringRef APINotesFile,
                                  DIFile *File, unsigned LineNo, bool IsDecl) {
  return DIModule::get(VMContext, File, getNonCompileUnitScope(Scope), Name,
                       ConfigurationMacros, IncludePath, APINotesFile, LineNo,
                       IsDecl);
}

DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,
                                                      DIFile *File,
                                                      unsigned Discriminator) {
  return DILexicalBlockFile::get(VMContext, Scope, File, Discriminator);
}

DILexicalBlock *DIBuilder::createLexicalBlock(DIScope *Scope, DIFile *File,
                                              unsigned Line, unsigned Col) {
  // Make these distinct, to avoid merging two lexical blocks on the same
  // file/line/column.
  return DILexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope),
                                     File, Line, Col);
}

DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
                                    DIExpression *Expr, const DILocation *DL,
                                    Instruction *InsertBefore) {
  return insertDeclare(Storage, VarInfo, Expr, DL, InsertBefore->getParent(),
                       InsertBefore);
}

DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
                                    DIExpression *Expr, const DILocation *DL,
                                    BasicBlock *InsertAtEnd) {
  // If this block already has a terminator then insert this intrinsic before
  // the terminator. Otherwise, put it at the end of the block.
  Instruction *InsertBefore = InsertAtEnd->getTerminator();
  return insertDeclare(Storage, VarInfo, Expr, DL, InsertAtEnd, InsertBefore);
}

DbgInstPtr DIBuilder::insertDbgAssign(Instruction *LinkedInstr, Value *Val,
                                      DILocalVariable *SrcVar,
                                      DIExpression *ValExpr, Value *Addr,
                                      DIExpression *AddrExpr,
                                      const DILocation *DL) {
  auto *Link = cast_or_null<DIAssignID>(
      LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID));
  assert(Link && "Linked instruction must have DIAssign metadata attached");

  if (M.IsNewDbgInfoFormat) {
    DbgVariableRecord *DVR = DbgVariableRecord::createDVRAssign(
        Val, SrcVar, ValExpr, Link, Addr, AddrExpr, DL);
    BasicBlock *InsertBB = LinkedInstr->getParent();
    // Insert after LinkedInstr.
    BasicBlock::iterator NextIt = std::next(LinkedInstr->getIterator());
    Instruction *InsertBefore = NextIt == InsertBB->end() ? nullptr : &*NextIt;
    insertDbgVariableRecord(DVR, InsertBB, InsertBefore, true);
    return DVR;
  }

  LLVMContext &Ctx = LinkedInstr->getContext();
  Module *M = LinkedInstr->getModule();
  if (!AssignFn)
    AssignFn = Intrinsic::getOrInsertDeclaration(M, Intrinsic::dbg_assign);

  std::array<Value *, 6> Args = {
      MetadataAsValue::get(Ctx, ValueAsMetadata::get(Val)),
      MetadataAsValue::get(Ctx, SrcVar),
      MetadataAsValue::get(Ctx, ValExpr),
      MetadataAsValue::get(Ctx, Link),
      MetadataAsValue::get(Ctx, ValueAsMetadata::get(Addr)),
      MetadataAsValue::get(Ctx, AddrExpr),
  };

  IRBuilder<> B(Ctx);
  B.SetCurrentDebugLocation(DL);

  auto *DVI = cast<DbgAssignIntrinsic>(B.CreateCall(AssignFn, Args));
  DVI->insertAfter(LinkedInstr->getIterator());
  return DVI;
}

DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,
                                  Instruction *InsertBefore) {
  return insertLabel(LabelInfo, DL,
                     InsertBefore ? InsertBefore->getParent() : nullptr,
                     InsertBefore);
}

DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,
                                  BasicBlock *InsertAtEnd) {
  return insertLabel(LabelInfo, DL, InsertAtEnd, nullptr);
}

DbgInstPtr DIBuilder::insertDbgValueIntrinsic(Value *V,
                                              DILocalVariable *VarInfo,
                                              DIExpression *Expr,
                                              const DILocation *DL,
                                              Instruction *InsertBefore) {
  DbgInstPtr DVI = insertDbgValueIntrinsic(
      V, VarInfo, Expr, DL, InsertBefore ? InsertBefore->getParent() : nullptr,
      InsertBefore);
  if (auto *Inst = dyn_cast<Instruction *>(DVI))
    cast<CallInst>(Inst)->setTailCall();
  return DVI;
}

DbgInstPtr DIBuilder::insertDbgValueIntrinsic(Value *V,
                                              DILocalVariable *VarInfo,
                                              DIExpression *Expr,
                                              const DILocation *DL,
                                              BasicBlock *InsertAtEnd) {
  return insertDbgValueIntrinsic(V, VarInfo, Expr, DL, InsertAtEnd, nullptr);
}

/// Initialize IRBuilder for inserting dbg.declare and dbg.value intrinsics.
/// This abstracts over the various ways to specify an insert position.
static void initIRBuilder(IRBuilder<> &Builder, const DILocation *DL,
                          BasicBlock *InsertBB, Instruction *InsertBefore) {
  if (InsertBefore)
    Builder.SetInsertPoint(InsertBefore);
  else if (InsertBB)
    Builder.SetInsertPoint(InsertBB);
  Builder.SetCurrentDebugLocation(DL);
}

static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) {
  assert(V && "no value passed to dbg intrinsic");
  return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V));
}

static Function *getDeclareIntrin(Module &M) {
  return Intrinsic::getOrInsertDeclaration(&M, Intrinsic::dbg_declare);
}

DbgInstPtr DIBuilder::insertDbgValueIntrinsic(
    llvm::Value *Val, DILocalVariable *VarInfo, DIExpression *Expr,
    const DILocation *DL, BasicBlock *InsertBB, Instruction *InsertBefore) {
  if (M.IsNewDbgInfoFormat) {
    DbgVariableRecord *DVR =
        DbgVariableRecord::createDbgVariableRecord(Val, VarInfo, Expr, DL);
    insertDbgVariableRecord(DVR, InsertBB, InsertBefore);
    return DVR;
  }

  if (!ValueFn)
    ValueFn = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::dbg_value);
  return insertDbgIntrinsic(ValueFn, Val, VarInfo, Expr, DL, InsertBB,
                            InsertBefore);
}

DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,
                                    DIExpression *Expr, const DILocation *DL,
                                    BasicBlock *InsertBB,
                                    Instruction *InsertBefore) {
  assert(VarInfo && "empty or invalid DILocalVariable* passed to dbg.declare");
  assert(DL && "Expected debug loc");
  assert(DL->getScope()->getSubprogram() ==
             VarInfo->getScope()->getSubprogram() &&
         "Expected matching subprograms");

  if (M.IsNewDbgInfoFormat) {
    DbgVariableRecord *DVR =
        DbgVariableRecord::createDVRDeclare(Storage, VarInfo, Expr, DL);
    insertDbgVariableRecord(DVR, InsertBB, InsertBefore);
    return DVR;
  }

  if (!DeclareFn)
    DeclareFn = getDeclareIntrin(M);

  trackIfUnresolved(VarInfo);
  trackIfUnresolved(Expr);
  Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage),
                   MetadataAsValue::get(VMContext, VarInfo),
                   MetadataAsValue::get(VMContext, Expr)};

  IRBuilder<> B(DL->getContext());
  initIRBuilder(B, DL, InsertBB, InsertBefore);
  return B.CreateCall(DeclareFn, Args);
}

void DIBuilder::insertDbgVariableRecord(DbgVariableRecord *DVR,
                                        BasicBlock *InsertBB,
                                        Instruction *InsertBefore,
                                        bool InsertAtHead) {
  assert(InsertBefore || InsertBB);
  trackIfUnresolved(DVR->getVariable());
  trackIfUnresolved(DVR->getExpression());
  if (DVR->isDbgAssign())
    trackIfUnresolved(DVR->getAddressExpression());

  BasicBlock::iterator InsertPt;
  if (InsertBB && InsertBefore)
    InsertPt = InsertBefore->getIterator();
  else if (InsertBB)
    InsertPt = InsertBB->end();
  InsertPt.setHeadBit(InsertAtHead);
  InsertBB->insertDbgRecordBefore(DVR, InsertPt);
}

Instruction *DIBuilder::insertDbgIntrinsic(llvm::Function *IntrinsicFn,
                                           Value *V, DILocalVariable *VarInfo,
                                           DIExpression *Expr,
                                           const DILocation *DL,
                                           BasicBlock *InsertBB,
                                           Instruction *InsertBefore) {
  assert(IntrinsicFn && "must pass a non-null intrinsic function");
  assert(V && "must pass a value to a dbg intrinsic");
  assert(VarInfo &&
         "empty or invalid DILocalVariable* passed to debug intrinsic");
  assert(DL && "Expected debug loc");
  assert(DL->getScope()->getSubprogram() ==
             VarInfo->getScope()->getSubprogram() &&
         "Expected matching subprograms");

  trackIfUnresolved(VarInfo);
  trackIfUnresolved(Expr);
  Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V),
                   MetadataAsValue::get(VMContext, VarInfo),
                   MetadataAsValue::get(VMContext, Expr)};

  IRBuilder<> B(DL->getContext());
  initIRBuilder(B, DL, InsertBB, InsertBefore);
  return B.CreateCall(IntrinsicFn, Args);
}

DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,
                                  BasicBlock *InsertBB,
                                  Instruction *InsertBefore) {
  assert(LabelInfo && "empty or invalid DILabel* passed to dbg.label");
  assert(DL && "Expected debug loc");
  assert(DL->getScope()->getSubprogram() ==
             LabelInfo->getScope()->getSubprogram() &&
         "Expected matching subprograms");

  trackIfUnresolved(LabelInfo);
  if (M.IsNewDbgInfoFormat) {
    DbgLabelRecord *DLR = new DbgLabelRecord(LabelInfo, DL);
    if (InsertBB && InsertBefore)
      InsertBB->insertDbgRecordBefore(DLR, InsertBefore->getIterator());
    else if (InsertBB)
      InsertBB->insertDbgRecordBefore(DLR, InsertBB->end());
    return DLR;
  }

  if (!LabelFn)
    LabelFn = Intrinsic::getOrInsertDeclaration(&M, Intrinsic::dbg_label);

  Value *Args[] = {MetadataAsValue::get(VMContext, LabelInfo)};

  IRBuilder<> B(DL->getContext());
  initIRBuilder(B, DL, InsertBB, InsertBefore);
  return B.CreateCall(LabelFn, Args);
}

void DIBuilder::replaceVTableHolder(DICompositeType *&T, DIType *VTableHolder) {
  {
    TypedTrackingMDRef<DICompositeType> N(T);
    N->replaceVTableHolder(VTableHolder);
    T = N.get();
  }

  // If this didn't create a self-reference, just return.
  if (T != VTableHolder)
    return;

  // Look for unresolved operands.  T will drop RAUW support, orphaning any
  // cycles underneath it.
  if (T->isResolved())
    for (const MDOperand &O : T->operands())
      if (auto *N = dyn_cast_or_null<MDNode>(O))
        trackIfUnresolved(N);
}

void DIBuilder::replaceArrays(DICompositeType *&T, DINodeArray Elements,
                              DINodeArray TParams) {
  {
    TypedTrackingMDRef<DICompositeType> N(T);
    if (Elements)
      N->replaceElements(Elements);
    if (TParams)
      N->replaceTemplateParams(DITemplateParameterArray(TParams));
    T = N.get();
  }

  // If T isn't resolved, there's no problem.
  if (!T->isResolved())
    return;

  // If T is resolved, it may be due to a self-reference cycle.  Track the
  // arrays explicitly if they're unresolved, or else the cycles will be
  // orphaned.
  if (Elements)
    trackIfUnresolved(Elements.get());
  if (TParams)
    trackIfUnresolved(TParams.get());
}
