blob: 91cb886f12658881d696cdab617d844732ba5536 [file] [log] [blame]
Sean Callananc0492742011-05-23 21:40:23 +00001//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
Sean Callanan65dafa82010-08-27 01:01:44 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11#include <stdio.h>
12#if HAVE_SYS_TYPES_H
13# include <sys/types.h>
14#endif
15
16// C++ Includes
17#include <cstdlib>
18#include <string>
19#include <map>
20
21#include "lldb/Core/ConstString.h"
22#include "lldb/Core/Log.h"
Greg Claytonc71899e2011-01-18 19:36:39 +000023#include "lldb/Core/StreamFile.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000024#include "lldb/Core/StreamString.h"
Greg Claytond1719722010-10-05 03:13:51 +000025#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan05a5a1b2010-12-16 03:17:46 +000026#include "lldb/Expression/ASTResultSynthesizer.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000027#include "lldb/Expression/ClangExpressionDeclMap.h"
28#include "lldb/Expression/ClangExpressionParser.h"
29#include "lldb/Expression/ClangFunction.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000030#include "lldb/Expression/ClangUserExpression.h"
Sean Callanande3d27e2011-09-26 18:45:31 +000031#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000032#include "lldb/Host/Host.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000033#include "lldb/Symbol/Block.h"
Jim Inghamc7f17c02012-10-30 23:35:54 +000034#include "lldb/Symbol/ClangASTContext.h"
35#include "lldb/Symbol/Function.h"
36#include "lldb/Symbol/Type.h"
37#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Sean Callanan3c9c5eb2010-09-21 00:44:12 +000038#include "lldb/Symbol/VariableList.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000039#include "lldb/Target/ExecutionContext.h"
Greg Clayton0baa3942010-11-04 01:54:29 +000040#include "lldb/Target/Process.h"
Sean Callanan3c9c5eb2010-09-21 00:44:12 +000041#include "lldb/Target/StackFrame.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000042#include "lldb/Target/Target.h"
Jim Ingham360f53f2010-11-30 02:22:11 +000043#include "lldb/Target/ThreadPlan.h"
44#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000045
Sean Callananc617a4c2011-08-05 23:43:37 +000046#include "clang/AST/DeclCXX.h"
47#include "clang/AST/DeclObjC.h"
48
Sean Callanan65dafa82010-08-27 01:01:44 +000049using namespace lldb_private;
50
Sean Callanan77e93942010-10-29 00:29:03 +000051ClangUserExpression::ClangUserExpression (const char *expr,
Sean Callanan5b658cc2011-11-07 23:35:40 +000052 const char *expr_prefix,
Sean Callanandaa6efe2011-12-21 22:22:58 +000053 lldb::LanguageType language,
54 ResultType desired_type) :
Greg Claytond0882d02011-01-19 23:00:49 +000055 ClangExpression (),
56 m_expr_text (expr),
57 m_expr_prefix (expr_prefix ? expr_prefix : ""),
Sean Callanan5b658cc2011-11-07 23:35:40 +000058 m_language (language),
Greg Claytond0882d02011-01-19 23:00:49 +000059 m_transformed_text (),
Sean Callanandaa6efe2011-12-21 22:22:58 +000060 m_desired_type (desired_type),
Bill Wendlingd787da42012-04-03 08:46:13 +000061 m_enforce_valid_object (false),
Greg Claytond0882d02011-01-19 23:00:49 +000062 m_cplusplus (false),
63 m_objectivec (false),
Bill Wendlingd787da42012-04-03 08:46:13 +000064 m_static_method(false),
Greg Claytond0882d02011-01-19 23:00:49 +000065 m_needs_object_ptr (false),
Sean Callanan696cf5f2011-05-07 01:06:41 +000066 m_const_object (false),
Daniel Dunbar97c89572011-10-31 22:50:49 +000067 m_target (NULL),
Sean Callanan47dc4572011-09-15 02:13:07 +000068 m_evaluated_statically (false),
Bill Wendlingd787da42012-04-03 08:46:13 +000069 m_const_result ()
Sean Callanan65dafa82010-08-27 01:01:44 +000070{
Sean Callanan5b658cc2011-11-07 23:35:40 +000071 switch (m_language)
72 {
73 case lldb::eLanguageTypeC_plus_plus:
74 m_allow_cxx = true;
75 break;
76 case lldb::eLanguageTypeObjC:
77 m_allow_objc = true;
78 break;
79 case lldb::eLanguageTypeObjC_plus_plus:
80 default:
81 m_allow_cxx = true;
82 m_allow_objc = true;
83 break;
84 }
Sean Callanan65dafa82010-08-27 01:01:44 +000085}
86
Sean Callanan830a9032010-08-27 23:31:21 +000087ClangUserExpression::~ClangUserExpression ()
88{
89}
90
Sean Callanan65dafa82010-08-27 01:01:44 +000091clang::ASTConsumer *
92ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
Sean Callanan036fa902011-08-24 22:18:12 +000093{
Sean Callanan24312442011-08-23 21:20:51 +000094 ClangASTContext *clang_ast_context = m_target->GetScratchClangASTContext();
95
96 if (!clang_ast_context)
97 return NULL;
98
Sean Callanan060d53f2011-10-08 00:21:35 +000099 if (!m_result_synthesizer.get())
100 m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
Sean Callanane1301a62011-12-06 03:41:14 +0000101 *m_target));
Sean Callanan060d53f2011-10-08 00:21:35 +0000102
103 return m_result_synthesizer.get();
Sean Callanan65dafa82010-08-27 01:01:44 +0000104}
105
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000106void
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000107ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000108{
Greg Clayton567e7f32011-09-22 04:58:26 +0000109 m_target = exe_ctx.GetTargetPtr();
Greg Clayton144188b2011-09-12 23:21:58 +0000110
Sean Callanan5b658cc2011-11-07 23:35:40 +0000111 if (!(m_allow_cxx || m_allow_objc))
112 return;
113
Greg Clayton567e7f32011-09-22 04:58:26 +0000114 StackFrame *frame = exe_ctx.GetFramePtr();
115 if (frame == NULL)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000116 return;
117
Sean Callananb573bd62012-07-13 21:20:29 +0000118 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sean Callanane8e55572010-12-01 21:35:54 +0000119
Sean Callananc617a4c2011-08-05 23:43:37 +0000120 if (!sym_ctx.function)
121 return;
122
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000123 // Find the block that defines the function represented by "sym_ctx"
124 Block *function_block = sym_ctx.GetFunctionBlock();
Sean Callananc617a4c2011-08-05 23:43:37 +0000125
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000126 if (!function_block)
127 return;
128
129 clang::DeclContext *decl_context = function_block->GetClangDeclContext();
130
Sean Callananc617a4c2011-08-05 23:43:37 +0000131 if (!decl_context)
132 return;
Sean Callanan036fa902011-08-24 22:18:12 +0000133
Sean Callananc617a4c2011-08-05 23:43:37 +0000134 if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
Sean Callanane8e55572010-12-01 21:35:54 +0000135 {
Sean Callanan5b658cc2011-11-07 23:35:40 +0000136 if (m_allow_cxx && method_decl->isInstance())
Sean Callanane8e55572010-12-01 21:35:54 +0000137 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000138 if (m_enforce_valid_object)
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000139 {
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000140 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000141
142 const char *thisErrorString = "Stopped in a C++ method, but 'this' isn't available; pretending we are in a generic context";
143
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000144 if (!variable_list_sp)
Sean Callanan5ed59a72011-12-13 01:42:04 +0000145 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000146 err.SetErrorString(thisErrorString);
147 return;
148 }
149
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000150 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000151
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000152 if (!this_var_sp ||
153 !this_var_sp->IsInScope(frame) ||
154 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanan5ed59a72011-12-13 01:42:04 +0000155 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000156 err.SetErrorString(thisErrorString);
157 return;
158 }
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000159 }
160
Sean Callananc617a4c2011-08-05 23:43:37 +0000161 m_cplusplus = true;
Sean Callanande3d27e2011-09-26 18:45:31 +0000162 m_needs_object_ptr = true;
Sean Callanane8e55572010-12-01 21:35:54 +0000163 }
164 }
Sean Callananc617a4c2011-08-05 23:43:37 +0000165 else if (clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context))
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000166 {
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000167 if (m_allow_objc)
Sean Callanande3d27e2011-09-26 18:45:31 +0000168 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000169 if (m_enforce_valid_object)
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000170 {
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000171 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000172
173 const char *selfErrorString = "Stopped in an Objective-C method, but 'self' isn't available; pretending we are in a generic context";
174
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000175 if (!variable_list_sp)
Sean Callanan5ed59a72011-12-13 01:42:04 +0000176 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000177 err.SetErrorString(selfErrorString);
178 return;
179 }
180
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000181 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sean Callanan5ed59a72011-12-13 01:42:04 +0000182
Greg Claytonb3a1a2b2012-07-14 00:53:55 +0000183 if (!self_variable_sp ||
184 !self_variable_sp->IsInScope(frame) ||
185 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanan5ed59a72011-12-13 01:42:04 +0000186 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000187 err.SetErrorString(selfErrorString);
188 return;
189 }
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000190 }
191
Sean Callananc617a4c2011-08-05 23:43:37 +0000192 m_objectivec = true;
Sean Callanande3d27e2011-09-26 18:45:31 +0000193 m_needs_object_ptr = true;
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000194
195 if (!method_decl->isInstanceMethod())
196 m_static_method = true;
Sean Callanande3d27e2011-09-26 18:45:31 +0000197 }
Sean Callanane8e55572010-12-01 21:35:54 +0000198 }
Jim Inghamc7f17c02012-10-30 23:35:54 +0000199 else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context))
200 {
201 // We might also have a function that said in the debug information that it captured an
202 // object pointer. The best way to deal with getting to the ivars at present it by pretending
203 // that this is a method of a class in whatever runtime the debug info says the object pointer
204 // belongs to. Do that here.
205
206 ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), (uintptr_t) function_decl);
207 if (metadata && metadata->HasObjectPtr())
208 {
209 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
210 if (language == lldb::eLanguageTypeC_plus_plus)
211 {
212 m_cplusplus = true;
213 m_needs_object_ptr = true;
214 }
215 else if (language == lldb::eLanguageTypeObjC)
216 {
217 m_objectivec = true;
218 m_needs_object_ptr = true;
219 }
220 }
221 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000222}
223
Sean Callanan550f2762010-10-22 23:25:16 +0000224// This is a really nasty hack, meant to fix Objective-C expressions of the form
225// (int)[myArray count]. Right now, because the type information for count is
226// not available, [myArray count] returns id, which can't be directly cast to
227// int without causing a clang error.
228static void
229ApplyObjcCastHack(std::string &expr)
230{
231#define OBJC_CAST_HACK_FROM "(int)["
232#define OBJC_CAST_HACK_TO "(int)(long long)["
233
234 size_t from_offset;
235
236 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
237 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
238
239#undef OBJC_CAST_HACK_TO
240#undef OBJC_CAST_HACK_FROM
241}
242
Sean Callanan30892372010-10-24 20:45:49 +0000243// Another hack, meant to allow use of unichar despite it not being available in
244// the type information. Although we could special-case it in type lookup,
245// hopefully we'll figure out a way to #include the same environment as is
246// present in the original source file rather than try to hack specific type
247// definitions in as needed.
248static void
249ApplyUnicharHack(std::string &expr)
250{
251#define UNICHAR_HACK_FROM "unichar"
252#define UNICHAR_HACK_TO "unsigned short"
253
254 size_t from_offset;
255
256 while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
257 expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
258
259#undef UNICHAR_HACK_TO
260#undef UNICHAR_HACK_FROM
261}
262
Sean Callanan550f2762010-10-22 23:25:16 +0000263bool
Sean Callanana91dd992010-11-19 02:52:21 +0000264ClangUserExpression::Parse (Stream &error_stream,
265 ExecutionContext &exe_ctx,
Sean Callanan47dc4572011-09-15 02:13:07 +0000266 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan696cf5f2011-05-07 01:06:41 +0000267 bool keep_result_in_memory)
Sean Callanan65dafa82010-08-27 01:01:44 +0000268{
Greg Claytone005f2c2010-11-06 01:53:30 +0000269 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan65dafa82010-08-27 01:01:44 +0000270
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000271 Error err;
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000272
273 InstallContext(exe_ctx);
Sean Callananfa9e6dd2011-11-04 02:09:33 +0000274
275 ScanContext(exe_ctx, err);
276
277 if (!err.Success())
278 {
279 error_stream.Printf("warning: %s\n", err.AsCString());
280 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000281
282 StreamString m_transformed_stream;
283
284 ////////////////////////////////////
285 // Generate the expression
286 //
Sean Callanan550f2762010-10-22 23:25:16 +0000287
288 ApplyObjcCastHack(m_expr_text);
Greg Claytonf3d0b0c2010-10-27 03:32:59 +0000289 //ApplyUnicharHack(m_expr_text);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000290
Sean Callanande3d27e2011-09-26 18:45:31 +0000291 std::auto_ptr <ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(m_expr_prefix.c_str(), m_expr_text.c_str()));
292
293 lldb::LanguageType lang_type;
294
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000295 if (m_cplusplus)
Sean Callanande3d27e2011-09-26 18:45:31 +0000296 lang_type = lldb::eLanguageTypeC_plus_plus;
297 else if(m_objectivec)
298 lang_type = lldb::eLanguageTypeObjC;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000299 else
Sean Callanande3d27e2011-09-26 18:45:31 +0000300 lang_type = lldb::eLanguageTypeC;
301
Sean Callanane6ea5fe2011-11-15 02:11:17 +0000302 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_static_method))
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000303 {
Sean Callanande3d27e2011-09-26 18:45:31 +0000304 error_stream.PutCString ("error: couldn't construct expression body");
305 return false;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000306 }
307
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000308 if (log)
309 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
310
Sean Callanan65dafa82010-08-27 01:01:44 +0000311 ////////////////////////////////////
312 // Set up the target and compiler
313 //
314
Greg Clayton567e7f32011-09-22 04:58:26 +0000315 Target *target = exe_ctx.GetTargetPtr();
Sean Callanan65dafa82010-08-27 01:01:44 +0000316
317 if (!target)
318 {
319 error_stream.PutCString ("error: invalid target\n");
320 return false;
321 }
322
Sean Callanan65dafa82010-08-27 01:01:44 +0000323 //////////////////////////
324 // Parse the expression
325 //
Sean Callanandaa6efe2011-12-21 22:22:58 +0000326
Sean Callanan73b520f2011-10-29 01:58:46 +0000327 m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sean Callananaa301c42010-12-03 01:38:59 +0000328
Sean Callanan166ba102011-08-01 18:18:33 +0000329 if (!m_expr_decl_map->WillParse(exe_ctx))
330 {
331 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
332 return false;
333 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000334
Greg Clayton567e7f32011-09-22 04:58:26 +0000335 Process *process = exe_ctx.GetProcessPtr();
Sean Callanane7ba1122012-02-08 18:43:35 +0000336 ExecutionContextScope *exe_scope = process;
337
338 if (!exe_scope)
339 exe_scope = exe_ctx.GetTargetPtr();
340
341 ClangExpressionParser parser(exe_scope, *this);
Sean Callanan65dafa82010-08-27 01:01:44 +0000342
343 unsigned num_errors = parser.Parse (error_stream);
344
345 if (num_errors)
346 {
347 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sean Callananaa301c42010-12-03 01:38:59 +0000348
349 m_expr_decl_map->DidParse();
350
Sean Callanan65dafa82010-08-27 01:01:44 +0000351 return false;
352 }
353
Sean Callanan47dc4572011-09-15 02:13:07 +0000354 //////////////////////////////////////////////////////////////////////////////////////////
355 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan65dafa82010-08-27 01:01:44 +0000356 //
Sean Callanan65dafa82010-08-27 01:01:44 +0000357
Greg Clayton567e7f32011-09-22 04:58:26 +0000358 if (execution_policy != eExecutionPolicyNever && process)
359 m_data_allocator.reset(new ProcessDataAllocator(*process));
Sean Callanan65dafa82010-08-27 01:01:44 +0000360
Sean Callanan47dc4572011-09-15 02:13:07 +0000361 Error jit_error = parser.PrepareForExecution (m_jit_alloc,
362 m_jit_start_addr,
363 m_jit_end_addr,
364 exe_ctx,
365 m_data_allocator.get(),
366 m_evaluated_statically,
367 m_const_result,
368 execution_policy);
Sean Callanan65dafa82010-08-27 01:01:44 +0000369
Sean Callanan47dc4572011-09-15 02:13:07 +0000370 if (log && m_data_allocator.get())
Sean Callananc0492742011-05-23 21:40:23 +0000371 {
372 StreamString dump_string;
373 m_data_allocator->Dump(dump_string);
374
375 log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str());
376 }
Sean Callanan6d284ef2011-10-12 22:20:02 +0000377
Sean Callanan65dafa82010-08-27 01:01:44 +0000378 if (jit_error.Success())
379 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000380 if (process && m_jit_alloc != LLDB_INVALID_ADDRESS)
Enrico Granata7adfcfd2012-09-18 00:08:47 +0000381 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan65dafa82010-08-27 01:01:44 +0000382 return true;
383 }
384 else
385 {
Greg Clayton30581972011-05-17 03:51:29 +0000386 const char *error_cstr = jit_error.AsCString();
387 if (error_cstr && error_cstr[0])
388 error_stream.Printf ("error: %s\n", error_cstr);
389 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000390 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan65dafa82010-08-27 01:01:44 +0000391 return false;
392 }
393}
394
395bool
Jim Inghamd1686902010-10-14 23:45:03 +0000396ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
Sean Callananab06af92010-10-19 23:57:21 +0000397 ExecutionContext &exe_ctx,
398 lldb::addr_t &struct_address,
Sean Callanan047923c2010-12-14 00:42:36 +0000399 lldb::addr_t &object_ptr,
400 lldb::addr_t &cmd_ptr)
Sean Callanan65dafa82010-08-27 01:01:44 +0000401{
Greg Claytone005f2c2010-11-06 01:53:30 +0000402 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan65dafa82010-08-27 01:01:44 +0000403
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000404 lldb::TargetSP target;
405 lldb::ProcessSP process;
406 lldb::StackFrameSP frame;
407
408 if (!LockAndCheckContext(exe_ctx,
409 target,
410 process,
411 frame))
412 {
413 error_stream.Printf("The context has changed before we could JIT the expression!");
414 return false;
415 }
416
Greg Claytond0882d02011-01-19 23:00:49 +0000417 if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
Sean Callanan65dafa82010-08-27 01:01:44 +0000418 {
Sean Callanan65dafa82010-08-27 01:01:44 +0000419 Error materialize_error;
420
Sean Callanan3aa7da52010-12-13 22:46:15 +0000421 if (m_needs_object_ptr)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000422 {
Sean Callanan3aa7da52010-12-13 22:46:15 +0000423 ConstString object_name;
424
425 if (m_cplusplus)
426 {
427 object_name.SetCString("this");
428 }
429 else if (m_objectivec)
430 {
431 object_name.SetCString("self");
432 }
433 else
434 {
435 error_stream.Printf("Need object pointer but don't know the language\n");
436 return false;
437 }
438
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000439 if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, materialize_error)))
Sean Callanan3aa7da52010-12-13 22:46:15 +0000440 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000441 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", materialize_error.AsCString());
442 object_ptr = 0;
Sean Callanan3aa7da52010-12-13 22:46:15 +0000443 }
Sean Callanan047923c2010-12-14 00:42:36 +0000444
445 if (m_objectivec)
446 {
447 ConstString cmd_name("_cmd");
448
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000449 if (!(m_expr_decl_map->GetObjectPointer(cmd_ptr, cmd_name, materialize_error, true)))
Sean Callanan047923c2010-12-14 00:42:36 +0000450 {
Sean Callanan5ed59a72011-12-13 01:42:04 +0000451 error_stream.Printf("warning: couldn't get object pointer (substituting NULL): %s\n", materialize_error.AsCString());
452 cmd_ptr = 0;
Sean Callanan047923c2010-12-14 00:42:36 +0000453 }
454 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000455 }
456
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000457 if (!m_expr_decl_map->Materialize(struct_address, materialize_error))
Sean Callanan65dafa82010-08-27 01:01:44 +0000458 {
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000459 error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
Sean Callanan65dafa82010-08-27 01:01:44 +0000460 return false;
461 }
Greg Claytonc71899e2011-01-18 19:36:39 +0000462
463#if 0
464 // jingham: look here
465 StreamFile logfile ("/tmp/exprs.txt", "a");
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000466 logfile.Printf("0x%16.16" PRIx64 ": thread = 0x%4.4x, expr = '%s'\n", m_jit_start_addr, exe_ctx.thread ? exe_ctx.thread->GetID() : -1, m_expr_text.c_str());
Greg Claytonc71899e2011-01-18 19:36:39 +0000467#endif
Sean Callanan65dafa82010-08-27 01:01:44 +0000468
469 if (log)
470 {
Sean Callanan94d255f2010-12-07 22:55:01 +0000471 log->Printf("-- [ClangUserExpression::PrepareToExecuteJITExpression] Materializing for execution --");
Sean Callanan33711022010-12-07 10:00:20 +0000472
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000473 log->Printf(" Function address : 0x%" PRIx64, (uint64_t)m_jit_start_addr);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000474
475 if (m_needs_object_ptr)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000476 log->Printf(" Object pointer : 0x%" PRIx64, (uint64_t)object_ptr);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000477
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000478 log->Printf(" Structure address : 0x%" PRIx64, (uint64_t)struct_address);
Sean Callanan65dafa82010-08-27 01:01:44 +0000479
480 StreamString args;
481
482 Error dump_error;
483
Sean Callanane8a59a82010-09-13 21:34:21 +0000484 if (struct_address)
Sean Callanan65dafa82010-08-27 01:01:44 +0000485 {
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000486 if (!m_expr_decl_map->DumpMaterializedStruct(args, dump_error))
Sean Callanane8a59a82010-09-13 21:34:21 +0000487 {
Sean Callanan33711022010-12-07 10:00:20 +0000488 log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
Sean Callanane8a59a82010-09-13 21:34:21 +0000489 }
490 else
491 {
Sean Callanan33711022010-12-07 10:00:20 +0000492 log->Printf(" Structure contents:\n%s", args.GetData());
Sean Callanane8a59a82010-09-13 21:34:21 +0000493 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000494 }
495 }
Jim Inghamd1686902010-10-14 23:45:03 +0000496 }
497 return true;
498}
499
500ThreadPlan *
501ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
Sean Callanan6a925532011-01-13 08:53:35 +0000502 ExecutionContext &exe_ctx)
Jim Inghamd1686902010-10-14 23:45:03 +0000503{
504 lldb::addr_t struct_address;
505
Johnny Chen2bc9eb32011-07-19 19:48:13 +0000506 lldb::addr_t object_ptr = 0;
507 lldb::addr_t cmd_ptr = 0;
Jim Inghamd1686902010-10-14 23:45:03 +0000508
Sean Callanan047923c2010-12-14 00:42:36 +0000509 PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
Jim Inghamd1686902010-10-14 23:45:03 +0000510
Jim Ingham360f53f2010-11-30 02:22:11 +0000511 // FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
512 // ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
Sean Callanan3aa7da52010-12-13 22:46:15 +0000513 // forcing unwind_on_error to be true here, in practical terms that can't happen.
514
Jim Inghamd1686902010-10-14 23:45:03 +0000515 return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
Greg Claytond0882d02011-01-19 23:00:49 +0000516 m_jit_start_addr,
Sean Callanana65b5272010-12-01 01:28:23 +0000517 struct_address,
518 error_stream,
519 true,
520 true,
Sean Callanan3aa7da52010-12-13 22:46:15 +0000521 (m_needs_object_ptr ? &object_ptr : NULL),
522 (m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
Jim Inghamd1686902010-10-14 23:45:03 +0000523}
524
525bool
526ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
527 ExecutionContext &exe_ctx,
Sean Callanan0ddf8062011-05-09 22:04:36 +0000528 lldb::ClangExpressionVariableSP &result,
529 lldb::addr_t function_stack_pointer)
Jim Inghamd1686902010-10-14 23:45:03 +0000530{
531 Error expr_error;
532
Sean Callanan33711022010-12-07 10:00:20 +0000533 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
534
535 if (log)
536 {
Sean Callanan94d255f2010-12-07 22:55:01 +0000537 log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
Sean Callanan33711022010-12-07 10:00:20 +0000538
539 StreamString args;
540
541 Error dump_error;
542
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000543 if (!m_expr_decl_map->DumpMaterializedStruct(args, dump_error))
Sean Callanan33711022010-12-07 10:00:20 +0000544 {
545 log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
546 }
547 else
548 {
549 log->Printf(" Structure contents:\n%s", args.GetData());
550 }
551 }
Sean Callanan0ddf8062011-05-09 22:04:36 +0000552
553 lldb::addr_t function_stack_bottom = function_stack_pointer - Host::GetPageSize();
554
Sean Callanan33711022010-12-07 10:00:20 +0000555
Sean Callanandd1dcfd2012-02-10 01:22:05 +0000556 if (!m_expr_decl_map->Dematerialize(result, function_stack_pointer, function_stack_bottom, expr_error))
Jim Inghamd1686902010-10-14 23:45:03 +0000557 {
558 error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
559 return false;
560 }
Sean Callanan6d284ef2011-10-12 22:20:02 +0000561
Johnny Chenc6134962012-01-06 00:35:38 +0000562 if (result)
563 result->TransferAddress();
564
Jim Inghamd1686902010-10-14 23:45:03 +0000565 return true;
566}
567
Greg Claytonb3448432011-03-24 21:19:54 +0000568ExecutionResults
Jim Inghamd1686902010-10-14 23:45:03 +0000569ClangUserExpression::Execute (Stream &error_stream,
570 ExecutionContext &exe_ctx,
Jim Inghamea9d4262010-11-05 19:25:48 +0000571 bool discard_on_error,
Jim Ingham360f53f2010-11-30 02:22:11 +0000572 ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
Enrico Granata6cca9692012-07-16 23:10:35 +0000573 lldb::ClangExpressionVariableSP &result,
Jim Ingham47beabb2012-10-16 21:41:58 +0000574 bool run_others,
575 uint32_t timeout_usec)
Jim Inghamd1686902010-10-14 23:45:03 +0000576{
Jim Ingham7812e012011-01-18 22:20:08 +0000577 // The expression log is quite verbose, and if you're just tracking the execution of the
578 // expression, it's quite convenient to have these logs come out with the STEP log as well.
579 lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanan33711022010-12-07 10:00:20 +0000580
Sean Callanan47dc4572011-09-15 02:13:07 +0000581 if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
Jim Inghamd1686902010-10-14 23:45:03 +0000582 {
Jim Ingham6f01c932012-10-12 17:34:26 +0000583 lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
Jim Inghamd1686902010-10-14 23:45:03 +0000584
Johnny Chen2bc9eb32011-07-19 19:48:13 +0000585 lldb::addr_t object_ptr = 0;
586 lldb::addr_t cmd_ptr = 0;
Jim Inghamd1686902010-10-14 23:45:03 +0000587
Johnny Chen544f2b62012-08-18 04:24:00 +0000588 if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
589 {
Johnny Chen8165d432012-08-18 04:14:54 +0000590 error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
Greg Claytonb3448432011-03-24 21:19:54 +0000591 return eExecutionSetupError;
Johnny Chen8165d432012-08-18 04:14:54 +0000592 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000593
Jim Inghamea9d4262010-11-05 19:25:48 +0000594 const bool stop_others = true;
595 const bool try_all_threads = true;
Sean Callanan65dafa82010-08-27 01:01:44 +0000596
Greg Clayton3508c382012-02-24 01:59:29 +0000597 Address wrapper_address (m_jit_start_addr);
Greg Clayton567e7f32011-09-22 04:58:26 +0000598 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
Sean Callanan3aa7da52010-12-13 22:46:15 +0000599 wrapper_address,
600 struct_address,
601 stop_others,
602 discard_on_error,
603 (m_needs_object_ptr ? &object_ptr : NULL),
604 ((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
605 shared_ptr_to_me));
606
Sean Callananb386d822012-08-09 00:50:26 +0000607 if (!call_plan_sp || !call_plan_sp->ValidatePlan (NULL))
Greg Claytonb3448432011-03-24 21:19:54 +0000608 return eExecutionSetupError;
Sean Callanan0ddf8062011-05-09 22:04:36 +0000609
610 lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
Jim Ingham360f53f2010-11-30 02:22:11 +0000611
Jim Ingham5ab7fba2011-05-17 22:24:54 +0000612 call_plan_sp->SetPrivate(true);
Jim Ingham360f53f2010-11-30 02:22:11 +0000613
Sean Callanan33711022010-12-07 10:00:20 +0000614 if (log)
Sean Callanan94d255f2010-12-07 22:55:01 +0000615 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
Sean Callanan33711022010-12-07 10:00:20 +0000616
Jim Ingham0296fe72011-11-08 03:00:11 +0000617 if (exe_ctx.GetProcessPtr())
618 exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
619
Greg Clayton567e7f32011-09-22 04:58:26 +0000620 ExecutionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
621 call_plan_sp,
622 stop_others,
623 try_all_threads,
624 discard_on_error,
Jim Ingham47beabb2012-10-16 21:41:58 +0000625 timeout_usec,
Greg Clayton567e7f32011-09-22 04:58:26 +0000626 error_stream);
Sean Callanan33711022010-12-07 10:00:20 +0000627
Jim Ingham0296fe72011-11-08 03:00:11 +0000628 if (exe_ctx.GetProcessPtr())
629 exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
630
Sean Callanan33711022010-12-07 10:00:20 +0000631 if (log)
Sean Callanan94d255f2010-12-07 22:55:01 +0000632 log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
Jim Ingham360f53f2010-11-30 02:22:11 +0000633
Greg Claytonb3448432011-03-24 21:19:54 +0000634 if (execution_result == eExecutionInterrupted)
Sean Callanan65dafa82010-08-27 01:01:44 +0000635 {
Jim Ingham2370a972011-05-17 01:10:11 +0000636 const char *error_desc = NULL;
637
638 if (call_plan_sp)
639 {
640 lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
641 if (real_stop_info_sp)
642 error_desc = real_stop_info_sp->GetDescription();
643 }
644 if (error_desc)
645 error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
Jim Ingham360f53f2010-11-30 02:22:11 +0000646 else
Jason Molenda7e5fa7f2011-09-20 21:44:10 +0000647 error_stream.Printf ("Execution was interrupted.");
Jim Ingham2370a972011-05-17 01:10:11 +0000648
649 if (discard_on_error)
650 error_stream.Printf ("\nThe process has been returned to the state before execution.");
651 else
652 error_stream.Printf ("\nThe process has been left at the point where it was interrupted.");
Jim Ingham360f53f2010-11-30 02:22:11 +0000653
654 return execution_result;
655 }
Greg Claytonb3448432011-03-24 21:19:54 +0000656 else if (execution_result != eExecutionCompleted)
Jim Ingham360f53f2010-11-30 02:22:11 +0000657 {
658 error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
659 return execution_result;
Sean Callanan65dafa82010-08-27 01:01:44 +0000660 }
661
Sean Callanan0ddf8062011-05-09 22:04:36 +0000662 if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_pointer))
Greg Claytonb3448432011-03-24 21:19:54 +0000663 return eExecutionCompleted;
Jim Ingham360f53f2010-11-30 02:22:11 +0000664 else
Johnny Chen544f2b62012-08-18 04:24:00 +0000665 {
Johnny Chen8165d432012-08-18 04:14:54 +0000666 error_stream.Printf("Errored out in %s: Couldn't FinalizeJITExpression", __FUNCTION__);
Greg Claytonb3448432011-03-24 21:19:54 +0000667 return eExecutionSetupError;
Johnny Chen544f2b62012-08-18 04:24:00 +0000668 }
Sean Callanan65dafa82010-08-27 01:01:44 +0000669 }
670 else
671 {
Sean Callanan47dc4572011-09-15 02:13:07 +0000672 error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
Greg Claytonb3448432011-03-24 21:19:54 +0000673 return eExecutionSetupError;
Sean Callanan65dafa82010-08-27 01:01:44 +0000674 }
675}
676
Greg Claytonb3448432011-03-24 21:19:54 +0000677ExecutionResults
Sean Callanan47dc4572011-09-15 02:13:07 +0000678ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
679 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan5b658cc2011-11-07 23:35:40 +0000680 lldb::LanguageType language,
Sean Callanandaa6efe2011-12-21 22:22:58 +0000681 ResultType desired_type,
Jim Inghamea9d4262010-11-05 19:25:48 +0000682 bool discard_on_error,
Sean Callanan77e93942010-10-29 00:29:03 +0000683 const char *expr_cstr,
Jim Ingham360f53f2010-11-30 02:22:11 +0000684 const char *expr_prefix,
Enrico Granata6cca9692012-07-16 23:10:35 +0000685 lldb::ValueObjectSP &result_valobj_sp,
Jim Ingham47beabb2012-10-16 21:41:58 +0000686 bool run_others,
687 uint32_t timeout_usec)
Greg Clayton377e0b42010-10-05 00:31:29 +0000688{
Jim Inghamec07c0d2011-08-09 00:00:49 +0000689 Error error;
Jim Ingham47beabb2012-10-16 21:41:58 +0000690 return EvaluateWithError (exe_ctx,
691 execution_policy,
692 language,
693 desired_type,
694 discard_on_error,
695 expr_cstr,
696 expr_prefix,
697 result_valobj_sp,
698 error,
699 run_others,
700 timeout_usec);
Jim Inghamec07c0d2011-08-09 00:00:49 +0000701}
702
703ExecutionResults
Sean Callanan47dc4572011-09-15 02:13:07 +0000704ClangUserExpression::EvaluateWithError (ExecutionContext &exe_ctx,
705 lldb_private::ExecutionPolicy execution_policy,
Sean Callanan5b658cc2011-11-07 23:35:40 +0000706 lldb::LanguageType language,
Sean Callanandaa6efe2011-12-21 22:22:58 +0000707 ResultType desired_type,
Sean Callanan47dc4572011-09-15 02:13:07 +0000708 bool discard_on_error,
709 const char *expr_cstr,
710 const char *expr_prefix,
711 lldb::ValueObjectSP &result_valobj_sp,
Enrico Granata6cca9692012-07-16 23:10:35 +0000712 Error &error,
Jim Ingham47beabb2012-10-16 21:41:58 +0000713 bool run_others,
714 uint32_t timeout_usec)
Jim Inghamec07c0d2011-08-09 00:00:49 +0000715{
Jim Ingham7812e012011-01-18 22:20:08 +0000716 lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
Sean Callanan94d255f2010-12-07 22:55:01 +0000717
Greg Claytonb3448432011-03-24 21:19:54 +0000718 ExecutionResults execution_results = eExecutionSetupError;
Greg Clayton0baa3942010-11-04 01:54:29 +0000719
Greg Clayton567e7f32011-09-22 04:58:26 +0000720 Process *process = exe_ctx.GetProcessPtr();
721
722 if (process == NULL || process->GetState() != lldb::eStateStopped)
Jim Ingham360f53f2010-11-30 02:22:11 +0000723 {
Sean Callanan47dc4572011-09-15 02:13:07 +0000724 if (execution_policy == eExecutionPolicyAlways)
725 {
726 if (log)
727 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
Jim Ingham360f53f2010-11-30 02:22:11 +0000728
Sean Callanan47dc4572011-09-15 02:13:07 +0000729 error.SetErrorString ("expression needed to run but couldn't");
730
731 return execution_results;
732 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000733 }
Sean Callananf7649bb2011-09-15 17:43:00 +0000734
Greg Clayton567e7f32011-09-22 04:58:26 +0000735 if (process == NULL || !process->CanJIT())
Sean Callananf7649bb2011-09-15 17:43:00 +0000736 execution_policy = eExecutionPolicyNever;
Greg Clayton0baa3942010-11-04 01:54:29 +0000737
Sean Callanandaa6efe2011-12-21 22:22:58 +0000738 ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix, language, desired_type));
Jim Ingham360f53f2010-11-30 02:22:11 +0000739
Greg Clayton377e0b42010-10-05 00:31:29 +0000740 StreamString error_stream;
Sean Callanan696cf5f2011-05-07 01:06:41 +0000741
Sean Callanan94d255f2010-12-07 22:55:01 +0000742 if (log)
743 log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
744
Sean Callanan47dc4572011-09-15 02:13:07 +0000745 const bool keep_expression_in_memory = true;
746
Sean Callanandaa6efe2011-12-21 22:22:58 +0000747 if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
Greg Clayton377e0b42010-10-05 00:31:29 +0000748 {
749 if (error_stream.GetString().empty())
750 error.SetErrorString ("expression failed to parse, unknown error");
751 else
752 error.SetErrorString (error_stream.GetString().c_str());
753 }
754 else
755 {
Greg Clayton427f2902010-12-14 02:59:59 +0000756 lldb::ClangExpressionVariableSP expr_result;
Greg Clayton377e0b42010-10-05 00:31:29 +0000757
Sean Callanan47dc4572011-09-15 02:13:07 +0000758 if (user_expression_sp->EvaluatedStatically())
Greg Clayton377e0b42010-10-05 00:31:29 +0000759 {
Sean Callanan94d255f2010-12-07 22:55:01 +0000760 if (log)
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000761 log->Printf("== [ClangUserExpression::Evaluate] Expression evaluated as a constant ==");
Sean Callanan94d255f2010-12-07 22:55:01 +0000762
Sean Callanan47dc4572011-09-15 02:13:07 +0000763 if (user_expression_sp->m_const_result)
764 result_valobj_sp = user_expression_sp->m_const_result->GetValueObject();
765 else
766 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
767
Jim Inghamec07c0d2011-08-09 00:00:49 +0000768 execution_results = eExecutionCompleted;
Greg Clayton377e0b42010-10-05 00:31:29 +0000769 }
Sean Callanan47dc4572011-09-15 02:13:07 +0000770 else if (execution_policy == eExecutionPolicyNever)
771 {
772 if (log)
773 log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
774
775 if (error_stream.GetString().empty())
776 error.SetErrorString ("expression needed to run but couldn't");
777 }
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000778 else
779 {
780 error_stream.GetString().clear();
781
782 if (log)
783 log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
784
785 execution_results = user_expression_sp->Execute (error_stream,
786 exe_ctx,
Sean Callanan6a925532011-01-13 08:53:35 +0000787 discard_on_error,
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000788 user_expression_sp,
Enrico Granata6cca9692012-07-16 23:10:35 +0000789 expr_result,
Jim Ingham47beabb2012-10-16 21:41:58 +0000790 run_others,
791 timeout_usec);
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000792
Greg Claytonb3448432011-03-24 21:19:54 +0000793 if (execution_results != eExecutionCompleted)
Greg Clayton377e0b42010-10-05 00:31:29 +0000794 {
Sean Callanan94d255f2010-12-07 22:55:01 +0000795 if (log)
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000796 log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
797
798 if (error_stream.GetString().empty())
799 error.SetErrorString ("expression failed to execute, unknown error");
800 else
801 error.SetErrorString (error_stream.GetString().c_str());
Greg Clayton377e0b42010-10-05 00:31:29 +0000802 }
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000803 else
Greg Clayton377e0b42010-10-05 00:31:29 +0000804 {
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000805 if (expr_result)
806 {
807 result_valobj_sp = expr_result->GetValueObject();
808
809 if (log)
Jim Inghamfa3a16a2011-03-31 00:19:25 +0000810 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000811 }
812 else
813 {
814 if (log)
815 log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
816
Sean Callanan24312442011-08-23 21:20:51 +0000817 error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
Sean Callanan05a5a1b2010-12-16 03:17:46 +0000818 }
Greg Clayton377e0b42010-10-05 00:31:29 +0000819 }
820 }
821 }
Sean Callanan44820ec2010-10-19 20:15:00 +0000822
Greg Claytond1719722010-10-05 03:13:51 +0000823 if (result_valobj_sp.get() == NULL)
Jim Ingham47da8102011-04-22 23:53:53 +0000824 result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
Greg Claytond1719722010-10-05 03:13:51 +0000825
Jim Ingham360f53f2010-11-30 02:22:11 +0000826 return execution_results;
Johnny Chenb4c0f022010-10-29 20:19:44 +0000827}