[Lldb-commits] [lldb] [lldb] Refactor DIL to take and store the context in `ExecutionContext` (PR #225849)
Ilia Kuklin via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 24 07:24:57 PDT 2026
https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/225849
>From f96f288742b373d209c310d74f11809a9a85363d Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Fri, 4 Sep 2026 22:26:37 +0500
Subject: [PATCH 1/2] [lldb] Refactor DIL to take and store context in
ExecutionContext
---
lldb/include/lldb/ValueObject/DILEval.h | 29 +--
lldb/include/lldb/ValueObject/DILParser.h | 16 +-
lldb/source/Target/StackFrame.cpp | 9 +-
lldb/source/ValueObject/DILEval.cpp | 229 ++++++++++++----------
lldb/source/ValueObject/DILParser.cpp | 32 ++-
5 files changed, 165 insertions(+), 150 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 4eccfd9ff0bac..4c7405a38f675 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -9,6 +9,7 @@
#ifndef LLDB_VALUEOBJECT_DILEVAL_H
#define LLDB_VALUEOBJECT_DILEVAL_H
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILParser.h"
#include "llvm/ADT/StringRef.h"
@@ -21,8 +22,7 @@ namespace lldb_private::dil {
/// Given the name of a persistent identifier (i.e., one that starts with a $),
/// find the ValueObject for that name (if it exists).
lldb::ValueObjectSP LookupPersistentIdentifier(llvm::StringRef name_ref,
- StackFrame &stack_frame,
- lldb::TargetSP target_sp,
+ ExecutionContext &exe_ctx,
lldb::LanguageType language);
/// Given the name of an identifier (variable name, member name, type name,
@@ -31,7 +31,7 @@ lldb::ValueObjectSP LookupPersistentIdentifier(llvm::StringRef name_ref,
/// the relevant information about that object (for DIL parsing and
/// evaluating).
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
- StackFrame &stack_frame,
+ ExecutionContext &exe_ctx,
lldb::DynamicValueType use_dynamic);
/// Given the name of an identifier, check to see if it matches the name of a
@@ -39,20 +39,18 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
/// create and return an IdentifierInfo object containing all the relevant
/// information about it.
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
- StackFrame &stack_frame,
- lldb::TargetSP target_sp,
+ ExecutionContext &exe_ctx,
lldb::DynamicValueType use_dynamic);
/// Given the name of an identifier, attempt to find an enumeration value.
/// If found, return a ValueObject with a const scalar value of the enum.
lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
- ExecutionContextScope &ctx_scope);
+ ExecutionContext &exe_ctx);
class Interpreter : Visitor {
public:
- Interpreter(lldb::TargetSP target, llvm::StringRef expr,
- StackFrame &stack_frame, lldb::DynamicValueType use_dynamic,
- uint32_t options);
+ Interpreter(ExecutionContext &exe_ctx, llvm::StringRef expr,
+ lldb::DynamicValueType use_dynamic, uint32_t options);
/// Evaluate an ASTNode tree.
/// \returns A non-null lldb::ValueObjectSP or an Error.
@@ -87,6 +85,12 @@ class Interpreter : Visitor {
Visit(const ConditionalNode &node) override;
llvm::Expected<lldb::ValueObjectSP> Visit(const SizeOfNode &node) override;
+ /// Retrieve the LanguageType from the compile unit of the current frame.
+ llvm::Expected<lldb::LanguageType> GetSourceLanguageFromCU();
+
+ /// Retrieve the TypeSystem from the compile unit of the current frame.
+ llvm::Expected<lldb::TypeSystemSP> GetTypeSystemFromCU();
+
/// Perform usual unary conversions on a value. At the moment this
/// includes array-to-pointer and integral promotion for eligible types.
llvm::Expected<lldb::ValueObjectSP>
@@ -151,7 +155,7 @@ class Interpreter : Visitor {
lldb::ValueObjectSP rhs, uint32_t location);
llvm::Expected<lldb::ValueObjectSP> EvaluateLogical(const BinaryOpNode &node);
llvm::Expected<CompilerType>
- PickIntegerType(lldb::TypeSystemSP type_system, ExecutionContextScope &ctx,
+ PickIntegerType(lldb::TypeSystemSP type_system, ExecutionContext &ext_ctx,
const IntegerLiteralNode &literal);
llvm::Expected<lldb::ValueObjectSP>
@@ -174,11 +178,10 @@ class Interpreter : Visitor {
CompilerType target_type,
int location);
- // Used by the interpreter to create objects, perform casts, etc.
- lldb::TargetSP m_target;
+ // Interpreter doesn't own the evaluation context.
+ ExecutionContext &m_exe_ctx;
llvm::StringRef m_expr;
lldb::ValueObjectSP m_scope;
- StackFrame &m_stack_frame;
lldb::DynamicValueType m_use_dynamic;
bool m_use_synthetic;
bool m_check_ptr_vs_member;
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 50791fe436a7c..31f1c08905b5e 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -10,6 +10,7 @@
#define LLDB_VALUEOBJECT_DILPARSER_H
#include "lldb/Host/common/DiagnosticsRendering.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/DILAST.h"
@@ -36,7 +37,7 @@ enum class ErrorCode : unsigned char {
};
CompilerType ResolveTypeByName(const std::string &name,
- ExecutionContextScope &ctx_scope);
+ ExecutionContext &exe_ctx);
// The following is modeled on class OptionParseError.
class DILDiagnosticError
@@ -70,16 +71,15 @@ class DILParser {
/// Parse the lexed tokens.
/// \returns An ASTNode tree or an error.
static llvm::Expected<ASTNodeUP>
- Parse(llvm::StringRef dil_input_expr, DILLexer lexer, StackFrame &stack_frame,
- lldb::DynamicValueType use_dynamic, lldb::DILMode mode);
+ Parse(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr,
+ DILLexer lexer, lldb::DynamicValueType use_dynamic, lldb::DILMode mode);
~DILParser() = default;
private:
- explicit DILParser(llvm::StringRef dil_input_expr, DILLexer lexer,
- StackFrame &stack_frame,
- lldb::DynamicValueType use_dynamic, llvm::Error &error,
- lldb::DILMode mode);
+ explicit DILParser(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr,
+ DILLexer lexer, lldb::DynamicValueType use_dynamic,
+ llvm::Error &error, lldb::DILMode mode);
ASTNodeUP Run();
@@ -137,7 +137,7 @@ class DILParser {
// Parser doesn't own the evaluation context. The produced AST may depend on
// it (for example, for source locations), so it's expected that expression
// context will outlive the parser.
- StackFrame &m_stack_frame;
+ ExecutionContext &m_exe_ctx;
llvm::StringRef m_input_expr;
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 81fdcd44be94a..5391caebee01b 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -557,16 +557,17 @@ ValueObjectSP StackFrame::DILGetValueForVariableExpressionPath(
}
// Parse the expression.
- auto tree_or_error = dil::DILParser::Parse(var_expr, std::move(*lex_or_err),
- *this, use_dynamic, mode);
+ ExecutionContext exe_ctx;
+ CalculateExecutionContext(exe_ctx);
+ auto tree_or_error = dil::DILParser::Parse(
+ exe_ctx, var_expr, std::move(*lex_or_err), use_dynamic, mode);
if (!tree_or_error) {
error = Status::FromError(tree_or_error.takeError());
return ValueObjectConstResult::Create(nullptr, error.Clone());
}
// Evaluate the parsed expression.
- lldb::TargetSP target = this->CalculateTarget();
- dil::Interpreter interpreter(target, var_expr, *this, use_dynamic, options);
+ dil::Interpreter interpreter(exe_ctx, var_expr, use_dynamic, options);
auto valobj_or_error = interpreter.EvaluateTree(*tree_or_error);
if (!valobj_or_error) {
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index 81c5e383312fe..b2beb710cb579 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -12,8 +12,8 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILParser.h"
@@ -35,37 +35,44 @@ static CompilerType GetBasicType(lldb::TypeSystemSP type_system,
}
static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj,
- ExecutionContextScope &ctx,
+ ExecutionContext &exe_ctx,
llvm::StringRef name) {
uint64_t addr = valobj.GetLoadAddress();
- ExecutionContext exe_ctx;
- ctx.CalculateExecutionContext(exe_ctx);
return ValueObject::CreateValueObjectFromAddress(
name, addr, exe_ctx,
- valobj.GetCompilerType().GetArrayElementType(&ctx).GetPointerType(),
+ valobj.GetCompilerType()
+ .GetArrayElementType(exe_ctx.GetBestExecutionContextScope())
+ .GetPointerType(),
/* do_deref */ false);
}
-static llvm::Expected<lldb::LanguageType>
-GetSourceLanguageFromCU(StackFrame &ctx) {
+llvm::Expected<lldb::LanguageType> Interpreter::GetSourceLanguageFromCU() {
+ auto frame_sp = m_exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return llvm::createStringError("no stack frame in execution context");
+
SymbolContext symbol_context =
- ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
+ frame_sp->GetSymbolContext(lldb::eSymbolContextCompUnit);
if (!symbol_context.comp_unit)
- return llvm::createStringErrorV("no compile unit for frame: {}",
- ctx.GetFunctionName());
+ return llvm::createStringErrorV("no compile unit for frame: {0}",
+ frame_sp->GetFunctionName());
return symbol_context.comp_unit->GetLanguage();
}
-static llvm::Expected<lldb::TypeSystemSP> GetTypeSystemFromCU(StackFrame &ctx) {
+llvm::Expected<lldb::TypeSystemSP> Interpreter::GetTypeSystemFromCU() {
+ auto frame_sp = m_exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return llvm::createStringError("no stack frame in execution context");
+
SymbolContext symbol_context =
- ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
+ frame_sp->GetSymbolContext(lldb::eSymbolContextCompUnit);
if (!symbol_context.comp_unit)
- return llvm::createStringErrorV("no compile unit for frame: {}",
- ctx.GetFunctionName());
+ return llvm::createStringErrorV("no compile unit for frame: {0}",
+ frame_sp->GetFunctionName());
lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
- symbol_context = ctx.GetSymbolContext(lldb::eSymbolContextModule);
+ symbol_context = frame_sp->GetSymbolContext(lldb::eSymbolContextModule);
return symbol_context.module_sp->GetTypeSystemForLanguage(language);
}
@@ -74,8 +81,7 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location) {
if (!valobj)
return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
location);
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
@@ -93,11 +99,11 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location) {
CompilerType uint_type =
GetBasicType(*type_system, lldb::eBasicTypeUnsignedInt);
llvm::Expected<uint64_t> int_bit_size =
- int_type.GetBitSize(&m_stack_frame);
+ int_type.GetBitSize(m_exe_ctx.GetBestExecutionContextScope());
if (!int_bit_size)
return int_bit_size.takeError();
llvm::Expected<uint64_t> uint_bit_size =
- uint_type.GetBitSize(&m_stack_frame);
+ uint_type.GetBitSize(m_exe_ctx.GetBestExecutionContextScope());
if (!uint_bit_size)
return uint_bit_size.takeError();
if (bitfield_size < *int_bit_size ||
@@ -120,13 +126,13 @@ Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location) {
bool resolved = valobj->ResolveValue(scalar);
if (!resolved)
return llvm::createStringError("invalid scalar value");
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar,
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, scalar,
in_type, "result");
}
}
if (in_type.IsArrayType())
- valobj = ArrayToPointerConversion(*valobj, m_stack_frame, "result");
+ valobj = ArrayToPointerConversion(*valobj, m_exe_ctx, "result");
CompilerType promoted_type =
valobj->GetCompilerType().GetPromotedIntegerType();
@@ -205,16 +211,17 @@ Interpreter::PromoteSignedInteger(CompilerType &lhs_type,
CompilerType &rhs_type) {
assert(lhs_type.IsInteger() && rhs_type.IsInteger());
if (!lhs_type.IsSigned() && rhs_type.IsSigned()) {
- llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
+ llvm::Expected<uint64_t> lhs_size =
+ lhs_type.GetBitSize(m_exe_ctx.GetBestExecutionContextScope());
if (!lhs_size)
return lhs_size.takeError();
- llvm::Expected<uint64_t> rhs_size = rhs_type.GetBitSize(&m_stack_frame);
+ llvm::Expected<uint64_t> rhs_size =
+ rhs_type.GetBitSize(m_exe_ctx.GetBestExecutionContextScope());
if (!rhs_size)
return rhs_size.takeError();
if (*rhs_size == *lhs_size) {
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
CompilerType r_type_unsigned = GetBasicType(
@@ -310,12 +317,14 @@ static lldb::VariableSP DILFindVariable(ConstString name,
}
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
- StackFrame &stack_frame,
- lldb::TargetSP target_sp,
+ ExecutionContext &exe_ctx,
lldb::DynamicValueType use_dynamic) {
// Get a global variables list without the locals from the current frame
+ auto frame_sp = exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return nullptr;
SymbolContext symbol_context =
- stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit);
+ frame_sp->GetSymbolContext(lldb::eSymbolContextCompUnit);
lldb::VariableListSP variable_list;
if (symbol_context.comp_unit)
variable_list = symbol_context.comp_unit->GetVariableList(true);
@@ -326,14 +335,16 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
lldb::VariableSP var_sp =
DILFindVariable(ConstString(name_ref), *variable_list);
if (var_sp)
- value_sp =
- stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
+ value_sp = frame_sp->GetValueObjectForFrameVariable(var_sp, use_dynamic);
}
if (value_sp)
return value_sp;
// Check for match in modules global variables.
+ auto target_sp = exe_ctx.GetTargetSP();
+ if (!target_sp)
+ return nullptr;
VariableList modules_var_list;
target_sp->GetImages().FindGlobalVariables(
ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
@@ -343,7 +354,8 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
lldb::VariableSP var_sp =
DILFindVariable(ConstString(name_ref), modules_var_list);
if (var_sp)
- value_sp = ValueObjectVariable::Create(&stack_frame, var_sp);
+ value_sp = ValueObjectVariable::Create(
+ exe_ctx.GetBestExecutionContextScope(), var_sp);
if (value_sp)
return value_sp;
@@ -352,9 +364,12 @@ lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref,
}
lldb::ValueObjectSP LookupPersistentIdentifier(llvm::StringRef name_ref,
- StackFrame &stack_frame,
- lldb::TargetSP target_sp,
+ ExecutionContext &exe_ctx,
lldb::LanguageType language) {
+ auto target_sp = exe_ctx.GetTargetSP();
+ if (!target_sp)
+ return nullptr;
+
if (name_ref.starts_with("$")) {
if (auto *state =
target_sp->GetPersistentExpressionStateForLanguage(language))
@@ -366,17 +381,21 @@ lldb::ValueObjectSP LookupPersistentIdentifier(llvm::StringRef name_ref,
}
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
- StackFrame &stack_frame,
+ ExecutionContext &exe_ctx,
lldb::DynamicValueType use_dynamic) {
// Support $rax as a special syntax for accessing registers.
// Will return an invalid value in case the requested register doesn't exist.
+ auto frame_sp = exe_ctx.GetFrameSP();
+ if (!frame_sp)
+ return nullptr;
if (name_ref.consume_front("$")) {
- lldb::RegisterContextSP reg_ctx(stack_frame.GetRegisterContext());
+ lldb::RegisterContextSP reg_ctx(frame_sp->GetRegisterContext());
if (!reg_ctx)
return nullptr;
if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
- return ValueObjectRegister::Create(&stack_frame, reg_ctx, reg_info);
+ return ValueObjectRegister::Create(exe_ctx.GetBestExecutionContextScope(),
+ reg_ctx, reg_info);
return nullptr;
}
@@ -384,8 +403,7 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
if (!name_ref.contains("::")) {
// Lookup in the current frame.
// Try looking for a local variable in current scope.
- lldb::VariableListSP variable_list(
- stack_frame.GetInScopeVariableList(false));
+ lldb::VariableListSP variable_list(frame_sp->GetInScopeVariableList(false));
lldb::ValueObjectSP value_sp;
if (variable_list) {
@@ -393,17 +411,17 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
variable_list->FindVariable(ConstString(name_ref));
if (var_sp)
value_sp =
- stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
+ frame_sp->GetValueObjectForFrameVariable(var_sp, use_dynamic);
}
if (value_sp)
return value_sp;
// Try looking for an instance variable (class member).
- SymbolContext sc = stack_frame.GetSymbolContext(
- lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
+ SymbolContext sc = frame_sp->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
llvm::StringRef instance_name = sc.GetInstanceName();
- value_sp = stack_frame.FindVariable(ConstString(instance_name));
+ value_sp = frame_sp->FindVariable(ConstString(instance_name));
if (value_sp)
value_sp = value_sp->GetChildMemberWithName(name_ref);
@@ -414,20 +432,20 @@ lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
}
lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
- ExecutionContextScope &ctx_scope) {
+ ExecutionContext &exe_ctx) {
if (name_ref.contains("::")) {
llvm::StringRef enum_typename, enumerator_name;
// FIXME: Change this to a structured binding for lambda capturing
// once we have C++20.
std::tie(enum_typename, enumerator_name) = name_ref.rsplit("::");
- CompilerType enum_type = ResolveTypeByName(enum_typename.str(), ctx_scope);
+ CompilerType enum_type = ResolveTypeByName(enum_typename.str(), exe_ctx);
lldb::ValueObjectSP result;
enum_type.ForEachEnumerator([&](const CompilerType &integer_type,
ConstString name,
const llvm::APSInt &value) -> bool {
if (name == enumerator_name) {
Scalar scalar(value);
- result = ValueObject::CreateValueObjectFromScalar(ctx_scope, scalar,
+ result = ValueObject::CreateValueObjectFromScalar(exe_ctx, scalar,
enum_type, "result");
return false; // Stop iterating
}
@@ -438,11 +456,9 @@ lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
return nullptr;
}
-Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
- StackFrame &stack_frame,
+Interpreter::Interpreter(ExecutionContext &exe_ctx, llvm::StringRef expr,
lldb::DynamicValueType use_dynamic, uint32_t options)
- : m_target(std::move(target)), m_expr(expr), m_stack_frame(stack_frame),
- m_use_dynamic(use_dynamic) {
+ : m_exe_ctx(exe_ctx), m_expr(expr), m_use_dynamic(use_dynamic) {
const bool check_ptr_vs_member =
(options & StackFrame::eExpressionPathOptionCheckPtrVsMember) != 0;
@@ -508,35 +524,33 @@ Interpreter::Visit(const IdentifierNode &node) {
lldb::DynamicValueType use_dynamic = m_use_dynamic;
lldb::ValueObjectSP identifier =
- LookupIdentifier(node.GetName(), m_stack_frame, use_dynamic);
+ LookupIdentifier(node.GetName(), m_exe_ctx, use_dynamic);
if (!identifier && m_allow_globals)
- identifier = LookupGlobalIdentifier(node.GetName(), m_stack_frame, m_target,
- use_dynamic);
+ identifier = LookupGlobalIdentifier(node.GetName(), m_exe_ctx, use_dynamic);
if (!identifier)
- identifier = LookupEnumValue(node.GetName(), m_stack_frame);
+ identifier = LookupEnumValue(node.GetName(), m_exe_ctx);
if (!identifier && node.GetName()[0] == '$') {
- auto language = GetSourceLanguageFromCU(m_stack_frame);
+ auto language = GetSourceLanguageFromCU();
if (!language)
return language.takeError();
- identifier = LookupPersistentIdentifier(node.GetName(), m_stack_frame,
- m_target, language.get());
+ identifier =
+ LookupPersistentIdentifier(node.GetName(), m_exe_ctx, language.get());
}
if (!identifier && node.GetName() == "nullptr") {
// If we got a "nullptr" identifier, and there is no defined variable with
// this name, resolve it as a null pointer.
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
type_system.get()->GetPointerByteSize();
llvm::APInt value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
Scalar scalar(value);
CompilerType type = GetBasicType(*type_system, lldb::eBasicTypeNullPtr);
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, type,
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, scalar, type,
"result");
}
@@ -614,7 +628,7 @@ Interpreter::Visit(const UnaryOpNode &node) {
bool negated = scalar.UnaryNegate();
if (negated)
return ValueObject::CreateValueObjectFromScalar(
- m_stack_frame, scalar, operand->GetCompilerType(), "result");
+ m_exe_ctx, scalar, operand->GetCompilerType(), "result");
break;
}
case UnaryOpKind::Plus: {
@@ -671,7 +685,7 @@ Interpreter::Visit(const UnaryOpNode &node) {
bool flipped = scalar.OnesComplement();
if (flipped)
return ValueObject::CreateValueObjectFromScalar(
- m_stack_frame, scalar, operand->GetCompilerType(), "result");
+ m_exe_ctx, scalar, operand->GetCompilerType(), "result");
break;
}
case UnaryOpKind::LNot: {
@@ -688,14 +702,13 @@ Interpreter::Visit(const UnaryOpNode &node) {
return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
node.GetLocation());
}
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
auto value_or_err = operand->GetValueAsBool();
if (!value_or_err)
return value_or_err.takeError();
- return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
+ return ValueObject::CreateValueObjectFromBool(m_exe_ctx, *type_system,
!(*value_or_err), "result");
}
}
@@ -724,7 +737,8 @@ Interpreter::PointerOffset(lldb::ValueObjectSP ptr, lldb::ValueObjectSP offset,
}
llvm::Expected<uint64_t> byte_size =
- ptr->GetCompilerType().GetPointeeType().GetByteSize(&m_stack_frame);
+ ptr->GetCompilerType().GetPointeeType().GetByteSize(
+ m_exe_ctx.GetBestExecutionContextScope());
if (!byte_size)
return byte_size.takeError();
uint64_t ptr_addr = ptr->GetValueAsUnsigned(0);
@@ -733,10 +747,9 @@ Interpreter::PointerOffset(lldb::ValueObjectSP ptr, lldb::ValueObjectSP offset,
else
ptr_addr += offset_int * (*byte_size);
- ExecutionContext exe_ctx(m_target.get(), false);
Scalar scalar(ptr_addr);
return ValueObject::CreateValueObjectFromScalar(
- m_stack_frame, scalar, ptr->GetCompilerType(), "result");
+ m_exe_ctx, scalar, ptr->GetCompilerType(), "result");
}
llvm::Expected<lldb::ValueObjectSP>
@@ -758,7 +771,7 @@ Interpreter::EvaluateScalarOp(BinaryOpKind kind, lldb::ValueObjectSP lhs,
}
auto value_object = [this, result_type](Scalar scalar) {
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar,
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, scalar,
result_type, "result");
};
@@ -880,7 +893,8 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
}
llvm::Expected<uint64_t> lhs_byte_size =
- lhs_type.GetPointeeType().GetByteSize(&m_stack_frame);
+ lhs_type.GetPointeeType().GetByteSize(
+ m_exe_ctx.GetBestExecutionContextScope());
if (!lhs_byte_size)
return lhs_byte_size.takeError();
// Since pointers have compatible types, both have the same pointee size.
@@ -896,8 +910,7 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
}
diff /= item_size;
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
CompilerType ptrdiff_type = type_system.get()->GetPointerDiffType(true);
@@ -906,7 +919,7 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
m_expr, "unable to determine pointer diff type", location);
Scalar scalar(diff);
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar,
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, scalar,
ptrdiff_type, "result");
}
@@ -1073,9 +1086,9 @@ Interpreter::ValidateComparison(BinaryOpKind kind, lldb::ValueObjectSP &lhs,
orig_rhs_type.IsNullPtrType() || IsLiteralZero(rhs, rhs_is_literal);
if (orig_lhs_type.IsArrayType())
- lhs = ArrayToPointerConversion(*lhs, m_stack_frame, "result");
+ lhs = ArrayToPointerConversion(*lhs, m_exe_ctx, "result");
if (orig_rhs_type.IsArrayType())
- rhs = ArrayToPointerConversion(*rhs, m_stack_frame, "result");
+ rhs = ArrayToPointerConversion(*rhs, m_exe_ctx, "result");
CompilerType lhs_type = lhs->GetCompilerType();
CompilerType rhs_type = rhs->GetCompilerType();
@@ -1218,8 +1231,7 @@ Interpreter::EvaluateComparison(BinaryOpKind kind, lldb::ValueObjectSP lhs,
rhs_is_literal, location))
return error;
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
CompilerType boolean_type = GetBasicType(*type_system, lldb::eBasicTypeBool);
@@ -1279,7 +1291,8 @@ Interpreter::EvaluateBinaryShift(BinaryOpKind kind, lldb::ValueObjectSP lhs,
if (!success)
return llvm::make_error<DILDiagnosticError>(
m_expr, "could not get the shift amount as an integer", location);
- llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
+ llvm::Expected<uint64_t> lhs_size =
+ lhs_type.GetBitSize(m_exe_ctx.GetBestExecutionContextScope());
if (!lhs_size)
return lhs_size.takeError();
if (amount >= *lhs_size)
@@ -1307,8 +1320,7 @@ Interpreter::EvaluateLogical(const BinaryOpNode &node) {
return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
node.GetLocation());
}
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
@@ -1320,7 +1332,7 @@ Interpreter::EvaluateLogical(const BinaryOpNode &node) {
bool lhs_val = *lvalue_or_err;
bool exit_early = node.GetKind() == BinaryOpKind::LAnd ? !lhs_val : lhs_val;
if (exit_early)
- return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
+ return ValueObject::CreateValueObjectFromBool(m_exe_ctx, *type_system,
lhs_val, "result");
// If the result is to be determined, evaluate the RHS.
@@ -1340,7 +1352,7 @@ Interpreter::EvaluateLogical(const BinaryOpNode &node) {
auto rvalue_or_err = rhs->GetValueAsBool();
if (!rvalue_or_err)
return rvalue_or_err.takeError();
- return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
+ return ValueObject::CreateValueObjectFromBool(m_exe_ctx, *type_system,
*rvalue_or_err, "result");
}
@@ -1784,8 +1796,8 @@ Interpreter::Visit(const BitFieldExtractionNode &node) {
// The high index must lie within the base object's storage; a bit index past
// its bit size shifts out of bounds when the child is later read or formatted
// (GetMaxU64Bitfield).
- llvm::Expected<uint64_t> base_bit_size =
- base->GetCompilerType().GetBitSize(&m_stack_frame);
+ llvm::Expected<uint64_t> base_bit_size = base->GetCompilerType().GetBitSize(
+ m_exe_ctx.GetBestExecutionContextScope());
if (!base_bit_size)
return base_bit_size.takeError();
if (static_cast<uint64_t>(last_index) >= *base_bit_size) {
@@ -1812,7 +1824,7 @@ Interpreter::Visit(const BitFieldExtractionNode &node) {
llvm::Expected<CompilerType>
Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,
- ExecutionContextScope &ctx,
+ ExecutionContext &exe_ctx,
const IntegerLiteralNode &literal) {
// Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
// an unsigned integer.
@@ -1834,7 +1846,8 @@ Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,
CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
if (!signed_type)
continue;
- llvm::Expected<uint64_t> size = signed_type.GetBitSize(&ctx);
+ llvm::Expected<uint64_t> size =
+ signed_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
if (!size)
return size.takeError();
if (!literal.IsUnsigned() && apint.isIntN(*size - 1))
@@ -1851,20 +1864,20 @@ Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,
llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const IntegerLiteralNode &node) {
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
llvm::Expected<CompilerType> type =
- PickIntegerType(*type_system, m_stack_frame, node);
+ PickIntegerType(*type_system, m_exe_ctx, node);
if (!type)
return type.takeError();
Scalar scalar = node.GetValue();
// APInt from StringRef::getAsInteger comes with just enough bitwidth to
// hold the value. This adjusts APInt bitwidth to match the compiler type.
- llvm::Expected<uint64_t> type_bitsize = type->GetBitSize(&m_stack_frame);
+ llvm::Expected<uint64_t> type_bitsize =
+ type->GetBitSize(m_exe_ctx.GetBestExecutionContextScope());
if (!type_bitsize)
return type_bitsize.takeError();
// Literal itself cannot be a negative value, so we do an unsigned extension.
@@ -1872,14 +1885,13 @@ Interpreter::Visit(const IntegerLiteralNode &node) {
// If the picked compiler type is signed, make the scalar signed as well.
if (type->IsSigned())
scalar.MakeSigned();
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, *type,
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, scalar, *type,
"result");
}
llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const FloatLiteralNode &node) {
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
@@ -1894,19 +1906,18 @@ Interpreter::Visit(const FloatLiteralNode &node) {
m_expr, "unable to create a const literal", node.GetLocation());
Scalar scalar = node.GetValue();
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, scalar, type,
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, scalar, type,
"result");
}
llvm::Expected<lldb::ValueObjectSP>
Interpreter::Visit(const BooleanLiteralNode &node) {
bool value = node.GetValue();
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
- return ValueObject::CreateValueObjectFromBool(m_stack_frame, *type_system,
- value, "result");
+ return ValueObject::CreateValueObjectFromBool(m_exe_ctx, *type_system, value,
+ "result");
}
llvm::Expected<CastKind>
@@ -1931,7 +1942,8 @@ Interpreter::VerifyArithmeticCast(CompilerType source_type,
// size.
uint64_t type_byte_size = 0;
uint64_t rhs_type_byte_size = 0;
- if (auto temp = target_type.GetByteSize(&m_stack_frame)) {
+ if (auto temp =
+ target_type.GetByteSize(m_exe_ctx.GetBestExecutionContextScope())) {
type_byte_size = *temp;
} else {
std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
@@ -1943,7 +1955,8 @@ Interpreter::VerifyArithmeticCast(CompilerType source_type,
target_type.TypeDescription().length());
}
- if (auto temp = source_type.GetByteSize(&m_stack_frame)) {
+ if (auto temp =
+ source_type.GetByteSize(m_exe_ctx.GetBestExecutionContextScope())) {
rhs_type_byte_size = *temp;
} else {
std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
@@ -2035,7 +2048,7 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
if (op_type.IsReferenceType())
op_type = op_type.GetNonReferenceType();
if (target_type.IsScalarType() && op_type.IsArrayType()) {
- operand = ArrayToPointerConversion(*operand, m_stack_frame,
+ operand = ArrayToPointerConversion(*operand, m_exe_ctx,
operand->GetName().GetStringRef());
op_type = operand->GetCompilerType();
}
@@ -2073,9 +2086,9 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
? operand->GetLoadAddress()
: (op_type.IsSigned() ? operand->GetValueAsSigned(0)
: operand->GetValueAsUnsigned(0));
- result = ValueObject::CreateValueObjectFromAddress(
- "result", addr, m_stack_frame, target_type,
- /* do_deref */ false);
+ result = ValueObject::CreateValueObjectFromAddress("result", addr,
+ m_exe_ctx, target_type,
+ /* do_deref */ false);
break;
}
case CastKind::eNone: {
@@ -2137,7 +2150,8 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const SizeOfNode &node) {
if (typearg.IsValid()) {
if (typearg.IsReferenceType())
typearg = typearg.GetNonReferenceType();
- llvm::Expected<uint64_t> byte_size = typearg.GetByteSize(m_target.get());
+ llvm::Expected<uint64_t> byte_size =
+ typearg.GetByteSize(m_exe_ctx.GetTargetSP().get());
if (!byte_size)
return byte_size.takeError();
size = *byte_size;
@@ -2158,8 +2172,7 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const SizeOfNode &node) {
size = *byte_size;
}
- llvm::Expected<lldb::TypeSystemSP> type_system =
- GetTypeSystemFromCU(m_stack_frame);
+ llvm::Expected<lldb::TypeSystemSP> type_system = GetTypeSystemFromCU();
if (!type_system)
return type_system.takeError();
CompilerType size_type = type_system.get()->GetSizeType();
@@ -2167,8 +2180,8 @@ llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const SizeOfNode &node) {
return llvm::make_error<DILDiagnosticError>(
m_expr, "unable to determine size type", node.GetLocation());
- return ValueObject::CreateValueObjectFromScalar(m_stack_frame, size,
- size_type, "result");
+ return ValueObject::CreateValueObjectFromScalar(m_exe_ctx, size, size_type,
+ "result");
}
} // namespace lldb_private::dil
diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index f35b2ccd8ac09..8fe55ea0e7033 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -16,7 +16,6 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILEval.h"
@@ -61,7 +60,7 @@ DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
}
CompilerType ResolveTypeByName(const std::string &name,
- ExecutionContextScope &ctx_scope) {
+ ExecutionContext &exe_ctx) {
// Internally types don't have global scope qualifier in their names and
// LLDB doesn't support queries with it too.
llvm::StringRef name_ref(name);
@@ -70,7 +69,7 @@ CompilerType ResolveTypeByName(const std::string &name,
name_ref = name_ref.drop_front(2);
std::vector<CompilerType> result_type_list;
- lldb::TargetSP target_sp = ctx_scope.CalculateTarget();
+ lldb::TargetSP target_sp = exe_ctx.GetTargetSP();
if (!name_ref.empty() && target_sp) {
ModuleList &images = target_sp->GetImages();
TypeQuery query{ConstString(name_ref), TypeQueryOptions::e_exact_match |
@@ -91,14 +90,13 @@ CompilerType ResolveTypeByName(const std::string &name,
return {};
}
-llvm::Expected<ASTNodeUP> DILParser::Parse(llvm::StringRef dil_input_expr,
+llvm::Expected<ASTNodeUP> DILParser::Parse(ExecutionContext &exe_ctx,
+ llvm::StringRef dil_input_expr,
DILLexer lexer,
- StackFrame &stack_frame,
lldb::DynamicValueType use_dynamic,
lldb::DILMode mode) {
llvm::Error error = llvm::Error::success();
- DILParser parser(dil_input_expr, lexer, stack_frame, use_dynamic, error,
- mode);
+ DILParser parser(exe_ctx, dil_input_expr, lexer, use_dynamic, error, mode);
ASTNodeUP node_up = parser.Run();
assert(node_up && "ASTNodeUP must not contain a nullptr");
@@ -113,11 +111,10 @@ llvm::Expected<ASTNodeUP> DILParser::Parse(llvm::StringRef dil_input_expr,
return node_up;
}
-DILParser::DILParser(llvm::StringRef dil_input_expr, DILLexer lexer,
- StackFrame &stack_frame,
- lldb::DynamicValueType use_dynamic, llvm::Error &error,
- lldb::DILMode mode)
- : m_stack_frame(stack_frame), m_input_expr(dil_input_expr),
+DILParser::DILParser(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr,
+ DILLexer lexer, lldb::DynamicValueType use_dynamic,
+ llvm::Error &error, lldb::DILMode mode)
+ : m_exe_ctx(exe_ctx), m_input_expr(dil_input_expr),
m_dil_lexer(std::move(lexer)), m_error(error), m_use_dynamic(use_dynamic),
m_mode(mode) {}
@@ -767,18 +764,17 @@ std::optional<CompilerType> DILParser::ParseTypeId() {
if (type_name.empty())
return {};
- type = ResolveTypeByName(type_name, m_stack_frame);
+ type = ResolveTypeByName(type_name, m_exe_ctx);
if (!type.IsValid())
return {};
// Same-name identifiers should be preferred over typenames.
- if (LookupIdentifier(type_name, m_stack_frame, m_use_dynamic))
+ if (LookupIdentifier(type_name, m_exe_ctx, m_use_dynamic))
// TODO: Make type accessible with 'class', 'struct' and 'union' keywords.
return {};
// Same-name identifiers should be preferred over typenames.
- if (LookupGlobalIdentifier(type_name, m_stack_frame,
- m_stack_frame.CalculateTarget(), m_use_dynamic))
+ if (LookupGlobalIdentifier(type_name, m_exe_ctx, m_use_dynamic))
// TODO: Make type accessible with 'class', 'struct' and 'union' keywords
return {};
}
@@ -827,7 +823,9 @@ std::optional<CompilerType> DILParser::ParseBuiltinType() {
}
if (type_name.size() > 0) {
- lldb::TargetSP target_sp = m_stack_frame.CalculateTarget();
+ lldb::TargetSP target_sp = m_exe_ctx.GetTargetSP();
+ if (!target_sp)
+ return {};
ConstString const_type_name(type_name);
for (auto type_system_sp : target_sp->GetScratchTypeSystems())
if (auto compiler_type =
>From edee7c1405d7b7745666f59bac80a448ebcde0dc Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 24 Sep 2026 19:24:30 +0500
Subject: [PATCH 2/2] Store ExecutionContext as a value
---
lldb/include/lldb/ValueObject/DILEval.h | 4 ++--
lldb/include/lldb/ValueObject/DILParser.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lldb/include/lldb/ValueObject/DILEval.h b/lldb/include/lldb/ValueObject/DILEval.h
index 4c7405a38f675..1a828395dc056 100644
--- a/lldb/include/lldb/ValueObject/DILEval.h
+++ b/lldb/include/lldb/ValueObject/DILEval.h
@@ -178,8 +178,8 @@ class Interpreter : Visitor {
CompilerType target_type,
int location);
- // Interpreter doesn't own the evaluation context.
- ExecutionContext &m_exe_ctx;
+ // Used by the interpreter to create objects, perform casts, etc.
+ ExecutionContext m_exe_ctx;
llvm::StringRef m_expr;
lldb::ValueObjectSP m_scope;
lldb::DynamicValueType m_use_dynamic;
diff --git a/lldb/include/lldb/ValueObject/DILParser.h b/lldb/include/lldb/ValueObject/DILParser.h
index 31f1c08905b5e..3e50472df5ddb 100644
--- a/lldb/include/lldb/ValueObject/DILParser.h
+++ b/lldb/include/lldb/ValueObject/DILParser.h
@@ -137,7 +137,7 @@ class DILParser {
// Parser doesn't own the evaluation context. The produced AST may depend on
// it (for example, for source locations), so it's expected that expression
// context will outlive the parser.
- ExecutionContext &m_exe_ctx;
+ ExecutionContext m_exe_ctx;
llvm::StringRef m_input_expr;
More information about the lldb-commits
mailing list