[Lldb-commits] [lldb] [lldb][Expression] Add --c++-ignore-context-qualifiers expression evaluation option (PR #177926)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 4 23:34:05 PST 2026
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/177926
>From 5ab6fcca44f249df200f9bcc1deca16cc188f189 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 23 Jan 2026 14:49:56 +0000
Subject: [PATCH 1/9] [lldb][Expression] Add --ignore-const-context expression
evaluation option
Depends on:
* https://github.com/llvm/llvm-project/pull/177920
* https://github.com/llvm/llvm-project/pull/177922
In https://github.com/llvm/llvm-project/pull/177922 we make expressions
run in C++ member functions honor the function qualifiers of the current
stop context. E.g., this means we can no longer run non-const member
functions when stopped in a const-member function.
To ensure users can still do this if they really need/want to, we
provide an option to not honor the qualifiers at all, leaving the
`__lldb_expr` as the least qualified, allowing it to call any
function/mutate any members.
---
lldb/include/lldb/Target/Target.h | 6 ++++
.../Commands/CommandObjectExpression.cpp | 5 +++
.../source/Commands/CommandObjectExpression.h | 1 +
lldb/source/Commands/Options.td | 8 +++++
.../Clang/ClangExpressionDeclMap.cpp | 9 +++--
.../Clang/ClangExpressionDeclMap.h | 15 +++++++-
.../Clang/ClangExpressionSourceCode.cpp | 34 +++++++++++--------
.../Clang/ClangExpressionSourceCode.h | 4 +--
.../Clang/ClangUserExpression.cpp | 9 ++---
.../Clang/ClangUserExpression.h | 8 ++---
.../Clang/ClangUtilityFunction.cpp | 2 +-
.../const_method/TestExprInConstMethod.py | 30 +++++++++++++++-
.../TestExprInConstVolatileMethod.py | 25 ++++++++++++++
.../TestExprInNonConstMethod.py | 4 +++
.../TestExprInTemplateConstMethod.py | 8 ++++-
.../TestExprInTemplateNonConstMethod.py | 4 +++
lldb/test/API/lang/cpp/this/TestCPPThis.py | 7 ++--
.../Expression/ClangExpressionDeclMapTest.cpp | 2 +-
18 files changed, 147 insertions(+), 34 deletions(-)
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index a79d0f1b6113e..5dea769bfc82b 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -539,6 +539,12 @@ class EvaluateExpressionOptions {
/// used for symbol/function lookup before any other context (except for
/// the module corresponding to the current frame).
SymbolContextList m_preferred_lookup_contexts;
+
+ /// If true, evaluates the expression without taking into account the
+ /// CV-qualifiers of the scope. E.g., this would permit calling a
+ /// non-const C++ method when stopped in a const-method (which would be
+ /// disallowed by C++ language rules).
+ bool m_ignore_context_qualifierss = false;
};
// Target
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 4919bd3639d3e..ab1dcd7d82cbf 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -44,6 +44,9 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
const int short_option = GetDefinitions()[option_idx].short_option;
switch (short_option) {
+ case 'Q':
+ ignore_context_qualifiers = true;
+ break;
case 'l':
language = Language::GetLanguageTypeFromString(option_arg);
if (language == eLanguageTypeUnknown) {
@@ -191,6 +194,7 @@ void CommandObjectExpression::CommandOptions::OptionParsingStarting(
top_level = false;
allow_jit = true;
suppress_persistent_result = eLazyBoolCalculate;
+ ignore_context_qualifiers = false;
}
llvm::ArrayRef<OptionDefinition>
@@ -213,6 +217,7 @@ CommandObjectExpression::CommandOptions::GetEvaluateExpressionOptions(
options.SetExecutionPolicy(
allow_jit ? EvaluateExpressionOptions::default_execution_policy
: lldb_private::eExecutionPolicyNever);
+ options.SetIgnoreContextQualifiers(ignore_context_qualifiers);
bool auto_apply_fixits;
if (this->auto_apply_fixits == eLazyBoolCalculate)
diff --git a/lldb/source/Commands/CommandObjectExpression.h b/lldb/source/Commands/CommandObjectExpression.h
index 6fccf10e5dbc1..6d60a674e5708 100644
--- a/lldb/source/Commands/CommandObjectExpression.h
+++ b/lldb/source/Commands/CommandObjectExpression.h
@@ -57,6 +57,7 @@ class CommandObjectExpression : public CommandObjectRaw,
LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
LazyBool auto_apply_fixits;
LazyBool suppress_persistent_result;
+ bool ignore_context_qualifiers;
};
CommandObjectExpression(CommandInterpreter &interpreter);
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index d96354a39b8b8..c3dddd0f64c2c 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -778,6 +778,14 @@ let Command = "expression" in {
Desc<"Persist expression result in a variable for subsequent use. "
"Expression results will be labeled with $-prefixed variables, "
"e.g. $0, $1, etc.">;
+ def ignore_context_qualifiers
+ : Option<"ignore-context-qualifiers", "Q">,
+ Groups<[1, 2]>,
+ Desc<"When specified, evaluates the expression without taking into "
+ "account the type ${Q}ualifiers of the scope. E.g., this would "
+ "permit "
+ "calling a non-const C++ method when stopped in a const-method "
+ "(which would be disallowed by C++ language rules).">;
}
let Command = "frame diag" in {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index b1f246f6690e7..9f4ccc60c0b34 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -88,10 +88,12 @@ ClangExpressionDeclMap::ClangExpressionDeclMap(
bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
const lldb::TargetSP &target,
- const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)
+ const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj,
+ bool ignore_context_qualifiers)
: ClangASTSource(target, importer), m_found_entities(), m_struct_members(),
m_keep_result_in_memory(keep_result_in_memory),
- m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
+ m_result_delegate(result_delegate), m_ctx_obj(ctx_obj),
+ m_ignore_context_qualifiers(ignore_context_qualifiers), m_parser_vars(),
m_struct_vars() {
EnableStructVars();
}
@@ -1997,7 +1999,8 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
std::array<CompilerType, 1> args{void_clang_type.GetPointerType()};
CompilerType method_type = m_clang_ast_context->CreateFunctionType(
- void_clang_type, args, false, ut.GetTypeQualifiers());
+ void_clang_type, args, false,
+ m_ignore_context_qualifiers ? 0 : ut.GetTypeQualifiers());
const bool is_virtual = false;
const bool is_static = false;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index df74ebc37a5de..d44c95068f45d 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -78,11 +78,18 @@ class ClangExpressionDeclMap : public ClangASTSource {
/// \param[in] ctx_obj
/// If not empty, then expression is evaluated in context of this object.
/// See the comment to `UserExpression::Evaluate` for details.
+ ///
+ /// \param[in] ignore_context_qualifiers
+ /// If \c true, evaluates the expression without taking into account the
+ /// CV-qualifiers of the scope. E.g., this would permit calling a
+ /// non-const C++ method when stopped in a const-method (which would be
+ /// disallowed by C++ language rules).
ClangExpressionDeclMap(
bool keep_result_in_memory,
Materializer::PersistentVariableDelegate *result_delegate,
const lldb::TargetSP &target,
- const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj);
+ const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj,
+ bool ignore_context_qualifiers);
/// Destructor
~ClangExpressionDeclMap() override;
@@ -306,6 +313,12 @@ class ClangExpressionDeclMap : public ClangASTSource {
///For details see the comment to
///`UserExpression::Evaluate`.
+ /// If \c true, evaluates the expression without taking into account the
+ /// CV-qualifiers of the scope. E.g., this would permit calling a
+ /// non-const C++ method when stopped in a const-method (which would be
+ /// disallowed by C++ language rules).
+ bool m_ignore_context_qualifiers = false;
+
/// The following values should not live beyond parsing
class ParserVars {
public:
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
index ca4199faa3841..c711367cb6177 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp
@@ -363,9 +363,12 @@ void ClangExpressionSourceCode::AddLocalVariableDecls(StreamString &stream,
}
}
-bool ClangExpressionSourceCode::GetText(
- std::string &text, ExecutionContext &exe_ctx, bool add_locals,
- bool force_add_all_locals, llvm::ArrayRef<std::string> modules) const {
+bool ClangExpressionSourceCode::GetText(std::string &text,
+ ExecutionContext &exe_ctx,
+ bool add_locals,
+ bool force_add_all_locals,
+ llvm::ArrayRef<std::string> modules,
+ bool ignore_context_qualifiers) const {
const char *target_specific_defines = "typedef signed char BOOL;\n";
std::string module_macros;
llvm::raw_string_ostream module_macros_stream(module_macros);
@@ -486,17 +489,20 @@ bool ClangExpressionSourceCode::GetText(
lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
case WrapKind::CppMemberFunction:
- wrap_stream.Printf(
- "%s"
- "void \n"
- "$__lldb_class::%s(void *$__lldb_arg) %s \n"
- "{ \n"
- " %s; \n"
- "%s"
- "} \n",
- module_imports.c_str(), m_name.c_str(),
- GetFrameCVQualifiers(exe_ctx.GetFramePtr()).getAsString().c_str(),
- lldb_local_var_decls.GetData(), tagged_body.c_str());
+ wrap_stream.Printf("%s"
+ "void \n"
+ "$__lldb_class::%s(void *$__lldb_arg) %s \n"
+ "{ \n"
+ " %s; \n"
+ "%s"
+ "} \n",
+ module_imports.c_str(), m_name.c_str(),
+ ignore_context_qualifiers
+ ? ""
+ : GetFrameCVQualifiers(exe_ctx.GetFramePtr())
+ .getAsString()
+ .c_str(),
+ lldb_local_var_decls.GetData(), tagged_body.c_str());
break;
case WrapKind::ObjCInstanceMethod:
wrap_stream.Printf(
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
index f721bb2f319e1..914d405139193 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h
@@ -63,8 +63,8 @@ class ClangExpressionSourceCode : public ExpressionSourceCode {
///
/// \return true iff the source code was successfully generated.
bool GetText(std::string &text, ExecutionContext &exe_ctx, bool add_locals,
- bool force_add_all_locals,
- llvm::ArrayRef<std::string> modules) const;
+ bool force_add_all_locals, llvm::ArrayRef<std::string> modules,
+ bool ignore_context_qualifiers) const;
// Given a string returned by GetText, find the beginning and end of the body
// passed to CreateWrapped. Return true if the bounds could be found. This
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 2cbbae11bd18a..2436468569958 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -416,7 +416,8 @@ void ClangUserExpression::CreateSourceCode(
m_filename, prefix, m_expr_text, GetWrapKind()));
if (!m_source_code->GetText(m_transformed_text, exe_ctx, !m_ctx_obj,
- for_completion, modules_to_import)) {
+ for_completion, modules_to_import,
+ m_options.GetIgnoreContextQualifiers())) {
diagnostic_manager.PutString(lldb::eSeverityError,
"couldn't construct expression body");
return;
@@ -950,8 +951,8 @@ char ClangUserExpression::ClangUserExpressionHelper::ID;
void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
ExecutionContext &exe_ctx,
Materializer::PersistentVariableDelegate &delegate,
- bool keep_result_in_memory,
- ValueObject *ctx_obj) {
+ bool keep_result_in_memory, ValueObject *ctx_obj,
+ bool ignore_context_qualifiers) {
std::shared_ptr<ClangASTImporter> ast_importer;
auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
lldb::eLanguageTypeC);
@@ -961,7 +962,7 @@ void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
}
m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), ast_importer,
- ctx_obj);
+ ctx_obj, ignore_context_qualifiers);
}
clang::ASTConsumer *
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index 7c0c6a0147e2a..b3c31529446ad 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -71,8 +71,8 @@ class ClangUserExpression : public LLVMUserExpression {
void ResetDeclMap(ExecutionContext &exe_ctx,
Materializer::PersistentVariableDelegate &result_delegate,
- bool keep_result_in_memory,
- ValueObject *ctx_obj);
+ bool keep_result_in_memory, ValueObject *ctx_obj,
+ bool ignore_context_qualifiers);
/// Return the object that the parser should allow to access ASTs. May be
/// NULL if the ASTs do not need to be transformed.
@@ -167,8 +167,8 @@ class ClangUserExpression : public LLVMUserExpression {
Materializer::PersistentVariableDelegate &result_delegate,
bool keep_result_in_memory) {
m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
- keep_result_in_memory,
- m_ctx_obj);
+ keep_result_in_memory, m_ctx_obj,
+ m_options.GetIgnoreContextQualifiers());
}
lldb::ExpressionVariableSP
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index e6983066a12fa..112ce9be7bd1a 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -187,5 +187,5 @@ void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
}
m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), ast_importer,
- nullptr);
+ nullptr, /*ignore_context_qualifiers=*/false);
}
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
index 0d8f477dce1fd..d73b6563b29a6 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
@@ -27,6 +27,26 @@ def test(self):
"cannot assign to non-static data member within const member function"
],
)
+ self.expect_expr("m_mem", result_value="-2")
+
+ # Test short and long --ignore-context-qualifiers option.
+ self.expect(
+ "expression --ignore-context-qualifiers -- m_mem = 3.0",
+ error=False,
+ )
+ self.expect_expr("m_mem", result_value="3")
+
+ self.expect(
+ "expression -Q -- m_mem = 4.0",
+ error=False,
+ )
+ self.expect_expr("m_mem", result_value="4")
+
+ # Test --ignore-context-qualifiers via SBExpressionOptions.
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreContextQualifiers()
+ self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
+
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
lldbutil.continue_to_source_breakpoint(
@@ -43,6 +63,9 @@ def test(self):
"cannot assign to non-static data member within const member function"
],
)
+ self.expect_expr("x", result_value="2")
+
+ self.expect_expr("x = -5; x", options=options, result_value="-5")
lldbutil.continue_to_source_breakpoint(
self,
@@ -76,6 +99,9 @@ def test(self):
],
)
self.expect_expr("m_mem", result_value="-2")
+
+ self.expect_expr("m_mem = -1; m_mem", options=options, result_value="-1")
+
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
lldbutil.continue_to_source_breakpoint(
@@ -102,4 +128,6 @@ def test(self):
"cannot assign to non-static data member within const member function"
],
)
- self.expect_expr("m_mem", result_value="-2")
+ self.expect_expr("m_mem", result_value="-1")
+
+ self.expect_expr("m_mem = -2; m_mem", options=options, result_value="-2")
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
index f20b9d8164841..0069b42f5da10 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
@@ -20,6 +20,16 @@ def test(self):
substrs=["has type 'const Foo'", "but function is not marked const"],
)
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreContextQualifiers()
+ options.SetIgnoreBreakpoints(True)
+ self.expect_expr("volatile_method()", options=options)
+ self.expect(
+ "expression --ignore-context-qualifiers -- bar()",
+ error=True,
+ substrs=["call to member function 'bar' is ambiguous"],
+ )
+
lldbutil.continue_to_source_breakpoint(
self, process, "Break here: volatile", lldb.SBFileSpec("main.cpp")
)
@@ -35,6 +45,13 @@ def test(self):
)
self.expect_expr("volatile_method()")
+ self.expect_expr("const_method()", options=options)
+ self.expect(
+ "expression --ignore-context-qualifiers -- bar()",
+ error=True,
+ substrs=["call to member function 'bar' is ambiguous"],
+ )
+
lldbutil.continue_to_source_breakpoint(
self, process, "Break here: const volatile", lldb.SBFileSpec("main.cpp")
)
@@ -58,3 +75,11 @@ def test(self):
"but function is not marked const or volatile",
],
)
+
+ self.expect_expr("const_method()", options=options)
+ self.expect_expr("volatile_method()", options=options)
+ self.expect(
+ "expression --ignore-context-qualifiers -- bar()",
+ error=True,
+ substrs=["call to member function 'bar' is ambiguous"],
+ )
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
index 835487f3bb7e0..78fe27508d10f 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
@@ -36,6 +36,10 @@ def test(self):
],
)
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreContextQualifiers()
+ self.expect_expr("x = 6.0; x", options=options, result_value="6")
+
lldbutil.continue_to_source_breakpoint(
self,
process,
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
index 0d8f477dce1fd..8489f09b69bba 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
@@ -29,6 +29,10 @@ def test(self):
)
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreContextQualifiers()
+ self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
+
lldbutil.continue_to_source_breakpoint(
self,
process,
@@ -43,6 +47,7 @@ def test(self):
"cannot assign to non-static data member within const member function"
],
)
+ self.expect_expr("x = -7.0; x", options=options, result_value="-7")
lldbutil.continue_to_source_breakpoint(
self,
@@ -77,6 +82,7 @@ def test(self):
)
self.expect_expr("m_mem", result_value="-2")
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
+ self.expect_expr("m_mem = -8.0; m_mem", options=options, result_value="-8")
lldbutil.continue_to_source_breakpoint(
self,
@@ -102,4 +108,4 @@ def test(self):
"cannot assign to non-static data member within const member function"
],
)
- self.expect_expr("m_mem", result_value="-2")
+ self.expect_expr("m_mem = -11.0; m_mem", options=options, result_value="-11")
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
index 835487f3bb7e0..78fe27508d10f 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
@@ -36,6 +36,10 @@ def test(self):
],
)
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreContextQualifiers()
+ self.expect_expr("x = 6.0; x", options=options, result_value="6")
+
lldbutil.continue_to_source_breakpoint(
self,
process,
diff --git a/lldb/test/API/lang/cpp/this/TestCPPThis.py b/lldb/test/API/lang/cpp/this/TestCPPThis.py
index f127f80663578..5a59bf3631e82 100644
--- a/lldb/test/API/lang/cpp/this/TestCPPThis.py
+++ b/lldb/test/API/lang/cpp/this/TestCPPThis.py
@@ -47,14 +47,17 @@ def test_with_run_command(self):
)
self.expect("expression -- (int)getpid(); m_a", startstr="(const int) $1 = 3")
+ self.expect(
+ "expression --ignore-context-qualifiers -- m_a = 2", startstr="(int) $2 = 2"
+ )
self.runCmd("process continue")
- self.expect("expression -- s_a", startstr="(int) $2 = 5")
+ self.expect("expression -- s_a", startstr="(int) $3 = 5")
self.runCmd("process continue")
- self.expect("expression -- m_a", startstr="(int) $3 = 3")
+ self.expect("expression -- m_a", startstr="(int) $4 = 2")
def set_breakpoint(self, line):
lldbutil.run_break_set_by_file_and_line(
diff --git a/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp b/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
index 1c07119d4497f..61905ee8df862 100644
--- a/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
+++ b/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
@@ -23,7 +23,7 @@ namespace {
struct FakeClangExpressionDeclMap : public ClangExpressionDeclMap {
FakeClangExpressionDeclMap(const std::shared_ptr<ClangASTImporter> &importer)
: ClangExpressionDeclMap(false, nullptr, lldb::TargetSP(), importer,
- nullptr) {
+ nullptr, /*ignore_context_qualifiers=*/false) {
m_holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
m_scratch_context = m_holder->GetAST();
}
>From 78effdfaeb729da8332a760a0a99c99405619874 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 30 Jan 2026 11:12:13 +0000
Subject: [PATCH 2/9] fixup! rename option to more c++ specific name
---
lldb/include/lldb/Target/Target.h | 4 +++-
lldb/source/Commands/CommandObjectExpression.cpp | 6 +++---
lldb/source/Commands/CommandObjectExpression.h | 2 +-
lldb/source/Commands/Options.td | 9 ++++-----
.../ExpressionParser/Clang/ClangUserExpression.cpp | 2 +-
.../Plugins/ExpressionParser/Clang/ClangUserExpression.h | 6 +++---
.../const_method/TestExprInConstMethod.py | 6 +++---
.../TestExprInConstVolatileMethod.py | 8 ++++----
.../non_const_method/TestExprInNonConstMethod.py | 2 +-
.../TestExprInTemplateConstMethod.py | 2 +-
.../TestExprInTemplateNonConstMethod.py | 2 +-
lldb/test/API/lang/cpp/this/TestCPPThis.py | 2 +-
12 files changed, 26 insertions(+), 25 deletions(-)
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 5dea769bfc82b..6181da9041566 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -544,7 +544,9 @@ class EvaluateExpressionOptions {
/// CV-qualifiers of the scope. E.g., this would permit calling a
/// non-const C++ method when stopped in a const-method (which would be
/// disallowed by C++ language rules).
- bool m_ignore_context_qualifierss = false;
+ ///
+ /// FIXME: move this to a language-specific dictionary of options.
+ bool m_cpp_ignore_context_qualifierss = false;
};
// Target
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index ab1dcd7d82cbf..efc0df6cd738e 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -45,7 +45,7 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
switch (short_option) {
case 'Q':
- ignore_context_qualifiers = true;
+ cpp_ignore_context_qualifiers = true;
break;
case 'l':
language = Language::GetLanguageTypeFromString(option_arg);
@@ -194,7 +194,7 @@ void CommandObjectExpression::CommandOptions::OptionParsingStarting(
top_level = false;
allow_jit = true;
suppress_persistent_result = eLazyBoolCalculate;
- ignore_context_qualifiers = false;
+ cpp_ignore_context_qualifiers = false;
}
llvm::ArrayRef<OptionDefinition>
@@ -217,7 +217,7 @@ CommandObjectExpression::CommandOptions::GetEvaluateExpressionOptions(
options.SetExecutionPolicy(
allow_jit ? EvaluateExpressionOptions::default_execution_policy
: lldb_private::eExecutionPolicyNever);
- options.SetIgnoreContextQualifiers(ignore_context_qualifiers);
+ options.SetCppIgnoreContextQualifiers(cpp_ignore_context_qualifiers);
bool auto_apply_fixits;
if (this->auto_apply_fixits == eLazyBoolCalculate)
diff --git a/lldb/source/Commands/CommandObjectExpression.h b/lldb/source/Commands/CommandObjectExpression.h
index 6d60a674e5708..0439ddffce925 100644
--- a/lldb/source/Commands/CommandObjectExpression.h
+++ b/lldb/source/Commands/CommandObjectExpression.h
@@ -57,7 +57,7 @@ class CommandObjectExpression : public CommandObjectRaw,
LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
LazyBool auto_apply_fixits;
LazyBool suppress_persistent_result;
- bool ignore_context_qualifiers;
+ bool cpp_ignore_context_qualifiers;
};
CommandObjectExpression(CommandInterpreter &interpreter);
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index c3dddd0f64c2c..72bb5df4dddac 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -779,13 +779,12 @@ let Command = "expression" in {
"Expression results will be labeled with $-prefixed variables, "
"e.g. $0, $1, etc.">;
def ignore_context_qualifiers
- : Option<"ignore-context-qualifiers", "Q">,
+ : Option<"cpp-ignore-context-qualifiers", "Q">,
Groups<[1, 2]>,
Desc<"When specified, evaluates the expression without taking into "
- "account the type ${Q}ualifiers of the scope. E.g., this would "
- "permit "
- "calling a non-const C++ method when stopped in a const-method "
- "(which would be disallowed by C++ language rules).">;
+ "account the type ${Q}ualifiers of the scope. In C++, this would "
+ "permit calling a non-const method when stopped in a const-method "
+ "(which would be disallowed by language rules).">;
}
let Command = "frame diag" in {
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 2436468569958..634cdec918057 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -417,7 +417,7 @@ void ClangUserExpression::CreateSourceCode(
if (!m_source_code->GetText(m_transformed_text, exe_ctx, !m_ctx_obj,
for_completion, modules_to_import,
- m_options.GetIgnoreContextQualifiers())) {
+ m_options.GetCppIgnoreContextQualifiers())) {
diagnostic_manager.PutString(lldb::eSeverityError,
"couldn't construct expression body");
return;
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index b3c31529446ad..7f1c1ddcad942 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -166,9 +166,9 @@ class ClangUserExpression : public LLVMUserExpression {
void ResetDeclMap(ExecutionContext &exe_ctx,
Materializer::PersistentVariableDelegate &result_delegate,
bool keep_result_in_memory) {
- m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
- keep_result_in_memory, m_ctx_obj,
- m_options.GetIgnoreContextQualifiers());
+ m_type_system_helper.ResetDeclMap(
+ exe_ctx, result_delegate, keep_result_in_memory, m_ctx_obj,
+ m_options.GetCppIgnoreContextQualifiers());
}
lldb::ExpressionVariableSP
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
index d73b6563b29a6..b501836a46483 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
@@ -29,9 +29,9 @@ def test(self):
)
self.expect_expr("m_mem", result_value="-2")
- # Test short and long --ignore-context-qualifiers option.
+ # Test short and long --cpp-ignore-context-qualifiers option.
self.expect(
- "expression --ignore-context-qualifiers -- m_mem = 3.0",
+ "expression --cpp-ignore-context-qualifiers -- m_mem = 3.0",
error=False,
)
self.expect_expr("m_mem", result_value="3")
@@ -42,7 +42,7 @@ def test(self):
)
self.expect_expr("m_mem", result_value="4")
- # Test --ignore-context-qualifiers via SBExpressionOptions.
+ # Test --cpp-ignore-context-qualifiers via SBExpressionOptions.
options = lldb.SBExpressionOptions()
options.SetIgnoreContextQualifiers()
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
index 0069b42f5da10..40e5bff0aa60c 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
@@ -21,11 +21,11 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetIgnoreContextQualifiers()
+ options.SetCppIgnoreContextQualifiers()
options.SetIgnoreBreakpoints(True)
self.expect_expr("volatile_method()", options=options)
self.expect(
- "expression --ignore-context-qualifiers -- bar()",
+ "expression --cpp-ignore-context-qualifiers -- bar()",
error=True,
substrs=["call to member function 'bar' is ambiguous"],
)
@@ -47,7 +47,7 @@ def test(self):
self.expect_expr("const_method()", options=options)
self.expect(
- "expression --ignore-context-qualifiers -- bar()",
+ "expression --cpp-ignore-context-qualifiers -- bar()",
error=True,
substrs=["call to member function 'bar' is ambiguous"],
)
@@ -79,7 +79,7 @@ def test(self):
self.expect_expr("const_method()", options=options)
self.expect_expr("volatile_method()", options=options)
self.expect(
- "expression --ignore-context-qualifiers -- bar()",
+ "expression --cpp-ignore-context-qualifiers -- bar()",
error=True,
substrs=["call to member function 'bar' is ambiguous"],
)
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
index 78fe27508d10f..c26239adb34ca 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetIgnoreContextQualifiers()
+ options.SetCppIgnoreContextQualifiers()
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
index 8489f09b69bba..e4cd5ea759f60 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
@@ -30,7 +30,7 @@ def test(self):
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
options = lldb.SBExpressionOptions()
- options.SetIgnoreContextQualifiers()
+ options.SetCppIgnoreContextQualifiers()
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
index 78fe27508d10f..c26239adb34ca 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetIgnoreContextQualifiers()
+ options.SetCppIgnoreContextQualifiers()
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/this/TestCPPThis.py b/lldb/test/API/lang/cpp/this/TestCPPThis.py
index 5a59bf3631e82..cb462b0ae68de 100644
--- a/lldb/test/API/lang/cpp/this/TestCPPThis.py
+++ b/lldb/test/API/lang/cpp/this/TestCPPThis.py
@@ -48,7 +48,7 @@ def test_with_run_command(self):
self.expect("expression -- (int)getpid(); m_a", startstr="(const int) $1 = 3")
self.expect(
- "expression --ignore-context-qualifiers -- m_a = 2", startstr="(int) $2 = 2"
+ "expression --cpp-ignore-context-qualifiers -- m_a = 2", startstr="(int) $2 = 2"
)
self.runCmd("process continue")
>From db397cbcc61c9966ae480e68ad01c422cca91445 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 30 Jan 2026 11:21:53 +0000
Subject: [PATCH 3/9] fixup! python format
---
lldb/test/API/lang/cpp/this/TestCPPThis.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/lang/cpp/this/TestCPPThis.py b/lldb/test/API/lang/cpp/this/TestCPPThis.py
index cb462b0ae68de..3d87eba8fe05a 100644
--- a/lldb/test/API/lang/cpp/this/TestCPPThis.py
+++ b/lldb/test/API/lang/cpp/this/TestCPPThis.py
@@ -48,7 +48,8 @@ def test_with_run_command(self):
self.expect("expression -- (int)getpid(); m_a", startstr="(const int) $1 = 3")
self.expect(
- "expression --cpp-ignore-context-qualifiers -- m_a = 2", startstr="(int) $2 = 2"
+ "expression --cpp-ignore-context-qualifiers -- m_a = 2",
+ startstr="(int) $2 = 2",
)
self.runCmd("process continue")
>From 2254e5f94333cfb7312bc360b35b80665121f81e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 30 Jan 2026 11:24:16 +0000
Subject: [PATCH 4/9] fixup! fix typo
---
lldb/include/lldb/Target/Target.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 6181da9041566..daaef03c0d1ef 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -546,7 +546,7 @@ class EvaluateExpressionOptions {
/// disallowed by C++ language rules).
///
/// FIXME: move this to a language-specific dictionary of options.
- bool m_cpp_ignore_context_qualifierss = false;
+ bool m_cpp_ignore_context_qualifiers = false;
};
// Target
>From 5c7f16fcdff8999deeebe17e2ea90c29a66788bb Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 30 Jan 2026 12:40:41 +0000
Subject: [PATCH 5/9] fixup! rename option
---
.../const_method/TestExprInConstMethod.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
index b501836a46483..74a68aae4817a 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
@@ -44,7 +44,7 @@ def test(self):
# Test --cpp-ignore-context-qualifiers via SBExpressionOptions.
options = lldb.SBExpressionOptions()
- options.SetIgnoreContextQualifiers()
+ options.SetCppIgnoreContextQualifiers()
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
>From dbe0688a0f45c30814d0e253244fb293724de16c Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 4 Feb 2026 15:32:43 +0000
Subject: [PATCH 6/9] fixup! rebase on new (S|G)etBooleanLanguageOption APIs
---
lldb/include/lldb/Target/Target.h | 7 +++++--
lldb/source/Target/Target.cpp | 20 +++++++++++++++++++
.../const_method/TestExprInConstMethod.py | 2 +-
.../TestExprInConstVolatileMethod.py | 2 +-
.../TestExprInNonConstMethod.py | 2 +-
.../TestExprInTemplateConstMethod.py | 2 +-
.../TestExprInTemplateNonConstMethod.py | 2 +-
7 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index daaef03c0d1ef..264074728faad 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -308,8 +308,7 @@ class TargetProperties : public Properties {
class EvaluateExpressionOptions {
public:
- EvaluateExpressionOptions()
- : m_language_options_sp(std::make_shared<StructuredData::Dictionary>()) {}
+ EvaluateExpressionOptions();
// MSVC has a bug here that reports C4268: 'const' static/global data
// initialized with compiler generated default constructor fills the object
@@ -494,6 +493,10 @@ class EvaluateExpressionOptions {
llvm::Expected<bool>
GetBooleanLanguageOption(llvm::StringRef option_name) const;
+ void SetCppIgnoreContextQualifiers(bool value);
+
+ bool GetCppIgnoreContextQualifiers() const;
+
private:
const StructuredData::Dictionary &GetLanguageOptions() const;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 301dbdc6da9be..42fd9eb92157c 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -5409,3 +5409,23 @@ StructuredData::Dictionary &EvaluateExpressionOptions::GetLanguageOptions() {
return *m_language_options_sp;
}
+
+// FIXME: this option is C++ plugin specific and should be registered by it,
+// instead of hard-coding it here.
+constexpr llvm::StringLiteral s_cpp_ignore_context_qualifiers_option =
+ "cpp-ignore-context-qualifiers";
+
+EvaluateExpressionOptions::EvaluateExpressionOptions()
+ : m_language_options_sp(std::make_shared<StructuredData::Dictionary>()) {
+ SetCppIgnoreContextQualifiers(false);
+}
+
+void EvaluateExpressionOptions::SetCppIgnoreContextQualifiers(bool value) {
+ llvm::cantFail(
+ SetBooleanLanguageOption(s_cpp_ignore_context_qualifiers_option, value));
+}
+
+bool EvaluateExpressionOptions::GetCppIgnoreContextQualifiers() const {
+ return llvm::cantFail(
+ GetBooleanLanguageOption(s_cpp_ignore_context_qualifiers_option));
+}
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
index 74a68aae4817a..c0f945d05340e 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
@@ -44,7 +44,7 @@ def test(self):
# Test --cpp-ignore-context-qualifiers via SBExpressionOptions.
options = lldb.SBExpressionOptions()
- options.SetCppIgnoreContextQualifiers()
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
index 40e5bff0aa60c..ab4a141cc3581 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
@@ -21,7 +21,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetCppIgnoreContextQualifiers()
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
options.SetIgnoreBreakpoints(True)
self.expect_expr("volatile_method()", options=options)
self.expect(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
index c26239adb34ca..179415c927397 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetCppIgnoreContextQualifiers()
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
index e4cd5ea759f60..c3f5f732ddf4f 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
@@ -30,7 +30,7 @@ def test(self):
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
options = lldb.SBExpressionOptions()
- options.SetCppIgnoreContextQualifiers()
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
index c26239adb34ca..179415c927397 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetCppIgnoreContextQualifiers()
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
>From 14020df8aeadc7ffb4591297c4f1c2d4e1163eb7 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 4 Feb 2026 16:40:44 +0000
Subject: [PATCH 7/9] fixup! remove unused member variable
---
lldb/include/lldb/Target/Target.h | 8 --------
1 file changed, 8 deletions(-)
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 264074728faad..f781c4dabdd9f 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -542,14 +542,6 @@ class EvaluateExpressionOptions {
/// used for symbol/function lookup before any other context (except for
/// the module corresponding to the current frame).
SymbolContextList m_preferred_lookup_contexts;
-
- /// If true, evaluates the expression without taking into account the
- /// CV-qualifiers of the scope. E.g., this would permit calling a
- /// non-const C++ method when stopped in a const-method (which would be
- /// disallowed by C++ language rules).
- ///
- /// FIXME: move this to a language-specific dictionary of options.
- bool m_cpp_ignore_context_qualifiers = false;
};
// Target
>From b17008dfc9fb28dff86de1b307e8b6d155c34150 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 4 Feb 2026 17:01:43 +0000
Subject: [PATCH 8/9] fixup! fix tests
---
.../const_method/TestExprInConstMethod.py | 2 +-
.../const_volatile_method/TestExprInConstVolatileMethod.py | 2 +-
.../non_const_method/TestExprInNonConstMethod.py | 2 +-
.../template_const_method/TestExprInTemplateConstMethod.py | 2 +-
.../TestExprInTemplateNonConstMethod.py | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
index c0f945d05340e..233ad5947848d 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
@@ -44,7 +44,7 @@ def test(self):
# Test --cpp-ignore-context-qualifiers via SBExpressionOptions.
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
index ab4a141cc3581..3b938d2f13119 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
@@ -21,7 +21,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
options.SetIgnoreBreakpoints(True)
self.expect_expr("volatile_method()", options=options)
self.expect(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
index 179415c927397..39150d6031500 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
index c3f5f732ddf4f..7fac61f65ba3b 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
@@ -30,7 +30,7 @@ def test(self):
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
index 179415c927397..39150d6031500 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers")
+ options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
>From d5ac01d53e6be171c2ce9084a394a2459cd6a39d Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 4 Feb 2026 23:35:28 +0000
Subject: [PATCH 9/9] fixup! cpp -> c++
---
lldb/source/Commands/Options.td | 2 +-
lldb/source/Target/Target.cpp | 2 +-
.../const_method/TestExprInConstMethod.py | 8 ++++----
.../TestExprInConstVolatileMethod.py | 8 ++++----
.../non_const_method/TestExprInNonConstMethod.py | 2 +-
.../TestExprInTemplateConstMethod.py | 2 +-
.../TestExprInTemplateNonConstMethod.py | 2 +-
lldb/test/API/lang/cpp/this/TestCPPThis.py | 2 +-
8 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 72bb5df4dddac..8e1b921f47c3d 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -779,7 +779,7 @@ let Command = "expression" in {
"Expression results will be labeled with $-prefixed variables, "
"e.g. $0, $1, etc.">;
def ignore_context_qualifiers
- : Option<"cpp-ignore-context-qualifiers", "Q">,
+ : Option<"c++-ignore-context-qualifiers", "Q">,
Groups<[1, 2]>,
Desc<"When specified, evaluates the expression without taking into "
"account the type ${Q}ualifiers of the scope. In C++, this would "
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 42fd9eb92157c..d9e72cd5453e4 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -5413,7 +5413,7 @@ StructuredData::Dictionary &EvaluateExpressionOptions::GetLanguageOptions() {
// FIXME: this option is C++ plugin specific and should be registered by it,
// instead of hard-coding it here.
constexpr llvm::StringLiteral s_cpp_ignore_context_qualifiers_option =
- "cpp-ignore-context-qualifiers";
+ "c++-ignore-context-qualifiers";
EvaluateExpressionOptions::EvaluateExpressionOptions()
: m_language_options_sp(std::make_shared<StructuredData::Dictionary>()) {
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
index 233ad5947848d..25c76b69aa3ab 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_method/TestExprInConstMethod.py
@@ -29,9 +29,9 @@ def test(self):
)
self.expect_expr("m_mem", result_value="-2")
- # Test short and long --cpp-ignore-context-qualifiers option.
+ # Test short and long --c++-ignore-context-qualifiers option.
self.expect(
- "expression --cpp-ignore-context-qualifiers -- m_mem = 3.0",
+ "expression --c++-ignore-context-qualifiers -- m_mem = 3.0",
error=False,
)
self.expect_expr("m_mem", result_value="3")
@@ -42,9 +42,9 @@ def test(self):
)
self.expect_expr("m_mem", result_value="4")
- # Test --cpp-ignore-context-qualifiers via SBExpressionOptions.
+ # Test --c++-ignore-context-qualifiers via SBExpressionOptions.
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
+ options.SetBooleanLanguageOption("c++-ignore-context-qualifiers", True)
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
index 3b938d2f13119..f1bcfb3c0827d 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/const_volatile_method/TestExprInConstVolatileMethod.py
@@ -21,11 +21,11 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
+ options.SetBooleanLanguageOption("c++-ignore-context-qualifiers", True)
options.SetIgnoreBreakpoints(True)
self.expect_expr("volatile_method()", options=options)
self.expect(
- "expression --cpp-ignore-context-qualifiers -- bar()",
+ "expression --c++-ignore-context-qualifiers -- bar()",
error=True,
substrs=["call to member function 'bar' is ambiguous"],
)
@@ -47,7 +47,7 @@ def test(self):
self.expect_expr("const_method()", options=options)
self.expect(
- "expression --cpp-ignore-context-qualifiers -- bar()",
+ "expression --c++-ignore-context-qualifiers -- bar()",
error=True,
substrs=["call to member function 'bar' is ambiguous"],
)
@@ -79,7 +79,7 @@ def test(self):
self.expect_expr("const_method()", options=options)
self.expect_expr("volatile_method()", options=options)
self.expect(
- "expression --cpp-ignore-context-qualifiers -- bar()",
+ "expression --c++-ignore-context-qualifiers -- bar()",
error=True,
substrs=["call to member function 'bar' is ambiguous"],
)
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
index 39150d6031500..f6358d2037095 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/non_const_method/TestExprInNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
+ options.SetBooleanLanguageOption("c++-ignore-context-qualifiers", True)
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
index 7fac61f65ba3b..cdaa06b8808b5 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_const_method/TestExprInTemplateConstMethod.py
@@ -30,7 +30,7 @@ def test(self):
self.expect_expr("((Foo*)this)->bar()", result_type="double", result_value="5")
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
+ options.SetBooleanLanguageOption("c++-ignore-context-qualifiers", True)
self.expect_expr("m_mem = -2.0; m_mem", options=options, result_value="-2")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
index 39150d6031500..f6358d2037095 100644
--- a/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
+++ b/lldb/test/API/lang/cpp/expression-context-qualifiers/template_non_const_method/TestExprInTemplateNonConstMethod.py
@@ -37,7 +37,7 @@ def test(self):
)
options = lldb.SBExpressionOptions()
- options.SetBooleanLanguageOption("cpp-ignore-context-qualifiers", True)
+ options.SetBooleanLanguageOption("c++-ignore-context-qualifiers", True)
self.expect_expr("x = 6.0; x", options=options, result_value="6")
lldbutil.continue_to_source_breakpoint(
diff --git a/lldb/test/API/lang/cpp/this/TestCPPThis.py b/lldb/test/API/lang/cpp/this/TestCPPThis.py
index 3d87eba8fe05a..4c4db30589fbf 100644
--- a/lldb/test/API/lang/cpp/this/TestCPPThis.py
+++ b/lldb/test/API/lang/cpp/this/TestCPPThis.py
@@ -48,7 +48,7 @@ def test_with_run_command(self):
self.expect("expression -- (int)getpid(); m_a", startstr="(const int) $1 = 3")
self.expect(
- "expression --cpp-ignore-context-qualifiers -- m_a = 2",
+ "expression --c++-ignore-context-qualifiers -- m_a = 2",
startstr="(int) $2 = 2",
)
More information about the lldb-commits
mailing list