diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1133 | 
1 files changed, 470 insertions, 663 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index a587b46c4ba8d..105ff6c198f88 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -14,6 +14,7 @@  #include "DwarfDebug.h"  #include "ByteStreamer.h"  #include "DIEHash.h" +#include "DebugLocEntry.h"  #include "DwarfCompileUnit.h"  #include "DwarfExpression.h"  #include "DwarfUnit.h" @@ -45,6 +46,7 @@  #include "llvm/Support/MD5.h"  #include "llvm/Support/Path.h"  #include "llvm/Support/Timer.h" +#include "llvm/Support/raw_ostream.h"  #include "llvm/Target/TargetFrameLowering.h"  #include "llvm/Target/TargetLoweringObjectFile.h"  #include "llvm/Target/TargetMachine.h" @@ -105,24 +107,45 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,  static const char *const DWARFGroupName = "DWARF Emission";  static const char *const DbgTimerName = "DWARF Debug Writer"; +void DebugLocDwarfExpression::EmitOp(uint8_t Op, const char *Comment) { +  BS.EmitInt8( +      Op, Comment ? Twine(Comment) + " " + dwarf::OperationEncodingString(Op) +                  : dwarf::OperationEncodingString(Op)); +} + +void DebugLocDwarfExpression::EmitSigned(int64_t Value) { +  BS.EmitSLEB128(Value, Twine(Value)); +} + +void DebugLocDwarfExpression::EmitUnsigned(uint64_t Value) { +  BS.EmitULEB128(Value, Twine(Value)); +} + +bool DebugLocDwarfExpression::isFrameRegister(unsigned MachineReg) { +  // This information is not available while emitting .debug_loc entries. +  return false; +} +  //===----------------------------------------------------------------------===//  /// resolve - Look in the DwarfDebug map for the MDNode that  /// corresponds to the reference. -template <typename T> T DbgVariable::resolve(DIRef<T> Ref) const { +template <typename T> T *DbgVariable::resolve(TypedDINodeRef<T> Ref) const {    return DD->resolve(Ref);  }  bool DbgVariable::isBlockByrefVariable() const { -  assert(Var.isVariable() && "Invalid complex DbgVariable!"); -  return Var.isBlockByrefVariable(DD->getTypeIdentifierMap()); +  assert(Var && "Invalid complex DbgVariable!"); +  return Var->getType() +      .resolve(DD->getTypeIdentifierMap()) +      ->isBlockByrefStruct();  } -DIType DbgVariable::getType() const { -  DIType Ty = Var.getType().resolve(DD->getTypeIdentifierMap()); +const DIType *DbgVariable::getType() const { +  DIType *Ty = Var->getType().resolve(DD->getTypeIdentifierMap());    // FIXME: isBlockByrefVariable should be reformulated in terms of complex    // addresses instead. -  if (Var.isBlockByrefVariable(DD->getTypeIdentifierMap())) { +  if (Ty->isBlockByrefStruct()) {      /* Byref variables, in Blocks, are declared by the programmer as         "SomeType VarName;", but the compiler creates a         __Block_byref_x_VarName struct, and gives the variable VarName @@ -147,17 +170,17 @@ DIType DbgVariable::getType() const {         have a DW_AT_location that tells the debugger how to unwind through         the pointers and __Block_byref_x_VarName struct to find the actual         value of the variable.  The function addBlockByrefType does this.  */ -    DIType subType = Ty; -    uint16_t tag = Ty.getTag(); +    DIType *subType = Ty; +    uint16_t tag = Ty->getTag();      if (tag == dwarf::DW_TAG_pointer_type) -      subType = resolve(DIDerivedType(Ty).getTypeDerivedFrom()); +      subType = resolve(cast<DIDerivedType>(Ty)->getBaseType()); -    DIArray Elements = DICompositeType(subType).getElements(); -    for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { -      DIDerivedType DT(Elements.getElement(i)); -      if (getName() == DT.getName()) -        return (resolve(DT.getTypeDerivedFrom())); +    auto Elements = cast<DICompositeTypeBase>(subType)->getElements(); +    for (unsigned i = 0, N = Elements.size(); i < N; ++i) { +      auto *DT = cast<DIDerivedTypeBase>(Elements[i]); +      if (getName() == DT->getName()) +        return resolve(DT->getBaseType());      }    }    return Ty; @@ -169,11 +192,12 @@ static LLVM_CONSTEXPR DwarfAccelTable::Atom TypeAtoms[] = {      DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)};  DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) -    : Asm(A), MMI(Asm->MMI), PrevLabel(nullptr), GlobalRangeCount(0), -      InfoHolder(A, *this, "info_string", DIEValueAllocator), +    : Asm(A), MMI(Asm->MMI), DebugLocs(A->OutStreamer->isVerboseAsm()), +      PrevLabel(nullptr), InfoHolder(A, "info_string", DIEValueAllocator),        UsedNonDefaultText(false), -      SkeletonHolder(A, *this, "skel_string", DIEValueAllocator), +      SkeletonHolder(A, "skel_string", DIEValueAllocator),        IsDarwin(Triple(A->getTargetTriple()).isOSDarwin()), +      IsPS4(Triple(A->getTargetTriple()).isPS4()),        AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,                                         dwarf::DW_FORM_data4)),        AccelObjC(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, @@ -182,17 +206,11 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)                                             dwarf::DW_FORM_data4)),        AccelTypes(TypeAtoms) { -  DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = nullptr; -  DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = nullptr; -  DwarfLineSectionSym = nullptr; -  DwarfAddrSectionSym = nullptr; -  DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = nullptr; -  FunctionBeginSym = FunctionEndSym = nullptr;    CurFn = nullptr;    CurMI = nullptr;    // Turn on accelerator tables for Darwin by default, pubnames by -  // default for non-Darwin, and handle split dwarf. +  // default for non-Darwin/PS4, and handle split dwarf.    if (DwarfAccelTables == Default)      HasDwarfAccelTables = IsDarwin;    else @@ -204,7 +222,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)      HasSplitDwarf = SplitDwarf == Enable;    if (DwarfPubSections == Default) -    HasDwarfPubSections = !IsDarwin; +    HasDwarfPubSections = !IsDarwin && !IsPS4;    else      HasDwarfPubSections = DwarfPubSections == Enable; @@ -212,7 +230,11 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)    DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber                                      : MMI->getModule()->getDwarfVersion(); -  Asm->OutStreamer.getContext().setDwarfVersion(DwarfVersion); +  // Darwin and PS4 use the standard TLS opcode (defined in DWARF 3). +  // Everybody else uses GNU's. +  UseGNUTLSOpcode = !(IsDarwin || IsPS4) || DwarfVersion < 3; + +  Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);    {      NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); @@ -223,19 +245,6 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)  // Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h.  DwarfDebug::~DwarfDebug() { } -// Switch to the specified MCSection and emit an assembler -// temporary label to it if SymbolStem is specified. -static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section, -                                const char *SymbolStem = nullptr) { -  Asm->OutStreamer.SwitchSection(Section); -  if (!SymbolStem) -    return nullptr; - -  MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem); -  Asm->OutStreamer.EmitLabel(TmpSym); -  return TmpSym; -} -  static bool isObjCClass(StringRef Name) {    return Name.startswith("+") || Name.startswith("-");  } @@ -264,37 +273,30 @@ static StringRef getObjCMethodName(StringRef In) {    return In.slice(In.find(' ') + 1, In.find(']'));  } -// Helper for sorting sections into a stable output order. -static bool SectionSort(const MCSection *A, const MCSection *B) { -  std::string LA = (A ? A->getLabelBeginName() : ""); -  std::string LB = (B ? B->getLabelBeginName() : ""); -  return LA < LB; -} -  // Add the various names to the Dwarf accelerator table names.  // TODO: Determine whether or not we should add names for programs  // that do not have a DW_AT_name or DW_AT_linkage_name field - this  // is only slightly different than the lookup of non-standard ObjC names. -void DwarfDebug::addSubprogramNames(DISubprogram SP, DIE &Die) { -  if (!SP.isDefinition()) +void DwarfDebug::addSubprogramNames(const DISubprogram *SP, DIE &Die) { +  if (!SP->isDefinition())      return; -  addAccelName(SP.getName(), Die); +  addAccelName(SP->getName(), Die);    // If the linkage name is different than the name, go ahead and output    // that as well into the name table. -  if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName()) -    addAccelName(SP.getLinkageName(), Die); +  if (SP->getLinkageName() != "" && SP->getName() != SP->getLinkageName()) +    addAccelName(SP->getLinkageName(), Die);    // If this is an Objective-C selector name add it to the ObjC accelerator    // too. -  if (isObjCClass(SP.getName())) { +  if (isObjCClass(SP->getName())) {      StringRef Class, Category; -    getObjCClassCategory(SP.getName(), Class, Category); +    getObjCClassCategory(SP->getName(), Class, Category);      addAccelObjC(Class, Die);      if (Category != "")        addAccelObjC(Category, Die);      // Also add the base method name to the name table. -    addAccelName(getObjCMethodName(SP.getName()), Die); +    addAccelName(getObjCMethodName(SP->getName()), Die);    }  } @@ -303,11 +305,10 @@ void DwarfDebug::addSubprogramNames(DISubprogram SP, DIE &Die) {  bool DwarfDebug::isSubprogramContext(const MDNode *Context) {    if (!Context)      return false; -  DIDescriptor D(Context); -  if (D.isSubprogram()) +  if (isa<DISubprogram>(Context))      return true; -  if (D.isType()) -    return isSubprogramContext(resolve(DIType(Context).getContext())); +  if (auto *T = dyn_cast<DIType>(Context)) +    return isSubprogramContext(resolve(T->getScope()));    return false;  } @@ -362,9 +363,10 @@ void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {  // Create new DwarfCompileUnit for the given metadata node with tag  // DW_TAG_compile_unit. -DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) { -  StringRef FN = DIUnit.getFilename(); -  CompilationDir = DIUnit.getDirectory(); +DwarfCompileUnit & +DwarfDebug::constructDwarfCompileUnit(const DICompileUnit *DIUnit) { +  StringRef FN = DIUnit->getFilename(); +  CompilationDir = DIUnit->getDirectory();    auto OwnedUnit = make_unique<DwarfCompileUnit>(        InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder); @@ -378,17 +380,17 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {    // To avoid the compilation directory being ambiguous, let the line table    // explicitly describe the directory of all files, never relying on the    // compilation directory. -  if (!Asm->OutStreamer.hasRawTextSupport() || SingleCU) -    Asm->OutStreamer.getContext().setMCLineTableCompilationDir( +  if (!Asm->OutStreamer->hasRawTextSupport() || SingleCU) +    Asm->OutStreamer->getContext().setMCLineTableCompilationDir(          NewCU.getUniqueID(), CompilationDir); -  NewCU.addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer()); +  NewCU.addString(Die, dwarf::DW_AT_producer, DIUnit->getProducer());    NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2, -                DIUnit.getLanguage()); +                DIUnit->getSourceLanguage());    NewCU.addString(Die, dwarf::DW_AT_name, FN);    if (!useSplitDwarf()) { -    NewCU.initStmtList(DwarfLineSectionSym); +    NewCU.initStmtList();      // If we're using split dwarf the compilation dir is going to be in the      // skeleton CU and so we don't need to duplicate it here. @@ -398,23 +400,21 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {      addGnuPubAttributes(NewCU, Die);    } -  if (DIUnit.isOptimized()) +  if (DIUnit->isOptimized())      NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized); -  StringRef Flags = DIUnit.getFlags(); +  StringRef Flags = DIUnit->getFlags();    if (!Flags.empty())      NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags); -  if (unsigned RVer = DIUnit.getRunTimeVersion()) +  if (unsigned RVer = DIUnit->getRuntimeVersion())      NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,                    dwarf::DW_FORM_data1, RVer);    if (useSplitDwarf()) -    NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection(), -                      DwarfInfoDWOSectionSym); +    NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());    else -    NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection(), -                      DwarfInfoSectionSym); +    NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection());    CUMap.insert(std::make_pair(DIUnit, &NewCU));    CUDieMap.insert(std::make_pair(&Die, &NewCU)); @@ -422,11 +422,9 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {  }  void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, -                                                  const MDNode *N) { -  DIImportedEntity Module(N); -  assert(Module.Verify()); -  if (DIE *D = TheCU.getOrCreateContextDIE(Module.getContext())) -    D->addChild(TheCU.constructImportedEntityDIE(Module)); +                                                  const DIImportedEntity *N) { +  if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope())) +    D->addChild(TheCU.constructImportedEntityDIE(N));  }  // Emit all Dwarf sections that should come prior to the content. Create @@ -445,54 +443,40 @@ void DwarfDebug::beginModule() {      return;    TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); -  // Emit initial sections so we can reference labels later. -  emitSectionLabels(); -    SingleCU = CU_Nodes->getNumOperands() == 1;    for (MDNode *N : CU_Nodes->operands()) { -    DICompileUnit CUNode(N); +    auto *CUNode = cast<DICompileUnit>(N);      DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode); -    DIArray ImportedEntities = CUNode.getImportedEntities(); -    for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i) -      ScopesWithImportedEntities.push_back(std::make_pair( -          DIImportedEntity(ImportedEntities.getElement(i)).getContext(), -          ImportedEntities.getElement(i))); -    std::sort(ScopesWithImportedEntities.begin(), -              ScopesWithImportedEntities.end(), less_first()); -    DIArray GVs = CUNode.getGlobalVariables(); -    for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) -      CU.getOrCreateGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i))); -    DIArray SPs = CUNode.getSubprograms(); -    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) -      SPMap.insert(std::make_pair(SPs.getElement(i), &CU)); -    DIArray EnumTypes = CUNode.getEnumTypes(); -    for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) { -      DIType Ty(EnumTypes.getElement(i)); +    for (auto *IE : CUNode->getImportedEntities()) +      ScopesWithImportedEntities.push_back(std::make_pair(IE->getScope(), IE)); +    // Stable sort to preserve the order of appearance of imported entities. +    // This is to avoid out-of-order processing of interdependent declarations +    // within the same scope, e.g. { namespace A = base; namespace B = A; } +    std::stable_sort(ScopesWithImportedEntities.begin(), +                     ScopesWithImportedEntities.end(), less_first()); +    for (auto *GV : CUNode->getGlobalVariables()) +      CU.getOrCreateGlobalVariableDIE(GV); +    for (auto *SP : CUNode->getSubprograms()) +      SPMap.insert(std::make_pair(SP, &CU)); +    for (auto *Ty : CUNode->getEnumTypes()) {        // The enum types array by design contains pointers to        // MDNodes rather than DIRefs. Unique them here. -      DIType UniqueTy(resolve(Ty.getRef())); -      CU.getOrCreateTypeDIE(UniqueTy); +      CU.getOrCreateTypeDIE(cast<DIType>(resolve(Ty->getRef())));      } -    DIArray RetainedTypes = CUNode.getRetainedTypes(); -    for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) { -      DIType Ty(RetainedTypes.getElement(i)); +    for (auto *Ty : CUNode->getRetainedTypes()) {        // The retained types array by design contains pointers to        // MDNodes rather than DIRefs. Unique them here. -      DIType UniqueTy(resolve(Ty.getRef())); -      CU.getOrCreateTypeDIE(UniqueTy); +      CU.getOrCreateTypeDIE(cast<DIType>(resolve(Ty->getRef())));      }      // Emit imported_modules last so that the relevant context is already      // available. -    for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i) -      constructAndAddImportedEntityDIE(CU, ImportedEntities.getElement(i)); +    for (auto *IE : CUNode->getImportedEntities()) +      constructAndAddImportedEntityDIE(CU, IE);    }    // Tell MMI that we have debug info.    MMI->setDebugInfoAvailability(true); - -  // Prime section data. -  SectionMap[Asm->getObjFileLowering().getTextSection()];  }  void DwarfDebug::finishVariableDefinitions() { @@ -504,7 +488,8 @@ void DwarfDebug::finishVariableDefinitions() {      // DIE::getUnit isn't simple - it walks parent pointers, etc.      DwarfCompileUnit *Unit = lookupUnit(VariableDie->getUnit());      assert(Unit); -    DbgVariable *AbsVar = getExistingAbstractVariable(Var->getVariable()); +    DbgVariable *AbsVar = getExistingAbstractVariable( +        InlinedVariable(Var->getVariable(), Var->getInlinedAt()));      if (AbsVar && AbsVar->getDIE()) {        Unit->addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,                          *AbsVar->getDIE()); @@ -516,7 +501,7 @@ void DwarfDebug::finishVariableDefinitions() {  void DwarfDebug::finishSubprogramDefinitions() {    for (const auto &P : SPMap)      forBothCUs(*P.second, [&](DwarfCompileUnit &CU) { -      CU.finishSubprogramDefinition(DISubprogram(P.first)); +      CU.finishSubprogramDefinition(cast<DISubprogram>(P.first));      });  } @@ -527,14 +512,12 @@ void DwarfDebug::collectDeadVariables() {    if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {      for (MDNode *N : CU_Nodes->operands()) { -      DICompileUnit TheCU(N); +      auto *TheCU = cast<DICompileUnit>(N);        // Construct subprogram DIE and add variables DIEs.        DwarfCompileUnit *SPCU =            static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));        assert(SPCU && "Unable to find Compile Unit!"); -      DIArray Subprograms = TheCU.getSubprograms(); -      for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { -        DISubprogram SP(Subprograms.getElement(i)); +      for (auto *SP : TheCU->getSubprograms()) {          if (ProcessedSPNodes.count(SP) != 0)            continue;          SPCU->collectDeadVariables(SP); @@ -544,6 +527,8 @@ void DwarfDebug::collectDeadVariables() {  }  void DwarfDebug::finalizeModuleInfo() { +  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); +    finishSubprogramDefinitions();    finishVariableDefinitions(); @@ -573,13 +558,16 @@ void DwarfDebug::finalizeModuleInfo() {        // We don't keep track of which addresses are used in which CU so this        // is a bit pessimistic under LTO. -      if (!AddrPool.isEmpty()) +      if (!AddrPool.isEmpty()) { +        const MCSymbol *Sym = TLOF.getDwarfAddrSection()->getBeginSymbol();          SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_addr_base, -                              DwarfAddrSectionSym, DwarfAddrSectionSym); -      if (!SkCU->getRangeLists().empty()) +                              Sym, Sym); +      } +      if (!SkCU->getRangeLists().empty()) { +        const MCSymbol *Sym = TLOF.getDwarfRangesSection()->getBeginSymbol();          SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base, -                              DwarfDebugRangeSectionSym, -                              DwarfDebugRangeSectionSym); +                              Sym, Sym); +      }      }      // If we have code split among multiple sections or non-contiguous @@ -597,7 +585,7 @@ void DwarfDebug::finalizeModuleInfo() {          // 2.17.3).          U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);        else -        TheCU.setBaseAddress(TheCU.getRanges().front().getStart()); +        U.setBaseAddress(TheCU.getRanges().front().getStart());        U.attachRangesOrLowHighPC(U.getUnitDie(), TheCU.takeRanges());      }    } @@ -608,53 +596,6 @@ void DwarfDebug::finalizeModuleInfo() {      SkeletonHolder.computeSizeAndOffsets();  } -void DwarfDebug::endSections() { -  // Filter labels by section. -  for (const SymbolCU &SCU : ArangeLabels) { -    if (SCU.Sym->isInSection()) { -      // Make a note of this symbol and it's section. -      const MCSection *Section = &SCU.Sym->getSection(); -      if (!Section->getKind().isMetadata()) -        SectionMap[Section].push_back(SCU); -    } else { -      // Some symbols (e.g. common/bss on mach-o) can have no section but still -      // appear in the output. This sucks as we rely on sections to build -      // arange spans. We can do it without, but it's icky. -      SectionMap[nullptr].push_back(SCU); -    } -  } - -  // Build a list of sections used. -  std::vector<const MCSection *> Sections; -  for (const auto &it : SectionMap) { -    const MCSection *Section = it.first; -    Sections.push_back(Section); -  } - -  // Sort the sections into order. -  // This is only done to ensure consistent output order across different runs. -  std::sort(Sections.begin(), Sections.end(), SectionSort); - -  // Add terminating symbols for each section. -  for (unsigned ID = 0, E = Sections.size(); ID != E; ID++) { -    const MCSection *Section = Sections[ID]; -    MCSymbol *Sym = nullptr; - -    if (Section) { -      // We can't call MCSection::getLabelEndName, as it's only safe to do so -      // if we know the section name up-front. For user-created sections, the -      // resulting label may not be valid to use as a label. (section names can -      // use a greater set of characters on some systems) -      Sym = Asm->GetTempSymbol("debug_end", ID); -      Asm->OutStreamer.SwitchSection(Section); -      Asm->OutStreamer.EmitLabel(Sym); -    } - -    // Insert a final terminator. -    SectionMap[Section].push_back(SymbolCU(nullptr, Sym)); -  } -} -  // Emit all Dwarf sections that should come after the content.  void DwarfDebug::endModule() {    assert(CurFn == nullptr); @@ -663,24 +604,26 @@ void DwarfDebug::endModule() {    // If we aren't actually generating debug info (check beginModule -    // conditionalized on !DisableDebugInfoPrinting and the presence of the    // llvm.dbg.cu metadata node) -  if (!DwarfInfoSectionSym) +  if (!MMI->hasDebugInfo())      return; -  // End any existing sections. -  // TODO: Does this need to happen? -  endSections(); -    // Finalize the debug info for the module.    finalizeModuleInfo();    emitDebugStr(); -  // Emit all the DIEs into a debug info section. -  emitDebugInfo(); +  if (useSplitDwarf()) +    emitDebugLocDWO(); +  else +    // Emit info into a debug loc section. +    emitDebugLoc();    // Corresponding abbreviations into a abbrev section.    emitAbbreviations(); +  // Emit all the DIEs into a debug info section. +  emitDebugInfo(); +    // Emit info into a debug aranges section.    if (GenerateARangeSection)      emitDebugARanges(); @@ -693,12 +636,9 @@ void DwarfDebug::endModule() {      emitDebugInfoDWO();      emitDebugAbbrevDWO();      emitDebugLineDWO(); -    emitDebugLocDWO();      // Emit DWO addresses.      AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection()); -  } else -    // Emit info into a debug loc section. -    emitDebugLoc(); +  }    // Emit info into the dwarf accelerator table sections.    if (useDwarfAccelTables()) { @@ -720,80 +660,80 @@ void DwarfDebug::endModule() {  }  // Find abstract variable, if any, associated with Var. -DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV, -                                                     DIVariable &Cleansed) { -  LLVMContext &Ctx = DV->getContext(); +DbgVariable * +DwarfDebug::getExistingAbstractVariable(InlinedVariable IV, +                                        const DILocalVariable *&Cleansed) {    // More then one inlined variable corresponds to one abstract variable. -  // FIXME: This duplication of variables when inlining should probably be -  // removed. It's done to allow each DIVariable to describe its location -  // because the DebugLoc on the dbg.value/declare isn't accurate. We should -  // make it accurate then remove this duplication/cleansing stuff. -  Cleansed = cleanseInlinedVariable(DV, Ctx); +  Cleansed = IV.first;    auto I = AbstractVariables.find(Cleansed);    if (I != AbstractVariables.end())      return I->second.get();    return nullptr;  } -DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) { -  DIVariable Cleansed; -  return getExistingAbstractVariable(DV, Cleansed); +DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV) { +  const DILocalVariable *Cleansed; +  return getExistingAbstractVariable(IV, Cleansed);  } -void DwarfDebug::createAbstractVariable(const DIVariable &Var, +void DwarfDebug::createAbstractVariable(const DILocalVariable *Var,                                          LexicalScope *Scope) { -  auto AbsDbgVariable = make_unique<DbgVariable>(Var, DIExpression(), this); +  auto AbsDbgVariable = +      make_unique<DbgVariable>(Var, /* IA */ nullptr, /* Expr */ nullptr, this);    InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get());    AbstractVariables[Var] = std::move(AbsDbgVariable);  } -void DwarfDebug::ensureAbstractVariableIsCreated(const DIVariable &DV, +void DwarfDebug::ensureAbstractVariableIsCreated(InlinedVariable IV,                                                   const MDNode *ScopeNode) { -  DIVariable Cleansed = DV; -  if (getExistingAbstractVariable(DV, Cleansed)) +  const DILocalVariable *Cleansed = nullptr; +  if (getExistingAbstractVariable(IV, Cleansed))      return; -  createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(ScopeNode)); +  createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope( +                                       cast<DILocalScope>(ScopeNode)));  } -void -DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(const DIVariable &DV, -                                                    const MDNode *ScopeNode) { -  DIVariable Cleansed = DV; -  if (getExistingAbstractVariable(DV, Cleansed)) +void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped( +    InlinedVariable IV, const MDNode *ScopeNode) { +  const DILocalVariable *Cleansed = nullptr; +  if (getExistingAbstractVariable(IV, Cleansed))      return; -  if (LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode)) +  if (LexicalScope *Scope = +          LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))      createAbstractVariable(Cleansed, Scope);  }  // Collect variable information from side table maintained by MMI.  void DwarfDebug::collectVariableInfoFromMMITable( -    SmallPtrSetImpl<const MDNode *> &Processed) { +    DenseSet<InlinedVariable> &Processed) {    for (const auto &VI : MMI->getVariableDbgInfo()) {      if (!VI.Var)        continue; -    Processed.insert(VI.Var); +    assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) && +           "Expected inlined-at fields to agree"); + +    InlinedVariable Var(VI.Var, VI.Loc->getInlinedAt()); +    Processed.insert(Var);      LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);      // If variable scope is not found then skip this variable.      if (!Scope)        continue; -    DIVariable DV(VI.Var); -    DIExpression Expr(VI.Expr); -    ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); -    ConcreteVariables.push_back(make_unique<DbgVariable>(DV, Expr, this)); -    DbgVariable *RegVar = ConcreteVariables.back().get(); -    RegVar->setFrameIndex(VI.Slot); -    InfoHolder.addScopeVariable(Scope, RegVar); +    const DIExpression *Expr = cast_or_null<DIExpression>(VI.Expr); +    ensureAbstractVariableIsCreatedIfScoped(Var, Scope->getScopeNode()); +    auto RegVar = +        make_unique<DbgVariable>(Var.first, Var.second, Expr, this, VI.Slot); +    if (InfoHolder.addScopeVariable(Scope, RegVar.get())) +      ConcreteVariables.push_back(std::move(RegVar));    }  }  // Get .debug_loc entry for the instruction range starting at MI.  static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) { -  const MDNode *Expr = MI->getDebugExpression(); -  const MDNode *Var = MI->getDebugVariable(); +  const DIExpression *Expr = MI->getDebugExpression();    assert(MI->getNumOperands() == 4);    if (MI->getOperand(0).isReg()) { @@ -804,26 +744,26 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {        MLoc.set(MI->getOperand(0).getReg());      else        MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); -    return DebugLocEntry::Value(Var, Expr, MLoc); +    return DebugLocEntry::Value(Expr, MLoc);    }    if (MI->getOperand(0).isImm()) -    return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getImm()); +    return DebugLocEntry::Value(Expr, MI->getOperand(0).getImm());    if (MI->getOperand(0).isFPImm()) -    return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getFPImm()); +    return DebugLocEntry::Value(Expr, MI->getOperand(0).getFPImm());    if (MI->getOperand(0).isCImm()) -    return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getCImm()); +    return DebugLocEntry::Value(Expr, MI->getOperand(0).getCImm());    llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");  }  /// Determine whether two variable pieces overlap. -static bool piecesOverlap(DIExpression P1, DIExpression P2) { -  if (!P1.isVariablePiece() || !P2.isVariablePiece()) +static bool piecesOverlap(const DIExpression *P1, const DIExpression *P2) { +  if (!P1->isBitPiece() || !P2->isBitPiece())      return true; -  unsigned l1 = P1.getPieceOffset(); -  unsigned l2 = P2.getPieceOffset(); -  unsigned r1 = l1 + P1.getPieceSize(); -  unsigned r2 = l2 + P2.getPieceSize(); +  unsigned l1 = P1->getBitPieceOffset(); +  unsigned l2 = P2->getBitPieceOffset(); +  unsigned r1 = l1 + P1->getBitPieceSize(); +  unsigned r2 = l2 + P2->getBitPieceSize();    // True where [l1,r1[ and [r1,r2[ overlap.    return (l1 < r2) && (l2 < r1);  } @@ -842,7 +782,8 @@ static bool piecesOverlap(DIExpression P1, DIExpression P2) {  // 1 | |    [x, (reg1, piece 32, 32)] <- IsPieceOfPrevEntry  // 2 | |    ...  // 3   |    [clobber reg0] -// 4        [x, (mem, piece 0, 64)] <- overlapping with both previous pieces of x. +// 4        [x, (mem, piece 0, 64)] <- overlapping with both previous pieces of +//                                     x.  //  // Output:  // @@ -868,7 +809,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      }      // If this piece overlaps with any open ranges, truncate them. -    DIExpression DIExpr = Begin->getDebugExpression(); +    const DIExpression *DIExpr = Begin->getDebugExpression();      auto Last = std::remove_if(OpenRanges.begin(), OpenRanges.end(),                                 [&](DebugLocEntry::Value R) {        return piecesOverlap(DIExpr, R.getExpression()); @@ -882,7 +823,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      if (End != nullptr)        EndLabel = getLabelAfterInsn(End);      else if (std::next(I) == Ranges.end()) -      EndLabel = FunctionEndSym; +      EndLabel = Asm->getFunctionEnd();      else        EndLabel = getLabelBeforeInsn(std::next(I)->first);      assert(EndLabel && "Forgot label after instruction ending a range!"); @@ -894,7 +835,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      bool couldMerge = false;      // If this is a piece, it may belong to the current DebugLocEntry. -    if (DIExpr.isVariablePiece()) { +    if (DIExpr->isBitPiece()) {        // Add this value to the list of open ranges.        OpenRanges.push_back(Value); @@ -916,54 +857,50 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      // Attempt to coalesce the ranges of two otherwise identical      // DebugLocEntries.      auto CurEntry = DebugLoc.rbegin(); -    auto PrevEntry = std::next(CurEntry); -    if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry)) -      DebugLoc.pop_back(); -      DEBUG({        dbgs() << CurEntry->getValues().size() << " Values:\n"; -      for (auto Value : CurEntry->getValues()) { -        Value.getVariable()->dump(); +      for (auto &Value : CurEntry->getValues())          Value.getExpression()->dump(); -      }        dbgs() << "-----\n";      }); + +    auto PrevEntry = std::next(CurEntry); +    if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry)) +      DebugLoc.pop_back();    }  }  // Find variables for each lexical scope. -void -DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP, -                                SmallPtrSetImpl<const MDNode *> &Processed) { +void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, +                                     const DISubprogram *SP, +                                     DenseSet<InlinedVariable> &Processed) {    // Grab the variable info that was squirreled away in the MMI side-table.    collectVariableInfoFromMMITable(Processed);    for (const auto &I : DbgValues) { -    DIVariable DV(I.first); -    if (Processed.count(DV)) +    InlinedVariable IV = I.first; +    if (Processed.count(IV))        continue; -    // Instruction ranges, specifying where DV is accessible. +    // Instruction ranges, specifying where IV is accessible.      const auto &Ranges = I.second;      if (Ranges.empty())        continue;      LexicalScope *Scope = nullptr; -    if (MDNode *IA = DV.getInlinedAt()) { -      DebugLoc DL = DebugLoc::getFromDILocation(IA); -      Scope = LScopes.findInlinedScope(DebugLoc::get( -          DL.getLine(), DL.getCol(), DV.getContext(), IA)); -    } else -      Scope = LScopes.findLexicalScope(DV.getContext()); +    if (const DILocation *IA = IV.second) +      Scope = LScopes.findInlinedScope(IV.first->getScope(), IA); +    else +      Scope = LScopes.findLexicalScope(IV.first->getScope());      // If variable scope is not found then skip this variable.      if (!Scope)        continue; -    Processed.insert(DV); +    Processed.insert(IV);      const MachineInstr *MInsn = Ranges.front().first;      assert(MInsn->isDebugValue() && "History must begin with debug value"); -    ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); +    ensureAbstractVariableIsCreatedIfScoped(IV, Scope->getScopeNode());      ConcreteVariables.push_back(make_unique<DbgVariable>(MInsn, this));      DbgVariable *RegVar = ConcreteVariables.back().get();      InfoHolder.addScopeVariable(Scope, RegVar); @@ -973,29 +910,33 @@ DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,        continue;      // Handle multiple DBG_VALUE instructions describing one variable. -    RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); - -    DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1); -    DebugLocList &LocList = DotDebugLocEntries.back(); -    LocList.CU = &TheCU; -    LocList.Label = -        Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1); +    RegVar->setDebugLocListIndex( +        DebugLocs.startList(&TheCU, Asm->createTempSymbol("debug_loc")));      // Build the location list for this variable. -    buildLocationList(LocList.List, Ranges); +    SmallVector<DebugLocEntry, 8> Entries; +    buildLocationList(Entries, Ranges); + +    // If the variable has an DIBasicType, extract it.  Basic types cannot have +    // unique identifiers, so don't bother resolving the type with the +    // identifier map. +    const DIBasicType *BT = dyn_cast<DIBasicType>( +        static_cast<const Metadata *>(IV.first->getType())); + +    // Finalize the entry by lowering it into a DWARF bytestream. +    for (auto &Entry : Entries) +      Entry.finalize(*Asm, DebugLocs, BT);    }    // Collect info for variables that were optimized out. -  DIArray Variables = SP.getVariables(); -  for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) { -    DIVariable DV(Variables.getElement(i)); -    assert(DV.isVariable()); -    if (!Processed.insert(DV).second) +  for (const DILocalVariable *DV : SP->getVariables()) { +    if (!Processed.insert(InlinedVariable(DV, nullptr)).second)        continue; -    if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) { -      ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); -      DIExpression NoExpr; -      ConcreteVariables.push_back(make_unique<DbgVariable>(DV, NoExpr, this)); +    if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) { +      ensureAbstractVariableIsCreatedIfScoped(InlinedVariable(DV, nullptr), +                                              Scope->getScopeNode()); +      ConcreteVariables.push_back(make_unique<DbgVariable>( +          DV, /* IA */ nullptr, /* Expr */ nullptr, this));        InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get());      }    } @@ -1020,23 +961,25 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {    // Check if source location changes, but ignore DBG_VALUE locations.    if (!MI->isDebugValue()) {      DebugLoc DL = MI->getDebugLoc(); -    if (DL != PrevInstLoc && (!DL.isUnknown() || UnknownLocations)) { -      unsigned Flags = 0; -      PrevInstLoc = DL; -      if (DL == PrologEndLoc) { -        Flags |= DWARF2_FLAG_PROLOGUE_END; -        PrologEndLoc = DebugLoc(); -        Flags |= DWARF2_FLAG_IS_STMT; -      } -      if (DL.getLine() != -          Asm->OutStreamer.getContext().getCurrentDwarfLoc().getLine()) -        Flags |= DWARF2_FLAG_IS_STMT; +    if (DL != PrevInstLoc) { +      if (DL) { +        unsigned Flags = 0; +        PrevInstLoc = DL; +        if (DL == PrologEndLoc) { +          Flags |= DWARF2_FLAG_PROLOGUE_END; +          PrologEndLoc = DebugLoc(); +          Flags |= DWARF2_FLAG_IS_STMT; +        } +        if (DL.getLine() != +            Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine()) +          Flags |= DWARF2_FLAG_IS_STMT; -      if (!DL.isUnknown()) { -        const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext()); +        const MDNode *Scope = DL.getScope();          recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags); -      } else +      } else if (UnknownLocations) { +        PrevInstLoc = DL;          recordSourceLine(0, 0, nullptr, 0); +      }      }    } @@ -1053,8 +996,8 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {      return;    if (!PrevLabel) { -    PrevLabel = MMI->getContext().CreateTempSymbol(); -    Asm->OutStreamer.EmitLabel(PrevLabel); +    PrevLabel = MMI->getContext().createTempSymbol(); +    Asm->OutStreamer->EmitLabel(PrevLabel);    }    I->second = PrevLabel;  } @@ -1081,8 +1024,8 @@ void DwarfDebug::endInstruction() {    // We need a label after this instruction.    if (!PrevLabel) { -    PrevLabel = MMI->getContext().CreateTempSymbol(); -    Asm->OutStreamer.EmitLabel(PrevLabel); +    PrevLabel = MMI->getContext().createTempSymbol(); +    Asm->OutStreamer->EmitLabel(PrevLabel);    }    I->second = PrevLabel;  } @@ -1119,7 +1062,7 @@ static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {    for (const auto &MBB : *MF)      for (const auto &MI : MBB)        if (!MI.isDebugValue() && !MI.getFlag(MachineInstr::FrameSetup) && -        !MI.getDebugLoc().isUnknown()) { +          MI.getDebugLoc()) {          // Did the target forget to set the FrameSetup flag for CFI insns?          assert(!MI.isCFIInstruction() &&                 "First non-frame-setup instruction is a CFI instruction."); @@ -1166,19 +1109,14 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {    // is absolute (such as an <> lookup header)))    DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());    assert(TheCU && "Unable to find compile unit!"); -  if (Asm->OutStreamer.hasRawTextSupport()) +  if (Asm->OutStreamer->hasRawTextSupport())      // Use a single line table if we are generating assembly. -    Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); +    Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);    else -    Asm->OutStreamer.getContext().setDwarfCompileUnitID(TheCU->getUniqueID()); - -  // Emit a label for the function so that we have a beginning address. -  FunctionBeginSym = Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); -  // Assumes in correct section after the entry point. -  Asm->OutStreamer.EmitLabel(FunctionBeginSym); +    Asm->OutStreamer->getContext().setDwarfCompileUnitID(TheCU->getUniqueID());    // Calculate history for local variables. -  calculateDbgValueHistory(MF, Asm->TM.getSubtargetImpl()->getRegisterInfo(), +  calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),                             DbgValues);    // Request labels for the full history. @@ -1187,21 +1125,21 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {      if (Ranges.empty())        continue; -    // The first mention of a function argument gets the FunctionBeginSym +    // The first mention of a function argument gets the CurrentFnBegin      // label, so arguments are visible when breaking at function entry. -    DIVariable DIVar(Ranges.front().first->getDebugVariable()); -    if (DIVar.isVariable() && DIVar.getTag() == dwarf::DW_TAG_arg_variable && -        getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) { -      LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym; -      if (Ranges.front().first->getDebugExpression().isVariablePiece()) { +    const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable(); +    if (DIVar->getTag() == dwarf::DW_TAG_arg_variable && +        getDISubprogram(DIVar->getScope())->describes(MF->getFunction())) { +      LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin(); +      if (Ranges.front().first->getDebugExpression()->isBitPiece()) {          // Mark all non-overlapping initial pieces.          for (auto I = Ranges.begin(); I != Ranges.end(); ++I) { -          DIExpression Piece = I->first->getDebugExpression(); +          const DIExpression *Piece = I->first->getDebugExpression();            if (std::all_of(Ranges.begin(), I,                            [&](DbgValueHistoryMap::InstrRange Pred) {                  return !piecesOverlap(Piece, Pred.first->getDebugExpression());                })) -            LabelsBeforeInsn[I->first] = FunctionBeginSym; +            LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();            else              break;          } @@ -1216,19 +1154,15 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {    }    PrevInstLoc = DebugLoc(); -  PrevLabel = FunctionBeginSym; +  PrevLabel = Asm->getFunctionBegin();    // Record beginning of function.    PrologEndLoc = findPrologueEndLoc(MF); -  if (!PrologEndLoc.isUnknown()) { -    DebugLoc FnStartDL = -        PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext()); -    recordSourceLine( -        FnStartDL.getLine(), FnStartDL.getCol(), -        FnStartDL.getScope(MF->getFunction()->getContext()), -        // We'd like to list the prologue as "not statements" but GDB behaves -        // poorly if we do that. Revisit this with caution/GDB (7.5+) testing. -        DWARF2_FLAG_IS_STMT); +  if (DILocation *L = PrologEndLoc) { +    // We'd like to list the prologue as "not statements" but GDB behaves +    // poorly if we do that. Revisit this with caution/GDB (7.5+) testing. +    auto *SP = L->getInlinedAtScope()->getSubprogram(); +    recordSourceLine(SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT);    }  } @@ -1247,27 +1181,22 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {      return;    } -  // Define end label for subprogram. -  FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); -  // Assumes in correct section after the entry point. -  Asm->OutStreamer.EmitLabel(FunctionEndSym); -    // Set DwarfDwarfCompileUnitID in MCContext to default value. -  Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); +  Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);    LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); -  DISubprogram SP(FnScope->getScopeNode()); +  auto *SP = cast<DISubprogram>(FnScope->getScopeNode());    DwarfCompileUnit &TheCU = *SPMap.lookup(SP); -  SmallPtrSet<const MDNode *, 16> ProcessedVars; +  DenseSet<InlinedVariable> ProcessedVars;    collectVariableInfo(TheCU, SP, ProcessedVars);    // Add the range of this function to the list of ranges for the CU. -  TheCU.addRange(RangeSpan(FunctionBeginSym, FunctionEndSym)); +  TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd()));    // Under -gmlt, skip building the subprogram if there are no inlined    // subroutines inside it. -  if (TheCU.getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly && +  if (TheCU.getCUNode()->getEmissionKind() == DIBuilder::LineTablesOnly &&        LScopes.getAbstractScopesList().empty() && !IsDarwin) {      assert(InfoHolder.getScopeVariables().empty());      assert(DbgValues.empty()); @@ -1286,16 +1215,13 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {  #endif    // Construct abstract scopes.    for (LexicalScope *AScope : LScopes.getAbstractScopesList()) { -    DISubprogram SP(AScope->getScopeNode()); -    assert(SP.isSubprogram()); +    auto *SP = cast<DISubprogram>(AScope->getScopeNode());      // Collect info for variables that were optimized out. -    DIArray Variables = SP.getVariables(); -    for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) { -      DIVariable DV(Variables.getElement(i)); -      assert(DV && DV.isVariable()); -      if (!ProcessedVars.insert(DV).second) +    for (const DILocalVariable *DV : SP->getVariables()) { +      if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)          continue; -      ensureAbstractVariableIsCreated(DV, DV.getContext()); +      ensureAbstractVariableIsCreated(InlinedVariable(DV, nullptr), +                                      DV->getScope());        assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes               && "ensureAbstractVariableIsCreated inserted abstract scopes");      } @@ -1327,122 +1253,28 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,    StringRef Dir;    unsigned Src = 1;    unsigned Discriminator = 0; -  if (DIScope Scope = DIScope(S)) { -    assert(Scope.isScope()); -    Fn = Scope.getFilename(); -    Dir = Scope.getDirectory(); -    if (Scope.isLexicalBlockFile()) -      Discriminator = DILexicalBlockFile(S).getDiscriminator(); - -    unsigned CUID = Asm->OutStreamer.getContext().getDwarfCompileUnitID(); +  if (auto *Scope = cast_or_null<DIScope>(S)) { +    Fn = Scope->getFilename(); +    Dir = Scope->getDirectory(); +    if (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope)) +      Discriminator = LBF->getDiscriminator(); + +    unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();      Src = static_cast<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])                .getOrCreateSourceID(Fn, Dir);    } -  Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, 0, -                                         Discriminator, Fn); +  Asm->OutStreamer->EmitDwarfLocDirective(Src, Line, Col, Flags, 0, +                                          Discriminator, Fn);  }  //===----------------------------------------------------------------------===//  // Emit Methods  //===----------------------------------------------------------------------===// -// Emit initial Dwarf sections with a label at the start of each one. -void DwarfDebug::emitSectionLabels() { -  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - -  // Dwarf sections base addresses. -  DwarfInfoSectionSym = -      emitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info"); -  if (useSplitDwarf()) { -    DwarfInfoDWOSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfInfoDWOSection(), "section_info_dwo"); -    DwarfTypesDWOSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfTypesDWOSection(), "section_types_dwo"); -  } -  DwarfAbbrevSectionSym = -      emitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev"); -  if (useSplitDwarf()) -    DwarfAbbrevDWOSectionSym = emitSectionSym( -        Asm, TLOF.getDwarfAbbrevDWOSection(), "section_abbrev_dwo"); -  if (GenerateARangeSection) -    emitSectionSym(Asm, TLOF.getDwarfARangesSection()); - -  DwarfLineSectionSym = -      emitSectionSym(Asm, TLOF.getDwarfLineSection(), "section_line"); -  if (GenerateGnuPubSections) { -    DwarfGnuPubNamesSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfGnuPubNamesSection()); -    DwarfGnuPubTypesSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfGnuPubTypesSection()); -  } else if (HasDwarfPubSections) { -    emitSectionSym(Asm, TLOF.getDwarfPubNamesSection()); -    emitSectionSym(Asm, TLOF.getDwarfPubTypesSection()); -  } - -  DwarfStrSectionSym = -      emitSectionSym(Asm, TLOF.getDwarfStrSection(), "info_string"); -  if (useSplitDwarf()) { -    DwarfStrDWOSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfStrDWOSection(), "skel_string"); -    DwarfAddrSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfAddrSection(), "addr_sec"); -    DwarfDebugLocSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfLocDWOSection(), "skel_loc"); -  } else -    DwarfDebugLocSectionSym = -        emitSectionSym(Asm, TLOF.getDwarfLocSection(), "section_debug_loc"); -  DwarfDebugRangeSectionSym = -      emitSectionSym(Asm, TLOF.getDwarfRangesSection(), "debug_range"); -} - -// Recursively emits a debug information entry. -void DwarfDebug::emitDIE(DIE &Die) { -  // Get the abbreviation for this DIE. -  const DIEAbbrev &Abbrev = Die.getAbbrev(); - -  // Emit the code (index) for the abbreviation. -  if (Asm->isVerbose()) -    Asm->OutStreamer.AddComment("Abbrev [" + Twine(Abbrev.getNumber()) + -                                "] 0x" + Twine::utohexstr(Die.getOffset()) + -                                ":0x" + Twine::utohexstr(Die.getSize()) + " " + -                                dwarf::TagString(Abbrev.getTag())); -  Asm->EmitULEB128(Abbrev.getNumber()); - -  const SmallVectorImpl<DIEValue *> &Values = Die.getValues(); -  const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData(); - -  // Emit the DIE attribute values. -  for (unsigned i = 0, N = Values.size(); i < N; ++i) { -    dwarf::Attribute Attr = AbbrevData[i].getAttribute(); -    dwarf::Form Form = AbbrevData[i].getForm(); -    assert(Form && "Too many attributes for DIE (check abbreviation)"); - -    if (Asm->isVerbose()) { -      Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr)); -      if (Attr == dwarf::DW_AT_accessibility) -        Asm->OutStreamer.AddComment(dwarf::AccessibilityString( -            cast<DIEInteger>(Values[i])->getValue())); -    } - -    // Emit an attribute using the defined form. -    Values[i]->EmitValue(Asm, Form); -  } - -  // Emit the DIE children if any. -  if (Abbrev.hasChildren()) { -    for (auto &Child : Die.getChildren()) -      emitDIE(*Child); - -    Asm->OutStreamer.AddComment("End Of Children Mark"); -    Asm->EmitInt8(0); -  } -} -  // Emit the debug info section.  void DwarfDebug::emitDebugInfo() {    DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder; - -  Holder.emitUnits(DwarfAbbrevSectionSym); +  Holder.emitUnits(/* UseOffsets */ false);  }  // Emit the abbreviation section. @@ -1452,65 +1284,39 @@ void DwarfDebug::emitAbbreviations() {    Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());  } -// Emit the last address of the section and the end of the line matrix. -void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { -  // Define last address of section. -  Asm->OutStreamer.AddComment("Extended Op"); -  Asm->EmitInt8(0); - -  Asm->OutStreamer.AddComment("Op size"); -  Asm->EmitInt8(Asm->getDataLayout().getPointerSize() + 1); -  Asm->OutStreamer.AddComment("DW_LNE_set_address"); -  Asm->EmitInt8(dwarf::DW_LNE_set_address); - -  Asm->OutStreamer.AddComment("Section end label"); - -  Asm->OutStreamer.EmitSymbolValue( -      Asm->GetTempSymbol("section_end", SectionEnd), -      Asm->getDataLayout().getPointerSize()); - -  // Mark end of matrix. -  Asm->OutStreamer.AddComment("DW_LNE_end_sequence"); -  Asm->EmitInt8(0); -  Asm->EmitInt8(1); -  Asm->EmitInt8(1); -} - -void DwarfDebug::emitAccel(DwarfAccelTable &Accel, const MCSection *Section, -                           StringRef TableName, StringRef SymName) { +void DwarfDebug::emitAccel(DwarfAccelTable &Accel, MCSection *Section, +                           StringRef TableName) {    Accel.FinalizeTable(Asm, TableName); -  Asm->OutStreamer.SwitchSection(Section); -  auto *SectionBegin = Asm->GetTempSymbol(SymName); -  Asm->OutStreamer.EmitLabel(SectionBegin); +  Asm->OutStreamer->SwitchSection(Section);    // Emit the full data. -  Accel.Emit(Asm, SectionBegin, this, DwarfStrSectionSym); +  Accel.emit(Asm, Section->getBeginSymbol(), this);  }  // Emit visible names into a hashed accelerator table section.  void DwarfDebug::emitAccelNames() {    emitAccel(AccelNames, Asm->getObjFileLowering().getDwarfAccelNamesSection(), -            "Names", "names_begin"); +            "Names");  }  // Emit objective C classes and categories into a hashed accelerator table  // section.  void DwarfDebug::emitAccelObjC() {    emitAccel(AccelObjC, Asm->getObjFileLowering().getDwarfAccelObjCSection(), -            "ObjC", "objc_begin"); +            "ObjC");  }  // Emit namespace dies into a hashed accelerator table.  void DwarfDebug::emitAccelNamespaces() {    emitAccel(AccelNamespace,              Asm->getObjFileLowering().getDwarfAccelNamespaceSection(), -            "namespac", "namespac_begin"); +            "namespac");  }  // Emit type dies into a hashed accelerator table.  void DwarfDebug::emitAccelTypes() {    emitAccel(AccelTypes, Asm->getObjFileLowering().getDwarfAccelTypesSection(), -            "types", "types_begin"); +            "types");  }  // Public name handling. @@ -1559,7 +1365,6 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,      return dwarf::GIEK_TYPE;    case dwarf::DW_TAG_subprogram:      return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_FUNCTION, Linkage); -  case dwarf::DW_TAG_constant:    case dwarf::DW_TAG_variable:      return dwarf::PubIndexEntryDescriptor(dwarf::GIEK_VARIABLE, Linkage);    case dwarf::DW_TAG_enumerator: @@ -1573,16 +1378,16 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,  /// emitDebugPubNames - Emit visible names into a debug pubnames section.  ///  void DwarfDebug::emitDebugPubNames(bool GnuStyle) { -  const MCSection *PSec = -      GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() -               : Asm->getObjFileLowering().getDwarfPubNamesSection(); +  MCSection *PSec = GnuStyle +                        ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection() +                        : Asm->getObjFileLowering().getDwarfPubNamesSection();    emitDebugPubSection(GnuStyle, PSec, "Names",                        &DwarfCompileUnit::getGlobalNames);  }  void DwarfDebug::emitDebugPubSection( -    bool GnuStyle, const MCSection *PSec, StringRef Name, +    bool GnuStyle, MCSection *PSec, StringRef Name,      const StringMap<const DIE *> &(DwarfCompileUnit::*Accessor)() const) {    for (const auto &NU : CUMap) {      DwarfCompileUnit *TheU = NU.second; @@ -1594,26 +1399,25 @@ void DwarfDebug::emitDebugPubSection(      if (auto *Skeleton = TheU->getSkeleton())        TheU = Skeleton; -    unsigned ID = TheU->getUniqueID();      // Start the dwarf pubnames section. -    Asm->OutStreamer.SwitchSection(PSec); +    Asm->OutStreamer->SwitchSection(PSec);      // Emit the header. -    Asm->OutStreamer.AddComment("Length of Public " + Name + " Info"); -    MCSymbol *BeginLabel = Asm->GetTempSymbol("pub" + Name + "_begin", ID); -    MCSymbol *EndLabel = Asm->GetTempSymbol("pub" + Name + "_end", ID); +    Asm->OutStreamer->AddComment("Length of Public " + Name + " Info"); +    MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin"); +    MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end");      Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); -    Asm->OutStreamer.EmitLabel(BeginLabel); +    Asm->OutStreamer->EmitLabel(BeginLabel); -    Asm->OutStreamer.AddComment("DWARF Version"); +    Asm->OutStreamer->AddComment("DWARF Version");      Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION); -    Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); -    Asm->EmitSectionOffset(TheU->getLabelBegin(), TheU->getSectionSym()); +    Asm->OutStreamer->AddComment("Offset of Compilation Unit Info"); +    Asm->emitSectionOffset(TheU->getLabelBegin()); -    Asm->OutStreamer.AddComment("Compilation Unit Length"); +    Asm->OutStreamer->AddComment("Compilation Unit Length");      Asm->EmitInt32(TheU->getLength());      // Emit the pubnames for this compilation unit. @@ -1621,31 +1425,31 @@ void DwarfDebug::emitDebugPubSection(        const char *Name = GI.getKeyData();        const DIE *Entity = GI.second; -      Asm->OutStreamer.AddComment("DIE offset"); +      Asm->OutStreamer->AddComment("DIE offset");        Asm->EmitInt32(Entity->getOffset());        if (GnuStyle) {          dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity); -        Asm->OutStreamer.AddComment( +        Asm->OutStreamer->AddComment(              Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " +              dwarf::GDBIndexEntryLinkageString(Desc.Linkage));          Asm->EmitInt8(Desc.toBits());        } -      Asm->OutStreamer.AddComment("External Name"); -      Asm->OutStreamer.EmitBytes(StringRef(Name, GI.getKeyLength() + 1)); +      Asm->OutStreamer->AddComment("External Name"); +      Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1));      } -    Asm->OutStreamer.AddComment("End Mark"); +    Asm->OutStreamer->AddComment("End Mark");      Asm->EmitInt32(0); -    Asm->OutStreamer.EmitLabel(EndLabel); +    Asm->OutStreamer->EmitLabel(EndLabel);    }  }  void DwarfDebug::emitDebugPubTypes(bool GnuStyle) { -  const MCSection *PSec = -      GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() -               : Asm->getObjFileLowering().getDwarfPubTypesSection(); +  MCSection *PSec = GnuStyle +                        ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection() +                        : Asm->getObjFileLowering().getDwarfPubTypesSection();    emitDebugPubSection(GnuStyle, PSec, "Types",                        &DwarfCompileUnit::getGlobalTypes); @@ -1657,86 +1461,44 @@ void DwarfDebug::emitDebugStr() {    Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection());  } -/// Emits an optimal (=sorted) sequence of DW_OP_pieces. -void DwarfDebug::emitLocPieces(ByteStreamer &Streamer, -                               const DITypeIdentifierMap &Map, -                               ArrayRef<DebugLocEntry::Value> Values) { -  assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) { -        return P.isVariablePiece(); -      }) && "all values are expected to be pieces"); -  assert(std::is_sorted(Values.begin(), Values.end()) && -         "pieces are expected to be sorted"); - -  unsigned Offset = 0; -  for (auto Piece : Values) { -    const unsigned SizeOfByte = 8; -    DIExpression Expr = Piece.getExpression(); -    unsigned PieceOffset = Expr.getPieceOffset(); -    unsigned PieceSize = Expr.getPieceSize(); -    assert(Offset <= PieceOffset && "overlapping or duplicate pieces"); -    if (Offset < PieceOffset) { -      // The DWARF spec seriously mandates pieces with no locations for gaps. -      Asm->EmitDwarfOpPiece(Streamer, (PieceOffset-Offset)*SizeOfByte); -      Offset += PieceOffset-Offset; -    } -    Offset += PieceSize; - -#ifndef NDEBUG -    DIVariable Var = Piece.getVariable(); -    assert(!Var.isIndirect() && "indirect address for piece"); -    unsigned VarSize = Var.getSizeInBits(Map); -    assert(PieceSize+PieceOffset <= VarSize/SizeOfByte -           && "piece is larger than or outside of variable"); -    assert(PieceSize*SizeOfByte != VarSize -           && "piece covers entire variable"); -#endif - -    emitDebugLocValue(Streamer, Piece, PieceOffset*SizeOfByte); -  } -} - -  void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, -                                   const DebugLocEntry &Entry) { -  const DebugLocEntry::Value Value = Entry.getValues()[0]; -  if (Value.isVariablePiece()) -    // Emit all pieces that belong to the same variable and range. -    return emitLocPieces(Streamer, TypeIdentifierMap, Entry.getValues()); - -  assert(Entry.getValues().size() == 1 && "only pieces may have >1 value"); -  emitDebugLocValue(Streamer, Value); -} - -void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer, -                                   const DebugLocEntry::Value &Value, -                                   unsigned PieceOffsetInBits) { -  DIVariable DV = Value.getVariable(); -  DebugLocDwarfExpression DwarfExpr(*Asm, Streamer); - +                                   const DebugLocStream::Entry &Entry) { +  auto &&Comments = DebugLocs.getComments(Entry); +  auto Comment = Comments.begin(); +  auto End = Comments.end(); +  for (uint8_t Byte : DebugLocs.getBytes(Entry)) +    Streamer.EmitInt8(Byte, Comment != End ? *(Comment++) : ""); +} + +static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, +                              ByteStreamer &Streamer, +                              const DebugLocEntry::Value &Value, +                              unsigned PieceOffsetInBits) { +  DebugLocDwarfExpression DwarfExpr(*AP.MF->getSubtarget().getRegisterInfo(), +                                    AP.getDwarfDebug()->getDwarfVersion(), +                                    Streamer);    // Regular entry.    if (Value.isInt()) { -    DIBasicType BTy(resolve(DV.getType())); -    if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed || -                         BTy.getEncoding() == dwarf::DW_ATE_signed_char)) +    if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed || +               BT->getEncoding() == dwarf::DW_ATE_signed_char))        DwarfExpr.AddSignedConstant(Value.getInt());      else        DwarfExpr.AddUnsignedConstant(Value.getInt());    } else if (Value.isLocation()) {      MachineLocation Loc = Value.getLoc(); -    DIExpression Expr = Value.getExpression(); -    if (!Expr || (Expr.getNumElements() == 0)) +    const DIExpression *Expr = Value.getExpression(); +    if (!Expr || !Expr->getNumElements())        // Regular entry. -      Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect()); +      AP.EmitDwarfRegOp(Streamer, Loc);      else {        // Complex address entry.        if (Loc.getOffset()) {          DwarfExpr.AddMachineRegIndirect(Loc.getReg(), Loc.getOffset()); -        DwarfExpr.AddExpression(Expr, PieceOffsetInBits); +        DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end(), +                                PieceOffsetInBits);        } else          DwarfExpr.AddMachineRegExpression(Expr, Loc.getReg(),                                            PieceOffsetInBits); -      if (DV.isIndirect()) -        DwarfExpr.EmitOp(dwarf::DW_OP_deref);      }    }    // else ... ignore constant fp. There is not any good way to @@ -1744,61 +1506,95 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,    // FIXME: ^  } -void DwarfDebug::emitDebugLocEntryLocation(const DebugLocEntry &Entry) { -  Asm->OutStreamer.AddComment("Loc expr size"); -  MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol(); -  MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol(); -  Asm->EmitLabelDifference(end, begin, 2); -  Asm->OutStreamer.EmitLabel(begin); +void DebugLocEntry::finalize(const AsmPrinter &AP, DebugLocStream &Locs, +                             const DIBasicType *BT) { +  Locs.startEntry(Begin, End); +  BufferByteStreamer Streamer = Locs.getStreamer(); +  const DebugLocEntry::Value &Value = Values[0]; +  if (Value.isBitPiece()) { +    // Emit all pieces that belong to the same variable and range. +    assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) { +          return P.isBitPiece(); +        }) && "all values are expected to be pieces"); +    assert(std::is_sorted(Values.begin(), Values.end()) && +           "pieces are expected to be sorted"); +    +    unsigned Offset = 0; +    for (auto Piece : Values) { +      const DIExpression *Expr = Piece.getExpression(); +      unsigned PieceOffset = Expr->getBitPieceOffset(); +      unsigned PieceSize = Expr->getBitPieceSize(); +      assert(Offset <= PieceOffset && "overlapping or duplicate pieces"); +      if (Offset < PieceOffset) { +        // The DWARF spec seriously mandates pieces with no locations for gaps. +        DebugLocDwarfExpression Expr(*AP.MF->getSubtarget().getRegisterInfo(), +                                     AP.getDwarfDebug()->getDwarfVersion(), +                                     Streamer); +        Expr.AddOpPiece(PieceOffset-Offset, 0); +        Offset += PieceOffset-Offset; +      } +      Offset += PieceSize; + +      emitDebugLocValue(AP, BT, Streamer, Piece, PieceOffset); +    } +  } else { +    assert(Values.size() == 1 && "only pieces may have >1 value"); +    emitDebugLocValue(AP, BT, Streamer, Value, 0); +  } +} + +void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry) { +  // Emit the size. +  Asm->OutStreamer->AddComment("Loc expr size"); +  Asm->EmitInt16(DebugLocs.getBytes(Entry).size()); +    // Emit the entry.    APByteStreamer Streamer(*Asm);    emitDebugLocEntry(Streamer, Entry); -  // Close the range. -  Asm->OutStreamer.EmitLabel(end);  }  // Emit locations into the debug loc section.  void DwarfDebug::emitDebugLoc() {    // Start the dwarf loc section. -  Asm->OutStreamer.SwitchSection( +  Asm->OutStreamer->SwitchSection(        Asm->getObjFileLowering().getDwarfLocSection());    unsigned char Size = Asm->getDataLayout().getPointerSize(); -  for (const auto &DebugLoc : DotDebugLocEntries) { -    Asm->OutStreamer.EmitLabel(DebugLoc.Label); -    const DwarfCompileUnit *CU = DebugLoc.CU; -    for (const auto &Entry : DebugLoc.List) { +  for (const auto &List : DebugLocs.getLists()) { +    Asm->OutStreamer->EmitLabel(List.Label); +    const DwarfCompileUnit *CU = List.CU; +    for (const auto &Entry : DebugLocs.getEntries(List)) {        // Set up the range. This range is relative to the entry point of the        // compile unit. This is a hard coded 0 for low_pc when we're emitting        // ranges, or the DW_AT_low_pc on the compile unit otherwise.        if (auto *Base = CU->getBaseAddress()) { -        Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); -        Asm->EmitLabelDifference(Entry.getEndSym(), Base, Size); +        Asm->EmitLabelDifference(Entry.BeginSym, Base, Size); +        Asm->EmitLabelDifference(Entry.EndSym, Base, Size);        } else { -        Asm->OutStreamer.EmitSymbolValue(Entry.getBeginSym(), Size); -        Asm->OutStreamer.EmitSymbolValue(Entry.getEndSym(), Size); +        Asm->OutStreamer->EmitSymbolValue(Entry.BeginSym, Size); +        Asm->OutStreamer->EmitSymbolValue(Entry.EndSym, Size);        }        emitDebugLocEntryLocation(Entry);      } -    Asm->OutStreamer.EmitIntValue(0, Size); -    Asm->OutStreamer.EmitIntValue(0, Size); +    Asm->OutStreamer->EmitIntValue(0, Size); +    Asm->OutStreamer->EmitIntValue(0, Size);    }  }  void DwarfDebug::emitDebugLocDWO() { -  Asm->OutStreamer.SwitchSection( +  Asm->OutStreamer->SwitchSection(        Asm->getObjFileLowering().getDwarfLocDWOSection()); -  for (const auto &DebugLoc : DotDebugLocEntries) { -    Asm->OutStreamer.EmitLabel(DebugLoc.Label); -    for (const auto &Entry : DebugLoc.List) { +  for (const auto &List : DebugLocs.getLists()) { +    Asm->OutStreamer->EmitLabel(List.Label); +    for (const auto &Entry : DebugLocs.getEntries(List)) {        // Just always use start_length for now - at least that's one address        // rather than two. We could get fancier and try to, say, reuse an        // address we know we've emitted elsewhere (the start of the function?        // The start of the CU or CU subrange that encloses this range?)        Asm->EmitInt8(dwarf::DW_LLE_start_length_entry); -      unsigned idx = AddrPool.getIndex(Entry.getBeginSym()); +      unsigned idx = AddrPool.getIndex(Entry.BeginSym);        Asm->EmitULEB128(idx); -      Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4); +      Asm->EmitLabelDifference(Entry.EndSym, Entry.BeginSym, 4);        emitDebugLocEntryLocation(Entry);      } @@ -1813,36 +1609,62 @@ struct ArangeSpan {  // Emit a debug aranges section, containing a CU lookup for any  // address we can tie back to a CU.  void DwarfDebug::emitDebugARanges() { -  // Start the dwarf aranges section. -  Asm->OutStreamer.SwitchSection( -      Asm->getObjFileLowering().getDwarfARangesSection()); +  // Provides a unique id per text section. +  MapVector<MCSection *, SmallVector<SymbolCU, 8>> SectionMap; -  typedef DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> SpansType; +  // Filter labels by section. +  for (const SymbolCU &SCU : ArangeLabels) { +    if (SCU.Sym->isInSection()) { +      // Make a note of this symbol and it's section. +      MCSection *Section = &SCU.Sym->getSection(); +      if (!Section->getKind().isMetadata()) +        SectionMap[Section].push_back(SCU); +    } else { +      // Some symbols (e.g. common/bss on mach-o) can have no section but still +      // appear in the output. This sucks as we rely on sections to build +      // arange spans. We can do it without, but it's icky. +      SectionMap[nullptr].push_back(SCU); +    } +  } + +  // Add terminating symbols for each section. +  for (const auto &I : SectionMap) { +    MCSection *Section = I.first; +    MCSymbol *Sym = nullptr; -  SpansType Spans; +    if (Section) +      Sym = Asm->OutStreamer->endSection(Section); -  // Build a list of sections used. -  std::vector<const MCSection *> Sections; -  for (const auto &it : SectionMap) { -    const MCSection *Section = it.first; -    Sections.push_back(Section); +    // Insert a final terminator. +    SectionMap[Section].push_back(SymbolCU(nullptr, Sym));    } -  // Sort the sections into order. -  // This is only done to ensure consistent output order across different runs. -  std::sort(Sections.begin(), Sections.end(), SectionSort); +  DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> Spans; -  // Build a set of address spans, sorted by CU. -  for (const MCSection *Section : Sections) { -    SmallVector<SymbolCU, 8> &List = SectionMap[Section]; +  for (auto &I : SectionMap) { +    const MCSection *Section = I.first; +    SmallVector<SymbolCU, 8> &List = I.second;      if (List.size() < 2)        continue; +    // If we have no section (e.g. common), just write out +    // individual spans for each symbol. +    if (!Section) { +      for (const SymbolCU &Cur : List) { +        ArangeSpan Span; +        Span.Start = Cur.Sym; +        Span.End = nullptr; +        if (Cur.CU) +          Spans[Cur.CU].push_back(Span); +      } +      continue; +    } +      // Sort the symbols by offset within the section.      std::sort(List.begin(), List.end(),                [&](const SymbolCU &A, const SymbolCU &B) { -      unsigned IA = A.Sym ? Asm->OutStreamer.GetSymbolOrder(A.Sym) : 0; -      unsigned IB = B.Sym ? Asm->OutStreamer.GetSymbolOrder(B.Sym) : 0; +      unsigned IA = A.Sym ? Asm->OutStreamer->GetSymbolOrder(A.Sym) : 0; +      unsigned IB = B.Sym ? Asm->OutStreamer->GetSymbolOrder(B.Sym) : 0;        // Symbols with no order assigned should be placed at the end.        // (e.g. section end labels) @@ -1853,35 +1675,27 @@ void DwarfDebug::emitDebugARanges() {        return IA < IB;      }); -    // If we have no section (e.g. common), just write out -    // individual spans for each symbol. -    if (!Section) { -      for (const SymbolCU &Cur : List) { +    // Build spans between each label. +    const MCSymbol *StartSym = List[0].Sym; +    for (size_t n = 1, e = List.size(); n < e; n++) { +      const SymbolCU &Prev = List[n - 1]; +      const SymbolCU &Cur = List[n]; + +      // Try and build the longest span we can within the same CU. +      if (Cur.CU != Prev.CU) {          ArangeSpan Span; -        Span.Start = Cur.Sym; -        Span.End = nullptr; -        if (Cur.CU) -          Spans[Cur.CU].push_back(Span); -      } -    } else { -      // Build spans between each label. -      const MCSymbol *StartSym = List[0].Sym; -      for (size_t n = 1, e = List.size(); n < e; n++) { -        const SymbolCU &Prev = List[n - 1]; -        const SymbolCU &Cur = List[n]; - -        // Try and build the longest span we can within the same CU. -        if (Cur.CU != Prev.CU) { -          ArangeSpan Span; -          Span.Start = StartSym; -          Span.End = Cur.Sym; -          Spans[Prev.CU].push_back(Span); -          StartSym = Cur.Sym; -        } +        Span.Start = StartSym; +        Span.End = Cur.Sym; +        Spans[Prev.CU].push_back(Span); +        StartSym = Cur.Sym;        }      }    } +  // Start the dwarf aranges section. +  Asm->OutStreamer->SwitchSection( +      Asm->getObjFileLowering().getDwarfARangesSection()); +    unsigned PtrSize = Asm->getDataLayout().getPointerSize();    // Build a list of CUs used. @@ -1921,18 +1735,18 @@ void DwarfDebug::emitDebugARanges() {      ContentSize += (List.size() + 1) * TupleSize;      // For each compile unit, write the list of spans it covers. -    Asm->OutStreamer.AddComment("Length of ARange Set"); +    Asm->OutStreamer->AddComment("Length of ARange Set");      Asm->EmitInt32(ContentSize); -    Asm->OutStreamer.AddComment("DWARF Arange version number"); +    Asm->OutStreamer->AddComment("DWARF Arange version number");      Asm->EmitInt16(dwarf::DW_ARANGES_VERSION); -    Asm->OutStreamer.AddComment("Offset Into Debug Info Section"); -    Asm->EmitSectionOffset(CU->getLabelBegin(), CU->getSectionSym()); -    Asm->OutStreamer.AddComment("Address Size (in bytes)"); +    Asm->OutStreamer->AddComment("Offset Into Debug Info Section"); +    Asm->emitSectionOffset(CU->getLabelBegin()); +    Asm->OutStreamer->AddComment("Address Size (in bytes)");      Asm->EmitInt8(PtrSize); -    Asm->OutStreamer.AddComment("Segment Size (in bytes)"); +    Asm->OutStreamer->AddComment("Segment Size (in bytes)");      Asm->EmitInt8(0); -    Asm->OutStreamer.EmitFill(Padding, 0xff); +    Asm->OutStreamer->EmitFill(Padding, 0xff);      for (const ArangeSpan &Span : List) {        Asm->EmitLabelReference(Span.Start, PtrSize); @@ -1947,20 +1761,20 @@ void DwarfDebug::emitDebugARanges() {          if (Size == 0)            Size = 1; -        Asm->OutStreamer.EmitIntValue(Size, PtrSize); +        Asm->OutStreamer->EmitIntValue(Size, PtrSize);        }      } -    Asm->OutStreamer.AddComment("ARange terminator"); -    Asm->OutStreamer.EmitIntValue(0, PtrSize); -    Asm->OutStreamer.EmitIntValue(0, PtrSize); +    Asm->OutStreamer->AddComment("ARange terminator"); +    Asm->OutStreamer->EmitIntValue(0, PtrSize); +    Asm->OutStreamer->EmitIntValue(0, PtrSize);    }  }  // Emit visible names into a debug ranges section.  void DwarfDebug::emitDebugRanges() {    // Start the dwarf ranges section. -  Asm->OutStreamer.SwitchSection( +  Asm->OutStreamer->SwitchSection(        Asm->getObjFileLowering().getDwarfRangesSection());    // Size for our labels. @@ -1976,7 +1790,7 @@ void DwarfDebug::emitDebugRanges() {      // Iterate over the misc ranges for the compile units in the module.      for (const RangeSpanList &List : TheCU->getRangeLists()) {        // Emit our symbol so we can find the beginning of the range. -      Asm->OutStreamer.EmitLabel(List.getSym()); +      Asm->OutStreamer->EmitLabel(List.getSym());        for (const RangeSpan &Range : List.getRanges()) {          const MCSymbol *Begin = Range.getStart(); @@ -1987,14 +1801,14 @@ void DwarfDebug::emitDebugRanges() {            Asm->EmitLabelDifference(Begin, Base, Size);            Asm->EmitLabelDifference(End, Base, Size);          } else { -          Asm->OutStreamer.EmitSymbolValue(Begin, Size); -          Asm->OutStreamer.EmitSymbolValue(End, Size); +          Asm->OutStreamer->EmitSymbolValue(Begin, Size); +          Asm->OutStreamer->EmitSymbolValue(End, Size);          }        }        // And terminate the list with two 0 values. -      Asm->OutStreamer.EmitIntValue(0, Size); -      Asm->OutStreamer.EmitIntValue(0, Size); +      Asm->OutStreamer->EmitIntValue(0, Size); +      Asm->OutStreamer->EmitIntValue(0, Size);      }    }  } @@ -2004,7 +1818,7 @@ void DwarfDebug::emitDebugRanges() {  void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,                                    std::unique_ptr<DwarfUnit> NewU) {    NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name, -                  U.getCUNode().getSplitDebugFilename()); +                  U.getCUNode()->getSplitDebugFilename());    if (!CompilationDir.empty())      NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); @@ -2022,10 +1836,9 @@ DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {    auto OwnedUnit = make_unique<DwarfCompileUnit>(        CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder);    DwarfCompileUnit &NewCU = *OwnedUnit; -  NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection(), -                    DwarfInfoSectionSym); +  NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection()); -  NewCU.initStmtList(DwarfLineSectionSym); +  NewCU.initStmtList();    initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit)); @@ -2036,9 +1849,8 @@ DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {  // compile units that would normally be in debug_info.  void DwarfDebug::emitDebugInfoDWO() {    assert(useSplitDwarf() && "No split dwarf debug info?"); -  // Don't pass an abbrev symbol, using a constant zero instead so as not to -  // emit relocations into the dwo file. -  InfoHolder.emitUnits(/* AbbrevSymbol */ nullptr); +  // Don't emit relocations into the dwo file. +  InfoHolder.emitUnits(/* UseOffsets */ true);  }  // Emit the .debug_abbrev.dwo section for separated dwarf. This contains the @@ -2050,9 +1862,9 @@ void DwarfDebug::emitDebugAbbrevDWO() {  void DwarfDebug::emitDebugLineDWO() {    assert(useSplitDwarf() && "No split dwarf?"); -  Asm->OutStreamer.SwitchSection( +  Asm->OutStreamer->SwitchSection(        Asm->getObjFileLowering().getDwarfLineDWOSection()); -  SplitTypeUnitFileTable.Emit(Asm->OutStreamer); +  SplitTypeUnitFileTable.Emit(*Asm->OutStreamer);  }  // Emit the .debug_str.dwo section for separated dwarf. This contains the @@ -2060,8 +1872,7 @@ void DwarfDebug::emitDebugLineDWO() {  // sections.  void DwarfDebug::emitDebugStrDWO() {    assert(useSplitDwarf() && "No split dwarf?"); -  const MCSection *OffSec = -      Asm->getObjFileLowering().getDwarfStrOffDWOSection(); +  MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();    InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),                           OffSec);  } @@ -2070,7 +1881,7 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {    if (!useSplitDwarf())      return nullptr;    if (SingleCU) -    SplitTypeUnitFileTable.setCompilationDir(CU.getCUNode().getDirectory()); +    SplitTypeUnitFileTable.setCompilationDir(CU.getCUNode()->getDirectory());    return &SplitTypeUnitFileTable;  } @@ -2082,12 +1893,12 @@ static uint64_t makeTypeSignature(StringRef Identifier) {    // appropriately.    MD5::MD5Result Result;    Hash.final(Result); -  return *reinterpret_cast<support::ulittle64_t *>(Result + 8); +  return support::endian::read64le(Result + 8);  }  void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,                                        StringRef Identifier, DIE &RefDie, -                                      DICompositeType CTy) { +                                      const DICompositeType *CTy) {    // Fast path if we're building some type units and one has already used the    // address pool we know we're going to throw away all this work anyway, so    // don't bother building dependent types. @@ -2146,7 +1957,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,        // This is inefficient because all the dependent types will be rebuilt        // from scratch, including building them in type units, discovering that        // they depend on addresses, throwing them out and rebuilding them. -      CU.constructTypeDIE(RefDie, CTy); +      CU.constructTypeDIE(RefDie, cast<DICompositeType>(CTy));        return;      } @@ -2165,27 +1976,23 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,  void DwarfDebug::addAccelName(StringRef Name, const DIE &Die) {    if (!useDwarfAccelTables())      return; -  AccelNames.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name), -                     &Die); +  AccelNames.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die);  }  void DwarfDebug::addAccelObjC(StringRef Name, const DIE &Die) {    if (!useDwarfAccelTables())      return; -  AccelObjC.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name), -                    &Die); +  AccelObjC.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die);  }  void DwarfDebug::addAccelNamespace(StringRef Name, const DIE &Die) {    if (!useDwarfAccelTables())      return; -  AccelNamespace.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name), -                         &Die); +  AccelNamespace.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die);  }  void DwarfDebug::addAccelType(StringRef Name, const DIE &Die, char Flags) {    if (!useDwarfAccelTables())      return; -  AccelTypes.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name), -                     &Die); +  AccelTypes.AddName(InfoHolder.getStringPool().getEntry(*Asm, Name), &Die);  }  | 
