blob: 22b091318550f14e7c6d7c1127ac70955cd17621 [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 Ingham151c0322015-09-15 21:13:50 +000058ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope,
59 const char *expr,
Sean Callananc7b65062011-11-07 23:35:40 +000060 const char *expr_prefix,
Sean Callanan20bb3aa2011-12-21 22:22:58 +000061 lldb::LanguageType language,
62 ResultType desired_type) :
Jim Ingham151c0322015-09-15 21:13:50 +000063 UserExpression (exe_scope, expr, expr_prefix, language, desired_type),
64 m_type_system_helper(*m_target_wp.lock().get())
Sean Callanan1a8d4092010-08-27 01:01:44 +000065{
Sean Callananc7b65062011-11-07 23:35:40 +000066 switch (m_language)
67 {
68 case lldb::eLanguageTypeC_plus_plus:
69 m_allow_cxx = true;
70 break;
71 case lldb::eLanguageTypeObjC:
72 m_allow_objc = true;
73 break;
74 case lldb::eLanguageTypeObjC_plus_plus:
75 default:
76 m_allow_cxx = true;
77 m_allow_objc = true;
78 break;
79 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000080}
81
Sean Callanane71d5532010-08-27 23:31:21 +000082ClangUserExpression::~ClangUserExpression ()
83{
Sean Callanan1a8d4092010-08-27 01:01:44 +000084}
85
Sean Callananfc55f5d2010-09-21 00:44:12 +000086void
Sean Callanan744756e2011-11-04 02:09:33 +000087ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +000088{
Greg Clayton5160ce52013-03-27 23:08:40 +000089 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +000090
91 if (log)
92 log->Printf("ClangUserExpression::ScanContext()");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000093
Greg Claytonc14ee322011-09-22 04:58:26 +000094 m_target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000095
Sean Callananc7b65062011-11-07 23:35:40 +000096 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +000097 {
98 if (log)
99 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +0000100 return;
Sean Callanan70385082012-12-01 00:08:33 +0000101 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000102
Jason Molendab57e4a12013-11-04 09:33:30 +0000103 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000104 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000105 {
106 if (log)
107 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000108 return;
Sean Callanan70385082012-12-01 00:08:33 +0000109 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000110
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000111 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000112
Sean Callanan72e49402011-08-05 23:43:37 +0000113 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000114 {
115 if (log)
116 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000117 return;
Sean Callanan70385082012-12-01 00:08:33 +0000118 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000119
Greg Clayton685c88c2012-07-14 00:53:55 +0000120 // Find the block that defines the function represented by "sym_ctx"
121 Block *function_block = sym_ctx.GetFunctionBlock();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000122
Greg Clayton685c88c2012-07-14 00:53:55 +0000123 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000124 {
125 if (log)
126 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000127 return;
Sean Callanan70385082012-12-01 00:08:33 +0000128 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000129
Greg Clayton99558cc42015-08-24 23:46:31 +0000130 CompilerDeclContext decl_context = function_block->GetDeclContext();
Greg Clayton685c88c2012-07-14 00:53:55 +0000131
Sean Callanan72e49402011-08-05 23:43:37 +0000132 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000133 {
134 if (log)
135 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000136 return;
Sean Callanan70385082012-12-01 00:08:33 +0000137 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000138
Greg Clayton99558cc42015-08-24 23:46:31 +0000139 if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000140 {
Sean Callananc7b65062011-11-07 23:35:40 +0000141 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000142 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000143 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000144 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000145 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000146
Sean Callanand5cc1322011-12-13 01:42:04 +0000147 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 +0000148
Greg Clayton685c88c2012-07-14 00:53:55 +0000149 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000150 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000151 err.SetErrorString(thisErrorString);
152 return;
153 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000154
Greg Clayton685c88c2012-07-14 00:53:55 +0000155 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000156
Greg Clayton685c88c2012-07-14 00:53:55 +0000157 if (!this_var_sp ||
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000158 !this_var_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000159 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000160 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000161 err.SetErrorString(thisErrorString);
162 return;
163 }
Sean Callanan744756e2011-11-04 02:09:33 +0000164 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000165
Dawn Perchik53f34c82015-07-01 00:54:02 +0000166 m_in_cplusplus_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000167 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000168 }
169 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000170 else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context))
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000171 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000172 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000173 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000174 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000175 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000176 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000177
Sean Callanand5cc1322011-12-13 01:42:04 +0000178 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 +0000179
Greg Clayton685c88c2012-07-14 00:53:55 +0000180 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000181 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000182 err.SetErrorString(selfErrorString);
183 return;
184 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000185
Greg Clayton685c88c2012-07-14 00:53:55 +0000186 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000187
188 if (!self_variable_sp ||
189 !self_variable_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000190 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000191 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000192 err.SetErrorString(selfErrorString);
193 return;
194 }
Sean Callanan744756e2011-11-04 02:09:33 +0000195 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000196
Dawn Perchik53f34c82015-07-01 00:54:02 +0000197 m_in_objectivec_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000198 m_needs_object_ptr = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000199
Sean Callanand5c17ed2011-11-15 02:11:17 +0000200 if (!method_decl->isInstanceMethod())
Dawn Perchik53f34c82015-07-01 00:54:02 +0000201 m_in_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000202 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000203 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000204 else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
Jim Ingham5fdeed42012-10-30 23:35:54 +0000205 {
206 // We might also have a function that said in the debug information that it captured an
Dawn Perchik508f0402015-07-01 17:41:02 +0000207 // object pointer. The best way to deal with getting to the ivars at present is by pretending
Jim Ingham5fdeed42012-10-30 23:35:54 +0000208 // that this is a method of a class in whatever runtime the debug info says the object pointer
209 // belongs to. Do that here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000210
Greg Clayton99558cc42015-08-24 23:46:31 +0000211 ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000212 if (metadata && metadata->HasObjectPtr())
213 {
214 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
215 if (language == lldb::eLanguageTypeC_plus_plus)
216 {
Sean Callanana2868d42013-01-19 01:49:02 +0000217 if (m_enforce_valid_object)
218 {
219 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000220
Sean Callanana2868d42013-01-19 01:49:02 +0000221 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 +0000222
Sean Callanana2868d42013-01-19 01:49:02 +0000223 if (!variable_list_sp)
224 {
225 err.SetErrorString(thisErrorString);
226 return;
227 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000228
Sean Callanana2868d42013-01-19 01:49:02 +0000229 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000230
Sean Callanana2868d42013-01-19 01:49:02 +0000231 if (!this_var_sp ||
232 !this_var_sp->IsInScope(frame) ||
233 !this_var_sp->LocationIsValidForFrame (frame))
234 {
235 err.SetErrorString(thisErrorString);
236 return;
237 }
238 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000239
Dawn Perchik53f34c82015-07-01 00:54:02 +0000240 m_in_cplusplus_method = true;
Jim Ingham5fdeed42012-10-30 23:35:54 +0000241 m_needs_object_ptr = true;
242 }
243 else if (language == lldb::eLanguageTypeObjC)
244 {
Sean Callanana2868d42013-01-19 01:49:02 +0000245 if (m_enforce_valid_object)
246 {
247 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000248
Sean Callanana2868d42013-01-19 01:49:02 +0000249 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 +0000250
Sean Callanana2868d42013-01-19 01:49:02 +0000251 if (!variable_list_sp)
252 {
253 err.SetErrorString(selfErrorString);
254 return;
255 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000256
Sean Callanana2868d42013-01-19 01:49:02 +0000257 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000258
Sean Callanana2868d42013-01-19 01:49:02 +0000259 if (!self_variable_sp ||
260 !self_variable_sp->IsInScope(frame) ||
261 !self_variable_sp->LocationIsValidForFrame (frame))
262 {
263 err.SetErrorString(selfErrorString);
264 return;
265 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000266
Sean Callanana2868d42013-01-19 01:49:02 +0000267 Type *self_type = self_variable_sp->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000268
Sean Callanana2868d42013-01-19 01:49:02 +0000269 if (!self_type)
270 {
271 err.SetErrorString(selfErrorString);
272 return;
273 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000274
Greg Clayton99558cc42015-08-24 23:46:31 +0000275 CompilerType self_clang_type = self_type->GetForwardCompilerType ();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000276
Greg Clayton57ee3062013-07-11 22:46:58 +0000277 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000278 {
279 err.SetErrorString(selfErrorString);
280 return;
281 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000282
Greg Claytond8d4a572015-08-11 21:38:15 +0000283 if (ClangASTContext::IsObjCClassType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000284 {
285 return;
286 }
Greg Claytond8d4a572015-08-11 21:38:15 +0000287 else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000288 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000289 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000290 m_needs_object_ptr = true;
291 }
292 else
293 {
294 err.SetErrorString(selfErrorString);
295 return;
296 }
297 }
298 else
299 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000300 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000301 m_needs_object_ptr = true;
302 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000303 }
304 }
305 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000306}
307
Sean Callanancf5498f2010-10-22 23:25:16 +0000308// This is a really nasty hack, meant to fix Objective-C expressions of the form
309// (int)[myArray count]. Right now, because the type information for count is
310// not available, [myArray count] returns id, which can't be directly cast to
311// int without causing a clang error.
312static void
313ApplyObjcCastHack(std::string &expr)
314{
315#define OBJC_CAST_HACK_FROM "(int)["
316#define OBJC_CAST_HACK_TO "(int)(long long)["
317
318 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000319
Sean Callanancf5498f2010-10-22 23:25:16 +0000320 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
321 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
322
323#undef OBJC_CAST_HACK_TO
324#undef OBJC_CAST_HACK_FROM
325}
326
327bool
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000328ClangUserExpression::Parse (Stream &error_stream,
Sean Callananf7c3e272010-11-19 02:52:21 +0000329 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000330 lldb_private::ExecutionPolicy execution_policy,
Greg Clayton23f8c952014-03-24 23:10:19 +0000331 bool keep_result_in_memory,
332 bool generate_debug_info)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000333{
Greg Clayton5160ce52013-03-27 23:08:40 +0000334 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000335
Sean Callanan744756e2011-11-04 02:09:33 +0000336 Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000337
Sean Callanan933693b2012-02-10 01:22:05 +0000338 InstallContext(exe_ctx);
Sean Callanan9fda9d22015-10-03 09:09:01 +0000339
340 if (Target *target = exe_ctx.GetTargetPtr())
341 {
342 if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
343 {
344 m_result_delegate.RegisterPersistentState(persistent_state);
345 }
346 else
347 {
348 error_stream.PutCString ("error: couldn't start parsing (no persistent data)");
349 return false;
350 }
351 }
352 else
353 {
354 error_stream.PutCString ("error: couldn't start parsing (no target)");
355 return false;
356 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000357
Sean Callanan744756e2011-11-04 02:09:33 +0000358 ScanContext(exe_ctx, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000359
Sean Callanan744756e2011-11-04 02:09:33 +0000360 if (!err.Success())
361 {
362 error_stream.Printf("warning: %s\n", err.AsCString());
363 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Sean Callananfc55f5d2010-09-21 00:44:12 +0000365 StreamString m_transformed_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000366
Sean Callananfc55f5d2010-09-21 00:44:12 +0000367 ////////////////////////////////////
368 // Generate the expression
369 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000370
Sean Callanancf5498f2010-10-22 23:25:16 +0000371 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000372 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000373
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000374 std::string prefix = m_expr_prefix;
375
376 if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
377 {
Sean Callananb92bd752015-10-01 16:28:02 +0000378 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000379 ClangModulesDeclVendor::ModuleVector modules_for_macros;
380
381 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
382 {
383 modules_for_macros.push_back(module);
384 }
385
386 if (m_target->GetEnableAutoImportClangModules())
387 {
388 if (StackFrame *frame = exe_ctx.GetFramePtr())
389 {
390 if (Block *block = frame->GetFrameBlock())
391 {
392 SymbolContext sc;
393
394 block->CalculateSymbolContext(&sc);
395
396 if (sc.comp_unit)
397 {
398 StreamString error_stream;
399
400 decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
401 }
402 }
403 }
404 }
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000405 }
406
407 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
408
Sean Callanan9bc83842011-09-26 18:45:31 +0000409 lldb::LanguageType lang_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000410
Dawn Perchik53f34c82015-07-01 00:54:02 +0000411 if (m_in_cplusplus_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000412 lang_type = lldb::eLanguageTypeC_plus_plus;
Dawn Perchik53f34c82015-07-01 00:54:02 +0000413 else if (m_in_objectivec_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000414 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000415 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000416 lang_type = lldb::eLanguageTypeC;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000417
Dawn Perchik53f34c82015-07-01 00:54:02 +0000418 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 +0000419 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000420 error_stream.PutCString ("error: couldn't construct expression body");
421 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000422 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000423
Sean Callananfc55f5d2010-09-21 00:44:12 +0000424 if (log)
425 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000426
Sean Callanan1a8d4092010-08-27 01:01:44 +0000427 ////////////////////////////////////
428 // Set up the target and compiler
429 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000430
Greg Claytonc14ee322011-09-22 04:58:26 +0000431 Target *target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000432
Sean Callanan1a8d4092010-08-27 01:01:44 +0000433 if (!target)
434 {
435 error_stream.PutCString ("error: invalid target\n");
436 return false;
437 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000438
Sean Callanan1a8d4092010-08-27 01:01:44 +0000439 //////////////////////////
440 // Parse the expression
441 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000442
Sean Callanan96d27302013-04-11 00:09:05 +0000443 m_materializer_ap.reset(new Materializer());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000444
Sean Callanan9fda9d22015-10-03 09:09:01 +0000445 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000446
Greg Clayton57ee3062013-07-11 22:46:58 +0000447 class OnExit
448 {
449 public:
450 typedef std::function <void (void)> Callback;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000451
Greg Clayton57ee3062013-07-11 22:46:58 +0000452 OnExit (Callback const &callback) :
453 m_callback(callback)
454 {
455 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000456
Greg Clayton57ee3062013-07-11 22:46:58 +0000457 ~OnExit ()
458 {
459 m_callback();
460 }
461 private:
462 Callback m_callback;
463 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000464
Jim Ingham151c0322015-09-15 21:13:50 +0000465 OnExit on_exit([this]() { ResetDeclMap(); });
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000466
Jim Ingham151c0322015-09-15 21:13:50 +0000467 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000468 {
469 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000470
Jim Ingham151c0322015-09-15 21:13:50 +0000471 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000472
Sean Callananb9951192011-08-01 18:18:33 +0000473 return false;
474 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000475
Greg Claytonc14ee322011-09-22 04:58:26 +0000476 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000477 ExecutionContextScope *exe_scope = process;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000478
Sean Callananaa719af2012-02-08 18:43:35 +0000479 if (!exe_scope)
480 exe_scope = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000481
Todd Fiala2c77a422014-10-10 01:11:39 +0000482 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000483
Sean Callanan1a8d4092010-08-27 01:01:44 +0000484 unsigned num_errors = parser.Parse (error_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000485
Sean Callanan1a8d4092010-08-27 01:01:44 +0000486 if (num_errors)
487 {
488 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000489
Jim Ingham151c0322015-09-15 21:13:50 +0000490 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000491
Sean Callanan1a8d4092010-08-27 01:01:44 +0000492 return false;
493 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000494
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000495 //////////////////////////////////////////////////////////////////////////////////////////
496 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000497 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000498
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000499 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000500 m_jit_end_addr,
Greg Clayton23f8c952014-03-24 23:10:19 +0000501 m_execution_unit_sp,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000502 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000503 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000504 execution_policy);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000505
Greg Clayton23f8c952014-03-24 23:10:19 +0000506 if (generate_debug_info)
507 {
508 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000509
Greg Clayton23f8c952014-03-24 23:10:19 +0000510 if (jit_module_sp)
511 {
512 ConstString const_func_name(FunctionName());
513 FileSpec jit_file;
514 jit_file.GetFilename() = const_func_name;
515 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
516 m_jit_module_wp = jit_module_sp;
517 target->GetImages().Append(jit_module_sp);
518 }
519// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
520// StreamFile strm (stdout, false);
521// if (jit_obj_file)
522// {
523// jit_obj_file->GetSectionList();
524// jit_obj_file->GetSymtab();
525// jit_obj_file->Dump(&strm);
526// }
527// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
528// if (jit_sym_vendor)
529// {
530// lldb_private::SymbolContextList sc_list;
531// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
532// sc_list.Dump(&strm, target);
533// jit_sym_vendor->Dump(&strm);
534// }
535 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000536
Jim Ingham151c0322015-09-15 21:13:50 +0000537 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 +0000538
Sean Callanan1a8d4092010-08-27 01:01:44 +0000539 if (jit_error.Success())
540 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000541 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000542 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000543 return true;
544 }
545 else
546 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000547 const char *error_cstr = jit_error.AsCString();
548 if (error_cstr && error_cstr[0])
549 error_stream.Printf ("error: %s\n", error_cstr);
550 else
Jason Molendafd54b362011-09-20 21:44:10 +0000551 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000552 return false;
553 }
554}
555
556bool
Jim Ingham151c0322015-09-15 21:13:50 +0000557ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx,
558 std::vector<lldb::addr_t> &args,
559 Stream &error_stream)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000560{
Jim Ingham151c0322015-09-15 21:13:50 +0000561 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
562 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
563
564 if (m_needs_object_ptr)
Sean Callanan933693b2012-02-10 01:22:05 +0000565 {
Jim Ingham151c0322015-09-15 21:13:50 +0000566 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
567 if (!frame_sp)
568 return true;
569
570 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000571
Jim Ingham151c0322015-09-15 21:13:50 +0000572 if (m_in_cplusplus_method)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000573 {
Jim Ingham151c0322015-09-15 21:13:50 +0000574 object_name.SetCString("this");
575 }
576 else if (m_in_objectivec_method)
577 {
578 object_name.SetCString("self");
579 }
580 else
581 {
582 error_stream.Printf("Need object pointer but don't know the language\n");
583 return false;
584 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000585
Jim Ingham151c0322015-09-15 21:13:50 +0000586 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000587
Jim Ingham151c0322015-09-15 21:13:50 +0000588 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000589
Jim Ingham151c0322015-09-15 21:13:50 +0000590 if (!object_ptr_error.Success())
591 {
592 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
593 object_ptr = 0;
594 }
595
596 if (m_in_objectivec_method)
597 {
598 ConstString cmd_name("_cmd");
599
600 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000601
Sean Callanan1582ee62013-04-18 22:06:33 +0000602 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000603 {
Jim Ingham151c0322015-09-15 21:13:50 +0000604 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
605 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000606 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000607 }
Jim Ingham151c0322015-09-15 21:13:50 +0000608 if (object_ptr)
609 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000610
Jim Ingham151c0322015-09-15 21:13:50 +0000611 if (m_in_objectivec_method)
612 args.push_back(cmd_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000613
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000614
Jim Ingham36f3b362010-10-14 23:45:03 +0000615 }
616 return true;
617}
618
Sean Callanan9fda9d22015-10-03 09:09:01 +0000619lldb::ExpressionVariableSP
620ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
Jim Ingham36f3b362010-10-14 23:45:03 +0000621{
Sean Callanan9fda9d22015-10-03 09:09:01 +0000622 return m_result_delegate.GetVariable();
623}
624
625void
626ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
627{
628 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000629}
Jim Ingham36f3b362010-10-14 23:45:03 +0000630
Jim Ingham151c0322015-09-15 21:13:50 +0000631clang::ASTConsumer *
632ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
Jim Ingham36f3b362010-10-14 23:45:03 +0000633{
Jim Ingham151c0322015-09-15 21:13:50 +0000634 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
635 m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000636
Jim Ingham151c0322015-09-15 21:13:50 +0000637 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000638}
639
Sean Callanan9fda9d22015-10-03 09:09:01 +0000640ClangUserExpression::ResultDelegate::ResultDelegate()
641{
642}
643
644ConstString
645ClangUserExpression::ResultDelegate::GetName()
646{
647 return m_persistent_state->GetNextPersistentVariableName();
648}
649
650void
651ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
652{
653 m_variable = variable;
654}
655
656void
657ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
658{
659 m_persistent_state = persistent_state;
660}
661
662lldb::ExpressionVariableSP &
663ClangUserExpression::ResultDelegate::GetVariable()
664{
665 return m_variable;
666}
667