The "desired result type" code in the expression
parser has hitherto been an implementation waiting
for a use. I have now tied the '-o' option for
the expression command -- which indicates that the
result is an Objective-C object and needs to be
printed -- to the ExpressionParser, which
communicates the desired type to Clang.
Now, if the result of an expression is determined
by an Objective-C method call for which there is
no type information, that result is implicitly
cast to id if and only if the -o option is passed
to the expression command. (Otherwise if there
is no explicit cast Clang will issue an error.
This behavior is identical to what happened before
r146756.)
Also added a testcase for -o enabled and disabled.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@147099 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp
index a541047..3a3c582 100644
--- a/source/API/SBFrame.cpp
+++ b/source/API/SBFrame.cpp
@@ -756,12 +756,14 @@
Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
expr, fetch_dynamic_value, frame_description.GetString().c_str());
+ const bool coerce_to_id = false;
const bool unwind_on_error = true;
const bool keep_in_memory = false;
exe_results = m_opaque_sp->GetThread().GetProcess().GetTarget().EvaluateExpression(expr,
m_opaque_sp.get(),
eExecutionPolicyOnlyWhenNeeded,
+ coerce_to_id,
unwind_on_error,
keep_in_memory,
fetch_dynamic_value,
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 654336d..1ed3fea 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -388,6 +388,7 @@
m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression,
m_opaque_sp->GetExecutionContextScope()->CalculateStackFrame(),
eExecutionPolicyOnlyWhenNeeded,
+ false, // coerce to id
true, // unwind on error
true, // keep in memory
eNoDynamicValues,
diff --git a/source/Breakpoint/BreakpointOptions.cpp b/source/Breakpoint/BreakpointOptions.cpp
index c2277db..79ffa32 100644
--- a/source/Breakpoint/BreakpointOptions.cpp
+++ b/source/Breakpoint/BreakpointOptions.cpp
@@ -60,7 +60,7 @@
if (rhs.m_thread_spec_ap.get() != NULL)
m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
if (rhs.m_condition_ap.get())
- m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown));
+ m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
}
//----------------------------------------------------------------------
@@ -77,7 +77,7 @@
if (rhs.m_thread_spec_ap.get() != NULL)
m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
if (rhs.m_condition_ap.get())
- m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown));
+ m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText(), NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
return *this;
}
@@ -166,7 +166,7 @@
}
else
{
- m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown));
+ m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
}
}
@@ -196,13 +196,9 @@
process->SetDynamicCheckers(dynamic_checkers);
}
- // Get the boolean type from the process's scratch AST context
- ClangASTContext *ast_context = exe_ctx.GetTargetRef().GetScratchClangASTContext();
- TypeFromUser bool_type(ast_context->GetBuiltInType_bool(), ast_context->getASTContext());
-
const bool keep_in_memory = false;
- if (!m_condition_ap->Parse (error_stream, exe_ctx, bool_type, eExecutionPolicyAlways, keep_in_memory))
+ if (!m_condition_ap->Parse (error_stream, exe_ctx, eExecutionPolicyAlways, keep_in_memory))
{
// Errors mean we should stop.
return NULL;
diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp
index 4645b60..e9b314b 100644
--- a/source/Breakpoint/Watchpoint.cpp
+++ b/source/Breakpoint/Watchpoint.cpp
@@ -212,7 +212,7 @@
else
{
// Pass NULL for expr_prefix (no translation-unit level definitions).
- m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown));
+ m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
}
}
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index 5134b28..e2ce4b2 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -312,6 +312,7 @@
exe_results = target->EvaluateExpression (expr,
m_exe_ctx.GetFramePtr(),
eExecutionPolicyOnlyWhenNeeded,
+ m_command_options.print_object,
m_command_options.unwind_on_error,
keep_in_memory,
use_dynamic,
diff --git a/source/Expression/ASTResultSynthesizer.cpp b/source/Expression/ASTResultSynthesizer.cpp
index 0df2a5e..de17ebd 100644
--- a/source/Expression/ASTResultSynthesizer.cpp
+++ b/source/Expression/ASTResultSynthesizer.cpp
@@ -30,14 +30,12 @@
using namespace lldb_private;
ASTResultSynthesizer::ASTResultSynthesizer(ASTConsumer *passthrough,
- TypeFromUser desired_type,
Target &target) :
m_ast_context (NULL),
m_passthrough (passthrough),
m_passthrough_sema (NULL),
m_target (target),
- m_sema (NULL),
- m_desired_type (desired_type)
+ m_sema (NULL)
{
if (!m_passthrough)
return;
diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp
index 351c484..9128223 100644
--- a/source/Expression/ClangExpressionParser.cpp
+++ b/source/Expression/ClangExpressionParser.cpp
@@ -245,7 +245,10 @@
m_compiler->getLangOpts().ThreadsafeStatics = false;
m_compiler->getLangOpts().AccessControl = false; // Debuggers get universal access
m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name
+
m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
+ if (expr.DesiredResultType() == ClangExpression::eResultTypeId)
+ m_compiler->getLangOpts().DebuggerCastResultToId = true;
// Set CodeGen options
m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
diff --git a/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index 8f011c0..c2164c8 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -45,13 +45,14 @@
ClangUserExpression::ClangUserExpression (const char *expr,
const char *expr_prefix,
- lldb::LanguageType language) :
+ lldb::LanguageType language,
+ ResultType desired_type) :
ClangExpression (),
m_expr_text (expr),
m_expr_prefix (expr_prefix ? expr_prefix : ""),
m_language (language),
m_transformed_text (),
- m_desired_type (NULL, NULL),
+ m_desired_type (desired_type),
m_cplusplus (false),
m_objectivec (false),
m_needs_object_ptr (false),
@@ -92,7 +93,6 @@
if (!m_result_synthesizer.get())
m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
- m_desired_type,
*m_target));
return m_result_synthesizer.get();
@@ -249,7 +249,6 @@
bool
ClangUserExpression::Parse (Stream &error_stream,
ExecutionContext &exe_ctx,
- TypeFromUser desired_type,
lldb_private::ExecutionPolicy execution_policy,
bool keep_result_in_memory)
{
@@ -308,9 +307,7 @@
//////////////////////////
// Parse the expression
//
-
- m_desired_type = desired_type;
-
+
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
if (!m_expr_decl_map->WillParse(exe_ctx))
@@ -638,19 +635,21 @@
ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
+ ResultType desired_type,
bool discard_on_error,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp)
{
Error error;
- return EvaluateWithError (exe_ctx, execution_policy, language, discard_on_error, expr_cstr, expr_prefix, result_valobj_sp, error);
+ return EvaluateWithError (exe_ctx, execution_policy, language, desired_type, discard_on_error, expr_cstr, expr_prefix, result_valobj_sp, error);
}
ExecutionResults
ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
+ ResultType desired_type,
bool discard_on_error,
const char *expr_cstr,
const char *expr_prefix,
@@ -679,7 +678,7 @@
if (process == NULL || !process->CanJIT())
execution_policy = eExecutionPolicyNever;
- ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language));
+ ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
StreamString error_stream;
@@ -688,7 +687,7 @@
const bool keep_expression_in_memory = true;
- if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL), execution_policy, keep_expression_in_memory))
+ if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
{
if (error_stream.GetString().empty())
error.SetErrorString ("expression failed to parse, unknown error");
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index bce32be..77cab23 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -1112,13 +1112,16 @@
target = Host::GetDummyTarget(GetDebugger()).get();
if (target)
{
+ const bool coerce_to_id = false;
const bool unwind_on_error = true;
const bool keep_in_memory = false;
ValueObjectSP expr_result_valobj_sp;
ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
m_exe_ctx.GetFramePtr(),
eExecutionPolicyOnlyWhenNeeded,
- unwind_on_error, keep_in_memory,
+ coerce_to_id,
+ unwind_on_error,
+ keep_in_memory,
eNoDynamicValues,
expr_result_valobj_sp);
if (expr_result == eExecutionCompleted)
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index fdd6b17..50bcb7a 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -1328,7 +1328,7 @@
expr.Printf("dlopen (\"%s\", 2)", path);
const char *prefix = "extern \"C\" void* dlopen (const char *path, int mode);\n";
lldb::ValueObjectSP result_valobj_sp;
- ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
+ ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
error = result_valobj_sp->GetError();
if (error.Success())
{
@@ -1392,7 +1392,7 @@
expr.Printf("dlclose ((void *)0x%llx)", image_addr);
const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
lldb::ValueObjectSP result_valobj_sp;
- ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
+ ClangUserExpression::Evaluate (exe_ctx, eExecutionPolicyAlways, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny, unwind_on_error, expr.GetData(), prefix, result_valobj_sp);
if (result_valobj_sp->GetError().Success())
{
Scalar scalar;
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index f90968f..00c7680 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -225,6 +225,7 @@
result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
eExecutionPolicyAlways,
lldb::eLanguageTypeUnknown,
+ ClangUserExpression::eResultTypeAny,
discard_on_error,
bp_loc_sp->GetConditionText(),
NULL,
@@ -494,6 +495,7 @@
result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
eExecutionPolicyAlways,
lldb::eLanguageTypeUnknown,
+ ClangUserExpression::eResultTypeAny,
discard_on_error,
wp_sp->GetConditionText(),
NULL,
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 902ffc7..c31b0b1 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -1462,6 +1462,7 @@
const char *expr_cstr,
StackFrame *frame,
lldb_private::ExecutionPolicy execution_policy,
+ bool coerce_to_id,
bool unwind_on_error,
bool keep_in_memory,
lldb::DynamicValueType use_dynamic,
@@ -1587,6 +1588,7 @@
execution_results = ClangUserExpression::Evaluate (exe_ctx,
execution_policy,
lldb::eLanguageTypeUnknown,
+ coerce_to_id ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
unwind_on_error,
expr_cstr,
prefix,