blob: e7e9ba972bb0ea45b9dc7b29c996cba7485b9441 [file] [log] [blame]
Sean Callanan79763a42011-05-23 21:40:23 +00001//===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
Sean Callanan1a8d4092010-08-27 01:01:44 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Sean Callanan1a8d4092010-08-27 01:01:44 +00006//
7//===----------------------------------------------------------------------===//
8
Sean Callanan1a8d4092010-08-27 01:01:44 +00009#include <stdio.h>
10#if HAVE_SYS_TYPES_H
Kate Stoneb9c1b512016-09-06 20:57:50 +000011#include <sys/types.h>
Sean Callanan1a8d4092010-08-27 01:01:44 +000012#endif
13
Sean Callanan1a8d4092010-08-27 01:01:44 +000014#include <cstdlib>
Sean Callanan1a8d4092010-08-27 01:01:44 +000015#include <map>
Kate Stoneb9c1b512016-09-06 20:57:50 +000016#include <string>
Sean Callanan1a8d4092010-08-27 01:01:44 +000017
Sean Callanan4dbb2712015-09-25 20:35:58 +000018#include "ClangUserExpression.h"
19
20#include "ASTResultSynthesizer.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "ClangDiagnostic.h"
Sean Callanan4dbb2712015-09-25 20:35:58 +000022#include "ClangExpressionDeclMap.h"
23#include "ClangExpressionParser.h"
24#include "ClangModulesDeclVendor.h"
25#include "ClangPersistentVariables.h"
26
Sean Callananbda7ef82016-06-22 17:32:17 +000027#include "lldb/Core/Debugger.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000028#include "lldb/Core/Module.h"
Greg Claytonc4e411f2011-01-18 19:36:39 +000029#include "lldb/Core/StreamFile.h"
Greg Claytonb71f3842010-10-05 03:13:51 +000030#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan9bc83842011-09-26 18:45:31 +000031#include "lldb/Expression/ExpressionSourceCode.h"
Sean Callanan14b1bae2013-04-16 23:25:35 +000032#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan1582ee62013-04-18 22:06:33 +000033#include "lldb/Expression/IRInterpreter.h"
Sean Callanan96d27302013-04-11 00:09:05 +000034#include "lldb/Expression/Materializer.h"
Zachary Turner97a14e62014-08-19 17:18:29 +000035#include "lldb/Host/HostInfo.h"
Greg Clayton1f746072012-08-29 21:13:06 +000036#include "lldb/Symbol/Block.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000037#include "lldb/Symbol/ClangASTContext.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000038#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000039#include "lldb/Symbol/Function.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000040#include "lldb/Symbol/ObjectFile.h"
41#include "lldb/Symbol/SymbolVendor.h"
Jim Ingham5fdeed42012-10-30 23:35:54 +000042#include "lldb/Symbol/Type.h"
Sean Callananfc55f5d2010-09-21 00:44:12 +000043#include "lldb/Symbol/VariableList.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000044#include "lldb/Target/ExecutionContext.h"
Greg Clayton8f343b02010-11-04 01:54:29 +000045#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000046#include "lldb/Target/StackFrame.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000047#include "lldb/Target/Target.h"
Jim Inghamf48169b2010-11-30 02:22:11 +000048#include "lldb/Target/ThreadPlan.h"
49#include "lldb/Target/ThreadPlanCallUserExpression.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000050#include "lldb/Utility/ConstString.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000051#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000052#include "lldb/Utility/StreamString.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
Kate Stoneb9c1b512016-09-06 20:57:50 +000059ClangUserExpression::ClangUserExpression(
Zachary Turnerc5d7df92016-11-08 04:52:16 +000060 ExecutionContextScope &exe_scope, llvm::StringRef expr,
61 llvm::StringRef prefix, lldb::LanguageType language,
62 ResultType desired_type, const EvaluateExpressionOptions &options)
63 : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 options),
65 m_type_system_helper(*m_target_wp.lock().get(),
66 options.GetExecutionPolicy() ==
Adrian Prantl5435f782018-04-30 23:59:15 +000067 eExecutionPolicyTopLevel),
68 m_result_delegate(exe_scope.CalculateTarget()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 switch (m_language) {
70 case lldb::eLanguageTypeC_plus_plus:
71 m_allow_cxx = true;
72 break;
73 case lldb::eLanguageTypeObjC:
74 m_allow_objc = true;
75 break;
76 case lldb::eLanguageTypeObjC_plus_plus:
77 default:
78 m_allow_cxx = true;
79 m_allow_objc = true;
80 break;
81 }
Sean Callanan1a8d4092010-08-27 01:01:44 +000082}
83
Kate Stoneb9c1b512016-09-06 20:57:50 +000084ClangUserExpression::~ClangUserExpression() {}
Sean Callanan1a8d4092010-08-27 01:01:44 +000085
Zachary Turner97206d52017-05-12 04:51:55 +000086void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan70385082012-12-01 00:08:33 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 if (log)
90 log->Printf("ClangUserExpression::ScanContext()");
91
92 m_target = exe_ctx.GetTargetPtr();
93
94 if (!(m_allow_cxx || m_allow_objc)) {
Sean Callanan70385082012-12-01 00:08:33 +000095 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
97 return;
98 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000099
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 StackFrame *frame = exe_ctx.GetFramePtr();
101 if (frame == NULL) {
102 if (log)
103 log->Printf(" [CUE::SC] Null stack frame");
104 return;
105 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
108 lldb::eSymbolContextBlock);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 if (!sym_ctx.function) {
111 if (log)
112 log->Printf(" [CUE::SC] Null function");
113 return;
114 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 // Find the block that defines the function represented by "sym_ctx"
117 Block *function_block = sym_ctx.GetFunctionBlock();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 if (!function_block) {
120 if (log)
121 log->Printf(" [CUE::SC] Null function block");
122 return;
123 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 CompilerDeclContext decl_context = function_block->GetDeclContext();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 if (!decl_context) {
128 if (log)
129 log->Printf(" [CUE::SC] Null decl context");
130 return;
131 }
Greg Clayton685c88c2012-07-14 00:53:55 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 if (clang::CXXMethodDecl *method_decl =
134 ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
135 if (m_allow_cxx && method_decl->isInstance()) {
136 if (m_enforce_valid_object) {
137 lldb::VariableListSP variable_list_sp(
138 function_block->GetBlockVariableList(true));
Greg Clayton685c88c2012-07-14 00:53:55 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 const char *thisErrorString = "Stopped in a C++ method, but 'this' "
141 "isn't available; pretending we are in a "
142 "generic context";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 if (!variable_list_sp) {
145 err.SetErrorString(thisErrorString);
146 return;
Sean Callanan3670ba52010-12-01 21:35:54 +0000147 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148
149 lldb::VariableSP this_var_sp(
150 variable_list_sp->FindVariable(ConstString("this")));
151
152 if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
153 !this_var_sp->LocationIsValidForFrame(frame)) {
154 err.SetErrorString(thisErrorString);
155 return;
156 }
157 }
158
159 m_in_cplusplus_method = true;
160 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000161 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 } else if (clang::ObjCMethodDecl *method_decl =
163 ClangASTContext::DeclContextGetAsObjCMethodDecl(
164 decl_context)) {
165 if (m_allow_objc) {
166 if (m_enforce_valid_object) {
167 lldb::VariableListSP variable_list_sp(
168 function_block->GetBlockVariableList(true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 const char *selfErrorString = "Stopped in an Objective-C method, but "
171 "'self' isn't available; pretending we "
172 "are in a generic context";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 if (!variable_list_sp) {
175 err.SetErrorString(selfErrorString);
176 return;
177 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 lldb::VariableSP self_variable_sp =
180 variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
183 !self_variable_sp->LocationIsValidForFrame(frame)) {
184 err.SetErrorString(selfErrorString);
185 return;
186 }
187 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000188
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 m_in_objectivec_method = true;
190 m_needs_object_ptr = true;
191
192 if (!method_decl->isInstanceMethod())
193 m_in_static_method = true;
194 }
195 } else if (clang::FunctionDecl *function_decl =
196 ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
197 // We might also have a function that said in the debug information that it
Adrian Prantl05097242018-04-30 16:49:04 +0000198 // captured an object pointer. The best way to deal with getting to the
199 // ivars at present is by pretending that this is a method of a class in
200 // whatever runtime the debug info says the object pointer belongs to. Do
201 // that here.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202
203 ClangASTMetadata *metadata =
204 ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
205 if (metadata && metadata->HasObjectPtr()) {
206 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
207 if (language == lldb::eLanguageTypeC_plus_plus) {
208 if (m_enforce_valid_object) {
209 lldb::VariableListSP variable_list_sp(
210 function_block->GetBlockVariableList(true));
211
212 const char *thisErrorString = "Stopped in a context claiming to "
213 "capture a C++ object pointer, but "
214 "'this' isn't available; pretending we "
215 "are in a generic context";
216
217 if (!variable_list_sp) {
218 err.SetErrorString(thisErrorString);
219 return;
220 }
221
222 lldb::VariableSP this_var_sp(
223 variable_list_sp->FindVariable(ConstString("this")));
224
225 if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
226 !this_var_sp->LocationIsValidForFrame(frame)) {
227 err.SetErrorString(thisErrorString);
228 return;
229 }
230 }
231
232 m_in_cplusplus_method = true;
233 m_needs_object_ptr = true;
234 } else if (language == lldb::eLanguageTypeObjC) {
235 if (m_enforce_valid_object) {
236 lldb::VariableListSP variable_list_sp(
237 function_block->GetBlockVariableList(true));
238
239 const char *selfErrorString =
240 "Stopped in a context claiming to capture an Objective-C object "
241 "pointer, but 'self' isn't available; pretending we are in a "
242 "generic context";
243
244 if (!variable_list_sp) {
245 err.SetErrorString(selfErrorString);
246 return;
247 }
248
249 lldb::VariableSP self_variable_sp =
250 variable_list_sp->FindVariable(ConstString("self"));
251
252 if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
253 !self_variable_sp->LocationIsValidForFrame(frame)) {
254 err.SetErrorString(selfErrorString);
255 return;
256 }
257
258 Type *self_type = self_variable_sp->GetType();
259
260 if (!self_type) {
261 err.SetErrorString(selfErrorString);
262 return;
263 }
264
265 CompilerType self_clang_type = self_type->GetForwardCompilerType();
266
267 if (!self_clang_type) {
268 err.SetErrorString(selfErrorString);
269 return;
270 }
271
272 if (ClangASTContext::IsObjCClassType(self_clang_type)) {
273 return;
274 } else if (ClangASTContext::IsObjCObjectPointerType(
275 self_clang_type)) {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000276 m_in_objectivec_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000277 m_needs_object_ptr = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 } else {
279 err.SetErrorString(selfErrorString);
280 return;
281 }
282 } else {
283 m_in_objectivec_method = true;
284 m_needs_object_ptr = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000285 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000287 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000289}
290
Adrian Prantl05097242018-04-30 16:49:04 +0000291// This is a really nasty hack, meant to fix Objective-C expressions of the
292// form (int)[myArray count]. Right now, because the type information for
293// count is not available, [myArray count] returns id, which can't be directly
294// cast to int without causing a clang error.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295static void ApplyObjcCastHack(std::string &expr) {
Sean Callanancf5498f2010-10-22 23:25:16 +0000296#define OBJC_CAST_HACK_FROM "(int)["
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297#define OBJC_CAST_HACK_TO "(int)(long long)["
Sean Callanancf5498f2010-10-22 23:25:16 +0000298
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000300
Kate Stoneb9c1b512016-09-06 20:57:50 +0000301 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
302 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1,
303 OBJC_CAST_HACK_TO);
Sean Callanancf5498f2010-10-22 23:25:16 +0000304
305#undef OBJC_CAST_HACK_TO
306#undef OBJC_CAST_HACK_FROM
307}
308
Raphael Isemann12468902018-06-19 21:25:59 +0000309namespace {
310// Utility guard that calls a callback when going out of scope.
311class OnExit {
312public:
313 typedef std::function<void(void)> Callback;
314
315 OnExit(Callback const &callback) : m_callback(callback) {}
316
317 ~OnExit() { m_callback(); }
318
319private:
320 Callback m_callback;
321};
322} // namespace
323
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000324bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
325 ExecutionContext &exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 if (Target *target = exe_ctx.GetTargetPtr()) {
327 if (PersistentExpressionState *persistent_state =
328 target->GetPersistentExpressionStateForLanguage(
329 lldb::eLanguageTypeC)) {
330 m_result_delegate.RegisterPersistentState(persistent_state);
331 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000332 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333 eDiagnosticSeverityError,
334 "couldn't start parsing (no persistent data)");
335 return false;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000336 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000338 diagnostic_manager.PutString(eDiagnosticSeverityError,
339 "error: couldn't start parsing (no target)");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340 return false;
341 }
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000342 return true;
343}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000345static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 if (ClangModulesDeclVendor *decl_vendor =
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000347 target->GetClangModulesDeclVendor()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
349 llvm::cast<ClangPersistentVariables>(
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000350 target->GetPersistentExpressionStateForLanguage(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 lldb::eLanguageTypeC))
352 ->GetHandLoadedClangModules();
353 ClangModulesDeclVendor::ModuleVector modules_for_macros;
354
355 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
356 modules_for_macros.push_back(module);
357 }
358
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000359 if (target->GetEnableAutoImportClangModules()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 if (StackFrame *frame = exe_ctx.GetFramePtr()) {
361 if (Block *block = frame->GetFrameBlock()) {
362 SymbolContext sc;
363
364 block->CalculateSymbolContext(&sc);
365
366 if (sc.comp_unit) {
367 StreamString error_stream;
368
369 decl_vendor->AddModulesForCompileUnit(
370 *sc.comp_unit, modules_for_macros, error_stream);
371 }
372 }
373 }
374 }
375 }
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000376}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377
Raphael Isemanndababf72018-09-27 10:12:54 +0000378void ClangUserExpression::UpdateLanguageForExpr(
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000379 DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
Raphael Isemanndababf72018-09-27 10:12:54 +0000380 m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000381
382 std::string prefix = m_expr_prefix;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383
384 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
385 m_transformed_text = m_expr_text;
386 } else {
387 std::unique_ptr<ExpressionSourceCode> source_code(
388 ExpressionSourceCode::CreateWrapped(prefix.c_str(),
389 m_expr_text.c_str()));
390
391 if (m_in_cplusplus_method)
Raphael Isemanndababf72018-09-27 10:12:54 +0000392 m_expr_lang = lldb::eLanguageTypeC_plus_plus;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 else if (m_in_objectivec_method)
Raphael Isemanndababf72018-09-27 10:12:54 +0000394 m_expr_lang = lldb::eLanguageTypeObjC;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000395 else
Raphael Isemanndababf72018-09-27 10:12:54 +0000396 m_expr_lang = lldb::eLanguageTypeC;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397
Raphael Isemanndababf72018-09-27 10:12:54 +0000398 if (!source_code->GetText(m_transformed_text, m_expr_lang,
399 m_in_static_method, exe_ctx)) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000400 diagnostic_manager.PutString(eDiagnosticSeverityError,
401 "couldn't construct expression body");
Raphael Isemanndababf72018-09-27 10:12:54 +0000402 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403 }
Raphael Isemann74829732018-08-30 17:29:37 +0000404
405 // Find and store the start position of the original code inside the
406 // transformed code. We need this later for the code completion.
407 std::size_t original_start;
408 std::size_t original_end;
409 bool found_bounds = source_code->GetOriginalBodyBounds(
Raphael Isemanndababf72018-09-27 10:12:54 +0000410 m_transformed_text, m_expr_lang, original_start, original_end);
Raphael Isemann74829732018-08-30 17:29:37 +0000411 if (found_bounds) {
412 m_user_expression_start_pos = original_start;
413 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 }
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000415}
416
417bool ClangUserExpression::PrepareForParsing(
418 DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
419 InstallContext(exe_ctx);
420
421 if (!SetupPersistentState(diagnostic_manager, exe_ctx))
422 return false;
423
424 Status err;
425 ScanContext(exe_ctx, err);
426
427 if (!err.Success()) {
428 diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
429 }
430
431 ////////////////////////////////////
432 // Generate the expression
433 //
434
435 ApplyObjcCastHack(m_expr_text);
436
437 SetupDeclVendor(exe_ctx, m_target);
Raphael Isemanndababf72018-09-27 10:12:54 +0000438
439 UpdateLanguageForExpr(diagnostic_manager, exe_ctx);
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000440 return true;
441}
442
443bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
444 ExecutionContext &exe_ctx,
445 lldb_private::ExecutionPolicy execution_policy,
446 bool keep_result_in_memory,
447 bool generate_debug_info) {
448 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
449
450 if (!PrepareForParsing(diagnostic_manager, exe_ctx))
451 return false;
452
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 if (log)
454 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
455
456 ////////////////////////////////////
457 // Set up the target and compiler
458 //
459
460 Target *target = exe_ctx.GetTargetPtr();
461
462 if (!target) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000463 diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 return false;
465 }
466
467 //////////////////////////
468 // Parse the expression
469 //
470
471 m_materializer_ap.reset(new Materializer());
472
473 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
474
Kate Stoneb9c1b512016-09-06 20:57:50 +0000475 OnExit on_exit([this]() { ResetDeclMap(); });
476
477 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000478 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 eDiagnosticSeverityError,
480 "current process state is unsuitable for expression parsing");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000481 return false;
482 }
483
484 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
485 DeclMap()->SetLookupsEnabled(true);
486 }
487
488 Process *process = exe_ctx.GetProcessPtr();
489 ExecutionContextScope *exe_scope = process;
490
491 if (!exe_scope)
492 exe_scope = exe_ctx.GetTargetPtr();
493
494 // We use a shared pointer here so we can use the original parser - if it
Adrian Prantl05097242018-04-30 16:49:04 +0000495 // succeeds or the rewrite parser we might make if it fails. But the
496 // parser_sp will never be empty.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497
498 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
499
500 unsigned num_errors = parser.Parse(diagnostic_manager);
501
502 // Check here for FixItHints. If there are any try to apply the fixits and
Adrian Prantl05097242018-04-30 16:49:04 +0000503 // set the fixed text in m_fixed_text before returning an error.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000504 if (num_errors) {
505 if (diagnostic_manager.HasFixIts()) {
506 if (parser.RewriteExpression(diagnostic_manager)) {
507 size_t fixed_start;
508 size_t fixed_end;
509 const std::string &fixed_expression =
510 diagnostic_manager.GetFixedExpression();
511 if (ExpressionSourceCode::GetOriginalBodyBounds(
Raphael Isemanndababf72018-09-27 10:12:54 +0000512 fixed_expression, m_expr_lang, fixed_start, fixed_end))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513 m_fixed_text =
514 fixed_expression.substr(fixed_start, fixed_end - fixed_start);
515 }
Sean Callanan9fda9d22015-10-03 09:09:01 +0000516 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517 return false;
518 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000519
Kate Stoneb9c1b512016-09-06 20:57:50 +0000520 //////////////////////////////////////////////////////////////////////////////////////////
Adrian Prantl05097242018-04-30 16:49:04 +0000521 // Prepare the output of the parser for execution, evaluating it statically
522 // if possible
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000524
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 {
Zachary Turner97206d52017-05-12 04:51:55 +0000526 Status jit_error = parser.PrepareForExecution(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
528 m_can_interpret, execution_policy);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000529
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530 if (!jit_error.Success()) {
531 const char *error_cstr = jit_error.AsCString();
532 if (error_cstr && error_cstr[0])
Zachary Turnere2411fa2016-11-12 19:12:56 +0000533 diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 else
Zachary Turnere2411fa2016-11-12 19:12:56 +0000535 diagnostic_manager.PutString(eDiagnosticSeverityError,
536 "expression can't be interpreted or run");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 return false;
538 }
539 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000540
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
Zachary Turner97206d52017-05-12 04:51:55 +0000542 Status static_init_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545 if (!static_init_error.Success()) {
546 const char *error_cstr = static_init_error.AsCString();
547 if (error_cstr && error_cstr[0])
548 diagnostic_manager.Printf(eDiagnosticSeverityError,
549 "couldn't run static initializers: %s\n",
550 error_cstr);
551 else
Zachary Turnere2411fa2016-11-12 19:12:56 +0000552 diagnostic_manager.PutString(eDiagnosticSeverityError,
553 "couldn't run static initializers\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 return false;
555 }
556 }
557
558 if (m_execution_unit_sp) {
559 bool register_execution_unit = false;
560
561 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
562 register_execution_unit = true;
Sean Callananb9951192011-08-01 18:18:33 +0000563 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000564
Adrian Prantl05097242018-04-30 16:49:04 +0000565 // If there is more than one external function in the execution unit, it
566 // needs to keep living even if it's not top level, because the result
567 // could refer to that function.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568
569 if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
570 register_execution_unit = true;
Sean Callanan00294b32016-03-22 21:05:51 +0000571 }
572
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573 if (register_execution_unit) {
574 llvm::cast<PersistentExpressionState>(
575 exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
576 m_language))
577 ->RegisterExecutionUnit(m_execution_unit_sp);
Sean Callanan1a8d4092010-08-27 01:01:44 +0000578 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000580
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 if (generate_debug_info) {
582 lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000583
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584 if (jit_module_sp) {
585 ConstString const_func_name(FunctionName());
586 FileSpec jit_file;
587 jit_file.GetFilename() = const_func_name;
588 jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
589 m_jit_module_wp = jit_module_sp;
590 target->GetImages().Append(jit_module_sp);
Sean Callanan00294b32016-03-22 21:05:51 +0000591 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 }
Sean Callanan00294b32016-03-22 21:05:51 +0000593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
595 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
596 return true;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000597}
598
Raphael Isemann74829732018-08-30 17:29:37 +0000599//------------------------------------------------------------------
600/// Converts an absolute position inside a given code string into
601/// a column/line pair.
602///
603/// @param[in] abs_pos
604/// A absolute position in the code string that we want to convert
605/// to a column/line pair.
606///
607/// @param[in] code
608/// A multi-line string usually representing source code.
609///
610/// @param[out] line
611/// The line in the code that contains the given absolute position.
612/// The first line in the string is indexed as 1.
613///
614/// @param[out] column
615/// The column in the line that contains the absolute position.
616/// The first character in a line is indexed as 0.
617//------------------------------------------------------------------
Raphael Isemannbfc5ef62018-09-22 13:33:08 +0000618static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code,
Raphael Isemann74829732018-08-30 17:29:37 +0000619 unsigned &line, unsigned &column) {
620 // Reset to code position to beginning of the file.
621 line = 0;
622 column = 0;
623
624 assert(abs_pos <= code.size() && "Absolute position outside code string?");
625
626 // We have to walk up to the position and count lines/columns.
627 for (std::size_t i = 0; i < abs_pos; ++i) {
628 // If we hit a line break, we go back to column 0 and enter a new line.
629 // We only handle \n because that's what we internally use to make new
630 // lines for our temporary code strings.
631 if (code[i] == '\n') {
632 ++line;
633 column = 0;
634 continue;
635 }
636 ++column;
637 }
638}
639
640bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
Raphael Isemannc11a7802018-08-30 21:26:32 +0000641 CompletionRequest &request,
642 unsigned complete_pos) {
Raphael Isemann74829732018-08-30 17:29:37 +0000643 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
644
645 // We don't want any visible feedback when completing an expression. Mostly
646 // because the results we get from an incomplete invocation are probably not
647 // correct.
648 DiagnosticManager diagnostic_manager;
649
650 if (!PrepareForParsing(diagnostic_manager, exe_ctx))
651 return false;
652
Raphael Isemann74829732018-08-30 17:29:37 +0000653 if (log)
654 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
655
656 //////////////////////////
657 // Parse the expression
658 //
659
660 m_materializer_ap.reset(new Materializer());
661
662 ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
663
664 OnExit on_exit([this]() { ResetDeclMap(); });
665
666 if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) {
667 diagnostic_manager.PutString(
668 eDiagnosticSeverityError,
669 "current process state is unsuitable for expression parsing");
670
671 return false;
672 }
673
674 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
675 DeclMap()->SetLookupsEnabled(true);
676 }
677
678 Process *process = exe_ctx.GetProcessPtr();
679 ExecutionContextScope *exe_scope = process;
680
681 if (!exe_scope)
682 exe_scope = exe_ctx.GetTargetPtr();
683
684 ClangExpressionParser parser(exe_scope, *this, false);
685
686 // We have to find the source code location where the user text is inside
687 // the transformed expression code. When creating the transformed text, we
688 // already stored the absolute position in the m_transformed_text string. The
689 // only thing left to do is to transform it into the line:column format that
690 // Clang expects.
691
692 // The line and column of the user expression inside the transformed source
693 // code.
694 unsigned user_expr_line, user_expr_column;
695 if (m_user_expression_start_pos.hasValue())
696 AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text,
697 user_expr_line, user_expr_column);
698 else
699 return false;
700
701 // The actual column where we have to complete is the start column of the
702 // user expression + the offset inside the user code that we were given.
703 const unsigned completion_column = user_expr_column + complete_pos;
Raphael Isemannc11a7802018-08-30 21:26:32 +0000704 parser.Complete(request, user_expr_line, completion_column, complete_pos);
Raphael Isemann74829732018-08-30 17:29:37 +0000705
706 return true;
707}
708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
710 std::vector<lldb::addr_t> &args,
711 lldb::addr_t struct_address,
712 DiagnosticManager &diagnostic_manager) {
713 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
714 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
Sean Callanan579e70c2016-03-19 00:03:59 +0000715
Kate Stoneb9c1b512016-09-06 20:57:50 +0000716 if (m_needs_object_ptr) {
717 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
718 if (!frame_sp)
719 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000720
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000722
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 if (m_in_cplusplus_method) {
724 object_name.SetCString("this");
725 } else if (m_in_objectivec_method) {
726 object_name.SetCString("self");
727 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000728 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000729 eDiagnosticSeverityError,
730 "need object pointer but don't know the language");
731 return false;
Jim Ingham51148e92015-11-05 00:24:18 +0000732 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733
Zachary Turner97206d52017-05-12 04:51:55 +0000734 Status object_ptr_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735
736 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
737
738 if (!object_ptr_error.Success()) {
739 exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
Jason Molenda599558e2017-02-21 05:09:26 +0000740 "warning: `%s' is not accessible (substituting 0)\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000741 object_name.AsCString());
742 object_ptr = 0;
Jim Ingham36f3b362010-10-14 23:45:03 +0000743 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744
745 if (m_in_objectivec_method) {
746 ConstString cmd_name("_cmd");
747
748 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
749
750 if (!object_ptr_error.Success()) {
751 diagnostic_manager.Printf(
752 eDiagnosticSeverityWarning,
753 "couldn't get cmd pointer (substituting NULL): %s",
754 object_ptr_error.AsCString());
755 cmd_ptr = 0;
756 }
757 }
758
759 args.push_back(object_ptr);
760
761 if (m_in_objectivec_method)
762 args.push_back(cmd_ptr);
763
764 args.push_back(struct_address);
765 } else {
766 args.push_back(struct_address);
767 }
768 return true;
Jim Ingham36f3b362010-10-14 23:45:03 +0000769}
770
Kate Stoneb9c1b512016-09-06 20:57:50 +0000771lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization(
772 ExecutionContextScope *exe_scope) {
773 return m_result_delegate.GetVariable();
Sean Callanan9fda9d22015-10-03 09:09:01 +0000774}
775
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
777 ExecutionContext &exe_ctx,
778 Materializer::PersistentVariableDelegate &delegate,
779 bool keep_result_in_memory) {
780 m_expr_decl_map_up.reset(
781 new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000782}
Jim Ingham36f3b362010-10-14 23:45:03 +0000783
Jim Ingham151c0322015-09-15 21:13:50 +0000784clang::ASTConsumer *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000785ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
786 clang::ASTConsumer *passthrough) {
787 m_result_synthesizer_up.reset(
788 new ASTResultSynthesizer(passthrough, m_top_level, m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000789
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000791}
792
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
794 if (m_result_synthesizer_up.get()) {
795 m_result_synthesizer_up->CommitPersistentDecls();
796 }
Sean Callanan00294b32016-03-22 21:05:51 +0000797}
798
Kate Stoneb9c1b512016-09-06 20:57:50 +0000799ConstString ClangUserExpression::ResultDelegate::GetName() {
Adrian Prantl03219f72018-04-30 23:59:17 +0000800 auto prefix = m_persistent_state->GetPersistentVariablePrefix();
801 return m_persistent_state->GetNextPersistentVariableName(*m_target_sp,
802 prefix);
Sean Callanan9fda9d22015-10-03 09:09:01 +0000803}
804
Kate Stoneb9c1b512016-09-06 20:57:50 +0000805void ClangUserExpression::ResultDelegate::DidDematerialize(
806 lldb::ExpressionVariableSP &variable) {
807 m_variable = variable;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000808}
809
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810void ClangUserExpression::ResultDelegate::RegisterPersistentState(
811 PersistentExpressionState *persistent_state) {
812 m_persistent_state = persistent_state;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000813}
814
Kate Stoneb9c1b512016-09-06 20:57:50 +0000815lldb::ExpressionVariableSP &ClangUserExpression::ResultDelegate::GetVariable() {
816 return m_variable;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000817}