blob: 7f09f6fa09423cb406d08a7954ba5327c6d5bd7f [file] [log] [blame]
Sean Callananc0492742011-05-23 21:40:23 +00001//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
Sean Callanan65dafa82010-08-27 01:01:44 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11#include <stdio.h>
12#if HAVE_SYS_TYPES_H
13# include <sys/types.h>
14#endif
15
16// C++ Includes
17#include <cstdlib>
18#include <string>
19#include <map>
20
21#include "lldb/Core/ConstString.h"
22#include "lldb/Core/Log.h"
Greg Claytonc71899e2011-01-18 19:36:39 +000023#include "lldb/Core/StreamFile.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000024#include "lldb/Core/StreamString.h"
Greg Claytond1719722010-10-05 03:13:51 +000025#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan05a5a1b2010-12-16 03:17:46 +000026#include "lldb/Expression/ASTResultSynthesizer.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000027#include "lldb/Expression/ClangExpressionDeclMap.h"
28#include "lldb/Expression/ClangExpressionParser.h"
29#include "lldb/Expression/ClangFunction.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000030#include "lldb/Expression/ClangUserExpression.h"
Sean Callanande3d27e2011-09-26 18:45:31 +000031#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanana6686e32013-04-16 23:25:35 +000032#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan0f0551e2013-04-18 22:06:33 +000033#include "lldb/Expression/IRInterpreter.h"
Sean Callanan3b16eb92013-04-11 00:09:05 +000034#include "lldb/Expression/Materializer.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000035#include "lldb/Host/Host.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000036#include "lldb/Symbol/Block.h"
Jim Inghamc7f17c02012-10-30 23:35:54 +000037#include "lldb/Symbol/ClangASTContext.h"
38#include "lldb/Symbol/Function.h"
39#include "lldb/Symbol/Type.h"
40#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Sean Callanan3c9c5eb2010-09-21 00:44:12 +000041#include "lldb/Symbol/VariableList.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000042#include "lldb/Target/ExecutionContext.h"
Greg Clayton0baa3942010-11-04 01:54:29 +000043#include "lldb/Target/Process.h"
Sean Callanan3c9c5eb2010-09-21 00:44:12 +000044#include "lldb/Target/StackFrame.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000045#include "lldb/Target/Target.h"
Jim Ingham360f53f2010-11-30 02:22:11 +000046#include "lldb/Target/ThreadPlan.h"
47#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000048
Sean Callananc617a4c2011-08-05 23:43:37 +000049#include "clang/AST/DeclCXX.h"
50#include "clang/AST/DeclObjC.h"
51
Sean Callanan65dafa82010-08-27 01:01:44 +000052using namespace lldb_private;
53
Sean Callanan77e93942010-10-29 00:29:03 +000054ClangUserExpression::ClangUserExpression (const char *expr,
Sean Callanan5b658cc2011-11-07 23:35:40 +000055 const char *expr_prefix,
Sean Callanandaa6efe2011-12-21 22:22:58 +000056 lldb::LanguageType language,
57 ResultType desired_type) :
Greg Claytond0882d02011-01-19 23:00:49 +000058 ClangExpression (),
Sean Callanancdc3ea52013-04-27 02:19:33 +000059 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
60 m_stack_frame_top (LLDB_INVALID_ADDRESS),
Greg Claytond0882d02011-01-19 23:00:49 +000061 m_expr_text (expr),
62 m_expr_prefix (expr_prefix ? expr_prefix : ""),
Sean Callanan5b658cc2011-11-07 23:35:40 +000063 m_language (language),
Greg Claytond0882d02011-01-19 23:00:49 +000064 m_transformed_text (),
Sean Callanandaa6efe2011-12-21 22:22:58 +000065 m_desired_type (desired_type),
Sean Callanan77dd4a42012-12-06 01:35:38 +000066 m_enforce_valid_object (true),
Greg Claytond0882d02011-01-19 23:00:49 +000067 m_cplusplus (false),
68 m_objectivec (false),
Bill Wendlingd787da42012-04-03 08:46:13 +000069 m_static_method(false),
Greg Claytond0882d02011-01-19 23:00:49 +000070 m_needs_object_ptr (false),
Sean Callanan696cf5f2011-05-07 01:06:41 +000071 m_const_object (false),
Daniel Dunbar97c89572011-10-31 22:50:49 +000072 m_target (NULL),
Sean Callanancdc3ea52013-04-27 02:19:33 +000073 m_can_interpret (false),
74 m_materialized_address (LLDB_INVALID_ADDRESS)
Sean Callanan65dafa82010-08-27 01:01:44 +000075{
Sean Callanan5b658cc2011-11-07 23:35:40 +000076 switch (m_language)
77 {
78 case lldb::eLanguageTypeC_plus_plus:
79 m_allow_cxx = true;
80 break;
81 case lldb::eLanguageTypeObjC:
82 m_allow_objc = true;
83 break;
84 case lldb::eLanguageTypeObjC_plus_plus:
85 default:
86 m_allow_cxx = true;
87 m_allow_objc = true;
88 break;
89 }
Sean Callanan65dafa82010-08-27 01:01:44 +000090}
91
Sean Callanan830a9032010-08-27 23:31:21 +000092ClangUserExpression::~ClangUserExpression ()
93{
94}
95
Sean Callanan65dafa82010-08-27 01:01:44 +000096clang::ASTConsumer *
97ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
Sean Callanan036fa902011-08-24 22:18:12 +000098{
Sean Callanan24312442011-08-23 21:20:51 +000099 ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
100
101 if (!clang_ast_context)
102 return NULL;
103
Sean Callanan060d53f2011-10-08 00:21:35 +0000104 if (!m_result_synthesizer.get())
105 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
Sean Callanane1301a62011-12-06 03:41:14 +0000106 *m_target));
Sean Callanan060d53f2011-10-08 00:21:35 +0000107
108 return m_result_synthesizer.get();
Sean Callanan65dafa82010-08-27 01:01:44 +0000109}
110
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000111void
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000112ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000113{
Greg Clayton952e9dc2013-03-27 23:08:40 +0000114 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan54741252012-12-01 00:08:33 +0000115
116 if (log)
117 log->Printf("ClangUserExpression::ScanContext()");
118
Greg Clayton567e7f32011-09-22 04:58:26 +0000119 m_target = exe_ctx.GetTargetPtr();
Greg Clayton144188b2011-09-12 23:21:58 +0000120
Sean Callanan5b658cc2011-11-07 23:35:40 +0000121 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan54741252012-12-01 00:08:33 +0000122 {
123 if (log)
124 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callanan5b658cc2011-11-07 23:35:40 +0000125 return;
Sean Callanan54741252012-12-01 00:08:33 +0000126 }
Sean Callanan5b658cc2011-11-07 23:35:40 +0000127
Greg Clayton567e7f32011-09-22 04:58:26 +0000128 StackFrame *frame = exe_ctx.GetFramePtr();
129 if (frame == NULL)
Sean Callanan54741252012-12-01 00:08:33 +0000130 {
131 if (log)
132 log->Printf(" [CUE::SC] Null stack frame");
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000133 return;
Sean Callanan54741252012-12-01 00:08:33 +0000134 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000135
Sean Callananb573bd62012-07-13 21:20:29 +0000136 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sean Callanane8e55572010-12-01 21:35:54 +0000137
Sean Callananc617a4c2011-08-05 23:43:37 +0000138 if (!sym_ctx.function)
Sean Callanan54741252012-12-01 00:08:33 +0000139 {
140 if (log)
141 log->Printf(" [CUE::SC] Null function");
Sean Callananc617a4c2011-08-05 23:43:37 +0000142 return;
Sean Callanan54741252012-12-01 00:08:33 +0000143 }
Sean Callananc617a4c2011-08-05 23:43:37 +0000144
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000145 // Find the block that defines the function represented by "sym_ctx"
146 Block *function_block = sym_ctx.GetFunctionBlock();
Sean Callananc617a4c2011-08-05 23:43:37 +0000147
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000148 if (!function_block)
Sean Callanan54741252012-12-01 00:08:33 +0000149 {
150 if (log)
151 log->Printf(" [CUE::SC] Null function block");
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000152 return;
Sean Callanan54741252012-12-01 00:08:33 +0000153 }
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000154
155 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
156
Sean Callananc617a4c2011-08-05 23:43:37 +0000157 if (!decl_context)
Sean Callanan54741252012-12-01 00:08:33 +0000158 {
159 if (log)
160 log->Printf(" [CUE::SC] Null decl context");
Sean Callananc617a4c2011-08-05 23:43:37 +0000161 return;
Sean Callanan54741252012-12-01 00:08:33 +0000162 }
163
Sean Callananc617a4c2011-08-05 23:43:37 +0000164 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
Sean Callanane8e55572010-12-01 21:35:54 +0000165 {
Sean Callanan5b658cc2011-11-07 23:35:40 +0000166 if (m_allow_cxx && method_decl->isInstance())
Sean Callanane8e55572010-12-01 21:35:54 +0000167 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000168 if (m_enforce_valid_object)
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000169 {
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000170 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000171
172 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
173
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000174 if (!variable_list_sp)
Sean Callanan5ed59a72011-12-13 01:42:04 +0000175 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000176 err.SetErrorString(thisErrorString);
177 return;
178 }
179
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000180 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000181
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000182 if (!this_var_sp ||
183 !this_var_sp->IsInScope(frame) ||
184 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanan5ed59a72011-12-13 01:42:04 +0000185 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000186 err.SetErrorString(thisErrorString);
187 return;
188 }
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000189 }
190
Sean Callananc617a4c2011-08-05 23:43:37 +0000191 m_cplusplus = true;
Sean Callanande3d27e2011-09-26 18:45:31 +0000192 m_needs_object_ptr = true;
Sean Callanane8e55572010-12-01 21:35:54 +0000193 }
194 }
Sean Callananc617a4c2011-08-05 23:43:37 +0000195 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000196 {
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000197 if (m_allow_objc)
Sean Callanande3d27e2011-09-26 18:45:31 +0000198 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000199 if (m_enforce_valid_object)
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000200 {
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000201 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000202
203 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
204
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000205 if (!variable_list_sp)
Sean Callanan5ed59a72011-12-13 01:42:04 +0000206 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000207 err.SetErrorString(selfErrorString);
208 return;
209 }
210
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000211 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000212
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000213 if (!self_variable_sp ||
214 !self_variable_sp->IsInScope(frame) ||
215 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanan5ed59a72011-12-13 01:42:04 +0000216 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000217 err.SetErrorString(selfErrorString);
218 return;
219 }
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000220 }
221
Sean Callananc617a4c2011-08-05 23:43:37 +0000222 m_objectivec = true;
Sean Callanande3d27e2011-09-26 18:45:31 +0000223 m_needs_object_ptr = true;
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000224
225 if (!method_decl->isInstanceMethod())
226 m_static_method = true;
Sean Callanande3d27e2011-09-26 18:45:31 +0000227 }
Sean Callanane8e55572010-12-01 21:35:54 +0000228 }
Jim Inghamc7f17c02012-10-30 23:35:54 +0000229 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
230 {
231 // We might also have a function that said in the debug information that it captured an
232 // object pointer. The best way to deal with getting to the ivars at present it by pretending
233 // that this is a method of a class in whatever runtime the debug info says the object pointer
234 // belongs to. Do that here.
235
Greg Clayton017c16a2013-03-27 01:48:02 +0000236 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
Jim Inghamc7f17c02012-10-30 23:35:54 +0000237 if (metadata && metadata->HasObjectPtr())
238 {
239 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
240 if (language == lldb::eLanguageTypeC_plus_plus)
241 {
Sean Callanan288ddfe2013-01-19 01:49:02 +0000242 if (m_enforce_valid_object)
243 {
244 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
245
246 const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
247
248 if (!variable_list_sp)
249 {
250 err.SetErrorString(thisErrorString);
251 return;
252 }
253
254 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
255
256 if (!this_var_sp ||
257 !this_var_sp->IsInScope(frame) ||
258 !this_var_sp->LocationIsValidForFrame (frame))
259 {
260 err.SetErrorString(thisErrorString);
261 return;
262 }
263 }
264
Jim Inghamc7f17c02012-10-30 23:35:54 +0000265 m_cplusplus = true;
266 m_needs_object_ptr = true;
267 }
268 else if (language == lldb::eLanguageTypeObjC)
269 {
Sean Callanan288ddfe2013-01-19 01:49:02 +0000270 if (m_enforce_valid_object)
271 {
272 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
273
274 const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
275
276 if (!variable_list_sp)
277 {
278 err.SetErrorString(selfErrorString);
279 return;
280 }
281
282 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
283
284 if (!self_variable_sp ||
285 !self_variable_sp->IsInScope(frame) ||
286 !self_variable_sp->LocationIsValidForFrame (frame))
287 {
288 err.SetErrorString(selfErrorString);
289 return;
290 }
291
292 Type *self_type = self_variable_sp->GetType();
293
294 if (!self_type)
295 {
296 err.SetErrorString(selfErrorString);
297 return;
298 }
299
Greg Clayton52f79232013-07-11 22:46:58 +0000300 ClangASTType self_clang_type = self_type->GetClangForwardType();
Sean Callanan288ddfe2013-01-19 01:49:02 +0000301
Greg Clayton52f79232013-07-11 22:46:58 +0000302 if (!self_clang_type)
Sean Callanan288ddfe2013-01-19 01:49:02 +0000303 {
304 err.SetErrorString(selfErrorString);
305 return;
306 }
Greg Clayton52f79232013-07-11 22:46:58 +0000307
308 if (self_clang_type.IsObjCClassType())
Sean Callanan288ddfe2013-01-19 01:49:02 +0000309 {
310 return;
311 }
Greg Clayton52f79232013-07-11 22:46:58 +0000312 else if (self_clang_type.IsObjCObjectPointerType())
Sean Callanan288ddfe2013-01-19 01:49:02 +0000313 {
314 m_objectivec = true;
315 m_needs_object_ptr = true;
316 }
317 else
318 {
319 err.SetErrorString(selfErrorString);
320 return;
321 }
322 }
323 else
324 {
325 m_objectivec = true;
326 m_needs_object_ptr = true;
327 }
Jim Inghamc7f17c02012-10-30 23:35:54 +0000328 }
329 }
330 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000331}
332
Sean Callanan28195f92013-04-19 07:09:15 +0000333void
334ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
335{
336 m_process_wp = exe_ctx.GetProcessSP();
337
338 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
339
340 if (frame_sp)
341 m_address = frame_sp->GetFrameCodeAddress();
342}
343
344bool
345ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
346 lldb::TargetSP &target_sp,
347 lldb::ProcessSP &process_sp,
348 lldb::StackFrameSP &frame_sp)
349{
350 lldb::ProcessSP expected_process_sp = m_process_wp.lock();
351 process_sp = exe_ctx.GetProcessSP();
352
353 if (process_sp != expected_process_sp)
354 return false;
355
356 process_sp = exe_ctx.GetProcessSP();
357 target_sp = exe_ctx.GetTargetSP();
358 frame_sp = exe_ctx.GetFrameSP();
359
360 if (m_address.IsValid())
361 {
362 if (!frame_sp)
363 return false;
364 else
365 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
366 }
367
368 return true;
369}
370
371bool
372ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
373{
374 lldb::TargetSP target_sp;
375 lldb::ProcessSP process_sp;
376 lldb::StackFrameSP frame_sp;
377
378 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
379}
380
Sean Callanan550f2762010-10-22 23:25:16 +0000381// This is a really nasty hack, meant to fix Objective-C expressions of the form
382// (int)[myArray count]. Right now, because the type information for count is
383// not available, [myArray count] returns id, which can't be directly cast to
384// int without causing a clang error.
385static void
386ApplyObjcCastHack(std::string &expr)
387{
388#define OBJC_CAST_HACK_FROM "(int)["
389#define OBJC_CAST_HACK_TO "(int)(long long)["
390
391 size_t from_offset;
392
393 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
394 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
395
396#undef OBJC_CAST_HACK_TO
397#undef OBJC_CAST_HACK_FROM
398}
399
Sean Callanan30892372010-10-24 20:45:49 +0000400// Another hack, meant to allow use of unichar despite it not being available in
401// the type information. Although we could special-case it in type lookup,
402// hopefully we'll figure out a way to #include the same environment as is
403// present in the original source file rather than try to hack specific type
404// definitions in as needed.
405static void
406ApplyUnicharHack(std::string &expr)
407{
408#define UNICHAR_HACK_FROM "unichar"
409#define UNICHAR_HACK_TO "unsigned short"
410
411 size_t from_offset;
412
413 while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
414 expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
415
416#undef UNICHAR_HACK_TO
417#undef UNICHAR_HACK_FROM
418}
419
Sean Callanan550f2762010-10-22 23:25:16 +0000420bool
Sean Callanana91dd992010-11-19 02:52:21 +0000421ClangUserExpression::Parse (Stream &error_stream,
422 ExecutionContext &exe_ctx,
Sean Callanan47dc4572011-09-15 02:13:07 +0000423 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan696cf5f2011-05-07 01:06:41 +0000424 bool keep_result_in_memory)
Sean Callanan65dafa82010-08-27 01:01:44 +0000425{
Greg Clayton952e9dc2013-03-27 23:08:40 +0000426 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan65dafa82010-08-27 01:01:44 +0000427
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000428 Error err;
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000429
430 InstallContext(exe_ctx);
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000431
432 ScanContext(exe_ctx, err);
433
434 if (!err.Success())
435 {
436 error_stream.Printf("warning: %s\n", err.AsCString());
437 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000438
439 StreamString m_transformed_stream;
440
441 ////////////////////////////////////
442 // Generate the expression
443 //
Sean Callanan550f2762010-10-22 23:25:16 +0000444
445 ApplyObjcCastHack(m_expr_text);
Greg Claytonf3d0b0c2010-10-27 03:32:59 +0000446 //ApplyUnicharHack(m_expr_text);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000447
Greg Clayton102b2c22013-04-18 22:45:39 +0000448 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
Sean Callanande3d27e2011-09-26 18:45:31 +0000449
450 lldb::LanguageType lang_type;
451
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000452 if (m_cplusplus)
Sean Callanande3d27e2011-09-26 18:45:31 +0000453 lang_type = lldb::eLanguageTypeC_plus_plus;
454 else if(m_objectivec)
455 lang_type = lldb::eLanguageTypeObjC;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000456 else
Sean Callanande3d27e2011-09-26 18:45:31 +0000457 lang_type = lldb::eLanguageTypeC;
458
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000459 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000460 {
Sean Callanande3d27e2011-09-26 18:45:31 +0000461 error_stream.PutCString ("error: couldn't construct expression body");
462 return false;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000463 }
464
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000465 if (log)
466 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
467
Sean Callanan65dafa82010-08-27 01:01:44 +0000468 ////////////////////////////////////
469 // Set up the target and compiler
470 //
471
Greg Clayton567e7f32011-09-22 04:58:26 +0000472 Target *target = exe_ctx.GetTargetPtr();
Sean Callanan65dafa82010-08-27 01:01:44 +0000473
474 if (!target)
475 {
476 error_stream.PutCString ("error: invalid target\n");
477 return false;
478 }
479
Sean Callanan65dafa82010-08-27 01:01:44 +0000480 //////////////////////////
481 // Parse the expression
482 //
Sean Callanandaa6efe2011-12-21 22:22:58 +0000483
Sean Callanan3b16eb92013-04-11 00:09:05 +0000484 m_materializer_ap.reset(new Materializer());
485
Sean Callanan73b520f2011-10-29 01:58:46 +0000486 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sean Callananaa301c42010-12-03 01:38:59 +0000487
Greg Clayton52f79232013-07-11 22:46:58 +0000488 class OnExit
489 {
490 public:
491 typedef std::function <void (void)> Callback;
492
493 OnExit (Callback const &callback) :
494 m_callback(callback)
495 {
496 }
497
498 ~OnExit ()
499 {
500 m_callback();
501 }
502 private:
503 Callback m_callback;
504 };
505
506 OnExit on_exit([this]() { m_expr_decl_map.reset(); });
507
Sean Callanan3b16eb92013-04-11 00:09:05 +0000508 if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callanan166ba102011-08-01 18:18:33 +0000509 {
510 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
511 return false;
512 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000513
Greg Clayton567e7f32011-09-22 04:58:26 +0000514 Process *process = exe_ctx.GetProcessPtr();
Sean Callanane7ba1122012-02-08 18:43:35 +0000515 ExecutionContextScope *exe_scope = process;
516
517 if (!exe_scope)
518 exe_scope = exe_ctx.GetTargetPtr();
519
520 ClangExpressionParser parser(exe_scope, *this);
Sean Callanan65dafa82010-08-27 01:01:44 +0000521
522 unsigned num_errors = parser.Parse (error_stream);
523
524 if (num_errors)
525 {
526 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callananaa301c42010-12-03 01:38:59 +0000527
528 m_expr_decl_map->DidParse();
529
Sean Callanan65dafa82010-08-27 01:01:44 +0000530 return false;
531 }
532
Sean Callanan47dc4572011-09-15 02:13:07 +0000533 //////////////////////////////////////////////////////////////////////////////////////////
534 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan65dafa82010-08-27 01:01:44 +0000535 //
Sean Callanan1cf3da82013-03-19 00:10:07 +0000536
537 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan47dc4572011-09-15 02:13:07 +0000538 m_jit_end_addr,
Sean Callanan9e6f6a62013-04-05 02:22:57 +0000539 m_execution_unit_ap,
Sean Callanan47dc4572011-09-15 02:13:07 +0000540 exe_ctx,
Sean Callanan0f0551e2013-04-18 22:06:33 +0000541 m_can_interpret,
Sean Callanan47dc4572011-09-15 02:13:07 +0000542 execution_policy);
Sean Callanan6d284ef2011-10-12 22:20:02 +0000543
Sean Callanan65dafa82010-08-27 01:01:44 +0000544 if (jit_error.Success())
545 {
Sean Callanan1cf3da82013-03-19 00:10:07 +0000546 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granata7adfcfd2012-09-18 00:08:47 +0000547 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan65dafa82010-08-27 01:01:44 +0000548 return true;
549 }
550 else
551 {
Greg Clayton30581972011-05-17 03:51:29 +0000552 const char *error_cstr = jit_error.AsCString();
553 if (error_cstr && error_cstr[0])
554 error_stream.Printf ("error: %s\n", error_cstr);
555 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000556 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan65dafa82010-08-27 01:01:44 +0000557 return false;
558 }
559}
560
Sean Callanan0f0551e2013-04-18 22:06:33 +0000561static lldb::addr_t
562GetObjectPointer (lldb::StackFrameSP frame_sp,
563 ConstString &object_name,
564 Error &err)
565{
566 err.Clear();
567
568 if (!frame_sp)
569 {
570 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
571 return LLDB_INVALID_ADDRESS;
572 }
573
574 lldb::VariableSP var_sp;
575 lldb::ValueObjectSP valobj_sp;
576
577 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
578 lldb::eNoDynamicValues,
579 StackFrame::eExpressionPathOptionCheckPtrVsMember ||
580 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
581 StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
582 StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
583 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
584 var_sp,
585 err);
586
587 if (!err.Success())
588 return LLDB_INVALID_ADDRESS;
589
590 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
591
592 if (ret == LLDB_INVALID_ADDRESS)
593 {
594 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
595 return LLDB_INVALID_ADDRESS;
596 }
597
598 return ret;
599}
600
Sean Callanan65dafa82010-08-27 01:01:44 +0000601bool
Jim Inghamd1686902010-10-14 23:45:03 +0000602ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
Sean Callananab06af92010-10-19 23:57:21 +0000603 ExecutionContext &exe_ctx,
604 lldb::addr_t &struct_address,
Sean Callanan047923c2010-12-14 00:42:36 +0000605 lldb::addr_t &object_ptr,
606 lldb::addr_t &cmd_ptr)
Sean Callanan65dafa82010-08-27 01:01:44 +0000607{
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000608 lldb::TargetSP target;
609 lldb::ProcessSP process;
610 lldb::StackFrameSP frame;
611
612 if (!LockAndCheckContext(exe_ctx,
613 target,
614 process,
615 frame))
616 {
Sean Callanan28195f92013-04-19 07:09:15 +0000617 error_stream.Printf("The context has changed before we could JIT the expression!\n");
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000618 return false;
619 }
620
Sean Callanan0f0551e2013-04-18 22:06:33 +0000621 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
622 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000623 if (m_needs_object_ptr)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000624 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000625 ConstString object_name;
626
627 if (m_cplusplus)
628 {
629 object_name.SetCString("this");
630 }
631 else if (m_objectivec)
632 {
633 object_name.SetCString("self");
634 }
635 else
636 {
637 error_stream.Printf("Need object pointer but don't know the language\n");
638 return false;
639 }
640
Sean Callanan0f0551e2013-04-18 22:06:33 +0000641 Error object_ptr_error;
642
643 object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
644
645 if (!object_ptr_error.Success())
Sean Callanan3aa7da52010-12-13 22:46:15 +0000646 {
Sean Callanan0f0551e2013-04-18 22:06:33 +0000647 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanan5ed59a72011-12-13 01:42:04 +0000648 object_ptr = 0;
Sean Callanan3aa7da52010-12-13 22:46:15 +0000649 }
Sean Callanan047923c2010-12-14 00:42:36 +0000650
651 if (m_objectivec)
652 {
653 ConstString cmd_name("_cmd");
654
Sean Callanan0f0551e2013-04-18 22:06:33 +0000655 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
656
657 if (!object_ptr_error.Success())
Sean Callanan047923c2010-12-14 00:42:36 +0000658 {
Sean Callanan0f0551e2013-04-18 22:06:33 +0000659 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanan5ed59a72011-12-13 01:42:04 +0000660 cmd_ptr = 0;
Sean Callanan047923c2010-12-14 00:42:36 +0000661 }
662 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000663 }
Sean Callanan0f0551e2013-04-18 22:06:33 +0000664
Sean Callanancdc3ea52013-04-27 02:19:33 +0000665 if (m_materialized_address == LLDB_INVALID_ADDRESS)
Sean Callanan0f0551e2013-04-18 22:06:33 +0000666 {
Sean Callanancdc3ea52013-04-27 02:19:33 +0000667 Error alloc_error;
668
669 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
670
671 m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
672 m_materializer_ap->GetStructAlignment(),
673 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
674 policy,
675 alloc_error);
676
677 if (!alloc_error.Success())
678 {
679 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
680 return false;
681 }
Sean Callanan0f0551e2013-04-18 22:06:33 +0000682 }
683
Sean Callanancdc3ea52013-04-27 02:19:33 +0000684 struct_address = m_materialized_address;
Sean Callanan0f0551e2013-04-18 22:06:33 +0000685
Sean Callanancdc3ea52013-04-27 02:19:33 +0000686 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
687 {
688 Error alloc_error;
689
690 const size_t stack_frame_size = 512 * 1024;
691
692 m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
693 8,
694 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
695 IRMemoryMap::eAllocationPolicyHostOnly,
696 alloc_error);
697
698 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
699
700 if (!alloc_error.Success())
701 {
702 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
703 return false;
704 }
705 }
706
Sean Callanan0f0551e2013-04-18 22:06:33 +0000707 Error materialize_error;
708
709 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
710
711 if (!materialize_error.Success())
Sean Callanan65dafa82010-08-27 01:01:44 +0000712 {
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000713 error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
Sean Callanan65dafa82010-08-27 01:01:44 +0000714 return false;
715 }
Jim Inghamd1686902010-10-14 23:45:03 +0000716 }
717 return true;
718}
719
720ThreadPlan *
721ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
Sean Callanan6a925532011-01-13 08:53:35 +0000722 ExecutionContext &exe_ctx)
Jim Inghamd1686902010-10-14 23:45:03 +0000723{
724 lldb::addr_t struct_address;
725
Johnny Chen2bc9eb32011-07-19 19:48:13 +0000726 lldb::addr_t object_ptr = 0;
727 lldb::addr_t cmd_ptr = 0;
Jim Inghamd1686902010-10-14 23:45:03 +0000728
Sean Callanan047923c2010-12-14 00:42:36 +0000729 PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
Jim Inghamd1686902010-10-14 23:45:03 +0000730
Jim Ingham360f53f2010-11-30 02:22:11 +0000731 // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
732 // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
Sean Callanan3aa7da52010-12-13 22:46:15 +0000733 // forcing unwind_on_error to be true here, in practical terms that can't happen.
734
Jim Inghamb7940202013-01-15 02:47:48 +0000735 const bool stop_others = true;
736 const bool unwind_on_error = true;
737 const bool ignore_breakpoints = false;
Jim Inghamd1686902010-10-14 23:45:03 +0000738 return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
Greg Claytond0882d02011-01-19 23:00:49 +0000739 m_jit_start_addr,
Sean Callanana65b5272010-12-01 01:28:23 +0000740 struct_address,
741 error_stream,
Jim Inghamb7940202013-01-15 02:47:48 +0000742 stop_others,
743 unwind_on_error,
744 ignore_breakpoints,
Sean Callanan3aa7da52010-12-13 22:46:15 +0000745 (m_needs_object_ptr ? &object_ptr : NULL),
746 (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
Jim Inghamd1686902010-10-14 23:45:03 +0000747}
748
749bool
750ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
751 ExecutionContext &exe_ctx,
Sean Callanan0ddf8062011-05-09 22:04:36 +0000752 lldb::ClangExpressionVariableSP &result,
Sean Callanancdc3ea52013-04-27 02:19:33 +0000753 lldb::addr_t function_stack_bottom,
754 lldb::addr_t function_stack_top)
Jim Inghamd1686902010-10-14 23:45:03 +0000755{
Greg Clayton952e9dc2013-03-27 23:08:40 +0000756 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan33711022010-12-07 10:00:20 +0000757
758 if (log)
Sean Callanan94d255f2010-12-07 22:55:01 +0000759 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
Sean Callanancdc3ea52013-04-27 02:19:33 +0000760
Sean Callanan0f0551e2013-04-18 22:06:33 +0000761 if (!m_dematerializer_sp)
762 {
Sean Callanan4a4448b2013-07-12 23:35:21 +0000763 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
Sean Callanan0f0551e2013-04-18 22:06:33 +0000764 return false;
765 }
766
767 Error dematerialize_error;
768
Sean Callanancdc3ea52013-04-27 02:19:33 +0000769 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
Sean Callanan0f0551e2013-04-18 22:06:33 +0000770
771 if (!dematerialize_error.Success())
Jim Inghamd1686902010-10-14 23:45:03 +0000772 {
Sean Callanan4a4448b2013-07-12 23:35:21 +0000773 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
Jim Inghamd1686902010-10-14 23:45:03 +0000774 return false;
775 }
Sean Callanan0f0551e2013-04-18 22:06:33 +0000776
Johnny Chenc6134962012-01-06 00:35:38 +0000777 if (result)
778 result->TransferAddress();
779
Sean Callanan0f0551e2013-04-18 22:06:33 +0000780 m_dematerializer_sp.reset();
781
Jim Inghamd1686902010-10-14 23:45:03 +0000782 return true;
783}
784
Greg Claytonb3448432011-03-24 21:19:54 +0000785ExecutionResults
Jim Inghamd1686902010-10-14 23:45:03 +0000786ClangUserExpression::Execute (Stream &error_stream,
787 ExecutionContext &exe_ctx,
Jim Inghamb7940202013-01-15 02:47:48 +0000788 bool unwind_on_error,
789 bool ignore_breakpoints,
Jim Ingham360f53f2010-11-30 02:22:11 +0000790 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
Enrico Granata6cca9692012-07-16 23:10:35 +0000791 lldb::ClangExpressionVariableSP &result,
Jim Ingham47beabb2012-10-16 21:41:58 +0000792 bool run_others,
793 uint32_t timeout_usec)
Jim Inghamd1686902010-10-14 23:45:03 +0000794{
Jim Ingham7812e012011-01-18 22:20:08 +0000795 // The expression log is quite verbose, and if you're just tracking the execution of the
796 // expression, it's quite convenient to have these logs come out with the STEP log as well.
Greg Clayton952e9dc2013-03-27 23:08:40 +0000797 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanan33711022010-12-07 10:00:20 +0000798
Sean Callanan0f0551e2013-04-18 22:06:33 +0000799 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
Jim Inghamd1686902010-10-14 23:45:03 +0000800 {
Jim Ingham6f01c932012-10-12 17:34:26 +0000801 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Jim Inghamd1686902010-10-14 23:45:03 +0000802
Johnny Chen2bc9eb32011-07-19 19:48:13 +0000803 lldb::addr_t object_ptr = 0;
804 lldb::addr_t cmd_ptr = 0;
Jim Inghamd1686902010-10-14 23:45:03 +0000805
Johnny Chen544f2b62012-08-18 04:24:00 +0000806 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
807 {
Johnny Chen8165d432012-08-18 04:14:54 +0000808 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
Greg Claytonb3448432011-03-24 21:19:54 +0000809 return eExecutionSetupError;
Johnny Chen8165d432012-08-18 04:14:54 +0000810 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000811
Sean Callanancdc3ea52013-04-27 02:19:33 +0000812 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
813 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
Sean Callanan65dafa82010-08-27 01:01:44 +0000814
Sean Callanan0f0551e2013-04-18 22:06:33 +0000815 if (m_can_interpret)
816 {
817 llvm::Module *module = m_execution_unit_ap->GetModule();
818 llvm::Function *function = m_execution_unit_ap->GetFunction();
Jim Ingham0296fe72011-11-08 03:00:11 +0000819
Sean Callanan0f0551e2013-04-18 22:06:33 +0000820 if (!module || !function)
Jim Ingham2370a972011-05-17 01:10:11 +0000821 {
Sean Callanan0f0551e2013-04-18 22:06:33 +0000822 error_stream.Printf("Supposed to interpret, but nothing is there");
823 return eExecutionSetupError;
Jim Ingham2370a972011-05-17 01:10:11 +0000824 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000825
Sean Callanan0f0551e2013-04-18 22:06:33 +0000826 Error interpreter_error;
827
828 llvm::SmallVector <lldb::addr_t, 3> args;
829
830 if (m_needs_object_ptr)
831 {
832 args.push_back(object_ptr);
833
834 if (m_objectivec)
835 args.push_back(cmd_ptr);
836 }
837
838 args.push_back(struct_address);
839
Sean Callanancdc3ea52013-04-27 02:19:33 +0000840 function_stack_bottom = m_stack_frame_bottom;
841 function_stack_top = m_stack_frame_top;
842
Sean Callanan0f0551e2013-04-18 22:06:33 +0000843 IRInterpreter::Interpret (*module,
844 *function,
845 args,
846 *m_execution_unit_ap.get(),
Sean Callanancdc3ea52013-04-27 02:19:33 +0000847 interpreter_error,
848 function_stack_bottom,
849 function_stack_top);
Sean Callanan0f0551e2013-04-18 22:06:33 +0000850
851 if (!interpreter_error.Success())
852 {
853 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
854 return eExecutionDiscarded;
855 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000856 }
Sean Callanan0f0551e2013-04-18 22:06:33 +0000857 else
Jim Ingham360f53f2010-11-30 02:22:11 +0000858 {
Sean Callanan0f0551e2013-04-18 22:06:33 +0000859 const bool stop_others = true;
860 const bool try_all_threads = run_others;
861
862 Address wrapper_address (m_jit_start_addr);
863 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
864 wrapper_address,
865 struct_address,
866 stop_others,
867 unwind_on_error,
868 ignore_breakpoints,
869 (m_needs_object_ptr ? &object_ptr : NULL),
870 ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
871 shared_ptr_to_me));
872
873 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
874 return eExecutionSetupError;
875
Sean Callanancdc3ea52013-04-27 02:19:33 +0000876 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
Sean Callanan0f0551e2013-04-18 22:06:33 +0000877
Sean Callanancdc3ea52013-04-27 02:19:33 +0000878 function_stack_bottom = function_stack_pointer - Host::GetPageSize();
879 function_stack_top = function_stack_pointer;
880
Sean Callanan0f0551e2013-04-18 22:06:33 +0000881 if (log)
882 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
883
884 if (exe_ctx.GetProcessPtr())
885 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
886
887 ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
888 call_plan_sp,
889 stop_others,
890 try_all_threads,
891 unwind_on_error,
892 ignore_breakpoints,
893 timeout_usec,
894 error_stream);
895
896 if (exe_ctx.GetProcessPtr())
897 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
898
899 if (log)
900 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
901
902 if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
903 {
904 const char *error_desc = NULL;
905
906 if (call_plan_sp)
907 {
908 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
909 if (real_stop_info_sp)
910 error_desc = real_stop_info_sp->GetDescription();
911 }
912 if (error_desc)
913 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
914 else
915 error_stream.Printf ("Execution was interrupted.");
916
917 if ((execution_result == eExecutionInterrupted && unwind_on_error)
918 || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
919 error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
920 else
921 error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
922
923 return execution_result;
924 }
925 else if (execution_result != eExecutionCompleted)
926 {
927 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
928 return execution_result;
929 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000930 }
931
Sean Callanancdc3ea52013-04-27 02:19:33 +0000932 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
933 {
Greg Claytonb3448432011-03-24 21:19:54 +0000934 return eExecutionCompleted;
Sean Callanancdc3ea52013-04-27 02:19:33 +0000935 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000936 else
Johnny Chen544f2b62012-08-18 04:24:00 +0000937 {
Greg Claytonb3448432011-03-24 21:19:54 +0000938 return eExecutionSetupError;
Johnny Chen544f2b62012-08-18 04:24:00 +0000939 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000940 }
941 else
942 {
Sean Callanan47dc4572011-09-15 02:13:07 +0000943 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
Greg Claytonb3448432011-03-24 21:19:54 +0000944 return eExecutionSetupError;
Sean Callanan65dafa82010-08-27 01:01:44 +0000945 }
946}
947
Greg Claytonb3448432011-03-24 21:19:54 +0000948ExecutionResults
Sean Callanan47dc4572011-09-15 02:13:07 +0000949ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
950 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan5b658cc2011-11-07 23:35:40 +0000951 lldb::LanguageType language,
Sean Callanandaa6efe2011-12-21 22:22:58 +0000952 ResultType desired_type,
Jim Inghamb7940202013-01-15 02:47:48 +0000953 bool unwind_on_error,
954 bool ignore_breakpoints,
Sean Callanan77e93942010-10-29 00:29:03 +0000955 const char *expr_cstr,
Jim Ingham360f53f2010-11-30 02:22:11 +0000956 const char *expr_prefix,
Enrico Granata6cca9692012-07-16 23:10:35 +0000957 lldb::ValueObjectSP &result_valobj_sp,
Jim Ingham47beabb2012-10-16 21:41:58 +0000958 bool run_others,
959 uint32_t timeout_usec)
Greg Clayton377e0b42010-10-05 00:31:29 +0000960{
Jim Inghamec07c0d2011-08-09 00:00:49 +0000961 Error error;
Jim Ingham47beabb2012-10-16 21:41:58 +0000962 return EvaluateWithError (exe_ctx,
963 execution_policy,
964 language,
965 desired_type,
Jim Inghamb7940202013-01-15 02:47:48 +0000966 unwind_on_error,
967 ignore_breakpoints,
Jim Ingham47beabb2012-10-16 21:41:58 +0000968 expr_cstr,
969 expr_prefix,
970 result_valobj_sp,
971 error,
972 run_others,
973 timeout_usec);
Jim Inghamec07c0d2011-08-09 00:00:49 +0000974}
975
976ExecutionResults
Sean Callanan47dc4572011-09-15 02:13:07 +0000977ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
978 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan5b658cc2011-11-07 23:35:40 +0000979 lldb::LanguageType language,
Sean Callanandaa6efe2011-12-21 22:22:58 +0000980 ResultType desired_type,
Jim Inghamb7940202013-01-15 02:47:48 +0000981 bool unwind_on_error,
982 bool ignore_breakpoints,
Sean Callanan47dc4572011-09-15 02:13:07 +0000983 const char *expr_cstr,
984 const char *expr_prefix,
985 lldb::ValueObjectSP &result_valobj_sp,
Enrico Granata6cca9692012-07-16 23:10:35 +0000986 Error &error,
Jim Ingham47beabb2012-10-16 21:41:58 +0000987 bool run_others,
988 uint32_t timeout_usec)
Jim Inghamec07c0d2011-08-09 00:00:49 +0000989{
Greg Clayton952e9dc2013-03-27 23:08:40 +0000990 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanan94d255f2010-12-07 22:55:01 +0000991
Greg Claytonb3448432011-03-24 21:19:54 +0000992 ExecutionResults execution_results = eExecutionSetupError;
Greg Clayton0baa3942010-11-04 01:54:29 +0000993
Greg Clayton567e7f32011-09-22 04:58:26 +0000994 Process *process = exe_ctx.GetProcessPtr();
995
996 if (process == NULL || process->GetState() != lldb::eStateStopped)
Jim Ingham360f53f2010-11-30 02:22:11 +0000997 {
Sean Callanan47dc4572011-09-15 02:13:07 +0000998 if (execution_policy == eExecutionPolicyAlways)
999 {
1000 if (log)
1001 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Jim Ingham360f53f2010-11-30 02:22:11 +00001002
Sean Callanan47dc4572011-09-15 02:13:07 +00001003 error.SetErrorString ("expression needed to run but couldn't");
1004
1005 return execution_results;
1006 }
Jim Ingham360f53f2010-11-30 02:22:11 +00001007 }
Sean Callananf7649bb2011-09-15 17:43:00 +00001008
Greg Clayton567e7f32011-09-22 04:58:26 +00001009 if (process == NULL || !process->CanJIT())
Sean Callananf7649bb2011-09-15 17:43:00 +00001010 execution_policy = eExecutionPolicyNever;
Greg Clayton0baa3942010-11-04 01:54:29 +00001011
Sean Callanandaa6efe2011-12-21 22:22:58 +00001012 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
Jim Ingham360f53f2010-11-30 02:22:11 +00001013
Greg Clayton377e0b42010-10-05 00:31:29 +00001014 StreamString error_stream;
Sean Callanan696cf5f2011-05-07 01:06:41 +00001015
Sean Callanan94d255f2010-12-07 22:55:01 +00001016 if (log)
1017 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
1018
Sean Callanan47dc4572011-09-15 02:13:07 +00001019 const bool keep_expression_in_memory = true;
1020
Sean Callanandaa6efe2011-12-21 22:22:58 +00001021 if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
Greg Clayton377e0b42010-10-05 00:31:29 +00001022 {
1023 if (error_stream.GetString().empty())
1024 error.SetErrorString ("expression failed to parse, unknown error");
1025 else
1026 error.SetErrorString (error_stream.GetString().c_str());
1027 }
1028 else
1029 {
Greg Clayton427f2902010-12-14 02:59:59 +00001030 lldb::ClangExpressionVariableSP expr_result;
Greg Clayton377e0b42010-10-05 00:31:29 +00001031
Sean Callanan0f0551e2013-04-18 22:06:33 +00001032 if (execution_policy == eExecutionPolicyNever &&
1033 !user_expression_sp->CanInterpret())
Sean Callanan47dc4572011-09-15 02:13:07 +00001034 {
1035 if (log)
1036 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
1037
1038 if (error_stream.GetString().empty())
1039 error.SetErrorString ("expression needed to run but couldn't");
1040 }
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001041 else
1042 {
1043 error_stream.GetString().clear();
1044
1045 if (log)
1046 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
1047
1048 execution_results = user_expression_sp->Execute (error_stream,
1049 exe_ctx,
Jim Inghamb7940202013-01-15 02:47:48 +00001050 unwind_on_error,
1051 ignore_breakpoints,
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001052 user_expression_sp,
Enrico Granata6cca9692012-07-16 23:10:35 +00001053 expr_result,
Jim Ingham47beabb2012-10-16 21:41:58 +00001054 run_others,
1055 timeout_usec);
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001056
Greg Claytonb3448432011-03-24 21:19:54 +00001057 if (execution_results != eExecutionCompleted)
Greg Clayton377e0b42010-10-05 00:31:29 +00001058 {
Sean Callanan94d255f2010-12-07 22:55:01 +00001059 if (log)
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001060 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
1061
1062 if (error_stream.GetString().empty())
1063 error.SetErrorString ("expression failed to execute, unknown error");
1064 else
1065 error.SetErrorString (error_stream.GetString().c_str());
Greg Clayton377e0b42010-10-05 00:31:29 +00001066 }
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001067 else
Greg Clayton377e0b42010-10-05 00:31:29 +00001068 {
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001069 if (expr_result)
1070 {
1071 result_valobj_sp = expr_result->GetValueObject();
1072
1073 if (log)
Jim Inghamfa3a16a2011-03-31 00:19:25 +00001074 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001075 }
1076 else
1077 {
1078 if (log)
1079 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
1080
Sean Callanan24312442011-08-23 21:20:51 +00001081 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
Sean Callanan05a5a1b2010-12-16 03:17:46 +00001082 }
Greg Clayton377e0b42010-10-05 00:31:29 +00001083 }
1084 }
1085 }
Sean Callanan44820ec2010-10-19 20:15:00 +00001086
Greg Claytond1719722010-10-05 03:13:51 +00001087 if (result_valobj_sp.get() == NULL)
Jim Ingham47da8102011-04-22 23:53:53 +00001088 result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
Greg Claytond1719722010-10-05 03:13:51 +00001089
Jim Ingham360f53f2010-11-30 02:22:11 +00001090 return execution_results;
Johnny Chenb4c0f022010-10-29 20:19:44 +00001091}