[llvm] r308543 - Use delegation instead of inheritance.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 19 15:27:28 PDT 2017


Author: rafael
Date: Wed Jul 19 15:27:28 2017
New Revision: 308543

URL: http://llvm.org/viewvc/llvm-project?rev=308543&view=rev
Log:
Use delegation instead of inheritance.

This changes DwarfContext to delegate to DwarfObject instead of having
pure virtual methods.

With this DwarfContextInMemory is replaced with an implementation of
DwarfObject that is local to a .cpp file.

Added:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFObject.h
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFSection.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
    llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp
    llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
    llvm/trunk/tools/llvm-objdump/MachODump.cpp
    llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
    llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
    llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
    llvm/trunk/tools/obj2yaml/macho2yaml.cpp
    llvm/trunk/tools/obj2yaml/obj2yaml.h
    llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Wed Jul 19 15:27:28 2017
@@ -26,6 +26,7 @@
 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
+#include "llvm/DebugInfo/DWARF/DWARFObject.h"
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
@@ -45,10 +46,14 @@ class DataExtractor;
 class MemoryBuffer;
 class raw_ostream;
 
+/// Used as a return value for a error callback passed to DWARF context.
+/// Callback should return Halt if client application wants to stop
+/// object parsing, or should return Continue otherwise.
+enum class ErrorPolicy { Halt, Continue };
+
 /// DWARFContext
 /// This data structure is the top level entity that deals with dwarf debug
-/// information parsing. The actual data is supplied through pure virtual
-/// methods that a concrete implementation provides.
+/// information parsing. The actual data is supplied through DWARFObj.
 class DWARFContext : public DIContext {
   DWARFUnitSection<DWARFCompileUnit> CUs;
   std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
@@ -95,11 +100,17 @@ class DWARFContext : public DIContext {
   /// and store them in DWOTUs.
   void parseDWOTypeUnits();
 
+protected:
+  std::unique_ptr<const DWARFObject> DObj;
+
 public:
-  DWARFContext() : DIContext(CK_DWARF) {}
+  DWARFContext(std::unique_ptr<const DWARFObject> DObj)
+      : DIContext(CK_DWARF), DObj(std::move(DObj)) {}
   DWARFContext(DWARFContext &) = delete;
   DWARFContext &operator=(DWARFContext &) = delete;
 
+  const DWARFObject &getDWARFObj() const { return *DObj; }
+
   static bool classof(const DIContext *DICtx) {
     return DICtx->getKind() == CK_DWARF;
   }
@@ -222,55 +233,24 @@ public:
   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
 
-  virtual StringRef getFileName() const = 0;
-  virtual bool isLittleEndian() const = 0;
-  virtual uint8_t getAddressSize() const = 0;
-  virtual const DWARFSection &getInfoSection() = 0;
-  virtual void forEachTypesSections(function_ref<void(DWARFSection &)> F) = 0;
-  virtual StringRef getAbbrevSection() = 0;
-  virtual const DWARFSection &getLocSection() = 0;
-  virtual StringRef getARangeSection() = 0;
-  virtual StringRef getDebugFrameSection() = 0;
-  virtual StringRef getEHFrameSection() = 0;
-  virtual const DWARFSection &getLineSection() = 0;
-  virtual StringRef getStringSection() = 0;
-  virtual const DWARFSection& getRangeSection() = 0;
-  virtual StringRef getMacinfoSection() = 0;
-  virtual StringRef getPubNamesSection() = 0;
-  virtual StringRef getPubTypesSection() = 0;
-  virtual StringRef getGnuPubNamesSection() = 0;
-  virtual StringRef getGnuPubTypesSection() = 0;
-
-  /// DWARF v5
-  /// @{
-  virtual const DWARFSection &getStringOffsetSection() = 0;
-  /// @}
-
-  // Sections for DWARF5 split dwarf proposal.
-  virtual const DWARFSection &getInfoDWOSection() = 0;
-  virtual void
-  forEachTypesDWOSections(function_ref<void(DWARFSection &)> F) = 0;
-  virtual StringRef getAbbrevDWOSection() = 0;
-  virtual const DWARFSection &getLineDWOSection() = 0;
-  virtual const DWARFSection &getLocDWOSection() = 0;
-  virtual StringRef getStringDWOSection() = 0;
-  virtual const DWARFSection &getStringOffsetDWOSection() = 0;
-  virtual const DWARFSection &getRangeDWOSection() = 0;
-  virtual const DWARFSection &getAddrSection() = 0;
-  virtual const DWARFSection& getAppleNamesSection() = 0;
-  virtual const DWARFSection& getAppleTypesSection() = 0;
-  virtual const DWARFSection& getAppleNamespacesSection() = 0;
-  virtual const DWARFSection& getAppleObjCSection() = 0;
-  virtual StringRef getCUIndexSection() = 0;
-  virtual StringRef getGdbIndexSection() = 0;
-  virtual StringRef getTUIndexSection() = 0;
-
+  bool isLittleEndian() const { return DObj->isLittleEndian(); }
   static bool isSupportedVersion(unsigned version) {
     return version == 2 || version == 3 || version == 4 || version == 5;
   }
 
   std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
 
+  /// Function used to handle default error reporting policy. Prints a error
+  /// message and returns Continue, so DWARF context ignores the error.
+  static ErrorPolicy defaultErrorHandler(Error E);
+  static std::unique_ptr<DWARFContext>
+  create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
+         function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
+
+  static std::unique_ptr<DWARFContext>
+  create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+         uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
+
 private:
   /// Return the compile unit that includes an offset (relative to .debug_info).
   DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
@@ -280,142 +260,6 @@ private:
   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
 };
 
-/// Used as a return value for a error callback passed to DWARF context.
-/// Callback should return Halt if client application wants to stop
-/// object parsing, or should return Continue otherwise.
-enum class ErrorPolicy { Halt, Continue };
-
-/// DWARFContextInMemory is the simplest possible implementation of a
-/// DWARFContext. It assumes all content is available in memory and stores
-/// pointers to it.
-class DWARFContextInMemory : public DWARFContext {
-  virtual void anchor();
-
-  using TypeSectionMap = MapVector<object::SectionRef, DWARFSection,
-                                   std::map<object::SectionRef, unsigned>>;
-
-  StringRef FileName;
-  bool IsLittleEndian;
-  uint8_t AddressSize;
-  DWARFSection InfoSection;
-  TypeSectionMap TypesSections;
-  StringRef AbbrevSection;
-  DWARFSection LocSection;
-  StringRef ARangeSection;
-  StringRef DebugFrameSection;
-  StringRef EHFrameSection;
-  DWARFSection LineSection;
-  StringRef StringSection;
-  DWARFSection RangeSection;
-  StringRef MacinfoSection;
-  StringRef PubNamesSection;
-  StringRef PubTypesSection;
-  StringRef GnuPubNamesSection;
-  StringRef GnuPubTypesSection;
-
-  /// DWARF v5
-  /// @{
-  DWARFSection StringOffsetSection;
-  /// @}
-
-  // Sections for DWARF5 split dwarf proposal.
-  DWARFSection InfoDWOSection;
-  TypeSectionMap TypesDWOSections;
-  StringRef AbbrevDWOSection;
-  DWARFSection LineDWOSection;
-  DWARFSection LocDWOSection;
-  StringRef StringDWOSection;
-  DWARFSection StringOffsetDWOSection;
-  DWARFSection RangeDWOSection;
-  DWARFSection AddrSection;
-  DWARFSection AppleNamesSection;
-  DWARFSection AppleTypesSection;
-  DWARFSection AppleNamespacesSection;
-  DWARFSection AppleObjCSection;
-  StringRef CUIndexSection;
-  StringRef GdbIndexSection;
-  StringRef TUIndexSection;
-
-  SmallVector<SmallString<32>, 4> UncompressedSections;
-
-  DWARFSection *mapNameToDWARFSection(StringRef Name);
-  StringRef *mapSectionToMember(StringRef Name);
-
-  /// If Sec is compressed section, decompresses and updates its contents
-  /// provided by Data. Otherwise leaves it unchanged.
-  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
-                        StringRef &Data);
-
-  /// Function used to handle default error reporting policy. Prints a error
-  /// message and returns Continue, so DWARF context ignores the error.
-  static ErrorPolicy defaultErrorHandler(Error E);
-
-public:
-  DWARFContextInMemory(
-      const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
-      function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
-
-  DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
-                       uint8_t AddrSize,
-                       bool isLittleEndian = sys::IsLittleEndianHost);
-
-  StringRef getFileName() const override { return FileName; }
-  bool isLittleEndian() const override { return IsLittleEndian; }
-  uint8_t getAddressSize() const override { return AddressSize; }
-  const DWARFSection &getInfoSection() override { return InfoSection; }
-  void forEachTypesSections(function_ref<void(DWARFSection &)> F) override {
-    for (auto &P : TypesSections)
-      F(P.second);
-  }
-  StringRef getAbbrevSection() override { return AbbrevSection; }
-  const DWARFSection &getLocSection() override { return LocSection; }
-  StringRef getARangeSection() override { return ARangeSection; }
-  StringRef getDebugFrameSection() override { return DebugFrameSection; }
-  StringRef getEHFrameSection() override { return EHFrameSection; }
-  const DWARFSection &getLineSection() override { return LineSection; }
-  StringRef getStringSection() override { return StringSection; }
-  const DWARFSection &getRangeSection() override { return RangeSection; }
-  StringRef getMacinfoSection() override { return MacinfoSection; }
-  StringRef getPubNamesSection() override { return PubNamesSection; }
-  StringRef getPubTypesSection() override { return PubTypesSection; }
-  StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
-  StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
-  const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
-  const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
-  const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
-  const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
-
-  // DWARF v5
-  const DWARFSection &getStringOffsetSection() override {
-    return StringOffsetSection;
-  }
-
-  // Sections for DWARF5 split dwarf proposal.
-  const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
-
-  void forEachTypesDWOSections(function_ref<void(DWARFSection &)> F) override {
-    for (auto &P : TypesDWOSections)
-      F(P.second);
-  }
-
-  StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
-  const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
-  const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
-  StringRef getStringDWOSection() override { return StringDWOSection; }
-
-  const DWARFSection &getStringOffsetDWOSection() override {
-    return StringOffsetDWOSection;
-  }
-
-  const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
-
-  const DWARFSection &getAddrSection() override { return AddrSection; }
-
-  StringRef getCUIndexSection() override { return CUIndexSection; }
-  StringRef getGdbIndexSection() override { return GdbIndexSection; }
-  StringRef getTUIndexSection() override { return TUIndexSection; }
-};
-
 } // end namespace llvm
 
 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h Wed Jul 19 15:27:28 2017
@@ -14,18 +14,21 @@
 #include "llvm/Support/DataExtractor.h"
 
 namespace llvm {
+class DWARFObject;
 
 /// A DataExtractor (typically for an in-memory copy of an object-file section)
 /// plus a relocation map for that section, if there is one.
 class DWARFDataExtractor : public DataExtractor {
-  const RelocAddrMap *RelocMap = nullptr;
+  const DWARFObject *Obj = nullptr;
+  const DWARFSection *Section = nullptr;
+
 public:
   /// Constructor for the normal case of extracting data from a DWARF section.
   /// The DWARFSection's lifetime must be at least as long as the extractor's.
-  DWARFDataExtractor(const DWARFSection &Section, bool IsLittleEndian,
-                     uint8_t AddressSize)
-    : DataExtractor(Section.Data, IsLittleEndian, AddressSize),
-      RelocMap(&Section.Relocs) {}
+  DWARFDataExtractor(const DWARFObject &Obj, const DWARFSection &Section,
+                     bool IsLittleEndian, uint8_t AddressSize)
+      : DataExtractor(Section.Data, IsLittleEndian, AddressSize), Obj(&Obj),
+        Section(&Section) {}
 
   /// Constructor for cases when there are no relocations.
   DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)

Added: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFObject.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFObject.h?rev=308543&view=auto
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFObject.h (added)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFObject.h Wed Jul 19 15:27:28 2017
@@ -0,0 +1,75 @@
+//===- DWARFObject.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFOBJECT_H
+#define LLVM_DEBUGINFO_DWARF_DWARFOBJECT_H
+
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+
+namespace llvm {
+// This is responsible for low level access to the object file. It
+// knows how to find the required sections and compute relocated
+// values.
+// The default implementations of the get<Section> methods return dummy values.
+// This is to allow clients that only need some of those to implement just the
+// ones they need. We can't use unreachable for as many cases because the parser
+// implementation is eager and will call some of these methods even if the
+// result is not used.
+class DWARFObject {
+  DWARFSection Dummy;
+
+public:
+  virtual ~DWARFObject() = default;
+  virtual StringRef getFileName() const { llvm_unreachable("unimplemented"); }
+  virtual bool isLittleEndian() const = 0;
+  virtual uint8_t getAddressSize() const { llvm_unreachable("unimplemented"); }
+  virtual const DWARFSection &getInfoSection() const { return Dummy; }
+  virtual void
+  forEachTypesSections(function_ref<void(const DWARFSection &)> F) const {}
+  virtual StringRef getAbbrevSection() const { return ""; }
+  virtual const DWARFSection &getLocSection() const { return Dummy; }
+  virtual StringRef getARangeSection() const { return ""; }
+  virtual StringRef getDebugFrameSection() const { return ""; }
+  virtual StringRef getEHFrameSection() const { return ""; }
+  virtual const DWARFSection &getLineSection() const { return Dummy; }
+  virtual StringRef getStringSection() const { return ""; }
+  virtual const DWARFSection &getRangeSection() const { return Dummy; }
+  virtual StringRef getMacinfoSection() const { return ""; }
+  virtual StringRef getPubNamesSection() const { return ""; }
+  virtual StringRef getPubTypesSection() const { return ""; }
+  virtual StringRef getGnuPubNamesSection() const { return ""; }
+  virtual StringRef getGnuPubTypesSection() const { return ""; }
+  virtual const DWARFSection &getStringOffsetSection() const { return Dummy; }
+  virtual const DWARFSection &getInfoDWOSection() const { return Dummy; }
+  virtual void
+  forEachTypesDWOSections(function_ref<void(const DWARFSection &)> F) const {}
+  virtual StringRef getAbbrevDWOSection() const { return ""; }
+  virtual const DWARFSection &getLineDWOSection() const { return Dummy; }
+  virtual const DWARFSection &getLocDWOSection() const { return Dummy; }
+  virtual StringRef getStringDWOSection() const { return ""; }
+  virtual const DWARFSection &getStringOffsetDWOSection() const {
+    return Dummy;
+  }
+  virtual const DWARFSection &getRangeDWOSection() const { return Dummy; }
+  virtual const DWARFSection &getAddrSection() const { return Dummy; }
+  virtual const DWARFSection &getAppleNamesSection() const { return Dummy; }
+  virtual const DWARFSection &getAppleTypesSection() const { return Dummy; }
+  virtual const DWARFSection &getAppleNamespacesSection() const {
+    return Dummy;
+  }
+  virtual const DWARFSection &getAppleObjCSection() const { return Dummy; }
+  virtual StringRef getCUIndexSection() const { return ""; }
+  virtual StringRef getGdbIndexSection() const { return ""; }
+  virtual StringRef getTUIndexSection() const { return ""; }
+  virtual Optional<RelocAddrEntry> find(const DWARFSection &Sec,
+                                        uint64_t Pos) const = 0;
+};
+
+} // namespace llvm
+#endif

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFSection.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFSection.h?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFSection.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFSection.h Wed Jul 19 15:27:28 2017
@@ -17,6 +17,9 @@ namespace llvm {
 
 struct DWARFSection {
   StringRef Data;
+};
+
+struct DWARFSectionMap final : public DWARFSection {
   RelocAddrMap Relocs;
 };
 

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Wed Jul 19 15:27:28 2017
@@ -197,19 +197,12 @@ public:
   bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
   bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
 
-  DWARFDataExtractor getDebugInfoExtractor() const {
-    return DWARFDataExtractor(InfoSection, isLittleEndian,
-                              getAddressByteSize());
-  }
+  DWARFDataExtractor getDebugInfoExtractor() const;
 
   DataExtractor getStringExtractor() const {
     return DataExtractor(StringSection, false, 0);
   }
 
-  const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
-  const RelocAddrMap &getStringOffsetsRelocMap() const {
-    return StringOffsetSection.Relocs;
-  }
 
   bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Wed Jul 19 15:27:28 2017
@@ -60,9 +60,10 @@ using FileLineInfoKind = DILineInfoSpeci
 using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
 
 static void dumpAccelSection(raw_ostream &OS, StringRef Name,
-                             const DWARFSection& Section, StringRef StringSection,
-                             bool LittleEndian) {
-  DWARFDataExtractor AccelSection(Section, LittleEndian, 0);
+                             const DWARFObject &Obj,
+                             const DWARFSection &Section,
+                             StringRef StringSection, bool LittleEndian) {
+  DWARFDataExtractor AccelSection(Obj, Section, LittleEndian, 0);
   DataExtractor StrData(StringSection, LittleEndian, 0);
   OS << "\n." << Name << " contents:\n";
   DWARFAcceleratorTable Accel(AccelSection, StrData);
@@ -73,9 +74,10 @@ static void dumpAccelSection(raw_ostream
 
 static void
 dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+                                const DWARFObject &Obj,
                                 const DWARFSection &StringOffsetsSection,
                                 StringRef StringSection, bool LittleEndian) {
-  DWARFDataExtractor StrOffsetExt(StringOffsetsSection, LittleEndian, 0);
+  DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
   uint32_t Offset = 0;
   uint64_t SectionSize = StringOffsetsSection.Data.size();
 
@@ -153,6 +155,7 @@ dumpDWARFv5StringOffsetsSection(raw_ostr
 // monolithic series of string offsets, as generated by the pre-DWARF v5
 // implementation of split DWARF.
 static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+                                     const DWARFObject &Obj,
                                      const DWARFSection &StringOffsetsSection,
                                      StringRef StringSection, bool LittleEndian,
                                      unsigned MaxVersion) {
@@ -163,7 +166,7 @@ static void dumpStringOffsetsSection(raw
   // we assume that the section is formatted like a DWARF v5 string offsets
   // section.
   if (MaxVersion >= 5)
-    dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,
+    dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
                                     StringSection, LittleEndian);
   else {
     DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
@@ -259,7 +262,7 @@ void DWARFContext::dump(raw_ostream &OS,
   uint32_t offset = 0;
   if (DumpType == DIDT_All || DumpType == DIDT_Aranges) {
     OS << "\n.debug_aranges contents:\n";
-    DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
+    DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
     DWARFDebugArangeSet set;
     while (set.extract(arangesData, &offset))
       set.dump(OS);
@@ -274,8 +277,8 @@ void DWARFContext::dump(raw_ostream &OS,
       if (!CUDIE)
         continue;
       if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) {
-        DWARFDataExtractor lineData(getLineSection(), isLittleEndian(),
-                                    savedAddressByteSize);
+        DWARFDataExtractor lineData(*DObj, DObj->getLineSection(),
+                                    isLittleEndian(), savedAddressByteSize);
         DWARFDebugLine::LineTable LineTable;
         uint32_t Offset = *StmtOffset;
         LineTable.parse(lineData, &Offset);
@@ -297,8 +300,8 @@ void DWARFContext::dump(raw_ostream &OS,
   if (DumpType == DIDT_All || DumpType == DIDT_LineDwo) {
     OS << "\n.debug_line.dwo contents:\n";
     unsigned stmtOffset = 0;
-    DWARFDataExtractor lineData(getLineDWOSection(), isLittleEndian(),
-                                savedAddressByteSize);
+    DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(),
+                                isLittleEndian(), savedAddressByteSize);
     DWARFDebugLine::LineTable LineTable;
     while (LineTable.Prologue.parse(lineData, &stmtOffset)) {
       LineTable.dump(OS);
@@ -308,7 +311,7 @@ void DWARFContext::dump(raw_ostream &OS,
 
   if (DumpType == DIDT_All || DumpType == DIDT_Str) {
     OS << "\n.debug_str contents:\n";
-    DataExtractor strData(getStringSection(), isLittleEndian(), 0);
+    DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
     offset = 0;
     uint32_t strOffset = 0;
     while (const char *s = strData.getCStr(&offset)) {
@@ -318,9 +321,9 @@ void DWARFContext::dump(raw_ostream &OS,
   }
 
   if ((DumpType == DIDT_All || DumpType == DIDT_StrDwo) &&
-      !getStringDWOSection().empty()) {
+      !DObj->getStringDWOSection().empty()) {
     OS << "\n.debug_str.dwo contents:\n";
-    DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
+    DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
     offset = 0;
     uint32_t strDWOOffset = 0;
     while (const char *s = strDWOData.getCStr(&offset)) {
@@ -335,8 +338,8 @@ void DWARFContext::dump(raw_ostream &OS,
     // sizes, but for simplicity we just use the address byte size of the last
     // compile unit (there is no easy and fast way to associate address range
     // list and the compile unit it describes).
-    DWARFDataExtractor rangesData(getRangeSection(), isLittleEndian(),
-                                  savedAddressByteSize);
+    DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
+                                  isLittleEndian(), savedAddressByteSize);
     offset = 0;
     DWARFDebugRangeList rangeList;
     while (rangeList.extract(rangesData, &offset))
@@ -344,55 +347,56 @@ void DWARFContext::dump(raw_ostream &OS,
   }
 
   if (DumpType == DIDT_All || DumpType == DIDT_Pubnames)
-    DWARFDebugPubTable(getPubNamesSection(), isLittleEndian(), false)
+    DWARFDebugPubTable(DObj->getPubNamesSection(), isLittleEndian(), false)
         .dump("debug_pubnames", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_Pubtypes)
-    DWARFDebugPubTable(getPubTypesSection(), isLittleEndian(), false)
+    DWARFDebugPubTable(DObj->getPubTypesSection(), isLittleEndian(), false)
         .dump("debug_pubtypes", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubnames)
-    DWARFDebugPubTable(getGnuPubNamesSection(), isLittleEndian(),
+    DWARFDebugPubTable(DObj->getGnuPubNamesSection(), isLittleEndian(),
                        true /* GnuStyle */)
         .dump("debug_gnu_pubnames", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_GnuPubtypes)
-    DWARFDebugPubTable(getGnuPubTypesSection(), isLittleEndian(),
+    DWARFDebugPubTable(DObj->getGnuPubTypesSection(), isLittleEndian(),
                        true /* GnuStyle */)
         .dump("debug_gnu_pubtypes", OS);
 
   if (DumpType == DIDT_All || DumpType == DIDT_StrOffsets)
-    dumpStringOffsetsSection(OS, "debug_str_offsets", getStringOffsetSection(),
-                             getStringSection(), isLittleEndian(),
-                             getMaxVersion());
+    dumpStringOffsetsSection(
+        OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
+        DObj->getStringSection(), isLittleEndian(), getMaxVersion());
 
   if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
-    dumpStringOffsetsSection(OS, "debug_str_offsets.dwo",
-                             getStringOffsetDWOSection(), getStringDWOSection(),
-                             isLittleEndian(), getMaxVersion());
+    dumpStringOffsetsSection(
+        OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
+        DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion());
   }
 
   if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
-      !getGdbIndexSection().empty()) {
+      !DObj->getGdbIndexSection().empty()) {
     OS << "\n.gnu_index contents:\n";
     getGdbIndex().dump(OS);
   }
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleNames)
-    dumpAccelSection(OS, "apple_names", getAppleNamesSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_names", *DObj, DObj->getAppleNamesSection(),
+                     DObj->getStringSection(), isLittleEndian());
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleTypes)
-    dumpAccelSection(OS, "apple_types", getAppleTypesSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_types", *DObj, DObj->getAppleTypesSection(),
+                     DObj->getStringSection(), isLittleEndian());
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleNamespaces)
-    dumpAccelSection(OS, "apple_namespaces", getAppleNamespacesSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_namespaces", *DObj,
+                     DObj->getAppleNamespacesSection(),
+                     DObj->getStringSection(), isLittleEndian());
 
   if (DumpType == DIDT_All || DumpType == DIDT_AppleObjC)
-    dumpAccelSection(OS, "apple_objc", getAppleObjCSection(),
-                     getStringSection(), isLittleEndian());
+    dumpAccelSection(OS, "apple_objc", *DObj, DObj->getAppleObjCSection(),
+                     DObj->getStringSection(), isLittleEndian());
 }
 
 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
@@ -433,7 +437,7 @@ const DWARFUnitIndex &DWARFContext::getC
   if (CUIndex)
     return *CUIndex;
 
-  DataExtractor CUIndexData(getCUIndexSection(), isLittleEndian(), 0);
+  DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
 
   CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
   CUIndex->parse(CUIndexData);
@@ -444,7 +448,7 @@ const DWARFUnitIndex &DWARFContext::getT
   if (TUIndex)
     return *TUIndex;
 
-  DataExtractor TUIndexData(getTUIndexSection(), isLittleEndian(), 0);
+  DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
 
   TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
   TUIndex->parse(TUIndexData);
@@ -455,7 +459,7 @@ DWARFGdbIndex &DWARFContext::getGdbIndex
   if (GdbIndex)
     return *GdbIndex;
 
-  DataExtractor GdbIndexData(getGdbIndexSection(), true /*LE*/, 0);
+  DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
   GdbIndex = llvm::make_unique<DWARFGdbIndex>();
   GdbIndex->parse(GdbIndexData);
   return *GdbIndex;
@@ -465,7 +469,7 @@ const DWARFDebugAbbrev *DWARFContext::ge
   if (Abbrev)
     return Abbrev.get();
 
-  DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
+  DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
 
   Abbrev.reset(new DWARFDebugAbbrev());
   Abbrev->extract(abbrData);
@@ -476,7 +480,7 @@ const DWARFDebugAbbrev *DWARFContext::ge
   if (AbbrevDWO)
     return AbbrevDWO.get();
 
-  DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
+  DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
   AbbrevDWO.reset(new DWARFDebugAbbrev());
   AbbrevDWO->extract(abbrData);
   return AbbrevDWO.get();
@@ -489,7 +493,7 @@ const DWARFDebugLoc *DWARFContext::getDe
   Loc.reset(new DWARFDebugLoc);
   // assume all compile units have the same address byte size
   if (getNumCompileUnits()) {
-    DWARFDataExtractor LocData(getLocSection(), isLittleEndian(),
+    DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
                                getCompileUnitAtIndex(0)->getAddressByteSize());
     Loc->parse(LocData);
   }
@@ -500,7 +504,7 @@ const DWARFDebugLocDWO *DWARFContext::ge
   if (LocDWO)
     return LocDWO.get();
 
-  DataExtractor LocData(getLocDWOSection().Data, isLittleEndian(), 0);
+  DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 0);
   LocDWO.reset(new DWARFDebugLocDWO());
   LocDWO->parse(LocData);
   return LocDWO.get();
@@ -528,8 +532,8 @@ const DWARFDebugFrame *DWARFContext::get
   // provides this information). This problem is fixed in DWARFv4
   // See this dwarf-discuss discussion for more details:
   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
-  DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
-                               getAddressSize());
+  DataExtractor debugFrameData(DObj->getDebugFrameSection(), isLittleEndian(),
+                               DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(false /* IsEH */));
   DebugFrame->parse(debugFrameData);
   return DebugFrame.get();
@@ -539,8 +543,8 @@ const DWARFDebugFrame *DWARFContext::get
   if (EHFrame)
     return EHFrame.get();
 
-  DataExtractor debugFrameData(getEHFrameSection(), isLittleEndian(),
-                               getAddressSize());
+  DataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
+                               DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(true /* IsEH */));
   DebugFrame->parse(debugFrameData);
   return DebugFrame.get();
@@ -550,7 +554,7 @@ const DWARFDebugMacro *DWARFContext::get
   if (Macro)
     return Macro.get();
 
-  DataExtractor MacinfoData(getMacinfoSection(), isLittleEndian(), 0);
+  DataExtractor MacinfoData(DObj->getMacinfoSection(), isLittleEndian(), 0);
   Macro.reset(new DWARFDebugMacro());
   Macro->parse(MacinfoData);
   return Macro.get();
@@ -579,32 +583,32 @@ DWARFContext::getLineTableForUnit(DWARFU
     return nullptr;  
 
   // We have to parse it first.
-  DWARFDataExtractor lineData(U->getLineSection(), isLittleEndian(),
+  DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
                               U->getAddressByteSize());
   return Line->getOrParseLineTable(lineData, stmtOffset);
 }
 
 void DWARFContext::parseCompileUnits() {
-  CUs.parse(*this, getInfoSection());
+  CUs.parse(*this, DObj->getInfoSection());
 }
 
 void DWARFContext::parseTypeUnits() {
   if (!TUs.empty())
     return;
-  forEachTypesSections([&](const DWARFSection &S) {
+  DObj->forEachTypesSections([&](const DWARFSection &S) {
     TUs.emplace_back();
     TUs.back().parse(*this, S);
   });
 }
 
 void DWARFContext::parseDWOCompileUnits() {
-  DWOCUs.parseDWO(*this, getInfoDWOSection());
+  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
 }
 
 void DWARFContext::parseDWOTypeUnits() {
   if (!DWOTUs.empty())
     return;
-  forEachTypesDWOSections([&](const DWARFSection &S) {
+  DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
     DWOTUs.emplace_back();
     DWOTUs.back().parseDWO(*this, S);
   });
@@ -779,6 +783,20 @@ DWARFContext::getInliningInfoForAddress(
   return InliningInfo;
 }
 
+/// DWARFContextInMemory is the simplest possible implementation of a
+/// DWARFContext. It assumes all content is available in memory and stores
+/// pointers to it.
+class DWARFContextInMemory : public DWARFContext {
+public:
+  DWARFContextInMemory(
+      const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
+      function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
+
+  DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+                       uint8_t AddrSize,
+                       bool isLittleEndian = sys::IsLittleEndianHost);
+};
+
 std::shared_ptr<DWARFContext>
 DWARFContext::getDWOContext(StringRef AbsolutePath) {
   if (auto S = DWP.lock()) {
@@ -796,7 +814,7 @@ DWARFContext::getDWOContext(StringRef Ab
   SmallString<128> DWPName;
   Expected<OwningBinary<ObjectFile>> Obj = [&] {
     if (!CheckedForDWP) {
-      (getFileName() + ".dwp").toVector(DWPName);
+      (DObj->getFileName() + ".dwp").toVector(DWPName);
       auto Obj = object::ObjectFile::createObjectFile(DWPName);
       if (Obj) {
         Entry = &DWP;
@@ -820,7 +838,7 @@ DWARFContext::getDWOContext(StringRef Ab
 
   auto S = std::make_shared<DWOFile>();
   S->File = std::move(Obj.get());
-  S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary());
+  S->Context = DWARFContext::create(*S->File.getBinary());
   *Entry = S;
   auto *Ctxt = S->Context.get();
   return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
@@ -906,208 +924,355 @@ static bool isRelocScattered(const objec
   return MachObj->isRelocationScattered(RelocInfo);
 }
 
-Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec,
-                                            StringRef Name, StringRef &Data) {
-  if (!Decompressor::isCompressed(Sec))
-    return Error::success();
-
-  Expected<Decompressor> Decompressor =
-      Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
-  if (!Decompressor)
-    return Decompressor.takeError();
-
-  SmallString<32> Out;
-  if (auto Err = Decompressor->resizeAndDecompress(Out))
-    return Err;
-
-  UncompressedSections.emplace_back(std::move(Out));
-  Data = UncompressedSections.back();
-
-  return Error::success();
-}
-
-ErrorPolicy DWARFContextInMemory::defaultErrorHandler(Error E) {
+ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
   errs() << "error: " + toString(std::move(E)) << '\n';
   return ErrorPolicy::Continue;
 }
 
-DWARFContextInMemory::DWARFContextInMemory(
-    const object::ObjectFile &Obj, const LoadedObjectInfo *L,
-    function_ref<ErrorPolicy(Error)> HandleError)
-    : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()),
-      AddressSize(Obj.getBytesInAddress()) {
-  for (const SectionRef &Section : Obj.sections()) {
-    StringRef Name;
-    Section.getName(Name);
-    // Skip BSS and Virtual sections, they aren't interesting.
-    if (Section.isBSS() || Section.isVirtual())
-      continue;
-
-    StringRef Data;
-    section_iterator RelocatedSection = Section.getRelocatedSection();
-    // Try to obtain an already relocated version of this section.
-    // Else use the unrelocated section from the object file. We'll have to
-    // apply relocations ourselves later.
-    if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
-      Section.getContents(Data);
-
-    if (auto Err = maybeDecompress(Section, Name, Data)) {
-      ErrorPolicy EP = HandleError(
-          createError("failed to decompress '" + Name + "', ", std::move(Err)));
-      if (EP == ErrorPolicy::Halt)
-        return;
-      continue;
+class DWARFObjInMemory final : public DWARFObject {
+  bool IsLittleEndian;
+  uint8_t AddressSize;
+  StringRef FileName;
+
+  using TypeSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
+                                   std::map<object::SectionRef, unsigned>>;
+
+  TypeSectionMap TypesSections;
+  TypeSectionMap TypesDWOSections;
+
+  DWARFSectionMap InfoSection;
+  DWARFSectionMap LocSection;
+  DWARFSectionMap LineSection;
+  DWARFSectionMap RangeSection;
+  DWARFSectionMap StringOffsetSection;
+  DWARFSectionMap InfoDWOSection;
+  DWARFSectionMap LineDWOSection;
+  DWARFSectionMap LocDWOSection;
+  DWARFSectionMap StringOffsetDWOSection;
+  DWARFSectionMap RangeDWOSection;
+  DWARFSectionMap AddrSection;
+  DWARFSectionMap AppleNamesSection;
+  DWARFSectionMap AppleTypesSection;
+  DWARFSectionMap AppleNamespacesSection;
+  DWARFSectionMap AppleObjCSection;
+
+  DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
+    return StringSwitch<DWARFSectionMap *>(Name)
+        .Case("debug_info", &InfoSection)
+        .Case("debug_loc", &LocSection)
+        .Case("debug_line", &LineSection)
+        .Case("debug_str_offsets", &StringOffsetSection)
+        .Case("debug_ranges", &RangeSection)
+        .Case("debug_info.dwo", &InfoDWOSection)
+        .Case("debug_loc.dwo", &LocDWOSection)
+        .Case("debug_line.dwo", &LineDWOSection)
+        .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
+        .Case("debug_addr", &AddrSection)
+        .Case("apple_names", &AppleNamesSection)
+        .Case("apple_types", &AppleTypesSection)
+        .Case("apple_namespaces", &AppleNamespacesSection)
+        .Case("apple_namespac", &AppleNamespacesSection)
+        .Case("apple_objc", &AppleObjCSection)
+        .Default(nullptr);
+  }
+
+  StringRef AbbrevSection;
+  StringRef ARangeSection;
+  StringRef DebugFrameSection;
+  StringRef EHFrameSection;
+  StringRef StringSection;
+  StringRef MacinfoSection;
+  StringRef PubNamesSection;
+  StringRef PubTypesSection;
+  StringRef GnuPubNamesSection;
+  StringRef AbbrevDWOSection;
+  StringRef StringDWOSection;
+  StringRef GnuPubTypesSection;
+  StringRef CUIndexSection;
+  StringRef GdbIndexSection;
+  StringRef TUIndexSection;
+
+  SmallVector<SmallString<32>, 4> UncompressedSections;
+
+  StringRef *mapSectionToMember(StringRef Name) {
+    if (DWARFSection *Sec = mapNameToDWARFSection(Name))
+      return &Sec->Data;
+    return StringSwitch<StringRef *>(Name)
+        .Case("debug_abbrev", &AbbrevSection)
+        .Case("debug_aranges", &ARangeSection)
+        .Case("debug_frame", &DebugFrameSection)
+        .Case("eh_frame", &EHFrameSection)
+        .Case("debug_str", &StringSection)
+        .Case("debug_macinfo", &MacinfoSection)
+        .Case("debug_pubnames", &PubNamesSection)
+        .Case("debug_pubtypes", &PubTypesSection)
+        .Case("debug_gnu_pubnames", &GnuPubNamesSection)
+        .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
+        .Case("debug_abbrev.dwo", &AbbrevDWOSection)
+        .Case("debug_str.dwo", &StringDWOSection)
+        .Case("debug_cu_index", &CUIndexSection)
+        .Case("debug_tu_index", &TUIndexSection)
+        .Case("gdb_index", &GdbIndexSection)
+        // Any more debug info sections go here.
+        .Default(nullptr);
+  }
+
+  /// If Sec is compressed section, decompresses and updates its contents
+  /// provided by Data. Otherwise leaves it unchanged.
+  Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
+                        StringRef &Data) {
+    if (!Decompressor::isCompressed(Sec))
+      return Error::success();
+
+    Expected<Decompressor> Decompressor =
+        Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
+    if (!Decompressor)
+      return Decompressor.takeError();
+
+    SmallString<32> Out;
+    if (auto Err = Decompressor->resizeAndDecompress(Out))
+      return Err;
+
+    UncompressedSections.emplace_back(std::move(Out));
+    Data = UncompressedSections.back();
+
+    return Error::success();
+  }
+
+public:
+  DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+                   uint8_t AddrSize, bool IsLittleEndian)
+      : IsLittleEndian(IsLittleEndian) {
+    for (const auto &SecIt : Sections) {
+      if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
+        *SectionData = SecIt.second->getBuffer();
     }
+  }
+  DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
+                   function_ref<ErrorPolicy(Error)> HandleError)
+      : IsLittleEndian(Obj.isLittleEndian()),
+        AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()) {
+
+    for (const SectionRef &Section : Obj.sections()) {
+      StringRef Name;
+      Section.getName(Name);
+      // Skip BSS and Virtual sections, they aren't interesting.
+      if (Section.isBSS() || Section.isVirtual())
+        continue;
 
-    // Compressed sections names in GNU style starts from ".z",
-    // at this point section is decompressed and we drop compression prefix.
-    Name = Name.substr(
-        Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
-
-    // Map platform specific debug section names to DWARF standard section
-    // names.
-    Name = Obj.mapDebugSectionName(Name);
-
-    if (StringRef *SectionData = mapSectionToMember(Name)) {
-      *SectionData = Data;
-      if (Name == "debug_ranges") {
-        // FIXME: Use the other dwo range section when we emit it.
-        RangeDWOSection.Data = Data;
+      StringRef Data;
+      section_iterator RelocatedSection = Section.getRelocatedSection();
+      // Try to obtain an already relocated version of this section.
+      // Else use the unrelocated section from the object file. We'll have to
+      // apply relocations ourselves later.
+      if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data))
+        Section.getContents(Data);
+
+      if (auto Err = maybeDecompress(Section, Name, Data)) {
+        ErrorPolicy EP = HandleError(createError(
+            "failed to decompress '" + Name + "', ", std::move(Err)));
+        if (EP == ErrorPolicy::Halt)
+          return;
+        continue;
       }
-    } else if (Name == "debug_types") {
-      // Find debug_types data by section rather than name as there are
-      // multiple, comdat grouped, debug_types sections.
-      TypesSections[Section].Data = Data;
-    } else if (Name == "debug_types.dwo") {
-      TypesDWOSections[Section].Data = Data;
-    }
 
-    if (RelocatedSection == Obj.section_end())
-      continue;
+      // Compressed sections names in GNU style starts from ".z",
+      // at this point section is decompressed and we drop compression prefix.
+      Name = Name.substr(
+          Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
+
+      // Map platform specific debug section names to DWARF standard section
+      // names.
+      Name = Obj.mapDebugSectionName(Name);
+
+      if (StringRef *SectionData = mapSectionToMember(Name)) {
+        *SectionData = Data;
+        if (Name == "debug_ranges") {
+          // FIXME: Use the other dwo range section when we emit it.
+          RangeDWOSection.Data = Data;
+        }
+      } else if (Name == "debug_types") {
+        // Find debug_types data by section rather than name as there are
+        // multiple, comdat grouped, debug_types sections.
+        TypesSections[Section].Data = Data;
+      } else if (Name == "debug_types.dwo") {
+        TypesDWOSections[Section].Data = Data;
+      }
 
-    StringRef RelSecName;
-    StringRef RelSecData;
-    RelocatedSection->getName(RelSecName);
-
-    // If the section we're relocating was relocated already by the JIT,
-    // then we used the relocated version above, so we do not need to process
-    // relocations for it now.
-    if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
-      continue;
-
-    // In Mach-o files, the relocations do not need to be applied if
-    // there is no load offset to apply. The value read at the
-    // relocation point already factors in the section address
-    // (actually applying the relocations will produce wrong results
-    // as the section address will be added twice).
-    if (!L && isa<MachOObjectFile>(&Obj))
-      continue;
-
-    RelSecName = RelSecName.substr(
-        RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
-
-    // TODO: Add support for relocations in other sections as needed.
-    // Record relocations for the debug_info and debug_line sections.
-    DWARFSection *Sec = mapNameToDWARFSection(RelSecName);
-    RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
-    if (!Map) {
-      // Find debug_types relocs by section rather than name as there are
-      // multiple, comdat grouped, debug_types sections.
-      if (RelSecName == "debug_types")
-        Map = &TypesSections[*RelocatedSection].Relocs;
-      else if (RelSecName == "debug_types.dwo")
-        Map = &TypesDWOSections[*RelocatedSection].Relocs;
-      else
+      if (RelocatedSection == Obj.section_end())
         continue;
-    }
-
-    if (Section.relocation_begin() == Section.relocation_end())
-      continue;
 
-    // Symbol to [address, section index] cache mapping.
-    std::map<SymbolRef, SymInfo> AddrCache;
-    for (const RelocationRef &Reloc : Section.relocations()) {
-      // FIXME: it's not clear how to correctly handle scattered
-      // relocations.
-      if (isRelocScattered(Obj, Reloc))
+      StringRef RelSecName;
+      StringRef RelSecData;
+      RelocatedSection->getName(RelSecName);
+
+      // If the section we're relocating was relocated already by the JIT,
+      // then we used the relocated version above, so we do not need to process
+      // relocations for it now.
+      if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
         continue;
 
-      Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
-      if (!SymInfoOrErr) {
-        if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
-          return;
+      // In Mach-o files, the relocations do not need to be applied if
+      // there is no load offset to apply. The value read at the
+      // relocation point already factors in the section address
+      // (actually applying the relocations will produce wrong results
+      // as the section address will be added twice).
+      if (!L && isa<MachOObjectFile>(&Obj))
         continue;
+
+      RelSecName = RelSecName.substr(
+          RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
+
+      // TODO: Add support for relocations in other sections as needed.
+      // Record relocations for the debug_info and debug_line sections.
+      DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
+      RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
+      if (!Map) {
+        // Find debug_types relocs by section rather than name as there are
+        // multiple, comdat grouped, debug_types sections.
+        if (RelSecName == "debug_types")
+          Map =
+              &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
+                   .Relocs;
+        else if (RelSecName == "debug_types.dwo")
+          Map = &static_cast<DWARFSectionMap &>(
+                     TypesDWOSections[*RelocatedSection])
+                     .Relocs;
+        else
+          continue;
       }
 
-      object::RelocVisitor V(Obj);
-      uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
-      if (V.error()) {
-        SmallString<32> Type;
-        Reloc.getTypeName(Type);
-        ErrorPolicy EP = HandleError(
-            createError("failed to compute relocation: " + Type + ", ",
-                        errorCodeToError(object_error::parse_failed)));
-        if (EP == ErrorPolicy::Halt)
-          return;
+      if (Section.relocation_begin() == Section.relocation_end())
         continue;
+
+      // Symbol to [address, section index] cache mapping.
+      std::map<SymbolRef, SymInfo> AddrCache;
+      for (const RelocationRef &Reloc : Section.relocations()) {
+        // FIXME: it's not clear how to correctly handle scattered
+        // relocations.
+        if (isRelocScattered(Obj, Reloc))
+          continue;
+
+        Expected<SymInfo> SymInfoOrErr =
+            getSymbolInfo(Obj, Reloc, L, AddrCache);
+        if (!SymInfoOrErr) {
+          if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
+            return;
+          continue;
+        }
+
+        object::RelocVisitor V(Obj);
+        uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address);
+        if (V.error()) {
+          SmallString<32> Type;
+          Reloc.getTypeName(Type);
+          ErrorPolicy EP = HandleError(
+              createError("failed to compute relocation: " + Type + ", ",
+                          errorCodeToError(object_error::parse_failed)));
+          if (EP == ErrorPolicy::Halt)
+            return;
+          continue;
+        }
+        RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
+        Map->insert({Reloc.getOffset(), Rel});
       }
-      RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
-      Map->insert({Reloc.getOffset(), Rel});
     }
   }
-}
 
-DWARFContextInMemory::DWARFContextInMemory(
-    const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize,
-    bool isLittleEndian)
-    : IsLittleEndian(isLittleEndian), AddressSize(AddrSize) {
-  for (const auto &SecIt : Sections) {
-    if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
-      *SectionData = SecIt.second->getBuffer();
+  Optional<RelocAddrEntry> find(const DWARFSection &S,
+                                uint64_t Pos) const override {
+    auto &Sec = static_cast<const DWARFSectionMap &>(S);
+    RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
+    if (AI == Sec.Relocs.end())
+      return None;
+    return AI->second;
+  }
+
+  bool isLittleEndian() const override { return IsLittleEndian; }
+  StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
+  const DWARFSection &getLineDWOSection() const override {
+    return LineDWOSection;
+  }
+  const DWARFSection &getLocDWOSection() const override {
+    return LocDWOSection;
+  }
+  StringRef getStringDWOSection() const override { return StringDWOSection; }
+  const DWARFSection &getStringOffsetDWOSection() const override {
+    return StringOffsetDWOSection;
+  }
+  const DWARFSection &getRangeDWOSection() const override {
+    return RangeDWOSection;
+  }
+  const DWARFSection &getAddrSection() const override { return AddrSection; }
+  StringRef getCUIndexSection() const override { return CUIndexSection; }
+  StringRef getGdbIndexSection() const override { return GdbIndexSection; }
+  StringRef getTUIndexSection() const override { return TUIndexSection; }
+
+  // DWARF v5
+  const DWARFSection &getStringOffsetSection() const override {
+    return StringOffsetSection;
+  }
+
+  // Sections for DWARF5 split dwarf proposal.
+  const DWARFSection &getInfoDWOSection() const override {
+    return InfoDWOSection;
+  }
+  void forEachTypesDWOSections(
+      function_ref<void(const DWARFSection &)> F) const override {
+    for (auto &P : TypesDWOSections)
+      F(P.second);
+  }
+
+  StringRef getAbbrevSection() const override { return AbbrevSection; }
+  const DWARFSection &getLocSection() const override { return LocSection; }
+  StringRef getARangeSection() const override { return ARangeSection; }
+  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
+  StringRef getEHFrameSection() const override { return EHFrameSection; }
+  const DWARFSection &getLineSection() const override { return LineSection; }
+  StringRef getStringSection() const override { return StringSection; }
+  const DWARFSection &getRangeSection() const override { return RangeSection; }
+  StringRef getMacinfoSection() const override { return MacinfoSection; }
+  StringRef getPubNamesSection() const override { return PubNamesSection; }
+  StringRef getPubTypesSection() const override { return PubTypesSection; }
+  StringRef getGnuPubNamesSection() const override {
+    return GnuPubNamesSection;
+  }
+  StringRef getGnuPubTypesSection() const override {
+    return GnuPubTypesSection;
+  }
+  const DWARFSection &getAppleNamesSection() const override {
+    return AppleNamesSection;
+  }
+  const DWARFSection &getAppleTypesSection() const override {
+    return AppleTypesSection;
+  }
+  const DWARFSection &getAppleNamespacesSection() const override {
+    return AppleNamespacesSection;
+  }
+  const DWARFSection &getAppleObjCSection() const override {
+    return AppleObjCSection;
+  }
+
+  StringRef getFileName() const override { return FileName; }
+  uint8_t getAddressSize() const override { return AddressSize; }
+  const DWARFSection &getInfoSection() const override { return InfoSection; }
+  void forEachTypesSections(
+      function_ref<void(const DWARFSection &)> F) const override {
+    for (auto &P : TypesSections)
+      F(P.second);
   }
-}
+};
 
-DWARFSection *DWARFContextInMemory::mapNameToDWARFSection(StringRef Name) {
-  return StringSwitch<DWARFSection *>(Name)
-      .Case("debug_info", &InfoSection)
-      .Case("debug_loc", &LocSection)
-      .Case("debug_line", &LineSection)
-      .Case("debug_str_offsets", &StringOffsetSection)
-      .Case("debug_ranges", &RangeSection)
-      .Case("debug_info.dwo", &InfoDWOSection)
-      .Case("debug_loc.dwo", &LocDWOSection)
-      .Case("debug_line.dwo", &LineDWOSection)
-      .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
-      .Case("debug_addr", &AddrSection)
-      .Case("apple_names", &AppleNamesSection)
-      .Case("apple_types", &AppleTypesSection)
-      .Case("apple_namespaces", &AppleNamespacesSection)
-      .Case("apple_namespac", &AppleNamespacesSection)
-      .Case("apple_objc", &AppleObjCSection)
-      .Default(nullptr);
-}
-
-StringRef *DWARFContextInMemory::mapSectionToMember(StringRef Name) {
-  if (DWARFSection *Sec = mapNameToDWARFSection(Name))
-    return &Sec->Data;
-  return StringSwitch<StringRef *>(Name)
-      .Case("debug_abbrev", &AbbrevSection)
-      .Case("debug_aranges", &ARangeSection)
-      .Case("debug_frame", &DebugFrameSection)
-      .Case("eh_frame", &EHFrameSection)
-      .Case("debug_str", &StringSection)
-      .Case("debug_macinfo", &MacinfoSection)
-      .Case("debug_pubnames", &PubNamesSection)
-      .Case("debug_pubtypes", &PubTypesSection)
-      .Case("debug_gnu_pubnames", &GnuPubNamesSection)
-      .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
-      .Case("debug_abbrev.dwo", &AbbrevDWOSection)
-      .Case("debug_str.dwo", &StringDWOSection)
-      .Case("debug_cu_index", &CUIndexSection)
-      .Case("debug_tu_index", &TUIndexSection)
-      .Case("gdb_index", &GdbIndexSection)
-      // Any more debug info sections go here.
-      .Default(nullptr);
+std::unique_ptr<DWARFContext>
+DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
+                     function_ref<ErrorPolicy(Error)> HandleError) {
+  auto DObj = make_unique<DWARFObjInMemory>(Obj, L, HandleError);
+  return make_unique<DWARFContext>(std::move(DObj));
 }
 
-void DWARFContextInMemory::anchor() {}
+std::unique_ptr<DWARFContext>
+DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+                     uint8_t AddrSize, bool isLittleEndian) {
+  auto DObj = make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
+  return make_unique<DWARFContext>(std::move(DObj));
+}

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp Wed Jul 19 15:27:28 2017
@@ -8,17 +8,18 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
 
 using namespace llvm;
 
 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
                                                uint64_t *SecNdx) const {
-  if (!RelocMap)
+  if (!Section)
     return getUnsigned(Off, Size);
-  RelocAddrMap::const_iterator AI = RelocMap->find(*Off);
-  if (AI == RelocMap->end())
+  Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
+  if (!Rel)
     return getUnsigned(Off, Size);
   if (SecNdx)
-    *SecNdx = AI->second.SectionIndex;
-  return getUnsigned(Off, Size) + AI->second.Value;
+    *SecNdx = Rel->SectionIndex;
+  return getUnsigned(Off, Size) + Rel->Value;
 }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp Wed Jul 19 15:27:28 2017
@@ -43,7 +43,8 @@ void DWARFDebugAranges::generate(DWARFCo
     return;
 
   // Extract aranges from .debug_aranges section.
-  DataExtractor ArangesData(CTX->getARangeSection(), CTX->isLittleEndian(), 0);
+  DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
+                            CTX->isLittleEndian(), 0);
   extract(ArangesData);
 
   // Generate aranges from DIEs: even if .debug_aranges section is present,

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Wed Jul 19 15:27:28 2017
@@ -30,17 +30,19 @@ using namespace llvm;
 using namespace dwarf;
 
 void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
-  parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
-            C.getStringSection(), C.getStringOffsetSection(),
-            &C.getAddrSection(), C.getLineSection(), C.isLittleEndian(), false);
+  const DWARFObject &D = C.getDWARFObj();
+  parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(),
+            D.getStringSection(), D.getStringOffsetSection(),
+            &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false);
 }
 
 void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
                                     const DWARFSection &DWOSection,
                                     DWARFUnitIndex *Index) {
-  parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(),
-            C.getStringDWOSection(), C.getStringOffsetDWOSection(),
-            &C.getAddrSection(), C.getLineDWOSection(), C.isLittleEndian(),
+  const DWARFObject &D = C.getDWARFObj();
+  parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
+            D.getStringDWOSection(), D.getStringOffsetDWOSection(),
+            &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
             true);
 }
 
@@ -59,13 +61,18 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, c
 
 DWARFUnit::~DWARFUnit() = default;
 
+DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
+  return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
+                            getAddressByteSize());
+}
+
 bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
                                                 uint64_t &Result) const {
   uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
   if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
     return false;
-  DWARFDataExtractor DA(*AddrOffsetSection, isLittleEndian,
-                        getAddressByteSize());
+  DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
+                        isLittleEndian, getAddressByteSize());
   Result = DA.getRelocatedAddress(&Offset);
   return true;
 }
@@ -76,7 +83,8 @@ bool DWARFUnit::getStringOffsetSectionIt
   uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
   if (StringOffsetSection.Data.size() < Offset + ItemSize)
     return false;
-  DWARFDataExtractor DA(StringOffsetSection, isLittleEndian, 0);
+  DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+                        isLittleEndian, 0);
   Result = DA.getRelocatedValue(ItemSize, &Offset);
   return true;
 }
@@ -141,8 +149,8 @@ bool DWARFUnit::extractRangeList(uint32_
                                  DWARFDebugRangeList &RangeList) const {
   // Require that compile unit is extracted.
   assert(!DieArray.empty());
-  DWARFDataExtractor RangesData(*RangeSection, isLittleEndian,
-                                getAddressByteSize());
+  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
+                                isLittleEndian, getAddressByteSize());
   uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
   return RangeList.extract(RangesData, &ActualRangeListOffset);
 }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Wed Jul 19 15:27:28 2017
@@ -105,8 +105,9 @@ bool DWARFVerifier::verifyUnitContents(D
 bool DWARFVerifier::handleDebugInfo() {
   OS << "Verifying .debug_info Unit Header Chain...\n";
 
-  DWARFDataExtractor DebugInfoData(DCtx.getInfoSection(), DCtx.isLittleEndian(),
-                                   0);
+  const DWARFObject &DObj = DCtx.getDWARFObj();
+  DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(),
+                                   DCtx.isLittleEndian(), 0);
   uint32_t NumDebugInfoErrors = 0;
   uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
   uint8_t UnitType = 0;
@@ -127,10 +128,10 @@ bool DWARFVerifier::handleDebugInfo() {
       case dwarf::DW_UT_split_type: {
         DWARFUnitSection<DWARFTypeUnit> TUSection{};
         Unit.reset(new DWARFTypeUnit(
-            DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(),
-            &DCtx.getRangeSection(), DCtx.getStringSection(),
-            DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(),
-            DCtx.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
+            DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
+            &DObj.getRangeSection(), DObj.getStringSection(),
+            DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+            DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection,
             nullptr));
         break;
       }
@@ -143,10 +144,10 @@ bool DWARFVerifier::handleDebugInfo() {
       case 0: {
         DWARFUnitSection<DWARFCompileUnit> CUSection{};
         Unit.reset(new DWARFCompileUnit(
-            DCtx, DCtx.getInfoSection(), DCtx.getDebugAbbrev(),
-            &DCtx.getRangeSection(), DCtx.getStringSection(),
-            DCtx.getStringOffsetSection(), &DCtx.getAppleObjCSection(),
-            DCtx.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
+            DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
+            &DObj.getRangeSection(), DObj.getStringSection(),
+            DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+            DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection,
             nullptr));
         break;
       }
@@ -169,13 +170,14 @@ bool DWARFVerifier::handleDebugInfo() {
 
 unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
                                                  DWARFAttribute &AttrValue) {
+  const DWARFObject &DObj = DCtx.getDWARFObj();
   unsigned NumErrors = 0;
   const auto Attr = AttrValue.Attr;
   switch (Attr) {
   case DW_AT_ranges:
     // Make sure the offset in the DW_AT_ranges attribute is valid.
     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
-      if (*SectionOffset >= DCtx.getRangeSection().Data.size()) {
+      if (*SectionOffset >= DObj.getRangeSection().Data.size()) {
         ++NumErrors;
         OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
               "bounds:\n";
@@ -192,7 +194,7 @@ unsigned DWARFVerifier::verifyDebugInfoA
   case DW_AT_stmt_list:
     // Make sure the offset in the DW_AT_stmt_list attribute is valid.
     if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
-      if (*SectionOffset >= DCtx.getLineSection().Data.size()) {
+      if (*SectionOffset >= DObj.getLineSection().Data.size()) {
         ++NumErrors;
         OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
               "bounds: "
@@ -216,6 +218,7 @@ unsigned DWARFVerifier::verifyDebugInfoA
 
 unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
                                             DWARFAttribute &AttrValue) {
+  const DWARFObject &DObj = DCtx.getDWARFObj();
   unsigned NumErrors = 0;
   const auto Form = AttrValue.Value.getForm();
   switch (Form) {
@@ -253,7 +256,7 @@ unsigned DWARFVerifier::verifyDebugInfoF
     Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
     assert(RefVal);
     if (RefVal) {
-      if (*RefVal >= DCtx.getInfoSection().Data.size()) {
+      if (*RefVal >= DObj.getInfoSection().Data.size()) {
         ++NumErrors;
         OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
               "bounds:\n";
@@ -270,7 +273,7 @@ unsigned DWARFVerifier::verifyDebugInfoF
   case DW_FORM_strp: {
     auto SecOffset = AttrValue.Value.getAsSectionOffset();
     assert(SecOffset); // DW_FORM_strp is a section offset.
-    if (SecOffset && *SecOffset >= DCtx.getStringSection().size()) {
+    if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
       ++NumErrors;
       OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
       Die.dump(OS, 0);
@@ -318,7 +321,7 @@ void DWARFVerifier::verifyDebugLineStmtO
       continue;
     const uint32_t LineTableOffset = *StmtSectionOffset;
     auto LineTable = DCtx.getLineTableForUnit(CU.get());
-    if (LineTableOffset < DCtx.getLineSection().Data.size()) {
+    if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
       if (!LineTable) {
         ++NumDebugLineErrors;
         OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
@@ -408,10 +411,10 @@ bool DWARFVerifier::handleDebugLine() {
 
 bool DWARFVerifier::handleAppleNames() {
   NumAppleNamesErrors = 0;
-
-  DWARFDataExtractor AppleNamesSection(DCtx.getAppleNamesSection(),
+  const DWARFObject &D = DCtx.getDWARFObj();
+  DWARFDataExtractor AppleNamesSection(D, D.getAppleNamesSection(),
                                        DCtx.isLittleEndian(), 0);
-  DataExtractor StrData(DCtx.getStringSection(), DCtx.isLittleEndian(), 0);
+  DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
   DWARFAcceleratorTable AppleNames(AppleNamesSection, StrData);
 
   if (!AppleNames.extract()) {

Modified: llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp Wed Jul 19 15:27:28 2017
@@ -409,7 +409,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(co
     }
   }
   if (!Context)
-    Context.reset(new DWARFContextInMemory(*Objects.second));
+    Context = DWARFContext::create(*Objects.second);
   assert(Context);
   auto InfoOrErr =
       SymbolizableObjectFile::create(Objects.first, std::move(Context));

Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Wed Jul 19 15:27:28 2017
@@ -845,7 +845,7 @@ void DwarfStreamer::emitLocationsForUnit
   MS->SwitchSection(MC->getObjectFileInfo()->getDwarfLocSection());
 
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
-  const DWARFSection &InputSec = Dwarf.getLocSection();
+  const DWARFSection &InputSec = Dwarf.getDWARFObj().getLocSection();
   DataExtractor Data(InputSec.Data, Dwarf.isLittleEndian(), AddressSize);
   DWARFUnit &OrigUnit = Unit.getOrigUnit();
   auto OrigUnitDie = OrigUnit.getUnitDIE(false);
@@ -1301,7 +1301,7 @@ private:
     /// Construct the output DIE tree by cloning the DIEs we
     /// chose to keep above. If there are no valid relocs, then there's
     /// nothing to clone/emit.
-    void cloneAllCompileUnits(DWARFContextInMemory &DwarfContext);
+    void cloneAllCompileUnits(DWARFContext &DwarfContext);
 
   private:
     typedef DWARFAbbreviationDeclaration::AttributeSpec AttributeSpec;
@@ -2873,7 +2873,8 @@ void DwarfLinker::patchRangesForUnit(con
   DWARFDebugRangeList RangeList;
   const auto &FunctionRanges = Unit.getFunctionRanges();
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();
-  DWARFDataExtractor RangeExtractor(OrigDwarf.getRangeSection(),
+  DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),
+                                    OrigDwarf.getDWARFObj().getRangeSection(),
                                     OrigDwarf.isLittleEndian(), AddressSize);
   auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
   DWARFUnit &OrigUnit = Unit.getOrigUnit();
@@ -2984,9 +2985,9 @@ void DwarfLinker::patchLineTableForUnit(
   // Parse the original line info for the unit.
   DWARFDebugLine::LineTable LineTable;
   uint32_t StmtOffset = *StmtList;
-  DWARFDataExtractor LineExtractor(OrigDwarf.getLineSection(),
-                                   OrigDwarf.isLittleEndian(),
-                                   Unit.getOrigUnit().getAddressByteSize());
+  DWARFDataExtractor LineExtractor(
+      OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(),
+      OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize());
   LineTable.parse(LineExtractor, &StmtOffset);
 
   // This vector is the output line table.
@@ -3086,7 +3087,7 @@ void DwarfLinker::patchLineTableForUnit(
       LineTable.Prologue.OpcodeBase > 13)
     reportWarning("line table parameters mismatch. Cannot emit.");
   else {
-    StringRef LineData = OrigDwarf.getLineSection().Data;
+    StringRef LineData = OrigDwarf.getDWARFObj().getLineSection().Data;
     MCDwarfLineTableParams Params;
     Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
     Params.DWARF2LineBase = LineTable.Prologue.LineBase;
@@ -3112,7 +3113,7 @@ void DwarfLinker::emitAcceleratorEntries
 void DwarfLinker::patchFrameInfoForObject(const DebugMapObject &DMO,
                                           DWARFContext &OrigDwarf,
                                           unsigned AddrSize) {
-  StringRef FrameData = OrigDwarf.getDebugFrameSection();
+  StringRef FrameData = OrigDwarf.getDWARFObj().getDebugFrameSection();
   if (FrameData.empty())
     return;
 
@@ -3323,9 +3324,9 @@ void DwarfLinker::loadClangModule(String
   std::unique_ptr<CompileUnit> Unit;
 
   // Setup access to the debug info.
-  DWARFContextInMemory DwarfContext(*ErrOrObj);
+  auto DwarfContext = DWARFContext::create(*ErrOrObj);
   RelocationManager RelocMgr(*this);
-  for (const auto &CU : DwarfContext.compile_units()) {
+  for (const auto &CU : DwarfContext->compile_units()) {
     auto CUDie = CU->getUnitDIE(false);
     // Recursively get all modules imported by this one.
     if (!registerModuleReference(CUDie, *CU, ModuleMap, Indent)) {
@@ -3365,11 +3366,10 @@ void DwarfLinker::loadClangModule(String
   std::vector<std::unique_ptr<CompileUnit>> CompileUnits;
   CompileUnits.push_back(std::move(Unit));
   DIECloner(*this, RelocMgr, DIEAlloc, CompileUnits, Options)
-      .cloneAllCompileUnits(DwarfContext);
+      .cloneAllCompileUnits(*DwarfContext);
 }
 
-void DwarfLinker::DIECloner::cloneAllCompileUnits(
-    DWARFContextInMemory &DwarfContext) {
+void DwarfLinker::DIECloner::cloneAllCompileUnits(DWARFContext &DwarfContext) {
   if (!Linker.Streamer)
     return;
 
@@ -3438,11 +3438,11 @@ bool DwarfLinker::link(const DebugMap &M
     }
 
     // Setup access to the debug info.
-    DWARFContextInMemory DwarfContext(*ErrOrObj);
-    startDebugObject(DwarfContext, *Obj);
+    auto DwarfContext = DWARFContext::create(*ErrOrObj);
+    startDebugObject(*DwarfContext, *Obj);
 
     // In a first phase, just read in the debug info and load all clang modules.
-    for (const auto &CU : DwarfContext.compile_units()) {
+    for (const auto &CU : DwarfContext->compile_units()) {
       auto CUDie = CU->getUnitDIE(false);
       if (Options.Verbose) {
         outs() << "Input compilation unit:";
@@ -3476,9 +3476,9 @@ bool DwarfLinker::link(const DebugMap &M
     RelocMgr.resetValidRelocs();
     if (RelocMgr.hasValidRelocs())
       DIECloner(*this, RelocMgr, DIEAlloc, Units, Options)
-          .cloneAllCompileUnits(DwarfContext);
+          .cloneAllCompileUnits(*DwarfContext);
     if (!Options.NoOutput && !Units.empty())
-      patchFrameInfoForObject(*Obj, DwarfContext,
+      patchFrameInfoForObject(*Obj, *DwarfContext,
                               Units[0]->getOrigUnit().getAddressByteSize());
 
     // Clean-up before starting working on the next object.

Modified: llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp (original)
+++ llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp Wed Jul 19 15:27:28 2017
@@ -94,7 +94,7 @@ static void error(StringRef Filename, st
 }
 
 static void DumpObjectFile(ObjectFile &Obj, Twine Filename) {
-  std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(Obj));
+  std::unique_ptr<DIContext> DICtx = DWARFContext::create(Obj);
 
   outs() << Filename.str() << ":\tfile format " << Obj.getFileFormatName()
          << "\n\n";
@@ -131,8 +131,8 @@ static void DumpInput(StringRef Filename
 }
 
 static bool VerifyObjectFile(ObjectFile &Obj, Twine Filename) {
-  std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(Obj));
-  
+  std::unique_ptr<DIContext> DICtx = DWARFContext::create(Obj);
+
   // Verify the DWARF and exit with non-zero exit status if verification
   // fails.
   raw_ostream &stream = Quiet ? nulls() : outs();

Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Wed Jul 19 15:27:28 2017
@@ -1275,7 +1275,7 @@ static void ProcessMachO(StringRef Name,
     printWeakBindTable(MachOOF);
 
   if (DwarfDumpType != DIDT_Null) {
-    std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*MachOOF));
+    std::unique_ptr<DIContext> DICtx = DWARFContext::create(*MachOOF);
     // Dump the complete DWARF structure.
     DIDumpOptions DumpOpts;
     DumpOpts.DumpType = DwarfDumpType;
@@ -6594,7 +6594,7 @@ static void DisassembleMachO(StringRef F
     }
 
     // Setup the DIContext
-    diContext.reset(new DWARFContextInMemory(*DbgObj));
+    diContext = DWARFContext::create(*DbgObj);
   }
 
   if (FilterSections.size() == 0)

Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
+++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Wed Jul 19 15:27:28 2017
@@ -62,8 +62,8 @@
 #include <cctype>
 #include <cstring>
 #include <system_error>
-#include <utility>
 #include <unordered_map>
+#include <utility>
 
 using namespace llvm;
 using namespace object;
@@ -2081,7 +2081,7 @@ static void DumpObject(ObjectFile *o, co
   if (PrintFaultMaps)
     printFaultMaps(o);
   if (DwarfDumpType != DIDT_Null) {
-    std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
+    std::unique_ptr<DIContext> DICtx = DWARFContext::create(*o);
     // Dump the complete DWARF structure.
     DIDumpOptions DumpOpts;
     DumpOpts.DumpType = DwarfDumpType;

Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Wed Jul 19 15:27:28 2017
@@ -324,8 +324,8 @@ static int printLineInfoForInput(bool Lo
       }
     }
 
-    std::unique_ptr<DIContext> Context(
-      new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get()));
+    std::unique_ptr<DIContext> Context =
+        DWARFContext::create(*SymbolObj, LoadedObjInfo.get());
 
     std::vector<std::pair<SymbolRef, uint64_t>> SymAddr =
         object::computeSymbolSizes(*SymbolObj);

Modified: llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp Wed Jul 19 15:27:28 2017
@@ -24,7 +24,7 @@ void dumpInitialLength(DataExtractor &Da
     InitialLength.TotalLength64 = Data.getU64(&Offset);
 }
 
-void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugAbbrev(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   auto AbbrevSetPtr = DCtx.getDebugAbbrev();
   if (AbbrevSetPtr) {
     for (auto AbbrvDeclSet : *AbbrevSetPtr) {
@@ -48,8 +48,8 @@ void dumpDebugAbbrev(DWARFContextInMemor
   }
 }
 
-void dumpDebugStrings(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
-  StringRef RemainingTable = DCtx.getStringSection();
+void dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  StringRef RemainingTable = DCtx.getDWARFObj().getStringSection();
   while (RemainingTable.size() > 0) {
     auto SymbolPair = RemainingTable.split('\0');
     RemainingTable = SymbolPair.second;
@@ -57,8 +57,9 @@ void dumpDebugStrings(DWARFContextInMemo
   }
 }
 
-void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
-  DataExtractor ArangesData(DCtx.getARangeSection(), DCtx.isLittleEndian(), 0);
+void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  DataExtractor ArangesData(DCtx.getDWARFObj().getARangeSection(),
+                            DCtx.isLittleEndian(), 0);
   uint32_t Offset = 0;
   DWARFDebugArangeSet Set;
 
@@ -79,7 +80,7 @@ void dumpDebugARanges(DWARFContextInMemo
   }
 }
 
-void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y,
+void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y,
                     StringRef Section) {
   DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0);
   uint32_t Offset = 0;
@@ -97,21 +98,22 @@ void dumpPubSection(DWARFContextInMemory
   }
 }
 
-void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) {
+  const DWARFObject &D = DCtx.getDWARFObj();
   Y.PubNames.IsGNUStyle = false;
-  dumpPubSection(DCtx, Y.PubNames, DCtx.getPubNamesSection());
+  dumpPubSection(DCtx, Y.PubNames, D.getPubNamesSection());
 
   Y.PubTypes.IsGNUStyle = false;
-  dumpPubSection(DCtx, Y.PubTypes, DCtx.getPubTypesSection());
+  dumpPubSection(DCtx, Y.PubTypes, D.getPubTypesSection());
 
   Y.GNUPubNames.IsGNUStyle = true;
-  dumpPubSection(DCtx, Y.GNUPubNames, DCtx.getGnuPubNamesSection());
+  dumpPubSection(DCtx, Y.GNUPubNames, D.getGnuPubNamesSection());
 
   Y.GNUPubTypes.IsGNUStyle = true;
-  dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection());
+  dumpPubSection(DCtx, Y.GNUPubTypes, D.getGnuPubTypesSection());
 }
 
-void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   for (const auto &CU : DCtx.compile_units()) {
     DWARFYAML::Unit NewUnit;
     NewUnit.Length.setLength(CU->getLength());
@@ -235,7 +237,7 @@ bool dumpFileEntry(DataExtractor &Data,
   return true;
 }
 
-void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   for (const auto &CU : DCtx.compile_units()) {
     auto CUDIE = CU->getUnitDIE();
     if (!CUDIE)
@@ -243,8 +245,8 @@ void dumpDebugLines(DWARFContextInMemory
     if (auto StmtOffset =
             dwarf::toSectionOffset(CUDIE.find(dwarf::DW_AT_stmt_list))) {
       DWARFYAML::LineTable DebugLines;
-      DataExtractor LineData(DCtx.getLineSection().Data, DCtx.isLittleEndian(),
-                             CU->getAddressByteSize());
+      DataExtractor LineData(DCtx.getDWARFObj().getLineSection().Data,
+                             DCtx.isLittleEndian(), CU->getAddressByteSize());
       uint32_t Offset = *StmtOffset;
       dumpInitialLength(LineData, Offset, DebugLines.Length);
       uint64_t LineTableLength = DebugLines.Length.getLength();
@@ -344,7 +346,7 @@ void dumpDebugLines(DWARFContextInMemory
   }
 }
 
-std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
+std::error_code dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
   dumpDebugAbbrev(DCtx, Y);
   dumpDebugStrings(DCtx, Y);
   dumpDebugARanges(DCtx, Y);

Modified: llvm/trunk/tools/obj2yaml/macho2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/macho2yaml.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/macho2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/macho2yaml.cpp Wed Jul 19 15:27:28 2017
@@ -35,9 +35,9 @@ class MachODumper {
                        ArrayRef<uint8_t> OpcodeBuffer, bool Lazy = false);
   void dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y);
   void dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y);
-  void dumpDebugAbbrev(DWARFContextInMemory &DCtx,
+  void dumpDebugAbbrev(DWARFContext &DCtx,
                        std::unique_ptr<MachOYAML::Object> &Y);
-  void dumpDebugStrings(DWARFContextInMemory &DCtx,
+  void dumpDebugStrings(DWARFContext &DCtx,
                         std::unique_ptr<MachOYAML::Object> &Y);
 
 public:
@@ -187,8 +187,8 @@ Expected<std::unique_ptr<MachOYAML::Obje
   dumpLoadCommands(Y);
   dumpLinkEdit(Y);
 
-  DWARFContextInMemory DICtx(Obj);
-  if (auto Err = dwarf2yaml(DICtx, Y->DWARF))
+  std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
+  if (auto Err = dwarf2yaml(*DICtx, Y->DWARF))
     return errorCodeToError(Err);
   return std::move(Y);
 }

Modified: llvm/trunk/tools/obj2yaml/obj2yaml.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/obj2yaml.h?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/obj2yaml.h (original)
+++ llvm/trunk/tools/obj2yaml/obj2yaml.h Wed Jul 19 15:27:28 2017
@@ -29,13 +29,12 @@ std::error_code wasm2yaml(llvm::raw_ostr
 
 // Forward decls for dwarf2yaml
 namespace llvm {
-class DWARFContextInMemory;
+class DWARFContext;
 namespace DWARFYAML {
 struct Data;
 }
 }
 
-std::error_code dwarf2yaml(llvm::DWARFContextInMemory &DCtx,
-                           llvm::DWARFYAML::Data &Y);
+std::error_code dwarf2yaml(llvm::DWARFContext &DCtx, llvm::DWARFYAML::Data &Y);
 
 #endif

Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp?rev=308543&r1=308542&r2=308543&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp Wed Jul 19 15:27:28 2017
@@ -14,8 +14,8 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/Config/llvm-config.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
@@ -28,8 +28,8 @@
 #include "llvm/ObjectYAML/DWARFYAML.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 #include <climits>
@@ -228,10 +228,10 @@ void TestAllForms() {
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
   auto DieDG = U->getUnitDIE(false);
   EXPECT_TRUE(DieDG.isValid());
 
@@ -458,12 +458,12 @@ template <uint16_t Version, class AddrTy
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
@@ -629,13 +629,13 @@ template <uint16_t Version, class AddrTy
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 2u);
-  DWARFCompileUnit *U1 = DwarfContext.getCompileUnitAtIndex(0);
-  DWARFCompileUnit *U2 = DwarfContext.getCompileUnitAtIndex(1);
+  DWARFCompileUnit *U1 = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U2 = DwarfContext->getCompileUnitAtIndex(1);
 
   // Get the compile unit DIE is valid.
   auto Unit1DieDG = U1->getUnitDIE(false);
@@ -837,12 +837,12 @@ template <uint16_t Version, class AddrTy
   MemoryBufferRef FileBuffer(FileBytes, "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
@@ -1012,12 +1012,12 @@ TEST(DWARFDebugInfo, TestRelations) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1127,12 +1127,12 @@ TEST(DWARFDebugInfo, TestChildIterators)
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1188,12 +1188,13 @@ TEST(DWARFDebugInfo, TestEmptyChildren)
 
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1235,12 +1236,12 @@ TEST(DWARFDebugInfo, TestAttributeIterat
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1299,12 +1300,12 @@ TEST(DWARFDebugInfo, TestFindRecurse) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1505,12 +1506,12 @@ TEST(DWARFDebugInfo, TestFindAttrs) {
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
 
   // Verify the number of compile units is correct.
-  uint32_t NumCUs = DwarfContext.getNumCompileUnits();
+  uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1568,8 +1569,8 @@ TEST(DWARFDebugInfo, TestImplicitConstAb
   MemoryBufferRef FileBuffer(DG->generate(), "dwarf");
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
-  DWARFContextInMemory DwarfContext(*Obj.get());
-  DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0);
+  std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
+  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
   EXPECT_TRUE((bool)U);
 
   const auto *Abbrevs = U->getAbbreviations();
@@ -1708,10 +1709,11 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is "
-                            "invalid (must be less than CU size of "
-                            "0x0000001a):");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is "
+                             "invalid (must be less than CU size of "
+                             "0x0000001a):");
 }
 
 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) {
@@ -1756,8 +1758,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext,
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
               "error: DW_FORM_ref_addr offset beyond .debug_info bounds:");
 }
 
@@ -1792,8 +1795,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext,
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
               "error: DW_AT_ranges offset is beyond .debug_ranges bounds:");
 }
 
@@ -1828,9 +1832,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
   VerifyError(
-      DwarfContext,
+      *DwarfContext,
       "error: DW_AT_stmt_list offset is beyond .debug_line bounds: 0x00001000");
 }
 
@@ -1860,8 +1865,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext,
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
               "error: DW_FORM_strp offset beyond .debug_str bounds:");
 }
 
@@ -1907,9 +1913,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata));
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
   VerifyError(
-      DwarfContext,
+      *DwarfContext,
       "error: invalid DIE reference 0x00000011. Offset is in between DIEs:");
 }
 
@@ -1977,9 +1984,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: .debug_line[0x00000000] row[1] decreases "
-                            "in address from previous row:");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext, "error: .debug_line[0x00000000] row[1] decreases "
+                             "in address from previous row:");
 }
 
 TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) {
@@ -2048,9 +2056,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInva
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
-                            "file index 5 (valid values are [1,1]):");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext, "error: .debug_line[0x00000000][1] has invalid "
+                             "file index 5 (valid values are [1,1]):");
 }
 
 TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) {
@@ -2128,10 +2137,12 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDo
   )";
   auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata);
   ASSERT_TRUE((bool)ErrOrSections);
-  DWARFContextInMemory DwarfContext(*ErrOrSections, 8);
-  VerifyError(DwarfContext, "error: two compile unit DIEs, 0x0000000b and "
-                            "0x0000001f, have the same DW_AT_stmt_list section "
-                            "offset:");
+  std::unique_ptr<DWARFContext> DwarfContext =
+      DWARFContext::create(*ErrOrSections, 8);
+  VerifyError(*DwarfContext,
+              "error: two compile unit DIEs, 0x0000000b and "
+              "0x0000001f, have the same DW_AT_stmt_list section "
+              "offset:");
 }
 
 TEST(DWARFDebugInfo, TestErrorReportingPolicy) {
@@ -2161,20 +2172,22 @@ TEST(DWARFDebugInfo, TestErrorReportingP
   // DWARFContextInMemory
   //         to parse whole file and find both two errors we know about.
   int Errors = 0;
-  DWARFContextInMemory Ctx1(*Obj.get(), nullptr, [&](Error E) {
-    ++Errors;
-    consumeError(std::move(E));
-    return ErrorPolicy::Continue;
-  });
+  std::unique_ptr<DWARFContext> Ctx1 =
+      DWARFContext::create(**Obj, nullptr, [&](Error E) {
+        ++Errors;
+        consumeError(std::move(E));
+        return ErrorPolicy::Continue;
+      });
   EXPECT_TRUE(Errors == 2);
 
   // Case 2: error handler stops parsing of object after first error.
   Errors = 0;
-  DWARFContextInMemory Ctx2(*Obj.get(), nullptr, [&](Error E) {
-    ++Errors;
-    consumeError(std::move(E));
-    return ErrorPolicy::Halt;
-  });
+  std::unique_ptr<DWARFContext> Ctx2 =
+      DWARFContext::create(**Obj, nullptr, [&](Error E) {
+        ++Errors;
+        consumeError(std::move(E));
+        return ErrorPolicy::Halt;
+      });
   EXPECT_TRUE(Errors == 1);
 }
 




More information about the llvm-commits mailing list