text: //===-- llvm/CodeGen/DwarfUnit.cpp - Dwarf Type and Compile Units ---------===//
  //
  // 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 contains support for constructing a dwarf compile unit.
  //
  //===----------------------------------------------------------------------===//
  
  #include "DwarfUnit.h"
  #include "AddressPool.h"
  #include "DwarfCompileUnit.h"
  #include "DwarfDebug.h"
  #include "DwarfExpression.h"
  #include "llvm/ADT/APFloat.h"
  #include "llvm/ADT/APInt.h"
  #include "llvm/ADT/None.h"
  #include "llvm/ADT/StringExtras.h"
  #include "llvm/ADT/iterator_range.h"
  #include "llvm/CodeGen/MachineFunction.h"
  #include "llvm/CodeGen/MachineOperand.h"
  #include "llvm/CodeGen/TargetRegisterInfo.h"
  #include "llvm/CodeGen/TargetSubtargetInfo.h"
  #include "llvm/IR/Constants.h"
  #include "llvm/IR/DataLayout.h"
  #include "llvm/IR/GlobalValue.h"
  #include "llvm/IR/Metadata.h"
  #include "llvm/MC/MCAsmInfo.h"
  #include "llvm/MC/MCContext.h"
  #include "llvm/MC/MCDwarf.h"
  #include "llvm/MC/MCSection.h"
  #include "llvm/MC/MCStreamer.h"
  #include "llvm/MC/MachineLocation.h"
  #include "llvm/Support/Casting.h"
  #include "llvm/Support/CommandLine.h"
  #include "llvm/Target/TargetLoweringObjectFile.h"
  #include <cassert>
  #include <cstdint>
  #include <string>
  #include <utility>
  
  using namespace llvm;
  
  #define DEBUG_TYPE "dwarfdebug"
  
  DIEDwarfExpression::DIEDwarfExpression(const AsmPrinter &AP,
                                         DwarfCompileUnit &CU, DIELoc &DIE)
      : DwarfExpression(AP.getDwarfVersion(), CU), AP(AP), OutDIE(DIE) {}
  
  void DIEDwarfExpression::emitOp(uint8_t Op, const char* Comment) {
    CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Op);
  }
  
  void DIEDwarfExpression::emitSigned(int64_t Value) {
    CU.addSInt(getActiveDIE(), dwarf::DW_FORM_sdata, Value);
  }
  
  void DIEDwarfExpression::emitUnsigned(uint64_t Value) {
    CU.addUInt(getActiveDIE(), dwarf::DW_FORM_udata, Value);
  }
  
  void DIEDwarfExpression::emitData1(uint8_t Value) {
    CU.addUInt(getActiveDIE(), dwarf::DW_FORM_data1, Value);
  }
  
  void DIEDwarfExpression::emitBaseTypeRef(uint64_t Idx) {
    CU.addBaseTypeRef(getActiveDIE(), Idx);
  }
  
  void DIEDwarfExpression::enableTemporaryBuffer() {
    assert(!IsBuffering && "Already buffering?");
    IsBuffering = true;
  }
  
  void DIEDwarfExpression::disableTemporaryBuffer() { IsBuffering = false; }
  
  unsigned DIEDwarfExpression::getTemporaryBufferSize() {
    return TmpDIE.ComputeSize(&AP);
  }
  
  void DIEDwarfExpression::commitTemporaryBuffer() { OutDIE.takeValues(TmpDIE); }
  
  bool DIEDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
                                           unsigned MachineReg) {
    return MachineReg == TRI.getFrameRegister(*AP.MF);
  }
  
  DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node,
                       AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
      : DIEUnit(A->getDwarfVersion(), A->MAI->getCodePointerSize(), UnitTag),
        CUNode(Node), Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) {
  }
  
  DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A,
                               DwarfDebug *DW, DwarfFile *DWU,
                               MCDwarfDwoLineTable *SplitLineTable)
      : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU), CU(CU),
        SplitLineTable(SplitLineTable) {
  }
  
  DwarfUnit::~DwarfUnit() {
    for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
      DIEBlocks[j]->~DIEBlock();
    for (unsigned j = 0, M = DIELocs.size(); j < M; ++j)
      DIELocs[j]->~DIELoc();
  }
  
  int64_t DwarfUnit::getDefaultLowerBound() const {
    switch (getLanguage()) {
    default:
      break;
  
    // The languages below have valid values in all DWARF versions.
    case dwarf::DW_LANG_C:
    case dwarf::DW_LANG_C89:
    case dwarf::DW_LANG_C_plus_plus:
      return 0;
  
    case dwarf::DW_LANG_Fortran77:
    case dwarf::DW_LANG_Fortran90:
      return 1;
  
    // The languages below have valid values only if the DWARF version >= 3.
    case dwarf::DW_LANG_C99:
    case dwarf::DW_LANG_ObjC:
    case dwarf::DW_LANG_ObjC_plus_plus:
      if (DD->getDwarfVersion() >= 3)
        return 0;
      break;
  
    case dwarf::DW_LANG_Fortran95:
      if (DD->getDwarfVersion() >= 3)
        return 1;
      break;
  
    // Starting with DWARF v4, all defined languages have valid values.
    case dwarf::DW_LANG_D:
    case dwarf::DW_LANG_Java:
    case dwarf::DW_LANG_Python:
    case dwarf::DW_LANG_UPC:
      if (DD->getDwarfVersion() >= 4)
        return 0;
      break;
  
    case dwarf::DW_LANG_Ada83:
    case dwarf::DW_LANG_Ada95:
    case dwarf::DW_LANG_Cobol74:
    case dwarf::DW_LANG_Cobol85:
    case dwarf::DW_LANG_Modula2:
    case dwarf::DW_LANG_Pascal83:
    case dwarf::DW_LANG_PLI:
      if (DD->getDwarfVersion() >= 4)
        return 1;
      break;
  
    // The languages below are new in DWARF v5.
    case dwarf::DW_LANG_BLISS:
    case dwarf::DW_LANG_C11:
    case dwarf::DW_LANG_C_plus_plus_03:
    case dwarf::DW_LANG_C_plus_plus_11:
    case dwarf::DW_LANG_C_plus_plus_14:
    case dwarf::DW_LANG_Dylan:
    case dwarf::DW_LANG_Go:
    case dwarf::DW_LANG_Haskell:
    case dwarf::DW_LANG_OCaml:
    case dwarf::DW_LANG_OpenCL:
    case dwarf::DW_LANG_RenderScript:
    case dwarf::DW_LANG_Rust:
    case dwarf::DW_LANG_Swift:
      if (DD->getDwarfVersion() >= 5)
        return 0;
      break;
  
    case dwarf::DW_LANG_Fortran03:
    case dwarf::DW_LANG_Fortran08:
    case dwarf::DW_LANG_Julia:
    case dwarf::DW_LANG_Modula3:
      if (DD->getDwarfVersion() >= 5)
        return 1;
      break;
    }
  
    return -1;
  }
  
  /// Check whether the DIE for this MDNode can be shared across CUs.
  bool DwarfUnit::isShareableAcrossCUs(const DINode *D) const {
    // When the MDNode can be part of the type system, the DIE can be shared
    // across CUs.
    // Combining type units and cross-CU DIE sharing is lower value (since
    // cross-CU DIE sharing is used in LTO and removes type redundancy at that
    // level already) but may be implementable for some value in projects
    // building multiple independent libraries with LTO and then linking those
    // together.
    if (isDwoUnit() && !DD->shareAcrossDWOCUs())
      return false;
    return (isa<DIType>(D) ||
            (isa<DISubprogram>(D) && !cast<DISubprogram>(D)->isDefinition())) &&
           !DD->generateTypeUnits();
  }
  
  DIE *DwarfUnit::getDIE(const DINode *D) const {
    if (isShareableAcrossCUs(D))
      return DU->getDIE(D);
    return MDNodeToDieMap.lookup(D);
  }
  
  void DwarfUnit::insertDIE(const DINode *Desc, DIE *D) {
    if (isShareableAcrossCUs(Desc)) {
      DU->insertDIE(Desc, D);
      return;
    }
    MDNodeToDieMap.insert(std::make_pair(Desc, D));
  }
  
  void DwarfUnit::insertDIE(DIE *D) {
    MDNodeToDieMap.insert(std::make_pair(nullptr, D));
  }
  
  void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) {
    if (DD->getDwarfVersion() >= 4)
      Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag_present,
                   DIEInteger(1));
    else
      Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_flag,
                   DIEInteger(1));
  }
  
  void DwarfUnit::addUInt(DIEValueList &Die, dwarf::Attribute Attribute,
                          Optional<dwarf::Form> Form, uint64_t Integer) {
    if (!Form)
      Form = DIEInteger::BestForm(false, Integer);
    assert(Form != dwarf::DW_FORM_implicit_const &&
           "DW_FORM_implicit_const is used only for signed integers");
    Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer));
  }
  
  void DwarfUnit::addUInt(DIEValueList &Block, dwarf::Form Form,
                          uint64_t Integer) {
    addUInt(Block, (dwarf::Attribute)0, Form, Integer);
  }
  
  void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
                          Optional<dwarf::Form> Form, int64_t Integer) {
    if (!Form)
      Form = DIEInteger::BestForm(true, Integer);
    Die.addValue(DIEValueAllocator, Attribute, *Form, DIEInteger(Integer));
  }
  
  void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form,
                          int64_t Integer) {
    addSInt(Die, (dwarf::Attribute)0, Form, Integer);
  }
  
  void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute,
                            StringRef String) {
    if (CUNode->isDebugDirectivesOnly())
      return;
  
    if (DD->useInlineStrings()) {
      Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_string,
                   new (DIEValueAllocator)
                       DIEInlineString(String, DIEValueAllocator));
      return;
    }
    dwarf::Form IxForm =
        isDwoUnit() ? dwarf::DW_FORM_GNU_str_index : dwarf::DW_FORM_strp;
  
    auto StringPoolEntry =
        useSegmentedStringOffsetsTable() || IxForm == dwarf::DW_FORM_GNU_str_index
            ? DU->getStringPool().getIndexedEntry(*Asm, String)
            : DU->getStringPool().getEntry(*Asm, String);
  
    // For DWARF v5 and beyond, use the smallest strx? form possible.
    if (useSegmentedStringOffsetsTable()) {
      IxForm = dwarf::DW_FORM_strx1;
      unsigned Index = StringPoolEntry.getIndex();
      if (Index > 0xffffff)
        IxForm = dwarf::DW_FORM_strx4;
      else if (Index > 0xffff)
        IxForm = dwarf::DW_FORM_strx3;
      else if (Index > 0xff)
        IxForm = dwarf::DW_FORM_strx2;
    }
    Die.addValue(DIEValueAllocator, Attribute, IxForm,
                 DIEString(StringPoolEntry));
  }
  
  DIEValueList::value_iterator DwarfUnit::addLabel(DIEValueList &Die,
                                                   dwarf::Attribute Attribute,
                                                   dwarf::Form Form,
                                                   const MCSymbol *Label) {
    return Die.addValue(DIEValueAllocator, Attribute, Form, DIELabel(Label));
  }
  
  void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) {
    addLabel(Die, (dwarf::Attribute)0, Form, Label);
  }
  
  void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute,
                                   uint64_t Integer) {
    if (DD->getDwarfVersion() >= 4)
      addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
    else
      addUInt(Die, Attribute, dwarf::DW_FORM_data4, Integer);
  }
  
  Optional<MD5::MD5Result> DwarfUnit::getMD5AsBytes(const DIFile *File) const {
    assert(File);
    if (DD->getDwarfVersion() < 5)
      return None;
    Optional<DIFile::ChecksumInfo<StringRef>> Checksum = File->getChecksum();
    if (!Checksum || Checksum->Kind != DIFile::CSK_MD5)
      return None;
  
    // Convert the string checksum to an MD5Result for the streamer.
    // The verifier validates the checksum so we assume it's okay.
    // An MD5 checksum is 16 bytes.
    std::string ChecksumString = fromHex(Checksum->Value);
    MD5::MD5Result CKMem;
    std::copy(ChecksumString.begin(), ChecksumString.end(), CKMem.Bytes.data());
    return CKMem;
  }
  
  unsigned DwarfTypeUnit::getOrCreateSourceID(const DIFile *File) {
    if (!SplitLineTable)
      return getCU().getOrCreateSourceID(File);
    if (!UsedLineTable) {
      UsedLineTable = true;
      // This is a split type unit that needs a line table.
      addSectionOffset(getUnitDie(), dwarf::DW_AT_stmt_list, 0);
    }
    return SplitLineTable->getFile(File->getDirectory(), File->getFilename(),
                                   getMD5AsBytes(File),
                                   Asm->OutContext.getDwarfVersion(),
                                   File->getSource());
  }
  
  void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {
    if (DD->getDwarfVersion() >= 5) {
      addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addrx);
      addUInt(Die, dwarf::DW_FORM_addrx, DD->getAddressPool().getIndex(Sym));
      return;
    }
  
    if (DD->useSplitDwarf()) {
      addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
      addUInt(Die, dwarf::DW_FORM_GNU_addr_index,
              DD->getAddressPool().getIndex(Sym));
      return;
    }
  
    addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
    addLabel(Die, dwarf::DW_FORM_udata, Sym);
  }
  
  void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute,
                                const MCSymbol *Hi, const MCSymbol *Lo) {
    Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_data4,
                 new (DIEValueAllocator) DIEDelta(Hi, Lo));
  }
  
  void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry) {
    addDIEEntry(Die, Attribute, DIEEntry(Entry));
  }
  
  void DwarfUnit::addDIETypeSignature(DIE &Die, uint64_t Signature) {
    // Flag the type unit reference as a declaration so that if it contains
    // members (implicit special members, static data member definitions, member
    // declarations for definitions in this CU, etc) consumers don't get confused
    // and think this is a full definition.
    addFlag(Die, dwarf::DW_AT_declaration);
  
    Die.addValue(DIEValueAllocator, dwarf::DW_AT_signature,
                 dwarf::DW_FORM_ref_sig8, DIEInteger(Signature));
  }
  
  void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,
                              DIEEntry Entry) {
    const DIEUnit *CU = Die.getUnit();
    const DIEUnit *EntryCU = Entry.getEntry().getUnit();
    if (!CU)
      // We assume that Die belongs to this CU, if it is not linked to any CU yet.
      CU = getUnitDie().getUnit();
    if (!EntryCU)
      EntryCU = getUnitDie().getUnit();
    Die.addValue(DIEValueAllocator, Attribute,
                 EntryCU == CU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
                 Entry);
  }
  
  DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N) {
    DIE &Die = Parent.addChild(DIE::get(DIEValueAllocator, (dwarf::Tag)Tag));
    if (N)
      insertDIE(N, &Die);
    return Die;
  }
  
  void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) {
    Loc->ComputeSize(Asm);
    DIELocs.push_back(Loc); // Memoize so we can call the destructor later on.
    Die.addValue(DIEValueAllocator, Attribute,
                 Loc->BestForm(DD->getDwarfVersion()), Loc);
  }
  
  void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute,
                           DIEBlock *Block) {
    Block->ComputeSize(Asm);
    DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
    Die.addValue(DIEValueAllocator, Attribute, Block->BestForm(), Block);
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, const DIFile *File) {
    if (Line == 0)
      return;
  
    unsigned FileID = getOrCreateSourceID(File);
    addUInt(Die, dwarf::DW_AT_decl_file, None, FileID);
    addUInt(Die, dwarf::DW_AT_decl_line, None, Line);
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, const DILocalVariable *V) {
    assert(V);
  
    addSourceLine(Die, V->getLine(), V->getFile());
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, const DIGlobalVariable *G) {
    assert(G);
  
    addSourceLine(Die, G->getLine(), G->getFile());
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, const DISubprogram *SP) {
    assert(SP);
  
    addSourceLine(Die, SP->getLine(), SP->getFile());
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, const DILabel *L) {
    assert(L);
  
    addSourceLine(Die, L->getLine(), L->getFile());
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, const DIType *Ty) {
    assert(Ty);
  
    addSourceLine(Die, Ty->getLine(), Ty->getFile());
  }
  
  void DwarfUnit::addSourceLine(DIE &Die, const DIObjCProperty *Ty) {
    assert(Ty);
  
    addSourceLine(Die, Ty->getLine(), Ty->getFile());
  }
  
  /// Return true if type encoding is unsigned.
  static bool isUnsignedDIType(DwarfDebug *DD, const DIType *Ty) {
    if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
      // FIXME: Enums without a fixed underlying type have unknown signedness
      // here, leading to incorrectly emitted constants.
      if (CTy->getTag() == dwarf::DW_TAG_enumeration_type)
        return false;
  
      // (Pieces of) aggregate types that get hacked apart by SROA may be
      // represented by a constant. Encode them as unsigned bytes.
      return true;
    }
  
    if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
      dwarf::Tag T = (dwarf::Tag)Ty->getTag();
      // Encode pointer constants as unsigned bytes. This is used at least for
      // null pointer constant emission.
      // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed
      // here, but accept them for now due to a bug in SROA producing bogus
      // dbg.values.
      if (T == dwarf::DW_TAG_pointer_type ||
          T == dwarf::DW_TAG_ptr_to_member_type ||
          T == dwarf::DW_TAG_reference_type ||
          T == dwarf::DW_TAG_rvalue_reference_type)
        return true;
      assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
             T == dwarf::DW_TAG_volatile_type ||
             T == dwarf::DW_TAG_restrict_type || T == dwarf::DW_TAG_atomic_type);
      assert(DTy->getBaseType() && "Expected valid base type");
      return isUnsignedDIType(DD, DTy->getBaseType());
    }
  
    auto *BTy = cast<DIBasicType>(Ty);
    unsigned Encoding = BTy->getEncoding();
    assert((Encoding == dwarf::DW_ATE_unsigned ||
            Encoding == dwarf::DW_ATE_unsigned_char ||
            Encoding == dwarf::DW_ATE_signed ||
            Encoding == dwarf::DW_ATE_signed_char ||
            Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
            Encoding == dwarf::DW_ATE_boolean ||
            (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
             Ty->getName() == "decltype(nullptr)")) &&
           "Unsupported encoding");
    return Encoding == dwarf::DW_ATE_unsigned ||
           Encoding == dwarf::DW_ATE_unsigned_char ||
           Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
           Ty->getTag() == dwarf::DW_TAG_unspecified_type;
  }
  
  void DwarfUnit::addConstantFPValue(DIE &Die, const MachineOperand &MO) {
    assert(MO.isFPImm() && "Invalid machine operand!");
    DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
    APFloat FPImm = MO.getFPImm()->getValueAPF();
  
    // Get the raw data form of the floating point.
    const APInt FltVal = FPImm.bitcastToAPInt();
    const char *FltPtr = (const char *)FltVal.getRawData();
  
    int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
    bool LittleEndian = Asm->getDataLayout().isLittleEndian();
    int Incr = (LittleEndian ? 1 : -1);
    int Start = (LittleEndian ? 0 : NumBytes - 1);
    int Stop = (LittleEndian ? NumBytes : -1);
  
    // Output the constant to DWARF one byte at a time.
    for (; Start != Stop; Start += Incr)
      addUInt(*Block, dwarf::DW_FORM_data1, (unsigned char)0xFF & FltPtr[Start]);
  
    addBlock(Die, dwarf::DW_AT_const_value, Block);
  }
  
  void DwarfUnit::addConstantFPValue(DIE &Die, const ConstantFP *CFP) {
    // Pass this down to addConstantValue as an unsigned bag of bits.
    addConstantValue(Die, CFP->getValueAPF().bitcastToAPInt(), true);
  }
  
  void DwarfUnit::addConstantValue(DIE &Die, const ConstantInt *CI,
                                   const DIType *Ty) {
    addConstantValue(Die, CI->getValue(), Ty);
  }
  
  void DwarfUnit::addConstantValue(DIE &Die, const MachineOperand &MO,
                                   const DIType *Ty) {
    assert(MO.isImm() && "Invalid machine operand!");
  
    addConstantValue(Die, isUnsignedDIType(DD, Ty), MO.getImm());
  }
  
  void DwarfUnit::addConstantValue(DIE &Die, uint64_t Val, const DIType *Ty) {
    addConstantValue(Die, isUnsignedDIType(DD, Ty), Val);
  }
  
  void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) {
    // FIXME: This is a bit conservative/simple - it emits negative values always
    // sign extended to 64 bits rather than minimizing the number of bytes.
    addUInt(Die, dwarf::DW_AT_const_value,
            Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);
  }
  
  void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty) {
    addConstantValue(Die, Val, isUnsignedDIType(DD, Ty));
  }
  
  void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) {
    unsigned CIBitWidth = Val.getBitWidth();
    if (CIBitWidth <= 64) {
      addConstantValue(Die, Unsigned,
                       Unsigned ? Val.getZExtValue() : Val.getSExtValue());
      return;
    }
  
    DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
  
    // Get the raw data form of the large APInt.
    const uint64_t *Ptr64 = Val.getRawData();
  
    int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
    bool LittleEndian = Asm->getDataLayout().isLittleEndian();
  
    // Output the constant to DWARF one byte at a time.
    for (int i = 0; i < NumBytes; i++) {
      uint8_t c;
      if (LittleEndian)
        c = Ptr64[i / 8] >> (8 * (i & 7));
      else
        c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
      addUInt(*Block, dwarf::DW_FORM_data1, c);
    }
  
    addBlock(Die, dwarf::DW_AT_const_value, Block);
  }
  
  void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) {
    if (!LinkageName.empty())
      addString(Die,
                DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name
                                           : dwarf::DW_AT_MIPS_linkage_name,
                GlobalValue::dropLLVMManglingEscape(LinkageName));
  }
  
  void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) {
    // Add template parameters.
    for (const auto *Element : TParams) {
      if (auto *TTP = dyn_cast<DITemplateTypeParameter>(Element))
        constructTemplateTypeParameterDIE(Buffer, TTP);
      else if (auto *TVP = dyn_cast<DITemplateValueParameter>(Element))
        constructTemplateValueParameterDIE(Buffer, TVP);
    }
  }
  
  /// Add thrown types.
  void DwarfUnit::addThrownTypes(DIE &Die, DINodeArray ThrownTypes) {
    for (const auto *Ty : ThrownTypes) {
      DIE &TT = createAndAddDIE(dwarf::DW_TAG_thrown_type, Die);
      addType(TT, cast<DIType>(Ty));
    }
  }
  
  DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {
    if (!Context || isa<DIFile>(Context))
      return &getUnitDie();
    if (auto *T = dyn_cast<DIType>(Context))
      return getOrCreateTypeDIE(T);
    if (auto *NS = dyn_cast<DINamespace>(Context))
      return getOrCreateNameSpace(NS);
    if (auto *M = dyn_cast<DIModule>(Context))
      return getOrCreateModule(M);
    if (auto *SP = dyn_cast<DISubprogram>(Context))
      return getOrCreateSubprogramDIE(SP);
    if (auto *M = dyn_cast<DIModule>(Context))
      return getOrCreateModule(M);
    return getDIE(Context);
  }
  
  DIE *DwarfUnit::createTypeDIE(const DICompositeType *Ty) {
    auto *Context = Ty->getScope();
    DIE *ContextDIE = getOrCreateContextDIE(Context);
  
    if (DIE *TyDIE = getDIE(Ty))
      return TyDIE;
  
    // Create new type.
    DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty);
  
    constructTypeDIE(TyDIE, cast<DICompositeType>(Ty));
  
    updateAcceleratorTables(Context, Ty, TyDIE);
    return &TyDIE;
  }
  
  DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE,
                                const DIType *Ty) {
    // Create new type.
    DIE &TyDIE = createAndAddDIE(Ty->getTag(), ContextDIE, Ty);
  
    updateAcceleratorTables(Context, Ty, TyDIE);
  
    if (auto *BT = dyn_cast<DIBasicType>(Ty))
      constructTypeDIE(TyDIE, BT);
    else if (auto *STy = dyn_cast<DISubroutineType>(Ty))
      constructTypeDIE(TyDIE, STy);
    else if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
      if (DD->generateTypeUnits() && !Ty->isForwardDecl() &&
          (Ty->getRawName() || CTy->getRawIdentifier())) {
        // Skip updating the accelerator tables since this is not the full type.
        if (MDString *TypeId = CTy->getRawIdentifier())
          DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy);
        else {
          auto X = DD->enterNonTypeUnitContext();
          finishNonUnitTypeDIE(TyDIE, CTy);
        }
        return &TyDIE;
      }
      constructTypeDIE(TyDIE, CTy);
    } else {
      constructTypeDIE(TyDIE, cast<DIDerivedType>(Ty));
    }
  
    return &TyDIE;
  }
  
  DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
    if (!TyNode)
      return nullptr;
  
    auto *Ty = cast<DIType>(TyNode);
  
    // DW_TAG_restrict_type is not supported in DWARF2
    if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)
      return getOrCreateTypeDIE(cast<DIDerivedType>(Ty)->getBaseType());
  
    // DW_TAG_atomic_type is not supported in DWARF < 5
    if (Ty->getTag() == dwarf::DW_TAG_atomic_type && DD->getDwarfVersion() < 5)
      return getOrCreateTypeDIE(cast<DIDerivedType>(Ty)->getBaseType());
  
    // Construct the context before querying for the existence of the DIE in case
    // such construction creates the DIE.
    auto *Context = Ty->getScope();
    DIE *ContextDIE = getOrCreateContextDIE(Context);
    assert(ContextDIE);
  
    if (DIE *TyDIE = getDIE(Ty))
      return TyDIE;
  
    return static_cast<DwarfUnit *>(ContextDIE->getUnit())
        ->createTypeDIE(Context, *ContextDIE, Ty);
  }
  
  void DwarfUnit::updateAcceleratorTables(const DIScope *Context,
                                          const DIType *Ty, const DIE &TyDIE) {
    if (!Ty->getName().empty() && !Ty->isForwardDecl()) {
      bool IsImplementation = false;
      if (auto *CT = dyn_cast<DICompositeType>(Ty)) {
        // A runtime language of 0 actually means C/C++ and that any
        // non-negative value is some version of Objective-C/C++.
        IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
      }
      unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
      DD->addAccelType(*CUNode, Ty->getName(), TyDIE, Flags);
  
      if (!Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) ||
          isa<DINamespace>(Context) || isa<DICommonBlock>(Context))
        addGlobalType(Ty, TyDIE, Context);
    }
  }
  
  void DwarfUnit::addType(DIE &Entity, const DIType *Ty,
                          dwarf::Attribute Attribute) {
    assert(Ty && "Trying to add a type that doesn't exist?");
    addDIEEntry(Entity, Attribute, DIEEntry(*getOrCreateTypeDIE(Ty)));
  }
  
  std::string DwarfUnit::getParentContextString(const DIScope *Context) const {
    if (!Context)
      return "";
  
    // FIXME: Decide whether to implement this for non-C++ languages.
    if (!dwarf::isCPlusPlus((dwarf::SourceLanguage)getLanguage()))
      return "";
  
    std::string CS;
    SmallVector<const DIScope *, 1> Parents;
    while (!isa<DICompileUnit>(Context)) {
      Parents.push_back(Context);
      if (const DIScope *S = Context->getScope())
        Context = S;
      else
        // Structure, etc types will have a NULL context if they're at the top
        // level.
        break;
    }
  
    // Reverse iterate over our list to go from the outermost construct to the
    // innermost.
    for (const DIScope *Ctx : make_range(Parents.rbegin(), Parents.rend())) {
      StringRef Name = Ctx->getName();
      if (Name.empty() && isa<DINamespace>(Ctx))
        Name = "(anonymous namespace)";
      if (!Name.empty()) {
        CS += Name;
        CS += "::";
      }
    }
    return CS;
  }
  
  void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
    // Get core information.
    StringRef Name = BTy->getName();
    // Add name if not anonymous or intermediate type.
    if (!Name.empty())
      addString(Buffer, dwarf::DW_AT_name, Name);
  
    // An unspecified type only has a name attribute.
    if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)
      return;
  
    addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
            BTy->getEncoding());
  
    uint64_t Size = BTy->getSizeInBits() >> 3;
    addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
  
    if (BTy->isBigEndian())
      addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_big);
    else if (BTy->isLittleEndian())
      addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_little);
  }
  
  void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {
    // Get core information.
    StringRef Name = DTy->getName();
    uint64_t Size = DTy->getSizeInBits() >> 3;
    uint16_t Tag = Buffer.getTag();
  
    // Map to main type, void will not have a type.
    const DIType *FromTy = DTy->getBaseType();
    if (FromTy)
      addType(Buffer, FromTy);
  
    // Add name if not anonymous or intermediate type.
    if (!Name.empty())
      addString(Buffer, dwarf::DW_AT_name, Name);
  
    // Add size if non-zero (derived types might be zero-sized.)
    if (Size && Tag != dwarf::DW_TAG_pointer_type
             && Tag != dwarf::DW_TAG_ptr_to_member_type
             && Tag != dwarf::DW_TAG_reference_type
             && Tag != dwarf::DW_TAG_rvalue_reference_type)
      addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
  
    if (Tag == dwarf::DW_TAG_ptr_to_member_type)
      addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
                  *getOrCreateTypeDIE(cast<DIDerivedType>(DTy)->getClassType()));
    // Add source line info if available and TyDesc is not a forward declaration.
    if (!DTy->isForwardDecl())
      addSourceLine(Buffer, DTy);
  
    // If DWARF address space value is other than None, add it.  The IR
    // verifier checks that DWARF address space only exists for pointer
    // or reference types.
    if (DTy->getDWARFAddressSpace())
      addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,
              DTy->getDWARFAddressSpace().getValue());
  }
  
  void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) {
    for (unsigned i = 1, N = Args.size(); i < N; ++i) {
      const DIType *Ty = Args[i];
      if (!Ty) {
        assert(i == N-1 && "Unspecified parameter must be the last argument");
        createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
      } else {
        DIE &Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
        addType(Arg, Ty);
        if (Ty->isArtificial())
          addFlag(Arg, dwarf::DW_AT_artificial);
      }
    }
  }
  
  void DwarfUnit::constructTypeDIE(DIE &Buffer, const DISubroutineType *CTy) {
    // Add return type.  A void return won't have a type.
    auto Elements = cast<DISubroutineType>(CTy)->getTypeArray();
    if (Elements.size())
      if (auto RTy = Elements[0])
        addType(Buffer, RTy);
  
    bool isPrototyped = true;
    if (Elements.size() == 2 && !Elements[1])
      isPrototyped = false;
  
    constructSubprogramArguments(Buffer, Elements);
  
    // Add prototype flag if we're dealing with a C language and the function has
    // been prototyped.
    uint16_t Language = getLanguage();
    if (isPrototyped &&
        (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
         Language == dwarf::DW_LANG_ObjC))
      addFlag(Buffer, dwarf::DW_AT_prototyped);
  
    // Add a DW_AT_calling_convention if this has an explicit convention.
    if (CTy->getCC() && CTy->getCC() != dwarf::DW_CC_normal)
      addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
              CTy->getCC());
  
    if (CTy->isLValueReference())
      addFlag(Buffer, dwarf::DW_AT_reference);
  
    if (CTy->isRValueReference())
      addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
  }
  
  void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
    // Add name if not anonymous or intermediate type.
    StringRef Name = CTy->getName();
  
    uint64_t Size = CTy->getSizeInBits() >> 3;
    uint16_t Tag = Buffer.getTag();
  
    switch (Tag) {
    case dwarf::DW_TAG_array_type:
      constructArrayTypeDIE(Buffer, CTy);
      break;
    case dwarf::DW_TAG_enumeration_type:
      constructEnumTypeDIE(Buffer, CTy);
      break;
    case dwarf::DW_TAG_variant_part:
    case dwarf::DW_TAG_structure_type:
    case dwarf::DW_TAG_union_type:
    case dwarf::DW_TAG_class_type: {
      // Emit the discriminator for a variant part.
      DIDerivedType *Discriminator = nullptr;
      if (Tag == dwarf::DW_TAG_variant_part) {
        Discriminator = CTy->getDiscriminator();
        if (Discriminator) {
          // DWARF says:
          //    If the variant part has a discriminant, the discriminant is
          //    represented by a separate debugging information entry which is
          //    a child of the variant part entry.
          DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
          addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
        }
      }
  
      // Add elements to structure type.
      DINodeArray Elements = CTy->getElements();
      for (const auto *Element : Elements) {
        if (!Element)
          continue;
        if (auto *SP = dyn_cast<DISubprogram>(Element))
          getOrCreateSubprogramDIE(SP);
        else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
          if (DDTy->getTag() == dwarf::DW_TAG_friend) {
            DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
            addType(ElemDie, DDTy->getBaseType(), dwarf::DW_AT_friend);
          } else if (DDTy->isStaticMember()) {
            getOrCreateStaticMemberDIE(DDTy);
          } else if (Tag == dwarf::DW_TAG_variant_part) {
            // When emitting a variant part, wrap each member in
            // DW_TAG_variant.
            DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
            if (const ConstantInt *CI =
                dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
              if (isUnsignedDIType(DD, Discriminator->getBaseType()))
                addUInt(Variant, dwarf::DW_AT_discr_value, None, CI->getZExtValue());
              else
                addSInt(Variant, dwarf::DW_AT_discr_value, None, CI->getSExtValue());
            }
            constructMemberDIE(Variant, DDTy);
          } else {
            constructMemberDIE(Buffer, DDTy);
          }
        } else if (auto *Property = dyn_cast<DIObjCProperty>(Element)) {
          DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer);
          StringRef PropertyName = Property->getName();
          addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
          if (Property->getType())
            addType(ElemDie, Property->getType());
          addSourceLine(ElemDie, Property);
          StringRef GetterName = Property->getGetterName();
          if (!GetterName.empty())
            addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
          StringRef SetterName = Property->getSetterName();
          if (!SetterName.empty())
            addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
          if (unsigned PropertyAttributes = Property->getAttributes())
            addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None,
                    PropertyAttributes);
        } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
          if (Composite->getTag() == dwarf::DW_TAG_variant_part) {
            DIE &VariantPart = createAndAddDIE(Composite->getTag(), Buffer);
            constructTypeDIE(VariantPart, Composite);
          }
        }
      }
  
      if (CTy->isAppleBlockExtension())
        addFlag(Buffer, dwarf::DW_AT_APPLE_block);
  
      if (CTy->getExportSymbols())
        addFlag(Buffer, dwarf::DW_AT_export_symbols);
  
      // This is outside the DWARF spec, but GDB expects a DW_AT_containing_type
      // inside C++ composite types to point to the base class with the vtable.
      // Rust uses DW_AT_containing_type to link a vtable to the type
      // for which it was created.
      if (auto *ContainingType = CTy->getVTableHolder())
        addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
                    *getOrCreateTypeDIE(ContainingType));
  
      if (CTy->isObjcClassComplete())
        addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
  
      // Add template parameters to a class, structure or union types.
      // FIXME: The support isn't in the metadata for this yet.
      if (Tag == dwarf::DW_TAG_class_type ||
          Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
        addTemplateParams(Buffer, CTy->getTemplateParams());
  
      // Add the type's non-standard calling convention.
      uint8_t CC = 0;
      if (CTy->isTypePassByValue())
        CC = dwarf::DW_CC_pass_by_value;
      else if (CTy->isTypePassByReference())
        CC = dwarf::DW_CC_pass_by_reference;
      if (CC)
        addUInt(Buffer, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1,
                CC);
      break;
    }
    default:
      break;
    }
  
    // Add name if not anonymous or intermediate type.
    if (!Name.empty())
      addString(Buffer, dwarf::DW_AT_name, Name);
  
    // For Swift, mangled names are put into DW_AT_linkage_name; human-readable
    // names are emitted put into DW_AT_name and the accelerator table.
    if ((CTy->getRuntimeLang() == dwarf::DW_LANG_Swift ||
         CTy->getRuntimeLang() == dwarf::DW_LANG_PLI) &&
        CTy->getRawIdentifier())
      addString(Buffer, dwarf::DW_AT_linkage_name, CTy->getIdentifier());
  
    if (Tag == dwarf::DW_TAG_enumeration_type ||
        Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
        Tag == dwarf::DW_TAG_union_type) {
      // Add size if non-zero (derived types might be zero-sized.)
      // TODO: Do we care about size for enum forward declarations?
      if (Size)
        addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
      else if (!CTy->isForwardDecl())
        // Add zero size if it is not a forward declaration.
        addUInt(Buffer, dwarf::DW_AT_byte_size, None, 0);
  
      // If we're a forward decl, say so.
      if (CTy->isForwardDecl())
        addFlag(Buffer, dwarf::DW_AT_declaration);
  
      // Add source line info if available.
      if (!CTy->isForwardDecl())
        addSourceLine(Buffer, CTy);
  
      // No harm in adding the runtime language to the declaration.
      unsigned RLang = CTy->getRuntimeLang();
      if (RLang)
        addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, None, RLang);
  
      // Add align info if available.
      if (uint32_t AlignInBytes = CTy->getAlignInBytes())
        addUInt(Buffer, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
                AlignInBytes);
    }
  }
  
  void DwarfUnit::constructTemplateTypeParameterDIE(
      DIE &Buffer, const DITemplateTypeParameter *TP) {
    DIE &ParamDIE =
        createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer);
    // Add the type if it exists, it could be void and therefore no type.
    if (TP->getType())
      addType(ParamDIE, TP->getType());
    if (!TP->getName().empty())
      addString(ParamDIE, dwarf::DW_AT_name, TP->getName());
  }
  
  void DwarfUnit::constructTemplateValueParameterDIE(
      DIE &Buffer, const DITemplateValueParameter *VP) {
    DIE &ParamDIE = createAndAddDIE(VP->getTag(), Buffer);
  
    // Add the type if there is one, template template and template parameter
    // packs will not have a type.
    if (VP->getTag() == dwarf::DW_TAG_template_value_parameter)
      addType(ParamDIE, VP->getType());
    if (!VP->getName().empty())
      addString(ParamDIE, dwarf::DW_AT_name, VP->getName());
    if (Metadata *Val = VP->getValue()) {
      if (ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
        addConstantValue(ParamDIE, CI, VP->getType());
      else if (GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {
        // We cannot describe the location of dllimport'd entities: the
        // computation of their address requires loads from the IAT.
        if (!GV->hasDLLImportStorageClass()) {
          // For declaration non-type template parameters (such as global values
          // and functions)
          DIELoc *Loc = new (DIEValueAllocator) DIELoc;
          addOpAddress(*Loc, Asm->getSymbol(GV));
          // Emit DW_OP_stack_value to use the address as the immediate value of
          // the parameter, rather than a pointer to it.
          addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
          addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
        }
      } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_template_param) {
        assert(isa<MDString>(Val));
        addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
                  cast<MDString>(Val)->getString());
      } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
        addTemplateParams(ParamDIE, cast<MDTuple>(Val));
      }
    }
  }
  
  DIE *DwarfUnit::getOrCreateNameSpace(const DINamespace *NS) {
    // Construct the context before querying for the existence of the DIE in case
    // such construction creates the DIE.
    DIE *ContextDIE = getOrCreateContextDIE(NS->getScope());
  
    if (DIE *NDie = getDIE(NS))
      return NDie;
    DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);
  
    StringRef Name = NS->getName();
    if (!Name.empty())
      addString(NDie, dwarf::DW_AT_name, NS->getName());
    else
      Name = "(anonymous namespace)";
    DD->addAccelNamespace(*CUNode, Name, NDie);
    addGlobalName(Name, NDie, NS->getScope());
    if (NS->getExportSymbols())
      addFlag(NDie, dwarf::DW_AT_export_symbols);
    return &NDie;
  }
  
  DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
    // Construct the context before querying for the existence of the DIE in case
    // such construction creates the DIE.
    DIE *ContextDIE = getOrCreateContextDIE(M->getScope());
  
    if (DIE *MDie = getDIE(M))
      return MDie;
    DIE &MDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, M);
  
    if (!M->getName().empty()) {
      addString(MDie, dwarf::DW_AT_name, M->getName());
      addGlobalName(M->getName(), MDie, M->getScope());
    }
    if (!M->getConfigurationMacros().empty())
      addString(MDie, dwarf::DW_AT_LLVM_config_macros,
                M->getConfigurationMacros());
    if (!M->getIncludePath().empty())
      addString(MDie, dwarf::DW_AT_LLVM_include_path, M->getIncludePath());
    if (!M->getISysRoot().empty())
      addString(MDie, dwarf::DW_AT_LLVM_isysroot, M->getISysRoot());
  
    return &MDie;
  }
  
  DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {
    // Construct the context before querying for the existence of the DIE in case
    // such construction creates the DIE (as is the case for member function
    // declarations).
    DIE *ContextDIE =
        Minimal ? &getUnitDie() : getOrCreateContextDIE(SP->getScope());
  
    if (DIE *SPDie = getDIE(SP))
      return SPDie;
  
    if (auto *SPDecl = SP->getDeclaration()) {
      if (!Minimal) {
        // Add subprogram definitions to the CU die directly.
        ContextDIE = &getUnitDie();
        // Build the decl now to ensure it precedes the definition.
        getOrCreateSubprogramDIE(SPDecl);
      }
    }
  
    // DW_TAG_inlined_subroutine may refer to this DIE.
    DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
  
    // Stop here and fill this in later, depending on whether or not this
    // subprogram turns out to have inlined instances or not.
    if (SP->isDefinition())
      return &SPDie;
  
    static_cast<DwarfUnit *>(SPDie.getUnit())
        ->applySubprogramAttributes(SP, SPDie);
    return &SPDie;
  }
  
  bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
                                                      DIE &SPDie) {
    DIE *DeclDie = nullptr;
    StringRef DeclLinkageName;
    if (auto *SPDecl = SP->getDeclaration()) {
      DeclDie = getDIE(SPDecl);
      assert(DeclDie && "This DIE should've already been constructed when the "
                        "definition DIE was created in "
                        "getOrCreateSubprogramDIE");
      // Look at the Decl's linkage name only if we emitted it.
      if (DD->useAllLinkageNames())
        DeclLinkageName = SPDecl->getLinkageName();
      unsigned DeclID = getOrCreateSourceID(SPDecl->getFile());
      unsigned DefID = getOrCreateSourceID(SP->getFile());
      if (DeclID != DefID)
        addUInt(SPDie, dwarf::DW_AT_decl_file, None, DefID);
  
      if (SP->getLine() != SPDecl->getLine())
        addUInt(SPDie, dwarf::DW_AT_decl_line, None, SP->getLine());
    }
  
    // Add function template parameters.
    addTemplateParams(SPDie, SP->getTemplateParams());
  
    // Add the linkage name if we have one and it isn't in the Decl.
    StringRef LinkageName = SP->getLinkageName();
    assert(((LinkageName.empty() || DeclLinkageName.empty()) ||
            LinkageName == DeclLinkageName) &&
           "decl has a linkage name and it is different");
    if (DeclLinkageName.empty() &&
        // Always emit it for abstract subprograms.
        (DD->useAllLinkageNames() || DU->getAbstractSPDies().lookup(SP)))
      addLinkageName(SPDie, LinkageName);
  
    if (!DeclDie)
      return false;
  
    // Refer to the function declaration where all the other attributes will be
    // found.
    addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
    return true;
  }
  
  void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
                                            bool SkipSPAttributes) {
    // If -fdebug-info-for-profiling is enabled, need to emit the subprogram
    // and its source location.
    bool SkipSPSourceLocation = SkipSPAttributes &&
                                !CUNode->getDebugInfoForProfiling();
    if (!SkipSPSourceLocation)
      if (applySubprogramDefinitionAttributes(SP, SPDie))
        return;
  
    // Constructors and operators for anonymous aggregates do not have names.
    if (!SP->getName().empty())
      addString(SPDie, dwarf::DW_AT_name, SP->getName());
  
    if (!SkipSPSourceLocation)
      addSourceLine(SPDie, SP);
  
    // Skip the rest of the attributes under -gmlt to save space.
    if (SkipSPAttributes)
      return;
  
    // Add the prototype if we have a prototype and we have a C like
    // language.
    uint16_t Language = getLanguage();
    if (SP->isPrototyped() &&
        (Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
         Language == dwarf::DW_LANG_ObjC))
      addFlag(SPDie, dwarf::DW_AT_prototyped);
  
    unsigned CC = 0;
    DITypeRefArray Args;
    if (const DISubroutineType *SPTy = SP->getType()) {
      Args = SPTy->getTypeArray();
      CC = SPTy->getCC();
    }
  
    // Add a DW_AT_calling_convention if this has an explicit convention.
    if (CC && CC != dwarf::DW_CC_normal)
      addUInt(SPDie, dwarf::DW_AT_calling_convention, dwarf::DW_FORM_data1, CC);
  
    // Add a return type. If this is a type like a C/C++ void type we don't add a
    // return type.
    if (Args.size())
      if (auto Ty = Args[0])
        addType(SPDie, Ty);
  
    unsigned VK = SP->getVirtuality();
    if (VK) {
      addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
      if (SP->getVirtualIndex() != -1u) {
        DIELoc *Block = getDIELoc();
        addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
        addUInt(*Block, dwarf::DW_FORM_udata, SP->getVirtualIndex());
        addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);
      }
      ContainingTypeMap.insert(std::make_pair(&SPDie, SP->getContainingType()));
    }
  
    if (!SP->isDefinition()) {
      addFlag(SPDie, dwarf::DW_AT_declaration);
  
      // Add arguments. Do not add arguments for subprogram definition. They will
      // be handled while processing variables.
      constructSubprogramArguments(SPDie, Args);
    }
  
    addThrownTypes(SPDie, SP->getThrownTypes());
  
    if (SP->isArtificial())
      addFlag(SPDie, dwarf::DW_AT_artificial);
  
    if (!SP->isLocalToUnit())
      addFlag(SPDie, dwarf::DW_AT_external);
  
    if (DD->useAppleExtensionAttributes()) {
      if (SP->isOptimized())
        addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
  
      if (unsigned isa = Asm->getISAEncoding())
        addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
    }
  
    if (SP->isLValueReference())
      addFlag(SPDie, dwarf::DW_AT_reference);
  
    if (SP->isRValueReference())
      addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
  
    if (SP->isNoReturn())
      addFlag(SPDie, dwarf::DW_AT_noreturn);
  
    if (SP->isProtected())
      addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_protected);
    else if (SP->isPrivate())
      addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_private);
    else if (SP->isPublic())
      addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_public);
  
    if (SP->isExplicit())
      addFlag(SPDie, dwarf::DW_AT_explicit);
  
    if (SP->isMainSubprogram())
      addFlag(SPDie, dwarf::DW_AT_main_subprogram);
    if (SP->isPure())
      addFlag(SPDie, dwarf::DW_AT_pure);
    if (SP->isElemental())
      addFlag(SPDie, dwarf::DW_AT_elemental);
    if (SP->isRecursive())
      addFlag(SPDie, dwarf::DW_AT_recursive);
  }
  
  void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
                                       DIE *IndexTy) {
    DIE &DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer);
    addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
  
    // The LowerBound value defines the lower bounds which is typically zero for
    // C/C++. The Count value is the number of elements.  Values are 64 bit. If
    // Count == -1 then the array is unbounded and we do not emit
    // DW_AT_lower_bound and DW_AT_count attributes.
    int64_t LowerBound = SR->getLowerBound();
    int64_t DefaultLowerBound = getDefaultLowerBound();
    int64_t Count = -1;
    if (auto *CI = SR->getCount().dyn_cast<ConstantInt*>())
      Count = CI->getSExtValue();
  
    if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
      addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, None, LowerBound);
  
    if (auto *CV = SR->getCount().dyn_cast<DIVariable*>()) {
      if (auto *CountVarDIE = getDIE(CV))
        addDIEEntry(DW_Subrange, dwarf::DW_AT_count, *CountVarDIE);
    } else if (Count != -1)
      addUInt(DW_Subrange, dwarf::DW_AT_count, None, Count);
  }
  
  DIE *DwarfUnit::getIndexTyDie() {
    if (IndexTyDie)
      return IndexTyDie;
    // Construct an integer type to use for indexes.
    IndexTyDie = &createAndAddDIE(dwarf::DW_TAG_base_type, getUnitDie());
    StringRef Name = "__ARRAY_SIZE_TYPE__";
    addString(*IndexTyDie, dwarf::DW_AT_name, Name);
    addUInt(*IndexTyDie, dwarf::DW_AT_byte_size, None, sizeof(int64_t));
    addUInt(*IndexTyDie, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
            dwarf::DW_ATE_unsigned);
    DD->addAccelType(*CUNode, Name, *IndexTyDie, /*Flags*/ 0);
    return IndexTyDie;
  }
  
  /// Returns true if the vector's size differs from the sum of sizes of elements
  /// the user specified.  This can occur if the vector has been rounded up to
  /// fit memory alignment constraints.
  static bool hasVectorBeenPadded(const DICompositeType *CTy) {
    assert(CTy && CTy->isVector() && "Composite type is not a vector");
    const uint64_t ActualSize = CTy->getSizeInBits();
  
    // Obtain the size of each element in the vector.
    DIType *BaseTy = CTy->getBaseType();
    assert(BaseTy && "Unknown vector element type.");
    const uint64_t ElementSize = BaseTy->getSizeInBits();
  
    // Locate the number of elements in the vector.
    const DINodeArray Elements = CTy->getElements();
    assert(Elements.size() == 1 &&
           Elements[0]->getTag() == dwarf::DW_TAG_subrange_type &&
           "Invalid vector element array, expected one element of type subrange");
    const auto Subrange = cast<DISubrange>(Elements[0]);
    const auto CI = Subrange->getCount().get<ConstantInt *>();
    const int32_t NumVecElements = CI->getSExtValue();
  
    // Ensure we found the element count and that the actual size is wide
    // enough to contain the requested size.
    assert(ActualSize >= (NumVecElements * ElementSize) && "Invalid vector size");
    return ActualSize != (NumVecElements * ElementSize);
  }
  
  void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
    if (CTy->isVector()) {
      addFlag(Buffer, dwarf::DW_AT_GNU_vector);
      if (hasVectorBeenPadded(CTy))
        addUInt(Buffer, dwarf::DW_AT_byte_size, None,
                CTy->getSizeInBits() / CHAR_BIT);
    }
  
    // Emit the element type.
    addType(Buffer, CTy->getBaseType());
  
    // Get an anonymous type for index type.
    // FIXME: This type should be passed down from the front end
    // as different languages may have different sizes for indexes.
    DIE *IdxTy = getIndexTyDie();
  
    // Add subranges to array type.
    DINodeArray Elements = CTy->getElements();
    for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
      // FIXME: Should this really be such a loose cast?
      if (auto *Element = dyn_cast_or_null<DINode>(Elements[i]))
        if (Element->getTag() == dwarf::DW_TAG_subrange_type)
          constructSubrangeDIE(Buffer, cast<DISubrange>(Element), IdxTy);
    }
  }
  
  void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
    const DIType *DTy = CTy->getBaseType();
    bool IsUnsigned = DTy && isUnsignedDIType(DD, DTy);
    if (DTy) {
      if (DD->getDwarfVersion() >= 3)
        addType(Buffer, DTy);
      if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagEnumClass))
        addFlag(Buffer, dwarf::DW_AT_enum_class);
    }
  
    auto *Context = CTy->getScope();
    bool IndexEnumerators = !Context || isa<DICompileUnit>(Context) || isa<DIFile>(Context) ||
        isa<DINamespace>(Context) || isa<DICommonBlock>(Context);
    DINodeArray Elements = CTy->getElements();
  
    // Add enumerators to enumeration type.
    for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
      auto *Enum = dyn_cast_or_null<DIEnumerator>(Elements[i]);
      if (Enum) {
        DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
        StringRef Name = Enum->getName();
        addString(Enumerator, dwarf::DW_AT_name, Name);
        auto Value = static_cast<uint64_t>(Enum->getValue());
        addConstantValue(Enumerator, IsUnsigned, Value);
        if (IndexEnumerators)
          addGlobalName(Name, Enumerator, Context);
      }
    }
  }
  
  void DwarfUnit::constructContainingTypeDIEs() {
    for (auto CI = ContainingTypeMap.begin(), CE = ContainingTypeMap.end();
         CI != CE; ++CI) {
      DIE &SPDie = *CI->first;
      const DINode *D = CI->second;
      if (!D)
        continue;
      DIE *NDie = getDIE(D);
      if (!NDie)
        continue;
      addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);
    }
  }
  
  DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
    DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer);
    StringRef Name = DT->getName();
    if (!Name.empty())
      addString(MemberDie, dwarf::DW_AT_name, Name);
  
    if (DIType *Resolved = DT->getBaseType())
      addType(MemberDie, Resolved);
  
    addSourceLine(MemberDie, DT);
  
    if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) {
  
      // For C++, virtual base classes are not at fixed offset. Use following
      // expression to extract appropriate offset from vtable.
      // BaseAddr = ObAddr + *((*ObAddr) - Offset)
  
      DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc;
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT->getOffsetInBits());
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
      addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
  
      addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
    } else {
      uint64_t Size = DT->getSizeInBits();
      uint64_t FieldSize = DD->getBaseTypeSize(DT);
      uint32_t AlignInBytes = DT->getAlignInBytes();
      uint64_t OffsetInBytes;
  
      bool IsBitfield = FieldSize && Size != FieldSize;
      if (IsBitfield) {
        // Handle bitfield, assume bytes are 8 bits.
        if (DD->useDWARF2Bitfields())
          addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8);
        addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size);
  
        uint64_t Offset = DT->getOffsetInBits();
        // We can't use DT->getAlignInBits() here: AlignInBits for member type
        // is non-zero if and only if alignment was forced (e.g. _Alignas()),
        // which can't be done with bitfields. Thus we use FieldSize here.
        uint32_t AlignInBits = FieldSize;
        uint32_t AlignMask = ~(AlignInBits - 1);
        // The bits from the start of the storage unit to the start of the field.
        uint64_t StartBitOffset = Offset - (Offset & AlignMask);
        // The byte offset of the field's aligned storage unit inside the struct.
        OffsetInBytes = (Offset - StartBitOffset) / 8;
  
        if (DD->useDWARF2Bitfields()) {
          uint64_t HiMark = (Offset + FieldSize) & AlignMask;
          uint64_t FieldOffset = (HiMark - FieldSize);
          Offset -= FieldOffset;
  
          // Maybe we need to work from the other end.
          if (Asm->getDataLayout().isLittleEndian())
            Offset = FieldSize - (Offset + Size);
  
          addUInt(MemberDie, dwarf::DW_AT_bit_offset, None, Offset);
          OffsetInBytes = FieldOffset >> 3;
        } else {
          addUInt(MemberDie, dwarf::DW_AT_data_bit_offset, None, Offset);
        }
      } else {
        // This is not a bitfield.
        OffsetInBytes = DT->getOffsetInBits() / 8;
        if (AlignInBytes)
          addUInt(MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
                  AlignInBytes);
      }
  
      if (DD->getDwarfVersion() <= 2) {
        DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
        addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
        addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
        addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
      } else if (!IsBitfield || DD->useDWARF2Bitfields())
        addUInt(MemberDie, dwarf::DW_AT_data_member_location, None,
                OffsetInBytes);
    }
  
    if (DT->isProtected())
      addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_protected);
    else if (DT->isPrivate())
      addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_private);
    // Otherwise C++ member and base classes are considered public.
    else if (DT->isPublic())
      addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_public);
    if (DT->isVirtual())
      addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
              dwarf::DW_VIRTUALITY_virtual);
  
    // Objective-C properties.
    if (DINode *PNode = DT->getObjCProperty())
      if (DIE *PDie = getDIE(PNode))
        MemberDie.addValue(DIEValueAllocator, dwarf::DW_AT_APPLE_property,
                           dwarf::DW_FORM_ref4, DIEEntry(*PDie));
  
    if (DT->isArtificial())
      addFlag(MemberDie, dwarf::DW_AT_artificial);
  
    return MemberDie;
  }
  
  DIE *DwarfUnit::getOrCreateStaticMemberDIE(const DIDerivedType *DT) {
    if (!DT)
      return nullptr;
  
    // Construct the context before querying for the existence of the DIE in case
    // such construction creates the DIE.
    DIE *ContextDIE = getOrCreateContextDIE(DT->getScope());
    assert(dwarf::isType(ContextDIE->getTag()) &&
           "Static member should belong to a type.");
  
    if (DIE *StaticMemberDIE = getDIE(DT))
      return StaticMemberDIE;
  
    DIE &StaticMemberDIE = createAndAddDIE(DT->getTag(), *ContextDIE, DT);
  
    const DIType *Ty = DT->getBaseType();
  
    addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName());
    addType(StaticMemberDIE, Ty);
    addSourceLine(StaticMemberDIE, DT);
    addFlag(StaticMemberDIE, dwarf::DW_AT_external);
    addFlag(StaticMemberDIE, dwarf::DW_AT_declaration);
  
    // FIXME: We could omit private if the parent is a class_type, and
    // public if the parent is something else.
    if (DT->isProtected())
      addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_protected);
    else if (DT->isPrivate())
      addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_private);
    else if (DT->isPublic())
      addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
              dwarf::DW_ACCESS_public);
  
    if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))
      addConstantValue(StaticMemberDIE, CI, Ty);
    if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))
      addConstantFPValue(StaticMemberDIE, CFP);
  
    if (uint32_t AlignInBytes = DT->getAlignInBytes())
      addUInt(StaticMemberDIE, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
              AlignInBytes);
  
    return &StaticMemberDIE;
  }
  
  void DwarfUnit::emitCommonHeader(bool UseOffsets, dwarf::UnitType UT) {
    // Emit size of content not including length itself
    Asm->OutStreamer->AddComment("Length of Unit");
    if (!DD->useSectionsAsReferences()) {
      StringRef Prefix = isDwoUnit() ? "debug_info_dwo_" : "debug_info_";
      MCSymbol *BeginLabel = Asm->createTempSymbol(Prefix + "start");
      EndLabel = Asm->createTempSymbol(Prefix + "end");
      Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
      Asm->OutStreamer->EmitLabel(BeginLabel);
    } else
      Asm->emitInt32(getHeaderSize() + getUnitDie().getSize());
  
    Asm->OutStreamer->AddComment("DWARF version number");
    unsigned Version = DD->getDwarfVersion();
    Asm->emitInt16(Version);
  
    // DWARF v5 reorders the address size and adds a unit type.
    if (Version >= 5) {
      Asm->OutStreamer->AddComment("DWARF Unit Type");
      Asm->emitInt8(UT);
      Asm->OutStreamer->AddComment("Address Size (in bytes)");
      Asm->emitInt8(Asm->MAI->getCodePointerSize());
    }
  
    // We share one abbreviations table across all units so it's always at the
    // start of the section. Use a relocatable offset where needed to ensure
    // linking doesn't invalidate that offset.
    Asm->OutStreamer->AddComment("Offset Into Abbrev. Section");
    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
    if (UseOffsets)
      Asm->emitInt32(0);
    else
      Asm->emitDwarfSymbolReference(
          TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false);
  
    if (Version <= 4) {
      Asm->OutStreamer->AddComment("Address Size (in bytes)");
      Asm->emitInt8(Asm->MAI->getCodePointerSize());
    }
  }
  
  void DwarfTypeUnit::emitHeader(bool UseOffsets) {
    DwarfUnit::emitCommonHeader(UseOffsets,
                                DD->useSplitDwarf() ? dwarf::DW_UT_split_type
                                                    : dwarf::DW_UT_type);
    Asm->OutStreamer->AddComment("Type Signature");
    Asm->OutStreamer->EmitIntValue(TypeSignature, sizeof(TypeSignature));
    Asm->OutStreamer->AddComment("Type DIE Offset");
    // In a skeleton type unit there is no type DIE so emit a zero offset.
    Asm->OutStreamer->EmitIntValue(Ty ? Ty->getOffset() : 0,
                                   sizeof(Ty->getOffset()));
  }
  
  DIE::value_iterator
  DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
                             const MCSymbol *Hi, const MCSymbol *Lo) {
    return Die.addValue(DIEValueAllocator, Attribute,
                        DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
                                                   : dwarf::DW_FORM_data4,
                        new (DIEValueAllocator) DIEDelta(Hi, Lo));
  }
  
  DIE::value_iterator
  DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
                             const MCSymbol *Label, const MCSymbol *Sec) {
    if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
      return addLabel(Die, Attribute,
                      DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
                                                 : dwarf::DW_FORM_data4,
                      Label);
    return addSectionDelta(Die, Attribute, Label, Sec);
  }
  
  bool DwarfTypeUnit::isDwoUnit() const {
    // Since there are no skeleton type units, all type units are dwo type units
    // when split DWARF is being used.
    return DD->useSplitDwarf();
  }
  
  void DwarfTypeUnit::addGlobalName(StringRef Name, const DIE &Die,
                                    const DIScope *Context) {
    getCU().addGlobalNameForTypeUnit(Name, Context);
  }
  
  void DwarfTypeUnit::addGlobalType(const DIType *Ty, const DIE &Die,
                                    const DIScope *Context) {
    getCU().addGlobalTypeUnitType(Ty, Context);
  }
  
  const MCSymbol *DwarfUnit::getCrossSectionRelativeBaseAddress() const {
    if (!Asm->MAI->doesDwarfUseRelocationsAcrossSections())
      return nullptr;
    if (isDwoUnit())
      return nullptr;
    return getSection()->getBeginSymbol();
  }
  
  void DwarfUnit::addStringOffsetsStart() {
    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
    addSectionLabel(getUnitDie(), dwarf::DW_AT_str_offsets_base,
                    DU->getStringOffsetsStartSym(),
                    TLOF.getDwarfStrOffSection()->getBeginSymbol());
  }
  
  void DwarfUnit::addRnglistsBase() {
    assert(DD->getDwarfVersion() >= 5 &&
           "DW_AT_rnglists_base requires DWARF version 5 or later");
    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
    addSectionLabel(getUnitDie(), dwarf::DW_AT_rnglists_base,
                    DU->getRnglistsTableBaseSym(),
                    TLOF.getDwarfRnglistsSection()->getBeginSymbol());
  }
  
  void DwarfTypeUnit::finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) {
    addFlag(D, dwarf::DW_AT_declaration);
    StringRef Name = CTy->getName();
    if (!Name.empty())
      addString(D, dwarf::DW_AT_name, Name);
    getCU().createTypeDIE(CTy);
  }
  