Skip to content

Commit 6be6655

Browse files
committed
[lldb][Expression] Add --ignore-const-context expression evaluation option
Depends on: * llvm#177920 * llvm#177922 In llvm#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.
1 parent 81429d8 commit 6be6655

File tree

20 files changed

+162
-33
lines changed

20 files changed

+162
-33
lines changed

lldb/include/lldb/API/SBExpressionOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class LLDB_API SBExpressionOptions {
107107
// Sets whether we will JIT an expression if it cannot be interpreted
108108
void SetAllowJIT(bool allow);
109109

110+
bool GetIgnoreConstContext();
111+
112+
void SetIgnoreConstContext(bool b = true);
113+
110114
protected:
111115
lldb_private::EvaluateExpressionOptions *get() const;
112116

lldb/include/lldb/Target/Target.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ class EvaluateExpressionOptions {
481481

482482
void SetIsForUtilityExpr(bool b) { m_running_utility_expression = b; }
483483

484+
bool GetIgnoreConstContext() const { return m_ignore_const_contexts; }
485+
486+
void SetIgnoreConstContext(bool val) { m_ignore_const_contexts = val; }
487+
484488
private:
485489
ExecutionPolicy m_execution_policy = default_execution_policy;
486490
SourceLanguage m_language;
@@ -518,6 +522,8 @@ class EvaluateExpressionOptions {
518522
/// used for symbol/function lookup before any other context (except for
519523
/// the module corresponding to the current frame).
520524
SymbolContextList m_preferred_lookup_contexts;
525+
526+
bool m_ignore_const_contexts = false;
521527
};
522528

523529
// Target

lldb/source/API/SBExpressionOptions.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,18 @@ void SBExpressionOptions::SetAllowJIT(bool allow) {
256256
: eExecutionPolicyNever);
257257
}
258258

259+
bool SBExpressionOptions::GetIgnoreConstContext() {
260+
LLDB_INSTRUMENT_VA(this);
261+
262+
return m_opaque_up->GetIgnoreConstContext();
263+
}
264+
265+
void SBExpressionOptions::SetIgnoreConstContext(bool b) {
266+
LLDB_INSTRUMENT_VA(this, b);
267+
268+
m_opaque_up->SetIgnoreConstContext(b);
269+
}
270+
259271
EvaluateExpressionOptions *SBExpressionOptions::get() const {
260272
return m_opaque_up.get();
261273
}

lldb/source/Commands/CommandObjectExpression.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "lldb/lldb-enumerations.h"
2626
#include "lldb/lldb-forward.h"
2727
#include "lldb/lldb-private-enumerations.h"
28+
#include <tuple>
2829

2930
using namespace lldb;
3031
using namespace lldb_private;
@@ -44,6 +45,9 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue(
4445
const int short_option = GetDefinitions()[option_idx].short_option;
4546

4647
switch (short_option) {
48+
case 'K':
49+
ignore_const_context = true;
50+
break;
4751
case 'l':
4852
language = Language::GetLanguageTypeFromString(option_arg);
4953
if (language == eLanguageTypeUnknown) {
@@ -191,6 +195,7 @@ void CommandObjectExpression::CommandOptions::OptionParsingStarting(
191195
top_level = false;
192196
allow_jit = true;
193197
suppress_persistent_result = eLazyBoolCalculate;
198+
ignore_const_context = false;
194199
}
195200

196201
llvm::ArrayRef<OptionDefinition>
@@ -213,6 +218,7 @@ CommandObjectExpression::CommandOptions::GetEvaluateExpressionOptions(
213218
options.SetExecutionPolicy(
214219
allow_jit ? EvaluateExpressionOptions::default_execution_policy
215220
: lldb_private::eExecutionPolicyNever);
221+
options.SetIgnoreConstContext(ignore_const_context);
216222

217223
bool auto_apply_fixits;
218224
if (this->auto_apply_fixits == eLazyBoolCalculate)

lldb/source/Commands/CommandObjectExpression.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class CommandObjectExpression : public CommandObjectRaw,
5757
LanguageRuntimeDescriptionDisplayVerbosity m_verbosity;
5858
LazyBool auto_apply_fixits;
5959
LazyBool suppress_persistent_result;
60+
bool ignore_const_context;
6061
};
6162

6263
CommandObjectExpression(CommandInterpreter &interpreter);

lldb/source/Commands/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,9 @@ let Command = "expression" in {
778778
Desc<"Persist expression result in a variable for subsequent use. "
779779
"Expression results will be labeled with $-prefixed variables, "
780780
"e.g. $0, $1, etc.">;
781+
def ignore_const_context : Option<"ignore-const-context", "K">,
782+
Groups<[1, 2]>,
783+
Desc<"TODO">;
781784
}
782785

783786
let Command = "frame diag" in {

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,12 @@ ClangExpressionDeclMap::ClangExpressionDeclMap(
8888
bool keep_result_in_memory,
8989
Materializer::PersistentVariableDelegate *result_delegate,
9090
const lldb::TargetSP &target,
91-
const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)
91+
const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj,
92+
bool ignore_const_context)
9293
: ClangASTSource(target, importer), m_found_entities(), m_struct_members(),
9394
m_keep_result_in_memory(keep_result_in_memory),
94-
m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
95+
m_result_delegate(result_delegate), m_ctx_obj(ctx_obj),
96+
m_ignore_const_context(ignore_const_context), m_parser_vars(),
9597
m_struct_vars() {
9698
EnableStructVars();
9799
}
@@ -1997,7 +1999,8 @@ void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
19971999
std::array<CompilerType, 1> args{void_clang_type.GetPointerType()};
19982000

19992001
CompilerType method_type = m_clang_ast_context->CreateFunctionType(
2000-
void_clang_type, args, false, ut.GetTypeQualifiers());
2002+
void_clang_type, args, false,
2003+
m_ignore_const_context ? 0 : ut.GetTypeQualifiers());
20012004

20022005
const bool is_virtual = false;
20032006
const bool is_static = false;

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ class ClangExpressionDeclMap : public ClangASTSource {
8282
bool keep_result_in_memory,
8383
Materializer::PersistentVariableDelegate *result_delegate,
8484
const lldb::TargetSP &target,
85-
const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj);
85+
const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj,
86+
bool ignore_const_context);
8687

8788
/// Destructor
8889
~ClangExpressionDeclMap() override;
@@ -306,6 +307,8 @@ class ClangExpressionDeclMap : public ClangASTSource {
306307
///For details see the comment to
307308
///`UserExpression::Evaluate`.
308309

310+
bool m_ignore_const_context = false;
311+
309312
/// The following values should not live beyond parsing
310313
class ParserVars {
311314
public:

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,12 @@ void ClangExpressionSourceCode::AddLocalVariableDecls(StreamString &stream,
363363
}
364364
}
365365

366-
bool ClangExpressionSourceCode::GetText(
367-
std::string &text, ExecutionContext &exe_ctx, bool add_locals,
368-
bool force_add_all_locals, llvm::ArrayRef<std::string> modules) const {
366+
bool ClangExpressionSourceCode::GetText(std::string &text,
367+
ExecutionContext &exe_ctx,
368+
bool add_locals,
369+
bool force_add_all_locals,
370+
llvm::ArrayRef<std::string> modules,
371+
bool ignore_const_context) const {
369372
const char *target_specific_defines = "typedef signed char BOOL;\n";
370373
std::string module_macros;
371374
llvm::raw_string_ostream module_macros_stream(module_macros);
@@ -486,17 +489,20 @@ bool ClangExpressionSourceCode::GetText(
486489
lldb_local_var_decls.GetData(), tagged_body.c_str());
487490
break;
488491
case WrapKind::CppMemberFunction:
489-
wrap_stream.Printf(
490-
"%s"
491-
"void \n"
492-
"$__lldb_class::%s(void *$__lldb_arg) %s \n"
493-
"{ \n"
494-
" %s; \n"
495-
"%s"
496-
"} \n",
497-
module_imports.c_str(), m_name.c_str(),
498-
GetFrameCVQualifiers(exe_ctx.GetFramePtr()).getAsString().c_str(),
499-
lldb_local_var_decls.GetData(), tagged_body.c_str());
492+
wrap_stream.Printf("%s"
493+
"void \n"
494+
"$__lldb_class::%s(void *$__lldb_arg) %s \n"
495+
"{ \n"
496+
" %s; \n"
497+
"%s"
498+
"} \n",
499+
module_imports.c_str(), m_name.c_str(),
500+
ignore_const_context
501+
? ""
502+
: GetFrameCVQualifiers(exe_ctx.GetFramePtr())
503+
.getAsString()
504+
.c_str(),
505+
lldb_local_var_decls.GetData(), tagged_body.c_str());
500506
break;
501507
case WrapKind::ObjCInstanceMethod:
502508
wrap_stream.Printf(

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ class ClangExpressionSourceCode : public ExpressionSourceCode {
6363
///
6464
/// \return true iff the source code was successfully generated.
6565
bool GetText(std::string &text, ExecutionContext &exe_ctx, bool add_locals,
66-
bool force_add_all_locals,
67-
llvm::ArrayRef<std::string> modules) const;
66+
bool force_add_all_locals, llvm::ArrayRef<std::string> modules,
67+
bool ignore_const_context) const;
6868

6969
// Given a string returned by GetText, find the beginning and end of the body
7070
// passed to CreateWrapped. Return true if the bounds could be found. This

0 commit comments

Comments
 (0)