[Lldb-commits] [lldb] 71d778f - [LLDB][NativePDB] Switch to use DWARFLocationList.

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Wed Aug 17 13:37:21 PDT 2022


Author: Zequan Wu
Date: 2022-08-17T13:37:13-07:00
New Revision: 71d778f33e8615f525f118db351c6541b40199ab

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

LOG: [LLDB][NativePDB] Switch to use DWARFLocationList.

Before, NativePDB uses scoped range as a workaround for value range, that causes
problems (e.g. a variable's value can only have one range, but usually a
variable's value is located at different address ranges, each at different
locations, in optimized build).
This patch let NativePDB switch to DWARFLocationList so a variable's value can
be described at multiple non-overlapped address ranges and each range maps to a
location.
Because overlapping ranges exists, here's peference when choosing ranges:
1. Always prefer whole value locations. Suppose a variable size is 8 bytes, one record is that for range [1, 5) first 4 bytes is at ecx, and another record is that for range [2, 8) the 8 bytes value is at rdx. This results: [1, 2) has first 4 bytes at ecx, [2, 8) has the whole value at rdx.
2. Always prefer the locations parsed later. Suppose first record is that for range [1, 5) value is at ecx, second record is that for range [2, 6) value is at eax. This results: [1, 2) -> ecx, [2, 6) -> eax.

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

Added: 
    

Modified: 
    lldb/include/lldb/Utility/RangeMap.h
    lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
    lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
    lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
    lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
    lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables-registers.lldbinit
    lldb/test/Shell/SymbolFile/NativePDB/inline_sites.test
    lldb/test/Shell/SymbolFile/NativePDB/local-variables-registers.s

Removed: 
    lldb/test/Shell/SymbolFile/NativePDB/subfield_register_simple_type.s


################################################################################
diff  --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index 257b177c70927..54c86648fc51c 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -49,6 +49,11 @@ template <typename B, typename S> struct Range {
 
   void Slide(BaseType slide) { base += slide; }
 
+  void ShrinkFront(S s) {
+    base += s;
+    size -= std::min(s, size);
+  }
+
   bool Union(const Range &rhs) {
     if (DoesAdjoinOrIntersect(rhs)) {
       auto new_end = std::max<BaseType>(GetRangeEnd(), rhs.GetRangeEnd());
@@ -445,6 +450,13 @@ class RangeDataVector {
 
   void Append(const Entry &entry) { m_entries.emplace_back(entry); }
 
+  bool Erase(uint32_t start, uint32_t end) {
+    if (start >= end || end > m_entries.size())
+      return false;
+    m_entries.erase(begin() + start, begin() + end);
+    return true;
+  }
+
   void Sort() {
     if (m_entries.size() > 1)
       std::stable_sort(m_entries.begin(), m_entries.end(),
@@ -621,6 +633,17 @@ class RangeDataVector {
     return nullptr;
   }
 
+  uint32_t FindEntryIndexThatContainsOrFollows(B addr) const {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+    assert(IsSorted());
+#endif
+    const AugmentedEntry *entry = static_cast<const AugmentedEntry *>(
+        FindEntryThatContainsOrFollows(addr));
+    if (entry)
+      return std::distance(m_entries.begin(), entry);
+    return UINT32_MAX;
+  }
+
   Entry *Back() { return (m_entries.empty() ? nullptr : &m_entries.back()); }
 
   const Entry *Back() const {

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
index 3d8030916c84f..d98e3c4c761a3 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp
@@ -649,3 +649,100 @@ uint32_t lldb_private::npdb::GetLLDBRegisterNumber(
     return LLDB_INVALID_REGNUM;
   }
 }
+
+uint32_t
+lldb_private::npdb::GetRegisterSize(llvm::codeview::RegisterId register_id) {
+  switch(register_id) {
+    case llvm::codeview::RegisterId::AL:
+    case llvm::codeview::RegisterId::BL:
+    case llvm::codeview::RegisterId::CL:
+    case llvm::codeview::RegisterId::DL:
+    case llvm::codeview::RegisterId::AH:
+    case llvm::codeview::RegisterId::BH:
+    case llvm::codeview::RegisterId::CH:
+    case llvm::codeview::RegisterId::DH:
+    case llvm::codeview::RegisterId::SIL:
+    case llvm::codeview::RegisterId::DIL:
+    case llvm::codeview::RegisterId::BPL:
+    case llvm::codeview::RegisterId::SPL:
+    case llvm::codeview::RegisterId::R8B:
+    case llvm::codeview::RegisterId::R9B:
+    case llvm::codeview::RegisterId::R10B:
+    case llvm::codeview::RegisterId::R11B:
+    case llvm::codeview::RegisterId::R12B:
+    case llvm::codeview::RegisterId::R13B:
+    case llvm::codeview::RegisterId::R14B:
+    case llvm::codeview::RegisterId::R15B:
+      return 1;
+    case llvm::codeview::RegisterId::AX:
+    case llvm::codeview::RegisterId::BX:
+    case llvm::codeview::RegisterId::CX:
+    case llvm::codeview::RegisterId::DX:
+    case llvm::codeview::RegisterId::SP:
+    case llvm::codeview::RegisterId::BP:
+    case llvm::codeview::RegisterId::SI:
+    case llvm::codeview::RegisterId::DI:
+    case llvm::codeview::RegisterId::R8W:
+    case llvm::codeview::RegisterId::R9W:
+    case llvm::codeview::RegisterId::R10W:
+    case llvm::codeview::RegisterId::R11W:
+    case llvm::codeview::RegisterId::R12W:
+    case llvm::codeview::RegisterId::R13W:
+    case llvm::codeview::RegisterId::R14W:
+    case llvm::codeview::RegisterId::R15W:
+      return 2;
+    case llvm::codeview::RegisterId::EAX:
+    case llvm::codeview::RegisterId::EBX:
+    case llvm::codeview::RegisterId::ECX:
+    case llvm::codeview::RegisterId::EDX:
+    case llvm::codeview::RegisterId::ESP:
+    case llvm::codeview::RegisterId::EBP:
+    case llvm::codeview::RegisterId::ESI:
+    case llvm::codeview::RegisterId::EDI:
+    case llvm::codeview::RegisterId::R8D:
+    case llvm::codeview::RegisterId::R9D:
+    case llvm::codeview::RegisterId::R10D:
+    case llvm::codeview::RegisterId::R11D:
+    case llvm::codeview::RegisterId::R12D:
+    case llvm::codeview::RegisterId::R13D:
+    case llvm::codeview::RegisterId::R14D:
+    case llvm::codeview::RegisterId::R15D:
+      return 4;
+    case llvm::codeview::RegisterId::RAX:
+    case llvm::codeview::RegisterId::RBX:
+    case llvm::codeview::RegisterId::RCX:
+    case llvm::codeview::RegisterId::RDX:
+    case llvm::codeview::RegisterId::RSI:
+    case llvm::codeview::RegisterId::RDI:
+    case llvm::codeview::RegisterId::RBP:
+    case llvm::codeview::RegisterId::RSP:
+    case llvm::codeview::RegisterId::R8:
+    case llvm::codeview::RegisterId::R9:
+    case llvm::codeview::RegisterId::R10:
+    case llvm::codeview::RegisterId::R11:
+    case llvm::codeview::RegisterId::R12:
+    case llvm::codeview::RegisterId::R13:
+    case llvm::codeview::RegisterId::R14:
+    case llvm::codeview::RegisterId::R15:
+      return 8;
+    case llvm::codeview::RegisterId::XMM0:
+    case llvm::codeview::RegisterId::XMM1:
+    case llvm::codeview::RegisterId::XMM2:
+    case llvm::codeview::RegisterId::XMM3:
+    case llvm::codeview::RegisterId::XMM4:
+    case llvm::codeview::RegisterId::XMM5:
+    case llvm::codeview::RegisterId::XMM6:
+    case llvm::codeview::RegisterId::XMM7:
+    case llvm::codeview::RegisterId::XMM8:
+    case llvm::codeview::RegisterId::XMM9:
+    case llvm::codeview::RegisterId::XMM10:
+    case llvm::codeview::RegisterId::XMM11:
+    case llvm::codeview::RegisterId::XMM12:
+    case llvm::codeview::RegisterId::XMM13:
+    case llvm::codeview::RegisterId::XMM14:
+    case llvm::codeview::RegisterId::XMM15:
+      return 16;
+    default:
+      return 0;
+  }
+}
\ No newline at end of file

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
index 02c7495565b86..1ed4fde9df320 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h
@@ -17,6 +17,7 @@ namespace npdb {
 
 uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
                                llvm::codeview::RegisterId register_id);
+uint32_t GetRegisterSize(llvm::codeview::RegisterId register_id);
 
 } // namespace npdb
 } // namespace lldb_private

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
index 3166c8ae65c6c..b1436575d881c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -128,33 +128,38 @@ static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
   return result;
 }
 
+static bool MakeRegisterBasedLocationExpressionInternal(
+    Stream &stream, llvm::codeview::RegisterId reg, RegisterKind register_kind,
+    llvm::Optional<int32_t> relative_offset, lldb::ModuleSP module) {
+  uint32_t reg_num = GetRegisterNumber(module->GetArchitecture().GetMachine(),
+                                       reg, register_kind);
+  if (reg_num == LLDB_INVALID_REGNUM)
+    return false;
+
+  if (reg_num > 31) {
+    llvm::dwarf::LocationAtom base =
+        relative_offset ? llvm::dwarf::DW_OP_bregx : llvm::dwarf::DW_OP_regx;
+    stream.PutHex8(base);
+    stream.PutULEB128(reg_num);
+  } else {
+    llvm::dwarf::LocationAtom base =
+        relative_offset ? llvm::dwarf::DW_OP_breg0 : llvm::dwarf::DW_OP_reg0;
+    stream.PutHex8(base + reg_num);
+  }
+
+  if (relative_offset)
+    stream.PutSLEB128(*relative_offset);
+
+  return true;
+}
+
 static DWARFExpression MakeRegisterBasedLocationExpressionInternal(
     llvm::codeview::RegisterId reg, llvm::Optional<int32_t> relative_offset,
     lldb::ModuleSP module) {
   return MakeLocationExpressionInternal(
       module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
-        uint32_t reg_num = GetRegisterNumber(
-            module->GetArchitecture().GetMachine(), reg, register_kind);
-        if (reg_num == LLDB_INVALID_REGNUM)
-          return false;
-
-        if (reg_num > 31) {
-          llvm::dwarf::LocationAtom base = relative_offset
-                                               ? llvm::dwarf::DW_OP_bregx
-                                               : llvm::dwarf::DW_OP_regx;
-          stream.PutHex8(base);
-          stream.PutULEB128(reg_num);
-        } else {
-          llvm::dwarf::LocationAtom base = relative_offset
-                                               ? llvm::dwarf::DW_OP_breg0
-                                               : llvm::dwarf::DW_OP_reg0;
-          stream.PutHex8(base + reg_num);
-        }
-
-        if (relative_offset)
-          stream.PutSLEB128(*relative_offset);
-
-        return true;
+        return MakeRegisterBasedLocationExpressionInternal(
+            stream, reg, register_kind, relative_offset, module);
       });
 }
 
@@ -251,28 +256,43 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
   return result;
 }
 
-DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpressionForClass(
-    std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info,
+DWARFExpression
+lldb_private::npdb::MakeEnregisteredLocationExpressionForComposite(
+    const std::map<uint64_t, MemberValLocation> &offset_to_location,
+    std::map<uint64_t, size_t> &offset_to_size, size_t total_size,
     lldb::ModuleSP module) {
   return MakeLocationExpressionInternal(
       module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
-        for (auto pair : members_info) {
-          std::pair<RegisterId, uint32_t> member_info = pair.second;
-          if (member_info.first != llvm::codeview::RegisterId::NONE) {
-            uint32_t reg_num =
-                GetRegisterNumber(module->GetArchitecture().GetMachine(),
-                                  member_info.first, register_kind);
-            if (reg_num == LLDB_INVALID_REGNUM)
-              return false;
-            if (reg_num > 31) {
-              stream.PutHex8(llvm::dwarf::DW_OP_regx);
-              stream.PutULEB128(reg_num);
-            } else {
-              stream.PutHex8(llvm::dwarf::DW_OP_reg0 + reg_num);
-            }
+        size_t cur_offset = 0;
+        bool is_simple_type = offset_to_size.empty();
+        // Iterate through offset_to_location because offset_to_size might be
+        // empty if the variable is a simple type.
+        for (const auto &offset_loc : offset_to_location) {
+          if (cur_offset < offset_loc.first) {
+            stream.PutHex8(llvm::dwarf::DW_OP_piece);
+            stream.PutULEB128(offset_loc.first - cur_offset);
+            cur_offset = offset_loc.first;
           }
+          MemberValLocation loc = offset_loc.second;
+          llvm::Optional<int32_t> offset =
+              loc.is_at_reg ? llvm::None
+                            : llvm::Optional<int32_t>(loc.reg_offset);
+          if (!MakeRegisterBasedLocationExpressionInternal(
+                  stream, (RegisterId)loc.reg_id, register_kind, offset,
+                  module))
+            return false;
+          if (!is_simple_type) {
+            stream.PutHex8(llvm::dwarf::DW_OP_piece);
+            stream.PutULEB128(offset_to_size[offset_loc.first]);
+            cur_offset = offset_loc.first + offset_to_size[offset_loc.first];
+          }
+        }
+        // For simple type, it specifies the byte size of the value described by
+        // the previous dwarf expr. For udt, it's the remaining byte size at end
+        // of a struct.
+        if (total_size > cur_offset) {
           stream.PutHex8(llvm::dwarf::DW_OP_piece);
-          stream.PutULEB128(member_info.second);
+          stream.PutULEB128(total_size - cur_offset);
         }
         return true;
       });

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
index 1ed6c55fea74b..2f12d8bf0dd78 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
@@ -26,6 +26,12 @@ class TpiStream;
 } // namespace llvm
 namespace lldb_private {
 namespace npdb {
+struct MemberValLocation {
+  uint16_t reg_id;
+  uint16_t reg_offset;
+  bool is_at_reg = true;
+};
+
 DWARFExpression
 MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg,
                                    lldb::ModuleSP module);
@@ -41,9 +47,9 @@ DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset,
 DWARFExpression MakeConstantLocationExpression(
     llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi,
     const llvm::APSInt &constant, lldb::ModuleSP module);
-DWARFExpression MakeEnregisteredLocationExpressionForClass(
-    std::map<uint64_t, std::pair<llvm::codeview::RegisterId, uint32_t>>
-        &members_info,
+DWARFExpression MakeEnregisteredLocationExpressionForComposite(
+    const std::map<uint64_t, MemberValLocation> &offset_to_location,
+    std::map<uint64_t, size_t> &offset_to_size, size_t total_size,
     lldb::ModuleSP module);
 } // namespace npdb
 } // namespace lldb_private

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
index 7d730ecdd1f33..387182cc46a97 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -19,6 +19,7 @@
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 
 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
 #include "lldb/Symbol/Block.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/LLDBLog.h"
@@ -29,6 +30,8 @@ using namespace lldb_private::npdb;
 using namespace llvm::codeview;
 using namespace llvm::pdb;
 
+// The returned range list is guaranteed to be sorted and no overlaps between
+// adjacent ranges because fields in LocalVariableAddrGap are unsigned integers.
 static Variable::RangeList
 MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
               llvm::ArrayRef<LocalVariableAddrGap> gaps) {
@@ -52,21 +55,144 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
 }
 
 namespace {
-struct FindMembersSize : public TypeVisitorCallbacks {
-  FindMembersSize(
-      std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info,
-      TpiStream &tpi)
-      : members_info(members_info), tpi(tpi) {}
-  std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info;
-  TpiStream &tpi;
-  llvm::Error visitKnownMember(CVMemberRecord &cvr,
-                               DataMemberRecord &member) override {
-    members_info.insert(
-        {member.getFieldOffset(),
-         {llvm::codeview::RegisterId::NONE, GetSizeOfType(member.Type, tpi)}});
-    return llvm::Error::success();
+struct MemberLocations {
+  std::map<uint64_t, MemberValLocation> offset_to_location;
+  DWARFExpression expr;
+  bool is_dwarf = false;
+
+  MemberLocations() = default;
+  MemberLocations(const DWARFExpression &expr) : expr(expr), is_dwarf(true) {}
+  MemberLocations(uint64_t offset, const MemberValLocation &member_loc) {
+    insert(offset, member_loc);
   }
+
+  void insert(uint64_t offset, const MemberValLocation &member_loc) {
+    offset_to_location[offset] = member_loc;
+  }
+
+  struct Comparator {
+  public:
+    bool operator()(const MemberLocations &, const MemberLocations &) const {
+      return false;
+    }
+  };
 };
+
+// A range map with address ranges to a map of pair of offset and locaitons.
+typedef RangeDataVector<lldb::addr_t, lldb::addr_t, MemberLocations, 0,
+                        MemberLocations::Comparator>
+    RangeMap;
+
+void AddMemberLocationRanges(RangeMap &location_map, uint64_t offset,
+                             MemberValLocation member_loc,
+                             const Variable::RangeList &ranges) {
+  RangeMap new_location_map;
+  auto add_overlap_region = [&](lldb::addr_t base, lldb::addr_t end,
+                                RangeMap::Entry *entry) {
+    RangeMap::Entry overlap_region = {base, end - base, entry->data};
+    overlap_region.data.insert(offset, member_loc);
+    new_location_map.Append(overlap_region);
+  };
+
+  for (const auto &range : ranges) {
+    lldb::addr_t base = range.GetRangeBase();
+    lldb::addr_t end = range.GetRangeEnd();
+    uint32_t base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
+    while (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
+      if (base >= end || entry->base >= end)
+        break;
+      if (entry->data.is_dwarf)
+        base = entry->GetRangeEnd();
+      else {
+        lldb::addr_t entry_end = entry->GetRangeEnd();
+        if (base > entry->base) {
+          if (end < entry_end)
+            new_location_map.Append({end, entry_end - end, entry->data});
+          add_overlap_region(base, end < entry_end ? end : entry_end, entry);
+          entry->SetRangeEnd(base);
+        } else if (base < entry->base) {
+          new_location_map.Append(
+              {base, entry->base - base, {offset, member_loc}});
+          if (entry_end == end)
+            entry->data.insert(offset, member_loc);
+          else {
+            add_overlap_region(entry->base, end, entry);
+            entry->ShrinkFront(end - entry->base);
+          }
+        } else {
+          if (end < entry_end) {
+            new_location_map.Append({end, entry_end, entry->data});
+            entry->SetRangeEnd(end);
+          }
+          entry->data.insert(offset, member_loc);
+        }
+        base = entry_end;
+      }
+      ++base_idx;
+    }
+    if (base >= end)
+      continue;
+    new_location_map.Append({base, end - base, {offset, member_loc}});
+  }
+  for (const auto &entry : new_location_map)
+    location_map.Append(entry);
+  if (!new_location_map.IsEmpty())
+    location_map.Sort();
+}
+
+void AddDwarfRange(RangeMap &location_map, const DWARFExpression &expr,
+                   const Variable::RangeList &ranges) {
+  if (!expr.IsValid())
+    return;
+  RangeMap new_location_map;
+  for (const auto &range : ranges) {
+    lldb::addr_t base = range.GetRangeBase();
+    lldb::addr_t end = range.GetRangeEnd();
+    uint32_t base_idx = location_map.FindEntryIndexThatContains(base);
+    uint32_t end_idx = location_map.FindEntryIndexThatContains(end - 1);
+    // range is within an entry.
+    if (base_idx == end_idx && base_idx != UINT32_MAX) {
+      auto *entry = location_map.GetMutableEntryAtIndex(base_idx);
+      if (base > entry->base) {
+        new_location_map.Append({entry->base, base - entry->base, entry->data});
+        entry->ShrinkFront(base - entry->base);
+      }
+      if (end == entry->GetRangeEnd())
+        entry->data = expr;
+      else {
+        entry->ShrinkFront(end - base);
+        new_location_map.Append({base, end - base, expr});
+      }
+      continue;
+    }
+    base_idx = location_map.FindEntryIndexThatContainsOrFollows(base);
+    if (auto *entry = location_map.GetMutableEntryAtIndex(base_idx)) {
+      if (entry->Contains(base) && entry->base != base) {
+        entry->SetRangeEnd(base);
+        ++base_idx;
+      }
+    }
+    end_idx = location_map.FindEntryIndexThatContainsOrFollows(end - 1);
+    if (auto *entry = location_map.GetMutableEntryAtIndex(end_idx)) {
+      if (entry->Contains(end - 1)) {
+        if (entry->GetRangeEnd() == end)
+          ++end_idx;
+        else
+          entry->ShrinkFront(end - entry->base);
+      }
+    }
+
+    if (end_idx == UINT32_MAX)
+      end_idx = location_map.GetSize();
+    // Erase existing ranges covered by new range.
+    location_map.Erase(base_idx, end_idx);
+    new_location_map.Append({base, end - base, expr});
+  }
+
+  for (const auto &entry : new_location_map)
+    location_map.Append(entry);
+  location_map.Sort();
+}
 } // namespace
 
 CVTagRecord CVTagRecord::create(CVType type) {
@@ -612,207 +738,176 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
   if (sym.kind() == S_REGREL32) {
     RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
     cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
-    result.location =
-        MakeRegRelLocationExpression(reg.Register, reg.Offset, module);
-    result.ranges.emplace();
+    result.location = DWARFExpressionList(
+        module, MakeRegRelLocationExpression(reg.Register, reg.Offset, module),
+        nullptr);
     return result;
   }
 
   if (sym.kind() == S_REGISTER) {
     RegisterSym reg(SymbolRecordKind::RegisterSym);
     cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
-    result.location = MakeEnregisteredLocationExpression(reg.Register, module);
-    result.ranges.emplace();
+    result.location = DWARFExpressionList(
+        module, MakeEnregisteredLocationExpression(reg.Register, module),
+        nullptr);
     return result;
   }
 
   if (sym.kind() == S_LOCAL) {
     LocalSym local(SymbolRecordKind::LocalSym);
-    cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
+    if (llvm::Error error =
+            SymbolDeserializer::deserializeAs<LocalSym>(sym, local)) {
+      llvm::consumeError(std::move(error));
+      return result;
+    }
 
     PdbCompilandSymId loc_specifier_id(var_id.modi,
                                        var_id.offset + sym.RecordData.size());
-    CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
-    switch(loc_specifier_cvs.kind()) {
-    case S_DEFRANGE_FRAMEPOINTER_REL: {
-      DefRangeFramePointerRelSym loc(
-          SymbolRecordKind::DefRangeFramePointerRelSym);
-      cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
-          loc_specifier_cvs, loc));
-
-      Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
-
-      PdbCompilandSymId func_scope_id =
-          PdbSymUid(func_block.GetID()).asCompilandSym();
-      CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
-      lldbassert(func_block_cvs.kind() == S_GPROC32 ||
-                 func_block_cvs.kind() == S_LPROC32);
-
-      PdbCompilandSymId frame_proc_id(
-          func_scope_id.modi, func_scope_id.offset + func_block_cvs.length());
-
-      RegisterId base_reg =
-          GetBaseFrameRegister(index, frame_proc_id, result.is_param);
-      if (base_reg == RegisterId::NONE)
-        break;
-      if (base_reg == RegisterId::VFRAME) {
-        llvm::StringRef program;
-        if (GetFrameDataProgram(index, ranges, program)) {
-          result.location =
-              MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module);
-          result.ranges = std::move(ranges);
-        } else {
-          // invalid variable
+    CVSymbol loc_specifier_cvs;
+    // Only used for S_DEFRANGE_FRAMEPOINTER_REL.
+    RegisterId base_reg = RegisterId::NONE;
+    size_t type_size = GetSizeOfType(result.type, index.tpi());
+    // A map from offset of a field in parent to size of the field.
+    std::map<uint64_t, size_t> offset_to_size;
+
+    // When overlaps happens, always prefer the one that doesn't split the value
+    // into multiple locations and the location parsed first is perfered.
+    RangeMap location_map;
+
+    // Iterate through all location records after S_LOCAL. They describe the
+    // value of this variable at 
diff erent locations.
+    bool finished = false;
+    while (!finished) {
+      loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
+      switch (loc_specifier_cvs.kind()) {
+      case S_DEFRANGE_FRAMEPOINTER_REL: {
+        DefRangeFramePointerRelSym loc(
+            SymbolRecordKind::DefRangeFramePointerRelSym);
+        if (llvm::Error error =
+                SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
+                    loc_specifier_cvs, loc)) {
+          llvm::consumeError(std::move(error));
+          return result;
+        }
+        Variable::RangeList raw_ranges =
+            MakeRangeList(index, loc.Range, loc.Gaps);
+        if (base_reg == RegisterId::NONE) {
+          PdbCompilandSymId func_scope_id =
+              PdbSymUid(func_block.GetID()).asCompilandSym();
+          CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id);
+          lldbassert(func_block_cvs.kind() == S_GPROC32 ||
+                     func_block_cvs.kind() == S_LPROC32);
+          PdbCompilandSymId frame_proc_id(func_scope_id.modi,
+                                          func_scope_id.offset +
+                                              func_block_cvs.length());
+          base_reg =
+              GetBaseFrameRegister(index, frame_proc_id, result.is_param);
+          if (base_reg == RegisterId::NONE)
+            break;
         }
-      } else {
-        result.location =
-            MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
-        result.ranges = std::move(ranges);
+        DWARFExpression expr;
+        if (base_reg == RegisterId::VFRAME) {
+          llvm::StringRef program;
+          if (GetFrameDataProgram(index, raw_ranges, program))
+            expr = MakeVFrameRelLocationExpression(program, loc.Hdr.Offset,
+                                                   module);
+          else {
+            // invalid variable
+          }
+        } else
+          expr = MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module);
+        AddDwarfRange(location_map, expr, raw_ranges);
+        break;
       }
-      break;
-    }
-    case S_DEFRANGE_REGISTER_REL: {
-      DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
-      cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
-          loc_specifier_cvs, loc));
-
-      Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
-
-      RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register;
-
-      if (base_reg == RegisterId::VFRAME) {
-        llvm::StringRef program;
-        if (GetFrameDataProgram(index, ranges, program)) {
-          result.location = MakeVFrameRelLocationExpression(
-              program, loc.Hdr.BasePointerOffset, module);
-          result.ranges = std::move(ranges);
-        } else {
-          // invalid variable
+      case S_DEFRANGE_REGISTER: {
+        DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
+        if (llvm::Error error =
+                SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
+                    loc_specifier_cvs, loc)) {
+          llvm::consumeError(std::move(error));
+          return result;
         }
-      } else {
-        result.location = MakeRegRelLocationExpression(
-            base_reg, loc.Hdr.BasePointerOffset, module);
-        result.ranges = std::move(ranges);
+        RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
+        Variable::RangeList raw_ranges =
+            MakeRangeList(index, loc.Range, loc.Gaps);
+        DWARFExpression expr =
+            MakeEnregisteredLocationExpression(reg_id, module);
+        AddDwarfRange(location_map, expr, raw_ranges);
+        break;
       }
-      break;
-    }
-    case S_DEFRANGE_REGISTER: {
-      DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym);
-      cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterSym>(
-          loc_specifier_cvs, loc));
-
-      RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register;
-      result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
-      result.location = MakeEnregisteredLocationExpression(base_reg, module);
-      break;
-    }
-    case S_DEFRANGE_SUBFIELD_REGISTER: {
-      // A map from offset in parent to pair of register id and size. If the
-      // variable is a simple type, then we don't know the number of subfields.
-      // Otherwise, the size of the map should be greater than or equal to the
-      // number of sub field record.
-      std::map<uint64_t, std::pair<RegisterId, uint32_t>> members_info;
-      bool is_simple_type = result.type.isSimple();
-      if (!is_simple_type) {
-        CVType class_cvt = index.tpi().getType(result.type);
-        TypeIndex class_id = result.type;
-        if (class_cvt.kind() == LF_MODIFIER)
-          class_id = LookThroughModifierRecord(class_cvt);
-        if (IsForwardRefUdt(class_id, index.tpi())) {
-          auto expected_full_ti =
-              index.tpi().findFullDeclForForwardRef(class_id);
-          if (!expected_full_ti) {
-            llvm::consumeError(expected_full_ti.takeError());
-            break;
-          }
-          class_cvt = index.tpi().getType(*expected_full_ti);
+      case S_DEFRANGE_REGISTER_REL: {
+        DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym);
+        if (llvm::Error error =
+                SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>(
+                    loc_specifier_cvs, loc)) {
+          llvm::consumeError(std::move(error));
+          return result;
         }
-        if (IsTagRecord(class_cvt)) {
-          TagRecord tag_record = CVTagRecord::create(class_cvt).asTag();
-          CVType field_list_cvt = index.tpi().getType(tag_record.FieldList);
-          FieldListRecord field_list;
-          if (llvm::Error error =
-                  TypeDeserializer::deserializeAs<FieldListRecord>(
-                      field_list_cvt, field_list))
-            llvm::consumeError(std::move(error));
-          FindMembersSize find_members_size(members_info, index.tpi());
-          if (llvm::Error err = visitMemberRecordStream(field_list.Data,
-                                                        find_members_size)) {
-            llvm::consumeError(std::move(err));
-            break;
+        Variable::RangeList raw_ranges =
+            MakeRangeList(index, loc.Range, loc.Gaps);
+        RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register;
+        DWARFExpression expr;
+        if (reg_id == RegisterId::VFRAME) {
+          llvm::StringRef program;
+          if (GetFrameDataProgram(index, raw_ranges, program))
+            expr = MakeVFrameRelLocationExpression(
+                program, loc.Hdr.BasePointerOffset, module);
+          else {
+            // invalid variable
           }
         } else {
-          // TODO: Handle poiner type.
-          break;
+          expr = MakeRegRelLocationExpression(reg_id, loc.Hdr.BasePointerOffset,
+                                              module);
         }
+        // FIXME: If it's UDT, we need to know the size of the value in byte.
+        if (!loc.hasSpilledUDTMember())
+          AddDwarfRange(location_map, expr, raw_ranges);
+        break;
       }
-
-      size_t member_idx = 0;
-      // Assuming S_DEFRANGE_SUBFIELD_REGISTER is followed only by
-      // S_DEFRANGE_SUBFIELD_REGISTER, need to verify.
-      while (loc_specifier_cvs.kind() == S_DEFRANGE_SUBFIELD_REGISTER) {
-        if (!is_simple_type && member_idx >= members_info.size())
-          break;
-
+      case S_DEFRANGE_SUBFIELD_REGISTER: {
         DefRangeSubfieldRegisterSym loc(
             SymbolRecordKind::DefRangeSubfieldRegisterSym);
-        cantFail(SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
-            loc_specifier_cvs, loc));
-
-        if (result.ranges) {
-          result.ranges = Variable::RangeList::GetOverlaps(
-              *result.ranges, MakeRangeList(index, loc.Range, loc.Gaps));
-        } else {
-          result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
-          result.ranges->Sort();
+        if (llvm::Error error =
+                SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>(
+                    loc_specifier_cvs, loc)) {
+          llvm::consumeError(std::move(error));
+          return result;
         }
 
-        if (is_simple_type) {
-          if (members_info.count(loc.Hdr.OffsetInParent)) {
-            // Malformed record.
-            result.ranges->Clear();
-            return result;
-          }
-          members_info[loc.Hdr.OffsetInParent] = {
-              (RegisterId)(uint16_t)loc.Hdr.Register, 0};
-        } else {
-          if (!members_info.count(loc.Hdr.OffsetInParent)) {
-            // Malformed record.
-            result.ranges->Clear();
-            return result;
-          }
-          members_info[loc.Hdr.OffsetInParent].first =
-              (RegisterId)(uint16_t)loc.Hdr.Register;
-        }
-        // Go to next S_DEFRANGE_SUBFIELD_REGISTER.
-        loc_specifier_id = PdbCompilandSymId(
-            loc_specifier_id.modi,
-            loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
-        loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
+        Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps);
+        uint32_t reg_size =
+            GetRegisterSize((RegisterId)(uint16_t)loc.Hdr.Register);
+        if (reg_size == 0)
+          break;
+        offset_to_size[loc.Hdr.OffsetInParent] = reg_size;
+        AddMemberLocationRanges(location_map, loc.Hdr.OffsetInParent,
+                                {loc.Hdr.Register, 0, true}, ranges);
+        break;
       }
-      // Fix size for simple type.
-      if (is_simple_type) {
-        auto cur = members_info.begin();
-        auto end = members_info.end();
-        auto next = cur;
-        ++next;
-        uint32_t size = 0;
-        while (next != end) {
-          cur->second.second = next->first - cur->first;
-          size += cur->second.second;
-          cur = next++;
-        }
-        cur->second.second =
-            GetTypeSizeForSimpleKind(result.type.getSimpleKind()) - size;
+      // FIXME: Handle other kinds. LLVM only generates the 4 types of records
+      // above. MSVC generates other location types.
+      case S_DEFRANGE:
+      case S_DEFRANGE_SUBFIELD:
+      case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
+        break;
+      default:
+        finished = true;
+        break;
       }
-      result.location =
-          MakeEnregisteredLocationExpressionForClass(members_info, module);
-      break;
+      loc_specifier_id = PdbCompilandSymId(
+          loc_specifier_id.modi,
+          loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
     }
-    default:
-      // FIXME: Handle other kinds. LLVM only generates the 4 types of records
-      // above.
-      break;
+    result.location = DWARFExpressionList();
+    for (const auto &entry : location_map) {
+      DWARFExpression dwarf_expr =
+          entry.data.is_dwarf ? entry.data.expr
+                              : MakeEnregisteredLocationExpressionForComposite(
+                                    entry.data.offset_to_location,
+                                    offset_to_size, type_size, module);
+
+      result.location->AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(),
+                                     dwarf_expr);
     }
     return result;
   }

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
index 066bcc89fd3b7..fa078ca061a8c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -103,8 +103,7 @@ struct SegmentOffsetLength {
 struct VariableInfo {
   llvm::StringRef name;
   llvm::codeview::TypeIndex type;
-  llvm::Optional<DWARFExpression> location;
-  llvm::Optional<Variable::RangeList> ranges;
+  llvm::Optional<DWARFExpressionList> location;
   bool is_param;
 };
 

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index cf17e616f659f..4109f6b7d4fa0 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1712,9 +1712,13 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
   func_block->GetStartAddress(addr);
   VariableInfo var_info =
       GetVariableLocationInfo(*m_index, var_id, *func_block, module);
-  if (!var_info.location || !var_info.ranges)
+  if (!var_info.location || var_info.location->GetSize() == 0)
     return nullptr;
-
+  Function *func = func_block->CalculateSymbolContextFunction();
+  if (!func)
+    return VariableSP();
+  var_info.location->SetFuncFileAddress(
+      func->GetAddressRange().GetBaseAddress().GetFileAddress());
   CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
   CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
   TypeSP type_sp = GetOrCreateType(var_info.type);
@@ -1732,11 +1736,10 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
   bool artificial = false;
   bool location_is_constant_data = false;
   bool static_member = false;
-  DWARFExpressionList locaiton_list = DWARFExpressionList(
-      module, *var_info.location, nullptr);
+  Variable::RangeList scope_ranges;
   VariableSP var_sp = std::make_shared<Variable>(
       toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
-      &block, *var_info.ranges, &decl, locaiton_list, external, artificial,
+      &block, scope_ranges, &decl, *var_info.location, external, artificial,
       location_is_constant_data, static_member);
   if (!is_param)
     m_ast->GetOrCreateVariableDecl(scope_id, var_id);

diff  --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables-registers.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables-registers.lldbinit
index 7b35ebbc0f7c8..ad080da24dab7 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables-registers.lldbinit
+++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables-registers.lldbinit
@@ -8,4 +8,28 @@ image lookup -a 0x140001019 -v
 image lookup -a 0x14000101e -v
 image lookup -a 0x14000102c -v
 
+image lookup -a 0x140001031 -v
+image lookup -a 0x140001032 -v
+image lookup -a 0x140001033 -v
+image lookup -a 0x140001034 -v
+image lookup -a 0x140001035 -v
+image lookup -a 0x140001036 -v
+image lookup -a 0x140001037 -v
+image lookup -a 0x14000103b -v
+image lookup -a 0x14000103d -v
+image lookup -a 0x14000103f -v
+image lookup -a 0x140001041 -v
+image lookup -a 0x140001043 -v
+image lookup -a 0x140001045 -v
+image lookup -a 0x140001046 -v
+image lookup -a 0x140001047 -v
+image lookup -a 0x140001048 -v
+image lookup -a 0x140001049 -v
+image lookup -a 0x14000104a -v
+image lookup -a 0x14000104b -v
+image lookup -a 0x14000104c -v
+image lookup -a 0x14000104e -v
+image lookup -a 0x14000104f -v
+image lookup -a 0x140001050 -v
+image lookup -a 0x140001051 -v
 exit

diff  --git a/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.test b/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.test
index 70e344e60aa9a..6fd4186e98846 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.test
+++ b/lldb/test/Shell/SymbolFile/NativePDB/inline_sites.test
@@ -52,13 +52,17 @@
 #CHECK: (lldb) b a.cpp:4
 #CHECK: Breakpoint 13: where = {{.*}}`main + 61 at a.cpp:4, address = 0x000000014000103d
 
+# FIXME: The following variable location have wrong register numbers due to
+# https://github.com/llvm/llvm-project/issues/53575. Fix them after resolving
+# the issue.
+
 # CEHCK-LABEL: (lldb) image lookup -a 0x140001003 -v
 # CHECK:       Summary: {{.*}}`main + 3 at a.cpp:2
 # CHECK:       Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x0000000140001046)
 # CHECK:       Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
 # CHECK:       LineEntry: [0x0000000140001000-0x0000000140001004): /tmp/a.cpp:2
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
 
 # CEHCK-LABEL: (lldb) image lookup -a 0x140001004 -v
 # CHECK:       Summary: {{.*}}`main + 4 [inlined] Namespace1::foo at a.h:5
@@ -67,10 +71,10 @@
 # CHECK:         Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
 # CHECK-NEXT:            id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
 # CHECK:       LineEntry: [0x0000000140001004-0x000000014000100c): /tmp/a.h:5
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
 
 # CEHCK-LABEL: (lldb) image lookup -a 0x140001010 -v
 # CHECK:       Summary: {{.*}}`main + 16 [inlined] Namespace1::foo + 12 at a.h:7
@@ -79,10 +83,10 @@
 # CHECK:         Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
 # CHECK-NEXT:            id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
 # CHECK:       LineEntry: [0x0000000140001010-0x0000000140001018): /tmp/a.h:7
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
 
 # CEHCK-LABEL: (lldb) image lookup -a 0x14000101c -v
 # CHECK:       Summary: {{.*}}`main + 28 [inlined] Class1::bar at b.h:5
@@ -93,12 +97,12 @@
 # CHECK-NEXT:            id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
 # CHECK-NEXT:            id = {{.*}}, range = [0x14000101c-0x140001039), name = "Class1::bar", decl = b.h:4
 # CHECK:       LineEntry: [0x000000014000101c-0x0000000140001022): /tmp/b.h:5
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "x", type = "int", valid ranges = [0x000000014000101c-0x000000014000101e)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = [0x000000014000101c-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x000000014000101e) -> DW_OP_reg24 XMM7
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x0000000140001039) -> DW_OP_breg7 RSP+52
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
 
 # CEHCK-LABEL: (lldb) image lookup -a 0x14000102a -v
 # CHECK:       Summary: {{.*}}`main + 42 [inlined] Namespace2::Class2::func at c.h:5
@@ -111,21 +115,21 @@
 # CHECK-NEXT:            id = {{.*}}, range = [0x14000101c-0x140001039), name = "Class1::bar", decl = b.h:4
 # CHECK-NEXT:            id = {{.*}}, range = [0x14000102a-0x140001039), name = "Namespace2::Class2::func", decl = c.h:4
 # CHECK:       LineEntry: [0x000000014000102a-0x0000000140001031): /tmp/c.h:5
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "x", type = "int", valid ranges = [0x000000014000102a-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "func_local", type = "int", valid ranges = [0x000000014000102a-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = [0x000000014000101c-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001039)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001000-0x000000014000102d)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x000000014000102a, 0x0000000140001039) -> DW_OP_reg24 XMM7
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "func_local", type = "int", valid ranges = <block>, location = [0x000000014000102a, 0x0000000140001039) -> DW_OP_breg7 RSP+48
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "bar_local", type = "int", valid ranges = <block>, location = [0x000000014000101c, 0x0000000140001039) -> DW_OP_breg7 RSP+52
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001039) -> DW_OP_breg7 RSP+44
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x000000014000102d) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
 
 # CEHCK-LABEL: (lldb) image lookup -a 0x140001039 -v
 # CHECK:       Summary: {{.*}}`main + 57 at a.cpp:3
 # CHECK:       Function: id = {{.*}}, name = "main", range = [0x0000000140001000-0x0000000140001046)
 # CHECK:         Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
 # CHECK:       LineEntry: [0x0000000140001039-0x000000014000103d): /tmp/a.cpp:3
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
 
 # CEHCK-LABEL: (lldb) image lookup -a 0x140001044 -v
 # CHECK:       Summary: {{.*}}`main + 68 [inlined] Namespace1::foo + 5 at a.h:8
@@ -134,10 +138,10 @@
 # CHECK:         Blocks: id = {{.*}}, range = [0x140001000-0x140001046)
 # CHECK-NEXT:            id = {{.*}}, ranges = [0x140001004-0x140001039)[0x14000103f-0x140001046), name = "Namespace1::foo", decl = a.h:4
 # CHECK:       LineEntry: [0x0000000140001044-0x0000000140001046): /tmp/a.h:8
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = [0x0000000140001044-0x0000000140001046)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001044-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001000-0x0000000140001045)
-# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = [0x0000000140001004-0x0000000140001046)
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "foo_local", type = "int", valid ranges = <block>, location = [0x0000000140001044, 0x0000000140001046) -> DW_OP_breg7 RSP+44
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001044, 0x0000000140001045) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001045) -> DW_OP_reg3 RBX
+# CHECK-NEXT:  Variable: id = {{.*}}, name = "main_local", type = "int", valid ranges = <block>, location = [0x0000000140001004, 0x0000000140001046) -> DW_OP_breg7 RSP+48
 
 # CHECK-LABEL: (lldb) target modules dump ast
 # CHECK-NEXT:  Dumping clang ast for 1 modules.

diff  --git a/lldb/test/Shell/SymbolFile/NativePDB/local-variables-registers.s b/lldb/test/Shell/SymbolFile/NativePDB/local-variables-registers.s
index ad524dd98c46a..ad2d0704cdf41 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/local-variables-registers.s
+++ b/lldb/test/Shell/SymbolFile/NativePDB/local-variables-registers.s
@@ -34,39 +34,38 @@
 
 # CHECK:      (lldb) image lookup -a 0x140001000 -v
 # CHECK:          LineEntry: [0x0000000140001000-0x0000000140001003): C:\src\test\a.cpp:10
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "p1", type = "int", valid ranges = [0x0000000140001000-0x0000000140001003), location = DW_OP_reg26 XMM9
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = [0x0000000140001000-0x0000000140001006), location = DW_OP_regx 0x3f
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "p1", type = "int", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001003) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001006) -> DW_OP_regx 0x3f
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x140001003 -v
 # CHECK:          LineEntry: [0x0000000140001003-0x0000000140001006): C:\src\test\a.cpp:11
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = [0x0000000140001000-0x0000000140001006), location = DW_OP_regx 0x3f
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "p2", type = "char", valid ranges = <block>, location = [0x0000000140001000, 0x0000000140001006) -> DW_OP_regx 0x3f
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "s", type = "S", valid ranges = <block>, location = [0x0000000140001003, 0x0000000140001006) -> DW_OP_piece 0x4, DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x140001006 -v
 # CHECK:          LineEntry: [0x0000000140001006-0x0000000140001011): C:\src\test\a.cpp:12
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "s", type = "S", valid ranges = [0x0000000140001006-0x0000000140001011), location = DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_regx 0x3f, DW_OP_piece 0x1
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "s", type = "S", valid ranges = <block>, location = [0x0000000140001006, 0x0000000140001011) -> DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x140001011 -v
 # CHECK:          LineEntry: [0x0000000140001011-0x0000000140001015): C:\src\test\a.cpp:15
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = [0x0000000140001011-0x0000000140001017), location = DW_OP_reg26 XMM9
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001011-0x0000000140001019), location = DW_OP_reg3 RBX
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "argc", type = "int", valid ranges = <block>, location = [0x0000000140001011, 0x0000000140001017) -> DW_OP_reg26 XMM9
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001011, 0x0000000140001019) -> DW_OP_reg3 RBX
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x140001017 -v
 # CHECK:          LineEntry: [0x0000000140001017-0x000000014000101e): C:\src\test\a.cpp:17
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = [0x0000000140001011-0x0000000140001019), location = DW_OP_reg3 RBX
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "local", type = "int", valid ranges = [0x0000000140001017-0x000000014000101e), location = DW_OP_reg26 XMM9
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "argv", type = "char **", valid ranges = <block>, location = [0x0000000140001011, 0x0000000140001019) -> DW_OP_reg3 RBX
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "local", type = "int", valid ranges = <block>, location = [0x0000000140001017, 0x000000014000101e) -> DW_OP_reg26 XMM9
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x140001019 -v
 # CHECK:          LineEntry: [0x0000000140001017-0x000000014000101e): C:\src\test\a.cpp:17
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "local", type = "int", valid ranges = [0x0000000140001017-0x000000014000101e), location = DW_OP_reg26 XMM9
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "local", type = "int", valid ranges = <block>, location = [0x0000000140001017, 0x000000014000101e) -> DW_OP_reg26 XMM9
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x14000101e -v
 # CHECK:          LineEntry: [0x000000014000101e-0x0000000140001031): C:\src\test\a.cpp:18
-# CHECK-NEXT:      Variable: id = {{.*}}, name = "s", type = "S", valid ranges = [0x000000014000101e-0x000000014000102c), location = DW_OP_reg24 XMM7, DW_OP_piece 0x4, DW_OP_piece 0x1
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "s", type = "S", valid ranges = <block>, location = [0x000000014000101e, 0x000000014000102c) -> DW_OP_reg24 XMM7, DW_OP_piece 0x4, DW_OP_piece 0x4
 # CHECK-EMPTY:
 # CHECK:      (lldb) image lookup -a 0x14000102c -v
 # CHECK:          LineEntry: [0x000000014000101e-0x0000000140001031): C:\src\test\a.cpp:18
-# CHECK-EMPTY:
-
 
 	.text
 	.def	 @feat.00;
@@ -153,6 +152,75 @@ main:                                   # @main
 .Ltmp7:
 	add	rsp, 40
 	ret
+# Manually created for testing purpose.
+.L31:
+	.cv_loc	1 1 1000 0                        # a.cpp:1000:0
+	ret
+.L32:
+	ret
+.L33:
+	ret
+.L34:
+	.cv_loc	1 1 1001 0                        # a.cpp:1001:0
+	ret
+.L35:
+	ret
+.L36:
+	ret
+.L37:
+	ret
+.L38:
+	ret
+.L39:
+	ret
+.L3a:
+	ret
+.L3b:
+	.cv_loc	1 1 1002 0                        # a.cpp:1002:0
+	ret
+.L3c:
+	ret
+.L3d:
+	ret
+.L3e:
+	ret
+.L3f:
+	ret
+.L40:
+	ret
+.L41:
+	ret
+.L42:
+	ret
+.L43:
+	ret
+.L44:
+	ret
+.L45:
+	.cv_loc	1 1 1003 0                        # a.cpp:1003:0
+	ret
+.L46:
+	ret
+.L47:
+	ret
+.L48:
+	ret
+.L49:
+	ret
+.L4a:
+	ret
+.L4b:
+	ret
+.L4c:
+	ret
+.L4d:
+	ret
+.L4e:
+	.cv_loc	1 1 1004 0                        # a.cpp:1004:0
+	ret
+.L4f:
+	ret
+.L50:
 .Ltmp8:
 .Lfunc_end1:
 	.seh_endproc
@@ -322,8 +390,172 @@ main:                                   # @main
 	.p2align	2
 .Ltmp38:
 	.cv_def_range	 .Ltmp6 .Ltmp7, subfield_reg, 17, 0
-	.short	2                               # Record length
+ 	.short	.Ltmp101-.Ltmp100
+# Manually created debug info for testing purpose.
+# 1. Test non-overlapped ranges.
+.Ltmp100:
+	.short	4414                            # Record kind: S_LOCAL
+	.long	4109                            # TypeIndex
+	.short	0                               # Flags
+	.asciz	"non_overlapped_ranges"
+	.p2align	2
+.Ltmp101:
+	.cv_def_range	.L31 .L32, reg, 331
+	.cv_def_range	.L32 .L33, reg, 330
+	.cv_def_range	.L33 .L34, reg, 336
+	.short	.Ltmp103-.Ltmp102
+# CHECK:      (lldb) image lookup -a 0x140001031 -v
+# CHECK:          LineEntry: [0x0000000140001031-0x0000000140001034): C:\src\test\a.cpp:1000
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "non_overlapped_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001031, 0x0000000140001032) -> DW_OP_reg3 RBX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001032 -v
+# CHECK:          LineEntry: [0x0000000140001031-0x0000000140001034): C:\src\test\a.cpp:1000
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "non_overlapped_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001032, 0x0000000140001033) -> DW_OP_reg2 RCX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001033 -v
+# CHECK:          LineEntry: [0x0000000140001031-0x0000000140001034): C:\src\test\a.cpp:1000
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "non_overlapped_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001033, 0x0000000140001034) -> DW_OP_reg8 R8
+# CHECK-EMPTY:
+
+# 2. Test overlapped subfield ranges at 
diff erent offsets.
+.Ltmp102:
+ 	.short	4414                            # Record kind: S_LOCAL
+ 	.long	4109                            # TypeIndex
+ 	.short	0                               # Flags
+ 	.asciz	"overlapped_subfield_ranges"
+ 	.p2align	2
+.Ltmp103:
+ 	.cv_def_range	 .L34 .L36, subfield_reg, 3, 0
+ 	.cv_def_range	 .L35 .L37, subfield_reg, 17, 4
+ 	.cv_def_range	 .L37 .L39, subfield_reg, 18, 4
+ 	.short	.Ltmp105-.Ltmp104
+# CHECK:      (lldb) image lookup -a 0x140001034 -v
+# CHECK:          LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001034, 0x0000000140001035) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x7
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001035 -v
+# CHECK:          LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001035, 0x0000000140001036) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3, DW_OP_reg24 XMM7, DW_OP_piece 0x4
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001036 -v
+# CHECK:          LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001036, 0x0000000140001037) -> DW_OP_piece 0x4, DW_OP_reg24 XMM7, DW_OP_piece 0x4
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001037 -v
+# CHECK:          LineEntry: [0x0000000140001034-0x000000014000103b): C:\src\test\a.cpp:1001
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_subfield_ranges", type = "S1", valid ranges = <block>, location = [0x0000000140001037, 0x0000000140001039) -> DW_OP_piece 0x4, DW_OP_reg26 XMM9, DW_OP_piece 0x4
+# CHECK-EMPTY:
+
+# 3. Test overlapped ranges for the whole value.
+.Ltmp104:
+	.short	4414                            # Record kind: S_LOCAL
+	.long	4109                            # TypeIndex
+	.short	0                               # Flags
+	.asciz	"overlapped_ranges_2"
+	.p2align	2
+.Ltmp105:
+	.cv_def_range	.L3b .L3d, reg, 331
+	.cv_def_range	.L3c .L3e, reg, 330
+	.cv_def_range	.L3f .L44, reg, 339
+	.cv_def_range   .L41 .L43, reg, 328
+	.short	.Ltmp107-.Ltmp106
+# CHECK:      (lldb) image lookup -a 0x14000103b -v
+# CHECK:          LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x000000014000103b, 0x000000014000103c) -> DW_OP_reg3 RBX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x14000103d -v
+# CHECK:          LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x000000014000103c, 0x000000014000103e) -> DW_OP_reg2 RCX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x14000103f -v
+# CHECK:          LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x000000014000103f, 0x0000000140001041) -> DW_OP_reg11 R11
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001041 -v
+# CHECK:          LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x0000000140001041, 0x0000000140001043) -> DW_OP_reg0 RAX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001043 -v
+# CHECK:          LineEntry: [0x000000014000103b-0x0000000140001045): C:\src\test\a.cpp:1002
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_2", type = "S1", valid ranges = <block>, location = [0x0000000140001043, 0x0000000140001044) -> DW_OP_reg11 R11
+# CHECK-EMPTY:
+
+# 4. Test overlapped ranges for both subfield and whole value.
+.Ltmp106:
+	.short	4414                            # Record kind: S_LOCAL
+	.long	4109                            # TypeIndex
+	.short	0                               # Flags
+	.asciz	"overlapped_ranges_3"
+	.p2align	2
+.Ltmp107:
+	# The following two lines result:
+	# [.L45, .L46) -> value at offset 0 is at reg 3.
+	# [.L46, .L49) -> value at offset 0 is at reg 3 and value at offset 4 is at reg 17.
+	# [.L49, .L4a) -> value at offset 4 is at reg 17.
+	.cv_def_range	.L46 .L4a, subfield_reg, 17, 4
+	.cv_def_range	.L45 .L49, subfield_reg, 3, 0
+	# The following overwrites range [.L47, .L48) and [.L49 .L4a) because whole
+	# value location is preferred over composited value locations.
+	.cv_def_range	.L47 .L48, reg, 331
+	.cv_def_range	.L49 .L4a, reg, 328
+	# For the same reason, reg 330 wins in following example.
+	.cv_def_range   .L4b .L4e, reg, 330
+	.cv_def_range	.L4b .L4d, subfield_reg, 17, 4
+	.cv_def_range	.L4c .L4e, subfield_reg, 3, 0
+ 	.short .Ltmp109-.Ltmp108
+# CHECK:      (lldb) image lookup -a 0x140001045 -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001045, 0x0000000140001046) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x7
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001046 -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001046, 0x0000000140001047) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3, DW_OP_reg24 XMM7, DW_OP_piece 0x4
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001047 -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001047, 0x0000000140001048) -> DW_OP_reg3 RBX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001048 -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001048, 0x0000000140001049) -> DW_OP_regx 0x3f, DW_OP_piece 0x1, DW_OP_piece 0x3, DW_OP_reg24 XMM7, DW_OP_piece 0x4
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x140001049 -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x0000000140001049, 0x000000014000104a) -> DW_OP_reg0 RAX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x14000104a -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x14000104b -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x000000014000104b, 0x000000014000104e) -> DW_OP_reg2 RCX
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x14000104c -v
+# CHECK:          LineEntry: [0x0000000140001045-0x000000014000104e): C:\src\test\a.cpp:1003
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "overlapped_ranges_3", type = "S1", valid ranges = <block>, location = [0x000000014000104b, 0x000000014000104e) -> DW_OP_reg2 RCX
+# CHECK-EMPTY:
+
+# 5. Simple type with subfield.
+.Ltmp108:
+	.short	4414                            # Record kind: S_LOCAL
+	.long	19                              # TypeIndex
+	.short	0                               # Flags
+	.asciz	"simple_type1"
+	.p2align	2
+.Ltmp109:
+	.cv_def_range	 .L4e .L4f, subfield_reg, 17, 4
+	.cv_def_range	 .L4e .L50, subfield_reg, 18, 0
+	.short 2
 	.short	4431                            # Record kind: S_PROC_ID_END
+# CHECK:      (lldb) image lookup -a 0x14000104e -v
+# CHECK:          LineEntry: [0x000000014000104e-0x0000000140001050): C:\src\test\a.cpp:1004
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "simple_type1", type = "int64_t", valid ranges = <block>, location = [0x000000014000104e, 0x000000014000104f) -> DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_reg24 XMM7, DW_OP_piece 0x4
+# CHECK-EMPTY:
+# CHECK:      (lldb) image lookup -a 0x14000104f -v
+# CHECK:          LineEntry: [0x000000014000104e-0x0000000140001050): C:\src\test\a.cpp:1004
+# CHECK-NEXT:      Variable: id = {{.*}}, name = "simple_type1", type = "int64_t", valid ranges = <block>, location = [0x000000014000104f, 0x0000000140001050) -> DW_OP_reg26 XMM9, DW_OP_piece 0x4, DW_OP_piece 0x4
+# CHECK-EMPTY:
+
 .Ltmp26:
 	.p2align	2
 	.cv_linetable	1, main, .Lfunc_end1
@@ -452,25 +684,38 @@ main:                                   # @main
 	.byte	243
 	.byte	242
 	.byte	241
-	# StringId (0x100C)
-	.short	0x12                            # Record length
-	.short	0x1605                          # Record kind: LF_STRING_ID
-	.long	0x0                             # Id
-	.asciz	"C:\\src\\test"                 # StringData
-	# StringId (0x100D)
-	.short	0xe                             # Record length
-	.short	0x1605                          # Record kind: LF_STRING_ID
-	.long	0x0                             # Id
-	.asciz	"a.cpp"                         # StringData
-	.byte	242
-	.byte	241
+	# Manually created debug info for testing purpose, FieldList (0x100C) and Struct (0x100D)
+	# FieldList (0x100C)
+	.short	0x1a                            # Record length
+	.short	0x1203                          # Record kind: LF_FIELDLIST
+	.short	0x150d                          # Member kind: DataMember ( LF_MEMBER )
+	.short	0x3                             # Attrs: Public
+	.long	0x70                            # Type: char
+	.short	0x0                             # FieldOffset
+	.asciz	"c"                             # Name
+	.short	0x150d                          # Member kind: DataMember ( LF_MEMBER )
+	.short	0x3                             # Attrs: Public
+	.long	0x74                            # Type: int
+	.short	0x4                             # FieldOffset
+	.asciz	"i"                             # Name
+	# Struct (0x100D)
+	.short	0x20                            # Record length
+	.short	0x1505                          # Record kind: LF_STRUCTURE
+	.short	0x2                             # MemberCount
+	.short	0x200                           # Properties ( HasUniqueName (0x200) )
+	.long	0x100c                          # FieldList: <field list>
+	.long	0x0                             # DerivedFrom
+	.long	0x0                             # VShape
+	.short	0x8                             # SizeOf
+	.asciz	"S1"                            # Name
+	.asciz	".?AUS1@@"                      # LinkageName
 	# BuildInfo (0x100E)
 	.short	0x1a                            # Record length
 	.short	0x1603                          # Record kind: LF_BUILDINFO
-	.short	0x5                             # NumArgs
-	.long	0x100c                          # Argument: C:\src\test
+	.short	0x1                             # NumArgs
+	.long	0x0                             # Argument
+	.long	0x0                             # Argument
 	.long	0x0                             # Argument
-	.long	0x100d                          # Argument: a.cpp
 	.long	0x0                             # Argument
 	.long	0x0                             # Argument
 	.byte	242

diff  --git a/lldb/test/Shell/SymbolFile/NativePDB/subfield_register_simple_type.s b/lldb/test/Shell/SymbolFile/NativePDB/subfield_register_simple_type.s
deleted file mode 100644
index 80fa421188a09..0000000000000
--- a/lldb/test/Shell/SymbolFile/NativePDB/subfield_register_simple_type.s
+++ /dev/null
@@ -1,433 +0,0 @@
-# clang-format off
-# REQUIRES: lld, x86
-
-# RUN: %clang_cl --target=i386-windows-msvc -c /Fo%t.obj -- %s
-# RUN: lld-link /debug:full /nodefaultlib /entry:main %t.obj /out:%t.exe /base:0x400000
-# RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
-# RUN:     %p/Inputs/subfield_register_simple_type.lldbinit 2>&1 | FileCheck %s
-
-# This file is compiled from following source file:
-# clang-cl --target=i386-windows-msvc /Z7 /O1 -c /Fa a.cpp
-# __int64 __attribute__((optnone)) bar(__int64 x) { return x; };
-# __int64 foo(__int64 x) {
-#   return bar(x);
-# }
-#
-# int main(int argc, char** argv) {
-#   foo(argc);
-#   return 0;
-# }
-
-# FIXME: The following variable location have wrong register numbers due to
-# https://github.com/llvm/llvm-project/issues/53575. Fix them after resolving
-# the issue.
-
-# CHECK:      (lldb) image lookup -a 0x40102f -v
-# CHECK:      LineEntry: [0x00401026-0x00401039): C:\src\a.cpp:3
-# CHECK-NEXT: Variable: id = {{.*}}, name = "x", type = "int64_t", valid ranges = [0x0040102f-0x00401036), location = DW_OP_reg0 EAX, DW_OP_piece 0x4, DW_OP_reg2 EDX, DW_OP_piece 0x4, decl =
-
-	.text
-	.def	@feat.00;
-	.scl	3;
-	.type	0;
-	.endef
-	.globl	@feat.00
-.set @feat.00, 1
-	.intel_syntax noprefix
-	.file	"a.cpp"
-	.def	"?bar@@YA_J_J at Z";
-	.scl	2;
-	.type	32;
-	.endef
-	.section	.text,"xr",one_only,"?bar@@YA_J_J at Z"
-	.globl	"?bar@@YA_J_J at Z"                # -- Begin function ?bar@@YA_J_J at Z
-	.p2align	4, 0x90
-"?bar@@YA_J_J at Z":                       # @"?bar@@YA_J_J at Z"
-Lfunc_begin0:
-	.cv_func_id 0
-	.cv_file	1 "C:\\src\\a.cpp" "CB99424BC3DD1AB059A2DBC6841147F2" 1
-	.cv_loc	0 1 1 0                         # a.cpp:1:0
-	.cv_fpo_proc	"?bar@@YA_J_J at Z" 8
-# %bb.0:                                # %entry
-	push	ebp
-	.cv_fpo_pushreg	ebp
-	mov	ebp, esp
-	.cv_fpo_setframe	ebp
-	and	esp, -8
-	.cv_fpo_stackalign	8
-	sub	esp, 8
-	.cv_fpo_stackalloc	8
-	.cv_fpo_endprologue
-	mov	eax, dword ptr [ebp + 8]
-	mov	ecx, dword ptr [ebp + 12]
-	mov	dword ptr [esp], eax
-	mov	dword ptr [esp + 4], ecx
-Ltmp0:
-	mov	eax, dword ptr [esp]
-	mov	edx, dword ptr [esp + 4]
-	mov	esp, ebp
-	pop	ebp
-	ret
-Ltmp1:
-	.cv_fpo_endproc
-Lfunc_end0:
-                                        # -- End function
-	.def	"?foo@@YA_J_J at Z";
-	.scl	2;
-	.type	32;
-	.endef
-	.section	.text,"xr",one_only,"?foo@@YA_J_J at Z"
-	.globl	"?foo@@YA_J_J at Z"                # -- Begin function ?foo@@YA_J_J at Z
-"?foo@@YA_J_J at Z":                       # @"?foo@@YA_J_J at Z"
-Lfunc_begin1:
-	.cv_func_id 1
-	.cv_fpo_proc	"?foo@@YA_J_J at Z" 8
-# %bb.0:                                # %entry
-	#DEBUG_VALUE: foo:x <- [DW_OP_plus_uconst 4] [$esp+0]
-	.cv_loc	1 1 3 0                         # a.cpp:3:0
-	jmp	"?bar@@YA_J_J at Z"                # TAILCALL
-Ltmp2:
-	.cv_fpo_endproc
-Lfunc_end1:
-                                        # -- End function
-	.def	_main;
-	.scl	2;
-	.type	32;
-	.endef
-	.section	.text,"xr",one_only,_main
-	.globl	_main                           # -- Begin function main
-_main:                                  # @main
-Lfunc_begin2:
-	.cv_func_id 2
-	.cv_loc	2 1 6 0                         # a.cpp:6:0
-	.cv_fpo_proc	_main 8
-# %bb.0:                                # %entry
-	#DEBUG_VALUE: main:argv <- [DW_OP_plus_uconst 8] [$esp+0]
-	#DEBUG_VALUE: main:argc <- [DW_OP_plus_uconst 4] [$esp+0]
-	.cv_inline_site_id 3 within 2 inlined_at 1 7 0
-	.cv_loc	3 1 3 0                         # a.cpp:3:0
-	mov	eax, dword ptr [esp + 4]
-	mov	ecx, eax
-	sar	ecx, 31
-Ltmp3:
-	#DEBUG_VALUE: foo:x <- [DW_OP_LLVM_fragment 0 32] $eax
-	#DEBUG_VALUE: foo:x <- [DW_OP_LLVM_fragment 32 32] $ecx
-	push	ecx
-Ltmp4:
-	push	eax
-	call	"?bar@@YA_J_J at Z"
-Ltmp5:
-	add	esp, 8
-Ltmp6:
-	.cv_loc	2 1 8 0                         # a.cpp:8:0
-	xor	eax, eax
-	ret
-Ltmp7:
-	.cv_fpo_endproc
-Lfunc_end2:
-                                        # -- End function
-	.section	.drectve,"yn"
-	.ascii	" /DEFAULTLIB:libcmt.lib"
-	.ascii	" /DEFAULTLIB:oldnames.lib"
-	.section	.debug$S,"dr"
-	.p2align	2
-	.long	4                               # Debug section magic
-	.long	241
-	.long	Ltmp9-Ltmp8                     # Subsection size
-Ltmp8:
-	.short	Ltmp11-Ltmp10                   # Record length
-Ltmp10:
-	.short	4353                            # Record kind: S_OBJNAME
-	.long	0                               # Signature
-	.asciz	"C:\\src\\a.obj"                # Object name
-	.p2align	2
-Ltmp11:
-	.short	Ltmp13-Ltmp12                   # Record length
-Ltmp12:
-	.short	4412                            # Record kind: S_COMPILE3
-	.long	1                               # Flags and language
-	.short	7                               # CPUType
-	.short	15                              # Frontend version
-	.short	0
-	.short	0
-	.short	0
-	.short	15000                           # Backend version
-	.short	0
-	.short	0
-	.short	0
-	.asciz	"clang version 15.0.0"          # Null-terminated compiler version string
-	.p2align	2
-Ltmp13:
-Ltmp9:
-	.p2align	2
-	.long	246                             # Inlinee lines subsection
-	.long	Ltmp15-Ltmp14                   # Subsection size
-Ltmp14:
-	.long	0                               # Inlinee lines signature
-
-                                        # Inlined function foo starts at a.cpp:2
-	.long	4098                            # Type index of inlined function
-	.cv_filechecksumoffset	1               # Offset into filechecksum table
-	.long	2                               # Starting line number
-Ltmp15:
-	.p2align	2
-	.section	.debug$S,"dr",associative,"?bar@@YA_J_J at Z"
-	.p2align	2
-	.long	4                               # Debug section magic
-	.cv_fpo_data	"?bar@@YA_J_J at Z"
-	.long	241                             # Symbol subsection for bar
-	.long	Ltmp17-Ltmp16                   # Subsection size
-Ltmp16:
-	.short	Ltmp19-Ltmp18                   # Record length
-Ltmp18:
-	.short	4423                            # Record kind: S_GPROC32_ID
-	.long	0                               # PtrParent
-	.long	0                               # PtrEnd
-	.long	0                               # PtrNext
-	.long	Lfunc_end0-"?bar@@YA_J_J at Z"     # Code size
-	.long	0                               # Offset after prologue
-	.long	0                               # Offset before epilogue
-	.long	4099                            # Function type index
-	.secrel32	"?bar@@YA_J_J at Z"        # Function section relative address
-	.secidx	"?bar@@YA_J_J at Z"                # Function section index
-	.byte	0                               # Flags
-	.asciz	"bar"                           # Function name
-	.p2align	2
-Ltmp19:
-	.short	Ltmp21-Ltmp20                   # Record length
-Ltmp20:
-	.short	4114                            # Record kind: S_FRAMEPROC
-	.long	12                              # FrameSize
-	.long	0                               # Padding
-	.long	0                               # Offset of padding
-	.long	0                               # Bytes of callee saved registers
-	.long	0                               # Exception handler offset
-	.short	0                               # Exception handler section
-	.long	147456                          # Flags (defines frame register)
-	.p2align	2
-Ltmp21:
-	.short	Ltmp23-Ltmp22                   # Record length
-Ltmp22:
-	.short	4414                            # Record kind: S_LOCAL
-	.long	19                              # TypeIndex
-	.short	1                               # Flags
-	.asciz	"x"
-	.p2align	2
-Ltmp23:
-	.cv_def_range	 Ltmp0 Ltmp1, reg_rel, 30006, 0, -8
-	.short	2                               # Record length
-	.short	4431                            # Record kind: S_PROC_ID_END
-Ltmp17:
-	.p2align	2
-	.cv_linetable	0, "?bar@@YA_J_J at Z", Lfunc_end0
-	.section	.debug$S,"dr",associative,"?foo@@YA_J_J at Z"
-	.p2align	2
-	.long	4                               # Debug section magic
-	.cv_fpo_data	"?foo@@YA_J_J at Z"
-	.long	241                             # Symbol subsection for foo
-	.long	Ltmp25-Ltmp24                   # Subsection size
-Ltmp24:
-	.short	Ltmp27-Ltmp26                   # Record length
-Ltmp26:
-	.short	4423                            # Record kind: S_GPROC32_ID
-	.long	0                               # PtrParent
-	.long	0                               # PtrEnd
-	.long	0                               # PtrNext
-	.long	Lfunc_end1-"?foo@@YA_J_J at Z"     # Code size
-	.long	0                               # Offset after prologue
-	.long	0                               # Offset before epilogue
-	.long	4098                            # Function type index
-	.secrel32	"?foo@@YA_J_J at Z"        # Function section relative address
-	.secidx	"?foo@@YA_J_J at Z"                # Function section index
-	.byte	0                               # Flags
-	.asciz	"foo"                           # Function name
-	.p2align	2
-Ltmp27:
-	.short	Ltmp29-Ltmp28                   # Record length
-Ltmp28:
-	.short	4114                            # Record kind: S_FRAMEPROC
-	.long	0                               # FrameSize
-	.long	0                               # Padding
-	.long	0                               # Offset of padding
-	.long	0                               # Bytes of callee saved registers
-	.long	0                               # Exception handler offset
-	.short	0                               # Exception handler section
-	.long	0                               # Flags (defines frame register)
-	.p2align	2
-Ltmp29:
-	.short	Ltmp31-Ltmp30                   # Record length
-Ltmp30:
-	.short	4414                            # Record kind: S_LOCAL
-	.long	19                              # TypeIndex
-	.short	1                               # Flags
-	.asciz	"x"
-	.p2align	2
-Ltmp31:
-	.cv_def_range	 Lfunc_begin1 Lfunc_end1, reg_rel, 30006, 0, 4
-	.short	2                               # Record length
-	.short	4431                            # Record kind: S_PROC_ID_END
-Ltmp25:
-	.p2align	2
-	.cv_linetable	1, "?foo@@YA_J_J at Z", Lfunc_end1
-	.section	.debug$S,"dr",associative,_main
-	.p2align	2
-	.long	4                               # Debug section magic
-	.cv_fpo_data	_main
-	.long	241                             # Symbol subsection for main
-	.long	Ltmp33-Ltmp32                   # Subsection size
-Ltmp32:
-	.short	Ltmp35-Ltmp34                   # Record length
-Ltmp34:
-	.short	4423                            # Record kind: S_GPROC32_ID
-	.long	0                               # PtrParent
-	.long	0                               # PtrEnd
-	.long	0                               # PtrNext
-	.long	Lfunc_end2-_main                # Code size
-	.long	0                               # Offset after prologue
-	.long	0                               # Offset before epilogue
-	.long	4103                            # Function type index
-	.secrel32	_main                   # Function section relative address
-	.secidx	_main                           # Function section index
-	.byte	0                               # Flags
-	.asciz	"main"                          # Function name
-	.p2align	2
-Ltmp35:
-	.short	Ltmp37-Ltmp36                   # Record length
-Ltmp36:
-	.short	4114                            # Record kind: S_FRAMEPROC
-	.long	0                               # FrameSize
-	.long	0                               # Padding
-	.long	0                               # Offset of padding
-	.long	0                               # Bytes of callee saved registers
-	.long	0                               # Exception handler offset
-	.short	0                               # Exception handler section
-	.long	0                               # Flags (defines frame register)
-	.p2align	2
-Ltmp37:
-	.short	Ltmp39-Ltmp38                   # Record length
-Ltmp38:
-	.short	4414                            # Record kind: S_LOCAL
-	.long	116                             # TypeIndex
-	.short	1                               # Flags
-	.asciz	"argc"
-	.p2align	2
-Ltmp39:
-	.cv_def_range	 Lfunc_begin2 Ltmp4, reg_rel, 30006, 0, 4
-	.short	Ltmp41-Ltmp40                   # Record length
-Ltmp40:
-	.short	4414                            # Record kind: S_LOCAL
-	.long	4100                            # TypeIndex
-	.short	1                               # Flags
-	.asciz	"argv"
-	.p2align	2
-Ltmp41:
-	.cv_def_range	 Lfunc_begin2 Ltmp4, reg_rel, 30006, 0, 8
-	.short	Ltmp43-Ltmp42                   # Record length
-Ltmp42:
-	.short	4429                            # Record kind: S_INLINESITE
-	.long	0                               # PtrParent
-	.long	0                               # PtrEnd
-	.long	4098                            # Inlinee type index
-	.cv_inline_linetable	3 1 2 Lfunc_begin2 Lfunc_end2
-	.p2align	2
-Ltmp43:
-	.short	Ltmp45-Ltmp44                   # Record length
-Ltmp44:
-	.short	4414                            # Record kind: S_LOCAL
-	.long	19                              # TypeIndex
-	.short	1                               # Flags
-	.asciz	"x"
-	.p2align	2
-Ltmp45:
-	.cv_def_range	 Ltmp3 Ltmp5, subfield_reg, 17, 0
-	.cv_def_range	 Ltmp3 Ltmp5, subfield_reg, 18, 4
-	.short	2                               # Record length
-	.short	4430                            # Record kind: S_INLINESITE_END
-	.short	2                               # Record length
-	.short	4431                            # Record kind: S_PROC_ID_END
-Ltmp33:
-	.p2align	2
-	.cv_linetable	2, _main, Lfunc_end2
-	.section	.debug$S,"dr"
-	.cv_filechecksums                       # File index to string table offset subsection
-	.cv_stringtable                         # String table
-	.long	241
-	.long	Ltmp47-Ltmp46                   # Subsection size
-Ltmp46:
-	.short	Ltmp49-Ltmp48                   # Record length
-Ltmp48:
-	.short	4428                            # Record kind: S_BUILDINFO
-	.long	4109                            # LF_BUILDINFO index
-	.p2align	2
-Ltmp49:
-Ltmp47:
-	.p2align	2
-	.section	.debug$T,"dr"
-	.p2align	2
-	.long	4                               # Debug section magic
-	# ArgList (0x1000)
-	.short	0xa                             # Record length
-	.short	0x1201                          # Record kind: LF_ARGLIST
-	.long	0x1                             # NumArgs
-	.long	0x13                            # Argument: __int64
-	# Procedure (0x1001)
-	.short	0xe                             # Record length
-	.short	0x1008                          # Record kind: LF_PROCEDURE
-	.long	0x13                            # ReturnType: __int64
-	.byte	0x0                             # CallingConvention: NearC
-	.byte	0x0                             # FunctionOptions
-	.short	0x1                             # NumParameters
-	.long	0x1000                          # ArgListType: (__int64)
-	# FuncId (0x1002)
-	.short	0xe                             # Record length
-	.short	0x1601                          # Record kind: LF_FUNC_ID
-	.long	0x0                             # ParentScope
-	.long	0x1001                          # FunctionType: __int64 (__int64)
-	.asciz	"foo"                           # Name
-	# FuncId (0x1003)
-	.short	0xe                             # Record length
-	.short	0x1601                          # Record kind: LF_FUNC_ID
-	.long	0x0                             # ParentScope
-	.long	0x1001                          # FunctionType: __int64 (__int64)
-	.asciz	"bar"                           # Name
-	# Pointer (0x1004)
-	.short	0xa                             # Record length
-	.short	0x1002                          # Record kind: LF_POINTER
-	.long	0x470                           # PointeeType: char*
-	.long	0x800a                          # Attrs: [ Type: Near32, Mode: Pointer, SizeOf: 4 ]
-	# ArgList (0x1005)
-	.short	0xe                             # Record length
-	.short	0x1201                          # Record kind: LF_ARGLIST
-	.long	0x2                             # NumArgs
-	.long	0x74                            # Argument: int
-	.long	0x1004                          # Argument: char**
-	# Procedure (0x1006)
-	.short	0xe                             # Record length
-	.short	0x1008                          # Record kind: LF_PROCEDURE
-	.long	0x74                            # ReturnType: int
-	.byte	0x0                             # CallingConvention: NearC
-	.byte	0x0                             # FunctionOptions
-	.short	0x2                             # NumParameters
-	.long	0x1005                          # ArgListType: (int, char**)
-	# FuncId (0x1007)
-	.short	0x12                            # Record length
-	.short	0x1601                          # Record kind: LF_FUNC_ID
-	.long	0x0                             # ParentScope
-	.long	0x1006                          # FunctionType: int (int, char**)
-	.asciz	"main"                          # Name
-	.byte	243
-	.byte	242
-	.byte	241
-	# StringId (0x1008)
-	.short	0xe                             # Record length
-	.short	0x1605                          # Record kind: LF_STRING_ID
-	.long	0x0                             # Id
-	.asciz	"C:\\src"                       # StringData
-	.byte	241
-	# StringId (0x1009)
-	.short	0xe                             # Record length
-	.short	0x1605                          # Record kind: LF_STRING_ID
-	.long	0x0                             # Id
-	.asciz	"a.cpp"                         # StringData
-	.byte	242
-	.byte	241


        


More information about the lldb-commits mailing list