blob: c32ad579fd388ec7841e92092c5460a21894e180 [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);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000339
Sean Callanan744756e2011-11-04 02:09:33 +0000340 ScanContext(exe_ctx, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000341
Sean Callanan744756e2011-11-04 02:09:33 +0000342 if (!err.Success())
343 {
344 error_stream.Printf("warning: %s\n", err.AsCString());
345 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000346
Sean Callananfc55f5d2010-09-21 00:44:12 +0000347 StreamString m_transformed_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000348
Sean Callananfc55f5d2010-09-21 00:44:12 +0000349 ////////////////////////////////////
350 // Generate the expression
351 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000352
Sean Callanancf5498f2010-10-22 23:25:16 +0000353 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000354 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000355
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000356 std::string prefix = m_expr_prefix;
357
358 if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
359 {
Sean Callananb92bd752015-10-01 16:28:02 +0000360 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000361 ClangModulesDeclVendor::ModuleVector modules_for_macros;
362
363 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
364 {
365 modules_for_macros.push_back(module);
366 }
367
368 if (m_target->GetEnableAutoImportClangModules())
369 {
370 if (StackFrame *frame = exe_ctx.GetFramePtr())
371 {
372 if (Block *block = frame->GetFrameBlock())
373 {
374 SymbolContext sc;
375
376 block->CalculateSymbolContext(&sc);
377
378 if (sc.comp_unit)
379 {
380 StreamString error_stream;
381
382 decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
383 }
384 }
385 }
386 }
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000387 }
388
389 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
390
Sean Callanan9bc83842011-09-26 18:45:31 +0000391 lldb::LanguageType lang_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000392
Dawn Perchik53f34c82015-07-01 00:54:02 +0000393 if (m_in_cplusplus_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000394 lang_type = lldb::eLanguageTypeC_plus_plus;
Dawn Perchik53f34c82015-07-01 00:54:02 +0000395 else if (m_in_objectivec_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000396 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000397 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000398 lang_type = lldb::eLanguageTypeC;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000399
Dawn Perchik53f34c82015-07-01 00:54:02 +0000400 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 +0000401 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000402 error_stream.PutCString ("error: couldn't construct expression body");
403 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000404 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000405
Sean Callananfc55f5d2010-09-21 00:44:12 +0000406 if (log)
407 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000408
Sean Callanan1a8d4092010-08-27 01:01:44 +0000409 ////////////////////////////////////
410 // Set up the target and compiler
411 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000412
Greg Claytonc14ee322011-09-22 04:58:26 +0000413 Target *target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000414
Sean Callanan1a8d4092010-08-27 01:01:44 +0000415 if (!target)
416 {
417 error_stream.PutCString ("error: invalid target\n");
418 return false;
419 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000420
Sean Callanan1a8d4092010-08-27 01:01:44 +0000421 //////////////////////////
422 // Parse the expression
423 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000424
Sean Callanan96d27302013-04-11 00:09:05 +0000425 m_materializer_ap.reset(new Materializer());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000426
Jim Ingham151c0322015-09-15 21:13:50 +0000427 ResetDeclMap(exe_ctx, keep_result_in_memory);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000428
Greg Clayton57ee3062013-07-11 22:46:58 +0000429 class OnExit
430 {
431 public:
432 typedef std::function <void (void)> Callback;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000433
Greg Clayton57ee3062013-07-11 22:46:58 +0000434 OnExit (Callback const &callback) :
435 m_callback(callback)
436 {
437 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000438
Greg Clayton57ee3062013-07-11 22:46:58 +0000439 ~OnExit ()
440 {
441 m_callback();
442 }
443 private:
444 Callback m_callback;
445 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000446
Jim Ingham151c0322015-09-15 21:13:50 +0000447 OnExit on_exit([this]() { ResetDeclMap(); });
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000448
Jim Ingham151c0322015-09-15 21:13:50 +0000449 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000450 {
451 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000452
Jim Ingham151c0322015-09-15 21:13:50 +0000453 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000454
Sean Callananb9951192011-08-01 18:18:33 +0000455 return false;
456 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000457
Greg Claytonc14ee322011-09-22 04:58:26 +0000458 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000459 ExecutionContextScope *exe_scope = process;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000460
Sean Callananaa719af2012-02-08 18:43:35 +0000461 if (!exe_scope)
462 exe_scope = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000463
Todd Fiala2c77a422014-10-10 01:11:39 +0000464 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000465
Sean Callanan1a8d4092010-08-27 01:01:44 +0000466 unsigned num_errors = parser.Parse (error_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000467
Sean Callanan1a8d4092010-08-27 01:01:44 +0000468 if (num_errors)
469 {
470 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
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 Callanan1a8d4092010-08-27 01:01:44 +0000474 return false;
475 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000476
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000477 //////////////////////////////////////////////////////////////////////////////////////////
478 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000479 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000480
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000481 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000482 m_jit_end_addr,
Greg Clayton23f8c952014-03-24 23:10:19 +0000483 m_execution_unit_sp,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000484 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000485 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000486 execution_policy);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000487
Greg Clayton23f8c952014-03-24 23:10:19 +0000488 if (generate_debug_info)
489 {
490 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000491
Greg Clayton23f8c952014-03-24 23:10:19 +0000492 if (jit_module_sp)
493 {
494 ConstString const_func_name(FunctionName());
495 FileSpec jit_file;
496 jit_file.GetFilename() = const_func_name;
497 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
498 m_jit_module_wp = jit_module_sp;
499 target->GetImages().Append(jit_module_sp);
500 }
501// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
502// StreamFile strm (stdout, false);
503// if (jit_obj_file)
504// {
505// jit_obj_file->GetSectionList();
506// jit_obj_file->GetSymtab();
507// jit_obj_file->Dump(&strm);
508// }
509// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
510// if (jit_sym_vendor)
511// {
512// lldb_private::SymbolContextList sc_list;
513// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
514// sc_list.Dump(&strm, target);
515// jit_sym_vendor->Dump(&strm);
516// }
517 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000518
Jim Ingham151c0322015-09-15 21:13:50 +0000519 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 +0000520
Sean Callanan1a8d4092010-08-27 01:01:44 +0000521 if (jit_error.Success())
522 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000523 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000524 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000525 return true;
526 }
527 else
528 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000529 const char *error_cstr = jit_error.AsCString();
530 if (error_cstr && error_cstr[0])
531 error_stream.Printf ("error: %s\n", error_cstr);
532 else
Jason Molendafd54b362011-09-20 21:44:10 +0000533 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000534 return false;
535 }
536}
537
538bool
Jim Ingham151c0322015-09-15 21:13:50 +0000539ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx,
540 std::vector<lldb::addr_t> &args,
541 Stream &error_stream)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000542{
Jim Ingham151c0322015-09-15 21:13:50 +0000543 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
544 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
545
546 if (m_needs_object_ptr)
Sean Callanan933693b2012-02-10 01:22:05 +0000547 {
Jim Ingham151c0322015-09-15 21:13:50 +0000548 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
549 if (!frame_sp)
550 return true;
551
552 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000553
Jim Ingham151c0322015-09-15 21:13:50 +0000554 if (m_in_cplusplus_method)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000555 {
Jim Ingham151c0322015-09-15 21:13:50 +0000556 object_name.SetCString("this");
557 }
558 else if (m_in_objectivec_method)
559 {
560 object_name.SetCString("self");
561 }
562 else
563 {
564 error_stream.Printf("Need object pointer but don't know the language\n");
565 return false;
566 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000567
Jim Ingham151c0322015-09-15 21:13:50 +0000568 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000569
Jim Ingham151c0322015-09-15 21:13:50 +0000570 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000571
Jim Ingham151c0322015-09-15 21:13:50 +0000572 if (!object_ptr_error.Success())
573 {
574 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
575 object_ptr = 0;
576 }
577
578 if (m_in_objectivec_method)
579 {
580 ConstString cmd_name("_cmd");
581
582 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000583
Sean Callanan1582ee62013-04-18 22:06:33 +0000584 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000585 {
Jim Ingham151c0322015-09-15 21:13:50 +0000586 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
587 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000588 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000589 }
Jim Ingham151c0322015-09-15 21:13:50 +0000590 if (object_ptr)
591 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000592
Jim Ingham151c0322015-09-15 21:13:50 +0000593 if (m_in_objectivec_method)
594 args.push_back(cmd_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000595
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000596
Jim Ingham36f3b362010-10-14 23:45:03 +0000597 }
598 return true;
599}
600
Jim Ingham151c0322015-09-15 21:13:50 +0000601void
602ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
Jim Ingham36f3b362010-10-14 23:45:03 +0000603{
Jim Ingham151c0322015-09-15 21:13:50 +0000604 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000605}
Jim Ingham36f3b362010-10-14 23:45:03 +0000606
Jim Ingham151c0322015-09-15 21:13:50 +0000607clang::ASTConsumer *
608ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
Jim Ingham36f3b362010-10-14 23:45:03 +0000609{
Jim Ingham151c0322015-09-15 21:13:50 +0000610 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
611 m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000612
Jim Ingham151c0322015-09-15 21:13:50 +0000613 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000614}
615