blob: 21c6de5c5a6e7cd2a95304ae47732a7c40fd5946 [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
Sean Callanan1a8d4092010-08-27 01:01:44 +000010#include <stdio.h>
11#if HAVE_SYS_TYPES_H
12# include <sys/types.h>
13#endif
14
Sean Callanan1a8d4092010-08-27 01:01:44 +000015#include <cstdlib>
16#include <string>
17#include <map>
18
19#include "lldb/Core/ConstString.h"
20#include "lldb/Core/Log.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000021#include "lldb/Core/Module.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000022#include "lldb/Core/StreamFile.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000023#include "lldb/Core/StreamString.h"
Greg Claytonb71f3842010-10-05 03:13:51 +000024#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanane4ec90e2010-12-16 03:17:46 +000025#include "lldb/Expression/ASTResultSynthesizer.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000026#include "lldb/Expression/ClangExpressionDeclMap.h"
27#include "lldb/Expression/ClangExpressionParser.h"
28#include "lldb/Expression/ClangFunction.h"
Zachary Turneraf0f45f2015-03-03 21:05:17 +000029#include "lldb/Expression/ClangPersistentVariables.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"
Zachary Turner97a14e62014-08-19 17:18:29 +000035#include "lldb/Host/HostInfo.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"
Greg Clayton23f8c952014-03-24 23:10:19 +000039#include "lldb/Symbol/ObjectFile.h"
40#include "lldb/Symbol/SymbolVendor.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000041#include "lldb/Symbol/Type.h"
42#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Sean Callananfc55f5d2010-09-21 00:44:12 +000043#include "lldb/Symbol/VariableList.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000044#include "lldb/Target/ExecutionContext.h"
Greg Clayton8f343b02010-11-04 01:54:29 +000045#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000046#include "lldb/Target/StackFrame.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000047#include "lldb/Target/Target.h"
Jim Inghamf48169b2010-11-30 02:22:11 +000048#include "lldb/Target/ThreadPlan.h"
49#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000050
Sean Callanan72e49402011-08-05 23:43:37 +000051#include "clang/AST/DeclCXX.h"
52#include "clang/AST/DeclObjC.h"
53
Sean Callanan1a8d4092010-08-27 01:01:44 +000054using namespace lldb_private;
55
Sean Callanan322f5292010-10-29 00:29:03 +000056ClangUserExpression::ClangUserExpression (const char *expr,
Sean Callananc7b65062011-11-07 23:35:40 +000057 const char *expr_prefix,
Sean Callanan20bb3aa2011-12-21 22:22:58 +000058 lldb::LanguageType language,
59 ResultType desired_type) :
Greg Clayton22a939a2011-01-19 23:00:49 +000060 ClangExpression (),
Sean Callanandf565402013-04-27 02:19:33 +000061 m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
62 m_stack_frame_top (LLDB_INVALID_ADDRESS),
Greg Clayton22a939a2011-01-19 23:00:49 +000063 m_expr_text (expr),
64 m_expr_prefix (expr_prefix ? expr_prefix : ""),
Sean Callananc7b65062011-11-07 23:35:40 +000065 m_language (language),
Greg Clayton22a939a2011-01-19 23:00:49 +000066 m_transformed_text (),
Sean Callanan20bb3aa2011-12-21 22:22:58 +000067 m_desired_type (desired_type),
Greg Clayton23f8c952014-03-24 23:10:19 +000068 m_expr_decl_map(),
69 m_execution_unit_sp(),
70 m_materializer_ap(),
71 m_result_synthesizer(),
72 m_jit_module_wp(),
Sean Callananeab6cc92012-12-06 01:35:38 +000073 m_enforce_valid_object (true),
Greg Clayton22a939a2011-01-19 23:00:49 +000074 m_cplusplus (false),
75 m_objectivec (false),
Bill Wendlingd53b5de2012-04-03 08:46:13 +000076 m_static_method(false),
Greg Clayton22a939a2011-01-19 23:00:49 +000077 m_needs_object_ptr (false),
Sean Callanan63697e52011-05-07 01:06:41 +000078 m_const_object (false),
Daniel Dunbara08823f2011-10-31 22:50:49 +000079 m_target (NULL),
Sean Callanandf565402013-04-27 02:19:33 +000080 m_can_interpret (false),
81 m_materialized_address (LLDB_INVALID_ADDRESS)
Sean Callanan1a8d4092010-08-27 01:01:44 +000082{
Sean Callananc7b65062011-11-07 23:35:40 +000083 switch (m_language)
84 {
85 case lldb::eLanguageTypeC_plus_plus:
86 m_allow_cxx = true;
87 break;
88 case lldb::eLanguageTypeObjC:
89 m_allow_objc = true;
90 break;
91 case lldb::eLanguageTypeObjC_plus_plus:
92 default:
93 m_allow_cxx = true;
94 m_allow_objc = true;
95 break;
96 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000097}
98
Sean Callanane71d5532010-08-27 23:31:21 +000099ClangUserExpression::~ClangUserExpression ()
100{
Greg Clayton23f8c952014-03-24 23:10:19 +0000101 if (m_target)
102 {
103 lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
104 if (jit_module_sp)
105 m_target->GetImages().Remove(jit_module_sp);
106 }
Sean Callanane71d5532010-08-27 23:31:21 +0000107}
108
Sean Callanan1a8d4092010-08-27 01:01:44 +0000109clang::ASTConsumer *
110ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
Sean Callanan394e36d2013-10-10 00:39:23 +0000111{
112 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
113 *m_target));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000114
Sean Callanan2590b9a2011-10-08 00:21:35 +0000115 return m_result_synthesizer.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000116}
117
Sean Callananfc55f5d2010-09-21 00:44:12 +0000118void
Sean Callanan744756e2011-11-04 02:09:33 +0000119ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000120{
Greg Clayton5160ce52013-03-27 23:08:40 +0000121 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +0000122
123 if (log)
124 log->Printf("ClangUserExpression::ScanContext()");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000125
Greg Claytonc14ee322011-09-22 04:58:26 +0000126 m_target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000127
Sean Callananc7b65062011-11-07 23:35:40 +0000128 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +0000129 {
130 if (log)
131 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +0000132 return;
Sean Callanan70385082012-12-01 00:08:33 +0000133 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000134
Jason Molendab57e4a12013-11-04 09:33:30 +0000135 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000136 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000137 {
138 if (log)
139 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000140 return;
Sean Callanan70385082012-12-01 00:08:33 +0000141 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000142
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000143 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000144
Sean Callanan72e49402011-08-05 23:43:37 +0000145 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000146 {
147 if (log)
148 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000149 return;
Sean Callanan70385082012-12-01 00:08:33 +0000150 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000151
Greg Clayton685c88c2012-07-14 00:53:55 +0000152 // Find the block that defines the function represented by "sym_ctx"
153 Block *function_block = sym_ctx.GetFunctionBlock();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000154
Greg Clayton685c88c2012-07-14 00:53:55 +0000155 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000156 {
157 if (log)
158 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000159 return;
Sean Callanan70385082012-12-01 00:08:33 +0000160 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000161
162 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
163
Sean Callanan72e49402011-08-05 23:43:37 +0000164 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000165 {
166 if (log)
167 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000168 return;
Sean Callanan70385082012-12-01 00:08:33 +0000169 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000170
Sean Callanan72e49402011-08-05 23:43:37 +0000171 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000172 {
Sean Callananc7b65062011-11-07 23:35:40 +0000173 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000174 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000175 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000176 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000177 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000178
Sean Callanand5cc1322011-12-13 01:42:04 +0000179 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000180
Greg Clayton685c88c2012-07-14 00:53:55 +0000181 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000182 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000183 err.SetErrorString(thisErrorString);
184 return;
185 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000186
Greg Clayton685c88c2012-07-14 00:53:55 +0000187 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000188
Greg Clayton685c88c2012-07-14 00:53:55 +0000189 if (!this_var_sp ||
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000190 !this_var_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000191 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000192 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000193 err.SetErrorString(thisErrorString);
194 return;
195 }
Sean Callanan744756e2011-11-04 02:09:33 +0000196 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000197
Sean Callanan72e49402011-08-05 23:43:37 +0000198 m_cplusplus = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000199 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000200 }
201 }
Sean Callanan72e49402011-08-05 23:43:37 +0000202 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000203 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000204 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000205 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000206 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000207 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000208 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000209
Sean Callanand5cc1322011-12-13 01:42:04 +0000210 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000211
Greg Clayton685c88c2012-07-14 00:53:55 +0000212 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000213 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000214 err.SetErrorString(selfErrorString);
215 return;
216 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000217
Greg Clayton685c88c2012-07-14 00:53:55 +0000218 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000219
220 if (!self_variable_sp ||
221 !self_variable_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000222 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000223 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000224 err.SetErrorString(selfErrorString);
225 return;
226 }
Sean Callanan744756e2011-11-04 02:09:33 +0000227 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000228
Sean Callanan72e49402011-08-05 23:43:37 +0000229 m_objectivec = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000230 m_needs_object_ptr = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000231
Sean Callanand5c17ed2011-11-15 02:11:17 +0000232 if (!method_decl->isInstanceMethod())
233 m_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000234 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000235 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000236 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
237 {
238 // We might also have a function that said in the debug information that it captured an
239 // object pointer. The best way to deal with getting to the ivars at present it by pretending
240 // that this is a method of a class in whatever runtime the debug info says the object pointer
241 // belongs to. Do that here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000242
Greg Claytond0029442013-03-27 01:48:02 +0000243 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000244 if (metadata && metadata->HasObjectPtr())
245 {
246 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
247 if (language == lldb::eLanguageTypeC_plus_plus)
248 {
Sean Callanana2868d42013-01-19 01:49:02 +0000249 if (m_enforce_valid_object)
250 {
251 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000252
Sean Callanana2868d42013-01-19 01:49:02 +0000253 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";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000254
Sean Callanana2868d42013-01-19 01:49:02 +0000255 if (!variable_list_sp)
256 {
257 err.SetErrorString(thisErrorString);
258 return;
259 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000260
Sean Callanana2868d42013-01-19 01:49:02 +0000261 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000262
Sean Callanana2868d42013-01-19 01:49:02 +0000263 if (!this_var_sp ||
264 !this_var_sp->IsInScope(frame) ||
265 !this_var_sp->LocationIsValidForFrame (frame))
266 {
267 err.SetErrorString(thisErrorString);
268 return;
269 }
270 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000271
Jim Ingham5fdeed42012-10-30 23:35:54 +0000272 m_cplusplus = true;
273 m_needs_object_ptr = true;
274 }
275 else if (language == lldb::eLanguageTypeObjC)
276 {
Sean Callanana2868d42013-01-19 01:49:02 +0000277 if (m_enforce_valid_object)
278 {
279 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000280
Sean Callanana2868d42013-01-19 01:49:02 +0000281 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";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000282
Sean Callanana2868d42013-01-19 01:49:02 +0000283 if (!variable_list_sp)
284 {
285 err.SetErrorString(selfErrorString);
286 return;
287 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000288
Sean Callanana2868d42013-01-19 01:49:02 +0000289 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000290
Sean Callanana2868d42013-01-19 01:49:02 +0000291 if (!self_variable_sp ||
292 !self_variable_sp->IsInScope(frame) ||
293 !self_variable_sp->LocationIsValidForFrame (frame))
294 {
295 err.SetErrorString(selfErrorString);
296 return;
297 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000298
Sean Callanana2868d42013-01-19 01:49:02 +0000299 Type *self_type = self_variable_sp->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000300
Sean Callanana2868d42013-01-19 01:49:02 +0000301 if (!self_type)
302 {
303 err.SetErrorString(selfErrorString);
304 return;
305 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000306
Greg Clayton57ee3062013-07-11 22:46:58 +0000307 ClangASTType self_clang_type = self_type->GetClangForwardType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000308
Greg Clayton57ee3062013-07-11 22:46:58 +0000309 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000310 {
311 err.SetErrorString(selfErrorString);
312 return;
313 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000314
Greg Clayton57ee3062013-07-11 22:46:58 +0000315 if (self_clang_type.IsObjCClassType())
Sean Callanana2868d42013-01-19 01:49:02 +0000316 {
317 return;
318 }
Greg Clayton57ee3062013-07-11 22:46:58 +0000319 else if (self_clang_type.IsObjCObjectPointerType())
Sean Callanana2868d42013-01-19 01:49:02 +0000320 {
321 m_objectivec = true;
322 m_needs_object_ptr = true;
323 }
324 else
325 {
326 err.SetErrorString(selfErrorString);
327 return;
328 }
329 }
330 else
331 {
332 m_objectivec = true;
333 m_needs_object_ptr = true;
334 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000335 }
336 }
337 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000338}
339
Sean Callanan3dbf3462013-04-19 07:09:15 +0000340void
341ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
342{
343 m_process_wp = exe_ctx.GetProcessSP();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000344
Jason Molendab57e4a12013-11-04 09:33:30 +0000345 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000346
Sean Callanan3dbf3462013-04-19 07:09:15 +0000347 if (frame_sp)
348 m_address = frame_sp->GetFrameCodeAddress();
349}
350
351bool
352ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
353 lldb::TargetSP &target_sp,
354 lldb::ProcessSP &process_sp,
Jason Molendab57e4a12013-11-04 09:33:30 +0000355 lldb::StackFrameSP &frame_sp)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000356{
357 lldb::ProcessSP expected_process_sp = m_process_wp.lock();
358 process_sp = exe_ctx.GetProcessSP();
359
360 if (process_sp != expected_process_sp)
361 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000362
Sean Callanan3dbf3462013-04-19 07:09:15 +0000363 process_sp = exe_ctx.GetProcessSP();
364 target_sp = exe_ctx.GetTargetSP();
365 frame_sp = exe_ctx.GetFrameSP();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000366
Sean Callanan3dbf3462013-04-19 07:09:15 +0000367 if (m_address.IsValid())
368 {
369 if (!frame_sp)
370 return false;
371 else
372 return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
373 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000374
Sean Callanan3dbf3462013-04-19 07:09:15 +0000375 return true;
376}
377
378bool
379ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
380{
381 lldb::TargetSP target_sp;
382 lldb::ProcessSP process_sp;
Jason Molendab57e4a12013-11-04 09:33:30 +0000383 lldb::StackFrameSP frame_sp;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000384
Sean Callanan3dbf3462013-04-19 07:09:15 +0000385 return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
386}
387
Sean Callanancf5498f2010-10-22 23:25:16 +0000388// This is a really nasty hack, meant to fix Objective-C expressions of the form
389// (int)[myArray count]. Right now, because the type information for count is
390// not available, [myArray count] returns id, which can't be directly cast to
391// int without causing a clang error.
392static void
393ApplyObjcCastHack(std::string &expr)
394{
395#define OBJC_CAST_HACK_FROM "(int)["
396#define OBJC_CAST_HACK_TO "(int)(long long)["
397
398 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000399
Sean Callanancf5498f2010-10-22 23:25:16 +0000400 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
401 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
402
403#undef OBJC_CAST_HACK_TO
404#undef OBJC_CAST_HACK_FROM
405}
406
Sean Callanan64186e72010-10-24 20:45:49 +0000407// Another hack, meant to allow use of unichar despite it not being available in
408// the type information. Although we could special-case it in type lookup,
409// hopefully we'll figure out a way to #include the same environment as is
410// present in the original source file rather than try to hack specific type
411// definitions in as needed.
Saleem Abdulrasoola68f7b62014-03-20 06:08:36 +0000412//static void
413//ApplyUnicharHack(std::string &expr)
414//{
415//#define UNICHAR_HACK_FROM "unichar"
416//#define UNICHAR_HACK_TO "unsigned short"
417//
418// size_t from_offset;
419//
420// while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
421// expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
422//
423//#undef UNICHAR_HACK_TO
424//#undef UNICHAR_HACK_FROM
425//}
Sean Callanan64186e72010-10-24 20:45:49 +0000426
Sean Callanancf5498f2010-10-22 23:25:16 +0000427bool
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000428ClangUserExpression::Parse (Stream &error_stream,
Sean Callananf7c3e272010-11-19 02:52:21 +0000429 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000430 lldb_private::ExecutionPolicy execution_policy,
Greg Clayton23f8c952014-03-24 23:10:19 +0000431 bool keep_result_in_memory,
432 bool generate_debug_info)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000433{
Greg Clayton5160ce52013-03-27 23:08:40 +0000434 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000435
Sean Callanan744756e2011-11-04 02:09:33 +0000436 Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000437
Sean Callanan933693b2012-02-10 01:22:05 +0000438 InstallContext(exe_ctx);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000439
Sean Callanan744756e2011-11-04 02:09:33 +0000440 ScanContext(exe_ctx, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000441
Sean Callanan744756e2011-11-04 02:09:33 +0000442 if (!err.Success())
443 {
444 error_stream.Printf("warning: %s\n", err.AsCString());
445 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000446
Sean Callananfc55f5d2010-09-21 00:44:12 +0000447 StreamString m_transformed_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000448
Sean Callananfc55f5d2010-09-21 00:44:12 +0000449 ////////////////////////////////////
450 // Generate the expression
451 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000452
Sean Callanancf5498f2010-10-22 23:25:16 +0000453 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000454 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000455
Greg Clayton7b0992d2013-04-18 22:45:39 +0000456 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000457
Sean Callanan9bc83842011-09-26 18:45:31 +0000458 lldb::LanguageType lang_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000459
Sean Callananfc55f5d2010-09-21 00:44:12 +0000460 if (m_cplusplus)
Sean Callanan9bc83842011-09-26 18:45:31 +0000461 lang_type = lldb::eLanguageTypeC_plus_plus;
462 else if(m_objectivec)
463 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000464 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000465 lang_type = lldb::eLanguageTypeC;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000466
Jason Molendaa3329782014-03-29 18:54:20 +0000467 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method, exe_ctx))
Sean Callananfc55f5d2010-09-21 00:44:12 +0000468 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000469 error_stream.PutCString ("error: couldn't construct expression body");
470 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000471 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000472
Sean Callananfc55f5d2010-09-21 00:44:12 +0000473 if (log)
474 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000475
Sean Callanan1a8d4092010-08-27 01:01:44 +0000476 ////////////////////////////////////
477 // Set up the target and compiler
478 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000479
Greg Claytonc14ee322011-09-22 04:58:26 +0000480 Target *target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000481
Sean Callanan1a8d4092010-08-27 01:01:44 +0000482 if (!target)
483 {
484 error_stream.PutCString ("error: invalid target\n");
485 return false;
486 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000487
Sean Callanan1a8d4092010-08-27 01:01:44 +0000488 //////////////////////////
489 // Parse the expression
490 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000491
Sean Callanan96d27302013-04-11 00:09:05 +0000492 m_materializer_ap.reset(new Materializer());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000493
Sean Callanan1ee44b72011-10-29 01:58:46 +0000494 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000495
Greg Clayton57ee3062013-07-11 22:46:58 +0000496 class OnExit
497 {
498 public:
499 typedef std::function <void (void)> Callback;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000500
Greg Clayton57ee3062013-07-11 22:46:58 +0000501 OnExit (Callback const &callback) :
502 m_callback(callback)
503 {
504 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000505
Greg Clayton57ee3062013-07-11 22:46:58 +0000506 ~OnExit ()
507 {
508 m_callback();
509 }
510 private:
511 Callback m_callback;
512 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000513
Greg Clayton57ee3062013-07-11 22:46:58 +0000514 OnExit on_exit([this]() { m_expr_decl_map.reset(); });
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000515
Sean Callanan96d27302013-04-11 00:09:05 +0000516 if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000517 {
518 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000519
Sean Callananffc12852013-08-23 00:36:14 +0000520 m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000521
Sean Callananb9951192011-08-01 18:18:33 +0000522 return false;
523 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000524
Greg Claytonc14ee322011-09-22 04:58:26 +0000525 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000526 ExecutionContextScope *exe_scope = process;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000527
Sean Callananaa719af2012-02-08 18:43:35 +0000528 if (!exe_scope)
529 exe_scope = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000530
Todd Fiala2c77a422014-10-10 01:11:39 +0000531 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000532
Sean Callanan1a8d4092010-08-27 01:01:44 +0000533 unsigned num_errors = parser.Parse (error_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000534
Sean Callanan1a8d4092010-08-27 01:01:44 +0000535 if (num_errors)
536 {
537 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000538
Sean Callananffc12852013-08-23 00:36:14 +0000539 m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000540
Sean Callanan1a8d4092010-08-27 01:01:44 +0000541 return false;
542 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000543
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000544 //////////////////////////////////////////////////////////////////////////////////////////
545 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000546 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000547
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000548 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000549 m_jit_end_addr,
Greg Clayton23f8c952014-03-24 23:10:19 +0000550 m_execution_unit_sp,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000551 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000552 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000553 execution_policy);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000554
Greg Clayton23f8c952014-03-24 23:10:19 +0000555 if (generate_debug_info)
556 {
557 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000558
Greg Clayton23f8c952014-03-24 23:10:19 +0000559 if (jit_module_sp)
560 {
561 ConstString const_func_name(FunctionName());
562 FileSpec jit_file;
563 jit_file.GetFilename() = const_func_name;
564 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
565 m_jit_module_wp = jit_module_sp;
566 target->GetImages().Append(jit_module_sp);
567 }
568// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
569// StreamFile strm (stdout, false);
570// if (jit_obj_file)
571// {
572// jit_obj_file->GetSectionList();
573// jit_obj_file->GetSymtab();
574// jit_obj_file->Dump(&strm);
575// }
576// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
577// if (jit_sym_vendor)
578// {
579// lldb_private::SymbolContextList sc_list;
580// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
581// sc_list.Dump(&strm, target);
582// jit_sym_vendor->Dump(&strm);
583// }
584 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000585
Sean Callananffc12852013-08-23 00:36:14 +0000586 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.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000587
Sean Callanan1a8d4092010-08-27 01:01:44 +0000588 if (jit_error.Success())
589 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000590 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000591 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000592 return true;
593 }
594 else
595 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000596 const char *error_cstr = jit_error.AsCString();
597 if (error_cstr && error_cstr[0])
598 error_stream.Printf ("error: %s\n", error_cstr);
599 else
Jason Molendafd54b362011-09-20 21:44:10 +0000600 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000601 return false;
602 }
603}
604
Sean Callanan1582ee62013-04-18 22:06:33 +0000605static lldb::addr_t
Jason Molendab57e4a12013-11-04 09:33:30 +0000606GetObjectPointer (lldb::StackFrameSP frame_sp,
Sean Callanan1582ee62013-04-18 22:06:33 +0000607 ConstString &object_name,
608 Error &err)
609{
610 err.Clear();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000611
Sean Callanan1582ee62013-04-18 22:06:33 +0000612 if (!frame_sp)
613 {
614 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
615 return LLDB_INVALID_ADDRESS;
616 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000617
Sean Callanan1582ee62013-04-18 22:06:33 +0000618 lldb::VariableSP var_sp;
619 lldb::ValueObjectSP valobj_sp;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000620
Sean Callanan1582ee62013-04-18 22:06:33 +0000621 valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
622 lldb::eNoDynamicValues,
Jason Molenda9bc86592014-10-16 08:27:27 +0000623 StackFrame::eExpressionPathOptionCheckPtrVsMember |
Jason Molenda9bc86592014-10-16 08:27:27 +0000624 StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
625 StackFrame::eExpressionPathOptionsNoSyntheticChildren |
Jason Molendab57e4a12013-11-04 09:33:30 +0000626 StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
Sean Callanan1582ee62013-04-18 22:06:33 +0000627 var_sp,
628 err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000629
Sean Callanan5e3bdbf2014-10-17 18:16:04 +0000630 if (!err.Success() || !valobj_sp.get())
Sean Callanan1582ee62013-04-18 22:06:33 +0000631 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000632
Sean Callanan1582ee62013-04-18 22:06:33 +0000633 lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000634
Sean Callanan1582ee62013-04-18 22:06:33 +0000635 if (ret == LLDB_INVALID_ADDRESS)
636 {
637 err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
638 return LLDB_INVALID_ADDRESS;
639 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000640
Sean Callanan1582ee62013-04-18 22:06:33 +0000641 return ret;
642}
643
Sean Callanan1a8d4092010-08-27 01:01:44 +0000644bool
Jim Ingham36f3b362010-10-14 23:45:03 +0000645ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
Sean Callanan104a6e92010-10-19 23:57:21 +0000646 ExecutionContext &exe_ctx,
647 lldb::addr_t &struct_address,
Sean Callanan9d48e802010-12-14 00:42:36 +0000648 lldb::addr_t &object_ptr,
649 lldb::addr_t &cmd_ptr)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000650{
Sean Callanan933693b2012-02-10 01:22:05 +0000651 lldb::TargetSP target;
652 lldb::ProcessSP process;
Jason Molendab57e4a12013-11-04 09:33:30 +0000653 lldb::StackFrameSP frame;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000654
Sean Callanan933693b2012-02-10 01:22:05 +0000655 if (!LockAndCheckContext(exe_ctx,
656 target,
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000657 process,
Sean Callanan933693b2012-02-10 01:22:05 +0000658 frame))
659 {
Sean Callanan3dbf3462013-04-19 07:09:15 +0000660 error_stream.Printf("The context has changed before we could JIT the expression!\n");
Sean Callanan933693b2012-02-10 01:22:05 +0000661 return false;
662 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000663
Sean Callanan1582ee62013-04-18 22:06:33 +0000664 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000665 {
Sean Callanan17827832010-12-13 22:46:15 +0000666 if (m_needs_object_ptr)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000667 {
Sean Callanan17827832010-12-13 22:46:15 +0000668 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000669
Sean Callanan17827832010-12-13 22:46:15 +0000670 if (m_cplusplus)
671 {
672 object_name.SetCString("this");
673 }
674 else if (m_objectivec)
675 {
676 object_name.SetCString("self");
677 }
678 else
679 {
680 error_stream.Printf("Need object pointer but don't know the language\n");
681 return false;
682 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000683
Sean Callanan1582ee62013-04-18 22:06:33 +0000684 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000685
Sean Callanan1582ee62013-04-18 22:06:33 +0000686 object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000687
Sean Callanan1582ee62013-04-18 22:06:33 +0000688 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000689 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000690 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 +0000691 object_ptr = 0;
Sean Callanan17827832010-12-13 22:46:15 +0000692 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000693
Sean Callanan9d48e802010-12-14 00:42:36 +0000694 if (m_objectivec)
695 {
696 ConstString cmd_name("_cmd");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000697
Sean Callanan1582ee62013-04-18 22:06:33 +0000698 cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000699
Sean Callanan1582ee62013-04-18 22:06:33 +0000700 if (!object_ptr_error.Success())
Sean Callanan9d48e802010-12-14 00:42:36 +0000701 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000702 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
Sean Callanand5cc1322011-12-13 01:42:04 +0000703 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000704 }
705 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000706 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000707
Sean Callanandf565402013-04-27 02:19:33 +0000708 if (m_materialized_address == LLDB_INVALID_ADDRESS)
Sean Callanan1582ee62013-04-18 22:06:33 +0000709 {
Sean Callanandf565402013-04-27 02:19:33 +0000710 Error alloc_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000711
Sean Callanandf565402013-04-27 02:19:33 +0000712 IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000713
Greg Clayton23f8c952014-03-24 23:10:19 +0000714 m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
Sean Callanandf565402013-04-27 02:19:33 +0000715 m_materializer_ap->GetStructAlignment(),
716 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
717 policy,
718 alloc_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000719
Sean Callanandf565402013-04-27 02:19:33 +0000720 if (!alloc_error.Success())
721 {
722 error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
723 return false;
724 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000725 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000726
Sean Callanandf565402013-04-27 02:19:33 +0000727 struct_address = m_materialized_address;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000728
Sean Callanandf565402013-04-27 02:19:33 +0000729 if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
730 {
731 Error alloc_error;
732
733 const size_t stack_frame_size = 512 * 1024;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000734
Greg Clayton23f8c952014-03-24 23:10:19 +0000735 m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
Sean Callanandf565402013-04-27 02:19:33 +0000736 8,
737 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
738 IRMemoryMap::eAllocationPolicyHostOnly,
739 alloc_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000740
Sean Callanandf565402013-04-27 02:19:33 +0000741 m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000742
Sean Callanandf565402013-04-27 02:19:33 +0000743 if (!alloc_error.Success())
744 {
745 error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
746 return false;
747 }
748 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000749
Sean Callanan1582ee62013-04-18 22:06:33 +0000750 Error materialize_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000751
Greg Clayton23f8c952014-03-24 23:10:19 +0000752 m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000753
Sean Callanan1582ee62013-04-18 22:06:33 +0000754 if (!materialize_error.Success())
Sean Callanan1a8d4092010-08-27 01:01:44 +0000755 {
Sean Callanan866e91c2014-02-28 22:27:53 +0000756 error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000757 return false;
758 }
Jim Ingham36f3b362010-10-14 23:45:03 +0000759 }
760 return true;
761}
762
Jim Ingham36f3b362010-10-14 23:45:03 +0000763bool
764ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
765 ExecutionContext &exe_ctx,
Sean Callanane359d9b2011-05-09 22:04:36 +0000766 lldb::ClangExpressionVariableSP &result,
Sean Callanandf565402013-04-27 02:19:33 +0000767 lldb::addr_t function_stack_bottom,
768 lldb::addr_t function_stack_top)
Jim Ingham36f3b362010-10-14 23:45:03 +0000769{
Greg Clayton5160ce52013-03-27 23:08:40 +0000770 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000771
Sean Callananc673a6e2010-12-07 10:00:20 +0000772 if (log)
Sean Callanana162eba2010-12-07 22:55:01 +0000773 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000774
Sean Callanan1582ee62013-04-18 22:06:33 +0000775 if (!m_dematerializer_sp)
776 {
Sean Callanand2a507a2013-07-12 23:35:21 +0000777 error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
Sean Callanan1582ee62013-04-18 22:06:33 +0000778 return false;
779 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000780
Sean Callanan1582ee62013-04-18 22:06:33 +0000781 Error dematerialize_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000782
Sean Callanandf565402013-04-27 02:19:33 +0000783 m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
Sean Callanan1582ee62013-04-18 22:06:33 +0000784
785 if (!dematerialize_error.Success())
Jim Ingham36f3b362010-10-14 23:45:03 +0000786 {
Sean Callanand2a507a2013-07-12 23:35:21 +0000787 error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
Jim Ingham36f3b362010-10-14 23:45:03 +0000788 return false;
789 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000790
Johnny Chenb49440f2012-01-06 00:35:38 +0000791 if (result)
792 result->TransferAddress();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000793
Sean Callanan1582ee62013-04-18 22:06:33 +0000794 m_dematerializer_sp.reset();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000795
Jim Ingham36f3b362010-10-14 23:45:03 +0000796 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000797}
Jim Ingham36f3b362010-10-14 23:45:03 +0000798
Jim Ingham1624a2d2014-05-05 02:26:40 +0000799lldb::ExpressionResults
Jim Ingham36f3b362010-10-14 23:45:03 +0000800ClangUserExpression::Execute (Stream &error_stream,
801 ExecutionContext &exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000802 const EvaluateExpressionOptions& options,
Zachary Turnerfc858812015-03-04 17:43:00 +0000803 lldb::ClangUserExpressionSP &shared_ptr_to_me,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000804 lldb::ClangExpressionVariableSP &result)
Jim Ingham36f3b362010-10-14 23:45:03 +0000805{
Jim Inghamb086ff72011-01-18 22:20:08 +0000806 // The expression log is quite verbose, and if you're just tracking the execution of the
807 // expression, it's quite convenient to have these logs come out with the STEP log as well.
Greg Clayton5160ce52013-03-27 23:08:40 +0000808 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callananc673a6e2010-12-07 10:00:20 +0000809
Sean Callanan1582ee62013-04-18 22:06:33 +0000810 if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
Jim Ingham36f3b362010-10-14 23:45:03 +0000811 {
Jim Ingham28eb5712012-10-12 17:34:26 +0000812 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000813
Johnny Chen44805302011-07-19 19:48:13 +0000814 lldb::addr_t object_ptr = 0;
815 lldb::addr_t cmd_ptr = 0;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000816
Johnny Chen8115c6d2012-08-18 04:24:00 +0000817 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
818 {
Johnny Chen2c90e992012-08-18 04:14:54 +0000819 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
Jim Ingham8646d3c2014-05-05 02:47:44 +0000820 return lldb::eExpressionSetupError;
Johnny Chen2c90e992012-08-18 04:14:54 +0000821 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000822
Sean Callanandf565402013-04-27 02:19:33 +0000823 lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
824 lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000825
Sean Callanan1582ee62013-04-18 22:06:33 +0000826 if (m_can_interpret)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000827 {
Greg Clayton23f8c952014-03-24 23:10:19 +0000828 llvm::Module *module = m_execution_unit_sp->GetModule();
829 llvm::Function *function = m_execution_unit_sp->GetFunction();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000830
Sean Callanan1582ee62013-04-18 22:06:33 +0000831 if (!module || !function)
Jim Ingham160f78c2011-05-17 01:10:11 +0000832 {
Sean Callanan1582ee62013-04-18 22:06:33 +0000833 error_stream.Printf("Supposed to interpret, but nothing is there");
Jim Ingham8646d3c2014-05-05 02:47:44 +0000834 return lldb::eExpressionSetupError;
Jim Ingham160f78c2011-05-17 01:10:11 +0000835 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000836
Sean Callanan1582ee62013-04-18 22:06:33 +0000837 Error interpreter_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000838
Sean Callanan1582ee62013-04-18 22:06:33 +0000839 llvm::SmallVector <lldb::addr_t, 3> args;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000840
Sean Callanan1582ee62013-04-18 22:06:33 +0000841 if (m_needs_object_ptr)
842 {
843 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000844
Sean Callanan1582ee62013-04-18 22:06:33 +0000845 if (m_objectivec)
846 args.push_back(cmd_ptr);
847 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000848
Sean Callanan1582ee62013-04-18 22:06:33 +0000849 args.push_back(struct_address);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000850
Sean Callanandf565402013-04-27 02:19:33 +0000851 function_stack_bottom = m_stack_frame_bottom;
852 function_stack_top = m_stack_frame_top;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000853
Sean Callanan1582ee62013-04-18 22:06:33 +0000854 IRInterpreter::Interpret (*module,
855 *function,
856 args,
Greg Clayton23f8c952014-03-24 23:10:19 +0000857 *m_execution_unit_sp.get(),
Sean Callanandf565402013-04-27 02:19:33 +0000858 interpreter_error,
859 function_stack_bottom,
860 function_stack_top);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000861
Sean Callanan1582ee62013-04-18 22:06:33 +0000862 if (!interpreter_error.Success())
863 {
864 error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
Jim Ingham8646d3c2014-05-05 02:47:44 +0000865 return lldb::eExpressionDiscarded;
Sean Callanan1582ee62013-04-18 22:06:33 +0000866 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000867 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000868 else
Jim Inghamf48169b2010-11-30 02:22:11 +0000869 {
Jim Ingham8225d592014-03-03 19:16:45 +0000870 if (!exe_ctx.HasThreadScope())
871 {
872 error_stream.Printf("ClangUserExpression::Execute called with no thread selected.");
Jim Ingham8646d3c2014-05-05 02:47:44 +0000873 return lldb::eExpressionSetupError;
Jim Ingham8225d592014-03-03 19:16:45 +0000874 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000875
Sean Callanan1582ee62013-04-18 22:06:33 +0000876 Address wrapper_address (m_jit_start_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000877
Sean Callanana464f3d2013-11-08 01:14:26 +0000878 llvm::SmallVector <lldb::addr_t, 3> args;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000879
Sean Callanana464f3d2013-11-08 01:14:26 +0000880 if (m_needs_object_ptr) {
881 args.push_back(object_ptr);
882 if (m_objectivec)
883 args.push_back(cmd_ptr);
884 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000885
Sean Callanana464f3d2013-11-08 01:14:26 +0000886 args.push_back(struct_address);
Jim Ingham30fadaf2014-07-08 01:07:32 +0000887
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000888 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
889 wrapper_address,
890 args,
891 options,
892 shared_ptr_to_me));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000893
Sean Callanan1582ee62013-04-18 22:06:33 +0000894 if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
Jim Ingham8646d3c2014-05-05 02:47:44 +0000895 return lldb::eExpressionSetupError;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000896
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000897 ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
898
Jim Ingham30fadaf2014-07-08 01:07:32 +0000899 lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
Sean Callanan1582ee62013-04-18 22:06:33 +0000900
Zachary Turner97a14e62014-08-19 17:18:29 +0000901 function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
Sean Callanandf565402013-04-27 02:19:33 +0000902 function_stack_top = function_stack_pointer;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000903
Sean Callanan1582ee62013-04-18 22:06:33 +0000904 if (log)
905 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000906
Sean Callanan1582ee62013-04-18 22:06:33 +0000907 if (exe_ctx.GetProcessPtr())
908 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000909
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);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000914
Sean Callanan1582ee62013-04-18 22:06:33 +0000915 if (exe_ctx.GetProcessPtr())
916 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000917
Sean Callanan1582ee62013-04-18 22:06:33 +0000918 if (log)
919 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
920
Jim Ingham8646d3c2014-05-05 02:47:44 +0000921 if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
Sean Callanan1582ee62013-04-18 22:06:33 +0000922 {
923 const char *error_desc = NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000924
Sean Callanan1582ee62013-04-18 22:06:33 +0000925 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.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000935
Jim Ingham8646d3c2014-05-05 02:47:44 +0000936 if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
937 || (execution_result == lldb::eExpressionHitBreakpoint && 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 Ingham30fadaf2014-07-08 01:07:32 +0000940 {
941 if (execution_result == lldb::eExpressionHitBreakpoint)
942 user_expression_plan->TransferExpressionOwnership();
Jim Ingham1624a2d2014-05-05 02:26:40 +0000943 error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
944 "use \"thread return -x\" to return to the state before expression evaluation.");
Jim Ingham30fadaf2014-07-08 01:07:32 +0000945 }
Sean Callanan1582ee62013-04-18 22:06:33 +0000946
947 return execution_result;
948 }
Jim Ingham8646d3c2014-05-05 02:47:44 +0000949 else if (execution_result == lldb::eExpressionStoppedForDebug)
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000950 {
Jim Ingham1624a2d2014-05-05 02:26:40 +0000951 error_stream.PutCString ("Execution was halted at the first instruction of the expression "
952 "function because \"debug\" was requested.\n"
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000953 "Use \"thread return -x\" to return to the state before expression evaluation.");
954 return execution_result;
955 }
Jim Ingham8646d3c2014-05-05 02:47:44 +0000956 else if (execution_result != lldb::eExpressionCompleted)
Sean Callanan1582ee62013-04-18 22:06:33 +0000957 {
958 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
959 return execution_result;
960 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000961 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000962
Sean Callanandf565402013-04-27 02:19:33 +0000963 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
964 {
Jim Ingham8646d3c2014-05-05 02:47:44 +0000965 return lldb::eExpressionCompleted;
Sean Callanandf565402013-04-27 02:19:33 +0000966 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000967 else
Johnny Chen8115c6d2012-08-18 04:24:00 +0000968 {
Jim Ingham8646d3c2014-05-05 02:47:44 +0000969 return lldb::eExpressionResultUnavailable;
Johnny Chen8115c6d2012-08-18 04:24:00 +0000970 }
Sean Callanan1a8d4092010-08-27 01:01:44 +0000971 }
972 else
973 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000974 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
Jim Ingham8646d3c2014-05-05 02:47:44 +0000975 return lldb::eExpressionSetupError;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000976 }
977}
978
Jim Ingham1624a2d2014-05-05 02:26:40 +0000979lldb::ExpressionResults
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000980ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000981 const EvaluateExpressionOptions& options,
Sean Callanan322f5292010-10-29 00:29:03 +0000982 const char *expr_cstr,
Jim Inghamf48169b2010-11-30 02:22:11 +0000983 const char *expr_prefix,
Enrico Granata3372f582012-07-16 23:10:35 +0000984 lldb::ValueObjectSP &result_valobj_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000985 Error &error)
Jim Ingham41c75912011-08-09 00:00:49 +0000986{
Greg Clayton5160ce52013-03-27 23:08:40 +0000987 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanana162eba2010-12-07 22:55:01 +0000988
Greg Clayton62afb9f2013-11-04 19:35:17 +0000989 lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
990 const lldb::LanguageType language = options.GetLanguage();
991 const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
Jim Ingham8646d3c2014-05-05 02:47:44 +0000992 lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000993
Greg Claytonc14ee322011-09-22 04:58:26 +0000994 Process *process = exe_ctx.GetProcessPtr();
995
996 if (process == NULL || process->GetState() != lldb::eStateStopped)
Jim Inghamf48169b2010-11-30 02:22:11 +0000997 {
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000998 if (execution_policy == eExecutionPolicyAlways)
999 {
1000 if (log)
1001 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001002
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001003 error.SetErrorString ("expression needed to run but couldn't");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001004
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001005 return execution_results;
1006 }
Jim Inghamf48169b2010-11-30 02:22:11 +00001007 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001008
Greg Claytonc14ee322011-09-22 04:58:26 +00001009 if (process == NULL || !process->CanJIT())
Sean Callanan64fe1992011-09-15 17:43:00 +00001010 execution_policy = eExecutionPolicyNever;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001011
Zachary Turnerfc858812015-03-04 17:43:00 +00001012 lldb::ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
Jim Inghamf48169b2010-11-30 02:22:11 +00001013
Greg Clayton0184f012010-10-05 00:31:29 +00001014 StreamString error_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001015
Sean Callanana162eba2010-12-07 22:55:01 +00001016 if (log)
1017 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001018
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001019 const bool keep_expression_in_memory = true;
Greg Clayton23f8c952014-03-24 23:10:19 +00001020 const bool generate_debug_info = options.GetGenerateDebugInfo();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001021
Jim Ingham1624a2d2014-05-05 02:26:40 +00001022 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
1023 {
1024 error.SetErrorString ("expression interrupted by callback before parse");
1025 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001026 return lldb::eExpressionInterrupted;
Jim Ingham1624a2d2014-05-05 02:26:40 +00001027 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001028
Greg Clayton23f8c952014-03-24 23:10:19 +00001029 if (!user_expression_sp->Parse (error_stream,
1030 exe_ctx,
1031 execution_policy,
1032 keep_expression_in_memory,
1033 generate_debug_info))
Greg Clayton0184f012010-10-05 00:31:29 +00001034 {
1035 if (error_stream.GetString().empty())
Jim Ingham8646d3c2014-05-05 02:47:44 +00001036 error.SetExpressionError (lldb::eExpressionParseError, "expression failed to parse, unknown error");
Greg Clayton0184f012010-10-05 00:31:29 +00001037 else
Jim Ingham8646d3c2014-05-05 02:47:44 +00001038 error.SetExpressionError (lldb::eExpressionParseError, error_stream.GetString().c_str());
Greg Clayton0184f012010-10-05 00:31:29 +00001039 }
1040 else
1041 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +00001042 lldb::ClangExpressionVariableSP expr_result;
Greg Clayton0184f012010-10-05 00:31:29 +00001043
Sean Callanan1582ee62013-04-18 22:06:33 +00001044 if (execution_policy == eExecutionPolicyNever &&
1045 !user_expression_sp->CanInterpret())
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001046 {
1047 if (log)
1048 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001049
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001050 if (error_stream.GetString().empty())
Jim Ingham8646d3c2014-05-05 02:47:44 +00001051 error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001052 }
Sean Callanane4ec90e2010-12-16 03:17:46 +00001053 else
Jim Ingham1624a2d2014-05-05 02:26:40 +00001054 {
1055 if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
1056 {
Jim Ingham8646d3c2014-05-05 02:47:44 +00001057 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
Jim Ingham1624a2d2014-05-05 02:26:40 +00001058 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
Jim Ingham8646d3c2014-05-05 02:47:44 +00001059 return lldb::eExpressionInterrupted;
Jim Ingham1624a2d2014-05-05 02:26:40 +00001060 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001061
Sean Callanane4ec90e2010-12-16 03:17:46 +00001062 error_stream.GetString().clear();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001063
Sean Callanane4ec90e2010-12-16 03:17:46 +00001064 if (log)
1065 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
1066
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001067 execution_results = user_expression_sp->Execute (error_stream,
Greg Clayton62afb9f2013-11-04 19:35:17 +00001068 exe_ctx,
1069 options,
1070 user_expression_sp,
1071 expr_result);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001072
Jason Molendae5d8eaf2014-10-16 21:25:43 +00001073 if (options.GetResultIsInternal() && expr_result && process)
Jim Ingham4ac04432014-07-19 01:09:16 +00001074 {
1075 process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
1076 }
1077
Jim Ingham8646d3c2014-05-05 02:47:44 +00001078 if (execution_results != lldb::eExpressionCompleted)
Greg Clayton0184f012010-10-05 00:31:29 +00001079 {
Sean Callanana162eba2010-12-07 22:55:01 +00001080 if (log)
Sean Callanane4ec90e2010-12-16 03:17:46 +00001081 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001082
Sean Callanane4ec90e2010-12-16 03:17:46 +00001083 if (error_stream.GetString().empty())
Jim Ingham1624a2d2014-05-05 02:26:40 +00001084 error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
Sean Callanane4ec90e2010-12-16 03:17:46 +00001085 else
Jim Ingham1624a2d2014-05-05 02:26:40 +00001086 error.SetExpressionError (execution_results, error_stream.GetString().c_str());
Greg Clayton0184f012010-10-05 00:31:29 +00001087 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001088 else
Greg Clayton0184f012010-10-05 00:31:29 +00001089 {
Sean Callanane4ec90e2010-12-16 03:17:46 +00001090 if (expr_result)
1091 {
1092 result_valobj_sp = expr_result->GetValueObject();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001093
Sean Callanane4ec90e2010-12-16 03:17:46 +00001094 if (log)
Jim Ingham1624a2d2014-05-05 02:26:40 +00001095 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==",
1096 result_valobj_sp->GetValueAsCString());
Sean Callanane4ec90e2010-12-16 03:17:46 +00001097 }
1098 else
1099 {
1100 if (log)
1101 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001102
Sean Callananbccce812011-08-23 21:20:51 +00001103 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
Sean Callanane4ec90e2010-12-16 03:17:46 +00001104 }
Greg Clayton0184f012010-10-05 00:31:29 +00001105 }
1106 }
1107 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001108
Jim Ingham1624a2d2014-05-05 02:26:40 +00001109 if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
1110 {
Jim Ingham8646d3c2014-05-05 02:47:44 +00001111 error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
1112 return lldb::eExpressionInterrupted;
Jim Ingham1624a2d2014-05-05 02:26:40 +00001113 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001114
Greg Claytonb71f3842010-10-05 03:13:51 +00001115 if (result_valobj_sp.get() == NULL)
Greg Claytoneeb15652013-12-10 23:16:40 +00001116 {
1117 result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
1118 }
Greg Claytonb71f3842010-10-05 03:13:51 +00001119
Jim Inghamf48169b2010-11-30 02:22:11 +00001120 return execution_results;
Johnny Chendabefd02010-10-29 20:19:44 +00001121}