blob: b78d5a2e45dbfbe7caa383d70d8263facbdb6a8f [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
Sean Callanan4dbb2712015-09-25 20:35:58 +000019#include "ClangUserExpression.h"
20
21#include "ASTResultSynthesizer.h"
22#include "ClangExpressionDeclMap.h"
23#include "ClangExpressionParser.h"
24#include "ClangModulesDeclVendor.h"
25#include "ClangPersistentVariables.h"
26
Sean Callanan1a8d4092010-08-27 01:01:44 +000027#include "lldb/Core/ConstString.h"
28#include "lldb/Core/Log.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000029#include "lldb/Core/Module.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000030#include "lldb/Core/StreamFile.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000031#include "lldb/Core/StreamString.h"
Greg Claytonb71f3842010-10-05 03:13:51 +000032#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan9bc83842011-09-26 18:45:31 +000033#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanan14b1bae2013-04-16 23:25:35 +000034#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan1582ee62013-04-18 22:06:33 +000035#include "lldb/Expression/IRInterpreter.h"
Sean Callanan96d27302013-04-11 00:09:05 +000036#include "lldb/Expression/Materializer.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000037#include "lldb/Host/HostInfo.h"
Greg Clayton1f746072012-08-29 21:13:06 +000038#include "lldb/Symbol/Block.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000039#include "lldb/Symbol/ClangASTContext.h"
40#include "lldb/Symbol/Function.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000041#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolVendor.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000043#include "lldb/Symbol/Type.h"
44#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Sean Callananfc55f5d2010-09-21 00:44:12 +000045#include "lldb/Symbol/VariableList.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000046#include "lldb/Target/ExecutionContext.h"
Greg Clayton8f343b02010-11-04 01:54:29 +000047#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000048#include "lldb/Target/StackFrame.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000049#include "lldb/Target/Target.h"
Jim Inghamf48169b2010-11-30 02:22:11 +000050#include "lldb/Target/ThreadPlan.h"
51#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000052
Sean Callanan72e49402011-08-05 23:43:37 +000053#include "clang/AST/DeclCXX.h"
54#include "clang/AST/DeclObjC.h"
55
Sean Callanan1a8d4092010-08-27 01:01:44 +000056using namespace lldb_private;
57
Jim Ingham19a63fc2015-11-03 02:11:24 +000058ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope,
59 const char *expr,
60 const char *expr_prefix,
61 lldb::LanguageType language,
62 ResultType desired_type,
63 const EvaluateExpressionOptions &options) :
64 LLVMUserExpression (exe_scope, expr, expr_prefix, language, desired_type, options),
65 m_type_system_helper(*m_target_wp.lock().get())
Sean Callanan1a8d4092010-08-27 01:01:44 +000066{
Sean Callananc7b65062011-11-07 23:35:40 +000067 switch (m_language)
68 {
69 case lldb::eLanguageTypeC_plus_plus:
70 m_allow_cxx = true;
71 break;
72 case lldb::eLanguageTypeObjC:
73 m_allow_objc = true;
74 break;
75 case lldb::eLanguageTypeObjC_plus_plus:
76 default:
77 m_allow_cxx = true;
78 m_allow_objc = true;
79 break;
80 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000081}
82
Sean Callanane71d5532010-08-27 23:31:21 +000083ClangUserExpression::~ClangUserExpression ()
84{
Sean Callanan1a8d4092010-08-27 01:01:44 +000085}
86
Sean Callananfc55f5d2010-09-21 00:44:12 +000087void
Sean Callanan744756e2011-11-04 02:09:33 +000088ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +000089{
Greg Clayton5160ce52013-03-27 23:08:40 +000090 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +000091
92 if (log)
93 log->Printf("ClangUserExpression::ScanContext()");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000094
Greg Claytonc14ee322011-09-22 04:58:26 +000095 m_target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000096
Sean Callananc7b65062011-11-07 23:35:40 +000097 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +000098 {
99 if (log)
100 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +0000101 return;
Sean Callanan70385082012-12-01 00:08:33 +0000102 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000103
Jason Molendab57e4a12013-11-04 09:33:30 +0000104 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000105 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000106 {
107 if (log)
108 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000109 return;
Sean Callanan70385082012-12-01 00:08:33 +0000110 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000111
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000112 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000113
Sean Callanan72e49402011-08-05 23:43:37 +0000114 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000115 {
116 if (log)
117 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000118 return;
Sean Callanan70385082012-12-01 00:08:33 +0000119 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000120
Greg Clayton685c88c2012-07-14 00:53:55 +0000121 // Find the block that defines the function represented by "sym_ctx"
122 Block *function_block = sym_ctx.GetFunctionBlock();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000123
Greg Clayton685c88c2012-07-14 00:53:55 +0000124 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000125 {
126 if (log)
127 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000128 return;
Sean Callanan70385082012-12-01 00:08:33 +0000129 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000130
Greg Clayton99558cc42015-08-24 23:46:31 +0000131 CompilerDeclContext decl_context = function_block->GetDeclContext();
Greg Clayton685c88c2012-07-14 00:53:55 +0000132
Sean Callanan72e49402011-08-05 23:43:37 +0000133 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000134 {
135 if (log)
136 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000137 return;
Sean Callanan70385082012-12-01 00:08:33 +0000138 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000139
Greg Clayton99558cc42015-08-24 23:46:31 +0000140 if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000141 {
Sean Callananc7b65062011-11-07 23:35:40 +0000142 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000143 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000144 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000145 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000146 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000147
Sean Callanand5cc1322011-12-13 01:42:04 +0000148 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 +0000149
Greg Clayton685c88c2012-07-14 00:53:55 +0000150 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000151 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000152 err.SetErrorString(thisErrorString);
153 return;
154 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000155
Greg Clayton685c88c2012-07-14 00:53:55 +0000156 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000157
Greg Clayton685c88c2012-07-14 00:53:55 +0000158 if (!this_var_sp ||
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000159 !this_var_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000160 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000161 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000162 err.SetErrorString(thisErrorString);
163 return;
164 }
Sean Callanan744756e2011-11-04 02:09:33 +0000165 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000166
Dawn Perchik53f34c82015-07-01 00:54:02 +0000167 m_in_cplusplus_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000168 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000169 }
170 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000171 else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context))
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000172 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000173 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +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 *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 +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(selfErrorString);
184 return;
185 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000186
Greg Clayton685c88c2012-07-14 00:53:55 +0000187 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000188
189 if (!self_variable_sp ||
190 !self_variable_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000191 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000192 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000193 err.SetErrorString(selfErrorString);
194 return;
195 }
Sean Callanan744756e2011-11-04 02:09:33 +0000196 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000197
Dawn Perchik53f34c82015-07-01 00:54:02 +0000198 m_in_objectivec_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000199 m_needs_object_ptr = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000200
Sean Callanand5c17ed2011-11-15 02:11:17 +0000201 if (!method_decl->isInstanceMethod())
Dawn Perchik53f34c82015-07-01 00:54:02 +0000202 m_in_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000203 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000204 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000205 else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
Jim Ingham5fdeed42012-10-30 23:35:54 +0000206 {
207 // We might also have a function that said in the debug information that it captured an
Dawn Perchik508f0402015-07-01 17:41:02 +0000208 // object pointer. The best way to deal with getting to the ivars at present is by pretending
Jim Ingham5fdeed42012-10-30 23:35:54 +0000209 // that this is a method of a class in whatever runtime the debug info says the object pointer
210 // belongs to. Do that here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000211
Greg Clayton99558cc42015-08-24 23:46:31 +0000212 ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000213 if (metadata && metadata->HasObjectPtr())
214 {
215 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
216 if (language == lldb::eLanguageTypeC_plus_plus)
217 {
Sean Callanana2868d42013-01-19 01:49:02 +0000218 if (m_enforce_valid_object)
219 {
220 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000221
Sean Callanana2868d42013-01-19 01:49:02 +0000222 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 +0000223
Sean Callanana2868d42013-01-19 01:49:02 +0000224 if (!variable_list_sp)
225 {
226 err.SetErrorString(thisErrorString);
227 return;
228 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000229
Sean Callanana2868d42013-01-19 01:49:02 +0000230 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000231
Sean Callanana2868d42013-01-19 01:49:02 +0000232 if (!this_var_sp ||
233 !this_var_sp->IsInScope(frame) ||
234 !this_var_sp->LocationIsValidForFrame (frame))
235 {
236 err.SetErrorString(thisErrorString);
237 return;
238 }
239 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000240
Dawn Perchik53f34c82015-07-01 00:54:02 +0000241 m_in_cplusplus_method = true;
Jim Ingham5fdeed42012-10-30 23:35:54 +0000242 m_needs_object_ptr = true;
243 }
244 else if (language == lldb::eLanguageTypeObjC)
245 {
Sean Callanana2868d42013-01-19 01:49:02 +0000246 if (m_enforce_valid_object)
247 {
248 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000249
Sean Callanana2868d42013-01-19 01:49:02 +0000250 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 +0000251
Sean Callanana2868d42013-01-19 01:49:02 +0000252 if (!variable_list_sp)
253 {
254 err.SetErrorString(selfErrorString);
255 return;
256 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000257
Sean Callanana2868d42013-01-19 01:49:02 +0000258 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000259
Sean Callanana2868d42013-01-19 01:49:02 +0000260 if (!self_variable_sp ||
261 !self_variable_sp->IsInScope(frame) ||
262 !self_variable_sp->LocationIsValidForFrame (frame))
263 {
264 err.SetErrorString(selfErrorString);
265 return;
266 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000267
Sean Callanana2868d42013-01-19 01:49:02 +0000268 Type *self_type = self_variable_sp->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000269
Sean Callanana2868d42013-01-19 01:49:02 +0000270 if (!self_type)
271 {
272 err.SetErrorString(selfErrorString);
273 return;
274 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000275
Greg Clayton99558cc42015-08-24 23:46:31 +0000276 CompilerType self_clang_type = self_type->GetForwardCompilerType ();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000277
Greg Clayton57ee3062013-07-11 22:46:58 +0000278 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000279 {
280 err.SetErrorString(selfErrorString);
281 return;
282 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000283
Greg Claytond8d4a572015-08-11 21:38:15 +0000284 if (ClangASTContext::IsObjCClassType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000285 {
286 return;
287 }
Greg Claytond8d4a572015-08-11 21:38:15 +0000288 else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000289 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000290 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000291 m_needs_object_ptr = true;
292 }
293 else
294 {
295 err.SetErrorString(selfErrorString);
296 return;
297 }
298 }
299 else
300 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000301 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000302 m_needs_object_ptr = true;
303 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000304 }
305 }
306 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000307}
308
Sean Callanancf5498f2010-10-22 23:25:16 +0000309// This is a really nasty hack, meant to fix Objective-C expressions of the form
310// (int)[myArray count]. Right now, because the type information for count is
311// not available, [myArray count] returns id, which can't be directly cast to
312// int without causing a clang error.
313static void
314ApplyObjcCastHack(std::string &expr)
315{
316#define OBJC_CAST_HACK_FROM "(int)["
317#define OBJC_CAST_HACK_TO "(int)(long long)["
318
319 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000320
Sean Callanancf5498f2010-10-22 23:25:16 +0000321 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
322 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
323
324#undef OBJC_CAST_HACK_TO
325#undef OBJC_CAST_HACK_FROM
326}
327
328bool
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000329ClangUserExpression::Parse (Stream &error_stream,
Sean Callananf7c3e272010-11-19 02:52:21 +0000330 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000331 lldb_private::ExecutionPolicy execution_policy,
Greg Clayton23f8c952014-03-24 23:10:19 +0000332 bool keep_result_in_memory,
333 bool generate_debug_info)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000334{
Greg Clayton5160ce52013-03-27 23:08:40 +0000335 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000336
Sean Callanan744756e2011-11-04 02:09:33 +0000337 Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000338
Sean Callanan933693b2012-02-10 01:22:05 +0000339 InstallContext(exe_ctx);
Sean Callanan9fda9d22015-10-03 09:09:01 +0000340
341 if (Target *target = exe_ctx.GetTargetPtr())
342 {
343 if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
344 {
345 m_result_delegate.RegisterPersistentState(persistent_state);
346 }
347 else
348 {
349 error_stream.PutCString ("error: couldn't start parsing (no persistent data)");
350 return false;
351 }
352 }
353 else
354 {
355 error_stream.PutCString ("error: couldn't start parsing (no target)");
356 return false;
357 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000358
Sean Callanan744756e2011-11-04 02:09:33 +0000359 ScanContext(exe_ctx, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000360
Sean Callanan744756e2011-11-04 02:09:33 +0000361 if (!err.Success())
362 {
363 error_stream.Printf("warning: %s\n", err.AsCString());
364 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000365
Sean Callananfc55f5d2010-09-21 00:44:12 +0000366 StreamString m_transformed_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000367
Sean Callananfc55f5d2010-09-21 00:44:12 +0000368 ////////////////////////////////////
369 // Generate the expression
370 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000371
Sean Callanancf5498f2010-10-22 23:25:16 +0000372 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000373 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000374
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000375 std::string prefix = m_expr_prefix;
376
377 if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
378 {
Sean Callananb92bd752015-10-01 16:28:02 +0000379 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000380 ClangModulesDeclVendor::ModuleVector modules_for_macros;
381
382 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
383 {
384 modules_for_macros.push_back(module);
385 }
386
387 if (m_target->GetEnableAutoImportClangModules())
388 {
389 if (StackFrame *frame = exe_ctx.GetFramePtr())
390 {
391 if (Block *block = frame->GetFrameBlock())
392 {
393 SymbolContext sc;
394
395 block->CalculateSymbolContext(&sc);
396
397 if (sc.comp_unit)
398 {
399 StreamString error_stream;
400
401 decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
402 }
403 }
404 }
405 }
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000406 }
407
408 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
409
Sean Callanan9bc83842011-09-26 18:45:31 +0000410 lldb::LanguageType lang_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000411
Dawn Perchik53f34c82015-07-01 00:54:02 +0000412 if (m_in_cplusplus_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000413 lang_type = lldb::eLanguageTypeC_plus_plus;
Dawn Perchik53f34c82015-07-01 00:54:02 +0000414 else if (m_in_objectivec_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000415 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000416 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000417 lang_type = lldb::eLanguageTypeC;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000418
Dawn Perchik53f34c82015-07-01 00:54:02 +0000419 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx))
Sean Callananfc55f5d2010-09-21 00:44:12 +0000420 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000421 error_stream.PutCString ("error: couldn't construct expression body");
422 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000423 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000424
Sean Callananfc55f5d2010-09-21 00:44:12 +0000425 if (log)
426 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000427
Sean Callanan1a8d4092010-08-27 01:01:44 +0000428 ////////////////////////////////////
429 // Set up the target and compiler
430 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000431
Greg Claytonc14ee322011-09-22 04:58:26 +0000432 Target *target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000433
Sean Callanan1a8d4092010-08-27 01:01:44 +0000434 if (!target)
435 {
436 error_stream.PutCString ("error: invalid target\n");
437 return false;
438 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000439
Sean Callanan1a8d4092010-08-27 01:01:44 +0000440 //////////////////////////
441 // Parse the expression
442 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000443
Sean Callanan96d27302013-04-11 00:09:05 +0000444 m_materializer_ap.reset(new Materializer());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000445
Sean Callanan9fda9d22015-10-03 09:09:01 +0000446 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000447
Greg Clayton57ee3062013-07-11 22:46:58 +0000448 class OnExit
449 {
450 public:
451 typedef std::function <void (void)> Callback;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000452
Greg Clayton57ee3062013-07-11 22:46:58 +0000453 OnExit (Callback const &callback) :
454 m_callback(callback)
455 {
456 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000457
Greg Clayton57ee3062013-07-11 22:46:58 +0000458 ~OnExit ()
459 {
460 m_callback();
461 }
462 private:
463 Callback m_callback;
464 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000465
Jim Ingham151c0322015-09-15 21:13:50 +0000466 OnExit on_exit([this]() { ResetDeclMap(); });
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000467
Jim Ingham151c0322015-09-15 21:13:50 +0000468 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000469 {
470 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000471
Jim Ingham151c0322015-09-15 21:13:50 +0000472 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000473
Sean Callananb9951192011-08-01 18:18:33 +0000474 return false;
475 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000476
Greg Claytonc14ee322011-09-22 04:58:26 +0000477 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000478 ExecutionContextScope *exe_scope = process;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000479
Sean Callananaa719af2012-02-08 18:43:35 +0000480 if (!exe_scope)
481 exe_scope = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000482
Todd Fiala2c77a422014-10-10 01:11:39 +0000483 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000484
Sean Callanan1a8d4092010-08-27 01:01:44 +0000485 unsigned num_errors = parser.Parse (error_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000486
Sean Callanan1a8d4092010-08-27 01:01:44 +0000487 if (num_errors)
488 {
489 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000490
Jim Ingham151c0322015-09-15 21:13:50 +0000491 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000492
Sean Callanan1a8d4092010-08-27 01:01:44 +0000493 return false;
494 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000495
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000496 //////////////////////////////////////////////////////////////////////////////////////////
497 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000498 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000499
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000500 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000501 m_jit_end_addr,
Greg Clayton23f8c952014-03-24 23:10:19 +0000502 m_execution_unit_sp,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000503 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000504 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000505 execution_policy);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000506
Greg Clayton23f8c952014-03-24 23:10:19 +0000507 if (generate_debug_info)
508 {
509 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000510
Greg Clayton23f8c952014-03-24 23:10:19 +0000511 if (jit_module_sp)
512 {
513 ConstString const_func_name(FunctionName());
514 FileSpec jit_file;
515 jit_file.GetFilename() = const_func_name;
516 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
517 m_jit_module_wp = jit_module_sp;
518 target->GetImages().Append(jit_module_sp);
519 }
520// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
521// StreamFile strm (stdout, false);
522// if (jit_obj_file)
523// {
524// jit_obj_file->GetSectionList();
525// jit_obj_file->GetSymtab();
526// jit_obj_file->Dump(&strm);
527// }
528// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
529// if (jit_sym_vendor)
530// {
531// lldb_private::SymbolContextList sc_list;
532// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
533// sc_list.Dump(&strm, target);
534// jit_sym_vendor->Dump(&strm);
535// }
536 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000537
Jim Ingham151c0322015-09-15 21:13:50 +0000538 ResetDeclMap(); // 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 +0000539
Sean Callanan1a8d4092010-08-27 01:01:44 +0000540 if (jit_error.Success())
541 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000542 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000543 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000544 return true;
545 }
546 else
547 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000548 const char *error_cstr = jit_error.AsCString();
549 if (error_cstr && error_cstr[0])
550 error_stream.Printf ("error: %s\n", error_cstr);
551 else
Jason Molendafd54b362011-09-20 21:44:10 +0000552 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000553 return false;
554 }
555}
556
557bool
Jim Ingham151c0322015-09-15 21:13:50 +0000558ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx,
559 std::vector<lldb::addr_t> &args,
560 Stream &error_stream)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000561{
Jim Ingham151c0322015-09-15 21:13:50 +0000562 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
563 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
564
565 if (m_needs_object_ptr)
Sean Callanan933693b2012-02-10 01:22:05 +0000566 {
Jim Ingham151c0322015-09-15 21:13:50 +0000567 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
568 if (!frame_sp)
569 return true;
570
571 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000572
Jim Ingham151c0322015-09-15 21:13:50 +0000573 if (m_in_cplusplus_method)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000574 {
Jim Ingham151c0322015-09-15 21:13:50 +0000575 object_name.SetCString("this");
576 }
577 else if (m_in_objectivec_method)
578 {
579 object_name.SetCString("self");
580 }
581 else
582 {
583 error_stream.Printf("Need object pointer but don't know the language\n");
584 return false;
585 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000586
Jim Ingham151c0322015-09-15 21:13:50 +0000587 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000588
Jim Ingham151c0322015-09-15 21:13:50 +0000589 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000590
Jim Ingham151c0322015-09-15 21:13:50 +0000591 if (!object_ptr_error.Success())
592 {
593 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
594 object_ptr = 0;
595 }
596
597 if (m_in_objectivec_method)
598 {
599 ConstString cmd_name("_cmd");
600
601 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000602
Sean Callanan1582ee62013-04-18 22:06:33 +0000603 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000604 {
Jim Ingham151c0322015-09-15 21:13:50 +0000605 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
606 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000607 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000608 }
Jim Ingham151c0322015-09-15 21:13:50 +0000609 if (object_ptr)
610 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000611
Jim Ingham151c0322015-09-15 21:13:50 +0000612 if (m_in_objectivec_method)
613 args.push_back(cmd_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000614
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000615
Jim Ingham36f3b362010-10-14 23:45:03 +0000616 }
617 return true;
618}
619
Sean Callanan9fda9d22015-10-03 09:09:01 +0000620lldb::ExpressionVariableSP
621ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
Jim Ingham36f3b362010-10-14 23:45:03 +0000622{
Sean Callanan9fda9d22015-10-03 09:09:01 +0000623 return m_result_delegate.GetVariable();
624}
625
626void
627ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
628{
629 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000630}
Jim Ingham36f3b362010-10-14 23:45:03 +0000631
Jim Ingham151c0322015-09-15 21:13:50 +0000632clang::ASTConsumer *
633ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
Jim Ingham36f3b362010-10-14 23:45:03 +0000634{
Jim Ingham151c0322015-09-15 21:13:50 +0000635 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
636 m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000637
Jim Ingham151c0322015-09-15 21:13:50 +0000638 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000639}
640
Sean Callanan9fda9d22015-10-03 09:09:01 +0000641ClangUserExpression::ResultDelegate::ResultDelegate()
642{
643}
644
645ConstString
646ClangUserExpression::ResultDelegate::GetName()
647{
648 return m_persistent_state->GetNextPersistentVariableName();
649}
650
651void
652ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
653{
654 m_variable = variable;
655}
656
657void
658ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
659{
660 m_persistent_state = persistent_state;
661}
662
663lldb::ExpressionVariableSP &
664ClangUserExpression::ResultDelegate::GetVariable()
665{
666 return m_variable;
667}
668