[Lldb-commits] [lldb] [LLDB][NFC] Added the interface DWARFUnitInterface to break dependencies and reduce lldb-server size (PR #131645)

Dmitry Vasilyev via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 18 09:52:54 PDT 2025


https://github.com/slydiman updated https://github.com/llvm/llvm-project/pull/131645

>From 464460db7550673bac788ad11e3ed4d45946cd71 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassiliev at accesssoftek.com>
Date: Mon, 17 Mar 2025 19:13:20 +0400
Subject: [PATCH 1/2] [LLDB][NFC] Added the interface DWARFUnitInterface to
 break dependencies and reduce lldb-server size

This patch addresses the issue #129543.

After this patch DWARFExpression does not call DWARFUnit directly and does not depend on lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp and a lot of clang code.

After this patch the size of lldb-server binary (Linux Aarch64)
is reduced from 42MB to 13MB with LLVM 20.0.0
and from 47MB to 17MB with LLVM 21.0.0.
---
 .../include/lldb/Expression/DWARFExpression.h | 23 ++++----
 lldb/source/Expression/DWARFExpression.cpp    | 55 ++++++-------------
 .../SymbolFile/DWARF/DWARFFormValue.cpp       |  6 +-
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    | 39 ++++++++++---
 .../Plugins/SymbolFile/DWARF/DWARFUnit.h      | 50 +++++++++++++----
 5 files changed, 101 insertions(+), 72 deletions(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 2c1e717ee32eb..cf4098f2acc51 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -23,7 +23,7 @@ namespace lldb_private {
 
 namespace plugin {
 namespace dwarf {
-class DWARFUnit;
+class DWARFUnitInterface;
 } // namespace dwarf
 } // namespace plugin
 
@@ -65,20 +65,20 @@ class DWARFExpression {
   /// \return
   ///     The address specified by the operation, if the operation exists, or
   ///     an llvm::Error otherwise.
-  llvm::Expected<lldb::addr_t>
-  GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
+  llvm::Expected<lldb::addr_t> GetLocation_DW_OP_addr(
+      const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;
 
-  bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu,
+  bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
                          lldb::addr_t file_addr);
 
   void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
                    uint8_t addr_byte_size);
 
-  bool
-  ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
+  bool ContainsThreadLocalStorage(
+      const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;
 
   bool LinkThreadLocalStorage(
-      const plugin::dwarf::DWARFUnit *dwarf_cu,
+      const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
       std::function<lldb::addr_t(lldb::addr_t file_addr)> const
           &link_address_callback);
 
@@ -132,13 +132,14 @@ class DWARFExpression {
   static llvm::Expected<Value>
   Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
            lldb::ModuleSP module_sp, const DataExtractor &opcodes,
-           const plugin::dwarf::DWARFUnit *dwarf_cu,
+           const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
            const lldb::RegisterKind reg_set, const Value *initial_value_ptr,
            const Value *object_address_ptr);
 
-  static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu,
-                                     const DataExtractor &data,
-                                     DWARFExpressionList *loc_list);
+  static bool
+  ParseDWARFLocationList(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
+                         const DataExtractor &data,
+                         DWARFExpressionList *loc_list);
 
   bool GetExpressionData(DataExtractor &data) const {
     data = m_data;
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index f48f3ab9307dd..41fbca59db60f 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -133,7 +133,7 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
 static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
                                         const lldb::offset_t data_offset,
                                         const LocationAtom op,
-                                        const DWARFUnit *dwarf_cu) {
+                                        const DWARFUnitInterface *dwarf_cu) {
   lldb::offset_t offset = data_offset;
   switch (op) {
   // Only used in LLVM metadata.
@@ -362,7 +362,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
                                // + LEB128
   {
     data.Skip_LEB128(&offset);
-    return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset;
+    return DWARFUnitInterface::GetAddressByteSize(dwarf_cu) + offset -
+           data_offset;
   }
 
   case DW_OP_GNU_entry_value:
@@ -393,8 +394,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
   return LLDB_INVALID_OFFSET;
 }
 
-llvm::Expected<lldb::addr_t>
-DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
+llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
+    const DWARFUnitInterface *dwarf_cu) const {
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -422,7 +423,7 @@ DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
   return LLDB_INVALID_ADDRESS;
 }
 
-bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
+bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu,
                                         lldb::addr_t file_addr) {
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
@@ -481,7 +482,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
 }
 
 bool DWARFExpression::ContainsThreadLocalStorage(
-    const DWARFUnit *dwarf_cu) const {
+    const DWARFUnitInterface *dwarf_cu) const {
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -497,7 +498,7 @@ bool DWARFExpression::ContainsThreadLocalStorage(
   return false;
 }
 bool DWARFExpression::LinkThreadLocalStorage(
-    const DWARFUnit *dwarf_cu,
+    const DWARFUnitInterface *dwarf_cu,
     std::function<lldb::addr_t(lldb::addr_t file_addr)> const
         &link_address_callback) {
   const uint32_t addr_byte_size = m_data.GetAddressByteSize();
@@ -783,7 +784,8 @@ enum LocationDescriptionKind {
   /* Composite*/
 };
 /// Adjust value's ValueType according to the kind of location description.
-void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu,
+void UpdateValueTypeFromLocationDescription(Log *log,
+                                            const DWARFUnitInterface *dwarf_cu,
                                             LocationDescriptionKind kind,
                                             Value *value = nullptr) {
   // Note that this function is conflating DWARF expressions with
@@ -875,7 +877,7 @@ static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
 llvm::Expected<Value> DWARFExpression::Evaluate(
     ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
     lldb::ModuleSP module_sp, const DataExtractor &opcodes,
-    const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
+    const DWARFUnitInterface *dwarf_cu, const lldb::RegisterKind reg_kind,
     const Value *initial_value_ptr, const Value *object_address_ptr) {
 
   if (opcodes.GetByteSize() == 0)
@@ -2164,35 +2166,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
         if (!bit_size)
           return llvm::createStringError("unspecified architecture");
       } else {
-        // Retrieve the type DIE that the value is being converted to. This
-        // offset is compile unit relative so we need to fix it up.
-        const uint64_t abs_die_offset = die_offset +  dwarf_cu->GetOffset();
-        // FIXME: the constness has annoying ripple effects.
-        DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);
-        if (!die)
-          return llvm::createStringError(
-              "cannot resolve DW_OP_convert type DIE");
-        uint64_t encoding =
-            die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
-        bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
-        if (!bit_size)
-          bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
-        if (!bit_size)
-          return llvm::createStringError(
-              "unsupported type size in DW_OP_convert");
-        switch (encoding) {
-        case DW_ATE_signed:
-        case DW_ATE_signed_char:
-          sign = true;
-          break;
-        case DW_ATE_unsigned:
-        case DW_ATE_unsigned_char:
-          sign = false;
-          break;
-        default:
-          return llvm::createStringError(
-              "unsupported encoding in DW_OP_convert");
-        }
+        if (llvm::Error err =
+                const_cast<DWARFUnitInterface *>(dwarf_cu)->GetBitSizeAndSign(
+                    die_offset, bit_size, sign))
+          return err;
       }
       Scalar &top = stack.back().ResolveValue(exe_ctx);
       top.TruncOrExtendTo(bit_size, sign);
@@ -2353,7 +2330,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
 }
 
 bool DWARFExpression::ParseDWARFLocationList(
-    const DWARFUnit *dwarf_cu, const DataExtractor &data,
+    const DWARFUnitInterface *dwarf_cu, const DataExtractor &data,
     DWARFExpressionList *location_list) {
   location_list->Clear();
   std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index fd3d45cef4c5e..c2f4cc6a24af7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -44,8 +44,8 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
     switch (m_form) {
     case DW_FORM_addr:
       assert(m_unit);
-      m_value.uval =
-          data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit));
+      m_value.uval = data.GetMaxU64(
+          offset_ptr, DWARFUnitInterface::GetAddressByteSize(m_unit));
       break;
     case DW_FORM_block1:
       m_value.uval = data.GetU8(offset_ptr);
@@ -242,7 +242,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
 
   // Compile unit address sized values
   case DW_FORM_addr:
-    *offset_ptr += DWARFUnit::GetAddressByteSize(unit);
+    *offset_ptr += DWARFUnitInterface::GetAddressByteSize(unit);
     return true;
 
   case DW_FORM_ref_addr:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 1ceeef76f7cc3..168b134b84e2f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -672,6 +672,37 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
   return DWARFDIE(); // Not found
 }
 
+llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset,
+                                         uint64_t &bit_size, bool &sign) {
+  // Retrieve the type DIE that the value is being converted to. This
+  // offset is compile unit relative so we need to fix it up.
+  const uint64_t abs_die_offset = die_offset + GetOffset();
+  // FIXME: the constness has annoying ripple effects.
+  DWARFDIE die = GetDIE(abs_die_offset);
+  if (!die)
+    return llvm::createStringError("cannot resolve DW_OP_convert type DIE");
+  uint64_t encoding =
+      die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
+  bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+  if (!bit_size)
+    bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
+  if (!bit_size)
+    return llvm::createStringError("unsupported type size in DW_OP_convert");
+  switch (encoding) {
+  case DW_ATE_signed:
+  case DW_ATE_signed_char:
+    sign = true;
+    break;
+  case DW_ATE_unsigned:
+  case DW_ATE_unsigned_char:
+    sign = false;
+    break;
+  default:
+    return llvm::createStringError("unsupported encoding in DW_OP_convert");
+  }
+  return llvm::Error::success();
+}
+
 llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
   DWARFDebugInfoEntry die;
   if (!die.Extract(GetData(), *this, &die_offset))
@@ -703,14 +734,6 @@ DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
   return *this;
 }
 
-uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
-  if (cu)
-    return cu->GetAddressByteSize();
-  return DWARFUnit::GetDefaultAddressSize();
-}
-
-uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
-
 DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() {
   if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) {
     SymbolFileDWARFDwo *dwo =
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index ba142ae86fe0e..8d0bf51208108 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -38,7 +38,34 @@ enum DWARFProducer {
   eProducerOther
 };
 
-class DWARFUnit : public UserID {
+class DWARFUnitInterface {
+public:
+  DWARFUnitInterface() = default;
+  virtual ~DWARFUnitInterface() = default;
+
+  virtual SymbolFileDWARF &GetSymbolFileDWARF() const = 0;
+  virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0;
+  virtual uint16_t GetVersion() const = 0;
+  virtual std::unique_ptr<llvm::DWARFLocationTable>
+  GetLocationTable(const DataExtractor &data) const = 0;
+  virtual dw_addr_t GetBaseAddress() const = 0;
+  virtual uint8_t GetAddressByteSize() const = 0;
+  virtual llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
+                                        bool &sign) = 0;
+
+  static uint8_t GetAddressByteSize(const DWARFUnitInterface *cu) {
+    if (cu)
+      return cu->GetAddressByteSize();
+    return GetDefaultAddressSize();
+  }
+
+  static uint8_t GetDefaultAddressSize() { return 4; }
+
+  DWARFUnitInterface(const DWARFUnitInterface &) = delete;
+  DWARFUnitInterface &operator=(const DWARFUnitInterface &) = delete;
+};
+
+class DWARFUnit : public UserID, public DWARFUnitInterface {
   using die_iterator_range =
       llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
 
@@ -116,12 +143,14 @@ class DWARFUnit : public UserID {
   size_t GetDebugInfoSize() const;
   // Size of the CU data incl. header but without initial length.
   dw_offset_t GetLength() const { return m_header.getLength(); }
-  uint16_t GetVersion() const { return m_header.getVersion(); }
+  uint16_t GetVersion() const override { return m_header.getVersion(); }
   const llvm::DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
   dw_offset_t GetAbbrevOffset() const;
-  uint8_t GetAddressByteSize() const { return m_header.getAddressByteSize(); }
+  uint8_t GetAddressByteSize() const override {
+    return m_header.getAddressByteSize();
+  }
   dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); }
-  dw_addr_t GetBaseAddress() const { return m_base_addr; }
+  dw_addr_t GetBaseAddress() const override { return m_base_addr; }
   dw_offset_t GetLineTableOffset();
   dw_addr_t GetRangesBase() const { return m_ranges_base; }
   dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
@@ -131,7 +160,7 @@ class DWARFUnit : public UserID {
   void SetStrOffsetsBase(dw_offset_t str_offsets_base);
   virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0;
 
-  dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const;
+  dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const override;
 
   lldb::ByteOrder GetByteOrder() const;
 
@@ -145,6 +174,9 @@ class DWARFUnit : public UserID {
 
   DWARFDIE GetDIE(dw_offset_t die_offset);
 
+  llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
+                                bool &sign) override;
+
   /// Returns the AT_Name of the DIE at `die_offset`, if it exists, without
   /// parsing the entire compile unit. An empty is string is returned upon
   /// error or if the attribute is not present.
@@ -152,10 +184,6 @@ class DWARFUnit : public UserID {
 
   DWARFUnit &GetNonSkeletonUnit();
 
-  static uint8_t GetAddressByteSize(const DWARFUnit *cu);
-
-  static uint8_t GetDefaultAddressSize();
-
   lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; }
 
   void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; }
@@ -174,7 +202,7 @@ class DWARFUnit : public UserID {
 
   bool Supports_unnamed_objc_bitfields();
 
-  SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; }
+  SymbolFileDWARF &GetSymbolFileDWARF() const override { return m_dwarf; }
 
   DWARFProducer GetProducer();
 
@@ -237,7 +265,7 @@ class DWARFUnit : public UserID {
   /// Return the location table for parsing the given location list data. The
   /// format is chosen according to the unit type. Never returns null.
   std::unique_ptr<llvm::DWARFLocationTable>
-  GetLocationTable(const DataExtractor &data) const;
+  GetLocationTable(const DataExtractor &data) const override;
 
   DWARFDataExtractor GetLocationData() const;
 

>From b5a55922e60719ae252bf62ea9345b83312a4af6 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassiliev at accesssoftek.com>
Date: Tue, 18 Mar 2025 20:52:28 +0400
Subject: [PATCH 2/2] Replaced DWARFUnitInterface with
 DWARFExpression::Delegate. Moved ParseDWARFLocationList to DWARF plugin.

---
 .../include/lldb/Expression/DWARFExpression.h |  54 ++++++----
 lldb/source/Expression/DWARFExpression.cpp    |  81 ++++----------
 .../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp  |   2 +-
 .../SymbolFile/DWARF/DWARFFormValue.cpp       |   6 +-
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    | 100 ++++++++++++++----
 .../Plugins/SymbolFile/DWARF/DWARFUnit.h      |  55 ++++------
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp      |   2 +-
 7 files changed, 159 insertions(+), 141 deletions(-)

diff --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index cf4098f2acc51..e37f9db2cf6cf 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -11,6 +11,7 @@
 
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Disassembler.h"
+#include "lldb/Core/dwarf.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/Scalar.h"
 #include "lldb/Utility/Status.h"
@@ -21,12 +22,6 @@
 
 namespace lldb_private {
 
-namespace plugin {
-namespace dwarf {
-class DWARFUnitInterface;
-} // namespace dwarf
-} // namespace plugin
-
 /// \class DWARFExpression DWARFExpression.h
 /// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location
 /// expression and interprets it.
@@ -40,6 +35,31 @@ class DWARFUnitInterface;
 /// location expression or a location list and interprets it.
 class DWARFExpression {
 public:
+  class Delegate {
+  public:
+    Delegate() = default;
+    virtual ~Delegate() = default;
+
+    virtual uint16_t GetVersion() const = 0;
+    virtual dw_addr_t GetBaseAddress() const = 0;
+    virtual uint8_t GetAddressByteSize() const = 0;
+    virtual llvm::Error GetDIEBitSizeAndSign(uint64_t die_offset,
+                                             uint64_t &bit_size,
+                                             bool &sign) = 0;
+    virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0;
+    virtual lldb::offset_t
+    GetVendorDWARFOpcodeSize(const DataExtractor &data,
+                             const lldb::offset_t data_offset,
+                             const uint8_t op) const = 0;
+    virtual bool ParseVendorDWARFOpcode(uint8_t op,
+                                        const DataExtractor &opcodes,
+                                        lldb::offset_t &offset,
+                                        std::vector<Value> &stack) const = 0;
+
+    Delegate(const Delegate &) = delete;
+    Delegate &operator=(const Delegate &) = delete;
+  };
+
   DWARFExpression();
 
   /// Constructor
@@ -65,20 +85,18 @@ class DWARFExpression {
   /// \return
   ///     The address specified by the operation, if the operation exists, or
   ///     an llvm::Error otherwise.
-  llvm::Expected<lldb::addr_t> GetLocation_DW_OP_addr(
-      const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;
+  llvm::Expected<lldb::addr_t>
+  GetLocation_DW_OP_addr(const Delegate *dwarf_cu) const;
 
-  bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
-                         lldb::addr_t file_addr);
+  bool Update_DW_OP_addr(const Delegate *dwarf_cu, lldb::addr_t file_addr);
 
   void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
                    uint8_t addr_byte_size);
 
-  bool ContainsThreadLocalStorage(
-      const plugin::dwarf::DWARFUnitInterface *dwarf_cu) const;
+  bool ContainsThreadLocalStorage(const Delegate *dwarf_cu) const;
 
   bool LinkThreadLocalStorage(
-      const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
+      const Delegate *dwarf_cu,
       std::function<lldb::addr_t(lldb::addr_t file_addr)> const
           &link_address_callback);
 
@@ -132,14 +150,8 @@ class DWARFExpression {
   static llvm::Expected<Value>
   Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
            lldb::ModuleSP module_sp, const DataExtractor &opcodes,
-           const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
-           const lldb::RegisterKind reg_set, const Value *initial_value_ptr,
-           const Value *object_address_ptr);
-
-  static bool
-  ParseDWARFLocationList(const plugin::dwarf::DWARFUnitInterface *dwarf_cu,
-                         const DataExtractor &data,
-                         DWARFExpressionList *loc_list);
+           const Delegate *dwarf_cu, const lldb::RegisterKind reg_set,
+           const Value *initial_value_ptr, const Value *object_address_ptr);
 
   bool GetExpressionData(DataExtractor &data) const {
     data = m_data;
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 41fbca59db60f..b80dea8b66c7c 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -15,7 +15,6 @@
 
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Core/dwarf.h"
 #include "lldb/Utility/DataEncoder.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
@@ -37,7 +36,6 @@
 #include "lldb/Target/StackID.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
 
 #include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
@@ -130,10 +128,10 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
 
 /// Return the length in bytes of the set of operands for \p op. No guarantees
 /// are made on the state of \p data after this call.
-static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
-                                        const lldb::offset_t data_offset,
-                                        const LocationAtom op,
-                                        const DWARFUnitInterface *dwarf_cu) {
+static lldb::offset_t
+GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset,
+                  const LocationAtom op,
+                  const DWARFExpression::Delegate *dwarf_cu) {
   lldb::offset_t offset = data_offset;
   switch (op) {
   // Only used in LLVM metadata.
@@ -362,7 +360,7 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
                                // + LEB128
   {
     data.Skip_LEB128(&offset);
-    return DWARFUnitInterface::GetAddressByteSize(dwarf_cu) + offset -
+    return (dwarf_cu ? dwarf_cu->GetAddressByteSize() : 4) + offset -
            data_offset;
   }
 
@@ -388,14 +386,13 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
   }
 
   if (dwarf_cu)
-    return dwarf_cu->GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(
-        data, data_offset, op);
+    return dwarf_cu->GetVendorDWARFOpcodeSize(data, data_offset, op);
 
   return LLDB_INVALID_OFFSET;
 }
 
 llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
-    const DWARFUnitInterface *dwarf_cu) const {
+    const DWARFExpression::Delegate *dwarf_cu) const {
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -423,8 +420,8 @@ llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
   return LLDB_INVALID_ADDRESS;
 }
 
-bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu,
-                                        lldb::addr_t file_addr) {
+bool DWARFExpression::Update_DW_OP_addr(
+    const DWARFExpression::Delegate *dwarf_cu, lldb::addr_t file_addr) {
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -482,7 +479,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnitInterface *dwarf_cu,
 }
 
 bool DWARFExpression::ContainsThreadLocalStorage(
-    const DWARFUnitInterface *dwarf_cu) const {
+    const DWARFExpression::Delegate *dwarf_cu) const {
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -498,7 +495,7 @@ bool DWARFExpression::ContainsThreadLocalStorage(
   return false;
 }
 bool DWARFExpression::LinkThreadLocalStorage(
-    const DWARFUnitInterface *dwarf_cu,
+    const DWARFExpression::Delegate *dwarf_cu,
     std::function<lldb::addr_t(lldb::addr_t file_addr)> const
         &link_address_callback) {
   const uint32_t addr_byte_size = m_data.GetAddressByteSize();
@@ -784,10 +781,9 @@ enum LocationDescriptionKind {
   /* Composite*/
 };
 /// Adjust value's ValueType according to the kind of location description.
-void UpdateValueTypeFromLocationDescription(Log *log,
-                                            const DWARFUnitInterface *dwarf_cu,
-                                            LocationDescriptionKind kind,
-                                            Value *value = nullptr) {
+void UpdateValueTypeFromLocationDescription(
+    Log *log, const DWARFExpression::Delegate *dwarf_cu,
+    LocationDescriptionKind kind, Value *value = nullptr) {
   // Note that this function is conflating DWARF expressions with
   // DWARF location descriptions. Perhaps it would be better to define
   // a wrapper for DWARFExpression::Eval() that deals with DWARF
@@ -877,8 +873,9 @@ static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
 llvm::Expected<Value> DWARFExpression::Evaluate(
     ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
     lldb::ModuleSP module_sp, const DataExtractor &opcodes,
-    const DWARFUnitInterface *dwarf_cu, const lldb::RegisterKind reg_kind,
-    const Value *initial_value_ptr, const Value *object_address_ptr) {
+    const DWARFExpression::Delegate *dwarf_cu,
+    const lldb::RegisterKind reg_kind, const Value *initial_value_ptr,
+    const Value *object_address_ptr) {
 
   if (opcodes.GetByteSize() == 0)
     return llvm::createStringError(
@@ -2167,8 +2164,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
           return llvm::createStringError("unspecified architecture");
       } else {
         if (llvm::Error err =
-                const_cast<DWARFUnitInterface *>(dwarf_cu)->GetBitSizeAndSign(
-                    die_offset, bit_size, sign))
+                const_cast<DWARFExpression::Delegate *>(dwarf_cu)
+                    ->GetDIEBitSizeAndSign(die_offset, bit_size, sign))
           return err;
       }
       Scalar &top = stack.back().ResolveValue(exe_ctx);
@@ -2293,8 +2290,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
 
     default:
       if (dwarf_cu) {
-        if (dwarf_cu->GetSymbolFileDWARF().ParseVendorDWARFOpcode(
-                op, opcodes, offset, stack)) {
+        if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, stack)) {
           break;
         }
       }
@@ -2329,43 +2325,6 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
   return stack.back();
 }
 
-bool DWARFExpression::ParseDWARFLocationList(
-    const DWARFUnitInterface *dwarf_cu, const DataExtractor &data,
-    DWARFExpressionList *location_list) {
-  location_list->Clear();
-  std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
-      dwarf_cu->GetLocationTable(data);
-  Log *log = GetLog(LLDBLog::Expressions);
-  auto lookup_addr =
-      [&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> {
-    addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);
-    if (address == LLDB_INVALID_ADDRESS)
-      return std::nullopt;
-    return llvm::object::SectionedAddress{address};
-  };
-  auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) {
-    if (!loc) {
-      LLDB_LOG_ERROR(log, loc.takeError(), "{0}");
-      return true;
-    }
-    auto buffer_sp =
-        std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());
-    DWARFExpression expr = DWARFExpression(DataExtractor(
-        buffer_sp, data.GetByteOrder(), data.GetAddressByteSize()));
-    location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);
-    return true;
-  };
-  llvm::Error error = loctable_up->visitAbsoluteLocationList(
-      0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},
-      lookup_addr, process_list);
-  location_list->Sort();
-  if (error) {
-    LLDB_LOG_ERROR(log, std::move(error), "{0}");
-    return false;
-  }
-  return true;
-}
-
 bool DWARFExpression::MatchesOperand(
     StackFrame &frame, const Instruction::Operand &operand) const {
   using namespace OperandMatchers;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 5b23f2e63fe6d..fa3acf04fbbf8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -240,7 +240,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
                 data = DataExtractor(data, offset, data.GetByteSize() - offset);
                 if (lo_pc != LLDB_INVALID_ADDRESS) {
                   assert(lo_pc >= cu->GetBaseAddress());
-                  DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
+                  cu->ParseDWARFLocationList(data, frame_base);
                   frame_base->SetFuncFileAddress(lo_pc);
                 } else
                   set_frame_base_loclist_addr = true;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index c2f4cc6a24af7..fd3d45cef4c5e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -44,8 +44,8 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
     switch (m_form) {
     case DW_FORM_addr:
       assert(m_unit);
-      m_value.uval = data.GetMaxU64(
-          offset_ptr, DWARFUnitInterface::GetAddressByteSize(m_unit));
+      m_value.uval =
+          data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_unit));
       break;
     case DW_FORM_block1:
       m_value.uval = data.GetU8(offset_ptr);
@@ -242,7 +242,7 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
 
   // Compile unit address sized values
   case DW_FORM_addr:
-    *offset_ptr += DWARFUnitInterface::GetAddressByteSize(unit);
+    *offset_ptr += DWARFUnit::GetAddressByteSize(unit);
     return true;
 
   case DW_FORM_ref_addr:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 168b134b84e2f..05bd623b48bf3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -672,8 +672,32 @@ DWARFUnit::GetDIE(dw_offset_t die_offset) {
   return DWARFDIE(); // Not found
 }
 
-llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset,
-                                         uint64_t &bit_size, bool &sign) {
+llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
+  DWARFDebugInfoEntry die;
+  if (!die.Extract(GetData(), *this, &die_offset))
+    return llvm::StringRef();
+
+  // Does die contain a DW_AT_Name?
+  if (const char *name =
+          die.GetAttributeValueAsString(this, DW_AT_name, nullptr))
+    return name;
+
+  // Does its DW_AT_specification or DW_AT_abstract_origin contain an AT_Name?
+  for (auto attr : {DW_AT_specification, DW_AT_abstract_origin}) {
+    DWARFFormValue form_value;
+    if (!die.GetAttributeValue(this, attr, form_value))
+      continue;
+    auto [unit, offset] = form_value.ReferencedUnitAndOffset();
+    if (unit)
+      if (auto name = unit->PeekDIEName(offset); !name.empty())
+        return name;
+  }
+
+  return llvm::StringRef();
+}
+
+llvm::Error DWARFUnit::GetDIEBitSizeAndSign(uint64_t die_offset,
+                                            uint64_t &bit_size, bool &sign) {
   // Retrieve the type DIE that the value is being converted to. This
   // offset is compile unit relative so we need to fix it up.
   const uint64_t abs_die_offset = die_offset + GetOffset();
@@ -703,28 +727,54 @@ llvm::Error DWARFUnit::GetBitSizeAndSign(uint64_t die_offset,
   return llvm::Error::success();
 }
 
-llvm::StringRef DWARFUnit::PeekDIEName(dw_offset_t die_offset) {
-  DWARFDebugInfoEntry die;
-  if (!die.Extract(GetData(), *this, &die_offset))
-    return llvm::StringRef();
+lldb::offset_t
+DWARFUnit::GetVendorDWARFOpcodeSize(const DataExtractor &data,
+                                    const lldb::offset_t data_offset,
+                                    const uint8_t op) const {
+  return GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(data, data_offset, op);
+}
 
-  // Does die contain a DW_AT_Name?
-  if (const char *name =
-          die.GetAttributeValueAsString(this, DW_AT_name, nullptr))
-    return name;
+bool DWARFUnit::ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+                                       lldb::offset_t &offset,
+                                       std::vector<Value> &stack) const {
+  return GetSymbolFileDWARF().ParseVendorDWARFOpcode(op, opcodes, offset,
+                                                     stack);
+}
 
-  // Does its DW_AT_specification or DW_AT_abstract_origin contain an AT_Name?
-  for (auto attr : {DW_AT_specification, DW_AT_abstract_origin}) {
-    DWARFFormValue form_value;
-    if (!die.GetAttributeValue(this, attr, form_value))
-      continue;
-    auto [unit, offset] = form_value.ReferencedUnitAndOffset();
-    if (unit)
-      if (auto name = unit->PeekDIEName(offset); !name.empty())
-        return name;
+bool DWARFUnit::ParseDWARFLocationList(
+    const DataExtractor &data, DWARFExpressionList *location_list) const {
+  location_list->Clear();
+  std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
+      GetLocationTable(data);
+  Log *log = GetLog(DWARFLog::DebugInfo);
+  auto lookup_addr =
+      [&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> {
+    addr_t address = ReadAddressFromDebugAddrSection(index);
+    if (address == LLDB_INVALID_ADDRESS)
+      return std::nullopt;
+    return llvm::object::SectionedAddress{address};
+  };
+  auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) {
+    if (!loc) {
+      LLDB_LOG_ERROR(log, loc.takeError(), "{0}");
+      return true;
+    }
+    auto buffer_sp =
+        std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());
+    DWARFExpression expr = DWARFExpression(DataExtractor(
+        buffer_sp, data.GetByteOrder(), data.GetAddressByteSize()));
+    location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);
+    return true;
+  };
+  llvm::Error error = loctable_up->visitAbsoluteLocationList(
+      0, llvm::object::SectionedAddress{GetBaseAddress()}, lookup_addr,
+      process_list);
+  location_list->Sort();
+  if (error) {
+    LLDB_LOG_ERROR(log, std::move(error), "{0}");
+    return false;
   }
-
-  return llvm::StringRef();
+  return true;
 }
 
 DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
@@ -734,6 +784,14 @@ DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
   return *this;
 }
 
+uint8_t DWARFUnit::GetAddressByteSize(const DWARFUnit *cu) {
+  if (cu)
+    return cu->GetAddressByteSize();
+  return DWARFUnit::GetDefaultAddressSize();
+}
+
+uint8_t DWARFUnit::GetDefaultAddressSize() { return 4; }
+
 DWARFCompileUnit *DWARFUnit::GetSkeletonUnit() {
   if (m_skeleton_unit.load() == nullptr && IsDWOUnit()) {
     SymbolFileDWARFDwo *dwo =
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 8d0bf51208108..9969ae9b4c09e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -11,6 +11,7 @@
 
 #include "DWARFDIE.h"
 #include "DWARFDebugInfoEntry.h"
+#include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Utility/XcodeSDK.h"
 #include "lldb/lldb-enumerations.h"
 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
@@ -38,34 +39,7 @@ enum DWARFProducer {
   eProducerOther
 };
 
-class DWARFUnitInterface {
-public:
-  DWARFUnitInterface() = default;
-  virtual ~DWARFUnitInterface() = default;
-
-  virtual SymbolFileDWARF &GetSymbolFileDWARF() const = 0;
-  virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0;
-  virtual uint16_t GetVersion() const = 0;
-  virtual std::unique_ptr<llvm::DWARFLocationTable>
-  GetLocationTable(const DataExtractor &data) const = 0;
-  virtual dw_addr_t GetBaseAddress() const = 0;
-  virtual uint8_t GetAddressByteSize() const = 0;
-  virtual llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
-                                        bool &sign) = 0;
-
-  static uint8_t GetAddressByteSize(const DWARFUnitInterface *cu) {
-    if (cu)
-      return cu->GetAddressByteSize();
-    return GetDefaultAddressSize();
-  }
-
-  static uint8_t GetDefaultAddressSize() { return 4; }
-
-  DWARFUnitInterface(const DWARFUnitInterface &) = delete;
-  DWARFUnitInterface &operator=(const DWARFUnitInterface &) = delete;
-};
-
-class DWARFUnit : public UserID, public DWARFUnitInterface {
+class DWARFUnit : public UserID, public DWARFExpression::Delegate {
   using die_iterator_range =
       llvm::iterator_range<DWARFDebugInfoEntry::collection::iterator>;
 
@@ -174,16 +148,31 @@ class DWARFUnit : public UserID, public DWARFUnitInterface {
 
   DWARFDIE GetDIE(dw_offset_t die_offset);
 
-  llvm::Error GetBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
-                                bool &sign) override;
-
   /// Returns the AT_Name of the DIE at `die_offset`, if it exists, without
   /// parsing the entire compile unit. An empty is string is returned upon
   /// error or if the attribute is not present.
   llvm::StringRef PeekDIEName(dw_offset_t die_offset);
 
+  llvm::Error GetDIEBitSizeAndSign(uint64_t die_offset, uint64_t &bit_size,
+                                   bool &sign) override;
+
+  lldb::offset_t GetVendorDWARFOpcodeSize(const DataExtractor &data,
+                                          const lldb::offset_t data_offset,
+                                          const uint8_t op) const override;
+
+  bool ParseVendorDWARFOpcode(uint8_t op, const DataExtractor &opcodes,
+                              lldb::offset_t &offset,
+                              std::vector<Value> &stack) const override;
+
+  bool ParseDWARFLocationList(const DataExtractor &data,
+                              DWARFExpressionList *loc_list) const;
+
   DWARFUnit &GetNonSkeletonUnit();
 
+  static uint8_t GetAddressByteSize(const DWARFUnit *cu);
+
+  static uint8_t GetDefaultAddressSize();
+
   lldb_private::CompileUnit *GetLLDBCompUnit() const { return m_lldb_cu; }
 
   void SetLLDBCompUnit(lldb_private::CompileUnit *cu) { m_lldb_cu = cu; }
@@ -202,7 +191,7 @@ class DWARFUnit : public UserID, public DWARFUnitInterface {
 
   bool Supports_unnamed_objc_bitfields();
 
-  SymbolFileDWARF &GetSymbolFileDWARF() const override { return m_dwarf; }
+  SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; }
 
   DWARFProducer GetProducer();
 
@@ -265,7 +254,7 @@ class DWARFUnit : public UserID, public DWARFUnitInterface {
   /// Return the location table for parsing the given location list data. The
   /// format is chosen according to the unit type. Never returns null.
   std::unique_ptr<llvm::DWARFLocationTable>
-  GetLocationTable(const DataExtractor &data) const override;
+  GetLocationTable(const DataExtractor &data) const;
 
   DWARFDataExtractor GetLocationData() const;
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d1aaf0bd36de4..7600459ac90b3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3296,7 +3296,7 @@ static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value,
   if (data.ValidOffset(offset)) {
     data = DataExtractor(data, offset, data.GetByteSize() - offset);
     const DWARFUnit *dwarf_cu = form_value.GetUnit();
-    if (DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list))
+    if (dwarf_cu->ParseDWARFLocationList(data, &location_list))
       location_list.SetFuncFileAddress(func_low_pc);
   }
 



More information about the lldb-commits mailing list