Index: include/llvm/MC/MCContext.h
===================================================================
--- include/llvm/MC/MCContext.h
+++ include/llvm/MC/MCContext.h
@@ -11,10 +11,12 @@
 #define LLVM_MC_MCCONTEXT_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/SectionKind.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Compiler.h"
@@ -123,11 +125,13 @@
     /// assembly source files.
     unsigned GenDwarfFileNumber;
 
-    /// The default initial text section that we generate dwarf debugging line
-    /// info for when generating dwarf assembly source files.
-    const MCSection *GenDwarfSection;
-    /// Symbols created for the start and end of this section.
-    MCSymbol *GenDwarfSectionStartSym, *GenDwarfSectionEndSym;
+    /// The sections that we generate dwarf debugging line info for when
+    /// generating dwarf assembly source files.
+    SetVector<const MCSection*> GenDwarfSections;
+    /// Symbols created for the start and end of each section, used for
+    /// generating the debug_aranges section
+    DenseMap<const MCSection*, MCSymbol*> GenDwarfSectionStartSyms;
+    DenseMap<const MCSection*, MCSymbol*> GenDwarfSectionEndSyms;
 
     /// The information gathered from labels that will have dwarf label
     /// entries when generating dwarf assembly source files.
@@ -141,6 +145,9 @@
     /// non-empty.
     StringRef DwarfDebugProducer;
 
+    /// The maximum version of dwarf that we should emit.
+    unsigned DwarfVersion;
+
     /// Honor temporary labels, this is useful for debugging semantic
     /// differences between temporary and non-temporary labels (primarily on
     /// Darwin).
@@ -371,15 +378,53 @@
     void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
     unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
     unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; }
-    const MCSection *getGenDwarfSection() { return GenDwarfSection; }
-    void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
-    MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }
-    void setGenDwarfSectionStartSym(MCSymbol *Sym) {
-      GenDwarfSectionStartSym = Sym;
+    SetVector<const MCSection *> &getGenDwarfSections() {
+      return GenDwarfSections;
+    }
+    void addGenDwarfSection(const MCSection *Sec) {
+      GenDwarfSections.insert(Sec);
+    }
+    void FinalizeDwarfSections(MCStreamer &MCOS) {
+      MCContext &context = MCOS.getContext();
+      SetVector<const MCSection *> InvalidSections;
+
+      for (SetVector<const MCSection *>::iterator sec =
+               GenDwarfSections.begin();
+           sec != GenDwarfSections.end(); ++sec) {
+        MCOS.SwitchSection(*sec);
+        if (MCOS.hasInstructions()) {
+          MCSymbol *SectionEndSym = context.CreateTempSymbol();
+          MCOS.EmitLabel(SectionEndSym);
+          context.setGenDwarfSectionEndSym(*sec, SectionEndSym);
+        } else {
+          InvalidSections.insert(*sec);
+        }
+      }
+
+      for (SetVector<const MCSection *>::iterator sec = InvalidSections.begin();
+           sec != InvalidSections.end(); ++sec) {
+        GenDwarfSections.remove(*sec);
+      }
+    }
+    MCSymbol *getGenDwarfSectionStartSym(const MCSection *Sec) {
+      DenseMap<const MCSection *, MCSymbol *>::iterator Sym =
+          GenDwarfSectionStartSyms.find(Sec);
+      if (Sym != GenDwarfSectionStartSyms.end())
+        return Sym->second;
+      return NULL;
     }
-    MCSymbol *getGenDwarfSectionEndSym() { return GenDwarfSectionEndSym; }
-    void setGenDwarfSectionEndSym(MCSymbol *Sym) {
-      GenDwarfSectionEndSym = Sym;
+    void setGenDwarfSectionStartSym(const MCSection *Sec, MCSymbol *Sym) {
+      GenDwarfSectionStartSyms[Sec] = Sym;
+    }
+    MCSymbol *getGenDwarfSectionEndSym(const MCSection *Sec) {
+      DenseMap<const MCSection *, MCSymbol *>::iterator Sym =
+          GenDwarfSectionEndSyms.find(Sec);
+      if (Sym != GenDwarfSectionEndSyms.end())
+        return Sym->second;
+      return NULL;
+    }
+    void setGenDwarfSectionEndSym(const MCSection *Sec, MCSymbol *Sym) {
+      GenDwarfSectionEndSyms[Sec] = Sym;
     }
     const std::vector<const MCGenDwarfLabelEntry *>
       &getMCGenDwarfLabelEntries() const {
@@ -395,6 +440,9 @@
     void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
     StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
 
+    void setDwarfVersion(unsigned v) { DwarfVersion = v; }
+    unsigned getDwarfVersion() const { return DwarfVersion; }
+
     /// @}
 
     char *getSecureLogFile() { return SecureLogFile; }
Index: include/llvm/MC/MCObjectStreamer.h
===================================================================
--- include/llvm/MC/MCObjectStreamer.h
+++ include/llvm/MC/MCObjectStreamer.h
@@ -119,6 +119,10 @@
   virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue);
   virtual void EmitZeros(uint64_t NumBytes);
   virtual void FinishImpl();
+
+  virtual bool hasInstructions() const {
+    return getCurrentSectionData()->hasInstructions();
+  }
 };
 
 } // end namespace llvm
Index: include/llvm/MC/MCStreamer.h
===================================================================
--- include/llvm/MC/MCStreamer.h
+++ include/llvm/MC/MCStreamer.h
@@ -719,6 +719,8 @@
   virtual void FinishImpl() = 0;
   /// Finish - Finish emission of machine code.
   void Finish();
+
+  virtual bool hasInstructions() const { return false; }
 };
 
 /// createNullStreamer - Create a dummy machine code streamer, which does
Index: lib/MC/MCDwarf.cpp
===================================================================
--- lib/MC/MCDwarf.cpp
+++ lib/MC/MCDwarf.cpp
@@ -16,7 +16,9 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSection.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/Debug.h"
@@ -464,7 +466,7 @@
 
 // When generating dwarf for assembly source files this emits
 // the data for .debug_abbrev section which contains three DIEs.
-static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
+static void EmitGenDwarfAbbrev(MCStreamer *MCOS, bool UseRangesSection) {
   MCContext &context = MCOS->getContext();
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
 
@@ -473,8 +475,12 @@
   MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
   MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
   EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
-  EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
-  EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
+  if (UseRangesSection) {
+    EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
+  } else {
+    EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
+    EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
+  }
   EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
   if (!context.getCompilationDir().empty())
     EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
@@ -514,13 +520,7 @@
                                 const MCSymbol *InfoSectionSymbol) {
   MCContext &context = MCOS->getContext();
 
-  // Create a symbol at the end of the section that we are creating the dwarf
-  // debugging info to use later in here as part of the expression to calculate
-  // the size of the section for the table.
-  MCOS->SwitchSection(context.getGenDwarfSection());
-  MCSymbol *SectionEndSym = context.CreateTempSymbol();
-  MCOS->EmitLabel(SectionEndSym);
-  context.setGenDwarfSectionEndSym(SectionEndSym);
+  SetVector<const MCSection*> &Sections = context.getGenDwarfSections();
 
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
 
@@ -538,8 +538,8 @@
   Length += Pad;
 
   // Add the size of the pair of PointerSize'ed values for the address and size
-  // of the one default .text section we have in the table.
-  Length += 2 * AddrSize;
+  // of each section we have in the table.
+  Length += 2 * AddrSize * Sections.size();
   // And the pair of terminating zeros.
   Length += 2 * AddrSize;
 
@@ -563,14 +563,22 @@
   for(int i = 0; i < Pad; i++)
     MCOS->EmitIntValue(0, 1);
 
-  // Now emit the table of pairs of PointerSize'ed values for the section(s)
-  // address and size, in our case just the one default .text section.
-  const MCExpr *Addr = MCSymbolRefExpr::Create(
-    context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
-  const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
-    *context.getGenDwarfSectionStartSym(), *SectionEndSym, 0);
-  MCOS->EmitAbsValue(Addr, AddrSize);
-  MCOS->EmitAbsValue(Size, AddrSize);
+  // Now emit the table of pairs of PointerSize'ed values for the section
+  // addresses and sizes.
+  for (SetVector<const MCSection*>::const_iterator sec = Sections.begin();
+       sec != Sections.end(); sec++) {
+    MCSymbol* StartSymbol = context.getGenDwarfSectionStartSym(*sec);
+    MCSymbol* EndSymbol = context.getGenDwarfSectionEndSym(*sec);
+    assert(StartSymbol && "StartSymbol must not be NULL");
+    assert(EndSymbol && "EndSymbol must not be NULL");
+
+    const MCExpr *Addr = MCSymbolRefExpr::Create(
+      StartSymbol, MCSymbolRefExpr::VK_None, context);
+    const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
+      *StartSymbol, *EndSymbol, 0);
+    MCOS->EmitAbsValue(Addr, AddrSize);
+    MCOS->EmitAbsValue(Size, AddrSize);
+  }
 
   // And finally the pair of terminating zeros.
   MCOS->EmitIntValue(0, AddrSize);
@@ -582,7 +590,8 @@
 // DIE and a list of label DIEs.
 static void EmitGenDwarfInfo(MCStreamer *MCOS,
                              const MCSymbol *AbbrevSectionSymbol,
-                             const MCSymbol *LineSectionSymbol) {
+                             const MCSymbol *LineSectionSymbol,
+                             const MCSymbol *RangesSectionSymbol) {
   MCContext &context = MCOS->getContext();
 
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
@@ -600,8 +609,8 @@
   const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
   MCOS->EmitAbsValue(Length, 4);
 
-  // The 2 byte DWARF version, which is 2.
-  MCOS->EmitIntValue(2, 2);
+  // The 2 byte DWARF version.
+  MCOS->EmitIntValue(context.getDwarfVersion(), 2);
 
   // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
   // it is at the start of that section so this is zero.
@@ -629,15 +638,43 @@
     MCOS->EmitIntValue(0, 4);
   }
 
-  // AT_low_pc, the first address of the default .text section.
-  const MCExpr *Start = MCSymbolRefExpr::Create(
-    context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
-  MCOS->EmitAbsValue(Start, AddrSize);
+  if (RangesSectionSymbol) {
+    // There are multiple sections containing code, so we must use the
+    // .debug_ranges sections.
 
-  // AT_high_pc, the last address of the default .text section.
-  const MCExpr *End = MCSymbolRefExpr::Create(
-    context.getGenDwarfSectionEndSym(), MCSymbolRefExpr::VK_None, context);
-  MCOS->EmitAbsValue(End, AddrSize);
+    // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
+    // to the address range list for this compilation unit.
+    MCOS->EmitSymbolValue(RangesSectionSymbol, 4);
+  } else {
+    // If we only have one non-empty code section, we can use the simpler
+    // AT_low_pc and AT_high_pc attributes.
+
+    // Find the first (and only) non-empty text section
+    SetVector<const MCSection*> &Sections = context.getGenDwarfSections();
+    SetVector<const MCSection*>::const_iterator TextSection = Sections.begin();
+    while (true) {
+      assert(TextSection != Sections.end() && "No text section found");
+      MCOS->SwitchSection(*TextSection);
+      if (MCOS->hasInstructions()) break;
+      ++TextSection;
+    }
+    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
+
+    MCSymbol* StartSymbol = context.getGenDwarfSectionStartSym(*TextSection);
+    MCSymbol* EndSymbol = context.getGenDwarfSectionEndSym(*TextSection);
+    assert(StartSymbol && "StartSymbol must not be NULL");
+    assert(EndSymbol && "EndSymbol must not be NULL");
+
+    // AT_low_pc, the first address of the default .text section.
+    const MCExpr *Start = MCSymbolRefExpr::Create(
+        StartSymbol, MCSymbolRefExpr::VK_None, context);
+    MCOS->EmitAbsValue(Start, AddrSize);
+
+    // AT_high_pc, the last address of the default .text section.
+    const MCExpr *End = MCSymbolRefExpr::Create(
+      EndSymbol, MCSymbolRefExpr::VK_None, context);
+    MCOS->EmitAbsValue(End, AddrSize);
+  }
 
   // AT_name, the name of the source file.  Reconstruct from the first directory
   // and file table entries.
@@ -734,13 +771,58 @@
   MCOS->EmitLabel(InfoEnd);
 }
 
+// When generating dwarf for assembly source files this emits the data for
+// .debug_ranges section. We currently only emit one range list, which spans
+// all of the executable sections of this file.
+static void EmitGenDwarfRanges(MCStreamer *MCOS) {
+  MCContext &context = MCOS->getContext();
+  SetVector<const MCSection*> &Sections = context.getGenDwarfSections();
+
+  const MCAsmInfo *AsmInfo = context.getAsmInfo();
+  int AddrSize = AsmInfo->getPointerSize();
+
+  for (SetVector<const MCSection*>::const_iterator sec = Sections.begin();
+       sec != Sections.end(); sec++) {
+    MCOS->SwitchSection(*sec);
+    if (!MCOS->hasInstructions()) continue;
+    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
+
+    MCSymbol* StartSymbol = context.getGenDwarfSectionStartSym(*sec);
+    MCSymbol* EndSymbol = context.getGenDwarfSectionEndSym(*sec);
+    assert(StartSymbol && "StartSymbol must not be NULL");
+    assert(EndSymbol && "EndSymbol must not be NULL");
+
+
+    // Emit a base address selection entry for the start of this section
+    const MCExpr *SectionStartAddr = MCSymbolRefExpr::Create(
+      StartSymbol, MCSymbolRefExpr::VK_None, context);
+    MCOS->EmitFill(AddrSize, 0xFF);
+    MCOS->EmitAbsValue(SectionStartAddr, AddrSize);
+
+    // Emit a range list entry spanning this section
+    const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
+      *StartSymbol, *EndSymbol, 0);
+    MCOS->EmitIntValue(0, AddrSize);
+    MCOS->EmitAbsValue(SectionSize, AddrSize);
+  }
+
+  // Emit end of list entry
+  MCOS->EmitIntValue(0, AddrSize);
+  MCOS->EmitIntValue(0, AddrSize);
+}
+
 //
 // When generating dwarf for assembly source files this emits the Dwarf
 // sections.
 //
 void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
-  // Create the dwarf sections in this order (.debug_line already created).
   MCContext &context = MCOS->getContext();
+
+  // If there are no line table entries then do not emit any debug sections.
+  if (context.getMCLineSections().empty())
+    return;
+
+  // Create the dwarf sections in this order (.debug_line already created).
   const MCAsmInfo *AsmInfo = context.getAsmInfo();
   bool CreateDwarfSectionSymbols =
       AsmInfo->doesDwarfUseRelocationsAcrossSections();
@@ -748,6 +830,23 @@
     LineSectionSymbol = NULL;
   MCSymbol *AbbrevSectionSymbol = NULL;
   MCSymbol *InfoSectionSymbol = NULL;
+  MCSymbol *RangesSectionSymbol = NULL;
+
+  // Create end symbols for each section, and remove empty sections
+  MCOS->getContext().FinalizeDwarfSections(*MCOS);
+
+  int NumSectionsWithInstructions = 0;
+  SetVector<const MCSection*> &Sections = MCOS->getContext().getGenDwarfSections();
+  for (SetVector<const MCSection*>::const_iterator sec = Sections.begin();
+       sec != Sections.end(); sec++) {
+    MCOS->SwitchSection(*sec);
+    if (MCOS->hasInstructions()) ++NumSectionsWithInstructions;
+  }
+  // We only need to use the .debug_ranges section if we have multiple
+  // non-empty code sections.
+  const bool UseRangesSection = NumSectionsWithInstructions > 1;
+  CreateDwarfSectionSymbols |= UseRangesSection;
+
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
   if (CreateDwarfSectionSymbols) {
     InfoSectionSymbol = context.CreateTempSymbol();
@@ -758,20 +857,30 @@
     AbbrevSectionSymbol = context.CreateTempSymbol();
     MCOS->EmitLabel(AbbrevSectionSymbol);
   }
-  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
+  if (UseRangesSection) {
+    MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
+    if (CreateDwarfSectionSymbols) {
+      RangesSectionSymbol = context.CreateTempSymbol();
+      MCOS->EmitLabel(RangesSectionSymbol);
+    }
+  }
 
-  // If there are no line table entries then do not emit any section contents.
-  if (context.getMCLineSections().empty())
-    return;
+  assert((RangesSectionSymbol != NULL) || !UseRangesSection);
+
+  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
 
   // Output the data for .debug_aranges section.
   EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
 
+  if (UseRangesSection)
+    EmitGenDwarfRanges(MCOS);
+
   // Output the data for .debug_abbrev section.
-  EmitGenDwarfAbbrev(MCOS);
+  EmitGenDwarfAbbrev(MCOS, UseRangesSection);
 
   // Output the data for .debug_info section.
-  EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol);
+  EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol,
+                   RangesSectionSymbol);
 }
 
 //
@@ -782,12 +891,13 @@
 //
 void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
                                      SourceMgr &SrcMgr, SMLoc &Loc) {
-  // We won't create dwarf labels for temporary symbols or symbols not in
-  // the default text.
+  // We won't create dwarf labels for temporary symbols.
   if (Symbol->isTemporary())
     return;
   MCContext &context = MCOS->getContext();
-  if (context.getGenDwarfSection() != MCOS->getCurrentSection().first)
+  // We won't create dwarf labels for symbols in sections that we are not
+  // generating debug info for.
+  if (!context.getGenDwarfSections().count(MCOS->getCurrentSection().first))
     return;
 
   // The dwarf label's name does not have the symbol name's leading
Index: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- lib/MC/MCParser/AsmParser.cpp
+++ lib/MC/MCParser/AsmParser.cpp
@@ -636,10 +636,10 @@
   // If we are generating dwarf for assembly source files save the initial text
   // section and generate a .file directive.
   if (getContext().getGenDwarfForAssembly()) {
-    getContext().setGenDwarfSection(getStreamer().getCurrentSection().first);
+    getContext().addGenDwarfSection(getStreamer().getCurrentSection().first);
     MCSymbol *SectionStartSym = getContext().CreateTempSymbol();
     getStreamer().EmitLabel(SectionStartSym);
-    getContext().setGenDwarfSectionStartSym(SectionStartSym);
+    getContext().setGenDwarfSectionStartSym(getStreamer().getCurrentSection().first, SectionStartSym);
     getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(),
                                          StringRef(),
                                          getContext().getMainFileName());
@@ -1578,12 +1578,11 @@
     printMessage(IDLoc, SourceMgr::DK_Note, OS.str());
   }
 
-  // If we are generating dwarf for assembly source files and the current
-  // section is the initial text section then generate a .loc directive for
-  // the instruction.
+  // If we are generating dwarf for the current section then generate a .loc
+  // directive for the instruction.
   if (!HadError && getContext().getGenDwarfForAssembly() &&
-      getContext().getGenDwarfSection() ==
-          getStreamer().getCurrentSection().first) {
+      getContext().getGenDwarfSections().count(
+        getStreamer().getCurrentSection().first)) {
 
     unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
 
Index: lib/MC/MCParser/ELFAsmParser.cpp
===================================================================
--- lib/MC/MCParser/ELFAsmParser.cpp
+++ lib/MC/MCParser/ELFAsmParser.cpp
@@ -150,7 +150,7 @@
 
 private:
   bool ParseSectionName(StringRef &SectionName);
-  bool ParseSectionArguments(bool IsPush);
+  bool ParseSectionArguments(bool IsPush, SMLoc loc);
 };
 
 }
@@ -325,7 +325,7 @@
 bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
   getStreamer().PushSection();
 
-  if (ParseSectionArguments(/*IsPush=*/true)) {
+  if (ParseSectionArguments(/*IsPush=*/true, loc)) {
     getStreamer().PopSection();
     return true;
   }
@@ -340,11 +340,11 @@
 }
 
 // FIXME: This is a work in progress.
-bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
-  return ParseSectionArguments(/*IsPush=*/false);
+bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
+  return ParseSectionArguments(/*IsPush=*/false, loc);
 }
 
-bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
+bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
   StringRef SectionName;
 
   if (ParseSectionName(SectionName))
@@ -482,10 +482,25 @@
   }
 
   SectionKind Kind = computeSectionKind(Flags);
-  getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
-                                                         Flags, Kind, Size,
-                                                         GroupName),
-                              Subsection);
+  const MCSection *ELFSection = getContext().getELFSection(
+      SectionName, Type, Flags, Kind, Size, GroupName);
+  getStreamer().SwitchSection(ELFSection, Subsection);
+
+  if (getContext().getGenDwarfForAssembly()) {
+    if (!getContext().getGenDwarfSections().count(ELFSection)) {
+      getContext().addGenDwarfSection(ELFSection);
+      if (getContext().getDwarfVersion() <= 2 &&
+          getContext().getGenDwarfSections().size() > 1)
+        Error(loc, "DWARF2 only supports one section per compilation unit");
+    }
+
+    if (!getContext().getGenDwarfSectionStartSym(ELFSection)) {
+      MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol();
+      getStreamer().EmitLabel(SectionStartSymbol);
+      getContext().setGenDwarfSectionStartSym(ELFSection, SectionStartSymbol);
+    }
+  }
+
   return false;
 }
 
Index: test/MC/ARM/dwarf-asm-multiple-sections.s
===================================================================
--- /dev/null
+++ test/MC/ARM/dwarf-asm-multiple-sections.s
@@ -0,0 +1,74 @@
+// RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -fdebug-compilation-dir=/tmp
+// RUN: llvm-dwarfdump %t | FileCheck -check-prefix DWARF %s
+// RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC %s
+// RUN: not llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -gdwarf-2 2>&1 | FileCheck -check-prefix VERSION %s
+  .section .text, "ax"
+a:
+  mov r0, r0
+
+  .section foo, "ax"
+b:
+  mov r1, r1
+
+// DWARF: .debug_abbrev contents:
+// DWARF: Abbrev table for offset: 0x00000000
+// DWARF: [1] DW_TAG_compile_unit DW_CHILDREN_yes
+// DWARF:         DW_AT_stmt_list DW_FORM_data4
+// DWARF:         DW_AT_ranges    DW_FORM_data4
+// DWARF:         DW_AT_name      DW_FORM_string
+// DWARF:         DW_AT_comp_dir  DW_FORM_string
+// DWARF:         DW_AT_producer  DW_FORM_string
+// DWARF:         DW_AT_language  DW_FORM_data2
+
+// DWARF: .debug_info contents:
+// DWARF: 0x{{[0-9a-f]+}}: DW_TAG_compile_unit [1]
+// CHECK-NOT-DWARF: DW_TAG_
+// DWARF: DW_AT_ranges [DW_FORM_data4]      (0x00000000)
+
+// DWARF: 0x{{[0-9a-f]+}}:   DW_TAG_label [2] *
+// DWARF-NEXT: DW_AT_name [DW_FORM_string]     ("a")
+
+// DWARF: 0x{{[0-9a-f]+}}:   DW_TAG_label [2] *
+// DWARF-NEXT: DW_AT_name [DW_FORM_string]     ("b")
+
+
+// DWARF: .debug_aranges contents:
+// DWARF-NEXT: Address Range Header: length = 0x00000024, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x04, seg_size = 0x00
+// DWARF-NEXT: [0x00000000 - 0x00000004)
+// DWARF-NEXT: [0x00000000 - 0x00000004)
+
+
+// DWARF: .debug_line contents:
+// DWARF:      0x0000000000000000      7      0      1   0   0  is_stmt
+// DWARF-NEXT: 0x0000000000000004      7      0      1   0   0  is_stmt end_sequence
+// DWARF-NEXT: 0x0000000000000000     11      0      1   0   0  is_stmt
+// DWARF-NEXT: 0x0000000000000004     11      0      1   0   0  is_stmt end_sequence
+
+
+// DWARF: .debug_ranges contents:
+// DWARF: 00000000 ffffffff 00000000
+// DWARF: 00000000 00000000 00000004
+// DWARF: 00000000 ffffffff 00000000
+// DWARF: 00000000 00000000 00000004
+// DWARF: 00000000 <End of list>
+
+
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]:
+// RELOC-NEXT: 6 R_ARM_ABS32 .debug_abbrev
+// RELOC-NEXT: 12 R_ARM_ABS32 .debug_line
+// RELOC-NEXT: 16 R_ARM_ABS32 .debug_ranges
+// RELOC-NEXT: 77 R_ARM_ABS32 .text
+// RELOC-NEXT: 95 R_ARM_ABS32 foo
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_ranges]:
+// RELOC-NEXT: 4 R_ARM_ABS32 .text
+// RELOC-NEXT: 20 R_ARM_ABS32 foo
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]:
+// RELOC-NEXT: 6 R_ARM_ABS32 .debug_info
+// RELOC-NEXT: 16 R_ARM_ABS32 .text
+// RELOC-NEXT: 24 R_ARM_ABS32 foo
+
+
+// VERSION: {{.*}} error: DWARF2 only supports one section per compilation unit
Index: test/MC/ARM/dwarf-asm-nonstandard-section.s
===================================================================
--- /dev/null
+++ test/MC/ARM/dwarf-asm-nonstandard-section.s
@@ -0,0 +1,57 @@
+// RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -fdebug-compilation-dir=/tmp
+// RUN: llvm-dwarfdump %t | FileCheck -check-prefix DWARF %s
+// RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC %s
+
+  .section foo, "ax"
+b:
+  mov r1, r1
+
+// DWARF: .debug_abbrev contents:
+// DWARF: Abbrev table for offset: 0x00000000
+// DWARF: [1] DW_TAG_compile_unit DW_CHILDREN_yes
+// DWARF:         DW_AT_stmt_list DW_FORM_data4
+// DWARF:         DW_AT_low_pc    DW_FORM_addr
+// DWARF:         DW_AT_high_pc   DW_FORM_addr
+// DWARF:         DW_AT_name      DW_FORM_string
+// DWARF:         DW_AT_comp_dir  DW_FORM_string
+// DWARF:         DW_AT_producer  DW_FORM_string
+// DWARF:         DW_AT_language  DW_FORM_data2
+
+// DWARF: .debug_info contents:
+// DWARF: 0x{{[0-9a-f]+}}: DW_TAG_compile_unit [1]
+// DWARF-NOT:         DW_TAG_
+// DWARF:               DW_AT_low_pc [DW_FORM_addr]       (0x0000000000000000)
+// DWARF:               DW_AT_high_pc [DW_FORM_addr]      (0x0000000000000004)
+
+// DWARF: 0x{{[0-9a-f]+}}:   DW_TAG_label [2] *
+// DWARF-NEXT: DW_AT_name [DW_FORM_string]     ("b")
+
+
+// DWARF: .debug_aranges contents:
+// DWARF-NEXT: Address Range Header: length = 0x0000001c, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x04, seg_size = 0x00
+// DWARF-NEXT: [0x00000000 - 0x00000004)
+
+
+// DWARF: .debug_line contents:
+// DWARF:      0x0000000000000000      7      0      1   0   0  is_stmt
+// DWARF-NEXT: 0x0000000000000004      7      0      1   0   0  is_stmt end_sequence
+
+
+// DWARF: .debug_ranges contents:
+// DWARF-NOT: {{0-9a-f}}
+// DWARF: .debug_pubnames contents:
+
+
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]:
+// RELOC-NEXT: 6 R_ARM_ABS32 .debug_abbrev
+// RELOC-NEXT: 12 R_ARM_ABS32 .debug_line
+// RELOC-NEXT: 16 R_ARM_ABS32 foo
+// RELOC-NEXT: 20 R_ARM_ABS32 foo
+// RELOC-NEXT: 81 R_ARM_ABS32 foo
+
+// RELOC-NOT: RELOCATION RECORDS FOR [.rel.debug_ranges]:
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]:
+// RELOC-NEXT: 6 R_ARM_ABS32 .debug_info
+// RELOC-NEXT: 16 R_ARM_ABS32 foo
Index: test/MC/ARM/dwarf-asm-single-section.s
===================================================================
--- /dev/null
+++ test/MC/ARM/dwarf-asm-single-section.s
@@ -0,0 +1,56 @@
+// RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o %t -g -fdebug-compilation-dir=/tmp
+// RUN: llvm-dwarfdump %t | FileCheck -check-prefix DWARF %s
+// RUN: llvm-objdump -r %t | FileCheck -check-prefix RELOC %s
+
+  .section .text, "ax"
+a:
+  mov r0, r0
+
+
+// DWARF: .debug_abbrev contents:
+// DWARF: Abbrev table for offset: 0x00000000
+// DWARF: [1] DW_TAG_compile_unit DW_CHILDREN_yes
+// DWARF:         DW_AT_stmt_list DW_FORM_data4
+// DWARF:         DW_AT_low_pc    DW_FORM_addr
+// DWARF:         DW_AT_high_pc   DW_FORM_addr
+// DWARF:         DW_AT_name      DW_FORM_string
+// DWARF:         DW_AT_comp_dir  DW_FORM_string
+// DWARF:         DW_AT_producer  DW_FORM_string
+// DWARF:         DW_AT_language  DW_FORM_data2
+
+// DWARF: .debug_info contents:
+// DWARF: 0x{{[0-9a-f]+}}: DW_TAG_compile_unit [1]
+// CHECK-NOT-DWARF: DW_TAG_
+// DWARF:               DW_AT_low_pc [DW_FORM_addr]       (0x0000000000000000)
+// DWARF:               DW_AT_high_pc [DW_FORM_addr]      (0x0000000000000004)
+
+// DWARF: 0x{{[0-9a-f]+}}:   DW_TAG_label [2] *
+// DWARF-NEXT: DW_AT_name [DW_FORM_string]     ("a")
+
+
+// DWARF: .debug_aranges contents:
+// DWARF-NEXT: Address Range Header: length = 0x0000001c, version = 0x0002, cu_offset = 0x00000000, addr_size = 0x04, seg_size = 0x00
+// DWARF-NEXT: [0x00000000 - 0x00000004)
+
+// DWARF: .debug_line contents:
+// DWARF:      0x0000000000000000      7      0      1   0   0 is_stmt
+// DWARF-NEXT: 0x0000000000000004      7      0      1   0   0 is_stmt end_sequence
+
+
+// DWARF: .debug_ranges contents:
+// DWARF-NOT: {{0-9a-f}}
+// DWARF: .debug_pubnames contents:
+
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]:
+// RELOC-NEXT: 6 R_ARM_ABS32 .debug_abbrev
+// RELOC-NEXT: 12 R_ARM_ABS32 .debug_line
+// RELOC-NEXT: 16 R_ARM_ABS32 .text
+// RELOC-NEXT: 20 R_ARM_ABS32 .text
+// RELOC-NEXT: 81 R_ARM_ABS32 .text
+
+// RELOC-NOT: RELOCATION RECORDS FOR [.rel.debug_ranges]:
+
+// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]:
+// RELOC-NEXT: 6 R_ARM_ABS32 .debug_info
+// RELOC-NEXT: 16 R_ARM_ABS32 .text
Index: test/MC/ARM/ldr-pseudo.s
===================================================================
--- test/MC/ARM/ldr-pseudo.s
+++ test/MC/ARM/ldr-pseudo.s
@@ -16,20 +16,20 @@
 @ CHECK-LABEL: f3:
 f3:
   ldr r0, =0x10001
-@ CHECK: ldr r0, .Ltmp0
+@ CHECK: ldr r0, .Ltmp[[TMP0:[0-9]+]]
 
 @ loading multiple constants
 .section c,"ax",%progbits
 @ CHECK-LABEL: f4:
 f4:
   ldr r0, =0x10002
-@ CHECK: ldr r0, .Ltmp1
+@ CHECK: ldr r0, .Ltmp[[TMP1:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =0x10003
-@ CHECK: ldr r0, .Ltmp2
+@ CHECK: ldr r0, .Ltmp[[TMP2:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
 
@@ -38,7 +38,7 @@
 @ CHECK-LABEL: f5:
 f5:
   ldr r0, =0x10004
-@ CHECK: ldr r0, .Ltmp3
+@ CHECK: ldr r0, .Ltmp[[TMP3:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
   adds r0, r0, #1
@@ -47,7 +47,7 @@
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =0x10004
-@ CHECK: ldr r0, .Ltmp4
+@ CHECK: ldr r0, .Ltmp[[TMP4:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
   adds r0, r0, #1
@@ -60,7 +60,7 @@
 @ CHECK-LABEL: f6:
 f6:
   ldr r0, =0x10006
-@ CHECK: ldr r0, .Ltmp5
+@ CHECK: ldr r0, .Ltmp[[TMP5:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
   adds r0, r0, #1
@@ -77,7 +77,7 @@
 f8:
   adds r0, r0, #1
   ldr r0, =0x10007
-@ CHECK: ldr r0, .Ltmp6
+@ CHECK: ldr r0, .Ltmp[[TMP6:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
 
@@ -90,21 +90,21 @@
 @ CHECK-LABEL: f9:
 f9:
   ldr r0, =foo
-@ CHECK: ldr r0, .Ltmp7
+@ CHECK: ldr r0, .Ltmp[[TMP7:[0-9]+]]
 
 @ load a symbol from another section
 .section h,"ax",%progbits
 @ CHECK-LABEL: f10:
 f10:
   ldr r0, =f5
-@ CHECK: ldr r0, .Ltmp8
+@ CHECK: ldr r0, .Ltmp[[TMP8:[0-9]+]]
 
 @ load a symbol from the same section
 .section i,"ax",%progbits
 @ CHECK-LABEL: f11:
 f11:
   ldr r0, =f12
-@ CHECK: ldr r0, .Ltmp9
+@ CHECK: ldr r0, .Ltmp[[TMP9:[0-9]+]]
 
 @ CHECK-LABEL: f12:
 f12:
@@ -118,11 +118,11 @@
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =0x101
-@ CHECK: ldr r0, .Ltmp10
+@ CHECK: ldr r0, .Ltmp[[TMP10:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =bar
-@ CHECK: ldr r0, .Ltmp11
+@ CHECK: ldr r0, .Ltmp[[TMP11:[0-9]+]]
   adds r0, r0, #1
   adds r0, r0, #1
 @
@@ -138,18 +138,18 @@
 @ CHECK-LABEL: f14:
 f14:
   useit_in_a_macro
-@ CHECK: ldr r0, .Ltmp12
-@ CHECK: ldr r0, .Ltmp13
+@ CHECK: ldr r0, .Ltmp[[TMP12:[0-9]+]]
+@ CHECK: ldr r0, .Ltmp[[TMP13:[0-9]+]]
 
 @ usage with expressions
 .section l, "ax", %progbits
 @ CHECK-LABEL: f15:
 f15:
   ldr r0, =0x10001+8
-@ CHECK: ldr r0, .Ltmp14
+@ CHECK: ldr r0, .Ltmp[[TMP14:[0-9]+]]
   adds r0, r0, #1
   ldr r0, =bar+4
-@ CHECK: ldr r0, .Ltmp15
+@ CHECK: ldr r0, .Ltmp[[TMP15:[0-9]+]]
   adds r0, r0, #1
 
 @
@@ -157,28 +157,28 @@
 @
 @ CHECK: .section b,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp0:
+@ CHECK: .Ltmp[[TMP0]]
 @ CHECK: .long 65537
 
 @ CHECK: .section c,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp1:
+@ CHECK: .Ltmp[[TMP1]]
 @ CHECK: .long 65538
-@ CHECK-LABEL: .Ltmp2:
+@ CHECK: .Ltmp[[TMP2]]
 @ CHECK: .long 65539
 
 @ CHECK: .section d,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp3:
+@ CHECK: .Ltmp[[TMP3]]
 @ CHECK: .long 65540
-@ CHECK-LABEL: .Ltmp4:
+@ CHECK: .Ltmp[[TMP4]]
 @ CHECK: .long 65540
 
 @ CHECK: .section e,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp5:
+@ CHECK: .Ltmp[[TMP5]]
 @ CHECK: .long 65542
-@ CHECK-LABEL: .Ltmp6:
+@ CHECK: .Ltmp[[TMP6]]
 @ CHECK: .long 65543
 
 @ Should not switch to section because it has no constant pool
@@ -186,36 +186,36 @@
 
 @ CHECK: .section g,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp7:
+@ CHECK: .Ltmp[[TMP7]]
 @ CHECK: .long foo
 
 @ CHECK: .section h,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp8:
+@ CHECK: .Ltmp[[TMP8]]
 @ CHECK: .long f5
 
 @ CHECK: .section i,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp9:
+@ CHECK: .Ltmp[[TMP9]]
 @ CHECK: .long f12
 
 @ CHECK: .section j,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp10:
+@ CHECK: .Ltmp[[TMP10]]
 @ CHECK: .long 257
-@ CHECK-LABEL: .Ltmp11:
+@ CHECK: .Ltmp[[TMP11]]
 @ CHECK: .long bar
 
 @ CHECK: .section k,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp12:
+@ CHECK: .Ltmp[[TMP12]]
 @ CHECK: .long 65544
-@ CHECK-LABEL: .Ltmp13:
+@ CHECK: .Ltmp[[TMP13]]
 @ CHECK: .long baz
 
 @ CHECK: .section l,"ax",%progbits
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp14:
+@ CHECK: .Ltmp[[TMP14]]
 @ CHECK: .long 65545
-@ CHECK-LABEL: .Ltmp15:
+@ CHECK: .Ltmp[[TMP15]]
 @ CHECK: .long bar+4
Index: test/MC/ARM/ltorg.s
===================================================================
--- test/MC/ARM/ltorg.s
+++ test/MC/ARM/ltorg.s
@@ -13,14 +13,14 @@
 @ CHECK-LABEL: f2:
 f2:
   ldr r0, =0x10001
-@ CHECK: ldr r0, .Ltmp0
+@ CHECK: ldr r0, .Ltmp[[TMP0:[0-9+]]]
   adds r0, r0, #1
   adds r0, r0, #1
   b f3
 .ltorg
 @ constant pool
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp0:
+@ CHECK: .Ltmp[[TMP0]]
 @ CHECK: .long 65537
 
 @ CHECK-LABEL: f3:
@@ -33,14 +33,14 @@
 @ CHECK-LABEL: f4:
 f4:
   ldr r0, =0x10002
-@ CHECK: ldr r0, .Ltmp1
+@ CHECK: ldr r0, .Ltmp[[TMP1:[0-9+]]]
   adds r0, r0, #1
   adds r0, r0, #1
   b f5
 .ltorg
 @ constant pool
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp1:
+@ CHECK: .Ltmp[[TMP1]]
 @ CHECK: .long 65538
 
 @ CHECK-LABEL: f5:
@@ -48,13 +48,13 @@
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =0x10003
-@ CHECK: ldr r0, .Ltmp2
+@ CHECK: ldr r0, .Ltmp[[TMP2:[0-9+]]]
   adds r0, r0, #1
   b f6
 .ltorg
 @ constant pool
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp2:
+@ CHECK: .Ltmp[[TMP2]]
 @ CHECK: .long 65539
 
 @ CHECK-LABEL: f6:
@@ -79,7 +79,7 @@
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =bar
-@ CHECK: ldr r0, .Ltmp3
+@ CHECK: ldr r0, .Ltmp[[TMP3:[0-9+]]]
   adds r0, r0, #1
   adds r0, r0, #1
   adds r0, r0, #1
@@ -87,7 +87,7 @@
 .ltorg
 @ constant pool
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp3:
+@ CHECK: .Ltmp[[TMP3]]
 @ CHECK: .long bar
 
 @ CHECK-LABEL: f10:
@@ -102,18 +102,18 @@
   adds r0, r0, #1
   adds r0, r0, #1
   ldr r0, =0x10004
-@ CHECK: ldr r0, .Ltmp4
+@ CHECK: ldr r0, .Ltmp[[TMP4:[0-9+]]]
   b f12
   .ltorg
 @ constant pool
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp4:
+@ CHECK: .Ltmp[[TMP4]]
 @ CHECK: .long 65540
 @ CHECK-LABEL: f12:
 f12:
   adds r0, r0, #1
   ldr r0, =0x10005
-@ CHECK: ldr r0, .Ltmp5
+@ CHECK: ldr r0, .Ltmp[[TMP5:[0-9+]]]
 
 .section f,"ax",%progbits
 @ CHECK-LABEL: f13
@@ -131,7 +131,7 @@
 @ CHECK: .section e,"ax",%progbits
 @ constant pool
 @ CHECK: .align 2
-@ CHECK-LABEL: .Ltmp5:
+@ CHECK: .Ltmp[[TMP5]]
 @ CHECK: .long 65541
 
 @ should not have a constant pool at end of section with empty constant pools
Index: tools/llvm-mc/llvm-mc.cpp
===================================================================
--- tools/llvm-mc/llvm-mc.cpp
+++ tools/llvm-mc/llvm-mc.cpp
@@ -153,6 +153,23 @@
 GenDwarfForAssembly("g", cl::desc("Generate dwarf debugging info for assembly "
                                   "source files"));
 
+enum DwarfVersionNumber {
+  DWARF2 = 2,
+  DWARF3 = 3,
+  DWARF4 = 4
+};
+
+static cl::opt<DwarfVersionNumber>
+DwarfVersion(cl::desc("Dwarf version"),
+       cl::init(DWARF3),
+       cl::values(clEnumValN(DWARF2, "gdwarf-2",
+                             "Dwarf version 2"),
+                  clEnumValN(DWARF3, "gdwarf-3",
+                             "Dwarf version 3"),
+                  clEnumValN(DWARF4, "gdwarf-4",
+                             "Dwarf version 4"),
+                  clEnumValEnd));
+
 static cl::opt<std::string>
 DebugCompilationDir("fdebug-compilation-dir",
                     cl::desc("Specifies the debug info's compilation dir"));
@@ -395,6 +412,7 @@
     Ctx.setAllowTemporaryLabels(false);
 
   Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
+  Ctx.setDwarfVersion(DwarfVersion);
   if (!DwarfDebugFlags.empty())
     Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
   if (!DwarfDebugProducer.empty())