blob: fdff4bddf08ac86d5328f9d664473f29e75ebc35 [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 Clayton23f8c952014-03-24 23:10:19 +000023#include "lldb/Core/Module.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000024#include "lldb/Core/StreamFile.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000025#include "lldb/Core/StreamString.h"
Greg Claytonb71f3842010-10-05 03:13:51 +000026#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanane4ec90e2010-12-16 03:17:46 +000027#include "lldb/Expression/ASTResultSynthesizer.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000028#include "lldb/Expression/ClangExpressionDeclMap.h"
29#include "lldb/Expression/ClangExpressionParser.h"
30#include "lldb/Expression/ClangFunction.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000031#include "lldb/Expression/ClangUserExpression.h"
Sean Callanan9bc83842011-09-26 18:45:31 +000032#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanan14b1bae2013-04-16 23:25:35 +000033#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan1582ee62013-04-18 22:06:33 +000034#include "lldb/Expression/IRInterpreter.h"
Sean Callanan96d27302013-04-11 00:09:05 +000035#include "lldb/Expression/Materializer.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000036#include "lldb/Host/Host.h"
Greg Clayton1f746072012-08-29 21:13:06 +000037#include "lldb/Symbol/Block.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000038#include "lldb/Symbol/ClangASTContext.h"
39#include "lldb/Symbol/Function.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000040#include "lldb/Symbol/ObjectFile.h"
41#include "lldb/Symbol/SymbolVendor.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000042#include "lldb/Symbol/Type.h"
43#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Sean Callananfc55f5d2010-09-21 00:44:12 +000044#include "lldb/Symbol/VariableList.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000045#include "lldb/Target/ExecutionContext.h"
Greg Clayton8f343b02010-11-04 01:54:29 +000046#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000047#include "lldb/Target/StackFrame.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000048#include "lldb/Target/Target.h"
Jim Inghamf48169b2010-11-30 02:22:11 +000049#include "lldb/Target/ThreadPlan.h"
50#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000051
Sean Callanan72e49402011-08-05 23:43:37 +000052#include "clang/AST/DeclCXX.h"
53#include "clang/AST/DeclObjC.h"
54
Sean Callanan1a8d4092010-08-27 01:01:44 +000055using namespace lldb_private;
56
Sean Callanan322f5292010-10-29 00:29:03 +000057ClangUserExpression::ClangUserExpression (const char *expr,
Sean Callananc7b65062011-11-07 23:35:40 +000058 const char *expr_prefix,
Sean Callanan20bb3aa2011-12-21 22:22:58 +000059 lldb::LanguageType language,
60 ResultType desired_type) :
Greg Clayton22a939a2011-01-19 23:00:49 +000061 ClangExpression (),
Sean Callanandf565402013-04-27 02:19:33 +000062 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
63 m_stack_frame_top (LLDB_INVALID_ADDRESS),
Greg Clayton22a939a2011-01-19 23:00:49 +000064 m_expr_text (expr),
65 m_expr_prefix (expr_prefix ? expr_prefix : ""),
Sean Callananc7b65062011-11-07 23:35:40 +000066 m_language (language),
Greg Clayton22a939a2011-01-19 23:00:49 +000067 m_transformed_text (),
Sean Callanan20bb3aa2011-12-21 22:22:58 +000068 m_desired_type (desired_type),
Greg Clayton23f8c952014-03-24 23:10:19 +000069 m_expr_decl_map(),
70 m_execution_unit_sp(),
71 m_materializer_ap(),
72 m_result_synthesizer(),
73 m_jit_module_wp(),
Sean Callananeab6cc92012-12-06 01:35:38 +000074 m_enforce_valid_object (true),
Greg Clayton22a939a2011-01-19 23:00:49 +000075 m_cplusplus (false),
76 m_objectivec (false),
Bill Wendlingd53b5de2012-04-03 08:46:13 +000077 m_static_method(false),
Greg Clayton22a939a2011-01-19 23:00:49 +000078 m_needs_object_ptr (false),
Sean Callanan63697e52011-05-07 01:06:41 +000079 m_const_object (false),
Daniel Dunbara08823f2011-10-31 22:50:49 +000080 m_target (NULL),
Sean Callanandf565402013-04-27 02:19:33 +000081 m_can_interpret (false),
82 m_materialized_address (LLDB_INVALID_ADDRESS)
Sean Callanan1a8d4092010-08-27 01:01:44 +000083{
Sean Callananc7b65062011-11-07 23:35:40 +000084 switch (m_language)
85 {
86 case lldb::eLanguageTypeC_plus_plus:
87 m_allow_cxx = true;
88 break;
89 case lldb::eLanguageTypeObjC:
90 m_allow_objc = true;
91 break;
92 case lldb::eLanguageTypeObjC_plus_plus:
93 default:
94 m_allow_cxx = true;
95 m_allow_objc = true;
96 break;
97 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000098}
99
Sean Callanane71d5532010-08-27 23:31:21 +0000100ClangUserExpression::~ClangUserExpression ()
101{
Greg Clayton23f8c952014-03-24 23:10:19 +0000102 if (m_target)
103 {
104 lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
105 if (jit_module_sp)
106 m_target->GetImages().Remove(jit_module_sp);
107 }
Sean Callanane71d5532010-08-27 23:31:21 +0000108}
109
Sean Callanan1a8d4092010-08-27 01:01:44 +0000110clang::ASTConsumer *
111ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
Sean Callanan394e36d2013-10-10 00:39:23 +0000112{
113 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
114 *m_target));
Sean Callanan2590b9a2011-10-08 00:21:35 +0000115
116 return m_result_synthesizer.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000117}
118
Sean Callananfc55f5d2010-09-21 00:44:12 +0000119void
Sean Callanan744756e2011-11-04 02:09:33 +0000120ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000121{
Greg Clayton5160ce52013-03-27 23:08:40 +0000122 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +0000123
124 if (log)
125 log->Printf("ClangUserExpression::ScanContext()");
126
Greg Claytonc14ee322011-09-22 04:58:26 +0000127 m_target = exe_ctx.GetTargetPtr();
Greg Claytond4a2b372011-09-12 23:21:58 +0000128
Sean Callananc7b65062011-11-07 23:35:40 +0000129 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +0000130 {
131 if (log)
132 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +0000133 return;
Sean Callanan70385082012-12-01 00:08:33 +0000134 }
Sean Callananc7b65062011-11-07 23:35:40 +0000135
Jason Molendab57e4a12013-11-04 09:33:30 +0000136 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000137 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000138 {
139 if (log)
140 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000141 return;
Sean Callanan70385082012-12-01 00:08:33 +0000142 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000143
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000144 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sean Callanan3670ba52010-12-01 21:35:54 +0000145
Sean Callanan72e49402011-08-05 23:43:37 +0000146 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000147 {
148 if (log)
149 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000150 return;
Sean Callanan70385082012-12-01 00:08:33 +0000151 }
Sean Callanan72e49402011-08-05 23:43:37 +0000152
Greg Clayton685c88c2012-07-14 00:53:55 +0000153 // Find the block that defines the function represented by "sym_ctx"
154 Block *function_block = sym_ctx.GetFunctionBlock();
Sean Callanan72e49402011-08-05 23:43:37 +0000155
Greg Clayton685c88c2012-07-14 00:53:55 +0000156 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000157 {
158 if (log)
159 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000160 return;
Sean Callanan70385082012-12-01 00:08:33 +0000161 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000162
163 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
164
Sean Callanan72e49402011-08-05 23:43:37 +0000165 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000166 {
167 if (log)
168 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000169 return;
Sean Callanan70385082012-12-01 00:08:33 +0000170 }
171
Sean Callanan72e49402011-08-05 23:43:37 +0000172 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000173 {
Sean Callananc7b65062011-11-07 23:35:40 +0000174 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000175 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000176 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000177 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000178 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanand5cc1322011-12-13 01:42:04 +0000179
180 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
181
Greg Clayton685c88c2012-07-14 00:53:55 +0000182 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000183 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000184 err.SetErrorString(thisErrorString);
185 return;
186 }
187
Greg Clayton685c88c2012-07-14 00:53:55 +0000188 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sean Callanand5cc1322011-12-13 01:42:04 +0000189
Greg Clayton685c88c2012-07-14 00:53:55 +0000190 if (!this_var_sp ||
191 !this_var_sp->IsInScope(frame) ||
192 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000193 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000194 err.SetErrorString(thisErrorString);
195 return;
196 }
Sean Callanan744756e2011-11-04 02:09:33 +0000197 }
198
Sean Callanan72e49402011-08-05 23:43:37 +0000199 m_cplusplus = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000200 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000201 }
202 }
Sean Callanan72e49402011-08-05 23:43:37 +0000203 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
Sean Callanan744756e2011-11-04 02:09:33 +0000204 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000205 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000206 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000207 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000208 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000209 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanand5cc1322011-12-13 01:42:04 +0000210
211 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
212
Greg Clayton685c88c2012-07-14 00:53:55 +0000213 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000214 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000215 err.SetErrorString(selfErrorString);
216 return;
217 }
218
Greg Clayton685c88c2012-07-14 00:53:55 +0000219 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sean Callanand5cc1322011-12-13 01:42:04 +0000220
Greg Clayton685c88c2012-07-14 00:53:55 +0000221 if (!self_variable_sp ||
222 !self_variable_sp->IsInScope(frame) ||
223 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000224 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000225 err.SetErrorString(selfErrorString);
226 return;
227 }
Sean Callanan744756e2011-11-04 02:09:33 +0000228 }
229
Sean Callanan72e49402011-08-05 23:43:37 +0000230 m_objectivec = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000231 m_needs_object_ptr = true;
Sean Callanand5c17ed2011-11-15 02:11:17 +0000232
233 if (!method_decl->isInstanceMethod())
234 m_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000235 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000236 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000237 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
238 {
239 // We might also have a function that said in the debug information that it captured an
240 // object pointer. The best way to deal with getting to the ivars at present it by pretending
241 // that this is a method of a class in whatever runtime the debug info says the object pointer
242 // belongs to. Do that here.
243
Greg Claytond0029442013-03-27 01:48:02 +0000244 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000245 if (metadata && metadata->HasObjectPtr())
246 {
247 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
248 if (language == lldb::eLanguageTypeC_plus_plus)
249 {
Sean Callanana2868d42013-01-19 01:49:02 +0000250 if (m_enforce_valid_object)
251 {
252 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
253
254 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";
255
256 if (!variable_list_sp)
257 {
258 err.SetErrorString(thisErrorString);
259 return;
260 }
261
262 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
263
264 if (!this_var_sp ||
265 !this_var_sp->IsInScope(frame) ||
266 !this_var_sp->LocationIsValidForFrame (frame))
267 {
268 err.SetErrorString(thisErrorString);
269 return;
270 }
271 }
272
Jim Ingham5fdeed42012-10-30 23:35:54 +0000273 m_cplusplus = true;
274 m_needs_object_ptr = true;
275 }
276 else if (language == lldb::eLanguageTypeObjC)
277 {
Sean Callanana2868d42013-01-19 01:49:02 +0000278 if (m_enforce_valid_object)
279 {
280 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
281
282 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";
283
284 if (!variable_list_sp)
285 {
286 err.SetErrorString(selfErrorString);
287 return;
288 }
289
290 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
291
292 if (!self_variable_sp ||
293 !self_variable_sp->IsInScope(frame) ||
294 !self_variable_sp->LocationIsValidForFrame (frame))
295 {
296 err.SetErrorString(selfErrorString);
297 return;
298 }
299
300 Type *self_type = self_variable_sp->GetType();
301
302 if (!self_type)
303 {
304 err.SetErrorString(selfErrorString);
305 return;
306 }
307
Greg Clayton57ee3062013-07-11 22:46:58 +0000308 ClangASTType self_clang_type = self_type->GetClangForwardType();
Sean Callanana2868d42013-01-19 01:49:02 +0000309
Greg Clayton57ee3062013-07-11 22:46:58 +0000310 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000311 {
312 err.SetErrorString(selfErrorString);
313 return;
314 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000315
316 if (self_clang_type.IsObjCClassType())
Sean Callanana2868d42013-01-19 01:49:02 +0000317 {
318 return;
319 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000320 else if (self_clang_type.IsObjCObjectPointerType())
Sean Callanana2868d42013-01-19 01:49:02 +0000321 {
322 m_objectivec = true;
323 m_needs_object_ptr = true;
324 }
325 else
326 {
327 err.SetErrorString(selfErrorString);
328 return;
329 }
330 }
331 else
332 {
333 m_objectivec = true;
334 m_needs_object_ptr = true;
335 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000336 }
337 }
338 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000339}
340
Sean Callanan3dbf3462013-04-19 07:09:15 +0000341void
342ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
343{
344 m_process_wp = exe_ctx.GetProcessSP();
345
Jason Molendab57e4a12013-11-04 09:33:30 +0000346 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000347
348 if (frame_sp)
349 m_address = frame_sp->GetFrameCodeAddress();
350}
351
352bool
353ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
354 lldb::TargetSP &target_sp,
355 lldb::ProcessSP &process_sp,
Jason Molendab57e4a12013-11-04 09:33:30 +0000356 lldb::StackFrameSP &frame_sp)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000357{
358 lldb::ProcessSP expected_process_sp = m_process_wp.lock();
359 process_sp = exe_ctx.GetProcessSP();
360
361 if (process_sp != expected_process_sp)
362 return false;
363
364 process_sp = exe_ctx.GetProcessSP();
365 target_sp = exe_ctx.GetTargetSP();
366 frame_sp = exe_ctx.GetFrameSP();
367
368 if (m_address.IsValid())
369 {
370 if (!frame_sp)
371 return false;
372 else
373 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
374 }
375
376 return true;
377}
378
379bool
380ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
381{
382 lldb::TargetSP target_sp;
383 lldb::ProcessSP process_sp;
Jason Molendab57e4a12013-11-04 09:33:30 +0000384 lldb::StackFrameSP frame_sp;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000385
386 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
387}
388
Sean Callanancf5498f2010-10-22 23:25:16 +0000389// This is a really nasty hack, meant to fix Objective-C expressions of the form
390// (int)[myArray count]. Right now, because the type information for count is
391// not available, [myArray count] returns id, which can't be directly cast to
392// int without causing a clang error.
393static void
394ApplyObjcCastHack(std::string &expr)
395{
396#define OBJC_CAST_HACK_FROM "(int)["
397#define OBJC_CAST_HACK_TO "(int)(long long)["
398
399 size_t from_offset;
400
401 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
402 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
403
404#undef OBJC_CAST_HACK_TO
405#undef OBJC_CAST_HACK_FROM
406}
407
Sean Callanan64186e72010-10-24 20:45:49 +0000408// Another hack, meant to allow use of unichar despite it not being available in
409// the type information. Although we could special-case it in type lookup,
410// hopefully we'll figure out a way to #include the same environment as is
411// present in the original source file rather than try to hack specific type
412// definitions in as needed.
Saleem Abdulrasoola68f7b62014-03-20 06:08:36 +0000413//static void
414//ApplyUnicharHack(std::string &expr)
415//{
416//#define UNICHAR_HACK_FROM "unichar"
417//#define UNICHAR_HACK_TO "unsigned short"
418//
419// size_t from_offset;
420//
421// while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
422// expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
423//
424//#undef UNICHAR_HACK_TO
425//#undef UNICHAR_HACK_FROM
426//}
Sean Callanan64186e72010-10-24 20:45:49 +0000427
Sean Callanancf5498f2010-10-22 23:25:16 +0000428bool
Sean Callananf7c3e272010-11-19 02:52:21 +0000429ClangUserExpression::Parse (Stream &error_stream,
430 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000431 lldb_private::ExecutionPolicy execution_policy,
Greg Clayton23f8c952014-03-24 23:10:19 +0000432 bool keep_result_in_memory,
433 bool generate_debug_info)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000434{
Greg Clayton5160ce52013-03-27 23:08:40 +0000435 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan1a8d4092010-08-27 01:01:44 +0000436
Sean Callanan744756e2011-11-04 02:09:33 +0000437 Error err;
Sean Callanan933693b2012-02-10 01:22:05 +0000438
439 InstallContext(exe_ctx);
Sean Callanan744756e2011-11-04 02:09:33 +0000440
441 ScanContext(exe_ctx, err);
442
443 if (!err.Success())
444 {
445 error_stream.Printf("warning: %s\n", err.AsCString());
446 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000447
448 StreamString m_transformed_stream;
449
450 ////////////////////////////////////
451 // Generate the expression
452 //
Sean Callanancf5498f2010-10-22 23:25:16 +0000453
454 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000455 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000456
Greg Clayton7b0992d2013-04-18 22:45:39 +0000457 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 +0000458
459 lldb::LanguageType lang_type;
460
Sean Callananfc55f5d2010-09-21 00:44:12 +0000461 if (m_cplusplus)
Sean Callanan9bc83842011-09-26 18:45:31 +0000462 lang_type = lldb::eLanguageTypeC_plus_plus;
463 else if(m_objectivec)
464 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000465 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000466 lang_type = lldb::eLanguageTypeC;
467
Jason Molendaa3329782014-03-29 18:54:20 +0000468 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method, exe_ctx))
Sean Callananfc55f5d2010-09-21 00:44:12 +0000469 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000470 error_stream.PutCString ("error: couldn't construct expression body");
471 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000472 }
473
Sean Callananfc55f5d2010-09-21 00:44:12 +0000474 if (log)
475 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
476
Sean Callanan1a8d4092010-08-27 01:01:44 +0000477 ////////////////////////////////////
478 // Set up the target and compiler
479 //
480
Greg Claytonc14ee322011-09-22 04:58:26 +0000481 Target *target = exe_ctx.GetTargetPtr();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000482
483 if (!target)
484 {
485 error_stream.PutCString ("error: invalid target\n");
486 return false;
487 }
488
Sean Callanan1a8d4092010-08-27 01:01:44 +0000489 //////////////////////////
490 // Parse the expression
491 //
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000492
Sean Callanan96d27302013-04-11 00:09:05 +0000493 m_materializer_ap.reset(new Materializer());
494
Sean Callanan1ee44b72011-10-29 01:58:46 +0000495 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sean Callanan979f74d2010-12-03 01:38:59 +0000496
Greg Clayton57ee3062013-07-11 22:46:58 +0000497 class OnExit
498 {
499 public:
500 typedef std::function <void (void)> Callback;
501
502 OnExit (Callback const &callback) :
503 m_callback(callback)
504 {
505 }
506
507 ~OnExit ()
508 {
509 m_callback();
510 }
511 private:
512 Callback m_callback;
513 };
514
515 OnExit on_exit([this]() { m_expr_decl_map.reset(); });
516
Sean Callanan96d27302013-04-11 00:09:05 +0000517 if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000518 {
519 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sean Callananffc12852013-08-23 00:36:14 +0000520
521 m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
522
Sean Callananb9951192011-08-01 18:18:33 +0000523 return false;
524 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000525
Greg Claytonc14ee322011-09-22 04:58:26 +0000526 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000527 ExecutionContextScope *exe_scope = process;
528
529 if (!exe_scope)
530 exe_scope = exe_ctx.GetTargetPtr();
531
Greg Clayton23f8c952014-03-24 23:10:19 +0000532 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sean Callanan1a8d4092010-08-27 01:01:44 +0000533
534 unsigned num_errors = parser.Parse (error_stream);
535
536 if (num_errors)
537 {
538 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callanan979f74d2010-12-03 01:38:59 +0000539
Sean Callananffc12852013-08-23 00:36:14 +0000540 m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
Sean Callanan979f74d2010-12-03 01:38:59 +0000541
Sean Callanan1a8d4092010-08-27 01:01:44 +0000542 return false;
543 }
544
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000545 //////////////////////////////////////////////////////////////////////////////////////////
546 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000547 //
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000548
549 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000550 m_jit_end_addr,
Greg Clayton23f8c952014-03-24 23:10:19 +0000551 m_execution_unit_sp,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000552 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000553 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000554 execution_policy);
Sean Callananffc12852013-08-23 00:36:14 +0000555
Greg Clayton23f8c952014-03-24 23:10:19 +0000556 if (generate_debug_info)
557 {
558 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
559
560 if (jit_module_sp)
561 {
562 ConstString const_func_name(FunctionName());
563 FileSpec jit_file;
564 jit_file.GetFilename() = const_func_name;
565 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
566 m_jit_module_wp = jit_module_sp;
567 target->GetImages().Append(jit_module_sp);
568 }
569// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
570// StreamFile strm (stdout, false);
571// if (jit_obj_file)
572// {
573// jit_obj_file->GetSectionList();
574// jit_obj_file->GetSymtab();
575// jit_obj_file->Dump(&strm);
576// }
577// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
578// if (jit_sym_vendor)
579// {
580// lldb_private::SymbolContextList sc_list;
581// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
582// sc_list.Dump(&strm, target);
583// jit_sym_vendor->Dump(&strm);
584// }
585 }
586
Sean Callananffc12852013-08-23 00:36:14 +0000587 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 +0000588
Sean Callanan1a8d4092010-08-27 01:01:44 +0000589 if (jit_error.Success())
590 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000591 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000592 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000593 return true;
594 }
595 else
596 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000597 const char *error_cstr = jit_error.AsCString();
598 if (error_cstr && error_cstr[0])
599 error_stream.Printf ("error: %s\n", error_cstr);
600 else
Jason Molendafd54b362011-09-20 21:44:10 +0000601 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000602 return false;
603 }
604}
605
Sean Callanan1582ee62013-04-18 22:06:33 +0000606static lldb::addr_t
Jason Molendab57e4a12013-11-04 09:33:30 +0000607GetObjectPointer (lldb::StackFrameSP frame_sp,
Sean Callanan1582ee62013-04-18 22:06:33 +0000608 ConstString &object_name,
609 Error &err)
610{
611 err.Clear();
612
613 if (!frame_sp)
614 {
615 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
616 return LLDB_INVALID_ADDRESS;
617 }
618
619 lldb::VariableSP var_sp;
620 lldb::ValueObjectSP valobj_sp;
621
622 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
623 lldb::eNoDynamicValues,
Jason Molendab57e4a12013-11-04 09:33:30 +0000624 StackFrame::eExpressionPathOptionCheckPtrVsMember ||
625 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
626 StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
627 StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
628 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
Sean Callanan1582ee62013-04-18 22:06:33 +0000629 var_sp,
630 err);
631
632 if (!err.Success())
633 return LLDB_INVALID_ADDRESS;
634
635 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
636
637 if (ret == LLDB_INVALID_ADDRESS)
638 {
639 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
640 return LLDB_INVALID_ADDRESS;
641 }
642
643 return ret;
644}
645
Sean Callanan1a8d4092010-08-27 01:01:44 +0000646bool
Jim Ingham36f3b362010-10-14 23:45:03 +0000647ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
Sean Callanan104a6e92010-10-19 23:57:21 +0000648 ExecutionContext &exe_ctx,
649 lldb::addr_t &struct_address,
Sean Callanan9d48e802010-12-14 00:42:36 +0000650 lldb::addr_t &object_ptr,
651 lldb::addr_t &cmd_ptr)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000652{
Sean Callanan933693b2012-02-10 01:22:05 +0000653 lldb::TargetSP target;
654 lldb::ProcessSP process;
Jason Molendab57e4a12013-11-04 09:33:30 +0000655 lldb::StackFrameSP frame;
Sean Callanan933693b2012-02-10 01:22:05 +0000656
657 if (!LockAndCheckContext(exe_ctx,
658 target,
659 process,
660 frame))
661 {
Sean Callanan3dbf3462013-04-19 07:09:15 +0000662 error_stream.Printf("The context has changed before we could JIT the expression!\n");
Sean Callanan933693b2012-02-10 01:22:05 +0000663 return false;
664 }
665
Sean Callanan1582ee62013-04-18 22:06:33 +0000666 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
667 {
Sean Callanan17827832010-12-13 22:46:15 +0000668 if (m_needs_object_ptr)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000669 {
Sean Callanan17827832010-12-13 22:46:15 +0000670 ConstString object_name;
671
672 if (m_cplusplus)
673 {
674 object_name.SetCString("this");
675 }
676 else if (m_objectivec)
677 {
678 object_name.SetCString("self");
679 }
680 else
681 {
682 error_stream.Printf("Need object pointer but don't know the language\n");
683 return false;
684 }
685
Sean Callanan1582ee62013-04-18 22:06:33 +0000686 Error object_ptr_error;
687
688 object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
689
690 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000691 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000692 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 +0000693 object_ptr = 0;
Sean Callanan17827832010-12-13 22:46:15 +0000694 }
Sean Callanan9d48e802010-12-14 00:42:36 +0000695
696 if (m_objectivec)
697 {
698 ConstString cmd_name("_cmd");
699
Sean Callanan1582ee62013-04-18 22:06:33 +0000700 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
701
702 if (!object_ptr_error.Success())
Sean Callanan9d48e802010-12-14 00:42:36 +0000703 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000704 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanand5cc1322011-12-13 01:42:04 +0000705 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000706 }
707 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000708 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000709
Sean Callanandf565402013-04-27 02:19:33 +0000710 if (m_materialized_address == LLDB_INVALID_ADDRESS)
Sean Callanan1582ee62013-04-18 22:06:33 +0000711 {
Sean Callanandf565402013-04-27 02:19:33 +0000712 Error alloc_error;
713
714 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
715
Greg Clayton23f8c952014-03-24 23:10:19 +0000716 m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
Sean Callanandf565402013-04-27 02:19:33 +0000717 m_materializer_ap->GetStructAlignment(),
718 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
719 policy,
720 alloc_error);
721
722 if (!alloc_error.Success())
723 {
724 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
725 return false;
726 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000727 }
728
Sean Callanandf565402013-04-27 02:19:33 +0000729 struct_address = m_materialized_address;
Sean Callanan1582ee62013-04-18 22:06:33 +0000730
Sean Callanandf565402013-04-27 02:19:33 +0000731 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
732 {
733 Error alloc_error;
734
735 const size_t stack_frame_size = 512 * 1024;
736
Greg Clayton23f8c952014-03-24 23:10:19 +0000737 m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
Sean Callanandf565402013-04-27 02:19:33 +0000738 8,
739 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
740 IRMemoryMap::eAllocationPolicyHostOnly,
741 alloc_error);
742
743 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
744
745 if (!alloc_error.Success())
746 {
747 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
748 return false;
749 }
750 }
751
Sean Callanan1582ee62013-04-18 22:06:33 +0000752 Error materialize_error;
753
Greg Clayton23f8c952014-03-24 23:10:19 +0000754 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
Sean Callanan1582ee62013-04-18 22:06:33 +0000755
756 if (!materialize_error.Success())
Sean Callanan1a8d4092010-08-27 01:01:44 +0000757 {
Sean Callanan866e91c2014-02-28 22:27:53 +0000758 error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000759 return false;
760 }
Jim Ingham36f3b362010-10-14 23:45:03 +0000761 }
762 return true;
763}
764
Jim Ingham36f3b362010-10-14 23:45:03 +0000765bool
766ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
767 ExecutionContext &exe_ctx,
Sean Callanane359d9b2011-05-09 22:04:36 +0000768 lldb::ClangExpressionVariableSP &result,
Sean Callanandf565402013-04-27 02:19:33 +0000769 lldb::addr_t function_stack_bottom,
770 lldb::addr_t function_stack_top)
Jim Ingham36f3b362010-10-14 23:45:03 +0000771{
Greg Clayton5160ce52013-03-27 23:08:40 +0000772 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananc673a6e2010-12-07 10:00:20 +0000773
774 if (log)
Sean Callanana162eba2010-12-07 22:55:01 +0000775 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
Sean Callanandf565402013-04-27 02:19:33 +0000776
Sean Callanan1582ee62013-04-18 22:06:33 +0000777 if (!m_dematerializer_sp)
778 {
Sean Callanand2a507a2013-07-12 23:35:21 +0000779 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
Sean Callanan1582ee62013-04-18 22:06:33 +0000780 return false;
781 }
782
783 Error dematerialize_error;
784
Sean Callanandf565402013-04-27 02:19:33 +0000785 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000786
787 if (!dematerialize_error.Success())
Jim Ingham36f3b362010-10-14 23:45:03 +0000788 {
Sean Callanand2a507a2013-07-12 23:35:21 +0000789 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
Jim Ingham36f3b362010-10-14 23:45:03 +0000790 return false;
791 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000792
Johnny Chenb49440f2012-01-06 00:35:38 +0000793 if (result)
794 result->TransferAddress();
795
Sean Callanan1582ee62013-04-18 22:06:33 +0000796 m_dematerializer_sp.reset();
797
Jim Ingham36f3b362010-10-14 23:45:03 +0000798 return true;
799}
800
Jim Ingham1624a2d2014-05-05 02:26:40 +0000801lldb::ExpressionResults
Jim Ingham36f3b362010-10-14 23:45:03 +0000802ClangUserExpression::Execute (Stream &error_stream,
803 ExecutionContext &exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000804 const EvaluateExpressionOptions& options,
Jim Inghamf48169b2010-11-30 02:22:11 +0000805 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000806 lldb::ClangExpressionVariableSP &result)
Jim Ingham36f3b362010-10-14 23:45:03 +0000807{
Jim Inghamb086ff72011-01-18 22:20:08 +0000808 // The expression log is quite verbose, and if you're just tracking the execution of the
809 // expression, it's quite convenient to have these logs come out with the STEP log as well.
Greg Clayton5160ce52013-03-27 23:08:40 +0000810 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callananc673a6e2010-12-07 10:00:20 +0000811
Sean Callanan1582ee62013-04-18 22:06:33 +0000812 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
Jim Ingham36f3b362010-10-14 23:45:03 +0000813 {
Jim Ingham28eb5712012-10-12 17:34:26 +0000814 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Jim Ingham36f3b362010-10-14 23:45:03 +0000815
Johnny Chen44805302011-07-19 19:48:13 +0000816 lldb::addr_t object_ptr = 0;
817 lldb::addr_t cmd_ptr = 0;
Jim Ingham36f3b362010-10-14 23:45:03 +0000818
Johnny Chen8115c6d2012-08-18 04:24:00 +0000819 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
820 {
Johnny Chen2c90e992012-08-18 04:14:54 +0000821 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
Jim Ingham1624a2d2014-05-05 02:26:40 +0000822 return lldb::eExecutionSetupError;
Johnny Chen2c90e992012-08-18 04:14:54 +0000823 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000824
Sean Callanandf565402013-04-27 02:19:33 +0000825 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
826 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000827
Sean Callanan1582ee62013-04-18 22:06:33 +0000828 if (m_can_interpret)
829 {
Greg Clayton23f8c952014-03-24 23:10:19 +0000830 llvm::Module *module = m_execution_unit_sp->GetModule();
831 llvm::Function *function = m_execution_unit_sp->GetFunction();
Jim Ingham0faa43f2011-11-08 03:00:11 +0000832
Sean Callanan1582ee62013-04-18 22:06:33 +0000833 if (!module || !function)
Jim Ingham160f78c2011-05-17 01:10:11 +0000834 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000835 error_stream.Printf("Supposed to interpret, but nothing is there");
Jim Ingham1624a2d2014-05-05 02:26:40 +0000836 return lldb::eExecutionSetupError;
Jim Ingham160f78c2011-05-17 01:10:11 +0000837 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000838
Sean Callanan1582ee62013-04-18 22:06:33 +0000839 Error interpreter_error;
840
841 llvm::SmallVector <lldb::addr_t, 3> args;
842
843 if (m_needs_object_ptr)
844 {
845 args.push_back(object_ptr);
846
847 if (m_objectivec)
848 args.push_back(cmd_ptr);
849 }
850
851 args.push_back(struct_address);
852
Sean Callanandf565402013-04-27 02:19:33 +0000853 function_stack_bottom = m_stack_frame_bottom;
854 function_stack_top = m_stack_frame_top;
855
Sean Callanan1582ee62013-04-18 22:06:33 +0000856 IRInterpreter::Interpret (*module,
857 *function,
858 args,
Greg Clayton23f8c952014-03-24 23:10:19 +0000859 *m_execution_unit_sp.get(),
Sean Callanandf565402013-04-27 02:19:33 +0000860 interpreter_error,
861 function_stack_bottom,
862 function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000863
864 if (!interpreter_error.Success())
865 {
866 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
Jim Ingham1624a2d2014-05-05 02:26:40 +0000867 return lldb::eExecutionDiscarded;
Sean Callanan1582ee62013-04-18 22:06:33 +0000868 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000869 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000870 else
Jim Inghamf48169b2010-11-30 02:22:11 +0000871 {
Jim Ingham8225d592014-03-03 19:16:45 +0000872 if (!exe_ctx.HasThreadScope())
873 {
874 error_stream.Printf("ClangUserExpression::Execute called with no thread selected.");
Jim Ingham1624a2d2014-05-05 02:26:40 +0000875 return lldb::eExecutionSetupError;
Jim Ingham8225d592014-03-03 19:16:45 +0000876 }
877
Sean Callanan1582ee62013-04-18 22:06:33 +0000878 Address wrapper_address (m_jit_start_addr);
Sean Callanana464f3d2013-11-08 01:14:26 +0000879
880 llvm::SmallVector <lldb::addr_t, 3> args;
881
882 if (m_needs_object_ptr) {
883 args.push_back(object_ptr);
884 if (m_objectivec)
885 args.push_back(cmd_ptr);
886 }
887
888 args.push_back(struct_address);
889
Sean Callanan1582ee62013-04-18 22:06:33 +0000890 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
891 wrapper_address,
Sean Callanana464f3d2013-11-08 01:14:26 +0000892 args,
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000893 options,
Sean Callanan1582ee62013-04-18 22:06:33 +0000894 shared_ptr_to_me));
895
896 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
Jim Ingham1624a2d2014-05-05 02:26:40 +0000897 return lldb::eExecutionSetupError;
Sean Callanan1582ee62013-04-18 22:06:33 +0000898
Sean Callanandf565402013-04-27 02:19:33 +0000899 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
Sean Callanan1582ee62013-04-18 22:06:33 +0000900
Sean Callanandf565402013-04-27 02:19:33 +0000901 function_stack_bottom = function_stack_pointer - Host::GetPageSize();
902 function_stack_top = function_stack_pointer;
903
Sean Callanan1582ee62013-04-18 22:06:33 +0000904 if (log)
905 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
906
907 if (exe_ctx.GetProcessPtr())
908 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
909
Jim Ingham1624a2d2014-05-05 02:26:40 +0000910 lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000911 call_plan_sp,
912 options,
Sean Callanan1582ee62013-04-18 22:06:33 +0000913 error_stream);
914
915 if (exe_ctx.GetProcessPtr())
916 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
917
918 if (log)
919 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
920
Jim Ingham1624a2d2014-05-05 02:26:40 +0000921 if (execution_result == lldb::eExecutionInterrupted || execution_result == lldb::eExecutionHitBreakpoint)
Sean Callanan1582ee62013-04-18 22:06:33 +0000922 {
923 const char *error_desc = NULL;
924
925 if (call_plan_sp)
926 {
927 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
928 if (real_stop_info_sp)
929 error_desc = real_stop_info_sp->GetDescription();
930 }
931 if (error_desc)
932 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
933 else
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000934 error_stream.PutCString ("Execution was interrupted.");
Sean Callanan1582ee62013-04-18 22:06:33 +0000935
Jim Ingham1624a2d2014-05-05 02:26:40 +0000936 if ((execution_result == lldb::eExecutionInterrupted && options.DoesUnwindOnError())
937 || (execution_result == lldb::eExecutionHitBreakpoint && options.DoesIgnoreBreakpoints()))
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000938 error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
Sean Callanan1582ee62013-04-18 22:06:33 +0000939 else
Jim Ingham1624a2d2014-05-05 02:26:40 +0000940 error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
941 "use \"thread return -x\" to return to the state before expression evaluation.");
Sean Callanan1582ee62013-04-18 22:06:33 +0000942
943 return execution_result;
944 }
Jim Ingham1624a2d2014-05-05 02:26:40 +0000945 else if (execution_result == lldb::eExecutionStoppedForDebug)
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000946 {
Jim Ingham1624a2d2014-05-05 02:26:40 +0000947 error_stream.PutCString ("Execution was halted at the first instruction of the expression "
948 "function because \"debug\" was requested.\n"
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000949 "Use \"thread return -x\" to return to the state before expression evaluation.");
950 return execution_result;
951 }
Jim Ingham1624a2d2014-05-05 02:26:40 +0000952 else if (execution_result != lldb::eExecutionCompleted)
Sean Callanan1582ee62013-04-18 22:06:33 +0000953 {
954 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
955 return execution_result;
956 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000957 }
958
Sean Callanandf565402013-04-27 02:19:33 +0000959 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
960 {
Jim Ingham1624a2d2014-05-05 02:26:40 +0000961 return lldb::eExecutionCompleted;
Sean Callanandf565402013-04-27 02:19:33 +0000962 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000963 else
Johnny Chen8115c6d2012-08-18 04:24:00 +0000964 {
Jim Ingham1624a2d2014-05-05 02:26:40 +0000965 return lldb::eExecutionResultUnavailable;
Johnny Chen8115c6d2012-08-18 04:24:00 +0000966 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000967 }
968 else
969 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000970 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
Jim Ingham1624a2d2014-05-05 02:26:40 +0000971 return lldb::eExecutionSetupError;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000972 }
973}
974
Jim Ingham1624a2d2014-05-05 02:26:40 +0000975lldb::ExpressionResults
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000976ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000977 const EvaluateExpressionOptions& options,
Sean Callanan322f5292010-10-29 00:29:03 +0000978 const char *expr_cstr,
Jim Inghamf48169b2010-11-30 02:22:11 +0000979 const char *expr_prefix,
Enrico Granata3372f582012-07-16 23:10:35 +0000980 lldb::ValueObjectSP &result_valobj_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000981 Error &error)
Jim Ingham41c75912011-08-09 00:00:49 +0000982{
Greg Clayton5160ce52013-03-27 23:08:40 +0000983 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanana162eba2010-12-07 22:55:01 +0000984
Greg Clayton62afb9f2013-11-04 19:35:17 +0000985 lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
986 const lldb::LanguageType language = options.GetLanguage();
987 const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
Jim Ingham1624a2d2014-05-05 02:26:40 +0000988 lldb::ExpressionResults execution_results = lldb::eExecutionSetupError;
Greg Clayton8f343b02010-11-04 01:54:29 +0000989
Greg Claytonc14ee322011-09-22 04:58:26 +0000990 Process *process = exe_ctx.GetProcessPtr();
991
992 if (process == NULL || process->GetState() != lldb::eStateStopped)
Jim Inghamf48169b2010-11-30 02:22:11 +0000993 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000994 if (execution_policy == eExecutionPolicyAlways)
995 {
996 if (log)
997 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Jim Inghamf48169b2010-11-30 02:22:11 +0000998
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000999 error.SetErrorString ("expression needed to run but couldn't");
1000
1001 return execution_results;
1002 }
Jim Inghamf48169b2010-11-30 02:22:11 +00001003 }
Sean Callanan64fe1992011-09-15 17:43:00 +00001004
Greg Claytonc14ee322011-09-22 04:58:26 +00001005 if (process == NULL || !process->CanJIT())
Sean Callanan64fe1992011-09-15 17:43:00 +00001006 execution_policy = eExecutionPolicyNever;
Greg Clayton8f343b02010-11-04 01:54:29 +00001007
Sean Callanan20bb3aa2011-12-21 22:22:58 +00001008 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
Jim Inghamf48169b2010-11-30 02:22:11 +00001009
Greg Clayton0184f012010-10-05 00:31:29 +00001010 StreamString error_stream;
Sean Callanan63697e52011-05-07 01:06:41 +00001011
Sean Callanana162eba2010-12-07 22:55:01 +00001012 if (log)
1013 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
1014
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001015 const bool keep_expression_in_memory = true;
Greg Clayton23f8c952014-03-24 23:10:19 +00001016 const bool generate_debug_info = options.GetGenerateDebugInfo();
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001017
Jim Ingham1624a2d2014-05-05 02:26:40 +00001018 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
1019 {
1020 error.SetErrorString ("expression interrupted by callback before parse");
1021 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
1022 return lldb::eExecutionInterrupted;
1023 }
1024
Greg Clayton23f8c952014-03-24 23:10:19 +00001025 if (!user_expression_sp->Parse (error_stream,
1026 exe_ctx,
1027 execution_policy,
1028 keep_expression_in_memory,
1029 generate_debug_info))
Greg Clayton0184f012010-10-05 00:31:29 +00001030 {
1031 if (error_stream.GetString().empty())
Jim Ingham1624a2d2014-05-05 02:26:40 +00001032 error.SetExpressionError (lldb::eExecutionParseError, "expression failed to parse, unknown error");
Greg Clayton0184f012010-10-05 00:31:29 +00001033 else
Jim Ingham1624a2d2014-05-05 02:26:40 +00001034 error.SetExpressionError (lldb::eExecutionParseError, error_stream.GetString().c_str());
Greg Clayton0184f012010-10-05 00:31:29 +00001035 }
1036 else
1037 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001038 lldb::ClangExpressionVariableSP expr_result;
Greg Clayton0184f012010-10-05 00:31:29 +00001039
Sean Callanan1582ee62013-04-18 22:06:33 +00001040 if (execution_policy == eExecutionPolicyNever &&
1041 !user_expression_sp->CanInterpret())
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001042 {
1043 if (log)
1044 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
1045
1046 if (error_stream.GetString().empty())
Jim Ingham1624a2d2014-05-05 02:26:40 +00001047 error.SetExpressionError (lldb::eExecutionSetupError, "expression needed to run but couldn't");
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001048 }
Sean Callanane4ec90e2010-12-16 03:17:46 +00001049 else
Jim Ingham1624a2d2014-05-05 02:26:40 +00001050 {
1051 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
1052 {
1053 error.SetExpressionError (lldb::eExecutionInterrupted, "expression interrupted by callback before execution");
1054 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
1055 return lldb::eExecutionInterrupted;
1056 }
1057
Sean Callanane4ec90e2010-12-16 03:17:46 +00001058 error_stream.GetString().clear();
1059
1060 if (log)
1061 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
1062
1063 execution_results = user_expression_sp->Execute (error_stream,
Greg Clayton62afb9f2013-11-04 19:35:17 +00001064 exe_ctx,
1065 options,
1066 user_expression_sp,
1067 expr_result);
Sean Callanane4ec90e2010-12-16 03:17:46 +00001068
Jim Ingham1624a2d2014-05-05 02:26:40 +00001069 if (execution_results != lldb::eExecutionCompleted)
Greg Clayton0184f012010-10-05 00:31:29 +00001070 {
Sean Callanana162eba2010-12-07 22:55:01 +00001071 if (log)
Sean Callanane4ec90e2010-12-16 03:17:46 +00001072 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
1073
1074 if (error_stream.GetString().empty())
Jim Ingham1624a2d2014-05-05 02:26:40 +00001075 error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
Sean Callanane4ec90e2010-12-16 03:17:46 +00001076 else
Jim Ingham1624a2d2014-05-05 02:26:40 +00001077 error.SetExpressionError (execution_results, error_stream.GetString().c_str());
Greg Clayton0184f012010-10-05 00:31:29 +00001078 }
Sean Callanane4ec90e2010-12-16 03:17:46 +00001079 else
Greg Clayton0184f012010-10-05 00:31:29 +00001080 {
Sean Callanane4ec90e2010-12-16 03:17:46 +00001081 if (expr_result)
1082 {
1083 result_valobj_sp = expr_result->GetValueObject();
1084
1085 if (log)
Jim Ingham1624a2d2014-05-05 02:26:40 +00001086 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==",
1087 result_valobj_sp->GetValueAsCString());
Sean Callanane4ec90e2010-12-16 03:17:46 +00001088 }
1089 else
1090 {
1091 if (log)
1092 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
1093
Sean Callananbccce812011-08-23 21:20:51 +00001094 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
Sean Callanane4ec90e2010-12-16 03:17:46 +00001095 }
Greg Clayton0184f012010-10-05 00:31:29 +00001096 }
1097 }
1098 }
Sean Callananc57f64d2010-10-19 20:15:00 +00001099
Jim Ingham1624a2d2014-05-05 02:26:40 +00001100 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
1101 {
1102 error.SetExpressionError (lldb::eExecutionInterrupted, "expression interrupted by callback after complete");
1103 return lldb::eExecutionInterrupted;
1104 }
1105
Greg Claytonb71f3842010-10-05 03:13:51 +00001106 if (result_valobj_sp.get() == NULL)
Greg Claytoneeb15652013-12-10 23:16:40 +00001107 {
1108 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
1109 }
Greg Claytonb71f3842010-10-05 03:13:51 +00001110
Jim Inghamf48169b2010-11-30 02:22:11 +00001111 return execution_results;
Johnny Chendabefd02010-10-29 20:19:44 +00001112}