[LLDB][NativePDB] Add local variables with no location info.
authorZequan Wu <zequanwu@google.com>
Sat, 10 Sep 2022 00:47:25 +0000 (17:47 -0700)
committerZequan Wu <zequanwu@google.com>
Mon, 12 Sep 2022 19:01:24 +0000 (12:01 -0700)
If we don't add local variables with no location info, when trying to print it,
lldb won't find it in the its parent DeclContext, which makes lldb to spend more
time to search all the way up in DeclContext hierarchy until found same name
variable or failed. Dwarf plugin also add local vars even if they don't have
location info.

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

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/inline_sites.test

index 387182c..695bb85 100644 (file)
@@ -898,7 +898,6 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
           loc_specifier_id.modi,
           loc_specifier_id.offset + loc_specifier_cvs.RecordData.size());
     }
-    result.location = DWARFExpressionList();
     for (const auto &entry : location_map) {
       DWARFExpression dwarf_expr =
           entry.data.is_dwarf ? entry.data.expr
@@ -906,7 +905,7 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo(
                                     entry.data.offset_to_location,
                                     offset_to_size, type_size, module);
 
-      result.location->AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(),
+      result.location.AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(),
                                      dwarf_expr);
     }
     return result;
index fa078ca..ee54c64 100644 (file)
@@ -103,7 +103,7 @@ struct SegmentOffsetLength {
 struct VariableInfo {
   llvm::StringRef name;
   llvm::codeview::TypeIndex type;
-  llvm::Optional<DWARFExpressionList> location;
+  DWARFExpressionList location;
   bool is_param;
 };
 
index 2781ae0..3bcebb6 100644 (file)
@@ -1729,12 +1729,14 @@ 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.location->GetSize() == 0)
-    return nullptr;
   Function *func = func_block->CalculateSymbolContextFunction();
   if (!func)
-    return VariableSP();
-  var_info.location->SetFuncFileAddress(
+    return nullptr;
+  // Use empty dwarf expr if optimized away so that it won't be filtered out
+  // when lookuping local variables in this scope.
+  if (!var_info.location.IsValid())
+    var_info.location = DWARFExpressionList(module, DWARFExpression(), nullptr);
+  var_info.location.SetFuncFileAddress(
       func->GetAddressRange().GetBaseAddress().GetFileAddress());
   CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
   CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
@@ -1756,11 +1758,10 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
   Variable::RangeList scope_ranges;
   VariableSP var_sp = std::make_shared<Variable>(
       toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
-      &block, scope_ranges, &decl, *var_info.location, 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);
-
   m_local_variables[toOpaqueUid(var_id)] = var_sp;
   return var_sp;
 }
index 6fd4186..cf82f8b 100644 (file)
@@ -71,6 +71,7 @@
 # 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 = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
 # 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
@@ -83,6 +84,7 @@
 # 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 = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
 # 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:       LineEntry: [0x000000014000101c-0x0000000140001022): /tmp/b.h:5
 # 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 = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
 # 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 = "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 = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
 # 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:         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 = "x", type = "int", valid ranges = <block>, location = <empty>, decl =
 # 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