[LLDB][NativePDB] Add local constant support (#180612)
This is mostly to support Swift `let`, but I found a way to get MSVC to
emit a local `S_CONSTANT` (see test).
I saw the note about `MakeConstantLocalExpression` at
2e34fecf02/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (L2177)
but couldn't repro with local or global (emitted as `S_LDATA32` in both
cases).
This commit is contained in:
parent
6da74dded0
commit
4c08780e7c
@ -2196,32 +2196,54 @@ SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
|
||||
|
||||
VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
PdbCompilandSymId var_id,
|
||||
bool is_param) {
|
||||
bool is_param,
|
||||
bool is_constant) {
|
||||
ModuleSP module = GetObjectFile()->GetModule();
|
||||
Block *block = GetOrCreateBlock(scope_id);
|
||||
if (!block)
|
||||
return nullptr;
|
||||
|
||||
// Get function block.
|
||||
Block *func_block = block;
|
||||
while (func_block->GetParent()) {
|
||||
func_block = func_block->GetParent();
|
||||
CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
|
||||
if (!cii)
|
||||
return nullptr;
|
||||
CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
|
||||
|
||||
VariableInfo var_info;
|
||||
bool location_is_constant_data = is_constant;
|
||||
|
||||
if (is_constant) {
|
||||
CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(var_id.offset);
|
||||
assert(sym.kind() == S_CONSTANT);
|
||||
ConstantSym constant(sym.kind());
|
||||
cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant));
|
||||
|
||||
var_info.name = constant.Name;
|
||||
var_info.type = constant.Type;
|
||||
var_info.location = DWARFExpressionList(
|
||||
module,
|
||||
MakeConstantLocationExpression(constant.Type, m_index->tpi(),
|
||||
constant.Value, module),
|
||||
nullptr);
|
||||
} else {
|
||||
// Get function block.
|
||||
Block *func_block = block;
|
||||
while (func_block->GetParent())
|
||||
func_block = func_block->GetParent();
|
||||
|
||||
Address addr;
|
||||
func_block->GetStartAddress(addr);
|
||||
var_info = GetVariableLocationInfo(*m_index, var_id, *func_block, module);
|
||||
Function *func = func_block->CalculateSymbolContextFunction();
|
||||
if (!func)
|
||||
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->GetAddress().GetFileAddress());
|
||||
}
|
||||
|
||||
Address addr;
|
||||
func_block->GetStartAddress(addr);
|
||||
VariableInfo var_info =
|
||||
GetVariableLocationInfo(*m_index, var_id, *func_block, module);
|
||||
Function *func = func_block->CalculateSymbolContextFunction();
|
||||
if (!func)
|
||||
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->GetAddress().GetFileAddress());
|
||||
CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
|
||||
CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
|
||||
TypeSP type_sp = GetOrCreateType(var_info.type);
|
||||
if (!type_sp)
|
||||
return nullptr;
|
||||
@ -2235,7 +2257,6 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
|
||||
bool external = false;
|
||||
bool artificial = false;
|
||||
bool location_is_constant_data = false;
|
||||
bool static_member = false;
|
||||
Variable::RangeList scope_ranges;
|
||||
VariableSP var_sp = std::make_shared<Variable>(
|
||||
@ -2256,13 +2277,15 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
return var_sp;
|
||||
}
|
||||
|
||||
VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(
|
||||
PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
|
||||
VariableSP
|
||||
SymbolFileNativePDB::GetOrCreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
PdbCompilandSymId var_id,
|
||||
bool is_param, bool is_constant) {
|
||||
auto iter = m_local_variables.find(toOpaqueUid(var_id));
|
||||
if (iter != m_local_variables.end())
|
||||
return iter->second;
|
||||
|
||||
return CreateLocalVariable(scope_id, var_id, is_param);
|
||||
return CreateLocalVariable(scope_id, var_id, is_param, is_constant);
|
||||
}
|
||||
|
||||
TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
|
||||
@ -2390,6 +2413,13 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
|
||||
if (variable)
|
||||
variables->AddVariableIfUnique(variable);
|
||||
break;
|
||||
case S_CONSTANT:
|
||||
variable = GetOrCreateLocalVariable(block_id, child_sym_id,
|
||||
/*is_param=*/false,
|
||||
/*is_constant=*/true);
|
||||
if (variable)
|
||||
variables->AddVariableIfUnique(variable);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -236,14 +236,16 @@ private:
|
||||
Block *GetOrCreateBlock(PdbCompilandSymId block_id);
|
||||
lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
PdbCompilandSymId var_id,
|
||||
bool is_param);
|
||||
bool is_param,
|
||||
bool is_constant = false);
|
||||
lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id);
|
||||
|
||||
lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id,
|
||||
CompileUnit &comp_unit);
|
||||
Block *CreateBlock(PdbCompilandSymId block_id);
|
||||
lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id,
|
||||
PdbCompilandSymId var_id, bool is_param);
|
||||
PdbCompilandSymId var_id, bool is_param,
|
||||
bool is_constant = false);
|
||||
lldb::TypeSP CreateTypedef(PdbGlobalSymId id);
|
||||
lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci);
|
||||
lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct);
|
||||
|
||||
24
lldb/test/Shell/SymbolFile/NativePDB/local-constant.test
Normal file
24
lldb/test/Shell/SymbolFile/NativePDB/local-constant.test
Normal file
@ -0,0 +1,24 @@
|
||||
# REQUIRES: msvc
|
||||
|
||||
# Test that we can display local S_CONSTANT records.
|
||||
# MSVC emits S_CONSTANT for static const locals; clang-cl does not.
|
||||
# RUN: split-file %s %t
|
||||
# RUN: %build --compiler=msvc --nodefaultlib -o %t.exe -- %t/main.cpp
|
||||
# RUN: %lldb -f %t.exe -s %t/commands.input 2>&1 | FileCheck %s
|
||||
|
||||
#--- main.cpp
|
||||
|
||||
int main() {
|
||||
static const int kConstant = 42;
|
||||
return kConstant;
|
||||
}
|
||||
|
||||
#--- commands.input
|
||||
|
||||
settings set stop-line-count-after 0
|
||||
break set -n main
|
||||
run
|
||||
frame variable
|
||||
quit
|
||||
|
||||
# CHECK: (const int) {{.*}}kConstant = 42
|
||||
Loading…
x
Reference in New Issue
Block a user