blob: 0a53f1191307cea4c87975285eaf21e70a43a552 [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
Ryan Brown998c8a1c12015-11-02 19:30:40 +000058ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
59 lldb::LanguageType language, ResultType desired_type)
60 : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type),
61 m_type_system_helper(*m_target_wp.lock().get())
Sean Callanan1a8d4092010-08-27 01:01:44 +000062{
Sean Callananc7b65062011-11-07 23:35:40 +000063 switch (m_language)
64 {
65 case lldb::eLanguageTypeC_plus_plus:
66 m_allow_cxx = true;
67 break;
68 case lldb::eLanguageTypeObjC:
69 m_allow_objc = true;
70 break;
71 case lldb::eLanguageTypeObjC_plus_plus:
72 default:
73 m_allow_cxx = true;
74 m_allow_objc = true;
75 break;
76 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000077}
78
Sean Callanane71d5532010-08-27 23:31:21 +000079ClangUserExpression::~ClangUserExpression ()
80{
Sean Callanan1a8d4092010-08-27 01:01:44 +000081}
82
Sean Callananfc55f5d2010-09-21 00:44:12 +000083void
Sean Callanan744756e2011-11-04 02:09:33 +000084ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +000085{
Greg Clayton5160ce52013-03-27 23:08:40 +000086 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +000087
88 if (log)
89 log->Printf("ClangUserExpression::ScanContext()");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000090
Greg Claytonc14ee322011-09-22 04:58:26 +000091 m_target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000092
Sean Callananc7b65062011-11-07 23:35:40 +000093 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +000094 {
95 if (log)
96 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +000097 return;
Sean Callanan70385082012-12-01 00:08:33 +000098 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000099
Jason Molendab57e4a12013-11-04 09:33:30 +0000100 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000101 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000102 {
103 if (log)
104 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000105 return;
Sean Callanan70385082012-12-01 00:08:33 +0000106 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000107
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000108 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000109
Sean Callanan72e49402011-08-05 23:43:37 +0000110 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000111 {
112 if (log)
113 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000114 return;
Sean Callanan70385082012-12-01 00:08:33 +0000115 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000116
Greg Clayton685c88c2012-07-14 00:53:55 +0000117 // Find the block that defines the function represented by "sym_ctx"
118 Block *function_block = sym_ctx.GetFunctionBlock();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000119
Greg Clayton685c88c2012-07-14 00:53:55 +0000120 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000121 {
122 if (log)
123 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000124 return;
Sean Callanan70385082012-12-01 00:08:33 +0000125 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000126
Greg Clayton99558cc42015-08-24 23:46:31 +0000127 CompilerDeclContext decl_context = function_block->GetDeclContext();
Greg Clayton685c88c2012-07-14 00:53:55 +0000128
Sean Callanan72e49402011-08-05 23:43:37 +0000129 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000130 {
131 if (log)
132 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000133 return;
Sean Callanan70385082012-12-01 00:08:33 +0000134 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000135
Greg Clayton99558cc42015-08-24 23:46:31 +0000136 if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000137 {
Sean Callananc7b65062011-11-07 23:35:40 +0000138 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000139 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000140 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000141 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000142 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000143
Sean Callanand5cc1322011-12-13 01:42:04 +0000144 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 +0000145
Greg Clayton685c88c2012-07-14 00:53:55 +0000146 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000147 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000148 err.SetErrorString(thisErrorString);
149 return;
150 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000151
Greg Clayton685c88c2012-07-14 00:53:55 +0000152 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000153
Greg Clayton685c88c2012-07-14 00:53:55 +0000154 if (!this_var_sp ||
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000155 !this_var_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000156 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000157 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000158 err.SetErrorString(thisErrorString);
159 return;
160 }
Sean Callanan744756e2011-11-04 02:09:33 +0000161 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000162
Dawn Perchik53f34c82015-07-01 00:54:02 +0000163 m_in_cplusplus_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000164 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000165 }
166 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000167 else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context))
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000168 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000169 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000170 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000171 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000172 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000173 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000174
Sean Callanand5cc1322011-12-13 01:42:04 +0000175 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 +0000176
Greg Clayton685c88c2012-07-14 00:53:55 +0000177 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000178 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000179 err.SetErrorString(selfErrorString);
180 return;
181 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000182
Greg Clayton685c88c2012-07-14 00:53:55 +0000183 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000184
185 if (!self_variable_sp ||
186 !self_variable_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000187 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000188 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000189 err.SetErrorString(selfErrorString);
190 return;
191 }
Sean Callanan744756e2011-11-04 02:09:33 +0000192 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000193
Dawn Perchik53f34c82015-07-01 00:54:02 +0000194 m_in_objectivec_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000195 m_needs_object_ptr = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000196
Sean Callanand5c17ed2011-11-15 02:11:17 +0000197 if (!method_decl->isInstanceMethod())
Dawn Perchik53f34c82015-07-01 00:54:02 +0000198 m_in_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000199 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000200 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000201 else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
Jim Ingham5fdeed42012-10-30 23:35:54 +0000202 {
203 // We might also have a function that said in the debug information that it captured an
Dawn Perchik508f0402015-07-01 17:41:02 +0000204 // object pointer. The best way to deal with getting to the ivars at present is by pretending
Jim Ingham5fdeed42012-10-30 23:35:54 +0000205 // that this is a method of a class in whatever runtime the debug info says the object pointer
206 // belongs to. Do that here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000207
Greg Clayton99558cc42015-08-24 23:46:31 +0000208 ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000209 if (metadata && metadata->HasObjectPtr())
210 {
211 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
212 if (language == lldb::eLanguageTypeC_plus_plus)
213 {
Sean Callanana2868d42013-01-19 01:49:02 +0000214 if (m_enforce_valid_object)
215 {
216 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000217
Sean Callanana2868d42013-01-19 01:49:02 +0000218 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 +0000219
Sean Callanana2868d42013-01-19 01:49:02 +0000220 if (!variable_list_sp)
221 {
222 err.SetErrorString(thisErrorString);
223 return;
224 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000225
Sean Callanana2868d42013-01-19 01:49:02 +0000226 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000227
Sean Callanana2868d42013-01-19 01:49:02 +0000228 if (!this_var_sp ||
229 !this_var_sp->IsInScope(frame) ||
230 !this_var_sp->LocationIsValidForFrame (frame))
231 {
232 err.SetErrorString(thisErrorString);
233 return;
234 }
235 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000236
Dawn Perchik53f34c82015-07-01 00:54:02 +0000237 m_in_cplusplus_method = true;
Jim Ingham5fdeed42012-10-30 23:35:54 +0000238 m_needs_object_ptr = true;
239 }
240 else if (language == lldb::eLanguageTypeObjC)
241 {
Sean Callanana2868d42013-01-19 01:49:02 +0000242 if (m_enforce_valid_object)
243 {
244 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000245
Sean Callanana2868d42013-01-19 01:49:02 +0000246 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 +0000247
Sean Callanana2868d42013-01-19 01:49:02 +0000248 if (!variable_list_sp)
249 {
250 err.SetErrorString(selfErrorString);
251 return;
252 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000253
Sean Callanana2868d42013-01-19 01:49:02 +0000254 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000255
Sean Callanana2868d42013-01-19 01:49:02 +0000256 if (!self_variable_sp ||
257 !self_variable_sp->IsInScope(frame) ||
258 !self_variable_sp->LocationIsValidForFrame (frame))
259 {
260 err.SetErrorString(selfErrorString);
261 return;
262 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000263
Sean Callanana2868d42013-01-19 01:49:02 +0000264 Type *self_type = self_variable_sp->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000265
Sean Callanana2868d42013-01-19 01:49:02 +0000266 if (!self_type)
267 {
268 err.SetErrorString(selfErrorString);
269 return;
270 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000271
Greg Clayton99558cc42015-08-24 23:46:31 +0000272 CompilerType self_clang_type = self_type->GetForwardCompilerType ();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000273
Greg Clayton57ee3062013-07-11 22:46:58 +0000274 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000275 {
276 err.SetErrorString(selfErrorString);
277 return;
278 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000279
Greg Claytond8d4a572015-08-11 21:38:15 +0000280 if (ClangASTContext::IsObjCClassType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000281 {
282 return;
283 }
Greg Claytond8d4a572015-08-11 21:38:15 +0000284 else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000285 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000286 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000287 m_needs_object_ptr = true;
288 }
289 else
290 {
291 err.SetErrorString(selfErrorString);
292 return;
293 }
294 }
295 else
296 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000297 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000298 m_needs_object_ptr = true;
299 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000300 }
301 }
302 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000303}
304
Sean Callanancf5498f2010-10-22 23:25:16 +0000305// This is a really nasty hack, meant to fix Objective-C expressions of the form
306// (int)[myArray count]. Right now, because the type information for count is
307// not available, [myArray count] returns id, which can't be directly cast to
308// int without causing a clang error.
309static void
310ApplyObjcCastHack(std::string &expr)
311{
312#define OBJC_CAST_HACK_FROM "(int)["
313#define OBJC_CAST_HACK_TO "(int)(long long)["
314
315 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000316
Sean Callanancf5498f2010-10-22 23:25:16 +0000317 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
318 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
319
320#undef OBJC_CAST_HACK_TO
321#undef OBJC_CAST_HACK_FROM
322}
323
324bool
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325ClangUserExpression::Parse (Stream &error_stream,
Sean Callananf7c3e272010-11-19 02:52:21 +0000326 ExecutionContext &exe_ctx,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000327 lldb_private::ExecutionPolicy execution_policy,
Greg Clayton23f8c952014-03-24 23:10:19 +0000328 bool keep_result_in_memory,
329 bool generate_debug_info)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000330{
Greg Clayton5160ce52013-03-27 23:08:40 +0000331 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000332
Sean Callanan744756e2011-11-04 02:09:33 +0000333 Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000334
Sean Callanan933693b2012-02-10 01:22:05 +0000335 InstallContext(exe_ctx);
Sean Callanan9fda9d22015-10-03 09:09:01 +0000336
337 if (Target *target = exe_ctx.GetTargetPtr())
338 {
339 if (PersistentExpressionState *persistent_state = target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))
340 {
341 m_result_delegate.RegisterPersistentState(persistent_state);
342 }
343 else
344 {
345 error_stream.PutCString ("error: couldn't start parsing (no persistent data)");
346 return false;
347 }
348 }
349 else
350 {
351 error_stream.PutCString ("error: couldn't start parsing (no target)");
352 return false;
353 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000354
Sean Callanan744756e2011-11-04 02:09:33 +0000355 ScanContext(exe_ctx, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000356
Sean Callanan744756e2011-11-04 02:09:33 +0000357 if (!err.Success())
358 {
359 error_stream.Printf("warning: %s\n", err.AsCString());
360 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000361
Sean Callananfc55f5d2010-09-21 00:44:12 +0000362 StreamString m_transformed_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000363
Sean Callananfc55f5d2010-09-21 00:44:12 +0000364 ////////////////////////////////////
365 // Generate the expression
366 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000367
Sean Callanancf5498f2010-10-22 23:25:16 +0000368 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000369 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000370
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000371 std::string prefix = m_expr_prefix;
372
373 if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
374 {
Sean Callananb92bd752015-10-01 16:28:02 +0000375 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000376 ClangModulesDeclVendor::ModuleVector modules_for_macros;
377
378 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
379 {
380 modules_for_macros.push_back(module);
381 }
382
383 if (m_target->GetEnableAutoImportClangModules())
384 {
385 if (StackFrame *frame = exe_ctx.GetFramePtr())
386 {
387 if (Block *block = frame->GetFrameBlock())
388 {
389 SymbolContext sc;
390
391 block->CalculateSymbolContext(&sc);
392
393 if (sc.comp_unit)
394 {
395 StreamString error_stream;
396
397 decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
398 }
399 }
400 }
401 }
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000402 }
403
404 std::unique_ptr<ExpressionSourceCode> source_code (ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
405
Sean Callanan9bc83842011-09-26 18:45:31 +0000406 lldb::LanguageType lang_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000407
Dawn Perchik53f34c82015-07-01 00:54:02 +0000408 if (m_in_cplusplus_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000409 lang_type = lldb::eLanguageTypeC_plus_plus;
Dawn Perchik53f34c82015-07-01 00:54:02 +0000410 else if (m_in_objectivec_method)
Sean Callanan9bc83842011-09-26 18:45:31 +0000411 lang_type = lldb::eLanguageTypeObjC;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000412 else
Sean Callanan9bc83842011-09-26 18:45:31 +0000413 lang_type = lldb::eLanguageTypeC;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000414
Dawn Perchik53f34c82015-07-01 00:54:02 +0000415 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 +0000416 {
Sean Callanan9bc83842011-09-26 18:45:31 +0000417 error_stream.PutCString ("error: couldn't construct expression body");
418 return false;
Sean Callananfc55f5d2010-09-21 00:44:12 +0000419 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000420
Sean Callananfc55f5d2010-09-21 00:44:12 +0000421 if (log)
422 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000423
Sean Callanan1a8d4092010-08-27 01:01:44 +0000424 ////////////////////////////////////
425 // Set up the target and compiler
426 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000427
Greg Claytonc14ee322011-09-22 04:58:26 +0000428 Target *target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000429
Sean Callanan1a8d4092010-08-27 01:01:44 +0000430 if (!target)
431 {
432 error_stream.PutCString ("error: invalid target\n");
433 return false;
434 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000435
Sean Callanan1a8d4092010-08-27 01:01:44 +0000436 //////////////////////////
437 // Parse the expression
438 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000439
Sean Callanan96d27302013-04-11 00:09:05 +0000440 m_materializer_ap.reset(new Materializer());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000441
Sean Callanan9fda9d22015-10-03 09:09:01 +0000442 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000443
Greg Clayton57ee3062013-07-11 22:46:58 +0000444 class OnExit
445 {
446 public:
447 typedef std::function <void (void)> Callback;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000448
Greg Clayton57ee3062013-07-11 22:46:58 +0000449 OnExit (Callback const &callback) :
450 m_callback(callback)
451 {
452 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000453
Greg Clayton57ee3062013-07-11 22:46:58 +0000454 ~OnExit ()
455 {
456 m_callback();
457 }
458 private:
459 Callback m_callback;
460 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000461
Jim Ingham151c0322015-09-15 21:13:50 +0000462 OnExit on_exit([this]() { ResetDeclMap(); });
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000463
Jim Ingham151c0322015-09-15 21:13:50 +0000464 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000465 {
466 error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000467
Jim Ingham151c0322015-09-15 21:13:50 +0000468 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000469
Sean Callananb9951192011-08-01 18:18:33 +0000470 return false;
471 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000472
Greg Claytonc14ee322011-09-22 04:58:26 +0000473 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000474 ExecutionContextScope *exe_scope = process;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000475
Sean Callananaa719af2012-02-08 18:43:35 +0000476 if (!exe_scope)
477 exe_scope = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000478
Todd Fiala2c77a422014-10-10 01:11:39 +0000479 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000480
Sean Callanan1a8d4092010-08-27 01:01:44 +0000481 unsigned num_errors = parser.Parse (error_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000482
Sean Callanan1a8d4092010-08-27 01:01:44 +0000483 if (num_errors)
484 {
485 error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000486
Jim Ingham151c0322015-09-15 21:13:50 +0000487 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000488
Sean Callanan1a8d4092010-08-27 01:01:44 +0000489 return false;
490 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000491
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000492 //////////////////////////////////////////////////////////////////////////////////////////
493 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000494 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000495
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000496 Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000497 m_jit_end_addr,
Greg Clayton23f8c952014-03-24 23:10:19 +0000498 m_execution_unit_sp,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000499 exe_ctx,
Sean Callanan1582ee62013-04-18 22:06:33 +0000500 m_can_interpret,
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000501 execution_policy);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000502
Greg Clayton23f8c952014-03-24 23:10:19 +0000503 if (generate_debug_info)
504 {
505 lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000506
Greg Clayton23f8c952014-03-24 23:10:19 +0000507 if (jit_module_sp)
508 {
509 ConstString const_func_name(FunctionName());
510 FileSpec jit_file;
511 jit_file.GetFilename() = const_func_name;
512 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
513 m_jit_module_wp = jit_module_sp;
514 target->GetImages().Append(jit_module_sp);
515 }
516// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
517// StreamFile strm (stdout, false);
518// if (jit_obj_file)
519// {
520// jit_obj_file->GetSectionList();
521// jit_obj_file->GetSymtab();
522// jit_obj_file->Dump(&strm);
523// }
524// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
525// if (jit_sym_vendor)
526// {
527// lldb_private::SymbolContextList sc_list;
528// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
529// sc_list.Dump(&strm, target);
530// jit_sym_vendor->Dump(&strm);
531// }
532 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000533
Jim Ingham151c0322015-09-15 21:13:50 +0000534 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 +0000535
Sean Callanan1a8d4092010-08-27 01:01:44 +0000536 if (jit_error.Success())
537 {
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000538 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
Enrico Granatadfc88a02012-09-18 00:08:47 +0000539 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Sean Callanan1a8d4092010-08-27 01:01:44 +0000540 return true;
541 }
542 else
543 {
Greg Claytone6a9e432011-05-17 03:51:29 +0000544 const char *error_cstr = jit_error.AsCString();
545 if (error_cstr && error_cstr[0])
546 error_stream.Printf ("error: %s\n", error_cstr);
547 else
Jason Molendafd54b362011-09-20 21:44:10 +0000548 error_stream.Printf ("error: expression can't be interpreted or run\n");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000549 return false;
550 }
551}
552
553bool
Jim Ingham151c0322015-09-15 21:13:50 +0000554ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx,
555 std::vector<lldb::addr_t> &args,
556 Stream &error_stream)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000557{
Jim Ingham151c0322015-09-15 21:13:50 +0000558 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
559 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
560
561 if (m_needs_object_ptr)
Sean Callanan933693b2012-02-10 01:22:05 +0000562 {
Jim Ingham151c0322015-09-15 21:13:50 +0000563 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
564 if (!frame_sp)
565 return true;
566
567 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000568
Jim Ingham151c0322015-09-15 21:13:50 +0000569 if (m_in_cplusplus_method)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000570 {
Jim Ingham151c0322015-09-15 21:13:50 +0000571 object_name.SetCString("this");
572 }
573 else if (m_in_objectivec_method)
574 {
575 object_name.SetCString("self");
576 }
577 else
578 {
579 error_stream.Printf("Need object pointer but don't know the language\n");
580 return false;
581 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000582
Jim Ingham151c0322015-09-15 21:13:50 +0000583 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000584
Jim Ingham151c0322015-09-15 21:13:50 +0000585 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000586
Jim Ingham151c0322015-09-15 21:13:50 +0000587 if (!object_ptr_error.Success())
588 {
589 error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
590 object_ptr = 0;
591 }
592
593 if (m_in_objectivec_method)
594 {
595 ConstString cmd_name("_cmd");
596
597 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000598
Sean Callanan1582ee62013-04-18 22:06:33 +0000599 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000600 {
Jim Ingham151c0322015-09-15 21:13:50 +0000601 error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
602 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000603 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000604 }
Jim Ingham151c0322015-09-15 21:13:50 +0000605 if (object_ptr)
606 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000607
Jim Ingham151c0322015-09-15 21:13:50 +0000608 if (m_in_objectivec_method)
609 args.push_back(cmd_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000610
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000611
Jim Ingham36f3b362010-10-14 23:45:03 +0000612 }
613 return true;
614}
615
Sean Callanan9fda9d22015-10-03 09:09:01 +0000616lldb::ExpressionVariableSP
617ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
Jim Ingham36f3b362010-10-14 23:45:03 +0000618{
Sean Callanan9fda9d22015-10-03 09:09:01 +0000619 return m_result_delegate.GetVariable();
620}
621
622void
623ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
624{
625 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000626}
Jim Ingham36f3b362010-10-14 23:45:03 +0000627
Jim Ingham151c0322015-09-15 21:13:50 +0000628clang::ASTConsumer *
629ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
Jim Ingham36f3b362010-10-14 23:45:03 +0000630{
Jim Ingham151c0322015-09-15 21:13:50 +0000631 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
632 m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000633
Jim Ingham151c0322015-09-15 21:13:50 +0000634 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000635}
636
Sean Callanan9fda9d22015-10-03 09:09:01 +0000637ClangUserExpression::ResultDelegate::ResultDelegate()
638{
639}
640
641ConstString
642ClangUserExpression::ResultDelegate::GetName()
643{
644 return m_persistent_state->GetNextPersistentVariableName();
645}
646
647void
648ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
649{
650 m_variable = variable;
651}
652
653void
654ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
655{
656 m_persistent_state = persistent_state;
657}
658
659lldb::ExpressionVariableSP &
660ClangUserExpression::ResultDelegate::GetVariable()
661{
662 return m_variable;
663}
664