blob: 6b0eee8cf3630f48f8c24ede6c6456680dfb15d9 [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"
Jason Molendab57e4a12013-11-04 09:33:30 +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 Callanan394e36d2013-10-10 00:39:23 +000098{
99 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
100 *m_target));
Sean Callanan2590b9a2011-10-08 00:21:35 +0000101
102 return m_result_synthesizer.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000103}
104
Sean Callananfc55f5d2010-09-21 00:44:12 +0000105void
Sean Callanan744756e2011-11-04 02:09:33 +0000106ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000107{
Greg Clayton5160ce52013-03-27 23:08:40 +0000108 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +0000109
110 if (log)
111 log->Printf("ClangUserExpression::ScanContext()");
112
Greg Claytonc14ee322011-09-22 04:58:26 +0000113 m_target = exe_ctx.GetTargetPtr();
Greg Claytond4a2b372011-09-12 23:21:58 +0000114
Sean Callananc7b65062011-11-07 23:35:40 +0000115 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +0000116 {
117 if (log)
118 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +0000119 return;
Sean Callanan70385082012-12-01 00:08:33 +0000120 }
Sean Callananc7b65062011-11-07 23:35:40 +0000121
Jason Molendab57e4a12013-11-04 09:33:30 +0000122 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000123 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000124 {
125 if (log)
126 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000127 return;
Sean Callanan70385082012-12-01 00:08:33 +0000128 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000129
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000130 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sean Callanan3670ba52010-12-01 21:35:54 +0000131
Sean Callanan72e49402011-08-05 23:43:37 +0000132 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000133 {
134 if (log)
135 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000136 return;
Sean Callanan70385082012-12-01 00:08:33 +0000137 }
Sean Callanan72e49402011-08-05 23:43:37 +0000138
Greg Clayton685c88c2012-07-14 00:53:55 +0000139 // Find the block that defines the function represented by "sym_ctx"
140 Block *function_block = sym_ctx.GetFunctionBlock();
Sean Callanan72e49402011-08-05 23:43:37 +0000141
Greg Clayton685c88c2012-07-14 00:53:55 +0000142 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000143 {
144 if (log)
145 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000146 return;
Sean Callanan70385082012-12-01 00:08:33 +0000147 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000148
149 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
150
Sean Callanan72e49402011-08-05 23:43:37 +0000151 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000152 {
153 if (log)
154 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000155 return;
Sean Callanan70385082012-12-01 00:08:33 +0000156 }
157
Sean Callanan72e49402011-08-05 23:43:37 +0000158 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000159 {
Sean Callananc7b65062011-11-07 23:35:40 +0000160 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000161 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000162 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000163 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000164 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanand5cc1322011-12-13 01:42:04 +0000165
166 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
167
Greg Clayton685c88c2012-07-14 00:53:55 +0000168 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000169 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000170 err.SetErrorString(thisErrorString);
171 return;
172 }
173
Greg Clayton685c88c2012-07-14 00:53:55 +0000174 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sean Callanand5cc1322011-12-13 01:42:04 +0000175
Greg Clayton685c88c2012-07-14 00:53:55 +0000176 if (!this_var_sp ||
177 !this_var_sp->IsInScope(frame) ||
178 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000179 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000180 err.SetErrorString(thisErrorString);
181 return;
182 }
Sean Callanan744756e2011-11-04 02:09:33 +0000183 }
184
Sean Callanan72e49402011-08-05 23:43:37 +0000185 m_cplusplus = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000186 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000187 }
188 }
Sean Callanan72e49402011-08-05 23:43:37 +0000189 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
Sean Callanan744756e2011-11-04 02:09:33 +0000190 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000191 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000192 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000193 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000194 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000195 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanand5cc1322011-12-13 01:42:04 +0000196
197 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
198
Greg Clayton685c88c2012-07-14 00:53:55 +0000199 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000200 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000201 err.SetErrorString(selfErrorString);
202 return;
203 }
204
Greg Clayton685c88c2012-07-14 00:53:55 +0000205 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sean Callanand5cc1322011-12-13 01:42:04 +0000206
Greg Clayton685c88c2012-07-14 00:53:55 +0000207 if (!self_variable_sp ||
208 !self_variable_sp->IsInScope(frame) ||
209 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000210 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000211 err.SetErrorString(selfErrorString);
212 return;
213 }
Sean Callanan744756e2011-11-04 02:09:33 +0000214 }
215
Sean Callanan72e49402011-08-05 23:43:37 +0000216 m_objectivec = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000217 m_needs_object_ptr = true;
Sean Callanand5c17ed2011-11-15 02:11:17 +0000218
219 if (!method_decl->isInstanceMethod())
220 m_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000221 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000222 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000223 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
224 {
225 // We might also have a function that said in the debug information that it captured an
226 // object pointer. The best way to deal with getting to the ivars at present it by pretending
227 // that this is a method of a class in whatever runtime the debug info says the object pointer
228 // belongs to. Do that here.
229
Greg Claytond0029442013-03-27 01:48:02 +0000230 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000231 if (metadata && metadata->HasObjectPtr())
232 {
233 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
234 if (language == lldb::eLanguageTypeC_plus_plus)
235 {
Sean Callanana2868d42013-01-19 01:49:02 +0000236 if (m_enforce_valid_object)
237 {
238 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
239
240 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";
241
242 if (!variable_list_sp)
243 {
244 err.SetErrorString(thisErrorString);
245 return;
246 }
247
248 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
249
250 if (!this_var_sp ||
251 !this_var_sp->IsInScope(frame) ||
252 !this_var_sp->LocationIsValidForFrame (frame))
253 {
254 err.SetErrorString(thisErrorString);
255 return;
256 }
257 }
258
Jim Ingham5fdeed42012-10-30 23:35:54 +0000259 m_cplusplus = true;
260 m_needs_object_ptr = true;
261 }
262 else if (language == lldb::eLanguageTypeObjC)
263 {
Sean Callanana2868d42013-01-19 01:49:02 +0000264 if (m_enforce_valid_object)
265 {
266 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
267
268 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";
269
270 if (!variable_list_sp)
271 {
272 err.SetErrorString(selfErrorString);
273 return;
274 }
275
276 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
277
278 if (!self_variable_sp ||
279 !self_variable_sp->IsInScope(frame) ||
280 !self_variable_sp->LocationIsValidForFrame (frame))
281 {
282 err.SetErrorString(selfErrorString);
283 return;
284 }
285
286 Type *self_type = self_variable_sp->GetType();
287
288 if (!self_type)
289 {
290 err.SetErrorString(selfErrorString);
291 return;
292 }
293
Greg Clayton57ee3062013-07-11 22:46:58 +0000294 ClangASTType self_clang_type = self_type->GetClangForwardType();
Sean Callanana2868d42013-01-19 01:49:02 +0000295
Greg Clayton57ee3062013-07-11 22:46:58 +0000296 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000297 {
298 err.SetErrorString(selfErrorString);
299 return;
300 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000301
302 if (self_clang_type.IsObjCClassType())
Sean Callanana2868d42013-01-19 01:49:02 +0000303 {
304 return;
305 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000306 else if (self_clang_type.IsObjCObjectPointerType())
Sean Callanana2868d42013-01-19 01:49:02 +0000307 {
308 m_objectivec = true;
309 m_needs_object_ptr = true;
310 }
311 else
312 {
313 err.SetErrorString(selfErrorString);
314 return;
315 }
316 }
317 else
318 {
319 m_objectivec = true;
320 m_needs_object_ptr = true;
321 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000322 }
323 }
324 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000325}
326
Sean Callanan3dbf3462013-04-19 07:09:15 +0000327void
328ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
329{
330 m_process_wp = exe_ctx.GetProcessSP();
331
Jason Molendab57e4a12013-11-04 09:33:30 +0000332 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000333
334 if (frame_sp)
335 m_address = frame_sp->GetFrameCodeAddress();
336}
337
338bool
339ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
340 lldb::TargetSP &target_sp,
341 lldb::ProcessSP &process_sp,
Jason Molendab57e4a12013-11-04 09:33:30 +0000342 lldb::StackFrameSP &frame_sp)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000343{
344 lldb::ProcessSP expected_process_sp = m_process_wp.lock();
345 process_sp = exe_ctx.GetProcessSP();
346
347 if (process_sp != expected_process_sp)
348 return false;
349
350 process_sp = exe_ctx.GetProcessSP();
351 target_sp = exe_ctx.GetTargetSP();
352 frame_sp = exe_ctx.GetFrameSP();
353
354 if (m_address.IsValid())
355 {
356 if (!frame_sp)
357 return false;
358 else
359 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
360 }
361
362 return true;
363}
364
365bool
366ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
367{
368 lldb::TargetSP target_sp;
369 lldb::ProcessSP process_sp;
Jason Molendab57e4a12013-11-04 09:33:30 +0000370 lldb::StackFrameSP frame_sp;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000371
372 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
373}
374
Sean Callanancf5498f2010-10-22 23:25:16 +0000375// This is a really nasty hack, meant to fix Objective-C expressions of the form
376// (int)[myArray count]. Right now, because the type information for count is
377// not available, [myArray count] returns id, which can't be directly cast to
378// int without causing a clang error.
379static void
380ApplyObjcCastHack(std::string &expr)
381{
382#define OBJC_CAST_HACK_FROM "(int)["
383#define OBJC_CAST_HACK_TO "(int)(long long)["
384
385 size_t from_offset;
386
387 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
388 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
389
390#undef OBJC_CAST_HACK_TO
391#undef OBJC_CAST_HACK_FROM
392}
393
Sean Callanan64186e72010-10-24 20:45:49 +0000394// Another hack, meant to allow use of unichar despite it not being available in
395// the type information. Although we could special-case it in type lookup,
396// hopefully we'll figure out a way to #include the same environment as is
397// present in the original source file rather than try to hack specific type
398// definitions in as needed.
399static void
400ApplyUnicharHack(std::string &expr)
401{
402#define UNICHAR_HACK_FROM "unichar"
403#define UNICHAR_HACK_TO "unsigned short"
404
405 size_t from_offset;
406
407 while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
408 expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
409
410#undef UNICHAR_HACK_TO
411#undef UNICHAR_HACK_FROM
412}
413
Sean Callanancf5498f2010-10-22 23:25:16 +0000414bool
Sean Callananf7c3e272010-11-19 02:52:21 +0000415ClangUserExpression::Parse (Stream &error_stream,
416 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000417 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan63697e52011-05-07 01:06:41 +0000418 bool keep_result_in_memory)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000419{
Greg Clayton5160ce52013-03-27 23:08:40 +0000420 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan1a8d4092010-08-27 01:01:44 +0000421
Sean Callanan744756e2011-11-04 02:09:33 +0000422 Error err;
Sean Callanan933693b2012-02-10 01:22:05 +0000423
424 InstallContext(exe_ctx);
Sean Callanan744756e2011-11-04 02:09:33 +0000425
426 ScanContext(exe_ctx, err);
427
428 if (!err.Success())
429 {
430 error_stream.Printf("warning: %s\n", err.AsCString());
431 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000432
433 StreamString m_transformed_stream;
434
435 ////////////////////////////////////
436 // Generate the expression
437 //
Sean Callanancf5498f2010-10-22 23:25:16 +0000438
439 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000440 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000441
Greg Clayton7b0992d2013-04-18 22:45:39 +0000442 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 +0000443
444 lldb::LanguageType lang_type;
445
Sean Callananfc55f5d2010-09-21 00:44:12 +0000446 if (m_cplusplus)
Sean Callanan9bc83842011-09-26 18:45:31 +0000447 lang_type = lldb::eLanguageTypeC_plus_plus;
448 else if(m_objectivec)
449 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000450 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000451 lang_type = lldb::eLanguageTypeC;
452
Sean Callanand5c17ed2011-11-15 02:11:17 +0000453 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
Sean Callananfc55f5d2010-09-21 00:44:12 +0000454 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000455 error_stream.PutCString ("error: couldn't construct expression body");
456 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000457 }
458
Sean Callananfc55f5d2010-09-21 00:44:12 +0000459 if (log)
460 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
461
Sean Callanan1a8d4092010-08-27 01:01:44 +0000462 ////////////////////////////////////
463 // Set up the target and compiler
464 //
465
Greg Claytonc14ee322011-09-22 04:58:26 +0000466 Target *target = exe_ctx.GetTargetPtr();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000467
468 if (!target)
469 {
470 error_stream.PutCString ("error: invalid target\n");
471 return false;
472 }
473
Sean Callanan1a8d4092010-08-27 01:01:44 +0000474 //////////////////////////
475 // Parse the expression
476 //
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000477
Sean Callanan96d27302013-04-11 00:09:05 +0000478 m_materializer_ap.reset(new Materializer());
479
Sean Callanan1ee44b72011-10-29 01:58:46 +0000480 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sean Callanan979f74d2010-12-03 01:38:59 +0000481
Greg Clayton57ee3062013-07-11 22:46:58 +0000482 class OnExit
483 {
484 public:
485 typedef std::function <void (void)> Callback;
486
487 OnExit (Callback const &callback) :
488 m_callback(callback)
489 {
490 }
491
492 ~OnExit ()
493 {
494 m_callback();
495 }
496 private:
497 Callback m_callback;
498 };
499
500 OnExit on_exit([this]() { m_expr_decl_map.reset(); });
501
Sean Callanan96d27302013-04-11 00:09:05 +0000502 if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000503 {
504 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sean Callananffc12852013-08-23 00:36:14 +0000505
506 m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
507
Sean Callananb9951192011-08-01 18:18:33 +0000508 return false;
509 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000510
Greg Claytonc14ee322011-09-22 04:58:26 +0000511 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000512 ExecutionContextScope *exe_scope = process;
513
514 if (!exe_scope)
515 exe_scope = exe_ctx.GetTargetPtr();
516
517 ClangExpressionParser parser(exe_scope, *this);
Sean Callanan1a8d4092010-08-27 01:01:44 +0000518
519 unsigned num_errors = parser.Parse (error_stream);
520
521 if (num_errors)
522 {
523 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callanan979f74d2010-12-03 01:38:59 +0000524
Sean Callananffc12852013-08-23 00:36:14 +0000525 m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
Sean Callanan979f74d2010-12-03 01:38:59 +0000526
Sean Callanan1a8d4092010-08-27 01:01:44 +0000527 return false;
528 }
529
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000530 //////////////////////////////////////////////////////////////////////////////////////////
531 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000532 //
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000533
534 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000535 m_jit_end_addr,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000536 m_execution_unit_ap,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000537 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000538 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000539 execution_policy);
Sean Callananffc12852013-08-23 00:36:14 +0000540
541 m_expr_decl_map.reset(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions.
Sean Callanane3aef1d2011-10-12 22:20:02 +0000542
Sean Callanan1a8d4092010-08-27 01:01:44 +0000543 if (jit_error.Success())
544 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000545 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000546 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000547 return true;
548 }
549 else
550 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000551 const char *error_cstr = jit_error.AsCString();
552 if (error_cstr && error_cstr[0])
553 error_stream.Printf ("error: %s\n", error_cstr);
554 else
Jason Molendafd54b362011-09-20 21:44:10 +0000555 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000556 return false;
557 }
558}
559
Sean Callanan1582ee62013-04-18 22:06:33 +0000560static lldb::addr_t
Jason Molendab57e4a12013-11-04 09:33:30 +0000561GetObjectPointer (lldb::StackFrameSP frame_sp,
Sean Callanan1582ee62013-04-18 22:06:33 +0000562 ConstString &object_name,
563 Error &err)
564{
565 err.Clear();
566
567 if (!frame_sp)
568 {
569 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
570 return LLDB_INVALID_ADDRESS;
571 }
572
573 lldb::VariableSP var_sp;
574 lldb::ValueObjectSP valobj_sp;
575
576 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
577 lldb::eNoDynamicValues,
Jason Molendab57e4a12013-11-04 09:33:30 +0000578 StackFrame::eExpressionPathOptionCheckPtrVsMember ||
579 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
580 StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
581 StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
582 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
Sean Callanan1582ee62013-04-18 22:06:33 +0000583 var_sp,
584 err);
585
586 if (!err.Success())
587 return LLDB_INVALID_ADDRESS;
588
589 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
590
591 if (ret == LLDB_INVALID_ADDRESS)
592 {
593 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
594 return LLDB_INVALID_ADDRESS;
595 }
596
597 return ret;
598}
599
Sean Callanan1a8d4092010-08-27 01:01:44 +0000600bool
Jim Ingham36f3b362010-10-14 23:45:03 +0000601ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
Sean Callanan104a6e92010-10-19 23:57:21 +0000602 ExecutionContext &exe_ctx,
603 lldb::addr_t &struct_address,
Sean Callanan9d48e802010-12-14 00:42:36 +0000604 lldb::addr_t &object_ptr,
605 lldb::addr_t &cmd_ptr)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000606{
Sean Callanan933693b2012-02-10 01:22:05 +0000607 lldb::TargetSP target;
608 lldb::ProcessSP process;
Jason Molendab57e4a12013-11-04 09:33:30 +0000609 lldb::StackFrameSP frame;
Sean Callanan933693b2012-02-10 01:22:05 +0000610
611 if (!LockAndCheckContext(exe_ctx,
612 target,
613 process,
614 frame))
615 {
Sean Callanan3dbf3462013-04-19 07:09:15 +0000616 error_stream.Printf("The context has changed before we could JIT the expression!\n");
Sean Callanan933693b2012-02-10 01:22:05 +0000617 return false;
618 }
619
Sean Callanan1582ee62013-04-18 22:06:33 +0000620 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
621 {
Sean Callanan17827832010-12-13 22:46:15 +0000622 if (m_needs_object_ptr)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000623 {
Sean Callanan17827832010-12-13 22:46:15 +0000624 ConstString object_name;
625
626 if (m_cplusplus)
627 {
628 object_name.SetCString("this");
629 }
630 else if (m_objectivec)
631 {
632 object_name.SetCString("self");
633 }
634 else
635 {
636 error_stream.Printf("Need object pointer but don't know the language\n");
637 return false;
638 }
639
Sean Callanan1582ee62013-04-18 22:06:33 +0000640 Error object_ptr_error;
641
642 object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
643
644 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000645 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000646 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 +0000647 object_ptr = 0;
Sean Callanan17827832010-12-13 22:46:15 +0000648 }
Sean Callanan9d48e802010-12-14 00:42:36 +0000649
650 if (m_objectivec)
651 {
652 ConstString cmd_name("_cmd");
653
Sean Callanan1582ee62013-04-18 22:06:33 +0000654 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
655
656 if (!object_ptr_error.Success())
Sean Callanan9d48e802010-12-14 00:42:36 +0000657 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000658 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanand5cc1322011-12-13 01:42:04 +0000659 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000660 }
661 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000662 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000663
Sean Callanandf565402013-04-27 02:19:33 +0000664 if (m_materialized_address == LLDB_INVALID_ADDRESS)
Sean Callanan1582ee62013-04-18 22:06:33 +0000665 {
Sean Callanandf565402013-04-27 02:19:33 +0000666 Error alloc_error;
667
668 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
669
670 m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
671 m_materializer_ap->GetStructAlignment(),
672 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
673 policy,
674 alloc_error);
675
676 if (!alloc_error.Success())
677 {
678 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
679 return false;
680 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000681 }
682
Sean Callanandf565402013-04-27 02:19:33 +0000683 struct_address = m_materialized_address;
Sean Callanan1582ee62013-04-18 22:06:33 +0000684
Sean Callanandf565402013-04-27 02:19:33 +0000685 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
686 {
687 Error alloc_error;
688
689 const size_t stack_frame_size = 512 * 1024;
690
691 m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
692 8,
693 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
694 IRMemoryMap::eAllocationPolicyHostOnly,
695 alloc_error);
696
697 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
698
699 if (!alloc_error.Success())
700 {
701 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
702 return false;
703 }
704 }
705
Sean Callanan1582ee62013-04-18 22:06:33 +0000706 Error materialize_error;
707
708 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
709
710 if (!materialize_error.Success())
Sean Callanan1a8d4092010-08-27 01:01:44 +0000711 {
Sean Callananfc55f5d2010-09-21 00:44:12 +0000712 error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000713 return false;
714 }
Jim Ingham36f3b362010-10-14 23:45:03 +0000715 }
716 return true;
717}
718
Jim Ingham36f3b362010-10-14 23:45:03 +0000719bool
720ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
721 ExecutionContext &exe_ctx,
Sean Callanane359d9b2011-05-09 22:04:36 +0000722 lldb::ClangExpressionVariableSP &result,
Sean Callanandf565402013-04-27 02:19:33 +0000723 lldb::addr_t function_stack_bottom,
724 lldb::addr_t function_stack_top)
Jim Ingham36f3b362010-10-14 23:45:03 +0000725{
Greg Clayton5160ce52013-03-27 23:08:40 +0000726 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananc673a6e2010-12-07 10:00:20 +0000727
728 if (log)
Sean Callanana162eba2010-12-07 22:55:01 +0000729 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
Sean Callanandf565402013-04-27 02:19:33 +0000730
Sean Callanan1582ee62013-04-18 22:06:33 +0000731 if (!m_dematerializer_sp)
732 {
Sean Callanand2a507a2013-07-12 23:35:21 +0000733 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
Sean Callanan1582ee62013-04-18 22:06:33 +0000734 return false;
735 }
736
737 Error dematerialize_error;
738
Sean Callanandf565402013-04-27 02:19:33 +0000739 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000740
741 if (!dematerialize_error.Success())
Jim Ingham36f3b362010-10-14 23:45:03 +0000742 {
Sean Callanand2a507a2013-07-12 23:35:21 +0000743 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
Jim Ingham36f3b362010-10-14 23:45:03 +0000744 return false;
745 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000746
Johnny Chenb49440f2012-01-06 00:35:38 +0000747 if (result)
748 result->TransferAddress();
749
Sean Callanan1582ee62013-04-18 22:06:33 +0000750 m_dematerializer_sp.reset();
751
Jim Ingham36f3b362010-10-14 23:45:03 +0000752 return true;
753}
754
Greg Claytone0d378b2011-03-24 21:19:54 +0000755ExecutionResults
Jim Ingham36f3b362010-10-14 23:45:03 +0000756ClangUserExpression::Execute (Stream &error_stream,
757 ExecutionContext &exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000758 const EvaluateExpressionOptions& options,
Jim Inghamf48169b2010-11-30 02:22:11 +0000759 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000760 lldb::ClangExpressionVariableSP &result)
Jim Ingham36f3b362010-10-14 23:45:03 +0000761{
Jim Inghamb086ff72011-01-18 22:20:08 +0000762 // The expression log is quite verbose, and if you're just tracking the execution of the
763 // expression, it's quite convenient to have these logs come out with the STEP log as well.
Greg Clayton5160ce52013-03-27 23:08:40 +0000764 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callananc673a6e2010-12-07 10:00:20 +0000765
Sean Callanan1582ee62013-04-18 22:06:33 +0000766 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
Jim Ingham36f3b362010-10-14 23:45:03 +0000767 {
Jim Ingham28eb5712012-10-12 17:34:26 +0000768 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Jim Ingham36f3b362010-10-14 23:45:03 +0000769
Johnny Chen44805302011-07-19 19:48:13 +0000770 lldb::addr_t object_ptr = 0;
771 lldb::addr_t cmd_ptr = 0;
Jim Ingham36f3b362010-10-14 23:45:03 +0000772
Johnny Chen8115c6d2012-08-18 04:24:00 +0000773 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
774 {
Johnny Chen2c90e992012-08-18 04:14:54 +0000775 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
Greg Claytone0d378b2011-03-24 21:19:54 +0000776 return eExecutionSetupError;
Johnny Chen2c90e992012-08-18 04:14:54 +0000777 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000778
Sean Callanandf565402013-04-27 02:19:33 +0000779 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
780 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000781
Sean Callanan1582ee62013-04-18 22:06:33 +0000782 if (m_can_interpret)
783 {
784 llvm::Module *module = m_execution_unit_ap->GetModule();
785 llvm::Function *function = m_execution_unit_ap->GetFunction();
Jim Ingham0faa43f2011-11-08 03:00:11 +0000786
Sean Callanan1582ee62013-04-18 22:06:33 +0000787 if (!module || !function)
Jim Ingham160f78c2011-05-17 01:10:11 +0000788 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000789 error_stream.Printf("Supposed to interpret, but nothing is there");
790 return eExecutionSetupError;
Jim Ingham160f78c2011-05-17 01:10:11 +0000791 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000792
Sean Callanan1582ee62013-04-18 22:06:33 +0000793 Error interpreter_error;
794
795 llvm::SmallVector <lldb::addr_t, 3> args;
796
797 if (m_needs_object_ptr)
798 {
799 args.push_back(object_ptr);
800
801 if (m_objectivec)
802 args.push_back(cmd_ptr);
803 }
804
805 args.push_back(struct_address);
806
Sean Callanandf565402013-04-27 02:19:33 +0000807 function_stack_bottom = m_stack_frame_bottom;
808 function_stack_top = m_stack_frame_top;
809
Sean Callanan1582ee62013-04-18 22:06:33 +0000810 IRInterpreter::Interpret (*module,
811 *function,
812 args,
813 *m_execution_unit_ap.get(),
Sean Callanandf565402013-04-27 02:19:33 +0000814 interpreter_error,
815 function_stack_bottom,
816 function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000817
818 if (!interpreter_error.Success())
819 {
820 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
821 return eExecutionDiscarded;
822 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000823 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000824 else
Jim Inghamf48169b2010-11-30 02:22:11 +0000825 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000826 Address wrapper_address (m_jit_start_addr);
Sean Callanana464f3d2013-11-08 01:14:26 +0000827
828 llvm::SmallVector <lldb::addr_t, 3> args;
829
830 if (m_needs_object_ptr) {
831 args.push_back(object_ptr);
832 if (m_objectivec)
833 args.push_back(cmd_ptr);
834 }
835
836 args.push_back(struct_address);
837
Sean Callanan1582ee62013-04-18 22:06:33 +0000838 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
839 wrapper_address,
Sean Callanana464f3d2013-11-08 01:14:26 +0000840 args,
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000841 options,
Sean Callanan1582ee62013-04-18 22:06:33 +0000842 shared_ptr_to_me));
843
844 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
845 return eExecutionSetupError;
846
Sean Callanandf565402013-04-27 02:19:33 +0000847 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
Sean Callanan1582ee62013-04-18 22:06:33 +0000848
Sean Callanandf565402013-04-27 02:19:33 +0000849 function_stack_bottom = function_stack_pointer - Host::GetPageSize();
850 function_stack_top = function_stack_pointer;
851
Sean Callanan1582ee62013-04-18 22:06:33 +0000852 if (log)
853 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
854
855 if (exe_ctx.GetProcessPtr())
856 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
857
858 ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000859 call_plan_sp,
860 options,
Sean Callanan1582ee62013-04-18 22:06:33 +0000861 error_stream);
862
863 if (exe_ctx.GetProcessPtr())
864 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
865
866 if (log)
867 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
868
869 if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
870 {
871 const char *error_desc = NULL;
872
873 if (call_plan_sp)
874 {
875 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
876 if (real_stop_info_sp)
877 error_desc = real_stop_info_sp->GetDescription();
878 }
879 if (error_desc)
880 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
881 else
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000882 error_stream.PutCString ("Execution was interrupted.");
Sean Callanan1582ee62013-04-18 22:06:33 +0000883
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000884 if ((execution_result == eExecutionInterrupted && options.DoesUnwindOnError())
885 || (execution_result == eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()))
886 error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
Sean Callanan1582ee62013-04-18 22:06:33 +0000887 else
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000888 error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
Sean Callanan1582ee62013-04-18 22:06:33 +0000889
890 return execution_result;
891 }
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000892 else if (execution_result == eExecutionStoppedForDebug)
893 {
894 error_stream.PutCString ("Execution was halted at the first instruction of the expression function because \"debug\" was requested.\n"
895 "Use \"thread return -x\" to return to the state before expression evaluation.");
896 return execution_result;
897 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000898 else if (execution_result != eExecutionCompleted)
899 {
900 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
901 return execution_result;
902 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000903 }
904
Sean Callanandf565402013-04-27 02:19:33 +0000905 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
906 {
Greg Claytone0d378b2011-03-24 21:19:54 +0000907 return eExecutionCompleted;
Sean Callanandf565402013-04-27 02:19:33 +0000908 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000909 else
Johnny Chen8115c6d2012-08-18 04:24:00 +0000910 {
Greg Claytone0d378b2011-03-24 21:19:54 +0000911 return eExecutionSetupError;
Johnny Chen8115c6d2012-08-18 04:24:00 +0000912 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000913 }
914 else
915 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000916 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
Greg Claytone0d378b2011-03-24 21:19:54 +0000917 return eExecutionSetupError;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000918 }
919}
920
Greg Claytone0d378b2011-03-24 21:19:54 +0000921ExecutionResults
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000922ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000923 const EvaluateExpressionOptions& options,
Sean Callanan322f5292010-10-29 00:29:03 +0000924 const char *expr_cstr,
Jim Inghamf48169b2010-11-30 02:22:11 +0000925 const char *expr_prefix,
Enrico Granata3372f582012-07-16 23:10:35 +0000926 lldb::ValueObjectSP &result_valobj_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000927 Error &error)
Jim Ingham41c75912011-08-09 00:00:49 +0000928{
Greg Clayton5160ce52013-03-27 23:08:40 +0000929 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanana162eba2010-12-07 22:55:01 +0000930
Greg Clayton62afb9f2013-11-04 19:35:17 +0000931 lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
932 const lldb::LanguageType language = options.GetLanguage();
933 const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
Greg Claytone0d378b2011-03-24 21:19:54 +0000934 ExecutionResults execution_results = eExecutionSetupError;
Greg Clayton8f343b02010-11-04 01:54:29 +0000935
Greg Claytonc14ee322011-09-22 04:58:26 +0000936 Process *process = exe_ctx.GetProcessPtr();
937
938 if (process == NULL || process->GetState() != lldb::eStateStopped)
Jim Inghamf48169b2010-11-30 02:22:11 +0000939 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000940 if (execution_policy == eExecutionPolicyAlways)
941 {
942 if (log)
943 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Jim Inghamf48169b2010-11-30 02:22:11 +0000944
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000945 error.SetErrorString ("expression needed to run but couldn't");
946
947 return execution_results;
948 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000949 }
Sean Callanan64fe1992011-09-15 17:43:00 +0000950
Greg Claytonc14ee322011-09-22 04:58:26 +0000951 if (process == NULL || !process->CanJIT())
Sean Callanan64fe1992011-09-15 17:43:00 +0000952 execution_policy = eExecutionPolicyNever;
Greg Clayton8f343b02010-11-04 01:54:29 +0000953
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000954 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
Jim Inghamf48169b2010-11-30 02:22:11 +0000955
Greg Clayton0184f012010-10-05 00:31:29 +0000956 StreamString error_stream;
Sean Callanan63697e52011-05-07 01:06:41 +0000957
Sean Callanana162eba2010-12-07 22:55:01 +0000958 if (log)
959 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
960
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000961 const bool keep_expression_in_memory = true;
962
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000963 if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
Greg Clayton0184f012010-10-05 00:31:29 +0000964 {
965 if (error_stream.GetString().empty())
966 error.SetErrorString ("expression failed to parse, unknown error");
967 else
968 error.SetErrorString (error_stream.GetString().c_str());
969 }
970 else
971 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000972 lldb::ClangExpressionVariableSP expr_result;
Greg Clayton0184f012010-10-05 00:31:29 +0000973
Sean Callanan1582ee62013-04-18 22:06:33 +0000974 if (execution_policy == eExecutionPolicyNever &&
975 !user_expression_sp->CanInterpret())
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000976 {
977 if (log)
978 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
979
980 if (error_stream.GetString().empty())
981 error.SetErrorString ("expression needed to run but couldn't");
982 }
Sean Callanane4ec90e2010-12-16 03:17:46 +0000983 else
984 {
985 error_stream.GetString().clear();
986
987 if (log)
988 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
989
990 execution_results = user_expression_sp->Execute (error_stream,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000991 exe_ctx,
992 options,
993 user_expression_sp,
994 expr_result);
Sean Callanane4ec90e2010-12-16 03:17:46 +0000995
Greg Claytone0d378b2011-03-24 21:19:54 +0000996 if (execution_results != eExecutionCompleted)
Greg Clayton0184f012010-10-05 00:31:29 +0000997 {
Sean Callanana162eba2010-12-07 22:55:01 +0000998 if (log)
Sean Callanane4ec90e2010-12-16 03:17:46 +0000999 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
1000
1001 if (error_stream.GetString().empty())
1002 error.SetErrorString ("expression failed to execute, unknown error");
1003 else
1004 error.SetErrorString (error_stream.GetString().c_str());
Greg Clayton0184f012010-10-05 00:31:29 +00001005 }
Sean Callanane4ec90e2010-12-16 03:17:46 +00001006 else
Greg Clayton0184f012010-10-05 00:31:29 +00001007 {
Sean Callanane4ec90e2010-12-16 03:17:46 +00001008 if (expr_result)
1009 {
1010 result_valobj_sp = expr_result->GetValueObject();
1011
1012 if (log)
Jim Ingham6035b672011-03-31 00:19:25 +00001013 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
Sean Callanane4ec90e2010-12-16 03:17:46 +00001014 }
1015 else
1016 {
1017 if (log)
1018 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
1019
Sean Callananbccce812011-08-23 21:20:51 +00001020 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
Sean Callanane4ec90e2010-12-16 03:17:46 +00001021 }
Greg Clayton0184f012010-10-05 00:31:29 +00001022 }
1023 }
1024 }
Sean Callananc57f64d2010-10-19 20:15:00 +00001025
Greg Claytonb71f3842010-10-05 03:13:51 +00001026 if (result_valobj_sp.get() == NULL)
Greg Claytoneeb15652013-12-10 23:16:40 +00001027 {
1028 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
1029 }
Greg Claytonb71f3842010-10-05 03:13:51 +00001030
Jim Inghamf48169b2010-11-30 02:22:11 +00001031 return execution_results;
Johnny Chendabefd02010-10-29 20:19:44 +00001032}