blob: bc725c9af16bbe78e8d201be545b95df8849c614 [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,
Aleksandr Urakov40624a02019-02-05 09:14:36 +000062 ResultType desired_type, const EvaluateExpressionOptions &options,
63 ValueObject *ctx_obj)
Zachary Turnerc5d7df92016-11-08 04:52:16 +000064 : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 options),
Jonas Devlieghere70355ac2019-02-12 03:47:39 +000066 m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() ==
67 eExecutionPolicyTopLevel),
68 m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) {
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
Aleksandr Urakov40624a02019-02-05 09:14:36 +0000133 if (m_ctx_obj) {
134 switch (m_ctx_obj->GetObjectRuntimeLanguage()) {
135 case lldb::eLanguageTypeC:
136 case lldb::eLanguageTypeC89:
137 case lldb::eLanguageTypeC99:
138 case lldb::eLanguageTypeC11:
139 case lldb::eLanguageTypeC_plus_plus:
140 case lldb::eLanguageTypeC_plus_plus_03:
141 case lldb::eLanguageTypeC_plus_plus_11:
142 case lldb::eLanguageTypeC_plus_plus_14:
143 m_in_cplusplus_method = true;
144 break;
145 case lldb::eLanguageTypeObjC:
146 case lldb::eLanguageTypeObjC_plus_plus:
147 m_in_objectivec_method = true;
148 break;
149 default:
150 break;
151 }
152 m_needs_object_ptr = true;
153 } else if (clang::CXXMethodDecl *method_decl =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
155 if (m_allow_cxx && method_decl->isInstance()) {
156 if (m_enforce_valid_object) {
157 lldb::VariableListSP variable_list_sp(
158 function_block->GetBlockVariableList(true));
Greg Clayton685c88c2012-07-14 00:53:55 +0000159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160 const char *thisErrorString = "Stopped in a C++ method, but 'this' "
161 "isn't available; pretending we are in a "
162 "generic context";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 if (!variable_list_sp) {
165 err.SetErrorString(thisErrorString);
166 return;
Sean Callanan3670ba52010-12-01 21:35:54 +0000167 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168
169 lldb::VariableSP this_var_sp(
170 variable_list_sp->FindVariable(ConstString("this")));
171
172 if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
173 !this_var_sp->LocationIsValidForFrame(frame)) {
174 err.SetErrorString(thisErrorString);
175 return;
176 }
177 }
178
179 m_in_cplusplus_method = true;
180 m_needs_object_ptr = true;
Sean Callanan3670ba52010-12-01 21:35:54 +0000181 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 } else if (clang::ObjCMethodDecl *method_decl =
183 ClangASTContext::DeclContextGetAsObjCMethodDecl(
184 decl_context)) {
185 if (m_allow_objc) {
186 if (m_enforce_valid_object) {
187 lldb::VariableListSP variable_list_sp(
188 function_block->GetBlockVariableList(true));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 const char *selfErrorString = "Stopped in an Objective-C method, but "
191 "'self' isn't available; pretending we "
192 "are in a generic context";
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 if (!variable_list_sp) {
195 err.SetErrorString(selfErrorString);
196 return;
197 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 lldb::VariableSP self_variable_sp =
200 variable_list_sp->FindVariable(ConstString("self"));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
203 !self_variable_sp->LocationIsValidForFrame(frame)) {
204 err.SetErrorString(selfErrorString);
205 return;
206 }
207 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 m_in_objectivec_method = true;
210 m_needs_object_ptr = true;
211
212 if (!method_decl->isInstanceMethod())
213 m_in_static_method = true;
214 }
215 } else if (clang::FunctionDecl *function_decl =
216 ClangASTContext::DeclContextGetAsFunctionDecl(decl_context)) {
217 // We might also have a function that said in the debug information that it
Adrian Prantl05097242018-04-30 16:49:04 +0000218 // captured an object pointer. The best way to deal with getting to the
219 // ivars at present is by pretending that this is a method of a class in
220 // whatever runtime the debug info says the object pointer belongs to. Do
221 // that here.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222
223 ClangASTMetadata *metadata =
224 ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
225 if (metadata && metadata->HasObjectPtr()) {
226 lldb::LanguageType language = metadata->GetObjectPtrLanguage();
227 if (language == lldb::eLanguageTypeC_plus_plus) {
228 if (m_enforce_valid_object) {
229 lldb::VariableListSP variable_list_sp(
230 function_block->GetBlockVariableList(true));
231
232 const char *thisErrorString = "Stopped in a context claiming to "
233 "capture a C++ object pointer, but "
234 "'this' isn't available; pretending we "
235 "are in a generic context";
236
237 if (!variable_list_sp) {
238 err.SetErrorString(thisErrorString);
239 return;
240 }
241
242 lldb::VariableSP this_var_sp(
243 variable_list_sp->FindVariable(ConstString("this")));
244
245 if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
246 !this_var_sp->LocationIsValidForFrame(frame)) {
247 err.SetErrorString(thisErrorString);
248 return;
249 }
250 }
251
252 m_in_cplusplus_method = true;
253 m_needs_object_ptr = true;
254 } else if (language == lldb::eLanguageTypeObjC) {
255 if (m_enforce_valid_object) {
256 lldb::VariableListSP variable_list_sp(
257 function_block->GetBlockVariableList(true));
258
259 const char *selfErrorString =
260 "Stopped in a context claiming to capture an Objective-C object "
261 "pointer, but 'self' isn't available; pretending we are in a "
262 "generic context";
263
264 if (!variable_list_sp) {
265 err.SetErrorString(selfErrorString);
266 return;
267 }
268
269 lldb::VariableSP self_variable_sp =
270 variable_list_sp->FindVariable(ConstString("self"));
271
272 if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
273 !self_variable_sp->LocationIsValidForFrame(frame)) {
274 err.SetErrorString(selfErrorString);
275 return;
276 }
277
278 Type *self_type = self_variable_sp->GetType();
279
280 if (!self_type) {
281 err.SetErrorString(selfErrorString);
282 return;
283 }
284
285 CompilerType self_clang_type = self_type->GetForwardCompilerType();
286
287 if (!self_clang_type) {
288 err.SetErrorString(selfErrorString);
289 return;
290 }
291
292 if (ClangASTContext::IsObjCClassType(self_clang_type)) {
293 return;
294 } else if (ClangASTContext::IsObjCObjectPointerType(
295 self_clang_type)) {
Dawn Perchik53f34c82015-07-01 00:54:02 +0000296 m_in_objectivec_method = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000297 m_needs_object_ptr = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 } else {
299 err.SetErrorString(selfErrorString);
300 return;
301 }
302 } else {
303 m_in_objectivec_method = true;
304 m_needs_object_ptr = true;
Sean Callanan9bc83842011-09-26 18:45:31 +0000305 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000306 }
Sean Callanan3670ba52010-12-01 21:35:54 +0000307 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000308 }
Sean Callananfc55f5d2010-09-21 00:44:12 +0000309}
310
Adrian Prantl05097242018-04-30 16:49:04 +0000311// This is a really nasty hack, meant to fix Objective-C expressions of the
312// form (int)[myArray count]. Right now, because the type information for
313// count is not available, [myArray count] returns id, which can't be directly
314// cast to int without causing a clang error.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315static void ApplyObjcCastHack(std::string &expr) {
Sean Callanancf5498f2010-10-22 23:25:16 +0000316#define OBJC_CAST_HACK_FROM "(int)["
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317#define OBJC_CAST_HACK_TO "(int)(long long)["
Sean Callanancf5498f2010-10-22 23:25:16 +0000318
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 size_t from_offset;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000320
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321 while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
322 expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1,
323 OBJC_CAST_HACK_TO);
Sean Callanancf5498f2010-10-22 23:25:16 +0000324
325#undef OBJC_CAST_HACK_TO
326#undef OBJC_CAST_HACK_FROM
327}
328
Raphael Isemann12468902018-06-19 21:25:59 +0000329namespace {
330// Utility guard that calls a callback when going out of scope.
331class OnExit {
332public:
333 typedef std::function<void(void)> Callback;
334
335 OnExit(Callback const &callback) : m_callback(callback) {}
336
337 ~OnExit() { m_callback(); }
338
339private:
340 Callback m_callback;
341};
342} // namespace
343
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000344bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
345 ExecutionContext &exe_ctx) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 if (Target *target = exe_ctx.GetTargetPtr()) {
347 if (PersistentExpressionState *persistent_state =
348 target->GetPersistentExpressionStateForLanguage(
349 lldb::eLanguageTypeC)) {
350 m_result_delegate.RegisterPersistentState(persistent_state);
351 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000352 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 eDiagnosticSeverityError,
354 "couldn't start parsing (no persistent data)");
355 return false;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000356 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000358 diagnostic_manager.PutString(eDiagnosticSeverityError,
359 "error: couldn't start parsing (no target)");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 return false;
361 }
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000362 return true;
363}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000365static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000366 if (ClangModulesDeclVendor *decl_vendor =
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000367 target->GetClangModulesDeclVendor()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
369 llvm::cast<ClangPersistentVariables>(
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000370 target->GetPersistentExpressionStateForLanguage(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000371 lldb::eLanguageTypeC))
372 ->GetHandLoadedClangModules();
373 ClangModulesDeclVendor::ModuleVector modules_for_macros;
374
375 for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
376 modules_for_macros.push_back(module);
377 }
378
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000379 if (target->GetEnableAutoImportClangModules()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380 if (StackFrame *frame = exe_ctx.GetFramePtr()) {
381 if (Block *block = frame->GetFrameBlock()) {
382 SymbolContext sc;
383
384 block->CalculateSymbolContext(&sc);
385
386 if (sc.comp_unit) {
387 StreamString error_stream;
388
389 decl_vendor->AddModulesForCompileUnit(
390 *sc.comp_unit, modules_for_macros, error_stream);
391 }
392 }
393 }
394 }
395 }
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000396}
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397
Raphael Isemanndababf72018-09-27 10:12:54 +0000398void ClangUserExpression::UpdateLanguageForExpr(
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000399 DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
Raphael Isemanndababf72018-09-27 10:12:54 +0000400 m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000401
402 std::string prefix = m_expr_prefix;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403
404 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
405 m_transformed_text = m_expr_text;
406 } else {
407 std::unique_ptr<ExpressionSourceCode> source_code(
408 ExpressionSourceCode::CreateWrapped(prefix.c_str(),
409 m_expr_text.c_str()));
410
411 if (m_in_cplusplus_method)
Raphael Isemanndababf72018-09-27 10:12:54 +0000412 m_expr_lang = lldb::eLanguageTypeC_plus_plus;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 else if (m_in_objectivec_method)
Raphael Isemanndababf72018-09-27 10:12:54 +0000414 m_expr_lang = lldb::eLanguageTypeObjC;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000415 else
Raphael Isemanndababf72018-09-27 10:12:54 +0000416 m_expr_lang = lldb::eLanguageTypeC;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417
Raphael Isemanndababf72018-09-27 10:12:54 +0000418 if (!source_code->GetText(m_transformed_text, m_expr_lang,
Aleksandr Urakov40624a02019-02-05 09:14:36 +0000419 m_in_static_method, exe_ctx,
420 !m_ctx_obj)) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000421 diagnostic_manager.PutString(eDiagnosticSeverityError,
422 "couldn't construct expression body");
Raphael Isemanndababf72018-09-27 10:12:54 +0000423 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424 }
Raphael Isemann74829732018-08-30 17:29:37 +0000425
426 // Find and store the start position of the original code inside the
427 // transformed code. We need this later for the code completion.
428 std::size_t original_start;
429 std::size_t original_end;
430 bool found_bounds = source_code->GetOriginalBodyBounds(
Raphael Isemanndababf72018-09-27 10:12:54 +0000431 m_transformed_text, m_expr_lang, original_start, original_end);
Raphael Isemann74829732018-08-30 17:29:37 +0000432 if (found_bounds) {
433 m_user_expression_start_pos = original_start;
434 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 }
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000436}
437
438bool ClangUserExpression::PrepareForParsing(
439 DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
440 InstallContext(exe_ctx);
441
442 if (!SetupPersistentState(diagnostic_manager, exe_ctx))
443 return false;
444
445 Status err;
446 ScanContext(exe_ctx, err);
447
448 if (!err.Success()) {
449 diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
450 }
451
452 ////////////////////////////////////
453 // Generate the expression
454 //
455
456 ApplyObjcCastHack(m_expr_text);
457
458 SetupDeclVendor(exe_ctx, m_target);
Raphael Isemanndababf72018-09-27 10:12:54 +0000459
460 UpdateLanguageForExpr(diagnostic_manager, exe_ctx);
Raphael Isemannba800e7d2018-07-10 22:12:39 +0000461 return true;
462}
463
464bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
465 ExecutionContext &exe_ctx,
466 lldb_private::ExecutionPolicy execution_policy,
467 bool keep_result_in_memory,
468 bool generate_debug_info) {
469 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
470
471 if (!PrepareForParsing(diagnostic_manager, exe_ctx))
472 return false;
473
Kate Stoneb9c1b512016-09-06 20:57:50 +0000474 if (log)
475 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
476
477 ////////////////////////////////////
478 // Set up the target and compiler
479 //
480
481 Target *target = exe_ctx.GetTargetPtr();
482
483 if (!target) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000484 diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485 return false;
486 }
487
488 //////////////////////////
489 // Parse the expression
490 //
491
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000492 m_materializer_up.reset(new Materializer());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493
494 ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496 OnExit on_exit([this]() { ResetDeclMap(); });
497
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000498 if (!DeclMap()->WillParse(exe_ctx, m_materializer_up.get())) {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000499 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000500 eDiagnosticSeverityError,
501 "current process state is unsuitable for expression parsing");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502 return false;
503 }
504
505 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
506 DeclMap()->SetLookupsEnabled(true);
507 }
508
509 Process *process = exe_ctx.GetProcessPtr();
510 ExecutionContextScope *exe_scope = process;
511
512 if (!exe_scope)
513 exe_scope = exe_ctx.GetTargetPtr();
514
515 // We use a shared pointer here so we can use the original parser - if it
Adrian Prantl05097242018-04-30 16:49:04 +0000516 // succeeds or the rewrite parser we might make if it fails. But the
517 // parser_sp will never be empty.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518
519 ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
520
521 unsigned num_errors = parser.Parse(diagnostic_manager);
522
523 // Check here for FixItHints. If there are any try to apply the fixits and
Adrian Prantl05097242018-04-30 16:49:04 +0000524 // set the fixed text in m_fixed_text before returning an error.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 if (num_errors) {
526 if (diagnostic_manager.HasFixIts()) {
527 if (parser.RewriteExpression(diagnostic_manager)) {
528 size_t fixed_start;
529 size_t fixed_end;
530 const std::string &fixed_expression =
531 diagnostic_manager.GetFixedExpression();
532 if (ExpressionSourceCode::GetOriginalBodyBounds(
Raphael Isemanndababf72018-09-27 10:12:54 +0000533 fixed_expression, m_expr_lang, fixed_start, fixed_end))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534 m_fixed_text =
535 fixed_expression.substr(fixed_start, fixed_end - fixed_start);
536 }
Sean Callanan9fda9d22015-10-03 09:09:01 +0000537 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000538 return false;
539 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000540
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 //////////////////////////////////////////////////////////////////////////////////////////
Adrian Prantl05097242018-04-30 16:49:04 +0000542 // Prepare the output of the parser for execution, evaluating it statically
543 // if possible
Kate Stoneb9c1b512016-09-06 20:57:50 +0000544 //
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546 {
Zachary Turner97206d52017-05-12 04:51:55 +0000547 Status jit_error = parser.PrepareForExecution(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000548 m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
549 m_can_interpret, execution_policy);
Sean Callananfc55f5d2010-09-21 00:44:12 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 if (!jit_error.Success()) {
552 const char *error_cstr = jit_error.AsCString();
553 if (error_cstr && error_cstr[0])
Zachary Turnere2411fa2016-11-12 19:12:56 +0000554 diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 else
Zachary Turnere2411fa2016-11-12 19:12:56 +0000556 diagnostic_manager.PutString(eDiagnosticSeverityError,
557 "expression can't be interpreted or run");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558 return false;
559 }
560 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000561
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
Zachary Turner97206d52017-05-12 04:51:55 +0000563 Status static_init_error =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564 parser.RunStaticInitializers(m_execution_unit_sp, exe_ctx);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000565
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 if (!static_init_error.Success()) {
567 const char *error_cstr = static_init_error.AsCString();
568 if (error_cstr && error_cstr[0])
569 diagnostic_manager.Printf(eDiagnosticSeverityError,
570 "couldn't run static initializers: %s\n",
571 error_cstr);
572 else
Zachary Turnere2411fa2016-11-12 19:12:56 +0000573 diagnostic_manager.PutString(eDiagnosticSeverityError,
574 "couldn't run static initializers\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 return false;
576 }
577 }
578
579 if (m_execution_unit_sp) {
580 bool register_execution_unit = false;
581
582 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
583 register_execution_unit = true;
Sean Callananb9951192011-08-01 18:18:33 +0000584 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000585
Adrian Prantl05097242018-04-30 16:49:04 +0000586 // If there is more than one external function in the execution unit, it
587 // needs to keep living even if it's not top level, because the result
588 // could refer to that function.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589
590 if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
591 register_execution_unit = true;
Sean Callanan00294b32016-03-22 21:05:51 +0000592 }
593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 if (register_execution_unit) {
595 llvm::cast<PersistentExpressionState>(
596 exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
597 m_language))
598 ->RegisterExecutionUnit(m_execution_unit_sp);
Sean Callanan1a8d4092010-08-27 01:01:44 +0000599 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000600 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000601
Kate Stoneb9c1b512016-09-06 20:57:50 +0000602 if (generate_debug_info) {
603 lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 if (jit_module_sp) {
606 ConstString const_func_name(FunctionName());
607 FileSpec jit_file;
608 jit_file.GetFilename() = const_func_name;
609 jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
610 m_jit_module_wp = jit_module_sp;
611 target->GetImages().Append(jit_module_sp);
Sean Callanan00294b32016-03-22 21:05:51 +0000612 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 }
Sean Callanan00294b32016-03-22 21:05:51 +0000614
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615 if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
616 m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
617 return true;
Sean Callanan1a8d4092010-08-27 01:01:44 +0000618}
619
Raphael Isemann74829732018-08-30 17:29:37 +0000620//------------------------------------------------------------------
621/// Converts an absolute position inside a given code string into
622/// a column/line pair.
623///
624/// @param[in] abs_pos
625/// A absolute position in the code string that we want to convert
626/// to a column/line pair.
627///
628/// @param[in] code
629/// A multi-line string usually representing source code.
630///
631/// @param[out] line
632/// The line in the code that contains the given absolute position.
633/// The first line in the string is indexed as 1.
634///
635/// @param[out] column
636/// The column in the line that contains the absolute position.
637/// The first character in a line is indexed as 0.
638//------------------------------------------------------------------
Raphael Isemannbfc5ef62018-09-22 13:33:08 +0000639static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code,
Raphael Isemann74829732018-08-30 17:29:37 +0000640 unsigned &line, unsigned &column) {
641 // Reset to code position to beginning of the file.
642 line = 0;
643 column = 0;
644
645 assert(abs_pos <= code.size() && "Absolute position outside code string?");
646
647 // We have to walk up to the position and count lines/columns.
648 for (std::size_t i = 0; i < abs_pos; ++i) {
649 // If we hit a line break, we go back to column 0 and enter a new line.
650 // We only handle \n because that's what we internally use to make new
651 // lines for our temporary code strings.
652 if (code[i] == '\n') {
653 ++line;
654 column = 0;
655 continue;
656 }
657 ++column;
658 }
659}
660
661bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
Raphael Isemannc11a7802018-08-30 21:26:32 +0000662 CompletionRequest &request,
663 unsigned complete_pos) {
Raphael Isemann74829732018-08-30 17:29:37 +0000664 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
665
666 // We don't want any visible feedback when completing an expression. Mostly
667 // because the results we get from an incomplete invocation are probably not
668 // correct.
669 DiagnosticManager diagnostic_manager;
670
671 if (!PrepareForParsing(diagnostic_manager, exe_ctx))
672 return false;
673
Raphael Isemann74829732018-08-30 17:29:37 +0000674 if (log)
675 log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
676
677 //////////////////////////
678 // Parse the expression
679 //
680
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000681 m_materializer_up.reset(new Materializer());
Raphael Isemann74829732018-08-30 17:29:37 +0000682
683 ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
684
685 OnExit on_exit([this]() { ResetDeclMap(); });
686
Jonas Devlieghered5b44032019-02-13 06:25:41 +0000687 if (!DeclMap()->WillParse(exe_ctx, m_materializer_up.get())) {
Raphael Isemann74829732018-08-30 17:29:37 +0000688 diagnostic_manager.PutString(
689 eDiagnosticSeverityError,
690 "current process state is unsuitable for expression parsing");
691
692 return false;
693 }
694
695 if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
696 DeclMap()->SetLookupsEnabled(true);
697 }
698
699 Process *process = exe_ctx.GetProcessPtr();
700 ExecutionContextScope *exe_scope = process;
701
702 if (!exe_scope)
703 exe_scope = exe_ctx.GetTargetPtr();
704
705 ClangExpressionParser parser(exe_scope, *this, false);
706
707 // We have to find the source code location where the user text is inside
708 // the transformed expression code. When creating the transformed text, we
709 // already stored the absolute position in the m_transformed_text string. The
710 // only thing left to do is to transform it into the line:column format that
711 // Clang expects.
712
713 // The line and column of the user expression inside the transformed source
714 // code.
715 unsigned user_expr_line, user_expr_column;
716 if (m_user_expression_start_pos.hasValue())
717 AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text,
718 user_expr_line, user_expr_column);
719 else
720 return false;
721
722 // The actual column where we have to complete is the start column of the
723 // user expression + the offset inside the user code that we were given.
724 const unsigned completion_column = user_expr_column + complete_pos;
Raphael Isemannc11a7802018-08-30 21:26:32 +0000725 parser.Complete(request, user_expr_line, completion_column, complete_pos);
Raphael Isemann74829732018-08-30 17:29:37 +0000726
727 return true;
728}
729
Kate Stoneb9c1b512016-09-06 20:57:50 +0000730bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
731 std::vector<lldb::addr_t> &args,
732 lldb::addr_t struct_address,
733 DiagnosticManager &diagnostic_manager) {
734 lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
735 lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
Sean Callanan579e70c2016-03-19 00:03:59 +0000736
Kate Stoneb9c1b512016-09-06 20:57:50 +0000737 if (m_needs_object_ptr) {
738 lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
739 if (!frame_sp)
740 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000741
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 ConstString object_name;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000743
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744 if (m_in_cplusplus_method) {
745 object_name.SetCString("this");
746 } else if (m_in_objectivec_method) {
747 object_name.SetCString("self");
748 } else {
Zachary Turnere2411fa2016-11-12 19:12:56 +0000749 diagnostic_manager.PutString(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750 eDiagnosticSeverityError,
751 "need object pointer but don't know the language");
752 return false;
Jim Ingham51148e92015-11-05 00:24:18 +0000753 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754
Zachary Turner97206d52017-05-12 04:51:55 +0000755 Status object_ptr_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000756
Aleksandr Urakov40624a02019-02-05 09:14:36 +0000757 if (m_ctx_obj) {
758 AddressType address_type;
759 object_ptr = m_ctx_obj->GetAddressOf(false, &address_type);
760 if (object_ptr == LLDB_INVALID_ADDRESS ||
761 address_type != eAddressTypeLoad)
762 object_ptr_error.SetErrorString("Can't get context object's "
763 "debuggee address");
764 } else
765 object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000766
767 if (!object_ptr_error.Success()) {
768 exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
Jason Molenda599558e2017-02-21 05:09:26 +0000769 "warning: `%s' is not accessible (substituting 0)\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 object_name.AsCString());
771 object_ptr = 0;
Jim Ingham36f3b362010-10-14 23:45:03 +0000772 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773
774 if (m_in_objectivec_method) {
775 ConstString cmd_name("_cmd");
776
777 cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
778
779 if (!object_ptr_error.Success()) {
780 diagnostic_manager.Printf(
781 eDiagnosticSeverityWarning,
782 "couldn't get cmd pointer (substituting NULL): %s",
783 object_ptr_error.AsCString());
784 cmd_ptr = 0;
785 }
786 }
787
788 args.push_back(object_ptr);
789
790 if (m_in_objectivec_method)
791 args.push_back(cmd_ptr);
792
793 args.push_back(struct_address);
794 } else {
795 args.push_back(struct_address);
796 }
797 return true;
Jim Ingham36f3b362010-10-14 23:45:03 +0000798}
799
Kate Stoneb9c1b512016-09-06 20:57:50 +0000800lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization(
801 ExecutionContextScope *exe_scope) {
802 return m_result_delegate.GetVariable();
Sean Callanan9fda9d22015-10-03 09:09:01 +0000803}
804
Kate Stoneb9c1b512016-09-06 20:57:50 +0000805void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
806 ExecutionContext &exe_ctx,
807 Materializer::PersistentVariableDelegate &delegate,
Aleksandr Urakov40624a02019-02-05 09:14:36 +0000808 bool keep_result_in_memory,
809 ValueObject *ctx_obj) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 m_expr_decl_map_up.reset(
Aleksandr Urakov40624a02019-02-05 09:14:36 +0000811 new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx,
812 ctx_obj));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000813}
Jim Ingham36f3b362010-10-14 23:45:03 +0000814
Jim Ingham151c0322015-09-15 21:13:50 +0000815clang::ASTConsumer *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
817 clang::ASTConsumer *passthrough) {
818 m_result_synthesizer_up.reset(
819 new ASTResultSynthesizer(passthrough, m_top_level, m_target));
Sean Callananc673a6e2010-12-07 10:00:20 +0000820
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 return m_result_synthesizer_up.get();
Sean Callanan1a8d4092010-08-27 01:01:44 +0000822}
823
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000825 if (m_result_synthesizer_up) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 m_result_synthesizer_up->CommitPersistentDecls();
827 }
Sean Callanan00294b32016-03-22 21:05:51 +0000828}
829
Kate Stoneb9c1b512016-09-06 20:57:50 +0000830ConstString ClangUserExpression::ResultDelegate::GetName() {
Adrian Prantl03219f72018-04-30 23:59:17 +0000831 auto prefix = m_persistent_state->GetPersistentVariablePrefix();
832 return m_persistent_state->GetNextPersistentVariableName(*m_target_sp,
833 prefix);
Sean Callanan9fda9d22015-10-03 09:09:01 +0000834}
835
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836void ClangUserExpression::ResultDelegate::DidDematerialize(
837 lldb::ExpressionVariableSP &variable) {
838 m_variable = variable;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000839}
840
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841void ClangUserExpression::ResultDelegate::RegisterPersistentState(
842 PersistentExpressionState *persistent_state) {
843 m_persistent_state = persistent_state;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000844}
845
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846lldb::ExpressionVariableSP &ClangUserExpression::ResultDelegate::GetVariable() {
847 return m_variable;
Sean Callanan9fda9d22015-10-03 09:09:01 +0000848}