zequanwu updated this revision to Diff 411898.
zequanwu marked 2 inline comments as done.
zequanwu added a comment.

Remove unnecessary `location_list_base_addr` parameter from `GetDescription()` 
as it doesn't do filtering when dumping.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119963/new/

https://reviews.llvm.org/D119963

Files:
  lldb/include/lldb/Core/Address.h
  lldb/include/lldb/Expression/DWARFExpression.h
  lldb/include/lldb/Symbol/Variable.h
  lldb/source/Commands/CommandObjectTarget.cpp
  lldb/source/Commands/Options.td
  lldb/source/Core/Address.cpp
  lldb/source/Expression/DWARFExpression.cpp
  lldb/source/Symbol/Variable.cpp
  lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s
  lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
  lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s
  lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
  lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s
  lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
  lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test

Index: lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test
+++ lldb/test/Shell/SymbolFile/DWARF/x86/unused-inlined-params.test
@@ -14,35 +14,35 @@
 # at the inlined function entry.
 image lookup -v -s break_at_inlined_f_in_main
 # CHECK-LABEL: image lookup -v -s break_at_inlined_f_in_main
-# CHECK: name = "unused1", type = "void *", location = <empty>
-# CHECK: name = "used", type = "int", location = DW_OP_consts +42
-# CHECK: name = "unused2", type = "int", location = <empty>
-# CHECK: name = "partial", type = "int", location = DW_OP_reg4 RSI
-# CHECK: name = "unused3", type = "int", location = <empty>
+# CHECK: name = "unused1", type = "void *", valid ranges = <block>, location = <empty>
+# CHECK: name = "used", type = "int", valid ranges = <block>, location = [0x0000000000000011, 0x0000000000000014) -> DW_OP_consts +42
+# CHECK: name = "unused2", type = "int", valid ranges = <block>, location = <empty>
+# CHECK: name = "partial", type = "int", valid ranges = <block>, location = [0x0000000000000011, 0x0000000000000019) -> DW_OP_reg4 RSI
+# CHECK: name = "unused3", type = "int", valid ranges = <block>, location = <empty>
 
 # Show variables outsid of the live range of the 'partial' parameter
 # and verify that the output is as expected.
 image lookup -v -s break_at_inlined_f_in_main_between_printfs
 # CHECK-LABEL: image lookup -v -s break_at_inlined_f_in_main_between_printfs
-# CHECK: name = "unused1", type = "void *", location = <empty>
-# CHECK: name = "used", type = "int", location = DW_OP_reg3 RBX
-# CHECK: name = "unused2", type = "int", location = <empty>
+# CHECK: name = "unused1", type = "void *", valid ranges = <block>, location = <empty>
+# CHECK: name = "used", type = "int", valid ranges = <block>, location = [0x0000000000000014, 0x000000000000001e) -> DW_OP_reg3 RBX
+# CHECK: name = "unused2", type = "int", valid ranges = <block>, location = <empty>
 # Note: image lookup does not show variables outside of their
 #       location, so |partial| is missing here.
 # CHECK-NOT: partial
-# CHECK: name = "unused3", type = "int", location = <empty>
+# CHECK: name = "unused3", type = "int", valid ranges = <block>, location = <empty>
 
 # Check that we show parameters even if all of them are compiled away.
 image lookup -v -s  break_at_inlined_g_in_main
 # CHECK-LABEL: image lookup -v -s  break_at_inlined_g_in_main
-# CHECK: name = "unused", type = "int", location = <empty>
+# CHECK: name = "unused", type = "int", valid ranges = <block>, location = <empty>
 
 # Check that even the other inlined instance of f displays the correct
 # parameters.
 image lookup -v -s  break_at_inlined_f_in_other
 # CHECK-LABEL: image lookup -v -s  break_at_inlined_f_in_other
-# CHECK: name = "unused1", type = "void *", location = <empty>
-# CHECK: name = "used", type = "int", location = DW_OP_consts +1
-# CHECK: name = "unused2", type = "int", location = <empty>
-# CHECK: name = "partial", type = "int", location =  DW_OP_consts +2
-# CHECK: name = "unused3", type = "int", location = <empty>
+# CHECK: name = "unused1", type = "void *", valid ranges = <block>, location = <empty>
+# CHECK: name = "used", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x000000000000000b) -> DW_OP_consts +1
+# CHECK: name = "unused2", type = "int", valid ranges = <block>, location = <empty>
+# CHECK: name = "partial", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x0000000000000006) -> DW_OP_consts +2
+# CHECK: name = "unused3", type = "int", valid ranges = <block>, location = <empty>
Index: lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/dwp.s
@@ -12,7 +12,7 @@
 # CHECK-LABEL: image lookup -v -n F1
 # CHECK: CompileUnit: id = {0x00000001}, file = "1.c", language = "<not loaded>"
 # CHECK: Function: {{.*}}, name = "F1", range = [0x0000000000000001-0x0000000000000002)
-# CHECK: Variable: {{.*}}, name = "x", type = "int", location = DW_OP_reg1 RDX
+# CHECK: Variable: {{.*}}, name = "x", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x0000000000000002) -> DW_OP_reg1 RDX
 
 # SYMBOLS:      Compile units:
 # SYMBOLS-NEXT: CompileUnit{0x00000000}, language = "<not loaded>", file = '0.c'
Index: lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwp.s
@@ -6,8 +6,8 @@
 # RUN: %lldb %t -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s
 
 # CHECK-LABEL: image lookup -v -s lookup_loclists
-# CHECK: Variable: id = {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX,
-# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", location = DW_OP_reg1 RDX,
+# CHECK: Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX,
+# CHECK: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = [0x0000000000000002, 0x0000000000000004) -> DW_OP_reg1 RDX,
 
 ## This part is kept in both the main and the dwp file to be able to reference the offsets.
 loclists:
Index: lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/debug_loclists-dwo.s
@@ -3,8 +3,8 @@
 # RUN: %lldb debug_loclists-dwo.o -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s
 
 # CHECK-LABEL: image lookup -v -s lookup_loclists
-# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX,
-# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = DW_OP_reg1 RDX,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX,
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = [0x0000000000000002, 0x0000000000000004) -> DW_OP_reg1 RDX,
 
 loclists:
         nop
Index: lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc_and_loclists.s
@@ -7,10 +7,10 @@
 
 
 # CHECK-LABEL: image lookup -v -s loc
-# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg5 RDI,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI,
 
 # CHECK-LABEL: image lookup -v -s loclists
-# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = DW_OP_reg0 RAX,
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x0000000000000002) -> DW_OP_reg0 RAX,
 
 
 loc:
Index: lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/debug_loc.s
@@ -8,18 +8,30 @@
 # RUN: %lldb %t -o "image lookup -v -a 0" -o "image lookup -v -a 2" \
 # RUN:   -o "image dump symfile" -o exit | FileCheck %s
 
+# RUN: %lldb %t -o "image lookup -v -a 0 -show-variable-ranges" -o \
+# RUN: "image lookup -v -a 2 -show-variable-ranges" \
+# RUN: -o exit | FileCheck %s --check-prefix=ALL-RANGES
+
 # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s --defsym LOCLISTS=0 > %t
 # RUN: %lldb %t -o "image lookup -v -a 0" -o "image lookup -v -a 2" \
 # RUN:   -o "image dump symfile" -o exit | FileCheck %s --check-prefix=CHECK --check-prefix=LOCLISTS
 
+# ALL-RANGES-LABEL: image lookup -v -a 0 -show-variable-ranges
+# ALL-RANGES: Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX
+# ALL-RANGES: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>
+# ALL-RANGES-LABEL: image lookup -v -a 2 -show-variable-ranges
+# ALL-RANGES:  Variable: id = {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI, [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX
+# ALL-RANGES: Variable: id = {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>
+# ALL-RANGES: Variable: id = {{.*}}, name = "x3", type = "int", valid ranges = <block>, location = [0x0000000000000002, 0x0000000000000003) -> DW_OP_reg1 RDX
+
 # CHECK-LABEL: image lookup -v -a 0
-# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg5 RDI,
-# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = <empty>,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000001) -> DW_OP_reg5 RDI
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>,
 
 # CHECK-LABEL: image lookup -v -a 2
-# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX,
-# CHECK: Variable: {{.*}}, name = "x1", type = "int", location = <empty>,
-# CHECK: Variable: {{.*}}, name = "x3", type = "int", location = DW_OP_reg1 RDX,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000001, 0x0000000000000006) -> DW_OP_reg0 RAX
+# CHECK: Variable: {{.*}}, name = "x1", type = "int", valid ranges = <block>, location = <empty>,
+# CHECK: Variable: {{.*}}, name = "x3", type = "int", valid ranges = <block>, location = [0x0000000000000002, 0x0000000000000003) -> DW_OP_reg1 RDX
 
 # CHECK-LABEL: image dump symfile
 # CHECK: CompileUnit{0x00000000}
Index: lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s
===================================================================
--- lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_loclists_base.s
@@ -2,7 +2,7 @@
 # RUN: %lldb %t -o "image lookup -v -s lookup_loclists" -o exit | FileCheck %s
 
 # CHECK-LABEL: image lookup -v -s lookup_loclists
-# CHECK: Variable: {{.*}}, name = "x0", type = "int", location = DW_OP_reg0 RAX,
+# CHECK: Variable: {{.*}}, name = "x0", type = "int", valid ranges = <block>, location = [0x0000000000000000, 0x0000000000000003) -> DW_OP_reg0 RAX,
 # CHECK-NOT: Variable:
 
 loclists:
Index: lldb/source/Symbol/Variable.cpp
===================================================================
--- lldb/source/Symbol/Variable.cpp
+++ lldb/source/Symbol/Variable.cpp
@@ -147,23 +147,13 @@
 
   if (m_location.IsValid()) {
     s->PutCString(", location = ");
-    lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
-    if (m_location.IsLocationList()) {
-      SymbolContext variable_sc;
-      m_owner_scope->CalculateSymbolContext(&variable_sc);
-      if (variable_sc.function)
-        loclist_base_addr = variable_sc.function->GetAddressRange()
-                                .GetBaseAddress()
-                                .GetFileAddress();
-    }
     ABISP abi;
     if (m_owner_scope) {
       ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
       if (module_sp)
         abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
     }
-    m_location.GetDescription(s, lldb::eDescriptionLevelBrief,
-                              loclist_base_addr, abi.get());
+    m_location.GetDescription(s, lldb::eDescriptionLevelBrief, abi.get());
   }
 
   if (m_external)
@@ -445,36 +435,27 @@
   return error;
 }
 
-bool Variable::DumpLocationForAddress(Stream *s, const Address &address) {
-  // Be sure to resolve the address to section offset prior to calling this
-  // function.
-  if (address.IsSectionOffset()) {
-    SymbolContext sc;
-    CalculateSymbolContext(&sc);
-    if (sc.module_sp == address.GetModule()) {
-      ABISP abi;
-      if (m_owner_scope) {
-        ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
-        if (module_sp)
-          abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
-      }
+bool Variable::DumpLocations(Stream *s, const Address &address) {
+  // When given invalid address, it dumps all locations. Otherwise it only dumps
+  // the location that contains this address.
+  SymbolContext sc;
+  CalculateSymbolContext(&sc);
+  ABISP abi;
+  if (m_owner_scope) {
+    ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule());
+    if (module_sp)
+      abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
+  }
 
-      const addr_t file_addr = address.GetFileAddress();
-      if (sc.function) {
-        if (sc.function->GetAddressRange().ContainsFileAddress(address)) {
-          addr_t loclist_base_file_addr =
-              sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
-          if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
-            return false;
-          return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief,
-                                                   loclist_base_file_addr,
-                                                   file_addr, abi.get());
-        }
-      }
-      return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief,
-                                               LLDB_INVALID_ADDRESS, file_addr,
-                                               abi.get());
-    }
+  const addr_t file_addr = address.GetFileAddress();
+  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;
 }
Index: lldb/source/Expression/DWARFExpression.cpp
===================================================================
--- lldb/source/Expression/DWARFExpression.cpp
+++ lldb/source/Expression/DWARFExpression.cpp
@@ -129,7 +129,6 @@
 }
 
 void DWARFExpression::GetDescription(Stream *s, lldb::DescriptionLevel level,
-                                     addr_t location_list_base_addr,
                                      ABI *abi) const {
   if (IsLocationList()) {
     // We have a location list
@@ -2673,14 +2672,50 @@
   return DataExtractor(buffer_sp, byte_order, addr_size);
 }
 
-llvm::Optional<DataExtractor>
-DWARFExpression::GetLocationExpression(addr_t load_function_start,
-                                       addr_t addr) const {
+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);
-  llvm::Optional<DataExtractor> result;
+
   uint64_t offset = 0;
   auto lookup_addr =
       [&](uint32_t index) -> llvm::Optional<llvm::object::SectionedAddress> {
@@ -2700,19 +2735,32 @@
       addr_t slide = load_function_start - m_loclist_addresses->func_file_addr;
       loc->Range->LowPC += slide;
       loc->Range->HighPC += slide;
-
-      if (loc->Range->LowPC <= addr && addr < loc->Range->HighPC)
-        result = ToDataExtractor(*loc, m_data.GetByteOrder(),
-                                 m_data.GetAddressByteSize());
     }
-    return !result;
+    return callback(*loc);
   };
   llvm::Error E = loctable_up->visitAbsoluteLocationList(
       offset, llvm::object::SectionedAddress{m_loclist_addresses->cu_file_addr},
       lookup_addr, process_list);
-  if (E)
+  if (E) {
     LLDB_LOG_ERROR(log, std::move(E), "{0}");
-  return result;
+    return false;
+  }
+  return true;
+}
+
+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,
@@ -2738,7 +2786,8 @@
     addr_t pc = frame.GetFrameCodeAddress().GetLoadAddress(
         frame.CalculateTarget().get());
 
-    if (llvm::Optional<DataExtractor> expr = GetLocationExpression(load_function_start, pc))
+    if (llvm::Optional<DataExtractor> expr =
+            GetLocationExpression(load_function_start, pc))
       opcodes = std::move(*expr);
     else
       return false;
Index: lldb/source/Core/Address.cpp
===================================================================
--- lldb/source/Core/Address.cpp
+++ lldb/source/Core/Address.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/Variable.h"
 #include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ABI.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/Process.h"
@@ -403,7 +404,8 @@
 }
 
 bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
-                   DumpStyle fallback_style, uint32_t addr_size) const {
+                   DumpStyle fallback_style, uint32_t addr_size,
+                   bool all_ranges) const {
   // If the section was nullptr, only load address is going to work unless we
   // are trying to deref a pointer
   SectionSP section_sp(GetSection());
@@ -720,27 +722,42 @@
           bool get_parent_variables = true;
           bool stop_if_block_is_inlined_function = false;
           VariableList variable_list;
-          sc.block->AppendVariables(can_create, get_parent_variables,
-                                    stop_if_block_is_inlined_function,
-                                    [](Variable *) { return true; },
-                                    &variable_list);
-
+          addr_t file_addr = GetFileAddress();
+          sc.block->AppendVariables(
+              can_create, get_parent_variables,
+              stop_if_block_is_inlined_function,
+              [&](Variable *var) {
+                return var && var->LocationIsValidForAddress(*this);
+              },
+              &variable_list);
+          ABISP abi =
+              ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture());
           for (const VariableSP &var_sp : variable_list) {
-            if (var_sp && var_sp->LocationIsValidForAddress(*this)) {
-              s->Indent();
-              s->Printf("   Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
-                        var_sp->GetID(), var_sp->GetName().GetCString());
-              Type *type = var_sp->GetType();
-              if (type)
-                s->Printf(", type = \"%s\"", type->GetName().GetCString());
-              else
-                s->PutCString(", type = <unknown>");
-              s->PutCString(", location = ");
-              var_sp->DumpLocationForAddress(s, *this);
-              s->PutCString(", decl = ");
-              var_sp->GetDeclaration().DumpStopContext(s, false);
-              s->EOL();
-            }
+            s->Indent();
+            s->Printf("   Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
+                      var_sp->GetID(), var_sp->GetName().GetCString());
+            Type *type = var_sp->GetType();
+            if (type)
+              s->Printf(", type = \"%s\"", type->GetName().GetCString());
+            else
+              s->PutCString(", type = <unknown>");
+            s->PutCString(", valid ranges = ");
+            if (var_sp->GetScopeRange().IsEmpty())
+              s->PutCString("<block>");
+            else if (all_ranges) {
+              for (auto range : var_sp->GetScopeRange())
+                DumpAddressRange(s->AsRawOstream(), range.GetRangeBase(),
+                                 range.GetRangeEnd(), addr_size);
+            } else if (auto *range =
+                           var_sp->GetScopeRange().FindEntryThatContains(
+                               file_addr))
+              DumpAddressRange(s->AsRawOstream(), range->GetRangeBase(),
+                               range->GetRangeEnd(), addr_size);
+            s->PutCString(", location = ");
+            var_sp->DumpLocations(s, all_ranges ? LLDB_INVALID_ADDRESS : *this);
+            s->PutCString(", decl = ");
+            var_sp->GetDeclaration().DumpStopContext(s, false);
+            s->EOL();
           }
         }
       }
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -957,6 +957,9 @@
   def target_modules_lookup_type : Option<"type", "t">, Group<6>, Arg<"Name">,
     Required, Desc<"Lookup a type by name in the debug symbols in one or more "
     "target modules.">;
+  def target_modules_lookup_variables_ranges : Option<"show-variable-ranges", 
+    "\\x01">, GroupRange<1, 6>, Desc<"Dump valid ranges of variables (must be "
+    "used in conjunction with --verbose">;
   def target_modules_lookup_verbose : Option<"verbose", "v">,
     Desc<"Enable verbose lookup information.">;
   def target_modules_lookup_all : Option<"all", "A">, Desc<"Print all matches, "
Index: lldb/source/Commands/CommandObjectTarget.cpp
===================================================================
--- lldb/source/Commands/CommandObjectTarget.cpp
+++ lldb/source/Commands/CommandObjectTarget.cpp
@@ -50,6 +50,7 @@
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/State.h"
 #include "lldb/Utility/Timer.h"
+#include "lldb/lldb-private-enumerations.h"
 
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/FileSystem.h"
@@ -1429,7 +1430,8 @@
 }
 
 static void DumpAddress(ExecutionContextScope *exe_scope,
-                        const Address &so_addr, bool verbose, Stream &strm) {
+                        const Address &so_addr, bool verbose, bool all_ranges,
+                        Stream &strm) {
   strm.IndentMore();
   strm.Indent("    Address: ");
   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
@@ -1444,7 +1446,8 @@
   // Print out detailed address information when verbose is enabled
   if (verbose) {
     strm.EOL();
-    so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
+    so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
+                 Address::DumpStyleInvalid, UINT32_MAX, all_ranges);
   }
   strm.IndentLess();
 }
@@ -1452,7 +1455,7 @@
 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
                                   Module *module, uint32_t resolve_mask,
                                   lldb::addr_t raw_addr, lldb::addr_t offset,
-                                  bool verbose) {
+                                  bool verbose, bool all_ranges) {
   if (module) {
     lldb::addr_t addr = raw_addr - offset;
     Address so_addr;
@@ -1470,7 +1473,7 @@
 
     ExecutionContextScope *exe_scope =
         interpreter.GetExecutionContext().GetBestExecutionContextScope();
-    DumpAddress(exe_scope, so_addr, verbose, strm);
+    DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
     //        strm.IndentMore();
     //        strm.Indent ("    Address: ");
     //        so_addr.Dump (&strm, exe_scope,
@@ -1502,7 +1505,7 @@
 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
                                      Stream &strm, Module *module,
                                      const char *name, bool name_is_regex,
-                                     bool verbose) {
+                                     bool verbose, bool all_ranges) {
   if (!module)
     return 0;
 
@@ -1535,7 +1538,7 @@
       if (symbol && symbol->ValueIsAddress()) {
         DumpAddress(
             interpreter.GetExecutionContext().GetBestExecutionContextScope(),
-            symbol->GetAddressRef(), verbose, strm);
+            symbol->GetAddressRef(), verbose, all_ranges, strm);
       }
     }
     strm.IndentLess();
@@ -1545,7 +1548,7 @@
 
 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
                                   Stream &strm, SymbolContextList &sc_list,
-                                  bool verbose) {
+                                  bool verbose, bool all_ranges) {
   strm.IndentMore();
 
   const uint32_t num_matches = sc_list.GetSize();
@@ -1557,7 +1560,7 @@
 
       sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
 
-      DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
+      DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm);
     }
   }
   strm.IndentLess();
@@ -1567,7 +1570,7 @@
                                      Stream &strm, Module *module,
                                      const char *name, bool name_is_regex,
                                      const ModuleFunctionSearchOptions &options,
-                                     bool verbose) {
+                                     bool verbose, bool all_ranges) {
   if (module && name && name[0]) {
     SymbolContextList sc_list;
     size_t num_matches = 0;
@@ -1588,7 +1591,7 @@
       strm.PutCString(":\n");
       DumpSymbolContextList(
           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
-          strm, sc_list, verbose);
+          strm, sc_list, verbose, all_ranges);
     }
     return num_matches;
   }
@@ -1693,7 +1696,7 @@
                                           Stream &strm, Module *module,
                                           const FileSpec &file_spec,
                                           uint32_t line, bool check_inlines,
-                                          bool verbose) {
+                                          bool verbose, bool all_ranges) {
   if (module && file_spec) {
     SymbolContextList sc_list;
     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
@@ -1710,7 +1713,7 @@
       strm.PutCString(":\n");
       DumpSymbolContextList(
           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
-          strm, sc_list, verbose);
+          strm, sc_list, verbose, all_ranges);
       return num_matches;
     }
   }
@@ -3598,6 +3601,10 @@
       case 'r':
         m_use_regex = true;
         break;
+
+      case '\x01':
+        m_all_ranges = true;
+        break;
       default:
         llvm_unreachable("Unimplemented option");
       }
@@ -3614,6 +3621,7 @@
       m_line_number = 0;
       m_use_regex = false;
       m_include_inlines = true;
+      m_all_ranges = false;
       m_verbose = false;
       m_print_all = false;
     }
@@ -3632,6 +3640,7 @@
     bool m_use_regex;       // Name lookups in m_str are regular expressions.
     bool m_include_inlines; // Check for inline entries when looking up by
                             // file/line.
+    bool m_all_ranges;      // Print all ranges or single range.
     bool m_verbose;         // Enable verbose lookup info
     bool m_print_all; // Print all matches, even in cases where there's a best
                       // match.
@@ -3714,7 +3723,8 @@
                     (m_options.m_verbose
                          ? static_cast<int>(eSymbolContextVariable)
                          : 0),
-                m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
+                m_options.m_addr, m_options.m_offset, m_options.m_verbose,
+                m_options.m_all_ranges)) {
           result.SetStatus(eReturnStatusSuccessFinishResult);
           return true;
         }
@@ -3725,7 +3735,8 @@
       if (!m_options.m_str.empty()) {
         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
                                  module, m_options.m_str.c_str(),
-                                 m_options.m_use_regex, m_options.m_verbose)) {
+                                 m_options.m_use_regex, m_options.m_verbose,
+                                 m_options.m_all_ranges)) {
           result.SetStatus(eReturnStatusSuccessFinishResult);
           return true;
         }
@@ -3737,7 +3748,8 @@
         if (LookupFileAndLineInModule(
                 m_interpreter, result.GetOutputStream(), module,
                 m_options.m_file, m_options.m_line_number,
-                m_options.m_include_inlines, m_options.m_verbose)) {
+                m_options.m_include_inlines, m_options.m_verbose,
+                m_options.m_all_ranges)) {
           result.SetStatus(eReturnStatusSuccessFinishResult);
           return true;
         }
@@ -3755,7 +3767,8 @@
         if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
                                    module, m_options.m_str.c_str(),
                                    m_options.m_use_regex, function_options,
-                                   m_options.m_verbose)) {
+                                   m_options.m_verbose,
+                                   m_options.m_all_ranges)) {
           result.SetStatus(eReturnStatusSuccessFinishResult);
           return true;
         }
Index: lldb/include/lldb/Symbol/Variable.h
===================================================================
--- lldb/include/lldb/Symbol/Variable.h
+++ lldb/include/lldb/Symbol/Variable.h
@@ -77,7 +77,7 @@
 
   const DWARFExpression &LocationExpression() const { return m_location; }
 
-  bool DumpLocationForAddress(Stream *s, const Address &address);
+  bool DumpLocations(Stream *s, const Address &address);
 
   size_t MemorySize() const;
 
Index: lldb/include/lldb/Expression/DWARFExpression.h
===================================================================
--- lldb/include/lldb/Expression/DWARFExpression.h
+++ lldb/include/lldb/Expression/DWARFExpression.h
@@ -15,6 +15,7 @@
 #include "lldb/Utility/Scalar.h"
 #include "lldb/Utility/Status.h"
 #include "lldb/lldb-private.h"
+#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
 #include <functional>
 
 class DWARFUnit;
@@ -55,18 +56,10 @@
   /// \param[in] level
   ///     The level of verbosity to use.
   ///
-  /// \param[in] location_list_base_addr
-  ///     If this is a location list based expression, this is the
-  ///     address of the object that owns it. NOTE: this value is
-  ///     different from the DWARF version of the location list base
-  ///     address which is compile unit relative. This base address
-  ///     is the address of the object that owns the location list.
-  ///
   /// \param[in] abi
   ///     An optional ABI plug-in that can be used to resolve register
   ///     names.
-  void GetDescription(Stream *s, lldb::DescriptionLevel level,
-                      lldb::addr_t location_list_base_addr, ABI *abi) const;
+  void GetDescription(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
 
   /// Return true if the location expression contains data
   bool IsValid() const;
@@ -217,6 +210,13 @@
                               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);
 
   llvm::Optional<DataExtractor>
Index: lldb/include/lldb/Core/Address.h
===================================================================
--- lldb/include/lldb/Core/Address.h
+++ lldb/include/lldb/Core/Address.h
@@ -238,7 +238,8 @@
   /// \see Address::DumpStyle
   bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
             DumpStyle fallback_style = DumpStyleInvalid,
-            uint32_t addr_byte_size = UINT32_MAX) const;
+            uint32_t addr_byte_size = UINT32_MAX,
+            bool all_ranges = false) const;
 
   AddressClass GetAddressClass() const;
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to