blob: 53b6fe1b4c7320bb34524fa66d5fe8398d6a38d8 [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"
Jim Inghama1e541b2016-03-25 01:57:14 +000026#include "ClangDiagnostic.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000027
Sean Callanan1a8d4092010-08-27 01:01:44 +000028#include "lldb/Core/ConstString.h"
29#include "lldb/Core/Log.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000030#include "lldb/Core/Module.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000031#include "lldb/Core/StreamFile.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000032#include "lldb/Core/StreamString.h"
Greg Claytonb71f3842010-10-05 03:13:51 +000033#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan9bc83842011-09-26 18:45:31 +000034#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanan14b1bae2013-04-16 23:25:35 +000035#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan1582ee62013-04-18 22:06:33 +000036#include "lldb/Expression/IRInterpreter.h"
Sean Callanan96d27302013-04-11 00:09:05 +000037#include "lldb/Expression/Materializer.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000038#include "lldb/Host/HostInfo.h"
Greg Clayton1f746072012-08-29 21:13:06 +000039#include "lldb/Symbol/Block.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000040#include "lldb/Symbol/ClangASTContext.h"
41#include "lldb/Symbol/Function.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000042#include "lldb/Symbol/ObjectFile.h"
43#include "lldb/Symbol/SymbolVendor.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000044#include "lldb/Symbol/Type.h"
45#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Sean Callananfc55f5d2010-09-21 00:44:12 +000046#include "lldb/Symbol/VariableList.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000047#include "lldb/Target/ExecutionContext.h"
Greg Clayton8f343b02010-11-04 01:54:29 +000048#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000049#include "lldb/Target/StackFrame.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000050#include "lldb/Target/Target.h"
Jim Inghamf48169b2010-11-30 02:22:11 +000051#include "lldb/Target/ThreadPlan.h"
52#include "lldb/Target/ThreadPlanCallUserExpression.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000053
Sean Callanan72e49402011-08-05 23:43:37 +000054#include "clang/AST/DeclCXX.h"
55#include "clang/AST/DeclObjC.h"
56
Sean Callanan1a8d4092010-08-27 01:01:44 +000057using namespace lldb_private;
58
Sean Callanan00294b32016-03-22 21:05:51 +000059ClangUserExpression::ClangUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix,
60 lldb::LanguageType language, ResultType desired_type,
61 const EvaluateExpressionOptions &options)
62 : LLVMUserExpression(exe_scope, expr, expr_prefix, language, desired_type, options),
63 m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
Sean Callanan1a8d4092010-08-27 01:01:44 +000064{
Sean Callananc7b65062011-11-07 23:35:40 +000065 switch (m_language)
66 {
Sean Callanan00294b32016-03-22 21:05:51 +000067 case lldb::eLanguageTypeC_plus_plus:
68 m_allow_cxx = true;
69 break;
70 case lldb::eLanguageTypeObjC:
71 m_allow_objc = true;
72 break;
73 case lldb::eLanguageTypeObjC_plus_plus:
74 default:
75 m_allow_cxx = true;
76 m_allow_objc = true;
77 break;
Sean Callananc7b65062011-11-07 23:35:40 +000078 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000079}
80
Sean Callanane71d5532010-08-27 23:31:21 +000081ClangUserExpression::~ClangUserExpression ()
82{
Sean Callanan1a8d4092010-08-27 01:01:44 +000083}
84
Sean Callananfc55f5d2010-09-21 00:44:12 +000085void
Sean Callanan744756e2011-11-04 02:09:33 +000086ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
Sean Callananfc55f5d2010-09-21 00:44:12 +000087{
Greg Clayton5160ce52013-03-27 23:08:40 +000088 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +000089
90 if (log)
91 log->Printf("ClangUserExpression::ScanContext()");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000092
Greg Claytonc14ee322011-09-22 04:58:26 +000093 m_target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000094
Sean Callananc7b65062011-11-07 23:35:40 +000095 if (!(m_allow_cxx || m_allow_objc))
Sean Callanan70385082012-12-01 00:08:33 +000096 {
97 if (log)
98 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
Sean Callananc7b65062011-11-07 23:35:40 +000099 return;
Sean Callanan70385082012-12-01 00:08:33 +0000100 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000101
Jason Molendab57e4a12013-11-04 09:33:30 +0000102 StackFrame *frame = exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000103 if (frame == NULL)
Sean Callanan70385082012-12-01 00:08:33 +0000104 {
105 if (log)
106 log->Printf(" [CUE::SC] Null stack frame");
Sean Callananfc55f5d2010-09-21 00:44:12 +0000107 return;
Sean Callanan70385082012-12-01 00:08:33 +0000108 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000109
Sean Callanan5dd6c3d2012-07-13 21:20:29 +0000110 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000111
Sean Callanan72e49402011-08-05 23:43:37 +0000112 if (!sym_ctx.function)
Sean Callanan70385082012-12-01 00:08:33 +0000113 {
114 if (log)
115 log->Printf(" [CUE::SC] Null function");
Sean Callanan72e49402011-08-05 23:43:37 +0000116 return;
Sean Callanan70385082012-12-01 00:08:33 +0000117 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000118
Greg Clayton685c88c2012-07-14 00:53:55 +0000119 // Find the block that defines the function represented by "sym_ctx"
120 Block *function_block = sym_ctx.GetFunctionBlock();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000121
Greg Clayton685c88c2012-07-14 00:53:55 +0000122 if (!function_block)
Sean Callanan70385082012-12-01 00:08:33 +0000123 {
124 if (log)
125 log->Printf(" [CUE::SC] Null function block");
Greg Clayton685c88c2012-07-14 00:53:55 +0000126 return;
Sean Callanan70385082012-12-01 00:08:33 +0000127 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000128
Greg Clayton99558cc42015-08-24 23:46:31 +0000129 CompilerDeclContext decl_context = function_block->GetDeclContext();
Greg Clayton685c88c2012-07-14 00:53:55 +0000130
Sean Callanan72e49402011-08-05 23:43:37 +0000131 if (!decl_context)
Sean Callanan70385082012-12-01 00:08:33 +0000132 {
133 if (log)
134 log->Printf(" [CUE::SC] Null decl context");
Sean Callanan72e49402011-08-05 23:43:37 +0000135 return;
Sean Callanan70385082012-12-01 00:08:33 +0000136 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000137
Greg Clayton99558cc42015-08-24 23:46:31 +0000138 if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context))
Sean Callanan3670ba52010-12-01 21:35:54 +0000139 {
Sean Callananc7b65062011-11-07 23:35:40 +0000140 if (m_allow_cxx && method_decl->isInstance())
Sean Callanan3670ba52010-12-01 21:35:54 +0000141 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000142 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000143 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000144 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000145
Sean Callanand5cc1322011-12-13 01:42:04 +0000146 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 +0000147
Greg Clayton685c88c2012-07-14 00:53:55 +0000148 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000149 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000150 err.SetErrorString(thisErrorString);
151 return;
152 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000153
Greg Clayton685c88c2012-07-14 00:53:55 +0000154 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000155
Greg Clayton685c88c2012-07-14 00:53:55 +0000156 if (!this_var_sp ||
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000157 !this_var_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000158 !this_var_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000159 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000160 err.SetErrorString(thisErrorString);
161 return;
162 }
Sean Callanan744756e2011-11-04 02:09:33 +0000163 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000164
Dawn Perchik53f34c82015-07-01 00:54:02 +0000165 m_in_cplusplus_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000166 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000167 }
168 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000169 else if (clang::ObjCMethodDecl *method_decl = ClangASTContext::DeclContextGetAsObjCMethodDecl(decl_context))
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000170 {
Sean Callanand5c17ed2011-11-15 02:11:17 +0000171 if (m_allow_objc)
Sean Callanan9bc83842011-09-26 18:45:31 +0000172 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000173 if (m_enforce_valid_object)
Sean Callanan744756e2011-11-04 02:09:33 +0000174 {
Greg Clayton685c88c2012-07-14 00:53:55 +0000175 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000176
Sean Callanand5cc1322011-12-13 01:42:04 +0000177 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 +0000178
Greg Clayton685c88c2012-07-14 00:53:55 +0000179 if (!variable_list_sp)
Sean Callanand5cc1322011-12-13 01:42:04 +0000180 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000181 err.SetErrorString(selfErrorString);
182 return;
183 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000184
Greg Clayton685c88c2012-07-14 00:53:55 +0000185 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000186
187 if (!self_variable_sp ||
188 !self_variable_sp->IsInScope(frame) ||
Greg Clayton685c88c2012-07-14 00:53:55 +0000189 !self_variable_sp->LocationIsValidForFrame (frame))
Sean Callanand5cc1322011-12-13 01:42:04 +0000190 {
Sean Callanand5cc1322011-12-13 01:42:04 +0000191 err.SetErrorString(selfErrorString);
192 return;
193 }
Sean Callanan744756e2011-11-04 02:09:33 +0000194 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000195
Dawn Perchik53f34c82015-07-01 00:54:02 +0000196 m_in_objectivec_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000197 m_needs_object_ptr = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000198
Sean Callanand5c17ed2011-11-15 02:11:17 +0000199 if (!method_decl->isInstanceMethod())
Dawn Perchik53f34c82015-07-01 00:54:02 +0000200 m_in_static_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000201 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000202 }
Greg Clayton99558cc42015-08-24 23:46:31 +0000203 else if (clang::FunctionDecl *function_decl = ClangASTContext::DeclContextGetAsFunctionDecl(decl_context))
Jim Ingham5fdeed42012-10-30 23:35:54 +0000204 {
205 // We might also have a function that said in the debug information that it captured an
Dawn Perchik508f0402015-07-01 17:41:02 +0000206 // object pointer. The best way to deal with getting to the ivars at present is by pretending
Jim Ingham5fdeed42012-10-30 23:35:54 +0000207 // that this is a method of a class in whatever runtime the debug info says the object pointer
208 // belongs to. Do that here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000209
Greg Clayton99558cc42015-08-24 23:46:31 +0000210 ClangASTMetadata *metadata = ClangASTContext::DeclContextGetMetaData (decl_context, function_decl);
Jim Ingham5fdeed42012-10-30 23:35:54 +0000211 if (metadata && metadata->HasObjectPtr())
212 {
213 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
214 if (language == lldb::eLanguageTypeC_plus_plus)
215 {
Sean Callanana2868d42013-01-19 01:49:02 +0000216 if (m_enforce_valid_object)
217 {
218 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000219
Sean Callanana2868d42013-01-19 01:49:02 +0000220 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 +0000221
Sean Callanana2868d42013-01-19 01:49:02 +0000222 if (!variable_list_sp)
223 {
224 err.SetErrorString(thisErrorString);
225 return;
226 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000227
Sean Callanana2868d42013-01-19 01:49:02 +0000228 lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000229
Sean Callanana2868d42013-01-19 01:49:02 +0000230 if (!this_var_sp ||
231 !this_var_sp->IsInScope(frame) ||
232 !this_var_sp->LocationIsValidForFrame (frame))
233 {
234 err.SetErrorString(thisErrorString);
235 return;
236 }
237 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000238
Dawn Perchik53f34c82015-07-01 00:54:02 +0000239 m_in_cplusplus_method = true;
Jim Ingham5fdeed42012-10-30 23:35:54 +0000240 m_needs_object_ptr = true;
241 }
242 else if (language == lldb::eLanguageTypeObjC)
243 {
Sean Callanana2868d42013-01-19 01:49:02 +0000244 if (m_enforce_valid_object)
245 {
246 lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000247
Sean Callanana2868d42013-01-19 01:49:02 +0000248 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 +0000249
Sean Callanana2868d42013-01-19 01:49:02 +0000250 if (!variable_list_sp)
251 {
252 err.SetErrorString(selfErrorString);
253 return;
254 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000255
Sean Callanana2868d42013-01-19 01:49:02 +0000256 lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000257
Sean Callanana2868d42013-01-19 01:49:02 +0000258 if (!self_variable_sp ||
259 !self_variable_sp->IsInScope(frame) ||
260 !self_variable_sp->LocationIsValidForFrame (frame))
261 {
262 err.SetErrorString(selfErrorString);
263 return;
264 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000265
Sean Callanana2868d42013-01-19 01:49:02 +0000266 Type *self_type = self_variable_sp->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000267
Sean Callanana2868d42013-01-19 01:49:02 +0000268 if (!self_type)
269 {
270 err.SetErrorString(selfErrorString);
271 return;
272 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000273
Greg Clayton99558cc42015-08-24 23:46:31 +0000274 CompilerType self_clang_type = self_type->GetForwardCompilerType ();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000275
Greg Clayton57ee3062013-07-11 22:46:58 +0000276 if (!self_clang_type)
Sean Callanana2868d42013-01-19 01:49:02 +0000277 {
278 err.SetErrorString(selfErrorString);
279 return;
280 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000281
Greg Claytond8d4a572015-08-11 21:38:15 +0000282 if (ClangASTContext::IsObjCClassType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000283 {
284 return;
285 }
Greg Claytond8d4a572015-08-11 21:38:15 +0000286 else if (ClangASTContext::IsObjCObjectPointerType(self_clang_type))
Sean Callanana2868d42013-01-19 01:49:02 +0000287 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000288 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000289 m_needs_object_ptr = true;
290 }
291 else
292 {
293 err.SetErrorString(selfErrorString);
294 return;
295 }
296 }
297 else
298 {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000299 m_in_objectivec_method = true;
Sean Callanana2868d42013-01-19 01:49:02 +0000300 m_needs_object_ptr = true;
301 }
Jim Ingham5fdeed42012-10-30 23:35:54 +0000302 }
303 }
304 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000305}
306
Sean Callanancf5498f2010-10-22 23:25:16 +0000307// This is a really nasty hack, meant to fix Objective-C expressions of the form
308// (int)[myArray count]. Right now, because the type information for count is
309// not available, [myArray count] returns id, which can't be directly cast to
310// int without causing a clang error.
311static void
312ApplyObjcCastHack(std::string &expr)
313{
314#define OBJC_CAST_HACK_FROM "(int)["
315#define OBJC_CAST_HACK_TO "(int)(long long)["
316
317 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000318
Sean Callanancf5498f2010-10-22 23:25:16 +0000319 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
320 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
321
322#undef OBJC_CAST_HACK_TO
323#undef OBJC_CAST_HACK_FROM
324}
325
326bool
Sean Callanan579e70c2016-03-19 00:03:59 +0000327ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
328 lldb_private::ExecutionPolicy execution_policy, 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 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000345 diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't start parsing (no persistent data)");
Sean Callanan9fda9d22015-10-03 09:09:01 +0000346 return false;
347 }
348 }
349 else
350 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000351 diagnostic_manager.PutCString(eDiagnosticSeverityError, "error: couldn't start parsing (no target)");
Sean Callanan9fda9d22015-10-03 09:09:01 +0000352 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 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000359 diagnostic_manager.PutCString(eDiagnosticSeverityWarning, err.AsCString());
Sean Callanan744756e2011-11-04 02:09:33 +0000360 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000361
Sean Callananfc55f5d2010-09-21 00:44:12 +0000362 ////////////////////////////////////
363 // Generate the expression
364 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000365
Sean Callanancf5498f2010-10-22 23:25:16 +0000366 ApplyObjcCastHack(m_expr_text);
Greg Clayton73b472d2010-10-27 03:32:59 +0000367 //ApplyUnicharHack(m_expr_text);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000368
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000369 std::string prefix = m_expr_prefix;
370
371 if (ClangModulesDeclVendor *decl_vendor = m_target->GetClangModulesDeclVendor())
372 {
Sean Callananb92bd752015-10-01 16:28:02 +0000373 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = llvm::cast<ClangPersistentVariables>(m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC))->GetHandLoadedClangModules();
Sean Callananf0c5aeb2015-04-20 16:31:29 +0000374 ClangModulesDeclVendor::ModuleVector modules_for_macros;
375
376 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
377 {
378 modules_for_macros.push_back(module);
379 }
380
381 if (m_target->GetEnableAutoImportClangModules())
382 {
383 if (StackFrame *frame = exe_ctx.GetFramePtr())
384 {
385 if (Block *block = frame->GetFrameBlock())
386 {
387 SymbolContext sc;
388
389 block->CalculateSymbolContext(&sc);
390
391 if (sc.comp_unit)
392 {
393 StreamString error_stream;
394
395 decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
396 }
397 }
398 }
399 }
Sean Callananb8bf6ef2015-04-14 18:36:17 +0000400 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000401
Jim Inghame5ee6f02016-03-29 22:00:08 +0000402 lldb::LanguageType lang_type = lldb::eLanguageTypeUnknown;
403
Sean Callanan00294b32016-03-22 21:05:51 +0000404 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000405 {
Sean Callanan00294b32016-03-22 21:05:51 +0000406 m_transformed_text = m_expr_text;
407 }
408 else
409 {
410 std::unique_ptr<ExpressionSourceCode> source_code(
411 ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
412
Sean Callanan00294b32016-03-22 21:05:51 +0000413 if (m_in_cplusplus_method)
414 lang_type = lldb::eLanguageTypeC_plus_plus;
415 else if (m_in_objectivec_method)
416 lang_type = lldb::eLanguageTypeObjC;
417 else
418 lang_type = lldb::eLanguageTypeC;
419
Sean Callanan7736a202016-04-29 18:09:03 +0000420 if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method, exe_ctx))
Sean Callanan00294b32016-03-22 21:05:51 +0000421 {
422 diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't construct expression body");
423 return false;
424 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000425 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000426
Sean Callananfc55f5d2010-09-21 00:44:12 +0000427 if (log)
428 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000429
Sean Callanan1a8d4092010-08-27 01:01:44 +0000430 ////////////////////////////////////
431 // Set up the target and compiler
432 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000433
Greg Claytonc14ee322011-09-22 04:58:26 +0000434 Target *target = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000435
Sean Callanan1a8d4092010-08-27 01:01:44 +0000436 if (!target)
437 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000438 diagnostic_manager.PutCString(eDiagnosticSeverityError, "invalid target");
Sean Callanan1a8d4092010-08-27 01:01:44 +0000439 return false;
440 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000441
Sean Callanan1a8d4092010-08-27 01:01:44 +0000442 //////////////////////////
443 // Parse the expression
444 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000445
Sean Callanan96d27302013-04-11 00:09:05 +0000446 m_materializer_ap.reset(new Materializer());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000447
Sean Callanan9fda9d22015-10-03 09:09:01 +0000448 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000449
Greg Clayton57ee3062013-07-11 22:46:58 +0000450 class OnExit
451 {
452 public:
453 typedef std::function <void (void)> Callback;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000454
Greg Clayton57ee3062013-07-11 22:46:58 +0000455 OnExit (Callback const &callback) :
456 m_callback(callback)
457 {
458 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000459
Greg Clayton57ee3062013-07-11 22:46:58 +0000460 ~OnExit ()
461 {
462 m_callback();
463 }
464 private:
465 Callback m_callback;
466 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000467
Jim Ingham151c0322015-09-15 21:13:50 +0000468 OnExit on_exit([this]() { ResetDeclMap(); });
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000469
Jim Ingham151c0322015-09-15 21:13:50 +0000470 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
Sean Callananb9951192011-08-01 18:18:33 +0000471 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000472 diagnostic_manager.PutCString(eDiagnosticSeverityError,
473 "current process state is unsuitable for expression parsing");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000474
Jim Ingham151c0322015-09-15 21:13:50 +0000475 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000476
Sean Callananb9951192011-08-01 18:18:33 +0000477 return false;
478 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000479
Sean Callanan00294b32016-03-22 21:05:51 +0000480 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
481 {
482 DeclMap()->SetLookupsEnabled(true);
483 }
484
Greg Claytonc14ee322011-09-22 04:58:26 +0000485 Process *process = exe_ctx.GetProcessPtr();
Sean Callananaa719af2012-02-08 18:43:35 +0000486 ExecutionContextScope *exe_scope = process;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000487
Sean Callananaa719af2012-02-08 18:43:35 +0000488 if (!exe_scope)
489 exe_scope = exe_ctx.GetTargetPtr();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000490
Jim Inghama1e541b2016-03-25 01:57:14 +0000491 // We use a shared pointer here so we can use the original parser - if it succeeds
492 // or the rewrite parser we might make if it fails. But the parser_sp will never be empty.
493
Jim Inghame5ee6f02016-03-29 22:00:08 +0000494 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000495
Jim Inghame5ee6f02016-03-29 22:00:08 +0000496 unsigned num_errors = parser.Parse(diagnostic_manager);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000497
Jim Inghame5ee6f02016-03-29 22:00:08 +0000498 // Check here for FixItHints. If there are any try to apply the fixits and set the fixed text in m_fixed_text
499 // before returning an error.
Sean Callanan1a8d4092010-08-27 01:01:44 +0000500 if (num_errors)
501 {
Jim Inghame5ee6f02016-03-29 22:00:08 +0000502 if (diagnostic_manager.HasFixIts())
503 {
504 if (parser.RewriteExpression(diagnostic_manager))
505 {
506 size_t fixed_start;
507 size_t fixed_end;
508 const std::string &fixed_expression = diagnostic_manager.GetFixedExpression();
509 if (ExpressionSourceCode::GetOriginalBodyBounds(fixed_expression, lang_type, fixed_start, fixed_end))
510 m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start);
511 }
512 }
Sean Callanan579e70c2016-03-19 00:03:59 +0000513 diagnostic_manager.Printf(eDiagnosticSeverityError, "%u error%s parsing expression", num_errors,
514 num_errors == 1 ? "" : "s");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000515
Jim Ingham151c0322015-09-15 21:13:50 +0000516 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000517
Sean Callanan1a8d4092010-08-27 01:01:44 +0000518 return false;
519 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000520
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000521 //////////////////////////////////////////////////////////////////////////////////////////
522 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000523 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000524
Sean Callanan00294b32016-03-22 21:05:51 +0000525 {
Jim Inghame5ee6f02016-03-29 22:00:08 +0000526 Error jit_error = parser.PrepareForExecution(m_jit_start_addr,
527 m_jit_end_addr,
528 m_execution_unit_sp,
529 exe_ctx,
530 m_can_interpret,
531 execution_policy);
Sean Callanan00294b32016-03-22 21:05:51 +0000532
533 if (!jit_error.Success())
534 {
535 const char *error_cstr = jit_error.AsCString();
536 if (error_cstr && error_cstr[0])
537 diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
538 else
539 diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
540 return false;
541 }
542 }
543
544 if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
545 {
Jim Inghame5ee6f02016-03-29 22:00:08 +0000546 Error static_init_error = parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
Sean Callanan00294b32016-03-22 21:05:51 +0000547
548 if (!static_init_error.Success())
549 {
550 const char *error_cstr = static_init_error.AsCString();
551 if (error_cstr && error_cstr[0])
552 diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n",
553 error_cstr);
554 else
555 diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n");
556 return false;
557 }
558 }
559
560 if (m_execution_unit_sp)
561 {
562 bool register_execution_unit = false;
563
564 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
565 {
566 register_execution_unit = true;
567 }
Sean Callanan47cca782016-03-26 00:30:40 +0000568
569 // If there is more than one external function in the execution
570 // unit, it needs to keep living even if it's not top level, because
571 // the result could refer to that function.
572
573 if (m_execution_unit_sp->GetJittedFunctions().size() > 1)
574 {
575 register_execution_unit = true;
576 }
Sean Callanan00294b32016-03-22 21:05:51 +0000577
578 if (register_execution_unit)
579 {
Sean Callanan00294b32016-03-22 21:05:51 +0000580 llvm::cast<PersistentExpressionState>(
581 exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language))
582 ->RegisterExecutionUnit(m_execution_unit_sp);
583 }
584 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000585
Greg Clayton23f8c952014-03-24 23:10:19 +0000586 if (generate_debug_info)
587 {
Sean Callanan00294b32016-03-22 21:05:51 +0000588 lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000589
Greg Clayton23f8c952014-03-24 23:10:19 +0000590 if (jit_module_sp)
591 {
592 ConstString const_func_name(FunctionName());
593 FileSpec jit_file;
594 jit_file.GetFilename() = const_func_name;
595 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
596 m_jit_module_wp = jit_module_sp;
597 target->GetImages().Append(jit_module_sp);
598 }
Greg Clayton23f8c952014-03-24 23:10:19 +0000599 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000600
Sean Callanan00294b32016-03-22 21:05:51 +0000601 ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any
602 // ClangASTImporter::Minions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000603
Sean Callanan00294b32016-03-22 21:05:51 +0000604 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
605 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
606 return true;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000607}
608
609bool
Sean Callanan579e70c2016-03-19 00:03:59 +0000610ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
611 lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000612{
Jim Ingham151c0322015-09-15 21:13:50 +0000613 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
Sean Callanan579e70c2016-03-19 00:03:59 +0000614 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
615
Jim Ingham151c0322015-09-15 21:13:50 +0000616 if (m_needs_object_ptr)
Sean Callanan933693b2012-02-10 01:22:05 +0000617 {
Jim Ingham151c0322015-09-15 21:13:50 +0000618 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
619 if (!frame_sp)
620 return true;
621
622 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000623
Jim Ingham151c0322015-09-15 21:13:50 +0000624 if (m_in_cplusplus_method)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000625 {
Jim Ingham151c0322015-09-15 21:13:50 +0000626 object_name.SetCString("this");
627 }
628 else if (m_in_objectivec_method)
629 {
630 object_name.SetCString("self");
631 }
632 else
633 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000634 diagnostic_manager.PutCString(eDiagnosticSeverityError, "need object pointer but don't know the language");
Jim Ingham151c0322015-09-15 21:13:50 +0000635 return false;
636 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000637
Jim Ingham151c0322015-09-15 21:13:50 +0000638 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000639
Jim Ingham151c0322015-09-15 21:13:50 +0000640 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000641
Jim Ingham151c0322015-09-15 21:13:50 +0000642 if (!object_ptr_error.Success())
643 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000644 diagnostic_manager.Printf(eDiagnosticSeverityWarning,
645 "couldn't get required object pointer (substituting NULL): %s",
646 object_ptr_error.AsCString());
Jim Ingham151c0322015-09-15 21:13:50 +0000647 object_ptr = 0;
648 }
649
650 if (m_in_objectivec_method)
651 {
652 ConstString cmd_name("_cmd");
653
654 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000655
Sean Callanan1582ee62013-04-18 22:06:33 +0000656 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000657 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000658 diagnostic_manager.Printf(eDiagnosticSeverityWarning,
659 "couldn't get cmd pointer (substituting NULL): %s",
660 object_ptr_error.AsCString());
Jim Ingham151c0322015-09-15 21:13:50 +0000661 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000662 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000663 }
Jim Ingham151c0322015-09-15 21:13:50 +0000664 if (object_ptr)
665 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000666
Jim Ingham151c0322015-09-15 21:13:50 +0000667 if (m_in_objectivec_method)
668 args.push_back(cmd_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000669
Jim Ingham51148e92015-11-05 00:24:18 +0000670 args.push_back(struct_address);
671 }
672 else
673 {
674 args.push_back(struct_address);
Jim Ingham36f3b362010-10-14 23:45:03 +0000675 }
676 return true;
677}
678
Sean Callanan9fda9d22015-10-03 09:09:01 +0000679lldb::ExpressionVariableSP
680ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
Jim Ingham36f3b362010-10-14 23:45:03 +0000681{
Sean Callanan9fda9d22015-10-03 09:09:01 +0000682 return m_result_delegate.GetVariable();
683}
684
685void
686ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
687{
688 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000689}
Jim Ingham36f3b362010-10-14 23:45:03 +0000690
Jim Ingham151c0322015-09-15 21:13:50 +0000691clang::ASTConsumer *
Sean Callanan00294b32016-03-22 21:05:51 +0000692ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough)
Jim Ingham36f3b362010-10-14 23:45:03 +0000693{
Sean Callanan00294b32016-03-22 21:05:51 +0000694 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000695
Jim Ingham151c0322015-09-15 21:13:50 +0000696 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000697}
698
Sean Callanan00294b32016-03-22 21:05:51 +0000699void
700ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls()
701{
702 if (m_result_synthesizer_up.get())
703 {
704 m_result_synthesizer_up->CommitPersistentDecls();
705 }
706}
707
Sean Callanan9fda9d22015-10-03 09:09:01 +0000708ClangUserExpression::ResultDelegate::ResultDelegate()
709{
710}
711
712ConstString
713ClangUserExpression::ResultDelegate::GetName()
714{
715 return m_persistent_state->GetNextPersistentVariableName();
716}
717
718void
719ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
720{
721 m_variable = variable;
722}
723
724void
725ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
726{
727 m_persistent_state = persistent_state;
728}
729
730lldb::ExpressionVariableSP &
731ClangUserExpression::ResultDelegate::GetVariable()
732{
733 return m_variable;
734}
735