summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Expression/ASTResultSynthesizer.h6
-rw-r--r--lldb/include/lldb/Expression/ClangExpression.h15
-rw-r--r--lldb/include/lldb/Expression/ClangUserExpression.h32
-rw-r--r--lldb/include/lldb/Target/Target.h1
-rw-r--r--lldb/scripts/clang.DebuggerCastResultToId.diff25
-rw-r--r--lldb/source/API/SBFrame.cpp2
-rw-r--r--lldb/source/API/SBValue.cpp1
-rw-r--r--lldb/source/Breakpoint/BreakpointOptions.cpp12
-rw-r--r--lldb/source/Breakpoint/Watchpoint.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp1
-rw-r--r--lldb/source/Expression/ASTResultSynthesizer.cpp4
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp3
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp19
-rw-r--r--lldb/source/Interpreter/CommandInterpreter.cpp5
-rw-r--r--lldb/source/Target/Process.cpp4
-rw-r--r--lldb/source/Target/StopInfo.cpp2
-rw-r--r--lldb/source/Target/Target.cpp2
-rw-r--r--lldb/test/lang/objc/foundation/TestObjCMethods2.py28
18 files changed, 125 insertions, 39 deletions
diff --git a/lldb/include/lldb/Expression/ASTResultSynthesizer.h b/lldb/include/lldb/Expression/ASTResultSynthesizer.h
index 2b5cac1e387..79709de3546 100644
--- a/lldb/include/lldb/Expression/ASTResultSynthesizer.h
+++ b/lldb/include/lldb/Expression/ASTResultSynthesizer.h
@@ -41,16 +41,11 @@ public:
/// pass to the next step in the chain after processing. Passthrough is
/// the next ASTConsumer, or NULL if none is required.
///
- /// @param[in] desired_type
- /// The type that the result should have. May be initialized with a
- /// NULL type, in which case the type is inferred.
- ///
/// @param[in] target
/// The target, which contains the persistent variable store and the
/// AST importer.
//----------------------------------------------------------------------
ASTResultSynthesizer(clang::ASTConsumer *passthrough,
- TypeFromUser desired_type,
Target &target);
//----------------------------------------------------------------------
@@ -182,7 +177,6 @@ private:
clang::SemaConsumer *m_passthrough_sema; ///< The SemaConsumer down the chain, for passthrough. NULL if it's an ASTConsumer.
Target &m_target; ///< The target, which contains the persistent variable store and the
clang::Sema *m_sema; ///< The Sema to use.
- TypeFromUser m_desired_type; ///< If non-NULL, the type to coerce the result to.
};
}
diff --git a/lldb/include/lldb/Expression/ClangExpression.h b/lldb/include/lldb/Expression/ClangExpression.h
index 435e7c7811d..b870dae07c6 100644
--- a/lldb/include/lldb/Expression/ClangExpression.h
+++ b/lldb/include/lldb/Expression/ClangExpression.h
@@ -41,6 +41,11 @@ class RecordingMemoryManager;
class ClangExpression
{
public:
+ enum ResultType {
+ eResultTypeAny,
+ eResultTypeId
+ };
+
ClangExpression () :
m_jit_process_sp(),
m_jit_alloc (LLDB_INVALID_ADDRESS),
@@ -108,6 +113,16 @@ public:
ASTTransformer (clang::ASTConsumer *passthrough) = 0;
//------------------------------------------------------------------
+ /// Return the desired result type of the function, or
+ /// eResultTypeAny if indifferent.
+ //------------------------------------------------------------------
+ virtual ResultType
+ DesiredResultType ()
+ {
+ return eResultTypeAny;
+ }
+
+ //------------------------------------------------------------------
/// Flags
//------------------------------------------------------------------
diff --git a/lldb/include/lldb/Expression/ClangUserExpression.h b/lldb/include/lldb/Expression/ClangUserExpression.h
index 6ce1c374d63..9e0080312b1 100644
--- a/lldb/include/lldb/Expression/ClangUserExpression.h
+++ b/lldb/include/lldb/Expression/ClangUserExpression.h
@@ -48,7 +48,7 @@ class ClangUserExpression : public ClangExpression
{
public:
typedef lldb::SharedPtr<ClangUserExpression>::Type ClangUserExpressionSP;
-
+
//------------------------------------------------------------------
/// Constructor
///
@@ -63,10 +63,15 @@ public:
/// If not eLanguageTypeUnknown, a language to use when parsing
/// the expression. Currently restricted to those languages
/// supported by Clang.
+ ///
+ /// @param[in] desired_type
+ /// If not eResultTypeAny, the type to use for the expression
+ /// result.
//------------------------------------------------------------------
ClangUserExpression (const char *expr,
const char *expr_prefix,
- lldb::LanguageType language);
+ lldb::LanguageType language,
+ ResultType desired_type);
//------------------------------------------------------------------
/// Destructor
@@ -85,10 +90,6 @@ public:
/// are needed for parsing (locations of functions, types of
/// variables, persistent variables, etc.)
///
- /// @param[in] desired_type
- /// The type that the expression should be coerced to. If NULL,
- /// inferred from the expression itself.
- ///
/// @param[in] execution_policy
/// Determines whether interpretation is possible or mandatory.
///
@@ -102,7 +103,6 @@ public:
bool
Parse (Stream &error_stream,
ExecutionContext &exe_ctx,
- TypeFromUser desired_type,
lldb_private::ExecutionPolicy execution_policy,
bool keep_result_in_memory);
@@ -247,6 +247,16 @@ public:
ASTTransformer (clang::ASTConsumer *passthrough);
//------------------------------------------------------------------
+ /// Return the desired result type of the function, or
+ /// eResultTypeAny if indifferent.
+ //------------------------------------------------------------------
+ virtual ResultType
+ DesiredResultType ()
+ {
+ return m_desired_type;
+ }
+
+ //------------------------------------------------------------------
/// Return true if validation code should be inserted into the
/// expression.
//------------------------------------------------------------------
@@ -285,6 +295,10 @@ public:
/// True if the thread's state should be restored in the case
/// of an error.
///
+ /// @param[in] result_type
+ /// If not eResultTypeAny, the type of the desired result. Will
+ /// result in parse errors if impossible.
+ ///
/// @param[in] expr_cstr
/// A C string containing the expression to be evaluated.
///
@@ -302,6 +316,7 @@ public:
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,
@@ -311,6 +326,7 @@ public:
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,
@@ -346,7 +362,7 @@ private:
bool m_allow_cxx; ///< True if the language allows C++.
bool m_allow_objc; ///< True if the language allows Objective-C.
std::string m_transformed_text; ///< The text of the expression, as send to the parser
- TypeFromUser m_desired_type; ///< The type to coerce the expression's result to. If NULL, inferred from the expression.
+ ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression.
std::auto_ptr<ClangExpressionDeclMap> m_expr_decl_map; ///< The map to use when parsing and materializing the expression.
std::auto_ptr<ClangExpressionVariableList> m_local_variables; ///< The local expression variables, if the expression is DWARF.
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 70ed0434c6c..a202fb8ee6c 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -816,6 +816,7 @@ public:
EvaluateExpression (const char *expression,
StackFrame *frame,
lldb_private::ExecutionPolicy execution_policy,
+ bool coerce_to_id,
bool unwind_on_error,
bool keep_in_memory,
lldb::DynamicValueType use_dynamic,
diff --git a/lldb/scripts/clang.DebuggerCastResultToId.diff b/lldb/scripts/clang.DebuggerCastResultToId.diff
new file mode 100644
index 00000000000..01fe8a2f064
--- /dev/null
+++ b/lldb/scripts/clang.DebuggerCastResultToId.diff
@@ -0,0 +1,25 @@
+Index: include/clang/Basic/LangOptions.def
+===================================================================
+--- include/clang/Basic/LangOptions.def (revision 146622)
++++ include/clang/Basic/LangOptions.def (working copy)
+@@ -121,6 +121,7 @@
+ BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods")
+ BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
+ BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
++BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
+ BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled")
+
+ BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
+Index: lib/Sema/SemaExprCXX.cpp
+===================================================================
+--- lib/Sema/SemaExprCXX.cpp (revision 146622)
++++ lib/Sema/SemaExprCXX.cpp (working copy)
+@@ -4675,7 +4675,7 @@
+ return ExprError();
+
+ // Top-level message sends default to 'id' when we're in a debugger.
+- if (getLangOptions().DebuggerSupport &&
++ if (getLangOptions().DebuggerCastResultToId &&
+ FullExpr.get()->getType() == Context.UnknownAnyTy &&
+ isa<ObjCMessageExpr>(FullExpr.get())) {
+ FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType());
diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp
index a541047e9ad..3a3c5823827 100644
--- a/lldb/source/API/SBFrame.cpp
+++ b/lldb/source/API/SBFrame.cpp
@@ -756,12 +756,14 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna
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/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 654336db8c5..1ed3fea133a 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -388,6 +388,7 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression)
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/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp
index c2277dbc910..79ffa32e3a2 100644
--- a/lldb/source/Breakpoint/BreakpointOptions.cpp
+++ b/lldb/source/Breakpoint/BreakpointOptions.cpp
@@ -60,7 +60,7 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) :
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 @@ BreakpointOptions::operator=(const BreakpointOptions& rhs)
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 @@ BreakpointOptions::SetCondition (const char *condition)
}
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 @@ BreakpointOptions::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx,
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/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp
index 4645b6072e0..e9b314b24ac 100644
--- a/lldb/source/Breakpoint/Watchpoint.cpp
+++ b/lldb/source/Breakpoint/Watchpoint.cpp
@@ -212,7 +212,7 @@ Watchpoint::SetCondition (const char *condition)
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/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 5134b28b08d..e2ce4b2cf89 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -312,6 +312,7 @@ CommandObjectExpression::EvaluateExpression
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/lldb/source/Expression/ASTResultSynthesizer.cpp b/lldb/source/Expression/ASTResultSynthesizer.cpp
index 0df2a5ec690..de17ebd792a 100644
--- a/lldb/source/Expression/ASTResultSynthesizer.cpp
+++ b/lldb/source/Expression/ASTResultSynthesizer.cpp
@@ -30,14 +30,12 @@ using namespace clang;
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/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp
index 351c4847170..912822399dc 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -245,7 +245,10 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
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/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 8f011c089d9..c2164c80037 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -45,13 +45,14 @@ using namespace lldb_private;
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 @@ ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
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 @@ ApplyUnicharHack(std::string &expr)
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 @@ ClangUserExpression::Parse (Stream &error_stream,
//////////////////////////
// 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 @@ ExecutionResults
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 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
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 @@ ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
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/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index bce32beb6f1..77cab233b7a 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -1112,13 +1112,16 @@ CommandInterpreter::PreprocessCommand (std::string &command)
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/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index fdd6b1753c7..50bcb7a952a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1328,7 +1328,7 @@ Process::LoadImage (const FileSpec &image_spec, Error &error)
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 @@ Process::UnloadImage (uint32_t image_token)
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/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index f90968fdad7..00c76802922 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -225,6 +225,7 @@ public:
result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
eExecutionPolicyAlways,
lldb::eLanguageTypeUnknown,
+ ClangUserExpression::eResultTypeAny,
discard_on_error,
bp_loc_sp->GetConditionText(),
NULL,
@@ -494,6 +495,7 @@ public:
result_code = ClangUserExpression::EvaluateWithError (context.exe_ctx,
eExecutionPolicyAlways,
lldb::eLanguageTypeUnknown,
+ ClangUserExpression::eResultTypeAny,
discard_on_error,
wp_sp->GetConditionText(),
NULL,
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 902ffc77ac7..c31b0b1d9d4 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1462,6 +1462,7 @@ Target::EvaluateExpression
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 @@ Target::EvaluateExpression
execution_results = ClangUserExpression::Evaluate (exe_ctx,
execution_policy,
lldb::eLanguageTypeUnknown,
+ coerce_to_id ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
unwind_on_error,
expr_cstr,
prefix,
diff --git a/lldb/test/lang/objc/foundation/TestObjCMethods2.py b/lldb/test/lang/objc/foundation/TestObjCMethods2.py
index 83d772b773f..6b10afc5e24 100644
--- a/lldb/test/lang/objc/foundation/TestObjCMethods2.py
+++ b/lldb/test/lang/objc/foundation/TestObjCMethods2.py
@@ -61,6 +61,16 @@ class FoundationTestCase2(TestBase):
"""Test that po of the result of an unknown method doesn't require a cast."""
self.buildDsym()
self.NSError_po()
+
+ def test_NSError_p_with_dsym(self):
+ """Test that p of the result of an unknown method does require a cast."""
+ self.buildDsym()
+ self.NSError_p()
+
+ def test_NSError_p_with_dwarf(self):
+ """Test that p of the result of an unknown method does require a cast."""
+ self.buildDsym()
+ self.NSError_p()
def setUp(self):
# Call super's setUp().
@@ -204,6 +214,24 @@ class FoundationTestCase2(TestBase):
patterns = ["\(id\) \$.* = ", "Error Domain=Hello", "Code=35", "be completed."])
self.runCmd("process continue")
+ def NSError_p(self):
+ """Test that p of the result of an unknown method does require a cast."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ line = self.lines[4]
+
+ self.expect("breakpoint set -f main.m -l %d" % line, BREAKPOINT_CREATED,
+ substrs = ["Breakpoint created:",
+ "file ='main.m', line = %d, locations = 1" % line])
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.expect("p [NSError errorWithDomain:@\"Hello\" code:35 userInfo:nil]",
+ error = True,
+ patterns = ["no known method", "cast the message send to the method's return type"])
+ self.runCmd("process continue")
+
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
OpenPOWER on IntegriCloud