Reland 196270 "Generalize debug info / EH emission in AsmPrinter"
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DwarfDebug.cpp
index 90f370ccf7161be63cfdf2899d4cf57d0f138387..010dcdf05556a9a687d99055dafefd2f8cfc86a9 100644 (file)
@@ -16,7 +16,7 @@
 #include "DIE.h"
 #include "DIEHash.h"
 #include "DwarfAccelTable.h"
-#include "DwarfCompileUnit.h"
+#include "DwarfUnit.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
@@ -185,8 +185,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
     : Asm(A), MMI(Asm->MMI), FirstCU(0),
       AbbreviationsSet(InitAbbreviationsSetSize),
       SourceIdMap(DIEValueAllocator), PrevLabel(NULL), GlobalCUIndexCount(0),
-      InfoHolder(A, &AbbreviationsSet, Abbreviations, "info_string",
-                 DIEValueAllocator),
+      GlobalRangeCount(0), InfoHolder(A, &AbbreviationsSet, Abbreviations,
+                                      "info_string", DIEValueAllocator),
       SkeletonAbbrevSet(InitAbbreviationsSetSize),
       SkeletonHolder(A, &SkeletonAbbrevSet, SkeletonAbbrevs, "skel_string",
                      DIEValueAllocator) {
@@ -197,6 +197,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
   DwarfAddrSectionSym = 0;
   DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0;
   FunctionBeginSym = FunctionEndSym = 0;
+  CurFn = 0; CurMI = 0;
 
   // Turn on accelerator tables for Darwin by default, pubnames by
   // default for non-Darwin, and handle split dwarf.
@@ -241,8 +242,8 @@ static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section,
 }
 
 DwarfUnits::~DwarfUnits() {
-  for (SmallVectorImpl<CompileUnit *>::iterator I = CUs.begin(), E = CUs.end();
-       I != E; ++I)
+  for (SmallVectorImpl<Unit *>::iterator I = CUs.begin(), E = CUs.end(); I != E;
+       ++I)
     delete *I;
 }
 
@@ -341,26 +342,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(CompileUnit *TheCU, DISubprogram SP, DIE *Die) {
+static void addSubprogramNames(Unit *TheU, DISubprogram SP, DIE *Die) {
   if (!SP.isDefinition())
     return;
-  TheCU->addAccelName(SP.getName(), Die);
+  TheU->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())
-    TheCU->addAccelName(SP.getLinkageName(), Die);
+    TheU->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);
-    TheCU->addAccelObjC(Class, Die);
+    TheU->addAccelObjC(Class, Die);
     if (Category != "")
-      TheCU->addAccelObjC(Category, Die);
+      TheU->addAccelObjC(Category, Die);
     // Also add the base method name to the name table.
-    TheCU->addAccelName(getObjCMethodName(SP.getName()), Die);
+    TheU->addAccelName(getObjCMethodName(SP.getName()), Die);
   }
 }
 
@@ -390,7 +391,8 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) {
   // concrete DIE twice.
   if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) {
     // Pick up abstract subprogram DIE.
-    SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getCUDie());
+    SPDie =
+        SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getUnitDie());
     SPCU->addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, AbsSPDIE);
   } else {
     DISubprogram SPDecl = SP.getFunctionDeclaration();
@@ -421,19 +423,19 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, DISubprogram SP) {
               SPCU->addDIEEntry(SPDie, dwarf::DW_AT_object_pointer, Arg);
           }
         DIE *SPDeclDie = SPDie;
-        SPDie =
-            SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getCUDie());
+        SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
+                                      *SPCU->getUnitDie());
         SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, SPDeclDie);
       }
     }
   }
 
-  SPCU->addLabelAddress(
-      SPDie, dwarf::DW_AT_low_pc,
-      Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
-  SPCU->addLabelAddress(
-      SPDie, dwarf::DW_AT_high_pc,
-      Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
+  MCSymbol *FuncBegin =
+      Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber());
+  MCSymbol *FuncEnd = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber());
+  SPCU->addLabelAddress(SPDie, dwarf::DW_AT_low_pc, FuncBegin);
+  SPCU->addLabelAddress(SPDie, dwarf::DW_AT_high_pc, FuncEnd);
+
   const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
   MachineLocation Location(RI->getFrameRegister(*Asm->MF));
   SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
@@ -466,6 +468,25 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) {
   return !End;
 }
 
+void DwarfDebug::addScopeRangeList(CompileUnit *TheCU, DIE *ScopeDIE,
+                                   const SmallVectorImpl<InsnRange> &Range) {
+  // Emit offset in .debug_range as a relocatable label. emitDIE will handle
+  // emitting it appropriately.
+  TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
+                         Asm->GetTempSymbol("debug_ranges", GlobalRangeCount));
+  RangeSpanList *List = new RangeSpanList(GlobalRangeCount++);
+  for (SmallVectorImpl<InsnRange>::const_iterator RI = Range.begin(),
+                                                  RE = Range.end();
+       RI != RE; ++RI) {
+    RangeSpan Span(getLabelBeforeInsn(RI->first),
+                   getLabelAfterInsn(RI->second));
+    List->addRange(Span);
+  }
+
+  // Add the range list to the set of ranges to be emitted.
+  TheCU->addRangeList(List);
+}
+
 // Construct new DW_TAG_lexical_block for this scope and attach
 // DW_AT_low_pc/DW_AT_high_pc labels.
 DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
@@ -477,30 +498,16 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
   if (Scope->isAbstractScope())
     return ScopeDIE;
 
-  const SmallVectorImpl<InsnRange> &Ranges = Scope->getRanges();
-  // If we have multiple ranges, emit them into the range section.
-  if (Ranges.size() > 1) {
-    // .debug_range section has not been laid out yet. Emit offset in
-    // .debug_range as a relocatable label. emitDIE will handle
-    // emitting it appropriately.
-    unsigned Offset = DebugRangeSymbols.size();
-    TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
-                           Asm->GetTempSymbol("debug_ranges", Offset));
-    for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
-                                                    RE = Ranges.end();
-         RI != RE; ++RI) {
-      DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
-      DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
-    }
+  const SmallVectorImpl<InsnRange> &ScopeRanges = Scope->getRanges();
 
-    // Terminate the range list.
-    DebugRangeSymbols.push_back(NULL);
-    DebugRangeSymbols.push_back(NULL);
+  // If we have multiple ranges, emit them into the range section.
+  if (ScopeRanges.size() > 1) {
+    addScopeRangeList(TheCU, ScopeDIE, ScopeRanges);
     return ScopeDIE;
   }
 
   // Construct the address range for this DIE.
-  SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin();
+  SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
   MCSymbol *Start = getLabelBeforeInsn(RI->first);
   MCSymbol *End = getLabelAfterInsn(RI->second);
   assert(End && "End label should not be null!");
@@ -518,8 +525,8 @@ DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU,
 // represent this concrete inlined copy of the function.
 DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
                                           LexicalScope *Scope) {
-  const SmallVectorImpl<InsnRange> &Ranges = Scope->getRanges();
-  assert(Ranges.empty() == false &&
+  const SmallVectorImpl<InsnRange> &ScopeRanges = Scope->getRanges();
+  assert(ScopeRanges.empty() == false &&
          "LexicalScope does not have instruction markers!");
 
   if (!Scope->getScopeNode())
@@ -535,23 +542,11 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU,
   DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
   TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, OriginDIE);
 
-  if (Ranges.size() > 1) {
-    // .debug_range section has not been laid out yet. Emit offset in
-    // .debug_range as a relocatable label. emitDIE will handle
-    // emitting it appropriately.
-    unsigned Offset = DebugRangeSymbols.size();
-    TheCU->addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges,
-                           Asm->GetTempSymbol("debug_ranges", Offset));
-    for (SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin(),
-                                                    RE = Ranges.end();
-         RI != RE; ++RI) {
-      DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first));
-      DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second));
-    }
-    DebugRangeSymbols.push_back(NULL);
-    DebugRangeSymbols.push_back(NULL);
-  } else {
-    SmallVectorImpl<InsnRange>::const_iterator RI = Ranges.begin();
+  // If we have multiple ranges, emit them into the range section.
+  if (ScopeRanges.size() > 1)
+    addScopeRangeList(TheCU, ScopeDIE, ScopeRanges);
+  else {
+    SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
     MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
     MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
 
@@ -685,9 +680,6 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) {
   if (DS.isSubprogram() && ObjectPointer != NULL)
     TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer);
 
-  if (DS.isSubprogram())
-    TheCU->addPubTypes(DISubprogram(DS));
-
   return ScopeDIE;
 }
 
@@ -1004,7 +996,7 @@ void DwarfDebug::collectDeadVariables() {
           continue;
 
         // Construct subprogram DIE and add variables DIEs.
-        CompileUnit *SPCU = CUMap.lookup(TheCU);
+        CompileUnit *SPCU = static_cast<CompileUnit *>(CUMap.lookup(TheCU));
         assert(SPCU && "Unable to find Compile Unit!");
         // FIXME: See the comment in constructSubprogramDIE about duplicate
         // subprogram DIEs.
@@ -1052,7 +1044,7 @@ static bool isContainedInAnonNamespace(DIE *Die) {
 
 /// Test if the current CU language is C++ and that we have
 /// a named type that is not contained in an anonymous namespace.
-static bool shouldAddODRHash(CompileUnit *CU, DIE *Die) {
+static bool shouldAddODRHash(TypeUnit *CU, DIE *Die) {
   return CU->getLanguage() == dwarf::DW_LANG_C_plus_plus &&
          getDIEStringAttr(Die, dwarf::DW_AT_name) != "" &&
          !isContainedInAnonNamespace(Die);
@@ -1066,29 +1058,30 @@ void DwarfDebug::finalizeModuleInfo() {
   computeInlinedDIEs();
 
   // Handle anything that needs to be done on a per-cu basis.
-  for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),
-                                                         CUE = CUMap.end();
-       CUI != CUE; ++CUI) {
-    CompileUnit *TheCU = CUI->second;
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
+       I != E; ++I) {
+    Unit *TheU = *I;
     // Emit DW_AT_containing_type attribute to connect types with their
     // vtable holding type.
-    TheCU->constructContainingTypeDIEs();
+    TheU->constructContainingTypeDIEs();
 
     // If we're splitting the dwarf out now that we've got the entire
     // CU then construct a skeleton CU based upon it.
-    if (useSplitDwarf()) {
+    if (useSplitDwarf() &&
+        TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) {
       uint64_t ID = 0;
       if (GenerateCUHash) {
         DIEHash CUHash;
-        ID = CUHash.computeCUSignature(*TheCU->getCUDie());
+        ID = CUHash.computeCUSignature(*TheU->getUnitDie());
       }
       // This should be a unique identifier when we want to build .dwp files.
-      TheCU->addUInt(TheCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
-                     dwarf::DW_FORM_data8, ID);
+      TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
+                    dwarf::DW_FORM_data8, ID);
       // Now construct the skeleton CU associated.
-      CompileUnit *SkCU = constructSkeletonCU(TheCU);
+      CompileUnit *SkCU = constructSkeletonCU(static_cast<CompileUnit *>(TheU));
       // This should be a unique identifier when we want to build .dwp files.
-      SkCU->addUInt(SkCU->getCUDie(), dwarf::DW_AT_GNU_dwo_id,
+      SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
                     dwarf::DW_FORM_data8, ID);
     }
   }
@@ -1152,6 +1145,8 @@ void DwarfDebug::endSections() {
 
 // Emit all Dwarf sections that should come after the content.
 void DwarfDebug::endModule() {
+  assert(CurFn == 0);
+  assert(CurMI == 0);
 
   if (!FirstCU)
     return;
@@ -1233,8 +1228,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
 }
 
 // If Var is a current function argument then add it to CurrentFnArguments list.
-bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF,
-                                      DbgVariable *Var, LexicalScope *Scope) {
+bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) {
   if (!LScopes.isCurrentFunctionScope(Scope))
     return false;
   DIVariable DV = Var->getVariable();
@@ -1246,7 +1240,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF,
 
   size_t Size = CurrentFnArguments.size();
   if (Size == 0)
-    CurrentFnArguments.resize(MF->getFunction()->arg_size());
+    CurrentFnArguments.resize(CurFn->getFunction()->arg_size());
   // llvm::Function argument size is not good indicator of how many
   // arguments does the function have at source level.
   if (ArgNo > Size)
@@ -1257,7 +1251,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF,
 
 // Collect variable information from side table maintained by MMI.
 void DwarfDebug::collectVariableInfoFromMMITable(
-    const MachineFunction *MF, SmallPtrSet<const MDNode *, 16> &Processed) {
+    SmallPtrSet<const MDNode *, 16> &Processed) {
   MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
   for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
                                                          VE = VMap.end();
@@ -1278,7 +1272,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(
     DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second);
     DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this);
     RegVar->setFrameIndex(VP.first);
-    if (!addCurrentFnArgument(MF, RegVar, Scope))
+    if (!addCurrentFnArgument(RegVar, Scope))
       addScopeVariable(Scope, RegVar);
     if (AbsDbgVariable)
       AbsDbgVariable->setFrameIndex(VP.first);
@@ -1325,11 +1319,10 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
 
 // Find variables for each lexical scope.
 void
-DwarfDebug::collectVariableInfo(const MachineFunction *MF,
-                                SmallPtrSet<const MDNode *, 16> &Processed) {
+DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
 
   // Grab the variable info that was squirreled away in the MMI side-table.
-  collectVariableInfoFromMMITable(MF, Processed);
+  collectVariableInfoFromMMITable(Processed);
 
   for (SmallVectorImpl<const MDNode *>::const_iterator
            UVI = UserVariables.begin(),
@@ -1349,7 +1342,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
     DIVariable DV(Var);
     LexicalScope *Scope = NULL;
     if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
-        DISubprogram(DV.getContext()).describes(MF->getFunction()))
+        DISubprogram(DV.getContext()).describes(CurFn->getFunction()))
       Scope = LScopes.getCurrentFunctionScope();
     else if (MDNode *IA = DV.getInlinedAt())
       Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA));
@@ -1363,7 +1356,7 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF,
     assert(MInsn->isDebugValue() && "History must begin with debug value");
     DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc());
     DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this);
-    if (!addCurrentFnArgument(MF, RegVar, Scope))
+    if (!addCurrentFnArgument(RegVar, Scope))
       addScopeVariable(Scope, RegVar);
     if (AbsVar)
       AbsVar->setMInsn(MInsn);
@@ -1445,6 +1438,8 @@ MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
 
 // Process beginning of an instruction.
 void DwarfDebug::beginInstruction(const MachineInstr *MI) {
+  assert(CurMI == 0);
+  CurMI = MI;
   // Check if source location changes, but ignore DBG_VALUE locations.
   if (!MI->isDebugValue()) {
     DebugLoc DL = MI->getDebugLoc();
@@ -1486,14 +1481,16 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
 }
 
 // Process end of an instruction.
-void DwarfDebug::endInstruction(const MachineInstr *MI) {
+void DwarfDebug::endInstruction() {
+  assert(CurMI != 0);
   // Don't create a new label after DBG_VALUE instructions.
   // They don't generate code.
-  if (!MI->isDebugValue())
+  if (!CurMI->isDebugValue())
     PrevLabel = 0;
 
   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
-      LabelsAfterInsn.find(MI);
+      LabelsAfterInsn.find(CurMI);
+  CurMI = 0;
 
   // No label needed.
   if (I == LabelsAfterInsn.end())
@@ -1573,6 +1570,7 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) {
 // Gather pre-function debug information.  Assumes being called immediately
 // after the function entry point has been emitted.
 void DwarfDebug::beginFunction(const MachineFunction *MF) {
+  CurFn = MF;
 
   // If there's no debug info for the function we're not going to do anything.
   if (!MMI->hasDebugInfo())
@@ -1800,8 +1798,19 @@ void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
 
 // Gather and emit post-function debug information.
 void DwarfDebug::endFunction(const MachineFunction *MF) {
-  if (!MMI->hasDebugInfo() || LScopes.empty())
+  // 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)
+    CurFn = MF;
+  else
+    assert(CurFn == MF);
+  assert(CurFn != 0);
+
+  if (!MMI->hasDebugInfo() || LScopes.empty()) {
+    CurFn = 0;
     return;
+  }
 
   // Define end label for subprogram.
   FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber());
@@ -1811,7 +1820,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
 
   SmallPtrSet<const MDNode *, 16> ProcessedVars;
-  collectVariableInfo(MF, ProcessedVars);
+  collectVariableInfo(ProcessedVars);
 
   LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
   CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
@@ -1845,7 +1854,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
 
   DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope);
 
-  if (!MF->getTarget().Options.DisableFramePointerElim(*MF))
+  if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn))
     TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
 
   // Clear debug info
@@ -1861,6 +1870,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
   LabelsBeforeInsn.clear();
   LabelsAfterInsn.clear();
   PrevLabel = NULL;
+  CurFn = 0;
 }
 
 // Register a source line with debug info. Returns the  unique label that was
@@ -1956,7 +1966,7 @@ void DwarfUnits::computeSizeAndOffsets() {
 
   // Iterate over each compile unit and set the size and offsets for each
   // DIE within each compile unit. All offsets are CU relative.
-  for (SmallVectorImpl<CompileUnit *>::iterator I = CUs.begin(), E = CUs.end();
+  for (SmallVectorImpl<Unit *>::const_iterator I = CUs.begin(), E = CUs.end();
        I != E; ++I) {
     (*I)->setDebugInfoOffset(SecOffset);
 
@@ -1966,7 +1976,7 @@ void DwarfUnits::computeSizeAndOffsets() {
 
     // EndOffset here is CU-relative, after laying out
     // all of the CU DIE.
-    unsigned EndOffset = computeSizeAndOffset((*I)->getCUDie(), Offset);
+    unsigned EndOffset = computeSizeAndOffset((*I)->getUnitDie(), Offset);
     SecOffset += EndOffset;
   }
 }
@@ -2133,24 +2143,24 @@ void DwarfUnits::emitUnits(DwarfDebug *DD, const MCSection *USection,
                            const MCSection *ASection,
                            const MCSymbol *ASectionSym) {
   Asm->OutStreamer.SwitchSection(USection);
-  for (SmallVectorImpl<CompileUnit *>::iterator I = CUs.begin(), E = CUs.end();
-       I != E; ++I) {
-    CompileUnit *TheCU = *I;
-    DIE *Die = TheCU->getCUDie();
+  for (SmallVectorImpl<Unit *>::iterator I = CUs.begin(), E = CUs.end(); I != E;
+       ++I) {
+    Unit *TheU = *I;
+    DIE *Die = TheU->getUnitDie();
 
     // Emit the compile units header.
-    Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol(USection->getLabelBeginName(),
-                                                  TheCU->getUniqueID()));
+    Asm->OutStreamer.EmitLabel(
+        Asm->GetTempSymbol(USection->getLabelBeginName(), TheU->getUniqueID()));
 
     // Emit size of content not including length itself
     Asm->OutStreamer.AddComment("Length of Unit");
-    Asm->EmitInt32(TheCU->getHeaderSize() + Die->getSize());
+    Asm->EmitInt32(TheU->getHeaderSize() + Die->getSize());
 
-    TheCU->emitHeader(ASection, ASectionSym);
+    TheU->emitHeader(ASection, ASectionSym);
 
     DD->emitDIE(Die, Abbreviations);
     Asm->OutStreamer.EmitLabel(
-        Asm->GetTempSymbol(USection->getLabelEndName(), TheCU->getUniqueID()));
+        Asm->GetTempSymbol(USection->getLabelEndName(), TheU->getUniqueID()));
   }
 }
 
@@ -2230,11 +2240,11 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
 void DwarfDebug::emitAccelNames() {
   DwarfAccelTable AT(
       DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
-                                                         E = CUMap.end();
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
        I != E; ++I) {
-    CompileUnit *TheCU = I->second;
-    const StringMap<std::vector<const DIE *> > &Names = TheCU->getAccelNames();
+    Unit *TheU = *I;
+    const StringMap<std::vector<const DIE *> > &Names = TheU->getAccelNames();
     for (StringMap<std::vector<const DIE *> >::const_iterator
              GI = Names.begin(),
              GE = Names.end();
@@ -2263,11 +2273,11 @@ void DwarfDebug::emitAccelNames() {
 void DwarfDebug::emitAccelObjC() {
   DwarfAccelTable AT(
       DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
-                                                         E = CUMap.end();
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
        I != E; ++I) {
-    CompileUnit *TheCU = I->second;
-    const StringMap<std::vector<const DIE *> > &Names = TheCU->getAccelObjC();
+    Unit *TheU = *I;
+    const StringMap<std::vector<const DIE *> > &Names = TheU->getAccelObjC();
     for (StringMap<std::vector<const DIE *> >::const_iterator
              GI = Names.begin(),
              GE = Names.end();
@@ -2295,12 +2305,12 @@ void DwarfDebug::emitAccelObjC() {
 void DwarfDebug::emitAccelNamespaces() {
   DwarfAccelTable AT(
       DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
-  for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
-                                                         E = CUMap.end();
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
        I != E; ++I) {
-    CompileUnit *TheCU = I->second;
+    Unit *TheU = *I;
     const StringMap<std::vector<const DIE *> > &Names =
-        TheCU->getAccelNamespace();
+        TheU->getAccelNamespace();
     for (StringMap<std::vector<const DIE *> >::const_iterator
              GI = Names.begin(),
              GE = Names.end();
@@ -2334,12 +2344,12 @@ void DwarfDebug::emitAccelTypes() {
   Atoms.push_back(
       DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1));
   DwarfAccelTable AT(Atoms);
-  for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
-                                                         E = CUMap.end();
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
        I != E; ++I) {
-    CompileUnit *TheCU = I->second;
+    Unit *TheU = *I;
     const StringMap<std::vector<std::pair<const DIE *, unsigned> > > &Names =
-        TheCU->getAccelTypes();
+        TheU->getAccelTypes();
     for (StringMap<
              std::vector<std::pair<const DIE *, unsigned> > >::const_iterator
              GI = Names.begin(),
@@ -2381,7 +2391,7 @@ void DwarfDebug::emitAccelTypes() {
 // reference in the pubname header doesn't change.
 
 /// computeIndexValue - Compute the gdb index value for the DIE and CU.
-static dwarf::PubIndexEntryDescriptor computeIndexValue(CompileUnit *CU,
+static dwarf::PubIndexEntryDescriptor computeIndexValue(Unit *CU,
                                                         const DIE *Die) {
   dwarf::GDBIndexEntryLinkage Linkage = dwarf::GIEL_STATIC;
 
@@ -2431,10 +2441,11 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) {
       GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
                : Asm->getObjFileLowering().getDwarfPubNamesSection();
 
-  typedef DenseMap<const MDNode *, CompileUnit *> CUMapType;
-  for (CUMapType::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) {
-    CompileUnit *TheCU = I->second;
-    unsigned ID = TheCU->getUniqueID();
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
+       I != E; ++I) {
+    Unit *TheU = *I;
+    unsigned ID = TheU->getUniqueID();
 
     // Start the dwarf pubnames section.
     Asm->OutStreamer.SwitchSection(PSec);
@@ -2442,7 +2453,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) {
     // Emit a label so we can reference the beginning of this pubname section.
     if (GnuStyle)
       Asm->OutStreamer.EmitLabel(
-          Asm->GetTempSymbol("gnu_pubnames", TheCU->getUniqueID()));
+          Asm->GetTempSymbol("gnu_pubnames", TheU->getUniqueID()));
 
     // Emit the header.
     Asm->OutStreamer.AddComment("Length of Public Names Info");
@@ -2464,7 +2475,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) {
                              4);
 
     // Emit the pubnames for this compilation unit.
-    const StringMap<const DIE *> &Globals = TheCU->getGlobalNames();
+    const StringMap<const DIE *> &Globals = TheU->getGlobalNames();
     for (StringMap<const DIE *>::const_iterator GI = Globals.begin(),
                                                 GE = Globals.end();
          GI != GE; ++GI) {
@@ -2475,7 +2486,7 @@ void DwarfDebug::emitDebugPubNames(bool GnuStyle) {
       Asm->EmitInt32(Entity->getOffset());
 
       if (GnuStyle) {
-        dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheCU, Entity);
+        dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity);
         Asm->OutStreamer.AddComment(
             Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " +
             dwarf::GDBIndexEntryLinkageString(Desc.Linkage));
@@ -2499,26 +2510,26 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) {
       GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
                : Asm->getObjFileLowering().getDwarfPubTypesSection();
 
-  for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
-                                                         E = CUMap.end();
+  for (SmallVectorImpl<Unit *>::const_iterator I = getUnits().begin(),
+                                               E = getUnits().end();
        I != E; ++I) {
-    CompileUnit *TheCU = I->second;
+    Unit *TheU = *I;
     // Start the dwarf pubtypes section.
     Asm->OutStreamer.SwitchSection(PSec);
 
     // Emit a label so we can reference the beginning of this pubtype section.
     if (GnuStyle)
       Asm->OutStreamer.EmitLabel(
-          Asm->GetTempSymbol("gnu_pubtypes", TheCU->getUniqueID()));
+          Asm->GetTempSymbol("gnu_pubtypes", TheU->getUniqueID()));
 
     // Emit the header.
     Asm->OutStreamer.AddComment("Length of Public Types Info");
     Asm->EmitLabelDifference(
-        Asm->GetTempSymbol("pubtypes_end", TheCU->getUniqueID()),
-        Asm->GetTempSymbol("pubtypes_begin", TheCU->getUniqueID()), 4);
+        Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID()),
+        Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID()), 4);
 
     Asm->OutStreamer.EmitLabel(
-        Asm->GetTempSymbol("pubtypes_begin", TheCU->getUniqueID()));
+        Asm->GetTempSymbol("pubtypes_begin", TheU->getUniqueID()));
 
     if (Asm->isVerbose())
       Asm->OutStreamer.AddComment("DWARF Version");
@@ -2526,16 +2537,16 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) {
 
     Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
     Asm->EmitSectionOffset(
-        Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()),
+        Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()),
         DwarfInfoSectionSym);
 
     Asm->OutStreamer.AddComment("Compilation Unit Length");
     Asm->EmitLabelDifference(
-        Asm->GetTempSymbol(ISec->getLabelEndName(), TheCU->getUniqueID()),
-        Asm->GetTempSymbol(ISec->getLabelBeginName(), TheCU->getUniqueID()), 4);
+        Asm->GetTempSymbol(ISec->getLabelEndName(), TheU->getUniqueID()),
+        Asm->GetTempSymbol(ISec->getLabelBeginName(), TheU->getUniqueID()), 4);
 
     // Emit the pubtypes.
-    const StringMap<const DIE *> &Globals = TheCU->getGlobalTypes();
+    const StringMap<const DIE *> &Globals = TheU->getGlobalTypes();
     for (StringMap<const DIE *>::const_iterator GI = Globals.begin(),
                                                 GE = Globals.end();
          GI != GE; ++GI) {
@@ -2547,7 +2558,7 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) {
       Asm->EmitInt32(Entity->getOffset());
 
       if (GnuStyle) {
-        dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheCU, Entity);
+        dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity);
         Asm->OutStreamer.AddComment(
             Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " +
             dwarf::GDBIndexEntryLinkageString(Desc.Linkage));
@@ -2564,7 +2575,7 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) {
     Asm->OutStreamer.AddComment("End Mark");
     Asm->EmitInt32(0);
     Asm->OutStreamer.EmitLabel(
-        Asm->GetTempSymbol("pubtypes_end", TheCU->getUniqueID()));
+        Asm->GetTempSymbol("pubtypes_end", TheU->getUniqueID()));
   }
 }
 
@@ -2768,7 +2779,7 @@ struct SymbolCUSorter {
   }
 };
 
-static bool CUSort(const CompileUnit *A, const CompileUnit *B) {
+static bool CUSort(const Unit *A, const Unit *B) {
   return (A->getUniqueID() < B->getUniqueID());
 }
 
@@ -2922,18 +2933,51 @@ void DwarfDebug::emitDebugRanges() {
   // Start the dwarf ranges section.
   Asm->OutStreamer.SwitchSection(
       Asm->getObjFileLowering().getDwarfRangesSection());
+
+  // Size for our labels.
   unsigned char Size = Asm->getDataLayout().getPointerSize();
-  for (uint32_t i = 0, e = DebugRangeSymbols.size(); i < e; ++i) {
-    // Only emit a symbol for every range pair for now.
-    // FIXME: Make this per range list.
-    if ((i % 2) == 0)
-      Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_ranges", i));
-
-    const MCSymbol *I = DebugRangeSymbols[i];
-    if (I)
-      Asm->OutStreamer.EmitSymbolValue(I, Size);
-    else
+
+  // Grab the specific ranges for the compile units in the module.
+  for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
+                                                         E = CUMap.end();
+       I != E; ++I) {
+    CompileUnit *TheCU = I->second;
+    unsigned ID = TheCU->getUniqueID();
+
+    // Emit a symbol so we can find the beginning of our ranges.
+    Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("gnu_ranges", ID));
+
+    // Iterate over the misc ranges for the compile units in the module.
+    const SmallVectorImpl<RangeSpanList *> &RangeLists = TheCU->getRangeLists();
+    for (SmallVectorImpl<RangeSpanList *>::const_iterator
+             I = RangeLists.begin(),
+             E = RangeLists.end();
+         I != E; ++I) {
+      RangeSpanList *List = *I;
+
+      // Emit a symbol so we can find the beginning of the range.
+      Asm->OutStreamer.EmitLabel(
+          Asm->GetTempSymbol("debug_ranges", List->getIndex()));
+
+      for (SmallVectorImpl<RangeSpan>::const_iterator
+               I = List->getRanges().begin(),
+               E = List->getRanges().end();
+           I != E; ++I) {
+        RangeSpan Range = *I;
+        // We occasionally have ranges without begin/end labels.
+        // FIXME: Verify and fix.
+        const MCSymbol *Begin = Range.getStart();
+        const MCSymbol *End = Range.getEnd();
+        Begin ? Asm->OutStreamer.EmitSymbolValue(Begin, Size)
+              : Asm->OutStreamer.EmitIntValue(0, Size);
+        End ? Asm->OutStreamer.EmitSymbolValue(End, Size)
+            : Asm->OutStreamer.EmitIntValue(0, Size);
+      }
+
+      // And terminate the list with two 0 values.
+      Asm->OutStreamer.EmitIntValue(0, Size);
       Asm->OutStreamer.EmitIntValue(0, Size);
+    }
   }
 }
 
@@ -3007,14 +3051,17 @@ CompileUnit *DwarfDebug::constructSkeletonCU(const CompileUnit *CU) {
           DwarfGnuPubTypesSectionSym);
   }
 
-  // Flag if we've emitted any ranges and their location for the compile unit.
-  if (DebugRangeSymbols.size()) {
+  // Attribute if we've emitted any ranges and their location for the compile unit.
+  if (CU->getRangeLists().size()) {
     if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
-      NewCU->addSectionLabel(Die, dwarf::DW_AT_GNU_ranges_base,
-                             DwarfDebugRangeSectionSym);
+      NewCU->addSectionLabel(
+          Die, dwarf::DW_AT_GNU_ranges_base,
+          Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()));
     else
-      NewCU->addUInt(Die, dwarf::DW_AT_GNU_ranges_base, dwarf::DW_FORM_data4,
-                     0);
+      NewCU->addSectionDelta(
+          Die, dwarf::DW_AT_GNU_ranges_base,
+          Asm->GetTempSymbol("gnu_ranges", NewCU->getUniqueID()),
+          DwarfDebugRangeSectionSym);
   }
 
   SkeletonHolder.addUnit(NewCU);
@@ -3056,8 +3103,11 @@ void DwarfDebug::emitDebugStrDWO() {
                          OffSec, StrSym);
 }
 
-void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {
-  DenseMap<const MDNode*, std::pair<uint64_t, SmallVectorImpl<DIE*>* > >::iterator I = TypeUnits.find(CTy);
+void DwarfDebug::addTypeUnitType(uint16_t Language, DIE *RefDie,
+                                 DICompositeType CTy) {
+  DenseMap<const MDNode *,
+           std::pair<uint64_t, SmallVectorImpl<DIE *> *> >::iterator I =
+      TypeUnits.find(CTy);
   SmallVector<DIE *, 8> References;
   References.push_back(RefDie);
   if (I != TypeUnits.end()) {
@@ -3067,12 +3117,10 @@ void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {
     }
   } else {
     DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
-    CompileUnit *NewCU =
-        new CompileUnit(GlobalCUIndexCount++, UnitDie,
-                        dwarf::DW_LANG_C_plus_plus, Asm, this, &InfoHolder);
-    CUDieMap.insert(std::make_pair(UnitDie, NewCU));
-    NewCU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
-                   dwarf::DW_LANG_C_plus_plus);
+    TypeUnit *NewTU = new TypeUnit(GlobalCUIndexCount++, UnitDie, Language, Asm,
+                                   this, &InfoHolder);
+    NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+                   Language);
 
     // Register the type in the TypeUnits map with a vector of references to be
     // populated whenever a reference is required.
@@ -3082,10 +3130,10 @@ void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {
     // Construct the type, this may, recursively, require more type units that
     // may in turn require this type again - in which case they will add DIEs to
     // the References vector.
-    DIE *Die = NewCU->createTypeDIE(CTy);
+    DIE *Die = NewTU->createTypeDIE(CTy);
 
-    if (GenerateODRHash && shouldAddODRHash(NewCU, Die))
-      NewCU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature,
+    if (GenerateODRHash && shouldAddODRHash(NewTU, Die))
+      NewTU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature,
                      dwarf::DW_FORM_data8,
                      DIEHash().computeDIEODRSignature(*Die));
     // FIXME: This won't handle circularly referential structures, as the DIE
@@ -3099,8 +3147,7 @@ void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {
     I->second.first = Signature;
     I->second.second = NULL;
 
-
-    InfoHolder.addUnit(NewCU);
+    InfoHolder.addUnit(NewTU);
   }
 
   // Populate all the signatures.