blob: c72c3b10d54a6936705f2d3e4a3f55d83a9f833f [file] [log] [blame]
Sean Callanan79763a42011-05-23 21:40:23 +00001//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
Sean Callanan1a8d4092010-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 Claytonc4e411f2011-01-18 19:36:39 +000023#include "lldb/Core/StreamFile.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000024#include "lldb/Core/StreamString.h"
Greg Claytonb71f3842010-10-05 03:13:51 +000025#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanane4ec90e2010-12-16 03:17:46 +000026#include "lldb/Expression/ASTResultSynthesizer.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000027#include "lldb/Expression/ClangExpressionDeclMap.h"
28#include "lldb/Expression/ClangExpressionParser.h"
29#include "lldb/Expression/ClangFunction.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000030#include "lldb/Expression/ClangUserExpression.h"
Sean Callanan9bc83842011-09-26 18:45:31 +000031#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanan14b1bae2013-04-16 23:25:35 +000032#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan1582ee62013-04-18 22:06:33 +000033#include "lldb/Expression/IRInterpreter.h"
Sean Callanan96d27302013-04-11 00:09:05 +000034#include "lldb/Expression/Materializer.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000035#include "lldb/Host/Host.h"
Greg Clayton1f746072012-08-29 21:13:06 +000036#include "lldb/Symbol/Block.h"
Jim Ingham5fdeed42012-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 Callananfc55f5d2010-09-21 00:44:12 +000041#include "lldb/Symbol/VariableList.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000042#include "lldb/Target/ExecutionContext.h"
Greg Clayton8f343b02010-11-04 01:54:29 +000043#include "lldb/Target/Process.h"
Sean Callananfc55f5d2010-09-21 00:44:12 +000044#include "lldb/Target/StackFrame.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000045#include "lldb/Target/Target.h"
Jim Inghamf48169b2010-11-30 02:22:11 +000046#include "lldb/Target/ThreadPlan.h"
47#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000048
Sean Callanan72e49402011-08-05 23:43:37 +000049#include "clang/AST/DeclCXX.h"
50#include "clang/AST/DeclObjC.h"
51
Sean Callanan1a8d4092010-08-27 01:01:44 +000052using namespace lldb_private;
53
Sean Callanan322f5292010-10-29 00:29:03 +000054ClangUserExpression::ClangUserExpression (const char *expr,
Sean Callananc7b65062011-11-07 23:35:40 +000055 const char *expr_prefix,
Sean Callanan20bb3aa2011-12-21 22:22:58 +000056 lldb::LanguageType language,
57 ResultType desired_type) :
Greg Clayton22a939a2011-01-19 23:00:49 +000058 ClangExpression (),
Sean Callanandf565402013-04-27 02:19:33 +000059 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
60 m_stack_frame_top (LLDB_INVALID_ADDRESS),
Greg Clayton22a939a2011-01-19 23:00:49 +000061 m_expr_text (expr),
62 m_expr_prefix (expr_prefix ? expr_prefix : ""),
Sean Callananc7b65062011-11-07 23:35:40 +000063 m_language (language),
Greg Clayton22a939a2011-01-19 23:00:49 +000064 m_transformed_text (),
Sean Callanan20bb3aa2011-12-21 22:22:58 +000065 m_desired_type (desired_type),
Sean Callananeab6cc92012-12-06 01:35:38 +000066 m_enforce_valid_object (true),
Greg Clayton22a939a2011-01-19 23:00:49 +000067 m_cplusplus (false),
68 m_objectivec (false),
Bill Wendlingd53b5de2012-04-03 08:46:13 +000069 m_static_method(false),
Greg Clayton22a939a2011-01-19 23:00:49 +000070 m_needs_object_ptr (false),
Sean Callanan63697e52011-05-07 01:06:41 +000071 m_const_object (false),
Daniel Dunbara08823f2011-10-31 22:50:49 +000072 m_target (NULL),
Sean Callanandf565402013-04-27 02:19:33 +000073 m_can_interpret (false),
74 m_materialized_address (LLDB_INVALID_ADDRESS)
Sean Callanan1a8d4092010-08-27 01:01:44 +000075{
Sean Callananc7b65062011-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 Callanan1a8d4092010-08-27 01:01:44 +000090}
91
Sean Callanane71d5532010-08-27 23:31:21 +000092ClangUserExpression::~ClangUserExpression ()
93{
94}
95
Sean Callanan1a8d4092010-08-27 01:01:44 +000096clang::ASTConsumer *
97ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
Sean Callanan737330c2011-08-24 22:18:12 +000098{
Sean Callananbccce812011-08-23 21:20:51 +000099 ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
100
101 if (!clang_ast_context)
102 return NULL;
103
Sean Callanan2590b9a2011-10-08 00:21:35 +0000104 if (!m_result_synthesizer.get())
105 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
Sean Callanan0eed0d42011-12-06 03:41:14 +0000106 *m_target));
Sean Callanan2590b9a2011-10-08 00:21:35 +0000107
108 return m_result_synthesizer.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000109}
110
Sean Callananfc55f5d2010-09-21 00:44:12 +0000111void
Sean Callanan744756e2011-11-04 02:09:33 +0000112ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000113{
Greg Clayton5160ce52013-03-27 23:08:40 +0000114 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +0000115
116 if (log)
117 log->Printf("ClangUserExpression::ScanContext()");
118
Greg Claytonc14ee322011-09-22 04:58:26 +0000119 m_target = exe_ctx.GetTargetPtr();
Greg Claytond4a2b372011-09-12 23:21:58 +0000120
Sean Callananc7b65062011-11-07 23:35:40 +0000121 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +0000122 {
123 if (log)
124 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +0000125 return;
Sean Callanan70385082012-12-01 00:08:33 +0000126 }
Sean Callananc7b65062011-11-07 23:35:40 +0000127
Greg Claytonc14ee322011-09-22 04:58:26 +0000128 StackFrame *frame = exe_ctx.GetFramePtr();
129 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000130 {
131 if (log)
132 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000133 return;
Sean Callanan70385082012-12-01 00:08:33 +0000134 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000135
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000136 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sean Callanan3670ba52010-12-01 21:35:54 +0000137
Sean Callanan72e49402011-08-05 23:43:37 +0000138 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000139 {
140 if (log)
141 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000142 return;
Sean Callanan70385082012-12-01 00:08:33 +0000143 }
Sean Callanan72e49402011-08-05 23:43:37 +0000144
Greg Clayton685c88c2012-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 Callanan72e49402011-08-05 23:43:37 +0000147
Greg Clayton685c88c2012-07-14 00:53:55 +0000148 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000149 {
150 if (log)
151 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000152 return;
Sean Callanan70385082012-12-01 00:08:33 +0000153 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000154
155 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
156
Sean Callanan72e49402011-08-05 23:43:37 +0000157 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000158 {
159 if (log)
160 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000161 return;
Sean Callanan70385082012-12-01 00:08:33 +0000162 }
163
Sean Callanan72e49402011-08-05 23:43:37 +0000164 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000165 {
Sean Callananc7b65062011-11-07 23:35:40 +0000166 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000167 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000168 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000169 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000170 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanand5cc1322011-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 Clayton685c88c2012-07-14 00:53:55 +0000174 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000175 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000176 err.SetErrorString(thisErrorString);
177 return;
178 }
179
Greg Clayton685c88c2012-07-14 00:53:55 +0000180 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sean Callanand5cc1322011-12-13 01:42:04 +0000181
Greg Clayton685c88c2012-07-14 00:53:55 +0000182 if (!this_var_sp ||
183 !this_var_sp->IsInScope(frame) ||
184 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000185 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000186 err.SetErrorString(thisErrorString);
187 return;
188 }
Sean Callanan744756e2011-11-04 02:09:33 +0000189 }
190
Sean Callanan72e49402011-08-05 23:43:37 +0000191 m_cplusplus = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000192 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000193 }
194 }
Sean Callanan72e49402011-08-05 23:43:37 +0000195 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
Sean Callanan744756e2011-11-04 02:09:33 +0000196 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000197 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000198 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000199 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000200 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000201 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanand5cc1322011-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 Clayton685c88c2012-07-14 00:53:55 +0000205 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000206 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000207 err.SetErrorString(selfErrorString);
208 return;
209 }
210
Greg Clayton685c88c2012-07-14 00:53:55 +0000211 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sean Callanand5cc1322011-12-13 01:42:04 +0000212
Greg Clayton685c88c2012-07-14 00:53:55 +0000213 if (!self_variable_sp ||
214 !self_variable_sp->IsInScope(frame) ||
215 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000216 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000217 err.SetErrorString(selfErrorString);
218 return;
219 }
Sean Callanan744756e2011-11-04 02:09:33 +0000220 }
221
Sean Callanan72e49402011-08-05 23:43:37 +0000222 m_objectivec = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000223 m_needs_object_ptr = true;
Sean Callanand5c17ed2011-11-15 02:11:17 +0000224
225 if (!method_decl->isInstanceMethod())
226 m_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000227 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000228 }
Jim Ingham5fdeed42012-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 Claytond0029442013-03-27 01:48:02 +0000236 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
Jim Ingham5fdeed42012-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 Callanana2868d42013-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 Ingham5fdeed42012-10-30 23:35:54 +0000265 m_cplusplus = true;
266 m_needs_object_ptr = true;
267 }
268 else if (language == lldb::eLanguageTypeObjC)
269 {
Sean Callanana2868d42013-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
300 lldb::clang_type_t self_opaque_type = self_type->GetClangForwardType();
301
302 if (!self_opaque_type)
303 {
304 err.SetErrorString(selfErrorString);
305 return;
306 }
307
308 clang::QualType self_qual_type = clang::QualType::getFromOpaquePtr(self_opaque_type);
309
310 if (self_qual_type->isObjCClassType())
311 {
312 return;
313 }
314 else if (self_qual_type->isObjCObjectPointerType())
315 {
316 m_objectivec = true;
317 m_needs_object_ptr = true;
318 }
319 else
320 {
321 err.SetErrorString(selfErrorString);
322 return;
323 }
324 }
325 else
326 {
327 m_objectivec = true;
328 m_needs_object_ptr = true;
329 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000330 }
331 }
332 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000333}
334
Sean Callanan3dbf3462013-04-19 07:09:15 +0000335void
336ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
337{
338 m_process_wp = exe_ctx.GetProcessSP();
339
340 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
341
342 if (frame_sp)
343 m_address = frame_sp->GetFrameCodeAddress();
344}
345
346bool
347ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
348 lldb::TargetSP &target_sp,
349 lldb::ProcessSP &process_sp,
350 lldb::StackFrameSP &frame_sp)
351{
352 lldb::ProcessSP expected_process_sp = m_process_wp.lock();
353 process_sp = exe_ctx.GetProcessSP();
354
355 if (process_sp != expected_process_sp)
356 return false;
357
358 process_sp = exe_ctx.GetProcessSP();
359 target_sp = exe_ctx.GetTargetSP();
360 frame_sp = exe_ctx.GetFrameSP();
361
362 if (m_address.IsValid())
363 {
364 if (!frame_sp)
365 return false;
366 else
367 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
368 }
369
370 return true;
371}
372
373bool
374ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
375{
376 lldb::TargetSP target_sp;
377 lldb::ProcessSP process_sp;
378 lldb::StackFrameSP frame_sp;
379
380 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
381}
382
Sean Callanancf5498f2010-10-22 23:25:16 +0000383// This is a really nasty hack, meant to fix Objective-C expressions of the form
384// (int)[myArray count]. Right now, because the type information for count is
385// not available, [myArray count] returns id, which can't be directly cast to
386// int without causing a clang error.
387static void
388ApplyObjcCastHack(std::string &expr)
389{
390#define OBJC_CAST_HACK_FROM "(int)["
391#define OBJC_CAST_HACK_TO "(int)(long long)["
392
393 size_t from_offset;
394
395 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
396 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
397
398#undef OBJC_CAST_HACK_TO
399#undef OBJC_CAST_HACK_FROM
400}
401
Sean Callanan64186e72010-10-24 20:45:49 +0000402// Another hack, meant to allow use of unichar despite it not being available in
403// the type information. Although we could special-case it in type lookup,
404// hopefully we'll figure out a way to #include the same environment as is
405// present in the original source file rather than try to hack specific type
406// definitions in as needed.
407static void
408ApplyUnicharHack(std::string &expr)
409{
410#define UNICHAR_HACK_FROM "unichar"
411#define UNICHAR_HACK_TO "unsigned short"
412
413 size_t from_offset;
414
415 while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
416 expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
417
418#undef UNICHAR_HACK_TO
419#undef UNICHAR_HACK_FROM
420}
421
Sean Callanancf5498f2010-10-22 23:25:16 +0000422bool
Sean Callananf7c3e272010-11-19 02:52:21 +0000423ClangUserExpression::Parse (Stream &error_stream,
424 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000425 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan63697e52011-05-07 01:06:41 +0000426 bool keep_result_in_memory)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000427{
Greg Clayton5160ce52013-03-27 23:08:40 +0000428 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan1a8d4092010-08-27 01:01:44 +0000429
Sean Callanan744756e2011-11-04 02:09:33 +0000430 Error err;
Sean Callanan933693b2012-02-10 01:22:05 +0000431
432 InstallContext(exe_ctx);
Sean Callanan744756e2011-11-04 02:09:33 +0000433
434 ScanContext(exe_ctx, err);
435
436 if (!err.Success())
437 {
438 error_stream.Printf("warning: %s\n", err.AsCString());
439 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000440
441 StreamString m_transformed_stream;
442
443 ////////////////////////////////////
444 // Generate the expression
445 //
Sean Callanancf5498f2010-10-22 23:25:16 +0000446
447 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000448 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000449
Greg Clayton7b0992d2013-04-18 22:45:39 +0000450 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
Sean Callanan9bc83842011-09-26 18:45:31 +0000451
452 lldb::LanguageType lang_type;
453
Sean Callananfc55f5d2010-09-21 00:44:12 +0000454 if (m_cplusplus)
Sean Callanan9bc83842011-09-26 18:45:31 +0000455 lang_type = lldb::eLanguageTypeC_plus_plus;
456 else if(m_objectivec)
457 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000458 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000459 lang_type = lldb::eLanguageTypeC;
460
Sean Callanand5c17ed2011-11-15 02:11:17 +0000461 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
Sean Callananfc55f5d2010-09-21 00:44:12 +0000462 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000463 error_stream.PutCString ("error: couldn't construct expression body");
464 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000465 }
466
Sean Callananfc55f5d2010-09-21 00:44:12 +0000467 if (log)
468 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
469
Sean Callanan1a8d4092010-08-27 01:01:44 +0000470 ////////////////////////////////////
471 // Set up the target and compiler
472 //
473
Greg Claytonc14ee322011-09-22 04:58:26 +0000474 Target *target = exe_ctx.GetTargetPtr();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000475
476 if (!target)
477 {
478 error_stream.PutCString ("error: invalid target\n");
479 return false;
480 }
481
Sean Callanan1a8d4092010-08-27 01:01:44 +0000482 //////////////////////////
483 // Parse the expression
484 //
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000485
Sean Callanan96d27302013-04-11 00:09:05 +0000486 m_materializer_ap.reset(new Materializer());
487
Sean Callanan1ee44b72011-10-29 01:58:46 +0000488 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sean Callanan979f74d2010-12-03 01:38:59 +0000489
Sean Callanan96d27302013-04-11 00:09:05 +0000490 if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000491 {
492 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
493 return false;
494 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000495
Greg Claytonc14ee322011-09-22 04:58:26 +0000496 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000497 ExecutionContextScope *exe_scope = process;
498
499 if (!exe_scope)
500 exe_scope = exe_ctx.GetTargetPtr();
501
502 ClangExpressionParser parser(exe_scope, *this);
Sean Callanan1a8d4092010-08-27 01:01:44 +0000503
504 unsigned num_errors = parser.Parse (error_stream);
505
506 if (num_errors)
507 {
508 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callanan979f74d2010-12-03 01:38:59 +0000509
510 m_expr_decl_map->DidParse();
511
Sean Callanan1a8d4092010-08-27 01:01:44 +0000512 return false;
513 }
514
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000515 //////////////////////////////////////////////////////////////////////////////////////////
516 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000517 //
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000518
519 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000520 m_jit_end_addr,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000521 m_execution_unit_ap,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000522 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000523 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000524 execution_policy);
Sean Callanane3aef1d2011-10-12 22:20:02 +0000525
Sean Callanan1a8d4092010-08-27 01:01:44 +0000526 if (jit_error.Success())
527 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000528 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000529 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000530 return true;
531 }
532 else
533 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000534 const char *error_cstr = jit_error.AsCString();
535 if (error_cstr && error_cstr[0])
536 error_stream.Printf ("error: %s\n", error_cstr);
537 else
Jason Molendafd54b362011-09-20 21:44:10 +0000538 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000539 return false;
540 }
541}
542
Sean Callanan1582ee62013-04-18 22:06:33 +0000543static lldb::addr_t
544GetObjectPointer (lldb::StackFrameSP frame_sp,
545 ConstString &object_name,
546 Error &err)
547{
548 err.Clear();
549
550 if (!frame_sp)
551 {
552 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
553 return LLDB_INVALID_ADDRESS;
554 }
555
556 lldb::VariableSP var_sp;
557 lldb::ValueObjectSP valobj_sp;
558
559 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
560 lldb::eNoDynamicValues,
561 StackFrame::eExpressionPathOptionCheckPtrVsMember ||
562 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
563 StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
564 StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
565 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
566 var_sp,
567 err);
568
569 if (!err.Success())
570 return LLDB_INVALID_ADDRESS;
571
572 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
573
574 if (ret == LLDB_INVALID_ADDRESS)
575 {
576 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
577 return LLDB_INVALID_ADDRESS;
578 }
579
580 return ret;
581}
582
Sean Callanan1a8d4092010-08-27 01:01:44 +0000583bool
Jim Ingham36f3b362010-10-14 23:45:03 +0000584ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
Sean Callanan104a6e92010-10-19 23:57:21 +0000585 ExecutionContext &exe_ctx,
586 lldb::addr_t &struct_address,
Sean Callanan9d48e802010-12-14 00:42:36 +0000587 lldb::addr_t &object_ptr,
588 lldb::addr_t &cmd_ptr)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000589{
Sean Callanan933693b2012-02-10 01:22:05 +0000590 lldb::TargetSP target;
591 lldb::ProcessSP process;
592 lldb::StackFrameSP frame;
593
594 if (!LockAndCheckContext(exe_ctx,
595 target,
596 process,
597 frame))
598 {
Sean Callanan3dbf3462013-04-19 07:09:15 +0000599 error_stream.Printf("The context has changed before we could JIT the expression!\n");
Sean Callanan933693b2012-02-10 01:22:05 +0000600 return false;
601 }
602
Sean Callanan1582ee62013-04-18 22:06:33 +0000603 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
604 {
Sean Callanan17827832010-12-13 22:46:15 +0000605 if (m_needs_object_ptr)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000606 {
Sean Callanan17827832010-12-13 22:46:15 +0000607 ConstString object_name;
608
609 if (m_cplusplus)
610 {
611 object_name.SetCString("this");
612 }
613 else if (m_objectivec)
614 {
615 object_name.SetCString("self");
616 }
617 else
618 {
619 error_stream.Printf("Need object pointer but don't know the language\n");
620 return false;
621 }
622
Sean Callanan1582ee62013-04-18 22:06:33 +0000623 Error object_ptr_error;
624
625 object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
626
627 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000628 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000629 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanand5cc1322011-12-13 01:42:04 +0000630 object_ptr = 0;
Sean Callanan17827832010-12-13 22:46:15 +0000631 }
Sean Callanan9d48e802010-12-14 00:42:36 +0000632
633 if (m_objectivec)
634 {
635 ConstString cmd_name("_cmd");
636
Sean Callanan1582ee62013-04-18 22:06:33 +0000637 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
638
639 if (!object_ptr_error.Success())
Sean Callanan9d48e802010-12-14 00:42:36 +0000640 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000641 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanand5cc1322011-12-13 01:42:04 +0000642 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000643 }
644 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000645 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000646
Sean Callanandf565402013-04-27 02:19:33 +0000647 if (m_materialized_address == LLDB_INVALID_ADDRESS)
Sean Callanan1582ee62013-04-18 22:06:33 +0000648 {
Sean Callanandf565402013-04-27 02:19:33 +0000649 Error alloc_error;
650
651 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
652
653 m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
654 m_materializer_ap->GetStructAlignment(),
655 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
656 policy,
657 alloc_error);
658
659 if (!alloc_error.Success())
660 {
661 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
662 return false;
663 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000664 }
665
Sean Callanandf565402013-04-27 02:19:33 +0000666 struct_address = m_materialized_address;
Sean Callanan1582ee62013-04-18 22:06:33 +0000667
Sean Callanandf565402013-04-27 02:19:33 +0000668 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
669 {
670 Error alloc_error;
671
672 const size_t stack_frame_size = 512 * 1024;
673
674 m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
675 8,
676 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
677 IRMemoryMap::eAllocationPolicyHostOnly,
678 alloc_error);
679
680 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
681
682 if (!alloc_error.Success())
683 {
684 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
685 return false;
686 }
687 }
688
Sean Callanan1582ee62013-04-18 22:06:33 +0000689 Error materialize_error;
690
691 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
692
693 if (!materialize_error.Success())
Sean Callanan1a8d4092010-08-27 01:01:44 +0000694 {
Sean Callananfc55f5d2010-09-21 00:44:12 +0000695 error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000696 return false;
697 }
Jim Ingham36f3b362010-10-14 23:45:03 +0000698 }
699 return true;
700}
701
702ThreadPlan *
703ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
Sean Callanan92adcac2011-01-13 08:53:35 +0000704 ExecutionContext &exe_ctx)
Jim Ingham36f3b362010-10-14 23:45:03 +0000705{
706 lldb::addr_t struct_address;
707
Johnny Chen44805302011-07-19 19:48:13 +0000708 lldb::addr_t object_ptr = 0;
709 lldb::addr_t cmd_ptr = 0;
Jim Ingham36f3b362010-10-14 23:45:03 +0000710
Sean Callanan9d48e802010-12-14 00:42:36 +0000711 PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
Jim Ingham36f3b362010-10-14 23:45:03 +0000712
Jim Inghamf48169b2010-11-30 02:22:11 +0000713 // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
714 // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
Sean Callanan17827832010-12-13 22:46:15 +0000715 // forcing unwind_on_error to be true here, in practical terms that can't happen.
716
Jim Ingham184e9812013-01-15 02:47:48 +0000717 const bool stop_others = true;
718 const bool unwind_on_error = true;
719 const bool ignore_breakpoints = false;
Jim Ingham36f3b362010-10-14 23:45:03 +0000720 return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
Greg Clayton22a939a2011-01-19 23:00:49 +0000721 m_jit_start_addr,
Sean Callanan1d47caf2010-12-01 01:28:23 +0000722 struct_address,
723 error_stream,
Jim Ingham184e9812013-01-15 02:47:48 +0000724 stop_others,
725 unwind_on_error,
726 ignore_breakpoints,
Sean Callanan17827832010-12-13 22:46:15 +0000727 (m_needs_object_ptr ? &object_ptr : NULL),
728 (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
Jim Ingham36f3b362010-10-14 23:45:03 +0000729}
730
731bool
732ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
733 ExecutionContext &exe_ctx,
Sean Callanane359d9b2011-05-09 22:04:36 +0000734 lldb::ClangExpressionVariableSP &result,
Sean Callanandf565402013-04-27 02:19:33 +0000735 lldb::addr_t function_stack_bottom,
736 lldb::addr_t function_stack_top)
Jim Ingham36f3b362010-10-14 23:45:03 +0000737{
738 Error expr_error;
739
Greg Clayton5160ce52013-03-27 23:08:40 +0000740 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananc673a6e2010-12-07 10:00:20 +0000741
742 if (log)
Sean Callanana162eba2010-12-07 22:55:01 +0000743 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
Sean Callanandf565402013-04-27 02:19:33 +0000744
Sean Callanan1582ee62013-04-18 22:06:33 +0000745 if (!m_dematerializer_sp)
746 {
747 error_stream.Printf ("Couldn't dematerialize struct : no dematerializer is present");
748 return false;
749 }
750
751 Error dematerialize_error;
752
Sean Callanandf565402013-04-27 02:19:33 +0000753 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000754
755 if (!dematerialize_error.Success())
Jim Ingham36f3b362010-10-14 23:45:03 +0000756 {
757 error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
758 return false;
759 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000760
Johnny Chenb49440f2012-01-06 00:35:38 +0000761 if (result)
762 result->TransferAddress();
763
Sean Callanan1582ee62013-04-18 22:06:33 +0000764 m_dematerializer_sp.reset();
765
Jim Ingham36f3b362010-10-14 23:45:03 +0000766 return true;
767}
768
Greg Claytone0d378b2011-03-24 21:19:54 +0000769ExecutionResults
Jim Ingham36f3b362010-10-14 23:45:03 +0000770ClangUserExpression::Execute (Stream &error_stream,
771 ExecutionContext &exe_ctx,
Jim Ingham184e9812013-01-15 02:47:48 +0000772 bool unwind_on_error,
773 bool ignore_breakpoints,
Jim Inghamf48169b2010-11-30 02:22:11 +0000774 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
Enrico Granata3372f582012-07-16 23:10:35 +0000775 lldb::ClangExpressionVariableSP &result,
Jim Ingham35e1bda2012-10-16 21:41:58 +0000776 bool run_others,
777 uint32_t timeout_usec)
Jim Ingham36f3b362010-10-14 23:45:03 +0000778{
Jim Inghamb086ff72011-01-18 22:20:08 +0000779 // The expression log is quite verbose, and if you're just tracking the execution of the
780 // expression, it's quite convenient to have these logs come out with the STEP log as well.
Greg Clayton5160ce52013-03-27 23:08:40 +0000781 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callananc673a6e2010-12-07 10:00:20 +0000782
Sean Callanan1582ee62013-04-18 22:06:33 +0000783 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
Jim Ingham36f3b362010-10-14 23:45:03 +0000784 {
Jim Ingham28eb5712012-10-12 17:34:26 +0000785 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Jim Ingham36f3b362010-10-14 23:45:03 +0000786
Johnny Chen44805302011-07-19 19:48:13 +0000787 lldb::addr_t object_ptr = 0;
788 lldb::addr_t cmd_ptr = 0;
Jim Ingham36f3b362010-10-14 23:45:03 +0000789
Johnny Chen8115c6d2012-08-18 04:24:00 +0000790 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
791 {
Johnny Chen2c90e992012-08-18 04:14:54 +0000792 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
Greg Claytone0d378b2011-03-24 21:19:54 +0000793 return eExecutionSetupError;
Johnny Chen2c90e992012-08-18 04:14:54 +0000794 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000795
Sean Callanandf565402013-04-27 02:19:33 +0000796 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
797 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000798
Sean Callanan1582ee62013-04-18 22:06:33 +0000799 if (m_can_interpret)
800 {
801 llvm::Module *module = m_execution_unit_ap->GetModule();
802 llvm::Function *function = m_execution_unit_ap->GetFunction();
Jim Ingham0faa43f2011-11-08 03:00:11 +0000803
Sean Callanan1582ee62013-04-18 22:06:33 +0000804 if (!module || !function)
Jim Ingham160f78c2011-05-17 01:10:11 +0000805 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000806 error_stream.Printf("Supposed to interpret, but nothing is there");
807 return eExecutionSetupError;
Jim Ingham160f78c2011-05-17 01:10:11 +0000808 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000809
Sean Callanan1582ee62013-04-18 22:06:33 +0000810 Error interpreter_error;
811
812 llvm::SmallVector <lldb::addr_t, 3> args;
813
814 if (m_needs_object_ptr)
815 {
816 args.push_back(object_ptr);
817
818 if (m_objectivec)
819 args.push_back(cmd_ptr);
820 }
821
822 args.push_back(struct_address);
823
Sean Callanandf565402013-04-27 02:19:33 +0000824 function_stack_bottom = m_stack_frame_bottom;
825 function_stack_top = m_stack_frame_top;
826
Sean Callanan1582ee62013-04-18 22:06:33 +0000827 IRInterpreter::Interpret (*module,
828 *function,
829 args,
830 *m_execution_unit_ap.get(),
Sean Callanandf565402013-04-27 02:19:33 +0000831 interpreter_error,
832 function_stack_bottom,
833 function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000834
835 if (!interpreter_error.Success())
836 {
837 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
838 return eExecutionDiscarded;
839 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000840 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000841 else
Jim Inghamf48169b2010-11-30 02:22:11 +0000842 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000843 const bool stop_others = true;
844 const bool try_all_threads = run_others;
845
846 Address wrapper_address (m_jit_start_addr);
847 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
848 wrapper_address,
849 struct_address,
850 stop_others,
851 unwind_on_error,
852 ignore_breakpoints,
853 (m_needs_object_ptr ? &object_ptr : NULL),
854 ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
855 shared_ptr_to_me));
856
857 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
858 return eExecutionSetupError;
859
Sean Callanandf565402013-04-27 02:19:33 +0000860 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
Sean Callanan1582ee62013-04-18 22:06:33 +0000861
Sean Callanandf565402013-04-27 02:19:33 +0000862 function_stack_bottom = function_stack_pointer - Host::GetPageSize();
863 function_stack_top = function_stack_pointer;
864
Sean Callanan1582ee62013-04-18 22:06:33 +0000865 if (log)
866 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
867
868 if (exe_ctx.GetProcessPtr())
869 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
870
871 ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
872 call_plan_sp,
873 stop_others,
874 try_all_threads,
875 unwind_on_error,
876 ignore_breakpoints,
877 timeout_usec,
878 error_stream);
879
880 if (exe_ctx.GetProcessPtr())
881 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
882
883 if (log)
884 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
885
886 if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
887 {
888 const char *error_desc = NULL;
889
890 if (call_plan_sp)
891 {
892 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
893 if (real_stop_info_sp)
894 error_desc = real_stop_info_sp->GetDescription();
895 }
896 if (error_desc)
897 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
898 else
899 error_stream.Printf ("Execution was interrupted.");
900
901 if ((execution_result == eExecutionInterrupted && unwind_on_error)
902 || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
903 error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
904 else
905 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.");
906
907 return execution_result;
908 }
909 else if (execution_result != eExecutionCompleted)
910 {
911 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
912 return execution_result;
913 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000914 }
915
Sean Callanandf565402013-04-27 02:19:33 +0000916 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
917 {
Greg Claytone0d378b2011-03-24 21:19:54 +0000918 return eExecutionCompleted;
Sean Callanandf565402013-04-27 02:19:33 +0000919 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000920 else
Johnny Chen8115c6d2012-08-18 04:24:00 +0000921 {
Johnny Chen2c90e992012-08-18 04:14:54 +0000922 error_stream.Printf("Errored out in %s: Couldn't FinalizeJITExpression", __FUNCTION__);
Greg Claytone0d378b2011-03-24 21:19:54 +0000923 return eExecutionSetupError;
Johnny Chen8115c6d2012-08-18 04:24:00 +0000924 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000925 }
926 else
927 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000928 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
Greg Claytone0d378b2011-03-24 21:19:54 +0000929 return eExecutionSetupError;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000930 }
931}
932
Greg Claytone0d378b2011-03-24 21:19:54 +0000933ExecutionResults
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000934ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
935 lldb_private::ExecutionPolicy execution_policy,
Sean Callananc7b65062011-11-07 23:35:40 +0000936 lldb::LanguageType language,
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000937 ResultType desired_type,
Jim Ingham184e9812013-01-15 02:47:48 +0000938 bool unwind_on_error,
939 bool ignore_breakpoints,
Sean Callanan322f5292010-10-29 00:29:03 +0000940 const char *expr_cstr,
Jim Inghamf48169b2010-11-30 02:22:11 +0000941 const char *expr_prefix,
Enrico Granata3372f582012-07-16 23:10:35 +0000942 lldb::ValueObjectSP &result_valobj_sp,
Jim Ingham35e1bda2012-10-16 21:41:58 +0000943 bool run_others,
944 uint32_t timeout_usec)
Greg Clayton0184f012010-10-05 00:31:29 +0000945{
Jim Ingham41c75912011-08-09 00:00:49 +0000946 Error error;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000947 return EvaluateWithError (exe_ctx,
948 execution_policy,
949 language,
950 desired_type,
Jim Ingham184e9812013-01-15 02:47:48 +0000951 unwind_on_error,
952 ignore_breakpoints,
Jim Ingham35e1bda2012-10-16 21:41:58 +0000953 expr_cstr,
954 expr_prefix,
955 result_valobj_sp,
956 error,
957 run_others,
958 timeout_usec);
Jim Ingham41c75912011-08-09 00:00:49 +0000959}
960
961ExecutionResults
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000962ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
963 lldb_private::ExecutionPolicy execution_policy,
Sean Callananc7b65062011-11-07 23:35:40 +0000964 lldb::LanguageType language,
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000965 ResultType desired_type,
Jim Ingham184e9812013-01-15 02:47:48 +0000966 bool unwind_on_error,
967 bool ignore_breakpoints,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000968 const char *expr_cstr,
969 const char *expr_prefix,
970 lldb::ValueObjectSP &result_valobj_sp,
Enrico Granata3372f582012-07-16 23:10:35 +0000971 Error &error,
Jim Ingham35e1bda2012-10-16 21:41:58 +0000972 bool run_others,
973 uint32_t timeout_usec)
Jim Ingham41c75912011-08-09 00:00:49 +0000974{
Greg Clayton5160ce52013-03-27 23:08:40 +0000975 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanana162eba2010-12-07 22:55:01 +0000976
Greg Claytone0d378b2011-03-24 21:19:54 +0000977 ExecutionResults execution_results = eExecutionSetupError;
Greg Clayton8f343b02010-11-04 01:54:29 +0000978
Greg Claytonc14ee322011-09-22 04:58:26 +0000979 Process *process = exe_ctx.GetProcessPtr();
980
981 if (process == NULL || process->GetState() != lldb::eStateStopped)
Jim Inghamf48169b2010-11-30 02:22:11 +0000982 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000983 if (execution_policy == eExecutionPolicyAlways)
984 {
985 if (log)
986 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Jim Inghamf48169b2010-11-30 02:22:11 +0000987
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000988 error.SetErrorString ("expression needed to run but couldn't");
989
990 return execution_results;
991 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000992 }
Sean Callanan64fe1992011-09-15 17:43:00 +0000993
Greg Claytonc14ee322011-09-22 04:58:26 +0000994 if (process == NULL || !process->CanJIT())
Sean Callanan64fe1992011-09-15 17:43:00 +0000995 execution_policy = eExecutionPolicyNever;
Greg Clayton8f343b02010-11-04 01:54:29 +0000996
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000997 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
Jim Inghamf48169b2010-11-30 02:22:11 +0000998
Greg Clayton0184f012010-10-05 00:31:29 +0000999 StreamString error_stream;
Sean Callanan63697e52011-05-07 01:06:41 +00001000
Sean Callanana162eba2010-12-07 22:55:01 +00001001 if (log)
1002 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
1003
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001004 const bool keep_expression_in_memory = true;
1005
Sean Callanan20bb3aa2011-12-21 22:22:58 +00001006 if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
Greg Clayton0184f012010-10-05 00:31:29 +00001007 {
1008 if (error_stream.GetString().empty())
1009 error.SetErrorString ("expression failed to parse, unknown error");
1010 else
1011 error.SetErrorString (error_stream.GetString().c_str());
1012 }
1013 else
1014 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001015 lldb::ClangExpressionVariableSP expr_result;
Greg Clayton0184f012010-10-05 00:31:29 +00001016
Sean Callanan1582ee62013-04-18 22:06:33 +00001017 if (execution_policy == eExecutionPolicyNever &&
1018 !user_expression_sp->CanInterpret())
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001019 {
1020 if (log)
1021 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
1022
1023 if (error_stream.GetString().empty())
1024 error.SetErrorString ("expression needed to run but couldn't");
1025 }
Sean Callanane4ec90e2010-12-16 03:17:46 +00001026 else
1027 {
1028 error_stream.GetString().clear();
1029
1030 if (log)
1031 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
1032
1033 execution_results = user_expression_sp->Execute (error_stream,
1034 exe_ctx,
Jim Ingham184e9812013-01-15 02:47:48 +00001035 unwind_on_error,
1036 ignore_breakpoints,
Sean Callanane4ec90e2010-12-16 03:17:46 +00001037 user_expression_sp,
Enrico Granata3372f582012-07-16 23:10:35 +00001038 expr_result,
Jim Ingham35e1bda2012-10-16 21:41:58 +00001039 run_others,
1040 timeout_usec);
Sean Callanane4ec90e2010-12-16 03:17:46 +00001041
Greg Claytone0d378b2011-03-24 21:19:54 +00001042 if (execution_results != eExecutionCompleted)
Greg Clayton0184f012010-10-05 00:31:29 +00001043 {
Sean Callanana162eba2010-12-07 22:55:01 +00001044 if (log)
Sean Callanane4ec90e2010-12-16 03:17:46 +00001045 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
1046
1047 if (error_stream.GetString().empty())
1048 error.SetErrorString ("expression failed to execute, unknown error");
1049 else
1050 error.SetErrorString (error_stream.GetString().c_str());
Greg Clayton0184f012010-10-05 00:31:29 +00001051 }
Sean Callanane4ec90e2010-12-16 03:17:46 +00001052 else
Greg Clayton0184f012010-10-05 00:31:29 +00001053 {
Sean Callanane4ec90e2010-12-16 03:17:46 +00001054 if (expr_result)
1055 {
1056 result_valobj_sp = expr_result->GetValueObject();
1057
1058 if (log)
Jim Ingham6035b672011-03-31 00:19:25 +00001059 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
Sean Callanane4ec90e2010-12-16 03:17:46 +00001060 }
1061 else
1062 {
1063 if (log)
1064 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
1065
Sean Callananbccce812011-08-23 21:20:51 +00001066 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
Sean Callanane4ec90e2010-12-16 03:17:46 +00001067 }
Greg Clayton0184f012010-10-05 00:31:29 +00001068 }
1069 }
1070 }
Sean Callananc57f64d2010-10-19 20:15:00 +00001071
Greg Claytonb71f3842010-10-05 03:13:51 +00001072 if (result_valobj_sp.get() == NULL)
Jim Ingham58b59f92011-04-22 23:53:53 +00001073 result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
Greg Claytonb71f3842010-10-05 03:13:51 +00001074
Jim Inghamf48169b2010-11-30 02:22:11 +00001075 return execution_results;
Johnny Chendabefd02010-10-29 20:19:44 +00001076}