blob: 9bf8cd5f295212d7fa46c75a329db36992e4f28b [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
Sean Callanan00294b32016-03-22 21:05:51 +0000402 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000403 {
Sean Callanan00294b32016-03-22 21:05:51 +0000404 m_transformed_text = m_expr_text;
405 }
406 else
407 {
408 std::unique_ptr<ExpressionSourceCode> source_code(
409 ExpressionSourceCode::CreateWrapped(prefix.c_str(), m_expr_text.c_str()));
410
411 lldb::LanguageType lang_type;
412
413 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
420 if (!source_code->GetText(m_transformed_text, lang_type, m_const_object, m_in_static_method, exe_ctx))
421 {
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
494 std::shared_ptr<ClangExpressionParser> parser_sp(new ClangExpressionParser(exe_scope, *this, generate_debug_info));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000495
Jim Inghama1e541b2016-03-25 01:57:14 +0000496 unsigned num_errors = parser_sp->Parse(diagnostic_manager);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000497
Jim Inghama1e541b2016-03-25 01:57:14 +0000498 // Check here for FixItHints. If there are any try fixing the source and re-parsing...
499 if (num_errors && diagnostic_manager.HasFixIts() && diagnostic_manager.ShouldAutoApplyFixIts())
500 {
501 if (parser_sp->RewriteExpression(diagnostic_manager))
502 {
503 std::string backup_source = std::move(m_transformed_text);
504 m_transformed_text = diagnostic_manager.GetFixedExpression();
505 // Make a new diagnostic manager and parser, and try again with the rewritten expression:
506 // FIXME: It would be nice to reuse the parser we have but that doesn't seem to be possible.
507 DiagnosticManager rewrite_manager;
508 std::shared_ptr<ClangExpressionParser> rewrite_parser_sp(new ClangExpressionParser(exe_scope, *this, generate_debug_info));
509 unsigned rewrite_errors = rewrite_parser_sp->Parse(rewrite_manager);
510 if (rewrite_errors == 0)
511 {
512 diagnostic_manager.Clear();
513 parser_sp = rewrite_parser_sp;
514 num_errors = 0;
515 }
516 else
517 {
518 m_transformed_text = std::move(backup_source);
519 }
520 }
521 }
522
Sean Callanan1a8d4092010-08-27 01:01:44 +0000523 if (num_errors)
524 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000525 diagnostic_manager.Printf(eDiagnosticSeverityError, "%u error%s parsing expression", num_errors,
526 num_errors == 1 ? "" : "s");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000527
Jim Ingham151c0322015-09-15 21:13:50 +0000528 ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000529
Sean Callanan1a8d4092010-08-27 01:01:44 +0000530 return false;
531 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000532
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000533 //////////////////////////////////////////////////////////////////////////////////////////
534 // Prepare the output of the parser for execution, evaluating it statically if possible
Sean Callanan1a8d4092010-08-27 01:01:44 +0000535 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000536
Sean Callanan00294b32016-03-22 21:05:51 +0000537 {
Jim Inghama1e541b2016-03-25 01:57:14 +0000538 Error jit_error = parser_sp->PrepareForExecution(m_jit_start_addr,
539 m_jit_end_addr,
540 m_execution_unit_sp,
541 exe_ctx,
542 m_can_interpret,
543 execution_policy);
Sean Callanan00294b32016-03-22 21:05:51 +0000544
545 if (!jit_error.Success())
546 {
547 const char *error_cstr = jit_error.AsCString();
548 if (error_cstr && error_cstr[0])
549 diagnostic_manager.PutCString(eDiagnosticSeverityError, error_cstr);
550 else
551 diagnostic_manager.PutCString(eDiagnosticSeverityError, "expression can't be interpreted or run");
552 return false;
553 }
554 }
555
556 if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel)
557 {
Jim Inghama1e541b2016-03-25 01:57:14 +0000558 Error static_init_error = parser_sp->RunStaticInitializers(m_execution_unit_sp, exe_ctx);
Sean Callanan00294b32016-03-22 21:05:51 +0000559
560 if (!static_init_error.Success())
561 {
562 const char *error_cstr = static_init_error.AsCString();
563 if (error_cstr && error_cstr[0])
564 diagnostic_manager.Printf(eDiagnosticSeverityError, "couldn't run static initializers: %s\n",
565 error_cstr);
566 else
567 diagnostic_manager.PutCString(eDiagnosticSeverityError, "couldn't run static initializers\n");
568 return false;
569 }
570 }
571
572 if (m_execution_unit_sp)
573 {
574 bool register_execution_unit = false;
575
576 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel)
577 {
578 register_execution_unit = true;
579 }
580
581 if (register_execution_unit)
582 {
583 // We currently key off there being more than one external function in the execution
584 // unit to determine whether it needs to live in the process.
585
586 llvm::cast<PersistentExpressionState>(
587 exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(m_language))
588 ->RegisterExecutionUnit(m_execution_unit_sp);
589 }
590 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000591
Greg Clayton23f8c952014-03-24 23:10:19 +0000592 if (generate_debug_info)
593 {
Sean Callanan00294b32016-03-22 21:05:51 +0000594 lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000595
Greg Clayton23f8c952014-03-24 23:10:19 +0000596 if (jit_module_sp)
597 {
598 ConstString const_func_name(FunctionName());
599 FileSpec jit_file;
600 jit_file.GetFilename() = const_func_name;
601 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
602 m_jit_module_wp = jit_module_sp;
603 target->GetImages().Append(jit_module_sp);
604 }
Greg Clayton23f8c952014-03-24 23:10:19 +0000605 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000606
Sean Callanan00294b32016-03-22 21:05:51 +0000607 ResetDeclMap(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any
608 // ClangASTImporter::Minions.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000609
Sean Callanan00294b32016-03-22 21:05:51 +0000610 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
611 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
612 return true;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000613}
614
615bool
Sean Callanan579e70c2016-03-19 00:03:59 +0000616ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
617 lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager)
Sean Callanan1a8d4092010-08-27 01:01:44 +0000618{
Jim Ingham151c0322015-09-15 21:13:50 +0000619 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
Sean Callanan579e70c2016-03-19 00:03:59 +0000620 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
621
Jim Ingham151c0322015-09-15 21:13:50 +0000622 if (m_needs_object_ptr)
Sean Callanan933693b2012-02-10 01:22:05 +0000623 {
Jim Ingham151c0322015-09-15 21:13:50 +0000624 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
625 if (!frame_sp)
626 return true;
627
628 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000629
Jim Ingham151c0322015-09-15 21:13:50 +0000630 if (m_in_cplusplus_method)
Sean Callananfc55f5d2010-09-21 00:44:12 +0000631 {
Jim Ingham151c0322015-09-15 21:13:50 +0000632 object_name.SetCString("this");
633 }
634 else if (m_in_objectivec_method)
635 {
636 object_name.SetCString("self");
637 }
638 else
639 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000640 diagnostic_manager.PutCString(eDiagnosticSeverityError, "need object pointer but don't know the language");
Jim Ingham151c0322015-09-15 21:13:50 +0000641 return false;
642 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000643
Jim Ingham151c0322015-09-15 21:13:50 +0000644 Error object_ptr_error;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000645
Jim Ingham151c0322015-09-15 21:13:50 +0000646 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000647
Jim Ingham151c0322015-09-15 21:13:50 +0000648 if (!object_ptr_error.Success())
649 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000650 diagnostic_manager.Printf(eDiagnosticSeverityWarning,
651 "couldn't get required object pointer (substituting NULL): %s",
652 object_ptr_error.AsCString());
Jim Ingham151c0322015-09-15 21:13:50 +0000653 object_ptr = 0;
654 }
655
656 if (m_in_objectivec_method)
657 {
658 ConstString cmd_name("_cmd");
659
660 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000661
Sean Callanan1582ee62013-04-18 22:06:33 +0000662 if (!object_ptr_error.Success())
Sean Callanan17827832010-12-13 22:46:15 +0000663 {
Sean Callanan579e70c2016-03-19 00:03:59 +0000664 diagnostic_manager.Printf(eDiagnosticSeverityWarning,
665 "couldn't get cmd pointer (substituting NULL): %s",
666 object_ptr_error.AsCString());
Jim Ingham151c0322015-09-15 21:13:50 +0000667 cmd_ptr = 0;
Sean Callanan9d48e802010-12-14 00:42:36 +0000668 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000669 }
Jim Ingham151c0322015-09-15 21:13:50 +0000670 if (object_ptr)
671 args.push_back(object_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000672
Jim Ingham151c0322015-09-15 21:13:50 +0000673 if (m_in_objectivec_method)
674 args.push_back(cmd_ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000675
Jim Ingham51148e92015-11-05 00:24:18 +0000676 args.push_back(struct_address);
677 }
678 else
679 {
680 args.push_back(struct_address);
Jim Ingham36f3b362010-10-14 23:45:03 +0000681 }
682 return true;
683}
684
Sean Callanan9fda9d22015-10-03 09:09:01 +0000685lldb::ExpressionVariableSP
686ClangUserExpression::GetResultAfterDematerialization(ExecutionContextScope *exe_scope)
Jim Ingham36f3b362010-10-14 23:45:03 +0000687{
Sean Callanan9fda9d22015-10-03 09:09:01 +0000688 return m_result_delegate.GetVariable();
689}
690
691void
692ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, bool keep_result_in_memory)
693{
694 m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000695}
Jim Ingham36f3b362010-10-14 23:45:03 +0000696
Jim Ingham151c0322015-09-15 21:13:50 +0000697clang::ASTConsumer *
Sean Callanan00294b32016-03-22 21:05:51 +0000698ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(clang::ASTConsumer *passthrough)
Jim Ingham36f3b362010-10-14 23:45:03 +0000699{
Sean Callanan00294b32016-03-22 21:05:51 +0000700 m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough, m_top_level, m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000701
Jim Ingham151c0322015-09-15 21:13:50 +0000702 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000703}
704
Sean Callanan00294b32016-03-22 21:05:51 +0000705void
706ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls()
707{
708 if (m_result_synthesizer_up.get())
709 {
710 m_result_synthesizer_up->CommitPersistentDecls();
711 }
712}
713
Sean Callanan9fda9d22015-10-03 09:09:01 +0000714ClangUserExpression::ResultDelegate::ResultDelegate()
715{
716}
717
718ConstString
719ClangUserExpression::ResultDelegate::GetName()
720{
721 return m_persistent_state->GetNextPersistentVariableName();
722}
723
724void
725ClangUserExpression::ResultDelegate::DidDematerialize(lldb::ExpressionVariableSP &variable)
726{
727 m_variable = variable;
728}
729
730void
731ClangUserExpression::ResultDelegate::RegisterPersistentState(PersistentExpressionState *persistent_state)
732{
733 m_persistent_state = persistent_state;
734}
735
736lldb::ExpressionVariableSP &
737ClangUserExpression::ResultDelegate::GetVariable()
738{
739 return m_variable;
740}
741