[llvm] r338628 - [DebugInfo/DWARF] [1/4] De-templatize DWARFUnitSection. NFC

Paul Robinson via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 1 13:43:47 PDT 2018


Author: probinson
Date: Wed Aug  1 13:43:47 2018
New Revision: 338628

URL: http://llvm.org/viewvc/llvm-project?rev=338628&view=rev
Log:
[DebugInfo/DWARF] [1/4] De-templatize DWARFUnitSection. NFC

This is patch 1 of 4 NFC refactorings to handle type units and compile
units more consistently and with less concern about the object-file
section that they came from.

Patch 1 replaces the templated DWARFUnitSection with a non-templated
version. That is, instead of being a SmallVector of pointers to a
specific unit kind, it is not a SmallVector of pointers to the base
class for both type and compile units.  Virtual methods are magic.

Differential Revision: https://reviews.llvm.org/D49741

Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
    llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
    llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h Wed Aug  1 13:43:47 2018
@@ -22,16 +22,16 @@ public:
                    const DWARFDebugAbbrev *DA, const DWARFSection *RS,
                    StringRef SS, const DWARFSection &SOS,
                    const DWARFSection *AOS, const DWARFSection &LS, bool LE,
-                   bool IsDWO, const DWARFUnitSectionBase &UnitSection)
+                   bool IsDWO, const DWARFUnitSection &UnitSection)
       : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
                   UnitSection) {}
 
-  // VTable anchor.
+  /// VTable anchor.
   ~DWARFCompileUnit() override;
-
-  void dump(raw_ostream &OS, DIDumpOptions DumpOpts);
-
-  static const DWARFSectionKind Section = DW_SECT_INFO;
+  /// Dump this compile unit to \p OS.
+  void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override;
+  /// Enable LLVM-style RTTI.
+  static bool classof(const DWARFUnit *U) { return !U->isTypeUnit(); }
 };
 
 } // end namespace llvm

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=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Wed Aug  1 13:43:47 2018
@@ -57,8 +57,8 @@ enum class ErrorPolicy { Halt, Continue
 /// This data structure is the top level entity that deals with dwarf debug
 /// information parsing. The actual data is supplied through DWARFObj.
 class DWARFContext : public DIContext {
-  DWARFUnitSection<DWARFCompileUnit> CUs;
-  std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
+  DWARFUnitSection CUs;
+  std::deque<DWARFUnitSection> TUs;
   std::unique_ptr<DWARFUnitIndex> CUIndex;
   std::unique_ptr<DWARFGdbIndex> GdbIndex;
   std::unique_ptr<DWARFUnitIndex> TUIndex;
@@ -75,8 +75,8 @@ class DWARFContext : public DIContext {
   std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
   std::unique_ptr<AppleAcceleratorTable> AppleObjC;
 
-  DWARFUnitSection<DWARFCompileUnit> DWOCUs;
-  std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
+  DWARFUnitSection DWOCUs;
+  std::deque<DWARFUnitSection> DWOTUs;
   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
   std::unique_ptr<DWARFDebugLocDWO> LocDWO;
 
@@ -139,8 +139,8 @@ public:
 
   bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
 
-  using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
-  using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
+  using cu_iterator_range = DWARFUnitSection::iterator_range;
+  using tu_iterator_range = DWARFUnitSection::iterator_range;
   using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>;
 
   /// Get compile units in this context.
@@ -191,14 +191,14 @@ public:
     return DWOTUs.size();
   }
 
-  /// Get the compile unit at the specified index for this compile unit.
-  DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
+  /// Get the unit at the specified index.
+  DWARFUnit *getUnitAtIndex(unsigned index) {
     parseCompileUnits();
     return CUs[index].get();
   }
 
-  /// Get the compile unit at the specified index for the DWO compile units.
-  DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
+  /// Get the unit at the specified index for the DWO units.
+  DWARFUnit *getDWOUnitAtIndex(unsigned index) {
     parseDWOCompileUnits();
     return DWOCUs[index].get();
   }

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h Wed Aug  1 13:43:47 2018
@@ -278,9 +278,8 @@ public:
   /// Helper to allow for parsing of an entire .debug_line section in sequence.
   class SectionParser {
   public:
-    using cu_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
-    using tu_range =
-        iterator_range<std::deque<DWARFUnitSection<DWARFTypeUnit>>::iterator>;
+    using cu_range = DWARFUnitSection::iterator_range;
+    using tu_range = iterator_range<std::deque<DWARFUnitSection>::iterator>;
     using LineToUnitMap = std::map<uint64_t, DWARFUnit *>;
 
     SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs,

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h Wed Aug  1 13:43:47 2018
@@ -30,15 +30,16 @@ public:
                 const DWARFDebugAbbrev *DA, const DWARFSection *RS,
                 StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
                 const DWARFSection &LS, bool LE, bool IsDWO,
-                const DWARFUnitSectionBase &UnitSection)
+                const DWARFUnitSection &UnitSection)
       : DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
                   UnitSection) {}
 
   uint64_t getTypeHash() const { return getHeader().getTypeHash(); }
   uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); }
 
-  void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {});
-  static const DWARFSectionKind Section = DW_SECT_TYPES;
+  void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
+  // Enable LLVM-style RTTI.
+  static bool classof(const DWARFUnit *U) { return U->isTypeUnit(); }
 };
 
 } // end namespace llvm

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=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Wed Aug  1 13:43:47 2018
@@ -101,125 +101,31 @@ public:
   uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
 };
 
-/// Base class for all DWARFUnitSection classes. This provides the
-/// functionality common to all unit types.
-class DWARFUnitSectionBase {
-public:
-  /// Returns the Unit that contains the given section offset in the
-  /// same section this Unit originated from.
-  virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
-  virtual DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) = 0;
-
-  void parse(DWARFContext &C, const DWARFSection &Section);
-  void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
-                bool Lazy = false);
-
-protected:
-  ~DWARFUnitSectionBase() = default;
-
-  virtual void parseImpl(DWARFContext &Context, const DWARFObject &Obj,
-                         const DWARFSection &Section,
-                         const DWARFDebugAbbrev *DA, const DWARFSection *RS,
-                         StringRef SS, const DWARFSection &SOS,
-                         const DWARFSection *AOS, const DWARFSection &LS,
-                         bool isLittleEndian, bool isDWO, bool Lazy) = 0;
-};
-
 const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
                                         DWARFSectionKind Kind);
 
-/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
-template<typename UnitType>
-class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
-                               public DWARFUnitSectionBase {
+/// Describes one section's Units.
+class DWARFUnitSection final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
   bool Parsed = false;
-  std::function<std::unique_ptr<UnitType>(uint32_t)> Parser;
+  std::function<std::unique_ptr<DWARFUnit>(uint32_t)> Parser;
 
 public:
-  using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
+  using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
   using iterator = typename UnitVector::iterator;
   using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
 
-  UnitType *getUnitForOffset(uint32_t Offset) const override {
-    auto *CU = std::upper_bound(
-        this->begin(), this->end(), Offset,
-        [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
-          return LHS < RHS->getNextUnitOffset();
-        });
-    if (CU != this->end() && (*CU)->getOffset() <= Offset)
-      return CU->get();
-    return nullptr;
-  }
-  UnitType *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) override {
-    const auto *CUOff = E.getOffset(DW_SECT_INFO);
-    if (!CUOff)
-      return nullptr;
-
-    auto Offset = CUOff->Offset;
-
-    auto *CU = std::upper_bound(
-        this->begin(), this->end(), CUOff->Offset,
-        [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
-          return LHS < RHS->getNextUnitOffset();
-        });
-    if (CU != this->end() && (*CU)->getOffset() <= Offset)
-      return CU->get();
-
-    if (!Parser)
-      return nullptr;
-
-    auto U = Parser(Offset);
-    if (!U)
-      U = nullptr;
-
-    auto *NewCU = U.get();
-    this->insert(CU, std::move(U));
-    return NewCU;
-  }
-
+  DWARFUnit *getUnitForOffset(uint32_t Offset) const;
+  DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
+  void parse(DWARFContext &C, const DWARFSection &Section,
+             DWARFSectionKind SectionKind);
+  void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
+                DWARFSectionKind SectionKind, bool Lazy = false);
 private:
   void parseImpl(DWARFContext &Context, const DWARFObject &Obj,
                  const DWARFSection &Section, const DWARFDebugAbbrev *DA,
                  const DWARFSection *RS, StringRef SS, const DWARFSection &SOS,
                  const DWARFSection *AOS, const DWARFSection &LS, bool LE,
-                 bool IsDWO, bool Lazy) override {
-    if (Parsed)
-      return;
-    DWARFDataExtractor Data(Obj, Section, LE, 0);
-    if (!Parser) {
-      const DWARFUnitIndex *Index = nullptr;
-      if (IsDWO)
-        Index = &getDWARFUnitIndex(Context, UnitType::Section);
-      Parser = [=, &Context, &Section, &SOS,
-                &LS](uint32_t Offset) -> std::unique_ptr<UnitType> {
-        if (!Data.isValidOffset(Offset))
-          return nullptr;
-        DWARFUnitHeader Header;
-        if (!Header.extract(Context, Data, &Offset, UnitType::Section, Index))
-          return nullptr;
-        auto U = llvm::make_unique<UnitType>(
-            Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
-            *this);
-        return U;
-      };
-    }
-    if (Lazy)
-      return;
-    auto I = this->begin();
-    uint32_t Offset = 0;
-    while (Data.isValidOffset(Offset)) {
-      if (I != this->end() && (*I)->getOffset() == Offset) {
-        ++I;
-        continue;
-      }
-      auto U = Parser(Offset);
-      if (!U)
-        break;
-      Offset = U->getNextUnitOffset();
-      I = std::next(this->insert(I, std::move(U)));
-    }
-    Parsed = true;
-  }
+                 bool IsDWO, bool Lazy, DWARFSectionKind SectionKind);
 };
 
 /// Represents base address of the CU.
@@ -268,7 +174,7 @@ class DWARFUnit {
   uint32_t AddrOffsetSectionBase = 0;
   bool isLittleEndian;
   bool isDWO;
-  const DWARFUnitSectionBase &UnitSection;
+  const DWARFUnitSection &UnitSection;
 
   /// Start, length, and DWARF format of the unit's contribution to the string
   /// offsets table (DWARF v5).
@@ -325,7 +231,7 @@ public:
             const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
             const DWARFSection &SOS, const DWARFSection *AOS,
             const DWARFSection &LS, bool LE, bool IsDWO,
-            const DWARFUnitSectionBase &UnitSection);
+            const DWARFUnitSection &UnitSection);
 
   virtual ~DWARFUnit();
 
@@ -342,6 +248,7 @@ public:
   }
   uint32_t getLength() const { return Header.getLength(); }
   uint8_t getUnitType() const { return Header.getUnitType(); }
+  bool isTypeUnit() const { return Header.isTypeUnit(); }
   uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
   const DWARFSection &getLineSection() const { return LineSection; }
   StringRef getStringSection() const { return StringSection; }
@@ -481,7 +388,7 @@ public:
                                  SmallVectorImpl<DWARFDie> &InlinedChain);
 
   /// getUnitSection - Return the DWARFUnitSection containing this unit.
-  const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
+  const DWARFUnitSection &getUnitSection() const { return UnitSection; }
 
   /// Returns the number of DIEs in the unit. Parses the unit
   /// if necessary.
@@ -541,6 +448,7 @@ public:
     return die_iterator_range(DieArray.begin(), DieArray.end());
   }
 
+  virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
 private:
   /// Size in bytes of the .debug_info data associated with this compile unit.
   size_t getDebugInfoSize() const {

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Wed Aug  1 13:43:47 2018
@@ -584,11 +584,11 @@ void DWARFContext::dump(
 }
 
 DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
-  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), true);
+  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO, true);
 
   if (const auto &CUI = getCUIndex()) {
     if (const auto *R = CUI.getFromHash(Hash))
-      return DWOCUs.getUnitForIndexEntry(*R);
+      return dyn_cast_or_null<DWARFCompileUnit>(DWOCUs.getUnitForIndexEntry(*R));
     return nullptr;
   }
 
@@ -607,7 +607,7 @@ DWARFCompileUnit *DWARFContext::getDWOCo
         continue;
     }
     if (DWOCU->getDWOId() == Hash)
-      return DWOCU.get();
+      return dyn_cast<DWARFCompileUnit>(DWOCU.get());
   }
   return nullptr;
 }
@@ -690,10 +690,10 @@ const DWARFDebugLoc *DWARFContext::getDe
     return Loc.get();
 
   Loc.reset(new DWARFDebugLoc);
-  // Assume all compile units have the same address byte size.
+  // Assume all units have the same address byte size.
   if (getNumCompileUnits()) {
     DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
-                               getCompileUnitAtIndex(0)->getAddressByteSize());
+                               getUnitAtIndex(0)->getAddressByteSize());
     Loc->parse(LocData);
   }
   return Loc.get();
@@ -707,7 +707,7 @@ const DWARFDebugLocDWO *DWARFContext::ge
   // Assume all compile units have the same address byte size.
   if (getNumCompileUnits()) {
     DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(),
-                          getCompileUnitAtIndex(0)->getAddressByteSize());
+                          getUnitAtIndex(0)->getAddressByteSize());
     LocDWO->parse(LocData);
   }
   return LocDWO.get();
@@ -844,7 +844,7 @@ Expected<const DWARFDebugLine::LineTable
 }
 
 void DWARFContext::parseCompileUnits() {
-  CUs.parse(*this, DObj->getInfoSection());
+  CUs.parse(*this, DObj->getInfoSection(), DW_SECT_INFO);
 }
 
 void DWARFContext::parseTypeUnits() {
@@ -852,12 +852,12 @@ void DWARFContext::parseTypeUnits() {
     return;
   DObj->forEachTypesSections([&](const DWARFSection &S) {
     TUs.emplace_back();
-    TUs.back().parse(*this, S);
+    TUs.back().parse(*this, S, DW_SECT_TYPES);
   });
 }
 
 void DWARFContext::parseDWOCompileUnits() {
-  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
+  DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO);
 }
 
 void DWARFContext::parseDWOTypeUnits() {
@@ -865,13 +865,13 @@ void DWARFContext::parseDWOTypeUnits() {
     return;
   DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
     DWOTUs.emplace_back();
-    DWOTUs.back().parseDWO(*this, S);
+    DWOTUs.back().parseDWO(*this, S, DW_SECT_TYPES);
   });
 }
 
 DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
   parseCompileUnits();
-  return CUs.getUnitForOffset(Offset);
+  return dyn_cast_or_null<DWARFCompileUnit>(CUs.getUnitForOffset(Offset));
 }
 
 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Wed Aug  1 13:43:47 2018
@@ -11,12 +11,14 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
 #include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/WithColor.h"
@@ -31,21 +33,112 @@
 using namespace llvm;
 using namespace dwarf;
 
-void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
+void DWARFUnitSection::parse(DWARFContext &C, const DWARFSection &Section,
+                             DWARFSectionKind SectionKind) {
   const DWARFObject &D = C.getDWARFObj();
   parseImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
             D.getStringSection(), D.getStringOffsetSection(),
             &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false,
-            false);
+            false, SectionKind);
 }
 
-void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
-                                    const DWARFSection &DWOSection, bool Lazy) {
+void DWARFUnitSection::parseDWO(DWARFContext &C,
+                                const DWARFSection &DWOSection,
+                                DWARFSectionKind SectionKind, bool Lazy) {
   const DWARFObject &D = C.getDWARFObj();
   parseImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
             D.getStringDWOSection(), D.getStringOffsetDWOSection(),
             &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
-            true, Lazy);
+            true, Lazy, SectionKind);
+}
+
+void DWARFUnitSection::parseImpl(DWARFContext &Context, const DWARFObject &Obj,
+               const DWARFSection &Section, const DWARFDebugAbbrev *DA,
+               const DWARFSection *RS, StringRef SS, const DWARFSection &SOS,
+               const DWARFSection *AOS, const DWARFSection &LS, bool LE,
+               bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) {
+  if (Parsed)
+    return;
+  DWARFDataExtractor Data(Obj, Section, LE, 0);
+  // Lazy initialization of Parser, now that we have all section info.
+  if (!Parser) {
+    const DWARFUnitIndex *Index = nullptr;
+    if (IsDWO)
+      Index = &getDWARFUnitIndex(Context, SectionKind);
+    Parser = [=, &Context, &Section, &SOS,
+      &LS](uint32_t Offset) -> std::unique_ptr<DWARFUnit> {
+      if (!Data.isValidOffset(Offset))
+        return nullptr;
+      DWARFUnitHeader Header;
+      if (!Header.extract(Context, Data, &Offset, SectionKind, Index))
+        return nullptr;
+      std::unique_ptr<DWARFUnit> U;
+      if (Header.isTypeUnit())
+        U = llvm::make_unique<DWARFTypeUnit>(
+          Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
+          *this);
+      else
+        U = llvm::make_unique<DWARFCompileUnit>(
+          Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
+          *this);
+      return U;
+    };
+  }
+  if (Lazy)
+    return;
+  auto I = this->begin();
+  uint32_t Offset = 0;
+  while (Data.isValidOffset(Offset)) {
+    if (I != this->end() && (*I)->getOffset() == Offset) {
+      ++I;
+      continue;
+    }
+    auto U = Parser(Offset);
+    if (!U)
+      break;
+    Offset = U->getNextUnitOffset();
+    I = std::next(this->insert(I, std::move(U)));
+  }
+  Parsed = true;
+}
+
+DWARFUnit *DWARFUnitSection::getUnitForOffset(uint32_t Offset) const {
+  auto *CU = std::upper_bound(
+    this->begin(), this->end(), Offset,
+    [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+    return LHS < RHS->getNextUnitOffset();
+  });
+  if (CU != this->end() && (*CU)->getOffset() <= Offset)
+    return CU->get();
+  return nullptr;
+}
+
+DWARFUnit *
+DWARFUnitSection::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
+  const auto *CUOff = E.getOffset(DW_SECT_INFO);
+  if (!CUOff)
+    return nullptr;
+
+  auto Offset = CUOff->Offset;
+
+  auto *CU = std::upper_bound(
+    this->begin(), this->end(), CUOff->Offset,
+    [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+    return LHS < RHS->getNextUnitOffset();
+  });
+  if (CU != this->end() && (*CU)->getOffset() <= Offset)
+    return CU->get();
+
+  if (!Parser)
+    return nullptr;
+
+  auto U = Parser(Offset);
+  if (!U)
+    U = nullptr;
+
+  auto *NewCU = U.get();
+  this->insert(CU, std::move(U));
+  return NewCU;
 }
 
 DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
@@ -53,7 +146,7 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, c
                      const DWARFDebugAbbrev *DA, const DWARFSection *RS,
                      StringRef SS, const DWARFSection &SOS,
                      const DWARFSection *AOS, const DWARFSection &LS, bool LE,
-                     bool IsDWO, const DWARFUnitSectionBase &UnitSection)
+                     bool IsDWO, const DWARFUnitSection &UnitSection)
     : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
       RangeSection(RS), LineSection(LS), StringSection(SS),
       StringOffsetSection(SOS),  AddrOffsetSection(AOS), isLittleEndian(LE),

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Wed Aug  1 13:43:47 2018
@@ -264,8 +264,7 @@ bool DWARFVerifier::handleDebugInfo() {
   bool isUnitDWARF64 = false;
   bool isHeaderChainValid = true;
   bool hasDIE = DebugInfoData.isValidOffset(Offset);
-  DWARFUnitSection<DWARFTypeUnit> TUSection{};
-  DWARFUnitSection<DWARFCompileUnit> CUSection{};
+  DWARFUnitSection UnitSection{};
   while (hasDIE) {
     OffsetStart = Offset;
     if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
@@ -284,7 +283,7 @@ bool DWARFVerifier::handleDebugInfo() {
             DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(),
             &DObj.getRangeSection(), DObj.getStringSection(),
             DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
-            DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection));
+            DObj.getLineSection(), DCtx.isLittleEndian(), false, UnitSection));
         break;
       }
       case dwarf::DW_UT_skeleton:
@@ -298,7 +297,7 @@ bool DWARFVerifier::handleDebugInfo() {
             DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(),
             &DObj.getRangeSection(), DObj.getStringSection(),
             DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
-            DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection));
+            DObj.getLineSection(), DCtx.isLittleEndian(), false, UnitSection));
         break;
       }
       default: { llvm_unreachable("Invalid UnitType."); }
@@ -1315,11 +1314,12 @@ unsigned DWARFVerifier::verifyDebugNames
   if (NumErrors > 0)
     return NumErrors;
 
-  for (const std::unique_ptr<DWARFCompileUnit> &CU : DCtx.compile_units()) {
+  for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
     if (const DWARFDebugNames::NameIndex *NI =
-            AccelTable.getCUNameIndex(CU->getOffset())) {
+            AccelTable.getCUNameIndex(U->getOffset())) {
+      auto *CU = cast<DWARFCompileUnit>(U.get());
       for (const DWARFDebugInfoEntry &Die : CU->dies())
-        NumErrors += verifyNameIndexCompleteness(DWARFDie(CU.get(), &Die), *NI);
+        NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
     }
   }
   return NumErrors;

Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp Wed Aug  1 13:43:47 2018
@@ -231,7 +231,8 @@ void TestAllForms() {
   std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
   auto DieDG = U->getUnitDIE(false);
   EXPECT_TRUE(DieDG.isValid());
 
@@ -496,7 +497,8 @@ template <uint16_t Version, class AddrTy
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
@@ -672,8 +674,10 @@ template <uint16_t Version, class AddrTy
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 2u);
-  DWARFCompileUnit *U1 = DwarfContext->getCompileUnitAtIndex(0);
-  DWARFCompileUnit *U2 = DwarfContext->getCompileUnitAtIndex(1);
+  DWARFCompileUnit *U1 =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
+  DWARFCompileUnit *U2 =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(1));
 
   // Get the compile unit DIE is valid.
   auto Unit1DieDG = U1->getUnitDIE(false);
@@ -880,7 +884,8 @@ template <uint16_t Version, class AddrTy
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto DieDG = U->getUnitDIE(false);
@@ -1055,7 +1060,8 @@ TEST(DWARFDebugInfo, TestRelations) {
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1222,7 +1228,8 @@ TEST(DWARFDebugInfo, TestChildIterators)
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1284,7 +1291,8 @@ TEST(DWARFDebugInfo, TestEmptyChildren)
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1331,7 +1339,8 @@ TEST(DWARFDebugInfo, TestAttributeIterat
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1399,7 +1408,8 @@ TEST(DWARFDebugInfo, TestFindRecurse) {
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1606,7 +1616,8 @@ TEST(DWARFDebugInfo, TestFindAttrs) {
   // Verify the number of compile units is correct.
   uint32_t NumCUs = DwarfContext->getNumCompileUnits();
   EXPECT_EQ(NumCUs, 1u);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
 
   // Get the compile unit DIE is valid.
   auto CUDie = U->getUnitDIE(false);
@@ -1665,7 +1676,8 @@ TEST(DWARFDebugInfo, TestImplicitConstAb
   auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
   EXPECT_TRUE((bool)Obj);
   std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
-  DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0);
+  DWARFCompileUnit *U =
+      cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
   EXPECT_TRUE((bool)U);
 
   const auto *Abbrevs = U->getAbbreviations();

Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp?rev=338628&r1=338627&r2=338628&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp Wed Aug  1 13:43:47 2018
@@ -129,8 +129,8 @@ struct CommonFixture {
   Error Unrecoverable;
   std::function<void(Error)> RecordUnrecoverable;
 
-  SmallVector<std::unique_ptr<DWARFCompileUnit>, 2> CUs;
-  std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
+  SmallVector<std::unique_ptr<DWARFUnit>, 2> CUs;
+  std::deque<DWARFUnitSection> TUs;
 };
 
 // Fixtures must derive from "Test", but parameterised fixtures from




More information about the llvm-commits mailing list