]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/blobdiff - lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Debug Info: Prepare DebugLocEntry to handle more than a single value per
[opencl/llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.cpp
index e98df8cd47ef319be2547b9a6141bc19ce364d31..a588c46718bbcae1e0fe1e71d532d173bb14bb1c 100644 (file)
@@ -15,7 +15,6 @@
 #include "DwarfDebug.h"
 #include "DIE.h"
 #include "DIEHash.h"
-#include "DwarfAccelTable.h"
 #include "DwarfUnit.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Statistic.h"
@@ -165,19 +164,32 @@ DIType DbgVariable::getType() const {
   return Ty;
 }
 
+static LLVM_CONSTEXPR DwarfAccelTable::Atom TypeAtoms[] = {
+    DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
+    DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
+    DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)};
+
 DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
-    : Asm(A), MMI(Asm->MMI), FirstCU(0), PrevLabel(NULL), GlobalRangeCount(0),
-      InfoHolder(A, "info_string", DIEValueAllocator),
+    : Asm(A), MMI(Asm->MMI), FirstCU(nullptr), PrevLabel(nullptr),
+      GlobalRangeCount(0), InfoHolder(A, "info_string", DIEValueAllocator),
       UsedNonDefaultText(false),
-      SkeletonHolder(A, "skel_string", DIEValueAllocator) {
-
-  DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = 0;
-  DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = DwarfLineSectionSym = 0;
-  DwarfAddrSectionSym = 0;
-  DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0;
-  FunctionBeginSym = FunctionEndSym = 0;
-  CurFn = 0;
-  CurMI = 0;
+      SkeletonHolder(A, "skel_string", DIEValueAllocator),
+      AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
+                                       dwarf::DW_FORM_data4)),
+      AccelObjC(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
+                                      dwarf::DW_FORM_data4)),
+      AccelNamespace(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
+                                           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.
@@ -211,10 +223,10 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
 // 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 = 0) {
+                                const char *SymbolStem = nullptr) {
   Asm->OutStreamer.SwitchSection(Section);
   if (!SymbolStem)
-    return 0;
+    return nullptr;
 
   MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
   Asm->OutStreamer.EmitLabel(TmpSym);
@@ -260,26 +272,26 @@ static bool SectionSort(const MCSection *A, const MCSection *B) {
 // 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.
-static void addSubprogramNames(DwarfUnit &TheU, DISubprogram SP, DIE *Die) {
+void DwarfDebug::addSubprogramNames(DISubprogram SP, DIE &Die) {
   if (!SP.isDefinition())
     return;
-  TheU.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())
-    TheU.addAccelName(SP.getLinkageName(), Die);
+    addAccelName(SP.getLinkageName(), Die);
 
   // If this is an Objective-C selector name add it to the ObjC accelerator
   // too.
   if (isObjCClass(SP.getName())) {
     StringRef Class, Category;
     getObjCClassCategory(SP.getName(), Class, Category);
-    TheU.addAccelObjC(Class, Die);
+    addAccelObjC(Class, Die);
     if (Category != "")
-      TheU.addAccelObjC(Category, Die);
+      addAccelObjC(Category, Die);
     // Also add the base method name to the name table.
-    TheU.addAccelName(getObjCMethodName(SP.getName()), Die);
+    addAccelName(getObjCMethodName(SP.getName()), Die);
   }
 }
 
@@ -310,8 +322,8 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU,
   // concrete DIE twice.
   if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) {
     // Pick up abstract subprogram DIE.
-    SPDie = SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU.getUnitDie());
-    SPCU.addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, AbsSPDIE);
+    SPDie = &SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, SPCU.getUnitDie());
+    SPCU.addDIEEntry(*SPDie, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
   } else {
     DISubprogram SPDecl = SP.getFunctionDeclaration();
     if (!SPDecl.isSubprogram()) {
@@ -323,7 +335,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU,
       DIScope SPContext = resolve(SP.getContext());
       if (SP.isDefinition() && !SPContext.isCompileUnit() &&
           !SPContext.isFile() && !isSubprogramContext(SPContext)) {
-        SPCU.addFlag(SPDie, dwarf::DW_AT_declaration);
+        SPCU.addFlag(*SPDie, dwarf::DW_AT_declaration);
 
         // Add arguments.
         DICompositeType SPTy = SP.getType();
@@ -333,21 +345,21 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU,
           SPCU.constructSubprogramArguments(*SPDie, Args);
         DIE *SPDeclDie = SPDie;
         SPDie =
-            SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU.getUnitDie());
-        SPCU.addDIEEntry(SPDie, dwarf::DW_AT_specification, SPDeclDie);
+            &SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, SPCU.getUnitDie());
+        SPCU.addDIEEntry(*SPDie, dwarf::DW_AT_specification, *SPDeclDie);
       }
     }
   }
 
-  attachLowHighPC(SPCU, SPDie, FunctionBeginSym, FunctionEndSym);
+  attachLowHighPC(SPCU, *SPDie, FunctionBeginSym, FunctionEndSym);
 
   const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
   MachineLocation Location(RI->getFrameRegister(*Asm->MF));
-  SPCU.addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
+  SPCU.addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
 
   // Add name to the name table, we do this here because we're guaranteed
   // to have concrete versions of our DW_TAG_subprogram nodes.
-  addSubprogramNames(SPCU, SP, SPDie);
+  addSubprogramNames(SP, *SPDie);
 
   return SPDie;
 }
@@ -373,7 +385,7 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) {
   return !End;
 }
 
-static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE *D,
+static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE &D,
                             dwarf::Attribute A, const MCSymbol *L,
                             const MCSymbol *Sec) {
   if (Asm.MAI->doesDwarfUseRelocationsAcrossSections())
@@ -382,7 +394,7 @@ static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE *D,
     U.addSectionDelta(D, A, L, Sec);
 }
 
-void DwarfDebug::addScopeRangeList(DwarfCompileUnit &TheCU, DIE *ScopeDIE,
+void DwarfDebug::addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE,
                                    const SmallVectorImpl<InsnRange> &Range) {
   // Emit offset in .debug_range as a relocatable label. emitDIE will handle
   // emitting it appropriately.
@@ -412,7 +424,7 @@ void DwarfDebug::addScopeRangeList(DwarfCompileUnit &TheCU, DIE *ScopeDIE,
 DIE *DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
                                           LexicalScope *Scope) {
   if (isLexicalScopeDIENull(Scope))
-    return 0;
+    return nullptr;
 
   DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
   if (Scope->isAbstractScope())
@@ -422,7 +434,7 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
 
   // If we have multiple ranges, emit them into the range section.
   if (ScopeRanges.size() > 1) {
-    addScopeRangeList(TheCU, ScopeDIE, ScopeRanges);
+    addScopeRangeList(TheCU, *ScopeDIE, ScopeRanges);
     return ScopeDIE;
   }
 
@@ -435,7 +447,7 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
   assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
   assert(End->isDefined() && "Invalid end label for an inlined scope!");
 
-  attachLowHighPC(TheCU, ScopeDIE, Start, End);
+  attachLowHighPC(TheCU, *ScopeDIE, Start, End);
 
   return ScopeDIE;
 }
@@ -449,88 +461,86 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DwarfCompileUnit &TheCU,
          "LexicalScope does not have instruction markers!");
 
   if (!Scope->getScopeNode())
-    return NULL;
+    return nullptr;
   DIScope DS(Scope->getScopeNode());
   DISubprogram InlinedSP = getDISubprogram(DS);
   DIE *OriginDIE = TheCU.getDIE(InlinedSP);
   if (!OriginDIE) {
     DEBUG(dbgs() << "Unable to find original DIE for an inlined subprogram.");
-    return NULL;
+    return nullptr;
   }
 
   DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
-  TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, OriginDIE);
+  TheCU.addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
 
   // If we have multiple ranges, emit them into the range section.
   if (ScopeRanges.size() > 1)
-    addScopeRangeList(TheCU, ScopeDIE, ScopeRanges);
+    addScopeRangeList(TheCU, *ScopeDIE, ScopeRanges);
   else {
     SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
     MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
     MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
 
-    if (StartLabel == 0 || EndLabel == 0)
+    if (!StartLabel || !EndLabel)
       llvm_unreachable("Unexpected Start and End labels for an inlined scope!");
 
     assert(StartLabel->isDefined() &&
            "Invalid starting label for an inlined scope!");
     assert(EndLabel->isDefined() && "Invalid end label for an inlined scope!");
 
-    attachLowHighPC(TheCU, ScopeDIE, StartLabel, EndLabel);
+    attachLowHighPC(TheCU, *ScopeDIE, StartLabel, EndLabel);
   }
 
   InlinedSubprogramDIEs.insert(OriginDIE);
 
   // Add the call site information to the DIE.
   DILocation DL(Scope->getInlinedAt());
-  TheCU.addUInt(ScopeDIE, dwarf::DW_AT_call_file, None,
+  TheCU.addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
                 TheCU.getOrCreateSourceID(DL.getFilename(), DL.getDirectory()));
-  TheCU.addUInt(ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber());
+  TheCU.addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber());
 
   // Add name to the name table, we do this here because we're guaranteed
   // to have concrete versions of our DW_TAG_inlined_subprogram nodes.
-  addSubprogramNames(TheCU, InlinedSP, ScopeDIE);
+  addSubprogramNames(InlinedSP, *ScopeDIE);
 
   return ScopeDIE;
 }
 
-DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit &TheCU,
-                                        LexicalScope *Scope,
-                                        SmallVectorImpl<DIE *> &Children) {
-  DIE *ObjectPointer = NULL;
+DIE *DwarfDebug::createScopeChildrenDIE(
+    DwarfCompileUnit &TheCU, LexicalScope *Scope,
+    SmallVectorImpl<std::unique_ptr<DIE>> &Children) {
+  DIE *ObjectPointer = nullptr;
 
   // Collect arguments for current function.
   if (LScopes.isCurrentFunctionScope(Scope)) {
     for (DbgVariable *ArgDV : CurrentFnArguments)
-      if (ArgDV)
-        if (DIE *Arg =
-                TheCU.constructVariableDIE(*ArgDV, Scope->isAbstractScope())) {
-          Children.push_back(Arg);
-          if (ArgDV->isObjectPointer())
-            ObjectPointer = Arg;
-        }
+      if (ArgDV) {
+        Children.push_back(
+            TheCU.constructVariableDIE(*ArgDV, Scope->isAbstractScope()));
+        if (ArgDV->isObjectPointer())
+          ObjectPointer = Children.back().get();
+      }
 
     // If this is a variadic function, add an unspecified parameter.
     DISubprogram SP(Scope->getScopeNode());
     DIArray FnArgs = SP.getType().getTypeArray();
     if (FnArgs.getElement(FnArgs.getNumElements() - 1)
             .isUnspecifiedParameter()) {
-      DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters);
-      Children.push_back(Ellipsis);
+      Children.push_back(
+          make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
     }
   }
 
   // Collect lexical scope children first.
-  for (DbgVariable *DV : ScopeVariables.lookup(Scope))
-    if (DIE *Variable =
-            TheCU.constructVariableDIE(*DV, Scope->isAbstractScope())) {
-      Children.push_back(Variable);
-      if (DV->isObjectPointer())
-        ObjectPointer = Variable;
-    }
+  for (DbgVariable *DV : ScopeVariables.lookup(Scope)) {
+    Children.push_back(
+        TheCU.constructVariableDIE(*DV, Scope->isAbstractScope()));
+    if (DV->isObjectPointer())
+      ObjectPointer = Children.back().get();
+  }
   for (LexicalScope *LS : Scope->getChildren())
     if (DIE *Nested = constructScopeDIE(TheCU, LS))
-      Children.push_back(Nested);
+      Children.push_back(std::unique_ptr<DIE>(Nested));
   return ObjectPointer;
 }
 
@@ -538,18 +548,18 @@ DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit &TheCU,
 DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
                                    LexicalScope *Scope) {
   if (!Scope || !Scope->getScopeNode())
-    return NULL;
+    return nullptr;
 
   DIScope DS(Scope->getScopeNode());
 
-  SmallVector<DIE *, 8> Children;
-  DIE *ObjectPointer = NULL;
+  SmallVector<std::unique_ptr<DIE>, 8> Children;
+  DIE *ObjectPointer = nullptr;
   bool ChildrenCreated = false;
 
   // We try to create the scope DIE first, then the children DIEs. This will
   // avoid creating un-used children then removing them later when we find out
   // the scope DIE is null.
-  DIE *ScopeDIE = NULL;
+  DIE *ScopeDIE = nullptr;
   if (Scope->getInlinedAt())
     ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
   else if (DS.isSubprogram()) {
@@ -564,7 +574,7 @@ DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
   } else {
     // Early exit when we know the scope DIE is going to be null.
     if (isLexicalScopeDIENull(Scope))
-      return NULL;
+      return nullptr;
 
     // We create children here when we know the scope DIE is not going to be
     // null and the children will be added to the scope DIE.
@@ -577,10 +587,10 @@ DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
         std::equal_range(
             ScopesWithImportedEntities.begin(),
             ScopesWithImportedEntities.end(),
-            std::pair<const MDNode *, const MDNode *>(DS, (const MDNode *)0),
+            std::pair<const MDNode *, const MDNode *>(DS, nullptr),
             less_first());
     if (Children.empty() && Range.first == Range.second)
-      return NULL;
+      return nullptr;
     ScopeDIE = constructLexicalScopeDIE(TheCU, Scope);
     assert(ScopeDIE && "Scope DIE should not be null.");
     for (ImportedEntityMap::const_iterator i = Range.first; i != Range.second;
@@ -591,23 +601,23 @@ DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
   if (!ScopeDIE) {
     assert(Children.empty() &&
            "We create children only when the scope DIE is not null.");
-    return NULL;
+    return nullptr;
   }
   if (!ChildrenCreated)
     // We create children when the scope DIE is not null.
     ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children);
 
   // Add children
-  for (DIE *I : Children)
-    ScopeDIE->addChild(I);
+  for (auto &I : Children)
+    ScopeDIE->addChild(std::move(I));
 
-  if (DS.isSubprogram() && ObjectPointer != NULL)
-    TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer);
+  if (DS.isSubprogram() && ObjectPointer != nullptr)
+    TheCU.addDIEEntry(*ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
 
   return ScopeDIE;
 }
 
-void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE *D) const {
+void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
   if (!GenerateGnuPubSections)
     return;
 
@@ -634,10 +644,10 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
     Asm->OutStreamer.getContext().setMCLineTableCompilationDir(
         NewCU.getUniqueID(), CompilationDir);
 
-  NewCU.addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer());
-  NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+  NewCU.addString(*Die, dwarf::DW_AT_producer, DIUnit.getProducer());
+  NewCU.addUInt(*Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
                 DIUnit.getLanguage());
-  NewCU.addString(Die, dwarf::DW_AT_name, FN);
+  NewCU.addString(*Die, dwarf::DW_AT_name, FN);
 
   if (!useSplitDwarf()) {
     NewCU.initStmtList(DwarfLineSectionSym);
@@ -645,20 +655,20 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
     // 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.
     if (!CompilationDir.empty())
-      NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
+      NewCU.addString(*Die, dwarf::DW_AT_comp_dir, CompilationDir);
 
-    addGnuPubAttributes(NewCU, Die);
+    addGnuPubAttributes(NewCU, *Die);
   }
 
   if (DIUnit.isOptimized())
-    NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized);
+    NewCU.addFlag(*Die, dwarf::DW_AT_APPLE_optimized);
 
   StringRef Flags = DIUnit.getFlags();
   if (!Flags.empty())
-    NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
+    NewCU.addString(*Die, dwarf::DW_AT_APPLE_flags, Flags);
 
   if (unsigned RVer = DIUnit.getRunTimeVersion())
-    NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
+    NewCU.addUInt(*Die, dwarf::DW_AT_APPLE_major_runtime_vers,
                   dwarf::DW_FORM_data1, RVer);
 
   if (!FirstCU)
@@ -695,7 +705,7 @@ void DwarfDebug::constructSubprogramDIE(DwarfCompileUnit &TheCU,
     // class type.
     return;
 
-  DIE *SubprogramDie = TheCU.getOrCreateSubprogramDIE(SP);
+  DIE &SubprogramDie = *TheCU.getOrCreateSubprogramDIE(SP);
 
   // Expose as a global name.
   TheCU.addGlobalName(SP.getName(), SubprogramDie, resolve(SP.getContext()));
@@ -722,7 +732,7 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
   assert(Module.Verify() &&
          "Use one of the MDNode * overloads to handle invalid metadata");
   assert(Context && "Should always have a context for an imported_module");
-  DIE *IMDie = TheCU.createAndAddDIE(Module.getTag(), *Context, Module);
+  DIE &IMDie = TheCU.createAndAddDIE(Module.getTag(), *Context, Module);
   DIE *EntityDie;
   DIDescriptor Entity = resolve(Module.getEntity());
   if (Entity.isNameSpace())
@@ -736,7 +746,7 @@ void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
   TheCU.addSourceLine(IMDie, Module.getLineNumber(),
                       Module.getContext().getFilename(),
                       Module.getContext().getDirectory());
-  TheCU.addDIEEntry(IMDie, dwarf::DW_AT_import, EntityDie);
+  TheCU.addDIEEntry(IMDie, dwarf::DW_AT_import, *EntityDie);
   StringRef Name = Module.getName();
   if (!Name.empty())
     TheCU.addString(IMDie, dwarf::DW_AT_name, Name);
@@ -807,11 +817,11 @@ void DwarfDebug::beginModule() {
 void DwarfDebug::computeInlinedDIEs() {
   // Attach DW_AT_inline attribute with inlined subprogram DIEs.
   for (DIE *ISP : InlinedSubprogramDIEs)
-    FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
+    FirstCU->addUInt(*ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
 
   for (const auto &AI : AbstractSPDies) {
-    DIE *ISP = AI.second;
-    if (InlinedSubprogramDIEs.count(ISP))
+    DIE &ISP = *AI.second;
+    if (InlinedSubprogramDIEs.count(&ISP))
       continue;
     FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
   }
@@ -849,9 +859,8 @@ void DwarfDebug::collectDeadVariables() {
           DIVariable DV(Variables.getElement(vi));
           if (!DV.isVariable())
             continue;
-          DbgVariable NewVar(DV, NULL, this);
-          if (DIE *VariableDIE = SPCU->constructVariableDIE(NewVar, false))
-            SPDIE->addChild(VariableDIE);
+          DbgVariable NewVar(DV, nullptr, this);
+          SPDIE->addChild(SPCU->constructVariableDIE(NewVar, false));
         }
       }
     }
@@ -873,14 +882,14 @@ void DwarfDebug::finalizeModuleInfo() {
     TheU->constructContainingTypeDIEs();
 
     // Add CU specific attributes if we need to add any.
-    if (TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) {
+    if (TheU->getUnitDie().getTag() == dwarf::DW_TAG_compile_unit) {
       // If we're splitting the dwarf out now that we've got the entire
       // CU then add the dwo id to it.
       DwarfCompileUnit *SkCU =
           static_cast<DwarfCompileUnit *>(TheU->getSkeleton());
       if (useSplitDwarf()) {
         // Emit a unique identifier for this CU.
-        uint64_t ID = DIEHash(Asm).computeCUSignature(*TheU->getUnitDie());
+        uint64_t ID = DIEHash(Asm).computeCUSignature(TheU->getUnitDie());
         TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
                       dwarf::DW_FORM_data8, ID);
         SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
@@ -888,7 +897,7 @@ 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 (!InfoHolder.getAddressPool().isEmpty())
+        if (!AddrPool.isEmpty())
           addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(),
                           dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym,
                           DwarfAddrSectionSym);
@@ -948,7 +957,7 @@ void DwarfDebug::endSections() {
       // 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[NULL].push_back(SCU);
+      SectionMap[nullptr].push_back(SCU);
     }
   }
 
@@ -966,7 +975,7 @@ void DwarfDebug::endSections() {
   // Add terminating symbols for each section.
   for (unsigned ID = 0, E = Sections.size(); ID != E; ID++) {
     const MCSection *Section = Sections[ID];
-    MCSymbol *Sym = NULL;
+    MCSymbol *Sym = nullptr;
 
     if (Section) {
       // We can't call MCSection::getLabelEndName, as it's only safe to do so
@@ -979,7 +988,7 @@ void DwarfDebug::endSections() {
     }
 
     // Insert a final terminator.
-    SectionMap[Section].push_back(SymbolCU(NULL, Sym));
+    SectionMap[Section].push_back(SymbolCU(nullptr, Sym));
   }
 }
 
@@ -1019,8 +1028,7 @@ void DwarfDebug::endModule() {
     emitDebugAbbrevDWO();
     emitDebugLineDWO();
     // Emit DWO addresses.
-    InfoHolder.getAddressPool().emit(
-        *Asm, Asm->getObjFileLowering().getDwarfAddrSection());
+    AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
     emitDebugLocDWO();
   } else
     // Emit info into a debug loc section.
@@ -1044,7 +1052,7 @@ void DwarfDebug::endModule() {
   SPMap.clear();
 
   // Reset these for the next Module if we have one.
-  FirstCU = NULL;
+  FirstCU = nullptr;
 }
 
 // Find abstract variable, if any, associated with Var.
@@ -1059,9 +1067,9 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
 
   LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx));
   if (!Scope)
-    return NULL;
+    return nullptr;
 
-  AbsDbgVariable = new DbgVariable(Var, NULL, this);
+  AbsDbgVariable = new DbgVariable(Var, nullptr, this);
   addScopeVariable(Scope, AbsDbgVariable);
   AbstractVariables[Var] = AbsDbgVariable;
   return AbsDbgVariable;
@@ -1100,7 +1108,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(
     LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
 
     // If variable scope is not found then skip this variable.
-    if (Scope == 0)
+    if (!Scope)
       continue;
 
     DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VI.Loc);
@@ -1124,11 +1132,7 @@ static bool isDbgValueInDefinedReg(const MachineInstr *MI) {
 }
 
 // Get .debug_loc entry for the instruction range starting at MI.
-static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
-                                      const MCSymbol *FLabel,
-                                      const MCSymbol *SLabel,
-                                      const MachineInstr *MI,
-                                      DwarfCompileUnit *Unit) {
+static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
   const MDNode *Var = MI->getDebugVariable();
 
   assert(MI->getNumOperands() == 3);
@@ -1140,16 +1144,14 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
       MLoc.set(MI->getOperand(0).getReg());
     else
       MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
-    return DebugLocEntry(FLabel, SLabel, MLoc, Var, Unit);
+    return DebugLocEntry::Value(Var, MLoc);
   }
   if (MI->getOperand(0).isImm())
-    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm(), Var, Unit);
+    return DebugLocEntry::Value(Var, MI->getOperand(0).getImm());
   if (MI->getOperand(0).isFPImm())
-    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm(),
-                         Var, Unit);
+    return DebugLocEntry::Value(Var, MI->getOperand(0).getFPImm());
   if (MI->getOperand(0).isCImm())
-    return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm(),
-                         Var, Unit);
+    return DebugLocEntry::Value(Var, MI->getOperand(0).getCImm());
 
   llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!");
 }
@@ -1157,6 +1159,8 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
 // Find variables for each lexical scope.
 void
 DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
+  LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
+  DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
 
   // Grab the variable info that was squirreled away in the MMI side-table.
   collectVariableInfoFromMMITable(Processed);
@@ -1173,7 +1177,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
     const MachineInstr *MInsn = History.front();
 
     DIVariable DV(Var);
-    LexicalScope *Scope = NULL;
+    LexicalScope *Scope = nullptr;
     if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
         DISubprogram(DV.getContext()).describes(CurFn->getFunction()))
       Scope = LScopes.getCurrentFunctionScope();
@@ -1223,7 +1227,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
 
       // Compute the range for a register location.
       const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
-      const MCSymbol *SLabel = 0;
+      const MCSymbol *SLabel = nullptr;
 
       if (HI + 1 == HE)
         // If Begin is the last instruction in History then its value is valid
@@ -1244,23 +1248,20 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
       }
 
       // The value is valid until the next DBG_VALUE or clobber.
-      LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
-      DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
-      DebugLocEntry Loc = getDebugLocEntry(Asm, FLabel, SLabel, Begin, TheCU);
+      DebugLocEntry Loc(FLabel, SLabel, getDebugLocValue(Begin), TheCU);
       if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc))
         DebugLoc.push_back(std::move(Loc));
     }
   }
 
   // Collect info for variables that were optimized out.
-  LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
   DIArray Variables = DISubprogram(FnScope->getScopeNode()).getVariables();
   for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) {
     DIVariable DV(Variables.getElement(i));
     if (!DV || !DV.isVariable() || !Processed.insert(DV))
       continue;
     if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
-      addScopeVariable(Scope, new DbgVariable(DV, NULL, this));
+      addScopeVariable(Scope, new DbgVariable(DV, nullptr, this));
   }
 }
 
@@ -1297,7 +1298,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
         const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
         recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
       } else
-        recordSourceLine(0, 0, 0, 0);
+        recordSourceLine(0, 0, nullptr, 0);
     }
   }
 
@@ -1326,11 +1327,11 @@ void DwarfDebug::endInstruction() {
   // Don't create a new label after DBG_VALUE instructions.
   // They don't generate code.
   if (!CurMI->isDebugValue())
-    PrevLabel = 0;
+    PrevLabel = nullptr;
 
   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
       LabelsAfterInsn.find(CurMI);
-  CurMI = 0;
+  CurMI = nullptr;
 
   // No label needed.
   if (I == LabelsAfterInsn.end())
@@ -1497,7 +1498,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
             if (!Var)
               continue;
             // Reg is now clobbered.
-            LiveUserVar[Reg] = 0;
+            LiveUserVar[Reg] = nullptr;
 
             // Was MD last defined by a DBG_VALUE referring to Reg?
             DbgValueHistoryMap::iterator HistI = DbgValues.find(Var);
@@ -1603,7 +1604,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   // Every beginFunction(MF) call should be followed by an endFunction(MF) call,
   // though the beginFunction may not be called at all.
   // We should handle both cases.
-  if (CurFn == 0)
+  if (!CurFn)
     CurFn = MF;
   else
     assert(CurFn == MF);
@@ -1615,7 +1616,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
     // previously used section to nullptr.
     PrevSection = nullptr;
     PrevCU = nullptr;
-    CurFn = 0;
+    CurFn = nullptr;
     return;
   }
 
@@ -1650,14 +1651,14 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
         if (AbstractVariables.lookup(CleanDV))
           continue;
         if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
-          addScopeVariable(Scope, new DbgVariable(DV, NULL, this));
+          addScopeVariable(Scope, new DbgVariable(DV, nullptr, this));
       }
     }
     if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0)
       constructScopeDIE(TheCU, AScope);
   }
 
-  DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope);
+  DIE &CurFnDIE = *constructScopeDIE(TheCU, FnScope);
   if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn))
     TheCU.addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
 
@@ -1677,8 +1678,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   AbstractVariables.clear();
   LabelsBeforeInsn.clear();
   LabelsAfterInsn.clear();
-  PrevLabel = NULL;
-  CurFn = 0;
+  PrevLabel = nullptr;
+  CurFn = nullptr;
 }
 
 // Register a source line with debug info. Returns the  unique label that was
@@ -1857,97 +1858,52 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
 
 // Emit visible names into a hashed accelerator table section.
 void DwarfDebug::emitAccelNames() {
-  DwarfAccelTable AT(
-      DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  for (const auto &TheU : getUnits()) {
-    for (const auto &GI : TheU->getAccelNames()) {
-      StringRef Name = GI.getKey();
-      for (const DIE *D : GI.second)
-        AT.AddName(Name, D);
-    }
-  }
-
-  AT.FinalizeTable(Asm, "Names");
+  AccelNames.FinalizeTable(Asm, "Names");
   Asm->OutStreamer.SwitchSection(
       Asm->getObjFileLowering().getDwarfAccelNamesSection());
   MCSymbol *SectionBegin = Asm->GetTempSymbol("names_begin");
   Asm->OutStreamer.EmitLabel(SectionBegin);
 
   // Emit the full data.
-  AT.Emit(Asm, SectionBegin, &InfoHolder);
+  AccelNames.Emit(Asm, SectionBegin, &InfoHolder);
 }
 
 // Emit objective C classes and categories into a hashed accelerator table
 // section.
 void DwarfDebug::emitAccelObjC() {
-  DwarfAccelTable AT(
-      DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  for (const auto &TheU : getUnits()) {
-    for (const auto &GI : TheU->getAccelObjC()) {
-      StringRef Name = GI.getKey();
-      for (const DIE *D : GI.second)
-        AT.AddName(Name, D);
-    }
-  }
-
-  AT.FinalizeTable(Asm, "ObjC");
+  AccelObjC.FinalizeTable(Asm, "ObjC");
   Asm->OutStreamer.SwitchSection(
       Asm->getObjFileLowering().getDwarfAccelObjCSection());
   MCSymbol *SectionBegin = Asm->GetTempSymbol("objc_begin");
   Asm->OutStreamer.EmitLabel(SectionBegin);
 
   // Emit the full data.
-  AT.Emit(Asm, SectionBegin, &InfoHolder);
+  AccelObjC.Emit(Asm, SectionBegin, &InfoHolder);
 }
 
 // Emit namespace dies into a hashed accelerator table.
 void DwarfDebug::emitAccelNamespaces() {
-  DwarfAccelTable AT(
-      DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  for (const auto &TheU : getUnits()) {
-    for (const auto &GI : TheU->getAccelNamespace()) {
-      StringRef Name = GI.getKey();
-      for (const DIE *D : GI.second)
-        AT.AddName(Name, D);
-    }
-  }
-
-  AT.FinalizeTable(Asm, "namespac");
+  AccelNamespace.FinalizeTable(Asm, "namespac");
   Asm->OutStreamer.SwitchSection(
       Asm->getObjFileLowering().getDwarfAccelNamespaceSection());
   MCSymbol *SectionBegin = Asm->GetTempSymbol("namespac_begin");
   Asm->OutStreamer.EmitLabel(SectionBegin);
 
   // Emit the full data.
-  AT.Emit(Asm, SectionBegin, &InfoHolder);
+  AccelNamespace.Emit(Asm, SectionBegin, &InfoHolder);
 }
 
 // Emit type dies into a hashed accelerator table.
 void DwarfDebug::emitAccelTypes() {
-  std::vector<DwarfAccelTable::Atom> Atoms;
-  Atoms.push_back(
-      DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  Atoms.push_back(
-      DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2));
-  Atoms.push_back(
-      DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1));
-  DwarfAccelTable AT(Atoms);
-  for (const auto &TheU : getUnits()) {
-    for (const auto &GI : TheU->getAccelTypes()) {
-      StringRef Name = GI.getKey();
-      for (const auto &DI : GI.second)
-        AT.AddName(Name, DI.first, DI.second);
-    }
-  }
 
-  AT.FinalizeTable(Asm, "types");
+  AccelTypes.FinalizeTable(Asm, "types");
   Asm->OutStreamer.SwitchSection(
       Asm->getObjFileLowering().getDwarfAccelTypesSection());
   MCSymbol *SectionBegin = Asm->GetTempSymbol("types_begin");
   Asm->OutStreamer.EmitLabel(SectionBegin);
 
   // Emit the full data.
-  AT.Emit(Asm, SectionBegin, &InfoHolder);
+  AccelTypes.Emit(Asm, SectionBegin, &InfoHolder);
 }
 
 // Public name handling.
@@ -1973,8 +1929,8 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,
   // look for that now.
   DIEValue *SpecVal = Die->findAttribute(dwarf::DW_AT_specification);
   if (SpecVal) {
-    DIE *SpecDIE = cast<DIEEntry>(SpecVal)->getEntry();
-    if (SpecDIE->findAttribute(dwarf::DW_AT_external))
+    DIE &SpecDIE = cast<DIEEntry>(SpecVal)->getEntry();
+    if (SpecDIE.findAttribute(dwarf::DW_AT_external))
       Linkage = dwarf::GIEL_EXTERNAL;
   } else if (Die->findAttribute(dwarf::DW_AT_external))
     Linkage = dwarf::GIEL_EXTERNAL;
@@ -2094,19 +2050,22 @@ void DwarfDebug::emitDebugStr() {
 
 void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
                                    const DebugLocEntry &Entry) {
-  DIVariable DV(Entry.getVariable());
-  if (Entry.isInt()) {
+  assert(Entry.getValues().size() == 1 &&
+        "multi-value entries are not supported yet.");
+  const DebugLocEntry::Value Value = Entry.getValues()[0];
+  DIVariable DV(Value.getVariable());
+  if (Value.isInt()) {
     DIBasicType BTy(resolve(DV.getType()));
     if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
                          BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
       Streamer.EmitInt8(dwarf::DW_OP_consts, "DW_OP_consts");
-      Streamer.EmitSLEB128(Entry.getInt());
+      Streamer.EmitSLEB128(Value.getInt());
     } else {
       Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu");
-      Streamer.EmitULEB128(Entry.getInt());
+      Streamer.EmitULEB128(Value.getInt());
     }
-  } else if (Entry.isLocation()) {
-    MachineLocation Loc = Entry.getLoc();
+  } else if (Value.isLocation()) {
+    MachineLocation Loc = Value.getLoc();
     if (!DV.hasComplexAddress())
       // Regular entry.
       Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
@@ -2205,7 +2164,7 @@ void DwarfDebug::emitDebugLocDWO() {
       // 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 = InfoHolder.getAddressPool().getIndex(Entry.getBeginSym());
+      unsigned idx = AddrPool.getIndex(Entry.getBeginSym());
       Asm->EmitULEB128(idx);
       Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4);
 
@@ -2264,11 +2223,11 @@ void DwarfDebug::emitDebugARanges() {
 
     // If we have no section (e.g. common), just write out
     // individual spans for each symbol.
-    if (Section == NULL) {
+    if (!Section) {
       for (const SymbolCU &Cur : List) {
         ArangeSpan Span;
         Span.Start = Cur.Sym;
-        Span.End = NULL;
+        Span.End = nullptr;
         if (Cur.CU)
           Spans[Cur.CU].push_back(Span);
       }
@@ -2388,8 +2347,15 @@ void DwarfDebug::emitDebugRanges() {
         const MCSymbol *End = Range.getEnd();
         assert(Begin && "Range without a begin symbol?");
         assert(End && "Range without an end symbol?");
-        Asm->OutStreamer.EmitSymbolValue(Begin, Size);
-        Asm->OutStreamer.EmitSymbolValue(End, Size);
+        if (TheCU->getRanges().size() == 1) {
+          // Grab the begin symbol from the first range as our base.
+          const MCSymbol *Base = TheCU->getRanges()[0].getStart();
+          Asm->EmitLabelDifference(Begin, Base, Size);
+          Asm->EmitLabelDifference(End, Base, Size);
+        } else {
+          Asm->OutStreamer.EmitSymbolValue(Begin, Size);
+          Asm->OutStreamer.EmitSymbolValue(End, Size);
+        }
       }
 
       // And terminate the list with two 0 values.
@@ -2418,7 +2384,7 @@ void DwarfDebug::emitDebugRanges() {
 
 // DWARF5 Experimental Separate Dwarf emitters.
 
-void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE *Die,
+void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
                                   std::unique_ptr<DwarfUnit> NewU) {
   NewU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name,
                        U.getCUNode().getSplitDebugFilename());
@@ -2445,7 +2411,7 @@ DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {
 
   NewCU.initStmtList(DwarfLineSectionSym);
 
-  initSkeletonUnit(CU, Die, std::move(OwnedUnit));
+  initSkeletonUnit(CU, *Die, std::move(OwnedUnit));
 
   return NewCU;
 }
@@ -2461,11 +2427,11 @@ DwarfTypeUnit &DwarfDebug::constructSkeletonTU(DwarfTypeUnit &TU) {
                                               this, &SkeletonHolder);
   DwarfTypeUnit &NewTU = *OwnedUnit;
   NewTU.setTypeSignature(TU.getTypeSignature());
-  NewTU.setType(NULL);
+  NewTU.setType(nullptr);
   NewTU.initSection(
       Asm->getObjFileLowering().getDwarfTypesSection(TU.getTypeSignature()));
 
-  initSkeletonUnit(TU, Die, std::move(OwnedUnit));
+  initSkeletonUnit(TU, *Die, std::move(OwnedUnit));
   return NewTU;
 }
 
@@ -2512,14 +2478,25 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
   return &SplitTypeUnitFileTable;
 }
 
+static uint64_t makeTypeSignature(StringRef Identifier) {
+  MD5 Hash;
+  Hash.update(Identifier);
+  // ... take the least significant 8 bytes and return those. Our MD5
+  // implementation always returns its results in little endian, swap bytes
+  // appropriately.
+  MD5::MD5Result Result;
+  Hash.final(Result);
+  return *reinterpret_cast<support::ulittle64_t *>(Result + 8);
+}
+
 void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
-                                      StringRef Identifier, DIE *RefDie,
+                                      StringRef Identifier, DIE &RefDie,
                                       DICompositeType CTy) {
-  // 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.
-  CU.addFlag(RefDie, dwarf::DW_AT_declaration);
+  // 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.
+  if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
+    return;
 
   const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy];
   if (TU) {
@@ -2527,42 +2504,67 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
     return;
   }
 
+  bool TopLevelType = TypeUnitsUnderConstruction.empty();
+  AddrPool.resetUsedFlag();
+
   DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
   auto OwnedUnit =
       make_unique<DwarfTypeUnit>(InfoHolder.getUnits().size(), UnitDie, CU, Asm,
                                  this, &InfoHolder, getDwoLineTable(CU));
   DwarfTypeUnit &NewTU = *OwnedUnit;
   TU = &NewTU;
-  InfoHolder.addUnit(std::move(OwnedUnit));
+  TypeUnitsUnderConstruction.push_back(std::make_pair(std::move(OwnedUnit), CTy));
 
-  NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+  NewTU.addUInt(*UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
                 CU.getLanguage());
 
-  MD5 Hash;
-  Hash.update(Identifier);
-  // ... take the least significant 8 bytes and return those. Our MD5
-  // implementation always returns its results in little endian, swap bytes
-  // appropriately.
-  MD5::MD5Result Result;
-  Hash.final(Result);
-  uint64_t Signature = *reinterpret_cast<support::ulittle64_t *>(Result + 8);
+  uint64_t Signature = makeTypeSignature(Identifier);
   NewTU.setTypeSignature(Signature);
-  if (useSplitDwarf())
-    NewTU.setSkeleton(constructSkeletonTU(NewTU));
-  else
-    CU.applyStmtList(*UnitDie);
 
-  NewTU.setType(NewTU.createTypeDIE(CTy));
+  if (!useSplitDwarf())
+    CU.applyStmtList(*UnitDie);
 
   NewTU.initSection(
       useSplitDwarf()
           ? Asm->getObjFileLowering().getDwarfTypesDWOSection(Signature)
           : Asm->getObjFileLowering().getDwarfTypesSection(Signature));
 
+  NewTU.setType(NewTU.createTypeDIE(CTy));
+
+  if (TopLevelType) {
+    auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
+    TypeUnitsUnderConstruction.clear();
+
+    // Types referencing entries in the address table cannot be placed in type
+    // units.
+    if (AddrPool.hasBeenUsed()) {
+
+      // Remove all the types built while building this type.
+      // This is pessimistic as some of these types might not be dependent on
+      // the type that used an address.
+      for (const auto &TU : TypeUnitsToAdd)
+        DwarfTypeUnits.erase(TU.second);
+
+      // Construct this type in the CU directly.
+      // 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);
+      return;
+    }
+
+    // If the type wasn't dependent on fission addresses, finish adding the type
+    // and all its dependent types.
+    for (auto &TU : TypeUnitsToAdd) {
+      if (useSplitDwarf())
+        TU.first->setSkeleton(constructSkeletonTU(*TU.first));
+      InfoHolder.addUnit(std::move(TU.first));
+    }
+  }
   CU.addDIETypeSignature(RefDie, NewTU);
 }
 
-void DwarfDebug::attachLowHighPC(DwarfCompileUnit &Unit, DIE *D,
+void DwarfDebug::attachLowHighPC(DwarfCompileUnit &Unit, DIE &D,
                                  MCSymbol *Begin, MCSymbol *End) {
   Unit.addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
   if (DwarfVersion < 4)
@@ -2570,3 +2572,35 @@ void DwarfDebug::attachLowHighPC(DwarfCompileUnit &Unit, DIE *D,
   else
     Unit.addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
 }
+
+// Accelerator table mutators - add each name along with its companion
+// DIE to the proper table while ensuring that the name that we're going
+// to reference is in the string table. We do this since the names we
+// add may not only be identical to the names in the DIE.
+void DwarfDebug::addAccelName(StringRef Name, const DIE &Die) {
+  if (!useDwarfAccelTables())
+    return;
+  AccelNames.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
+                     &Die);
+}
+
+void DwarfDebug::addAccelObjC(StringRef Name, const DIE &Die) {
+  if (!useDwarfAccelTables())
+    return;
+  AccelObjC.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
+                    &Die);
+}
+
+void DwarfDebug::addAccelNamespace(StringRef Name, const DIE &Die) {
+  if (!useDwarfAccelTables())
+    return;
+  AccelNamespace.AddName(Name, InfoHolder.getStringPool().getSymbol(*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);
+}