[Lldb-commits] [lldb] e4c5bca - Revert "[LLDB][NFC] Decouple dwarf location table from DWARFExpression."

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Thu Jul 7 16:37:54 PDT 2022


Author: Jonas Devlieghere
Date: 2022-07-07T16:36:10-07:00
New Revision: e4c5bca597a6f12e8f789a53e862387b9808ff48

URL: https://github.com/llvm/llvm-project/commit/e4c5bca597a6f12e8f789a53e862387b9808ff48
DIFF: https://github.com/llvm/llvm-project/commit/e4c5bca597a6f12e8f789a53e862387b9808ff48.diff

LOG: Revert "[LLDB][NFC] Decouple dwarf location table from DWARFExpression."

This reverts commit 227dffd0b6d78154516ace45f6ed28259c7baa48 and its
follow up 562c3467a6738aa89203f72fc1d1343e5baadf3c because it breaks a
bunch of tests on GreenDragon:

https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/45155/

Added: 
    

Modified: 
    lldb/include/lldb/Expression/DWARFExpression.h
    lldb/include/lldb/Symbol/Function.h
    lldb/include/lldb/Symbol/Variable.h
    lldb/include/lldb/Target/StackFrame.h
    lldb/include/lldb/Utility/RangeMap.h
    lldb/include/lldb/lldb-forward.h
    lldb/source/Core/ValueObjectVariable.cpp
    lldb/source/Expression/CMakeLists.txt
    lldb/source/Expression/DWARFExpression.cpp
    lldb/source/Expression/Materializer.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
    lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
    lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
    lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
    lldb/source/Symbol/Function.cpp
    lldb/source/Symbol/Variable.cpp
    lldb/source/Target/RegisterContextUnwind.cpp
    lldb/source/Target/StackFrame.cpp
    lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
    lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
    llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn

Removed: 
    lldb/include/lldb/Expression/DWARFExpressionList.h
    lldb/source/Expression/DWARFExpressionList.cpp


################################################################################
diff  --git a/lldb/include/lldb/Expression/DWARFExpression.h b/lldb/include/lldb/Expression/DWARFExpression.h
index 49e51d51f211c..96a0e8e02da13 100644
--- a/lldb/include/lldb/Expression/DWARFExpression.h
+++ b/lldb/include/lldb/Expression/DWARFExpression.h
@@ -42,14 +42,49 @@ class DWARFExpression {
   /// \param[in] data
   ///     A data extractor configured to read the DWARF location expression's
   ///     bytecode.
-  DWARFExpression(const DataExtractor &data);
+  DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
+                  const DWARFUnit *dwarf_cu);
 
   /// Destructor
   virtual ~DWARFExpression();
 
+  /// Print the description of the expression to a stream
+  ///
+  /// \param[in] s
+  ///     The stream to print to.
+  ///
+  /// \param[in] level
+  ///     The level of verbosity to use.
+  ///
+  /// \param[in] abi
+  ///     An optional ABI plug-in that can be used to resolve register
+  ///     names.
+  void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
+
   /// Return true if the location expression contains data
   bool IsValid() const;
 
+  /// Return true if a location list was provided
+  bool IsLocationList() const;
+
+  /// Search for a load address in the location list
+  ///
+  /// \param[in] func_load_addr
+  ///     The actual address of the function containing this location list.
+  ///
+  /// \param[in] addr
+  ///     The address to resolve
+  ///
+  /// \return
+  ///     True if IsLocationList() is true and the address was found;
+  ///     false otherwise.
+  //    bool
+  //    LocationListContainsLoadAddress (Process* process, const Address &addr)
+  //    const;
+  //
+  bool LocationListContainsAddress(lldb::addr_t func_load_addr,
+                                   lldb::addr_t addr) const;
+
   /// If a location is not a location list, return true if the location
   /// contains a DW_OP_addr () opcode in the stream that matches \a file_addr.
   /// If file_addr is LLDB_INVALID_ADDRESS, the this function will return true
@@ -58,9 +93,6 @@ class DWARFExpression {
   /// static variable since there is no other indication from DWARF debug
   /// info.
   ///
-  /// \param[in] dwarf_cu
-  ///     The dwarf unit this expression belongs to.
-  ///
   /// \param[in] op_addr_idx
   ///     The DW_OP_addr index to retrieve in case there is more than
   ///     one DW_OP_addr opcode in the location byte stream.
@@ -72,22 +104,36 @@ class DWARFExpression {
   /// \return
   ///     LLDB_INVALID_ADDRESS if the location doesn't contain a
   ///     DW_OP_addr for \a op_addr_idx, otherwise a valid file address
-  lldb::addr_t GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
-                                      uint32_t op_addr_idx, bool &error) const;
+  lldb::addr_t GetLocation_DW_OP_addr(uint32_t op_addr_idx, bool &error) const;
 
   bool Update_DW_OP_addr(lldb::addr_t file_addr);
 
   void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
                    uint8_t addr_byte_size);
 
+  void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
+
   bool ContainsThreadLocalStorage() const;
 
   bool LinkThreadLocalStorage(
+      lldb::ModuleSP new_module_sp,
       std::function<lldb::addr_t(lldb::addr_t file_addr)> const
           &link_address_callback);
 
+  /// Tells the expression that it refers to a location list.
+  ///
+  /// \param[in] cu_file_addr
+  ///     The base address to use for interpreting relative location list
+  ///     entries.
+  /// \param[in] func_file_addr
+  ///     The file address of the function containing this location list. This
+  ///     address will be used to relocate the location list on the fly (in
+  ///     conjuction with the func_load_addr arguments).
+  void SetLocationListAddresses(lldb::addr_t cu_file_addr,
+                                lldb::addr_t func_file_addr);
+
   /// Return the call-frame-info style register kind
-  lldb::RegisterKind GetRegisterKind() const;
+  int GetRegisterKind();
 
   /// Set the call-frame-info style register kind
   ///
@@ -95,6 +141,20 @@ class DWARFExpression {
   ///     The register kind.
   void SetRegisterKind(lldb::RegisterKind reg_kind);
 
+  /// Wrapper for the static evaluate function that accepts an
+  /// ExecutionContextScope instead of an ExecutionContext and uses member
+  /// variables to populate many operands
+  bool Evaluate(ExecutionContextScope *exe_scope, lldb::addr_t func_load_addr,
+                const Value *initial_value_ptr, const Value *object_address_ptr,
+                Value &result, Status *error_ptr) const;
+
+  /// Wrapper for the static evaluate function that uses member variables to
+  /// populate many operands
+  bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
+                lldb::addr_t loclist_base_load_addr,
+                const Value *initial_value_ptr, const Value *object_address_ptr,
+                Value &result, Status *error_ptr) const;
+
   /// Evaluate a DWARF location expression in a particular context
   ///
   /// \param[in] exe_ctx
@@ -134,32 +194,72 @@ class DWARFExpression {
   ///     True on success; false otherwise.  If error_ptr is non-NULL,
   ///     details of the failure are provided through it.
   static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
-                       lldb::ModuleSP module_sp, const DataExtractor &opcodes,
+                       lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
                        const DWARFUnit *dwarf_cu,
                        const lldb::RegisterKind reg_set,
                        const Value *initial_value_ptr,
                        const Value *object_address_ptr, Value &result,
                        Status *error_ptr);
 
-  static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu,
-                                     const DataExtractor &data,
-                                     DWARFExpressionList *loc_list);
-
   bool GetExpressionData(DataExtractor &data) const {
     data = m_data;
     return data.GetByteSize() > 0;
   }
 
-  void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
+  bool DumpLocationForAddress(Stream *s, lldb::DescriptionLevel level,
+                              lldb::addr_t func_load_addr, lldb::addr_t address,
+                              ABI *abi);
+
+  bool DumpLocations(Stream *s, lldb::DescriptionLevel level,
+                     lldb::addr_t func_load_addr, lldb::addr_t addr, ABI *abi);
+
+  bool GetLocationExpressions(
+      lldb::addr_t load_function_start,
+      llvm::function_ref<bool(llvm::DWARFLocationExpression)> callback) const;
 
-  bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
+  bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op);
+
+  llvm::Optional<DataExtractor>
+  GetLocationExpression(lldb::addr_t load_function_start,
+                        lldb::addr_t addr) const;
 
 private:
+  /// Pretty-prints the location expression to a stream
+  ///
+  /// \param[in] s
+  ///     The stream to use for pretty-printing.
+  ///
+  /// \param[in] data
+  ///     The data extractor.
+  ///
+  /// \param[in] level
+  ///     The level of detail to use in pretty-printing.
+  ///
+  /// \param[in] abi
+  ///     An optional ABI plug-in that can be used to resolve register
+  ///     names.
+  void DumpLocation(Stream *s, const DataExtractor &data,
+                    lldb::DescriptionLevel level, ABI *abi) const;
+
+  /// Module which defined this expression.
+  lldb::ModuleWP m_module_wp;
+
   /// A data extractor capable of reading opcode bytes
   DataExtractor m_data;
 
+  /// The DWARF compile unit this expression belongs to. It is used to evaluate
+  /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
+  /// DW_OP_GNU_const_index)
+  const DWARFUnit *m_dwarf_cu = nullptr;
+
   /// One of the defines that starts with LLDB_REGKIND_
   lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF;
+
+  struct LoclistAddresses {
+    lldb::addr_t cu_file_addr;
+    lldb::addr_t func_file_addr;
+  };
+  llvm::Optional<LoclistAddresses> m_loclist_addresses;
 };
 
 } // namespace lldb_private

diff  --git a/lldb/include/lldb/Expression/DWARFExpressionList.h b/lldb/include/lldb/Expression/DWARFExpressionList.h
deleted file mode 100644
index 34cd217b8fe4a..0000000000000
--- a/lldb/include/lldb/Expression/DWARFExpressionList.h
+++ /dev/null
@@ -1,132 +0,0 @@
-//===-- DWARFExpressionList.h -----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
-#define LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H
-
-#include "lldb/Expression/DWARFExpression.h"
-#include "lldb/Utility/RangeMap.h"
-#include "lldb/lldb-private.h"
-#include "llvm/ADT/Optional.h"
-
-class DWARFUnit;
-
-namespace lldb_private {
-
-/// \class DWARFExpressionList DWARFExpressionList.h
-/// "lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file
-/// address range to a single DWARF location expression.
-class DWARFExpressionList {
-public:
-  DWARFExpressionList() = default;
-
-  DWARFExpressionList(lldb::ModuleSP module_sp, const DWARFUnit *dwarf_cu)
-      : m_module_wp(module_sp), m_dwarf_cu(dwarf_cu) {}
-
-  DWARFExpressionList(lldb::ModuleSP module_sp, DWARFExpression expr,
-                      const DWARFUnit *dwarf_cu)
-      : DWARFExpressionList(module_sp, dwarf_cu) {
-    AddExpression(0, LLDB_INVALID_ADDRESS, expr);
-  }
-
-  /// Return true if the location expression contains data
-  bool IsValid() const { return !m_exprs.IsEmpty(); }
-
-  void Clear() { m_exprs.Clear(); }
-
-  // Return true if the location expression is always valid.
-  bool IsAlwaysValidSingleExpr() const;
-
-  bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr);
-
-  /// Get the expression data at the file address.
-  bool GetExpressionData(DataExtractor &data, lldb::addr_t file_addr = 0) const;
-
-  /// Sort m_expressions.
-  void Sort() { m_exprs.Sort(); }
-
-  const DWARFExpression *GetExpressionAtAddress(lldb::addr_t file_addr) const;
-
-  const DWARFExpression *GetAlwaysValidExpr() const {
-    return GetExpressionAtAddress(0);
-  }
-
-  DWARFExpression *GetMutableExpressionAtAddress(lldb::addr_t file_addr = 0);
-
-  size_t GetSize() const { return m_exprs.GetSize(); }
-
-  bool ContainsThreadLocalStorage() const;
-
-  bool LinkThreadLocalStorage(
-      lldb::ModuleSP new_module_sp,
-      std::function<lldb::addr_t(lldb::addr_t file_addr)> const
-          &link_address_callback);
-
-  bool MatchesOperand(StackFrame &frame,
-                      const Instruction::Operand &operand) const;
-
-  /// Dump locations that contains file_addr if it's valid. Otherwise. dump all
-  /// locations.
-  bool DumpLocations(Stream *s, lldb::DescriptionLevel level,
-                     lldb::addr_t file_addr, ABI *abi) const;
-
-  /// Dump all locaitons with each seperated by new line.
-  void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
-
-  /// Search for a load address in the location list
-  ///
-  /// \param[in] file_addr
-  ///     The file address to resolve
-  ///
-  /// \return
-  ///     True if IsLocationList() is true and the address was found;
-  ///     false otherwise.
-  //    bool
-  //    LocationListContainsLoadAddress (Process* process, const Address &addr)
-  //    const;
-  //
-  bool ContainsAddress(lldb::addr_t file_addr) const;
-
-  void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; }
-
-  bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
-                const Value *initial_value_ptr, const Value *object_address_ptr,
-                Value &result, Status *error_ptr) const;
-
-private:
-  // RangeDataVector requires a comparator for DWARFExpression, but it doesn't
-  // make sense to do so.
-  struct DWARFExpressionCompare {
-  public:
-    bool operator()(const DWARFExpression &lhs,
-                    const DWARFExpression &rhs) const {
-      return false;
-    }
-  };
-  using ExprVec = RangeDataVector<lldb::addr_t, lldb::addr_t, DWARFExpression,
-                                  0, DWARFExpressionCompare>;
-  using Entry = ExprVec::Entry;
-
-  // File address range mapping to single dwarf expression.
-  ExprVec m_exprs;
-
-  /// Module which defined this expression.
-  lldb::ModuleWP m_module_wp;
-
-  /// The DWARF compile unit this expression belongs to. It is used to evaluate
-  /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
-  /// DW_OP_GNU_const_index)
-  const DWARFUnit *m_dwarf_cu = nullptr;
-
-  using const_iterator = ExprVec::Collection::const_iterator;
-  const_iterator begin() const { return m_exprs.begin(); }
-  const_iterator end() const { return m_exprs.end(); }
-};
-} // namespace lldb_private
-
-#endif // LLDB_EXPRESSION_DWARFEXPRESSIONLIST_H

diff  --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h
index 3eb4f5d7dedf4..83f9979c3c529 100644
--- a/lldb/include/lldb/Symbol/Function.h
+++ b/lldb/include/lldb/Symbol/Function.h
@@ -12,7 +12,7 @@
 #include "lldb/Core/AddressRange.h"
 #include "lldb/Core/Declaration.h"
 #include "lldb/Core/Mangled.h"
-#include "lldb/Expression/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Symbol/Block.h"
 #include "lldb/Utility/UserID.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -253,8 +253,8 @@ class Function;
 /// Represent the locations of a parameter at a call site, both in the caller
 /// and in the callee.
 struct CallSiteParameter {
-  DWARFExpressionList LocationInCallee;
-  DWARFExpressionList LocationInCaller;
+  DWARFExpression LocationInCallee;
+  DWARFExpression LocationInCaller;
 };
 
 /// A vector of \c CallSiteParameter.
@@ -370,7 +370,7 @@ class IndirectCallEdge : public CallEdge {
 public:
   /// Construct a call edge using a DWARFExpression to identify the callee, and
   /// a return PC within the calling function to identify a specific call site.
-  IndirectCallEdge(DWARFExpressionList call_target, AddrType caller_address_type,
+  IndirectCallEdge(DWARFExpression call_target, AddrType caller_address_type,
                    lldb::addr_t caller_address, bool is_tail_call,
                    CallSiteParameterArray &&parameters)
       : CallEdge(caller_address_type, caller_address, is_tail_call,
@@ -383,7 +383,7 @@ class IndirectCallEdge : public CallEdge {
   // Used to describe an indirect call.
   //
   // Specifies the location of the callee address in the calling frame.
-  DWARFExpressionList call_target;
+  DWARFExpression call_target;
 };
 
 /// \class Function Function.h "lldb/Symbol/Function.h"
@@ -521,13 +521,13 @@ class Function : public UserID, public SymbolContextScope {
   /// \return
   ///     A location expression that describes the function frame
   ///     base.
-  DWARFExpressionList &GetFrameBaseExpression() { return m_frame_base; }
+  DWARFExpression &GetFrameBaseExpression() { return m_frame_base; }
 
   /// Get const accessor for the frame base location.
   ///
   /// \return
   ///     A const compile unit object pointer.
-  const DWARFExpressionList &GetFrameBaseExpression() const { return m_frame_base; }
+  const DWARFExpression &GetFrameBaseExpression() const { return m_frame_base; }
 
   ConstString GetName() const;
 
@@ -659,7 +659,7 @@ class Function : public UserID, public SymbolContextScope {
 
   /// The frame base expression for variables that are relative to the frame
   /// pointer.
-  DWARFExpressionList m_frame_base;
+  DWARFExpression m_frame_base;
 
   Flags m_flags;
 

diff  --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h
index c437624d1ea6d..88a975df39928 100644
--- a/lldb/include/lldb/Symbol/Variable.h
+++ b/lldb/include/lldb/Symbol/Variable.h
@@ -11,7 +11,7 @@
 
 #include "lldb/Core/Declaration.h"
 #include "lldb/Core/Mangled.h"
-#include "lldb/Expression/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Utility/CompletionRequest.h"
 #include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/UserID.h"
@@ -32,8 +32,8 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
   Variable(lldb::user_id_t uid, const char *name, const char *mangled,
            const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope,
            SymbolContextScope *owner_scope, const RangeList &scope_range,
-           Declaration *decl, const DWARFExpressionList &location,
-           bool external, bool artificial, bool location_is_constant_data,
+           Declaration *decl, const DWARFExpression &location, bool external,
+           bool artificial, bool location_is_constant_data,
            bool static_member = false);
 
   virtual ~Variable();
@@ -73,11 +73,9 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
 
   bool IsStaticMember() const { return m_static_member; }
 
-  DWARFExpressionList &LocationExpressionList() { return m_location_list; }
+  DWARFExpression &LocationExpression() { return m_location; }
 
-  const DWARFExpressionList &LocationExpressionList() const {
-    return m_location_list;
-  }
+  const DWARFExpression &LocationExpression() const { return m_location; }
 
   // When given invalid address, it dumps all locations. Otherwise it only dumps
   // the location that contains this address.
@@ -130,7 +128,7 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> {
   Declaration m_declaration;
   /// The location of this variable that can be fed to
   /// DWARFExpression::Evaluate().
-  DWARFExpressionList m_location_list;
+  DWARFExpression m_location;
   /// Visible outside the containing compile unit?
   unsigned m_external : 1;
   /// Non-zero if the variable is not explicitly declared in source.

diff  --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h
index 7c4340de4de06..1b0485b22cacb 100644
--- a/lldb/include/lldb/Target/StackFrame.h
+++ b/lldb/include/lldb/Target/StackFrame.h
@@ -202,7 +202,7 @@ class StackFrame : public ExecutionContextScope,
   ///   frames may be unable to provide this value; they will return false.
   bool GetFrameBaseValue(Scalar &value, Status *error_ptr);
 
-  /// Get the DWARFExpressionList corresponding to the Canonical Frame Address.
+  /// Get the DWARFExpression corresponding to the Canonical Frame Address.
   ///
   /// Often a register (bp), but sometimes a register + offset.
   ///
@@ -212,7 +212,7 @@ class StackFrame : public ExecutionContextScope,
   ///
   /// \return
   ///   Returns the corresponding DWARF expression, or NULL.
-  DWARFExpressionList *GetFrameBaseExpression(Status *error_ptr);
+  DWARFExpression *GetFrameBaseExpression(Status *error_ptr);
 
   /// Get the current lexical scope block for this StackFrame, if possible.
   ///

diff  --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index 257b177c70927..7eb0cab8084c7 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -627,10 +627,6 @@ class RangeDataVector {
     return (m_entries.empty() ? nullptr : &m_entries.back());
   }
 
-  using const_iterator = typename Collection::const_iterator;
-  const_iterator begin() const { return m_entries.begin(); }
-  const_iterator end() const { return m_entries.end(); }
-
 protected:
   Collection m_entries;
   Compare m_compare;

diff  --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index c51e1850338ff..487b2f20792b9 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -66,7 +66,6 @@ class ConstStringTable;
 class DWARFCallFrameInfo;
 class DWARFDataExtractor;
 class DWARFExpression;
-class DWARFExpressionList;
 class DataBuffer;
 class WritableDataBuffer;
 class DataBufferHeap;

diff  --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index 7f0e86b9294da..8e89503a8a76b 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -13,7 +13,7 @@
 #include "lldb/Core/Declaration.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolContext.h"
@@ -127,20 +127,22 @@ bool ValueObjectVariable::UpdateValue() {
   m_error.Clear();
 
   Variable *variable = m_variable_sp.get();
-  DWARFExpressionList &expr_list = variable->LocationExpressionList();
+  DWARFExpression &expr = variable->LocationExpression();
 
   if (variable->GetLocationIsConstantValueData()) {
     // expr doesn't contain DWARF bytes, it contains the constant variable
     // value bytes themselves...
-    if (expr_list.GetExpressionData(m_data)) {
-      if (m_data.GetDataStart() && m_data.GetByteSize())
+    if (expr.GetExpressionData(m_data)) {
+       if (m_data.GetDataStart() && m_data.GetByteSize())
         m_value.SetBytes(m_data.GetDataStart(), m_data.GetByteSize());
       m_value.SetContext(Value::ContextType::Variable, variable);
-    } else
+    }
+    else
       m_error.SetErrorString("empty constant data");
     // constant bytes can't be edited - sorry
     m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
   } else {
+    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
     ExecutionContext exe_ctx(GetExecutionContextRef());
 
     Target *target = exe_ctx.GetTargetPtr();
@@ -149,8 +151,17 @@ bool ValueObjectVariable::UpdateValue() {
       m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
     }
 
+    if (expr.IsLocationList()) {
+      SymbolContext sc;
+      variable->CalculateSymbolContext(&sc);
+      if (sc.function)
+        loclist_base_load_addr =
+            sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
+                target);
+    }
     Value old_value(m_value);
-    if (expr_list.Evaluate(&exe_ctx, nullptr, nullptr, nullptr, m_value, &m_error)) {
+    if (expr.Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, nullptr,
+                      nullptr, m_value, &m_error)) {
       m_resolved_value = m_value;
       m_value.SetContext(Value::ContextType::Variable, variable);
 
@@ -235,7 +246,7 @@ bool ValueObjectVariable::UpdateValue() {
       m_resolved_value.SetContext(Value::ContextType::Invalid, nullptr);
     }
   }
-
+  
   return m_error.Success();
 }
 

diff  --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt
index 54414fb2a7c4f..c935e1b1c04b9 100644
--- a/lldb/source/Expression/CMakeLists.txt
+++ b/lldb/source/Expression/CMakeLists.txt
@@ -1,7 +1,6 @@
 add_lldb_library(lldbExpression
   DiagnosticManager.cpp
   DWARFExpression.cpp
-  DWARFExpressionList.cpp
   Expression.cpp
   ExpressionVariable.cpp
   FunctionCaller.cpp

diff  --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index fff5f60bc3abf..1f11907dc64c4 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -45,10 +45,29 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::dwarf;
 
-// DWARFExpression constructor
-DWARFExpression::DWARFExpression() : m_data() {}
+static lldb::addr_t
+ReadAddressFromDebugAddrSection(const DWARFUnit *dwarf_cu,
+                                uint32_t index) {
+  uint32_t index_size = dwarf_cu->GetAddressByteSize();
+  dw_offset_t addr_base = dwarf_cu->GetAddrBase();
+  lldb::offset_t offset = addr_base + index * index_size;
+  const DWARFDataExtractor &data =
+      dwarf_cu->GetSymbolFileDWARF().GetDWARFContext().getOrLoadAddrData();
+  if (data.ValidOffsetForDataOfSize(offset, index_size))
+    return data.GetMaxU64_unchecked(&offset, index_size);
+  return LLDB_INVALID_ADDRESS;
+}
 
-DWARFExpression::DWARFExpression(const DataExtractor &data) : m_data(data) {}
+// DWARFExpression constructor
+DWARFExpression::DWARFExpression() : m_module_wp(), m_data() {}
+
+DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp,
+                                 const DataExtractor &data,
+                                 const DWARFUnit *dwarf_cu)
+    : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu) {
+  if (module_sp)
+    m_module_wp = module_sp;
+}
 
 // Destructor
 DWARFExpression::~DWARFExpression() = default;
@@ -67,19 +86,71 @@ void DWARFExpression::UpdateValue(uint64_t const_value,
   m_data.SetAddressByteSize(addr_byte_size);
 }
 
-void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
+void DWARFExpression::DumpLocation(Stream *s, const DataExtractor &data,
+                                   lldb::DescriptionLevel level,
                                    ABI *abi) const {
-  llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize())
+  llvm::DWARFExpression(data.GetAsLLVM(), data.GetAddressByteSize())
       .print(s->AsRawOstream(), llvm::DIDumpOptions(),
              abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr);
 }
 
-RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
+void DWARFExpression::SetLocationListAddresses(addr_t cu_file_addr,
+                                               addr_t func_file_addr) {
+  m_loclist_addresses = LoclistAddresses{cu_file_addr, func_file_addr};
+}
+
+int DWARFExpression::GetRegisterKind() { return m_reg_kind; }
 
 void DWARFExpression::SetRegisterKind(RegisterKind reg_kind) {
   m_reg_kind = reg_kind;
 }
 
+bool DWARFExpression::IsLocationList() const {
+  return bool(m_loclist_addresses);
+}
+
+namespace {
+/// Implement enough of the DWARFObject interface in order to be able to call
+/// DWARFLocationTable::dumpLocationList. We don't have access to a real
+/// DWARFObject here because DWARFExpression is used in non-DWARF scenarios too.
+class DummyDWARFObject final: public llvm::DWARFObject {
+public:
+  DummyDWARFObject(bool IsLittleEndian) : IsLittleEndian(IsLittleEndian) {}
+
+  bool isLittleEndian() const override { return IsLittleEndian; }
+
+  llvm::Optional<llvm::RelocAddrEntry> find(const llvm::DWARFSection &Sec,
+                                            uint64_t Pos) const override {
+    return llvm::None;
+  }
+private:
+  bool IsLittleEndian;
+};
+}
+
+void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level,
+                                     ABI *abi) const {
+  if (IsLocationList()) {
+    // We have a location list
+    lldb::offset_t offset = 0;
+    std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
+        m_dwarf_cu->GetLocationTable(m_data);
+
+    llvm::MCRegisterInfo *MRI = abi ? &abi->GetMCRegisterInfo() : nullptr;
+    llvm::DIDumpOptions DumpOpts;
+    DumpOpts.RecoverableErrorHandler = [&](llvm::Error E) {
+      s->AsRawOstream() << "error: " << toString(std::move(E));
+    };
+    loctable_up->dumpLocationList(
+        &offset, s->AsRawOstream(),
+        llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr}, MRI,
+        DummyDWARFObject(m_data.GetByteOrder() == eByteOrderLittle), nullptr,
+        DumpOpts, s->GetIndentLevel() + 2);
+  } else {
+    // We have a normal location that contains DW_OP location opcodes
+    DumpLocation(s, m_data, level, abi);
+  }
+}
 
 static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
                                       lldb::RegisterKind reg_kind,
@@ -338,10 +409,11 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data,
   return LLDB_INVALID_OFFSET;
 }
 
-lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
-                                                     uint32_t op_addr_idx,
+lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(uint32_t op_addr_idx,
                                                      bool &error) const {
   error = false;
+  if (IsLocationList())
+    return LLDB_INVALID_ADDRESS;
   lldb::offset_t offset = 0;
   uint32_t curr_op_addr_idx = 0;
   while (m_data.ValidOffset(offset)) {
@@ -351,18 +423,19 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
       const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
       if (curr_op_addr_idx == op_addr_idx)
         return op_file_addr;
-      ++curr_op_addr_idx;
+      else
+        ++curr_op_addr_idx;
     } else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
       uint64_t index = m_data.GetULEB128(&offset);
       if (curr_op_addr_idx == op_addr_idx) {
-        if (!dwarf_cu) {
+        if (!m_dwarf_cu) {
           error = true;
           break;
         }
 
-        return dwarf_cu->ReadAddressFromDebugAddrSection(index);
-      }
-      ++curr_op_addr_idx;
+        return ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
+      } else
+        ++curr_op_addr_idx;
     } else {
       const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
       if (op_arg_size == LLDB_INVALID_OFFSET) {
@@ -376,6 +449,8 @@ lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
 }
 
 bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
+  if (IsLocationList())
+    return false;
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const uint8_t op = m_data.GetU8(&offset);
@@ -412,6 +487,11 @@ bool DWARFExpression::Update_DW_OP_addr(lldb::addr_t file_addr) {
 }
 
 bool DWARFExpression::ContainsThreadLocalStorage() const {
+  // We are assuming for now that any thread local variable will not have a
+  // location list. This has been true for all thread local variables we have
+  // seen so far produced by any compiler.
+  if (IsLocationList())
+    return false;
   lldb::offset_t offset = 0;
   while (m_data.ValidOffset(offset)) {
     const uint8_t op = m_data.GetU8(&offset);
@@ -421,18 +501,27 @@ bool DWARFExpression::ContainsThreadLocalStorage() const {
     const offset_t op_arg_size = GetOpcodeDataSize(m_data, offset, op);
     if (op_arg_size == LLDB_INVALID_OFFSET)
       return false;
-    offset += op_arg_size;
+    else
+      offset += op_arg_size;
   }
   return false;
 }
 bool DWARFExpression::LinkThreadLocalStorage(
+    lldb::ModuleSP new_module_sp,
     std::function<lldb::addr_t(lldb::addr_t file_addr)> const
         &link_address_callback) {
+  // We are assuming for now that any thread local variable will not have a
+  // location list. This has been true for all thread local variables we have
+  // seen so far produced by any compiler.
+  if (IsLocationList())
+    return false;
+
   const uint32_t addr_byte_size = m_data.GetAddressByteSize();
   // We have to make a copy of the data as we don't know if this data is from a
   // read only memory mapped buffer, so we duplicate all of the data first,
   // then modify it, and if all goes well, we then replace the data for this
   // expression.
+
   // Make en encoder that contains a copy of the location expression data so we
   // can write the address into the buffer using the correct byte order.
   DataEncoder encoder(m_data.GetDataStart(), m_data.GetByteSize(),
@@ -504,10 +593,42 @@ bool DWARFExpression::LinkThreadLocalStorage(
     }
   }
 
+  // If we linked the TLS address correctly, update the module so that when the
+  // expression is evaluated it can resolve the file address to a load address
+  // and read the
+  // TLS data
+  m_module_wp = new_module_sp;
   m_data.SetData(encoder.GetDataBuffer());
   return true;
 }
 
+bool DWARFExpression::LocationListContainsAddress(addr_t func_load_addr,
+                                                  lldb::addr_t addr) const {
+  if (func_load_addr == LLDB_INVALID_ADDRESS || addr == LLDB_INVALID_ADDRESS)
+    return false;
+
+  if (!IsLocationList())
+    return false;
+
+  return GetLocationExpression(func_load_addr, addr) != llvm::None;
+}
+
+bool DWARFExpression::DumpLocationForAddress(Stream *s,
+                                             lldb::DescriptionLevel level,
+                                             addr_t func_load_addr,
+                                             addr_t address, ABI *abi) {
+  if (!IsLocationList()) {
+    DumpLocation(s, m_data, level, abi);
+    return true;
+  }
+  if (llvm::Optional<DataExtractor> expr =
+          GetLocationExpression(func_load_addr, address)) {
+    DumpLocation(s, *expr, level, abi);
+    return true;
+  }
+  return false;
+}
+
 static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
                                        ExecutionContext *exe_ctx,
                                        RegisterContext *reg_ctx,
@@ -703,9 +824,10 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
   // TODO: Add support for DW_OP_push_object_address within a DW_OP_entry_value
   // subexpresion whenever llvm does.
   Value result;
-  const DWARFExpressionList &param_expr = matched_param->LocationInCaller;
+  const DWARFExpression &param_expr = matched_param->LocationInCaller;
   if (!param_expr.Evaluate(&parent_exe_ctx,
                            parent_frame->GetRegisterContext().get(),
+                           /*loclist_base_load_addr=*/LLDB_INVALID_ADDRESS,
                            /*initial_value_ptr=*/nullptr,
                            /*object_address_ptr=*/nullptr, result, error_ptr)) {
     LLDB_LOG(log,
@@ -717,6 +839,63 @@ static bool Evaluate_DW_OP_entry_value(std::vector<Value> &stack,
   return true;
 }
 
+bool DWARFExpression::Evaluate(ExecutionContextScope *exe_scope,
+                               lldb::addr_t loclist_base_load_addr,
+                               const Value *initial_value_ptr,
+                               const Value *object_address_ptr, Value &result,
+                               Status *error_ptr) const {
+  ExecutionContext exe_ctx(exe_scope);
+  return Evaluate(&exe_ctx, nullptr, loclist_base_load_addr, initial_value_ptr,
+                  object_address_ptr, result, error_ptr);
+}
+
+bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
+                               RegisterContext *reg_ctx,
+                               lldb::addr_t func_load_addr,
+                               const Value *initial_value_ptr,
+                               const Value *object_address_ptr, Value &result,
+                               Status *error_ptr) const {
+  ModuleSP module_sp = m_module_wp.lock();
+
+  if (IsLocationList()) {
+    Address pc;
+    StackFrame *frame = nullptr;
+    if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) {
+      frame = exe_ctx->GetFramePtr();
+      if (!frame)
+        return false;
+      RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
+      if (!reg_ctx_sp)
+        return false;
+      reg_ctx_sp->GetPCForSymbolication(pc);
+    }
+
+    if (func_load_addr != LLDB_INVALID_ADDRESS) {
+      if (!pc.IsValid()) {
+        if (error_ptr)
+          error_ptr->SetErrorString("Invalid PC in frame.");
+        return false;
+      }
+
+      Target *target = exe_ctx->GetTargetPtr();
+      if (llvm::Optional<DataExtractor> expr = GetLocationExpression(
+              func_load_addr, pc.GetLoadAddress(target))) {
+        return DWARFExpression::Evaluate(
+            exe_ctx, reg_ctx, module_sp, *expr, m_dwarf_cu, m_reg_kind,
+            initial_value_ptr, object_address_ptr, result, error_ptr);
+      }
+    }
+    if (error_ptr)
+      error_ptr->SetErrorString("variable not available");
+    return false;
+  }
+
+  // Not a location list, just a single expression.
+  return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, m_data,
+                                   m_dwarf_cu, m_reg_kind, initial_value_ptr,
+                                   object_address_ptr, result, error_ptr);
+}
+
 namespace {
 /// The location description kinds described by the DWARF v5
 /// specification.  Composite locations are handled out-of-band and
@@ -2491,7 +2670,7 @@ bool DWARFExpression::Evaluate(
         return false;
       }
       uint64_t index = opcodes.GetULEB128(&offset);
-      lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
+      lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
       stack.push_back(Scalar(value));
       stack.back().SetValueType(Value::ValueType::FileAddress);
     } break;
@@ -2511,7 +2690,7 @@ bool DWARFExpression::Evaluate(
         return false;
       }
       uint64_t index = opcodes.GetULEB128(&offset);
-      lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
+      lldb::addr_t value = ReadAddressFromDebugAddrSection(dwarf_cu, index);
       stack.push_back(Scalar(value));
     } break;
 
@@ -2564,16 +2743,61 @@ bool DWARFExpression::Evaluate(
   return true; // Return true on success
 }
 
-bool DWARFExpression::ParseDWARFLocationList(
-    const DWARFUnit *dwarf_cu, const DataExtractor &data,
-    DWARFExpressionList *location_list) {
-  location_list->Clear();
-  std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
-      dwarf_cu->GetLocationTable(data);
+static DataExtractor ToDataExtractor(const llvm::DWARFLocationExpression &loc,
+                                     ByteOrder byte_order, uint32_t addr_size) {
+  auto buffer_sp =
+      std::make_shared<DataBufferHeap>(loc.Expr.data(), loc.Expr.size());
+  return DataExtractor(buffer_sp, byte_order, addr_size);
+}
+
+bool DWARFExpression::DumpLocations(Stream *s, lldb::DescriptionLevel level,
+                                    addr_t load_function_start, addr_t addr,
+                                    ABI *abi) {
+  if (!IsLocationList()) {
+    DumpLocation(s, m_data, level, abi);
+    return true;
+  }
+  bool dump_all = addr == LLDB_INVALID_ADDRESS;
+  llvm::ListSeparator separator;
+  auto callback = [&](llvm::DWARFLocationExpression loc) -> bool {
+    if (loc.Range &&
+        (dump_all || (loc.Range->LowPC <= addr && addr < loc.Range->HighPC))) {
+      uint32_t addr_size = m_data.GetAddressByteSize();
+      DataExtractor data = ToDataExtractor(loc, m_data.GetByteOrder(),
+                                           m_data.GetAddressByteSize());
+      s->AsRawOstream() << separator;
+      s->PutCString("[");
+      s->AsRawOstream() << llvm::format_hex(loc.Range->LowPC,
+                                            2 + 2 * addr_size);
+      s->PutCString(", ");
+      s->AsRawOstream() << llvm::format_hex(loc.Range->HighPC,
+                                            2 + 2 * addr_size);
+      s->PutCString(") -> ");
+      DumpLocation(s, data, level, abi);
+      return dump_all;
+    }
+    return true;
+  };
+  if (!GetLocationExpressions(load_function_start, callback))
+    return false;
+  return true;
+}
+
+bool DWARFExpression::GetLocationExpressions(
+    addr_t load_function_start,
+    llvm::function_ref<bool(llvm::DWARFLocationExpression)> callback) const {
+  if (load_function_start == LLDB_INVALID_ADDRESS)
+    return false;
+
   Log *log = GetLog(LLDBLog::Expressions);
+
+  std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
+      m_dwarf_cu->GetLocationTable(m_data);
+
+  uint64_t offset = 0;
   auto lookup_addr =
       [&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> {
-    addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);
+    addr_t address = ReadAddressFromDebugAddrSection(m_dwarf_cu, index);
     if (address == LLDB_INVALID_ADDRESS)
       return llvm::None;
     return llvm::object::SectionedAddress{address};
@@ -2583,17 +2807,18 @@ bool DWARFExpression::ParseDWARFLocationList(
       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;
+    if (loc->Range) {
+      // This relocates low_pc and high_pc by adding the 
diff erence between the
+      // function file address, and the actual address it is loaded in memory.
+      addr_t slide = load_function_start - m_loclist_addresses->func_file_addr;
+      loc->Range->LowPC += slide;
+      loc->Range->HighPC += slide;
+    }
+    return callback(*loc);
   };
   llvm::Error error = loctable_up->visitAbsoluteLocationList(
-      0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},
+      offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr},
       lookup_addr, process_list);
-  location_list->Sort();
   if (error) {
     LLDB_LOG_ERROR(log, std::move(error), "{0}");
     return false;
@@ -2601,8 +2826,23 @@ bool DWARFExpression::ParseDWARFLocationList(
   return true;
 }
 
-bool DWARFExpression::MatchesOperand(
-    StackFrame &frame, const Instruction::Operand &operand) const {
+llvm::Optional<DataExtractor>
+DWARFExpression::GetLocationExpression(addr_t load_function_start,
+                                       addr_t addr) const {
+  llvm::Optional<DataExtractor> data;
+  auto callback = [&](llvm::DWARFLocationExpression loc) {
+    if (loc.Range && loc.Range->LowPC <= addr && addr < loc.Range->HighPC) {
+      data = ToDataExtractor(loc, m_data.GetByteOrder(),
+                             m_data.GetAddressByteSize());
+    }
+    return !data;
+  };
+  GetLocationExpressions(load_function_start, callback);
+  return data;
+}
+
+bool DWARFExpression::MatchesOperand(StackFrame &frame,
+                                     const Instruction::Operand &operand) {
   using namespace OperandMatchers;
 
   RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
@@ -2610,7 +2850,28 @@ bool DWARFExpression::MatchesOperand(
     return false;
   }
 
-  DataExtractor opcodes(m_data);
+  DataExtractor opcodes;
+  if (IsLocationList()) {
+    SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
+    if (!sc.function)
+      return false;
+
+    addr_t load_function_start =
+        sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
+    if (load_function_start == LLDB_INVALID_ADDRESS)
+      return false;
+
+    addr_t pc = frame.GetFrameCodeAddressForSymbolication().GetLoadAddress(
+        frame.CalculateTarget().get());
+
+    if (llvm::Optional<DataExtractor> expr =
+            GetLocationExpression(load_function_start, pc))
+      opcodes = std::move(*expr);
+    else
+      return false;
+  } else
+    opcodes = m_data;
+
 
   lldb::offset_t op_offset = 0;
   uint8_t opcode = opcodes.GetU8(&op_offset);
@@ -2618,7 +2879,7 @@ bool DWARFExpression::MatchesOperand(
   if (opcode == DW_OP_fbreg) {
     int64_t offset = opcodes.GetSLEB128(&op_offset);
 
-    DWARFExpressionList *fb_expr = frame.GetFrameBaseExpression(nullptr);
+    DWARFExpression *fb_expr = frame.GetFrameBaseExpression(nullptr);
     if (!fb_expr) {
       return false;
     }

diff  --git a/lldb/source/Expression/DWARFExpressionList.cpp b/lldb/source/Expression/DWARFExpressionList.cpp
deleted file mode 100644
index 68e3e8c611b9f..0000000000000
--- a/lldb/source/Expression/DWARFExpressionList.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-//===-- DWARFExpressionList.cpp -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Expression/DWARFExpressionList.h"
-#include "Plugins/SymbolFile/DWARF/DWARFUnit.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-bool DWARFExpressionList::IsAlwaysValidSingleExpr() const {
-  if (m_exprs.GetSize() != 1)
-    return false;
-  const Entry expr = m_exprs.GetEntryRef(0);
-  return expr.base == 0 && expr.size == LLDB_INVALID_ADDRESS;
-}
-
-bool DWARFExpressionList::AddExpression(addr_t base, addr_t end,
-                                        DWARFExpression expr) {
-  if (IsAlwaysValidSingleExpr() || base >= end)
-    return false;
-  m_exprs.Append({base, end - base, expr});
-  return true;
-}
-
-bool DWARFExpressionList::GetExpressionData(DataExtractor &data,
-                                            lldb::addr_t file_addr) const {
-  if (const DWARFExpression *expr = GetExpressionAtAddress(file_addr))
-    return expr->GetExpressionData(data);
-  return false;
-}
-
-bool DWARFExpressionList::ContainsAddress(lldb::addr_t file_addr) const {
-  return m_exprs.FindEntryThatContains(file_addr) != nullptr;
-}
-
-const DWARFExpression *
-DWARFExpressionList::GetExpressionAtAddress(lldb::addr_t file_addr) const {
-  uint32_t index = m_exprs.FindEntryIndexThatContains(file_addr);
-  if (index == UINT32_MAX)
-    return nullptr;
-  return &m_exprs.GetEntryAtIndex(index)->data;
-}
-
-DWARFExpression *
-DWARFExpressionList::GetMutableExpressionAtAddress(lldb::addr_t file_addr) {
-  uint32_t index = m_exprs.FindEntryIndexThatContains(file_addr);
-  if (index == UINT32_MAX)
-    return nullptr;
-  return &m_exprs.GetMutableEntryAtIndex(index)->data;
-}
-
-bool DWARFExpressionList::ContainsThreadLocalStorage() const {
-  // We are assuming for now that any thread local variable will not have a
-  // location list. This has been true for all thread local variables we have
-  // seen so far produced by any compiler.
-  if (!IsAlwaysValidSingleExpr())
-    return false;
-
-  const DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
-  return expr.ContainsThreadLocalStorage();
-}
-
-bool DWARFExpressionList::LinkThreadLocalStorage(
-    lldb::ModuleSP new_module_sp,
-    std::function<lldb::addr_t(lldb::addr_t file_addr)> const
-        &link_address_callback) {
-  // We are assuming for now that any thread local variable will not have a
-  // location list. This has been true for all thread local variables we have
-  // seen so far produced by any compiler.
-  if (!IsAlwaysValidSingleExpr())
-    return false;
-
-  DWARFExpression &expr = m_exprs.GetEntryRef(0).data;
-  // If we linked the TLS address correctly, update the module so that when the
-  // expression is evaluated it can resolve the file address to a load address
-  // and read the TLS data
-  if (expr.LinkThreadLocalStorage(link_address_callback))
-    m_module_wp = new_module_sp;
-  return true;
-}
-
-bool DWARFExpressionList::MatchesOperand(
-    StackFrame &frame, const Instruction::Operand &operand) const {
-  RegisterContextSP reg_ctx_sp = frame.GetRegisterContext();
-  if (!reg_ctx_sp) {
-    return false;
-  }
-  const DWARFExpression *expr = nullptr;
-  if (IsAlwaysValidSingleExpr())
-    expr = &m_exprs.GetEntryAtIndex(0)->data;
-  else {
-    SymbolContext sc = frame.GetSymbolContext(eSymbolContextFunction);
-    if (!sc.function)
-      return false;
-
-    addr_t load_function_start =
-        sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
-    if (load_function_start == LLDB_INVALID_ADDRESS)
-      return false;
-
-    addr_t pc = frame.GetFrameCodeAddressForSymbolication().GetFileAddress();
-    expr = GetExpressionAtAddress(pc);
-  }
-  if (!expr)
-    return false;
-  return expr->MatchesOperand(frame, operand);
-}
-
-bool DWARFExpressionList::DumpLocations(Stream *s, lldb::DescriptionLevel level,
-                                        lldb::addr_t file_addr,
-                                        ABI *abi) const {
-  llvm::raw_ostream &os = s->AsRawOstream();
-  llvm::ListSeparator separator;
-  for (const Entry &entry : *this) {
-    if (file_addr != LLDB_INVALID_ADDRESS &&
-        (file_addr < entry.GetRangeBase() || file_addr >= entry.GetRangeEnd()))
-      continue;
-    const auto &expr = entry.data;
-    DataExtractor data;
-    expr.GetExpressionData(data);
-    uint32_t addr_size = data.GetAddressByteSize();
-    if (entry.GetRangeEnd() == LLDB_INVALID_ADDRESS) {
-      expr.DumpLocation(s, level, abi);
-      break;
-    }
-
-    os << separator;
-    os << "[";
-    os << llvm::format_hex(entry.GetRangeBase(), 2 + 2 * addr_size);
-    os << ", ";
-    os << llvm::format_hex(entry.GetRangeEnd(), 2 + 2 * addr_size);
-    os << ") -> ";
-    expr.DumpLocation(s, level, abi);
-    if (file_addr != LLDB_INVALID_ADDRESS)
-      break;
-  }
-  return true;
-}
-
-void DWARFExpressionList::GetDescription(Stream *s,
-                                         lldb::DescriptionLevel level,
-                                         ABI *abi) const {
-  llvm::raw_ostream &os = s->AsRawOstream();
-  if (IsAlwaysValidSingleExpr()) {
-    m_exprs.Back()->data.DumpLocation(s, level, abi);
-    return;
-  }
-  os << llvm::format("0x%8.8" PRIx64 ": ", 0);
-  for (const Entry &entry : *this) {
-    const auto &expr = entry.data;
-    DataExtractor data;
-    expr.GetExpressionData(data);
-    uint32_t addr_size = data.GetAddressByteSize();
-    os << "\n";
-    os.indent(s->GetIndentLevel() + 2);
-    os << "[";
-    llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeBase());
-    os << ", ";
-    llvm::DWARFFormValue::dumpAddress(os, addr_size, entry.GetRangeEnd());
-    os << "): ";
-    expr.DumpLocation(s, level, abi);
-  }
-}
-
-bool DWARFExpressionList::Evaluate(ExecutionContext *exe_ctx,
-                                   RegisterContext *reg_ctx,
-                                   const Value *initial_value_ptr,
-                                   const Value *object_address_ptr,
-                                   Value &result, Status *error_ptr) const {
-  ModuleSP module_sp = m_module_wp.lock();
-  DataExtractor data;
-  RegisterKind reg_kind;
-  DWARFExpression expr;
-  if (IsAlwaysValidSingleExpr()) {
-    expr = m_exprs.Back()->data;
-  } else {
-    Address pc;
-    StackFrame *frame = nullptr;
-    if (!reg_ctx || !reg_ctx->GetPCForSymbolication(pc)) {
-      if (exe_ctx)
-        frame = exe_ctx->GetFramePtr();
-      if (!frame)
-        return false;
-      RegisterContextSP reg_ctx_sp = frame->GetRegisterContext();
-      if (!reg_ctx_sp)
-        return false;
-      reg_ctx_sp->GetPCForSymbolication(pc);
-    }
-
-    if (!pc.IsValid()) {
-      if (error_ptr)
-        error_ptr->SetErrorString("Invalid PC in frame.");
-      return false;
-    }
-    addr_t addr = pc.GetFileAddress();
-    const auto *entry = m_exprs.FindEntryThatContains(addr);
-    if (!entry) {
-      if (error_ptr)
-        error_ptr->SetErrorString("variable not available");
-      return false;
-    }
-    expr = entry->data;
-  }
-  expr.GetExpressionData(data);
-  reg_kind = expr.GetRegisterKind();
-  return DWARFExpression::Evaluate(exe_ctx, reg_ctx, module_sp, data,
-                                   m_dwarf_cu, reg_kind, initial_value_ptr,
-                                   object_address_ptr, result, error_ptr);
-}

diff  --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 965a96b7f909d..9ee2d983ddfc6 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -520,7 +520,7 @@ class EntityVariable : public Materializer::Entity {
 
         if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize(scope)) {
           if (data.GetByteSize() == 0 &&
-              !m_variable_sp->LocationExpressionList().IsValid()) {
+              !m_variable_sp->LocationExpression().IsValid()) {
             err.SetErrorStringWithFormat("the variable '%s' has no location, "
                                          "it may have been optimized out",
                                          m_variable_sp->GetName().AsCString());

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 6fb7d92244f90..cc45871bcd71a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1485,14 +1485,15 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
     return false;
   }
 
-  DWARFExpressionList &var_location_list = var->LocationExpressionList();
+  DWARFExpression &var_location_expr = var->LocationExpression();
 
   Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
   Status err;
 
   if (var->GetLocationIsConstantValueData()) {
     DataExtractor const_value_extractor;
-    if (var_location_list.GetExpressionData(const_value_extractor)) {
+
+    if (var_location_expr.GetExpressionData(const_value_extractor)) {
       var_location = Value(const_value_extractor.GetDataStart(),
                            const_value_extractor.GetByteSize());
       var_location.SetValueType(Value::ValueType::HostAddress);

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 4b9354371bda3..2aacac3692be5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2292,7 +2292,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
   int call_file = 0;
   int call_line = 0;
   int call_column = 0;
-  DWARFExpressionList frame_base;
+  DWARFExpression frame_base;
 
   const dw_tag_t tag = die.Tag();
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 06cdd877f7dcd..ec074be581b54 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -441,7 +441,7 @@ bool DWARFDIE::GetDIENamesAndRanges(
     const char *&name, const char *&mangled, DWARFRangeList &ranges,
     int &decl_file, int &decl_line, int &decl_column, int &call_file,
     int &call_line, int &call_column,
-    lldb_private::DWARFExpressionList *frame_base) const {
+    lldb_private::DWARFExpression *frame_base) const {
   if (IsValid()) {
     return m_die->GetDIENamesAndRanges(
         GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column,

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index 7ce9550a081e9..5ee44a7632049 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -85,12 +85,11 @@ class DWARFDIE : public DWARFBaseDIE {
   DWARFDIE
   GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const;
 
-  bool
-  GetDIENamesAndRanges(const char *&name, const char *&mangled,
-                       DWARFRangeList &ranges, int &decl_file, int &decl_line,
-                       int &decl_column, int &call_file, int &call_line,
-                       int &call_column,
-                       lldb_private::DWARFExpressionList *frame_base) const;
+  bool GetDIENamesAndRanges(const char *&name, const char *&mangled,
+                            DWARFRangeList &ranges, int &decl_file,
+                            int &decl_line, int &decl_column, int &call_file,
+                            int &call_line, int &call_column,
+                            lldb_private::DWARFExpression *frame_base) const;
 
   /// The range of all the children of this DIE.
   llvm::iterator_range<child_iterator> children() const;

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index c1d49c5f23d7c..95c0cb6472c59 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -231,10 +231,11 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
     DWARFUnit *cu, const char *&name, const char *&mangled,
     DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
     int &call_file, int &call_line, int &call_column,
-    DWARFExpressionList *frame_base) const {
+    DWARFExpression *frame_base) const {
   dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
   dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
   std::vector<DWARFDIE> dies;
+  bool set_frame_base_loclist_addr = false;
 
   const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu);
 
@@ -344,17 +345,21 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
               uint32_t block_offset =
                   form_value.BlockData() - data.GetDataStart();
               uint32_t block_length = form_value.Unsigned();
-              *frame_base =
-                  DWARFExpressionList(module,
-                                      DWARFExpression(DataExtractor(
-                                          data, block_offset, block_length)),
-                                      cu);
+              *frame_base = DWARFExpression(
+                  module, DataExtractor(data, block_offset, block_length), cu);
             } else {
               DataExtractor data = cu->GetLocationData();
               const dw_offset_t offset = form_value.Unsigned();
               if (data.ValidOffset(offset)) {
                 data = DataExtractor(data, offset, data.GetByteSize() - offset);
-                DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
+                *frame_base = DWARFExpression(module, data, cu);
+                if (lo_pc != LLDB_INVALID_ADDRESS) {
+                  assert(lo_pc >= cu->GetBaseAddress());
+                  frame_base->SetLocationListAddresses(cu->GetBaseAddress(),
+                                                       lo_pc);
+                } else {
+                  set_frame_base_loclist_addr = true;
+                }
               }
             }
           }
@@ -376,6 +381,12 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
     }
   }
 
+  if (set_frame_base_loclist_addr) {
+    dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
+    assert(lowest_range_pc >= cu->GetBaseAddress());
+    frame_base->SetLocationListAddresses(cu->GetBaseAddress(), lowest_range_pc);
+  }
+
   if (ranges.IsEmpty() || name == nullptr || mangled == nullptr) {
     for (const DWARFDIE &die : dies) {
       if (die) {

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 32f653e99a705..64e86c71ac09e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -104,7 +104,7 @@ class DWARFDebugInfoEntry {
       DWARFUnit *cu, const char *&name, const char *&mangled,
       DWARFRangeList &rangeList, int &decl_file, int &decl_line,
       int &decl_column, int &call_file, int &call_line, int &call_column,
-      lldb_private::DWARFExpressionList *frame_base = nullptr) const;
+      lldb_private::DWARFExpression *frame_base = nullptr) const;
 
   const DWARFAbbreviationDeclaration *
   GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const;

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 7b4a5d8eca3ed..903cd2e38f769 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -579,17 +579,6 @@ void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
   m_str_offsets_base = str_offsets_base;
 }
 
-dw_addr_t DWARFUnit::ReadAddressFromDebugAddrSection(uint32_t index) const {
-  uint32_t index_size = GetAddressByteSize();
-  dw_offset_t addr_base = GetAddrBase();
-  dw_addr_t offset = addr_base + index * index_size;
-  const DWARFDataExtractor &data =
-      m_dwarf.GetDWARFContext().getOrLoadAddrData();
-  if (data.ValidOffsetForDataOfSize(offset, index_size))
-    return data.GetMaxU64_unchecked(&offset, index_size);
-  return LLDB_INVALID_ADDRESS;
-}
-
 // It may be called only with m_die_array_mutex held R/W.
 void DWARFUnit::ClearDIEsRWLocked() {
   m_die_array.clear();

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 40a1943b847a0..265e28b51c991 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -166,8 +166,6 @@ class DWARFUnit : public lldb_private::UserID {
   void SetStrOffsetsBase(dw_offset_t str_offsets_base);
   virtual void BuildAddressRangeTable(DWARFDebugAranges *debug_aranges) = 0;
 
-  dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const;
-
   lldb::ByteOrder GetByteOrder() const;
 
   const DWARFDebugAranges &GetFunctionAranges();

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ab61a699c3edf..c0bf13e0281d3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -9,7 +9,6 @@
 #include "SymbolFileDWARF.h"
 
 #include "llvm/ADT/Optional.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Threading.h"
 
@@ -1886,13 +1885,11 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
             for (size_t g = 0; g < num_globals; ++g) {
               VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
               if (var_sp && !var_sp->GetLocationIsConstantValueData()) {
-                const DWARFExpressionList &location =
-                    var_sp->LocationExpressionList();
+                const DWARFExpression &location = var_sp->LocationExpression();
                 Value location_result;
                 Status error;
-                ExecutionContext exe_ctx;
-                if (location.Evaluate(&exe_ctx, nullptr, nullptr, nullptr,
-                                      location_result, &error)) {
+                if (location.Evaluate(nullptr, LLDB_INVALID_ADDRESS, nullptr,
+                                      nullptr, location_result, &error)) {
                   if (location_result.GetValueType() ==
                       Value::ValueType::FileAddress) {
                     lldb::addr_t file_addr =
@@ -3166,7 +3163,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
   const char *mangled = nullptr;
   Declaration decl;
   DWARFFormValue type_die_form;
-  DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU());
+  DWARFExpression location;
   bool is_external = false;
   bool is_artificial = false;
   DWARFFormValue const_value_form, location_form;
@@ -3232,15 +3229,16 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
   // present in the class declaration and DW_AT_location in the DIE defining
   // the member.
   bool location_is_const_value_data = false;
-  bool has_explicit_location = location_form.IsValid();
+  bool has_explicit_location = false;
   bool use_type_size_for_value = false;
   if (location_form.IsValid()) {
+    has_explicit_location = true;
     if (DWARFFormValue::IsBlockForm(location_form.Form())) {
       const DWARFDataExtractor &data = die.GetData();
 
       uint32_t block_offset = location_form.BlockData() - data.GetDataStart();
       uint32_t block_length = location_form.Unsigned();
-      location_list = DWARFExpressionList(
+      location = DWARFExpression(
           module, DataExtractor(data, block_offset, block_length), die.GetCU());
     } else {
       DataExtractor data = die.GetCU()->GetLocationData();
@@ -3249,8 +3247,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
         offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1);
       if (data.ValidOffset(offset)) {
         data = DataExtractor(data, offset, data.GetByteSize() - offset);
-        const DWARFUnit *dwarf_cu = location_form.GetUnit();
-        DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list);
+        location = DWARFExpression(module, data, die.GetCU());
+        assert(func_low_pc != LLDB_INVALID_ADDRESS);
+        location.SetLocationListAddresses(
+            location_form.GetUnit()->GetBaseAddress(), func_low_pc);
       }
     }
   } else if (const_value_form.IsValid()) {
@@ -3263,7 +3263,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
       uint32_t block_offset =
           const_value_form.BlockData() - debug_info_data.GetDataStart();
       uint32_t block_length = const_value_form.Unsigned();
-      location_list = DWARFExpressionList(
+      location = DWARFExpression(
           module, DataExtractor(debug_info_data, block_offset, block_length),
           die.GetCU());
     } else if (DWARFFormValue::IsDataForm(const_value_form.Form())) {
@@ -3273,7 +3273,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
       use_type_size_for_value = true;
     } else if (const char *str = const_value_form.AsCString()) {
       uint32_t string_length = strlen(str) + 1;
-      location_list = DWARFExpressionList(
+      location = DWARFExpression(
           module,
           DataExtractor(str, string_length, die.GetCU()->GetByteOrder(),
                         die.GetCU()->GetAddressByteSize()),
@@ -3323,19 +3323,16 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
     // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
     // so we need to look through the whole expression.
     bool is_static_lifetime =
-        has_explicit_mangled ||
-        (has_explicit_location && !location_list.IsValid());
+        has_explicit_mangled || (has_explicit_location && !location.IsValid());
     // Check if the location has a DW_OP_addr with any address value...
     lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
     if (!location_is_const_value_data) {
       bool op_error = false;
-      const DWARFExpression* location = location_list.GetAlwaysValidExpr();
-      if (location)
-        location_DW_OP_addr = location->GetLocation_DW_OP_addr(
-            location_form.GetUnit(), 0, op_error);
+      location_DW_OP_addr = location.GetLocation_DW_OP_addr(0, op_error);
       if (op_error) {
         StreamString strm;
-        location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
+        location.DumpLocationForAddress(&strm, eDescriptionLevelFull, 0, 0,
+                                        nullptr);
         GetObjectFile()->GetModule()->ReportError(
             "0x%8.8x: %s has an invalid location: %s", die.GetOffset(),
             die.GetTagAsCString(), strm.GetData());
@@ -3348,7 +3345,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
       // Set the module of the expression to the linked module
       // instead of the object file so the relocated address can be
       // found there.
-      location_list.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
+      location.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
 
     if (is_static_lifetime) {
       if (is_external)
@@ -3389,9 +3386,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
                   const addr_t exe_file_addr =
                       exe_symbol->GetAddressRef().GetFileAddress();
                   if (exe_file_addr != LLDB_INVALID_ADDRESS) {
-                    DWARFExpression *location =
-                        location_list.GetMutableExpressionAtAddress();
-                    if (location->Update_DW_OP_addr(exe_file_addr)) {
+                    if (location.Update_DW_OP_addr(exe_file_addr)) {
                       linked_oso_file_addr = true;
                       symbol_context_scope = exe_symbol;
                     }
@@ -3409,9 +3404,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
               debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
           if (exe_file_addr != LLDB_INVALID_ADDRESS) {
             // Update the file address for this variable
-            DWARFExpression *location =
-                location_list.GetMutableExpressionAtAddress();
-            location->Update_DW_OP_addr(exe_file_addr);
+            location.Update_DW_OP_addr(exe_file_addr);
           } else {
             // Variable didn't make it into the final executable
             return nullptr;
@@ -3426,8 +3419,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
         scope = eValueTypeVariableLocal;
         if (debug_map_symfile) {
           // We need to check for TLS addresses that we need to fixup
-          if (location_list.ContainsThreadLocalStorage()) {
-            location_list.LinkThreadLocalStorage(
+          if (location.ContainsThreadLocalStorage()) {
+            location.LinkThreadLocalStorage(
                 debug_map_symfile->GetObjectFile()->GetModule(),
                 [this, debug_map_symfile](
                     lldb::addr_t unlinked_file_addr) -> lldb::addr_t {
@@ -3470,17 +3463,14 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
   auto type_sp = std::make_shared<SymbolFileType>(
       *this, GetUID(type_die_form.Reference()));
 
-  if (use_type_size_for_value && type_sp->GetType()) {
-    DWARFExpression *location = location_list.GetMutableExpressionAtAddress();
-    location->UpdateValue(
-        const_value_form.Unsigned(),
-        type_sp->GetType()->GetByteSize(nullptr).getValueOr(0),
-        die.GetCU()->GetAddressByteSize());
-  }
+  if (use_type_size_for_value && type_sp->GetType())
+    location.UpdateValue(const_value_form.Unsigned(),
+                         type_sp->GetType()->GetByteSize(nullptr).value_or(0),
+                         die.GetCU()->GetAddressByteSize());
 
   return std::make_shared<Variable>(
       die.GetID(), name, mangled, type_sp, scope, symbol_context_scope,
-      scope_ranges, &decl, location_list, is_external, is_artificial,
+      scope_ranges, &decl, location, is_external, is_artificial,
       location_is_const_value_data, is_static_member);
 }
 
@@ -3765,8 +3755,8 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
         child.Tag() != DW_TAG_GNU_call_site_parameter)
       continue;
 
-    llvm::Optional<DWARFExpressionList> LocationInCallee;
-    llvm::Optional<DWARFExpressionList> LocationInCaller;
+    llvm::Optional<DWARFExpression> LocationInCallee;
+    llvm::Optional<DWARFExpression> LocationInCaller;
 
     DWARFAttributes attributes;
     const size_t num_attributes = child.GetAttributes(attributes);
@@ -3774,7 +3764,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
     // Parse the location at index \p attr_index within this call site parameter
     // DIE, or return None on failure.
     auto parse_simple_location =
-        [&](int attr_index) -> llvm::Optional<DWARFExpressionList> {
+        [&](int attr_index) -> llvm::Optional<DWARFExpression> {
       DWARFFormValue form_value;
       if (!attributes.ExtractFormValueAtIndex(attr_index, form_value))
         return {};
@@ -3783,9 +3773,9 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) {
       auto data = child.GetData();
       uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
       uint32_t block_length = form_value.Unsigned();
-      return DWARFExpressionList(
-          module, DataExtractor(data, block_offset, block_length),
-          child.GetCU());
+      return DWARFExpression(module,
+                             DataExtractor(data, block_offset, block_length),
+                             child.GetCU());
     };
 
     for (size_t i = 0; i < num_attributes; ++i) {
@@ -3830,7 +3820,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
       continue;
 
     llvm::Optional<DWARFDIE> call_origin;
-    llvm::Optional<DWARFExpressionList> call_target;
+    llvm::Optional<DWARFExpression> call_target;
     addr_t return_pc = LLDB_INVALID_ADDRESS;
     addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
     addr_t low_pc = LLDB_INVALID_ADDRESS;
@@ -3891,7 +3881,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
         auto data = child.GetData();
         uint32_t block_offset = form_value.BlockData() - data.GetDataStart();
         uint32_t block_length = form_value.Unsigned();
-        call_target = DWARFExpressionList(
+        call_target = DWARFExpression(
             module, DataExtractor(data, block_offset, block_length),
             child.GetCU());
       }

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index cfd18f02053b4..2403ee2624ea1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -21,7 +21,6 @@
 
 #include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Core/dwarf.h"
-#include "lldb/Expression/DWARFExpressionList.h"
 #include "lldb/Symbol/DebugMacros.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/SymbolFile.h"

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 3166c8ae65c6c..3ba0079c96e6a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -122,7 +122,7 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
   DataBufferSP buffer =
       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
   DataExtractor extractor(buffer, byte_order, address_size, byte_size);
-  DWARFExpression result(extractor);
+  DWARFExpression result(module, extractor, nullptr);
   result.SetRegisterKind(register_kind);
 
   return result;
@@ -247,7 +247,7 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
               .take_front(size);
   buffer->CopyData(bytes.data(), size);
   DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
-  DWARFExpression result(extractor);
+  DWARFExpression result(nullptr, extractor, nullptr);
   return result;
 }
 

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index d94ba6b3531a6..7dc99818c2443 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -823,10 +823,8 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
 
   m_ast->GetOrCreateVariableDecl(var_id);
 
-  ModuleSP module_sp = GetObjectFile()->GetModule();
-  DWARFExpressionList location(
-      module_sp, MakeGlobalLocationExpression(section, offset, module_sp),
-      nullptr);
+  DWARFExpression location = MakeGlobalLocationExpression(
+      section, offset, GetObjectFile()->GetModule());
 
   std::string global_name("::");
   global_name += name;
@@ -857,10 +855,8 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
   Declaration decl;
   Variable::RangeList ranges;
   ModuleSP module = GetObjectFile()->GetModule();
-  DWARFExpressionList location(module,
-                               MakeConstantLocationExpression(
-                                   constant.Type, tpi, constant.Value, module),
-                               nullptr);
+  DWARFExpression location = MakeConstantLocationExpression(
+      constant.Type, tpi, constant.Value, module);
 
   bool external = false;
   bool artificial = false;
@@ -1715,8 +1711,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
   bool static_member = false;
   VariableSP var_sp = std::make_shared<Variable>(
       toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
-      &block, *var_info.ranges, &decl,
-      DWARFExpressionList(module, *var_info.location, nullptr), external,
+      &block, *var_info.ranges, &decl, *var_info.location, external,
       artificial, location_is_constant_data, static_member);
 
   if (!is_param)

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 94023737b2a2e..96e9de704e414 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -175,7 +175,7 @@ DWARFExpression ConvertPDBLocationToDWARFExpression(
   DataBufferSP buffer =
       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
   DataExtractor extractor(buffer, byte_order, address_size, byte_size);
-  DWARFExpression result(extractor);
+  DWARFExpression result(module, extractor, nullptr);
   result.SetRegisterKind(register_kind);
 
   return result;

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index baa48532864bb..bd3d16aad6c2e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1023,11 +1023,8 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
   auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
 
   bool is_constant;
-  ModuleSP module_sp = GetObjectFile()->GetModule();
-  DWARFExpressionList location(module_sp,
-                               ConvertPDBLocationToDWARFExpression(
-                                   module_sp, pdb_data, ranges, is_constant),
-                               nullptr);
+  DWARFExpression location = ConvertPDBLocationToDWARFExpression(
+      GetObjectFile()->GetModule(), pdb_data, ranges, is_constant);
 
   var_sp = std::make_shared<Variable>(
       var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,

diff  --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index 54c562eb1bdd9..648a12524aed1 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -197,6 +197,7 @@ Function *IndirectCallEdge::GetCallee(ModuleList &images,
   Status error;
   Value callee_addr_val;
   if (!call_target.Evaluate(&exe_ctx, exe_ctx.GetRegisterContext(),
+                            /*loclist_base_load_addr=*/LLDB_INVALID_ADDRESS,
                             /*initial_value_ptr=*/nullptr,
                             /*object_address_ptr=*/nullptr, callee_addr_val,
                             &error)) {

diff  --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index 285e32d21ce23..b92c866544969 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -39,13 +39,13 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled,
                    const lldb::SymbolFileTypeSP &symfile_type_sp,
                    ValueType scope, SymbolContextScope *context,
                    const RangeList &scope_range, Declaration *decl_ptr,
-                   const DWARFExpressionList &location_list, bool external,
+                   const DWARFExpression &location, bool external,
                    bool artificial, bool location_is_constant_data,
                    bool static_member)
     : UserID(uid), m_name(name), m_mangled(ConstString(mangled)),
       m_symfile_type_sp(symfile_type_sp), m_scope(scope),
       m_owner_scope(context), m_scope_range(scope_range),
-      m_declaration(decl_ptr), m_location_list(location_list), m_external(external),
+      m_declaration(decl_ptr), m_location(location), m_external(external),
       m_artificial(artificial), m_loc_is_const_data(location_is_constant_data),
       m_static_member(static_member) {}
 
@@ -145,7 +145,7 @@ void Variable::Dump(Stream *s, bool show_context) const {
   bool show_fullpaths = false;
   m_declaration.Dump(s, show_fullpaths);
 
-  if (m_location_list.IsValid()) {
+  if (m_location.IsValid()) {
     s->PutCString(", location = ");
     ABISP abi;
     if (m_owner_scope) {
@@ -153,7 +153,7 @@ void Variable::Dump(Stream *s, bool show_context) const {
       if (module_sp)
         abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
     }
-    m_location_list.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
+    m_location.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
   }
 
   if (m_external)
@@ -212,8 +212,31 @@ void Variable::CalculateSymbolContext(SymbolContext *sc) {
 }
 
 bool Variable::LocationIsValidForFrame(StackFrame *frame) {
-  return m_location_list.ContainsAddress(
-      frame->GetFrameCodeAddress().GetFileAddress());
+  // Is the variable is described by a single location?
+  if (!m_location.IsLocationList()) {
+    // Yes it is, the location is valid.
+    return true;
+  }
+
+  if (frame) {
+    Function *function =
+        frame->GetSymbolContext(eSymbolContextFunction).function;
+    if (function) {
+      TargetSP target_sp(frame->CalculateTarget());
+
+      addr_t loclist_base_load_addr =
+          function->GetAddressRange().GetBaseAddress().GetLoadAddress(
+              target_sp.get());
+      if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
+        return false;
+      // It is a location list. We just need to tell if the location list
+      // contains the current address when converted to a load address
+      return m_location.LocationListContainsAddress(
+          loclist_base_load_addr,
+          frame->GetFrameCodeAddress().GetLoadAddress(target_sp.get()));
+    }
+  }
+  return false;
 }
 
 bool Variable::LocationIsValidForAddress(const Address &address) {
@@ -221,7 +244,7 @@ bool Variable::LocationIsValidForAddress(const Address &address) {
   // function.
   if (address.IsSectionOffset()) {
     // We need to check if the address is valid for both scope range and value
-    // range.
+    // range. 
     // Empty scope range means block range.
     bool valid_in_scope_range =
         GetScopeRange().IsEmpty() || GetScopeRange().FindEntryThatContains(
@@ -231,10 +254,22 @@ bool Variable::LocationIsValidForAddress(const Address &address) {
     SymbolContext sc;
     CalculateSymbolContext(&sc);
     if (sc.module_sp == address.GetModule()) {
-      // Empty location list means we have missing value range info, but it's in
-      // the scope.
-      return m_location_list.GetSize() == 0 ||
-             m_location_list.ContainsAddress(address.GetFileAddress());
+      // Is the variable is described by a single location?
+      if (!m_location.IsLocationList()) {
+        // Yes it is, the location is valid.
+        return true;
+      }
+
+      if (sc.function) {
+        addr_t loclist_base_file_addr =
+            sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
+        if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
+          return false;
+        // It is a location list. We just need to tell if the location list
+        // contains the current address when converted to a load address
+        return m_location.LocationListContainsAddress(loclist_base_file_addr,
+                                                      address.GetFileAddress());
+      }
     }
   }
   return false;
@@ -419,8 +454,16 @@ bool Variable::DumpLocations(Stream *s, const Address &address) {
   }
 
   const addr_t file_addr = address.GetFileAddress();
-  return m_location_list.DumpLocations(s, eDescriptionLevelBrief, file_addr,
-                                       abi.get());
+  if (sc.function) {
+    addr_t loclist_base_file_addr =
+        sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
+    if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
+      return false;
+    return m_location.DumpLocations(s, eDescriptionLevelBrief,
+                                    loclist_base_file_addr, file_addr,
+                                    abi.get());
+  }
+  return false;
 }
 
 static void PrivateAutoComplete(

diff  --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index bca7eec5e939e..e98aed7e15552 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -11,7 +11,7 @@
 #include "lldb/Core/AddressRange.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/DWARFExpressionList.h"
+#include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Symbol/ArmUnwindInfo.h"
 #include "lldb/Symbol/CallFrameInfo.h"
 #include "lldb/Symbol/DWARFCallFrameInfo.h"
@@ -381,7 +381,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() {
   // symbol/function information - just stick in some reasonable defaults and
   // hope we can unwind past this frame.  If we're above a trap handler,
   // we may be at a bogus address because we jumped through a bogus function
-  // pointer and trapped, so don't force the arch default unwind plan in that
+  // pointer and trapped, so don't force the arch default unwind plan in that 
   // case.
   ModuleSP pc_module_sp(m_current_pc.GetModule());
   if ((!m_current_pc.IsValid() || !pc_module_sp) &&
@@ -1286,7 +1286,7 @@ RegisterContextUnwind::SavedLocationForRegister(
     // arch default unwind plan is used as the Fast Unwind Plan, we
     // need to recognize this & switch over to the Full Unwind Plan
     // to see what unwind rule that (more knoweldgeable, probably)
-    // UnwindPlan has.  If the full UnwindPlan says the register
+    // UnwindPlan has.  If the full UnwindPlan says the register 
     // location is Undefined, then it really is.
     if (active_row->GetRegisterInfo(regnum.GetAsKind(unwindplan_registerkind),
                                     unwindplan_regloc) &&
@@ -1335,13 +1335,13 @@ RegisterContextUnwind::SavedLocationForRegister(
           m_full_unwind_plan_sp->GetReturnAddressRegister() !=
               LLDB_INVALID_REGNUM) {
         // If this is a trap handler frame, we should have access to
-        // the complete register context when the interrupt/async
+        // the complete register context when the interrupt/async 
         // signal was received, we should fetch the actual saved $pc
         // value instead of the Return Address register.
         // If $pc is not available, fall back to the RA reg.
         UnwindPlan::Row::RegisterLocation scratch;
         if (m_frame_type == eTrapHandlerFrame &&
-            active_row->GetRegisterInfo
+            active_row->GetRegisterInfo 
               (pc_regnum.GetAsKind (unwindplan_registerkind), scratch)) {
           UnwindLogMsg("Providing pc register instead of rewriting to "
                        "RA reg because this is a trap handler and there is "
@@ -1642,14 +1642,14 @@ RegisterContextUnwind::SavedLocationForRegister(
                             process->GetByteOrder(),
                             process->GetAddressByteSize());
     ModuleSP opcode_ctx;
-    DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
-    dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
-        unwindplan_registerkind);
+    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+    dwarfexpr.SetRegisterKind(unwindplan_registerkind);
     Value cfa_val = Scalar(m_cfa);
     cfa_val.SetValueType(Value::ValueType::LoadAddress);
     Value result;
     Status error;
-    if (dwarfexpr.Evaluate(&exe_ctx, this, &cfa_val, nullptr, result, &error)) {
+    if (dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr, result,
+                           &error)) {
       addr_t val;
       val = result.GetScalar().ULongLong();
       if (unwindplan_regloc.IsDWARFExpression()) {
@@ -2006,12 +2006,11 @@ bool RegisterContextUnwind::ReadFrameAddress(
                             process->GetByteOrder(),
                             process->GetAddressByteSize());
     ModuleSP opcode_ctx;
-    DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
-    dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
-        row_register_kind);
+    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+    dwarfexpr.SetRegisterKind(row_register_kind);
     Value result;
     Status error;
-    if (dwarfexpr.Evaluate(&exe_ctx, this, nullptr, nullptr, result,
+    if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
                            &error)) {
       address = result.GetScalar().ULongLong();
       if (ABISP abi_sp = m_thread.GetProcess()->GetABI())

diff  --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 28c8dfde72a8d..1e3dbc73a04ed 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1086,9 +1086,15 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
       m_flags.Set(GOT_FRAME_BASE);
       ExecutionContext exe_ctx(shared_from_this());
       Value expr_value;
+      addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
+      if (m_sc.function->GetFrameBaseExpression().IsLocationList())
+        loclist_base_addr =
+            m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
+                exe_ctx.GetTargetPtr());
+
       if (!m_sc.function->GetFrameBaseExpression().Evaluate(
-              &exe_ctx, nullptr, nullptr, nullptr, expr_value,
-              &m_frame_base_error)) {
+              &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr,
+              expr_value, &m_frame_base_error)) {
         // We should really have an error if evaluate returns, but in case we
         // don't, lets set the error to something at least.
         if (m_frame_base_error.Success())
@@ -1110,7 +1116,7 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) {
   return m_frame_base_error.Success();
 }
 
-DWARFExpressionList *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
+DWARFExpression *StackFrame::GetFrameBaseExpression(Status *error_ptr) {
   if (!m_sc.function) {
     if (error_ptr) {
       error_ptr->SetErrorString("No function in symbol context.");
@@ -1194,7 +1200,7 @@ lldb::LanguageType StackFrame::GuessLanguage() {
   LanguageType lang_type = GetLanguage();
 
   if (lang_type == eLanguageTypeUnknown) {
-    SymbolContext sc = GetSymbolContext(eSymbolContextFunction
+    SymbolContext sc = GetSymbolContext(eSymbolContextFunction 
                                         | eSymbolContextSymbol);
     if (sc.function) {
       lang_type = sc.function->GetMangled().GuessLanguage();
@@ -1411,7 +1417,7 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame,
 
   Status error;
   ValueObjectSP pointee = base->Dereference(error);
-
+    
   if (!pointee) {
     return ValueObjectSP();
   }
@@ -1499,7 +1505,7 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
                    Instruction::Operand::BuildRegister(reg));
 
   for (VariableSP var_sp : variables) {
-    if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
+    if (var_sp->LocationExpression().MatchesOperand(frame, op))
       return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
   }
 

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
index f8e8bfba970f0..2daf816d300c8 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
@@ -40,11 +40,11 @@
 # CHECK-NEXT:  [0x0000000000000000, 0x0000000000000001): DW_OP_reg5 RDI
 # CHECK-NEXT:  [0x0000000000000001, 0x0000000000000006): DW_OP_reg0 RAX
 # CHECK:     Variable{{.*}}, name = "x1", {{.*}}, scope = parameter
-# CHECK:     Variable{{.*}}, name = "x2", {{.*}}, scope = parameter
+# CHECK:     Variable{{.*}}, name = "x2", {{.*}}, scope = parameter, location = 0x00000000: error: unexpected end of data
 # CHECK:     Variable{{.*}}, name = "x3", {{.*}}, scope = parameter, location =
 # CHECK-NEXT:  [0x0000000000000002, 0x0000000000000003): DW_OP_reg1 RDX
-# LOCLISTS:  Variable{{.*}}, name = "x4", {{.*}}, scope = parameter
-# LOCLISTS-EMPTY:
+# LOCLISTS:  Variable{{.*}}, name = "x4", {{.*}}, scope = parameter, location =
+# LOCLISTS-NEXT: DW_LLE_startx_length   (0x000000000000dead, 0x0000000000000001): DW_OP_reg2 RCX
 
 .ifdef LOC
 .macro OFFSET_PAIR lo hi

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
index c8eead3d28d29..a921641bcec54 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
@@ -19,29 +19,29 @@
 # SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x0
 # SYMBOLS-NEXT:   Function{{.*}}, demangled = F0
 # SYMBOLS-NEXT:   Block{{.*}}, ranges = [0x00000000-0x00000001)
-# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT:       [0x0000000000000000, 0x0000000000000001): DW_OP_reg0 RAX
+# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location = 
+# SYMBOLS-NEXT:       DW_LLE_startx_length   (0x0000000000000001, 0x0000000000000001): DW_OP_reg0 RAX
 # SYMBOLS-EMPTY:
 # SYMBOLS-NEXT: CompileUnit{0x00000001}, language = "<not loaded>", file = '1.c'
 # SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x2
 # SYMBOLS-NEXT:   Function{{.*}}, demangled = F1
 # SYMBOLS-NEXT:   Block{{.*}}, ranges = [0x00000001-0x00000002)
-# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT:       [0x0000000000000001, 0x0000000000000002): DW_OP_reg1 RDX
+# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location = 
+# SYMBOLS-NEXT:       DW_LLE_startx_length   (0x0000000000000003, 0x0000000000000001): DW_OP_reg1 RDX
 # SYMBOLS-EMPTY:
 # SYMBOLS-NEXT: CompileUnit{0x00000002}, language = "<not loaded>", file = '2.c'
 # SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x4
 # SYMBOLS-NEXT:   Function{{.*}}, demangled = F2
 # SYMBOLS-NEXT:   Block{{.*}}, ranges = [0x00000002-0x00000003)
-# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT:       [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX
+# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location = 
+# SYMBOLS-NEXT:       DW_LLE_startx_length   (0x0000000000000005, 0x0000000000000001): DW_OP_reg2 RCX
 # SYMBOLS-EMPTY:
 # SYMBOLS-NEXT: CompileUnit{0x00000003}, language = "<not loaded>", file = '3.c'
 # SYMBOLS-NEXT:   Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x6
 # SYMBOLS-NEXT:   Function{{.*}}, demangled = F3
 # SYMBOLS-NEXT:   Block{{.*}}, ranges = [0x00000003-0x00000004)
-# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location =
-# SYMBOLS-NEXT:       [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX
+# SYMBOLS-NEXT:     Variable{{.*}}, name = "x", {{.*}}, location = 
+# SYMBOLS-NEXT:       DW_LLE_startx_length   (0x0000000000000007, 0x0000000000000001): DW_OP_reg3 RBX
 # SYMBOLS-EMPTY:
 # SYMBOLS-NEXT: CompileUnit{0x00000004}, language = "<not loaded>", file = ''
 # SYMBOLS-EMPTY:
@@ -116,7 +116,7 @@ F\I:
 .Lloc\I:
         .byte   3                       # DW_LLE_startx_length
         .uleb128 \I*2+1
-        .long   1
+        .long   1                
         .short 1                      # Expression size
         .byte   80+\I                   # super-register DW_OP_reg0+\I
         .byte   0                       # DW_LLE_end_of_list

diff  --git a/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
index 62d7335384216..f58874f794eec 100644
--- a/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Expression/BUILD.gn
@@ -23,7 +23,6 @@ static_library("Expression") {
   include_dirs = [ ".." ]
   sources = [
     "DWARFExpression.cpp",
-    "DWARFExpressionList.cpp",
     "DiagnosticManager.cpp",
     "Expression.cpp",
     "ExpressionVariable.cpp",


        


More information about the lldb-commits mailing list