Author: Leonard Grey Date: 2026-02-12T09:35:00-05:00 New Revision: 4c08780e7c5b7db8ab8c888fe7f97039b44f3c77
URL: https://github.com/llvm/llvm-project/commit/4c08780e7c5b7db8ab8c888fe7f97039b44f3c77 DIFF: https://github.com/llvm/llvm-project/commit/4c08780e7c5b7db8ab8c888fe7f97039b44f3c77.diff LOG: [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 https://github.com/llvm/llvm-project/blob/2e34fecf02962e4c8477ca88cc5ac9386a0f76bb/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp#L2177 but couldn't repro with local or global (emitted as `S_LDATA32` in both cases). Added: lldb/test/Shell/SymbolFile/NativePDB/local-constant.test Modified: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 7e39af7d32e2f..bed15839be1cd 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -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(); - } - - 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); + 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()); + } + 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; } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 11b982e6fc67e..4d5d9fb58bcac 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -236,14 +236,16 @@ class SymbolFileNativePDB : public SymbolFileCommon { 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); diff --git a/lldb/test/Shell/SymbolFile/NativePDB/local-constant.test b/lldb/test/Shell/SymbolFile/NativePDB/local-constant.test new file mode 100644 index 0000000000000..83d376312a295 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/local-constant.test @@ -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 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
