xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- ClangUserExpression.cpp -------------------------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cstdio>
10 #include <sys/types.h>
11 
12 #include <cstdlib>
13 #include <map>
14 #include <string>
15 
16 #include "ClangUserExpression.h"
17 
18 #include "ASTResultSynthesizer.h"
19 #include "ClangASTMetadata.h"
20 #include "ClangDiagnostic.h"
21 #include "ClangExpressionDeclMap.h"
22 #include "ClangExpressionParser.h"
23 #include "ClangModulesDeclVendor.h"
24 #include "ClangPersistentVariables.h"
25 #include "CppModuleConfiguration.h"
26 
27 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
28 #include "lldb/Core/Debugger.h"
29 #include "lldb/Core/Module.h"
30 #include "lldb/Core/ValueObjectConstResult.h"
31 #include "lldb/Expression/ExpressionSourceCode.h"
32 #include "lldb/Expression/IRExecutionUnit.h"
33 #include "lldb/Expression/IRInterpreter.h"
34 #include "lldb/Expression/Materializer.h"
35 #include "lldb/Host/HostInfo.h"
36 #include "lldb/Symbol/Block.h"
37 #include "lldb/Symbol/CompileUnit.h"
38 #include "lldb/Symbol/Function.h"
39 #include "lldb/Symbol/ObjectFile.h"
40 #include "lldb/Symbol/SymbolFile.h"
41 #include "lldb/Symbol/SymbolVendor.h"
42 #include "lldb/Symbol/Type.h"
43 #include "lldb/Symbol/VariableList.h"
44 #include "lldb/Target/ExecutionContext.h"
45 #include "lldb/Target/Process.h"
46 #include "lldb/Target/StackFrame.h"
47 #include "lldb/Target/Target.h"
48 #include "lldb/Target/ThreadPlan.h"
49 #include "lldb/Target/ThreadPlanCallUserExpression.h"
50 #include "lldb/Utility/ConstString.h"
51 #include "lldb/Utility/LLDBLog.h"
52 #include "lldb/Utility/Log.h"
53 #include "lldb/Utility/StreamString.h"
54 
55 #include "clang/AST/DeclCXX.h"
56 #include "clang/AST/DeclObjC.h"
57 
58 #include "llvm/ADT/ScopeExit.h"
59 #include "llvm/BinaryFormat/Dwarf.h"
60 
61 using namespace lldb_private;
62 
63 char ClangUserExpression::ID;
64 
ClangUserExpression(ExecutionContextScope & exe_scope,llvm::StringRef expr,llvm::StringRef prefix,SourceLanguage language,ResultType desired_type,const EvaluateExpressionOptions & options,ValueObject * ctx_obj)65 ClangUserExpression::ClangUserExpression(
66     ExecutionContextScope &exe_scope, llvm::StringRef expr,
67     llvm::StringRef prefix, SourceLanguage language, ResultType desired_type,
68     const EvaluateExpressionOptions &options, ValueObject *ctx_obj)
69     : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
70                          options),
71       m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() ==
72                                                     eExecutionPolicyTopLevel),
73       m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) {
74   switch (m_language.name) {
75   case llvm::dwarf::DW_LNAME_C_plus_plus:
76     m_allow_cxx = true;
77     break;
78   case llvm::dwarf::DW_LNAME_ObjC:
79     m_allow_objc = true;
80     break;
81   case llvm::dwarf::DW_LNAME_ObjC_plus_plus:
82   default:
83     m_allow_cxx = true;
84     m_allow_objc = true;
85     break;
86   }
87 }
88 
89 ClangUserExpression::~ClangUserExpression() = default;
90 
ScanContext(ExecutionContext & exe_ctx,Status & err)91 void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
92   Log *log = GetLog(LLDBLog::Expressions);
93 
94   LLDB_LOGF(log, "ClangUserExpression::ScanContext()");
95 
96   m_target = exe_ctx.GetTargetPtr();
97 
98   if (!(m_allow_cxx || m_allow_objc)) {
99     LLDB_LOGF(log, "  [CUE::SC] Settings inhibit C++ and Objective-C");
100     return;
101   }
102 
103   StackFrame *frame = exe_ctx.GetFramePtr();
104   if (frame == nullptr) {
105     LLDB_LOGF(log, "  [CUE::SC] Null stack frame");
106     return;
107   }
108 
109   SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
110                                                   lldb::eSymbolContextBlock);
111 
112   if (!sym_ctx.function) {
113     LLDB_LOGF(log, "  [CUE::SC] Null function");
114     return;
115   }
116 
117   // Find the block that defines the function represented by "sym_ctx"
118   Block *function_block = sym_ctx.GetFunctionBlock();
119 
120   if (!function_block) {
121     LLDB_LOGF(log, "  [CUE::SC] Null function block");
122     return;
123   }
124 
125   CompilerDeclContext decl_context = function_block->GetDeclContext();
126 
127   if (!decl_context) {
128     LLDB_LOGF(log, "  [CUE::SC] Null decl context");
129     return;
130   }
131 
132   if (m_ctx_obj) {
133     switch (m_ctx_obj->GetObjectRuntimeLanguage()) {
134     case lldb::eLanguageTypeC:
135     case lldb::eLanguageTypeC89:
136     case lldb::eLanguageTypeC99:
137     case lldb::eLanguageTypeC11:
138     case lldb::eLanguageTypeC_plus_plus:
139     case lldb::eLanguageTypeC_plus_plus_03:
140     case lldb::eLanguageTypeC_plus_plus_11:
141     case lldb::eLanguageTypeC_plus_plus_14:
142       m_in_cplusplus_method = true;
143       break;
144     case lldb::eLanguageTypeObjC:
145     case lldb::eLanguageTypeObjC_plus_plus:
146       m_in_objectivec_method = true;
147       break;
148     default:
149       break;
150     }
151     m_needs_object_ptr = true;
152   } else if (clang::CXXMethodDecl *method_decl =
153           TypeSystemClang::DeclContextGetAsCXXMethodDecl(decl_context)) {
154     if (m_allow_cxx && method_decl->isInstance()) {
155       if (m_enforce_valid_object) {
156         lldb::VariableListSP variable_list_sp(
157             function_block->GetBlockVariableList(true));
158 
159         const char *thisErrorString = "Stopped in a C++ method, but 'this' "
160                                       "isn't available; pretending we are in a "
161                                       "generic context";
162 
163         if (!variable_list_sp) {
164           err.SetErrorString(thisErrorString);
165           return;
166         }
167 
168         lldb::VariableSP this_var_sp(
169             variable_list_sp->FindVariable(ConstString("this")));
170 
171         if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
172             !this_var_sp->LocationIsValidForFrame(frame)) {
173           err.SetErrorString(thisErrorString);
174           return;
175         }
176       }
177 
178       m_in_cplusplus_method = true;
179       m_needs_object_ptr = true;
180     }
181   } else if (clang::ObjCMethodDecl *method_decl =
182                  TypeSystemClang::DeclContextGetAsObjCMethodDecl(
183                      decl_context)) {
184     if (m_allow_objc) {
185       if (m_enforce_valid_object) {
186         lldb::VariableListSP variable_list_sp(
187             function_block->GetBlockVariableList(true));
188 
189         const char *selfErrorString = "Stopped in an Objective-C method, but "
190                                       "'self' isn't available; pretending we "
191                                       "are in a generic context";
192 
193         if (!variable_list_sp) {
194           err.SetErrorString(selfErrorString);
195           return;
196         }
197 
198         lldb::VariableSP self_variable_sp =
199             variable_list_sp->FindVariable(ConstString("self"));
200 
201         if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
202             !self_variable_sp->LocationIsValidForFrame(frame)) {
203           err.SetErrorString(selfErrorString);
204           return;
205         }
206       }
207 
208       m_in_objectivec_method = true;
209       m_needs_object_ptr = true;
210 
211       if (!method_decl->isInstanceMethod())
212         m_in_static_method = true;
213     }
214   } else if (clang::FunctionDecl *function_decl =
215                  TypeSystemClang::DeclContextGetAsFunctionDecl(decl_context)) {
216     // We might also have a function that said in the debug information that it
217     // captured an object pointer.  The best way to deal with getting to the
218     // ivars at present is by pretending that this is a method of a class in
219     // whatever runtime the debug info says the object pointer belongs to.  Do
220     // that here.
221 
222     ClangASTMetadata *metadata =
223         TypeSystemClang::DeclContextGetMetaData(decl_context, function_decl);
224     if (metadata && metadata->HasObjectPtr()) {
225       lldb::LanguageType language = metadata->GetObjectPtrLanguage();
226       if (language == lldb::eLanguageTypeC_plus_plus) {
227         if (m_enforce_valid_object) {
228           lldb::VariableListSP variable_list_sp(
229               function_block->GetBlockVariableList(true));
230 
231           const char *thisErrorString = "Stopped in a context claiming to "
232                                         "capture a C++ object pointer, but "
233                                         "'this' isn't available; pretending we "
234                                         "are in a generic context";
235 
236           if (!variable_list_sp) {
237             err.SetErrorString(thisErrorString);
238             return;
239           }
240 
241           lldb::VariableSP this_var_sp(
242               variable_list_sp->FindVariable(ConstString("this")));
243 
244           if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
245               !this_var_sp->LocationIsValidForFrame(frame)) {
246             err.SetErrorString(thisErrorString);
247             return;
248           }
249         }
250 
251         m_in_cplusplus_method = true;
252         m_needs_object_ptr = true;
253       } else if (language == lldb::eLanguageTypeObjC) {
254         if (m_enforce_valid_object) {
255           lldb::VariableListSP variable_list_sp(
256               function_block->GetBlockVariableList(true));
257 
258           const char *selfErrorString =
259               "Stopped in a context claiming to capture an Objective-C object "
260               "pointer, but 'self' isn't available; pretending we are in a "
261               "generic context";
262 
263           if (!variable_list_sp) {
264             err.SetErrorString(selfErrorString);
265             return;
266           }
267 
268           lldb::VariableSP self_variable_sp =
269               variable_list_sp->FindVariable(ConstString("self"));
270 
271           if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
272               !self_variable_sp->LocationIsValidForFrame(frame)) {
273             err.SetErrorString(selfErrorString);
274             return;
275           }
276 
277           Type *self_type = self_variable_sp->GetType();
278 
279           if (!self_type) {
280             err.SetErrorString(selfErrorString);
281             return;
282           }
283 
284           CompilerType self_clang_type = self_type->GetForwardCompilerType();
285 
286           if (!self_clang_type) {
287             err.SetErrorString(selfErrorString);
288             return;
289           }
290 
291           if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
292             return;
293           } else if (TypeSystemClang::IsObjCObjectPointerType(
294                          self_clang_type)) {
295             m_in_objectivec_method = true;
296             m_needs_object_ptr = true;
297           } else {
298             err.SetErrorString(selfErrorString);
299             return;
300           }
301         } else {
302           m_in_objectivec_method = true;
303           m_needs_object_ptr = true;
304         }
305       }
306     }
307   }
308 }
309 
310 // This is a really nasty hack, meant to fix Objective-C expressions of the
311 // form (int)[myArray count].  Right now, because the type information for
312 // count is not available, [myArray count] returns id, which can't be directly
313 // cast to int without causing a clang error.
ApplyObjcCastHack(std::string & expr)314 static void ApplyObjcCastHack(std::string &expr) {
315   const std::string from = "(int)[";
316   const std::string to = "(int)(long long)[";
317 
318   size_t offset;
319 
320   while ((offset = expr.find(from)) != expr.npos)
321     expr.replace(offset, from.size(), to);
322 }
323 
SetupPersistentState(DiagnosticManager & diagnostic_manager,ExecutionContext & exe_ctx)324 bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
325                                  ExecutionContext &exe_ctx) {
326   if (Target *target = exe_ctx.GetTargetPtr()) {
327     if (PersistentExpressionState *persistent_state =
328             target->GetPersistentExpressionStateForLanguage(
329                 lldb::eLanguageTypeC)) {
330       m_clang_state = llvm::cast<ClangPersistentVariables>(persistent_state);
331       m_result_delegate.RegisterPersistentState(persistent_state);
332     } else {
333       diagnostic_manager.PutString(
334           lldb::eSeverityError, "couldn't start parsing (no persistent data)");
335       return false;
336     }
337   } else {
338     diagnostic_manager.PutString(lldb::eSeverityError,
339                                  "error: couldn't start parsing (no target)");
340     return false;
341   }
342   return true;
343 }
344 
SetupDeclVendor(ExecutionContext & exe_ctx,Target * target,DiagnosticManager & diagnostic_manager)345 static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target,
346                             DiagnosticManager &diagnostic_manager) {
347   if (!target->GetEnableAutoImportClangModules())
348     return;
349 
350   auto *persistent_state = llvm::cast<ClangPersistentVariables>(
351       target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
352   if (!persistent_state)
353     return;
354 
355   std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
356       persistent_state->GetClangModulesDeclVendor();
357   if (!decl_vendor)
358     return;
359 
360   StackFrame *frame = exe_ctx.GetFramePtr();
361   if (!frame)
362     return;
363 
364   Block *block = frame->GetFrameBlock();
365   if (!block)
366     return;
367   SymbolContext sc;
368 
369   block->CalculateSymbolContext(&sc);
370 
371   if (!sc.comp_unit)
372     return;
373   StreamString error_stream;
374 
375   ClangModulesDeclVendor::ModuleVector modules_for_macros =
376       persistent_state->GetHandLoadedClangModules();
377   if (decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros,
378                                             error_stream))
379     return;
380 
381   // Failed to load some modules, so emit the error stream as a diagnostic.
382   if (!error_stream.Empty()) {
383     // The error stream already contains several Clang diagnostics that might
384     // be either errors or warnings, so just print them all as one remark
385     // diagnostic to prevent that the message starts with "error: error:".
386     diagnostic_manager.PutString(lldb::eSeverityInfo, error_stream.GetString());
387     return;
388   }
389 
390   diagnostic_manager.PutString(lldb::eSeverityError,
391                                "Unknown error while loading modules needed for "
392                                "current compilation unit.");
393 }
394 
GetWrapKind() const395 ClangExpressionSourceCode::WrapKind ClangUserExpression::GetWrapKind() const {
396   assert(m_options.GetExecutionPolicy() != eExecutionPolicyTopLevel &&
397          "Top level expressions aren't wrapped.");
398   using Kind = ClangExpressionSourceCode::WrapKind;
399   if (m_in_cplusplus_method)
400     return Kind::CppMemberFunction;
401   else if (m_in_objectivec_method) {
402     if (m_in_static_method)
403       return Kind::ObjCStaticMethod;
404     return Kind::ObjCInstanceMethod;
405   }
406   // Not in any kind of 'special' function, so just wrap it in a normal C
407   // function.
408   return Kind::Function;
409 }
410 
CreateSourceCode(DiagnosticManager & diagnostic_manager,ExecutionContext & exe_ctx,std::vector<std::string> modules_to_import,bool for_completion)411 void ClangUserExpression::CreateSourceCode(
412     DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
413     std::vector<std::string> modules_to_import, bool for_completion) {
414 
415   std::string prefix = m_expr_prefix;
416 
417   if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
418     m_transformed_text = m_expr_text;
419   } else {
420     m_source_code.reset(ClangExpressionSourceCode::CreateWrapped(
421         m_filename, prefix, m_expr_text, GetWrapKind()));
422 
423     if (!m_source_code->GetText(m_transformed_text, exe_ctx, !m_ctx_obj,
424                                 for_completion, modules_to_import)) {
425       diagnostic_manager.PutString(lldb::eSeverityError,
426                                    "couldn't construct expression body");
427       return;
428     }
429 
430     // Find and store the start position of the original code inside the
431     // transformed code. We need this later for the code completion.
432     std::size_t original_start;
433     std::size_t original_end;
434     bool found_bounds = m_source_code->GetOriginalBodyBounds(
435         m_transformed_text, original_start, original_end);
436     if (found_bounds)
437       m_user_expression_start_pos = original_start;
438   }
439 }
440 
SupportsCxxModuleImport(lldb::LanguageType language)441 static bool SupportsCxxModuleImport(lldb::LanguageType language) {
442   switch (language) {
443   case lldb::eLanguageTypeC_plus_plus:
444   case lldb::eLanguageTypeC_plus_plus_03:
445   case lldb::eLanguageTypeC_plus_plus_11:
446   case lldb::eLanguageTypeC_plus_plus_14:
447   case lldb::eLanguageTypeObjC_plus_plus:
448     return true;
449   default:
450     return false;
451   }
452 }
453 
454 /// Utility method that puts a message into the expression log and
455 /// returns an invalid module configuration.
LogConfigError(const std::string & msg)456 static CppModuleConfiguration LogConfigError(const std::string &msg) {
457   Log *log = GetLog(LLDBLog::Expressions);
458   LLDB_LOG(log, "[C++ module config] {0}", msg);
459   return CppModuleConfiguration();
460 }
461 
GetModuleConfig(lldb::LanguageType language,ExecutionContext & exe_ctx)462 CppModuleConfiguration GetModuleConfig(lldb::LanguageType language,
463                                        ExecutionContext &exe_ctx) {
464   Log *log = GetLog(LLDBLog::Expressions);
465 
466   // Don't do anything if this is not a C++ module configuration.
467   if (!SupportsCxxModuleImport(language))
468     return LogConfigError("Language doesn't support C++ modules");
469 
470   Target *target = exe_ctx.GetTargetPtr();
471   if (!target)
472     return LogConfigError("No target");
473 
474   StackFrame *frame = exe_ctx.GetFramePtr();
475   if (!frame)
476     return LogConfigError("No frame");
477 
478   Block *block = frame->GetFrameBlock();
479   if (!block)
480     return LogConfigError("No block");
481 
482   SymbolContext sc;
483   block->CalculateSymbolContext(&sc);
484   if (!sc.comp_unit)
485     return LogConfigError("Couldn't calculate symbol context");
486 
487   // Build a list of files we need to analyze to build the configuration.
488   FileSpecList files;
489   for (auto &f : sc.comp_unit->GetSupportFiles())
490     files.AppendIfUnique(f->Materialize());
491   // We also need to look at external modules in the case of -gmodules as they
492   // contain the support files for libc++ and the C library.
493   llvm::DenseSet<SymbolFile *> visited_symbol_files;
494   sc.comp_unit->ForEachExternalModule(
495       visited_symbol_files, [&files](Module &module) {
496         for (std::size_t i = 0; i < module.GetNumCompileUnits(); ++i) {
497           const SupportFileList &support_files =
498               module.GetCompileUnitAtIndex(i)->GetSupportFiles();
499           for (auto &f : support_files) {
500             files.AppendIfUnique(f->Materialize());
501           }
502         }
503         return false;
504       });
505 
506   LLDB_LOG(log, "[C++ module config] Found {0} support files to analyze",
507            files.GetSize());
508   if (log && log->GetVerbose()) {
509     for (auto &f : files)
510       LLDB_LOGV(log, "[C++ module config] Analyzing support file: {0}",
511                 f.GetPath());
512   }
513 
514   // Try to create a configuration from the files. If there is no valid
515   // configuration possible with the files, this just returns an invalid
516   // configuration.
517   return CppModuleConfiguration(files, target->GetArchitecture().GetTriple());
518 }
519 
PrepareForParsing(DiagnosticManager & diagnostic_manager,ExecutionContext & exe_ctx,bool for_completion)520 bool ClangUserExpression::PrepareForParsing(
521     DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
522     bool for_completion) {
523   InstallContext(exe_ctx);
524 
525   if (!SetupPersistentState(diagnostic_manager, exe_ctx))
526     return false;
527 
528   Status err;
529   ScanContext(exe_ctx, err);
530 
531   if (!err.Success()) {
532     diagnostic_manager.PutString(lldb::eSeverityWarning, err.AsCString());
533   }
534 
535   ////////////////////////////////////
536   // Generate the expression
537   //
538 
539   ApplyObjcCastHack(m_expr_text);
540 
541   SetupDeclVendor(exe_ctx, m_target, diagnostic_manager);
542 
543   m_filename = m_clang_state->GetNextExprFileName();
544 
545   if (m_target->GetImportStdModule() == eImportStdModuleTrue)
546     SetupCppModuleImports(exe_ctx);
547 
548   CreateSourceCode(diagnostic_manager, exe_ctx, m_imported_cpp_modules,
549                    for_completion);
550   return true;
551 }
552 
TryParse(DiagnosticManager & diagnostic_manager,ExecutionContext & exe_ctx,lldb_private::ExecutionPolicy execution_policy,bool keep_result_in_memory,bool generate_debug_info)553 bool ClangUserExpression::TryParse(
554     DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
555     lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
556     bool generate_debug_info) {
557   m_materializer_up = std::make_unique<Materializer>();
558 
559   ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
560 
561   auto on_exit = llvm::make_scope_exit([this]() { ResetDeclMap(); });
562 
563   if (!DeclMap()->WillParse(exe_ctx, GetMaterializer())) {
564     diagnostic_manager.PutString(
565         lldb::eSeverityError,
566         "current process state is unsuitable for expression parsing");
567     return false;
568   }
569 
570   if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
571     DeclMap()->SetLookupsEnabled(true);
572   }
573 
574   m_parser = std::make_unique<ClangExpressionParser>(
575       exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info,
576       m_include_directories, m_filename);
577 
578   unsigned num_errors = m_parser->Parse(diagnostic_manager);
579 
580   // Check here for FixItHints.  If there are any try to apply the fixits and
581   // set the fixed text in m_fixed_text before returning an error.
582   if (num_errors) {
583     if (diagnostic_manager.HasFixIts()) {
584       if (m_parser->RewriteExpression(diagnostic_manager)) {
585         size_t fixed_start;
586         size_t fixed_end;
587         m_fixed_text = diagnostic_manager.GetFixedExpression();
588         // Retrieve the original expression in case we don't have a top level
589         // expression (which has no surrounding source code).
590         if (m_source_code && m_source_code->GetOriginalBodyBounds(
591                                  m_fixed_text, fixed_start, fixed_end))
592           m_fixed_text =
593               m_fixed_text.substr(fixed_start, fixed_end - fixed_start);
594       }
595     }
596     return false;
597   }
598 
599   //////////////////////////////////////////////////////////////////////////////
600   // Prepare the output of the parser for execution, evaluating it statically
601   // if possible
602   //
603 
604   {
605     Status jit_error = m_parser->PrepareForExecution(
606         m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
607         m_can_interpret, execution_policy);
608 
609     if (!jit_error.Success()) {
610       const char *error_cstr = jit_error.AsCString();
611       if (error_cstr && error_cstr[0])
612         diagnostic_manager.PutString(lldb::eSeverityError, error_cstr);
613       else
614         diagnostic_manager.PutString(lldb::eSeverityError,
615                                      "expression can't be interpreted or run");
616       return false;
617     }
618   }
619   return true;
620 }
621 
SetupCppModuleImports(ExecutionContext & exe_ctx)622 void ClangUserExpression::SetupCppModuleImports(ExecutionContext &exe_ctx) {
623   Log *log = GetLog(LLDBLog::Expressions);
624 
625   CppModuleConfiguration module_config =
626       GetModuleConfig(m_language.AsLanguageType(), exe_ctx);
627   m_imported_cpp_modules = module_config.GetImportedModules();
628   m_include_directories = module_config.GetIncludeDirs();
629 
630   LLDB_LOG(log, "List of imported modules in expression: {0}",
631            llvm::make_range(m_imported_cpp_modules.begin(),
632                             m_imported_cpp_modules.end()));
633   LLDB_LOG(log, "List of include directories gathered for modules: {0}",
634            llvm::make_range(m_include_directories.begin(),
635                             m_include_directories.end()));
636 }
637 
shouldRetryWithCppModule(Target & target,ExecutionPolicy exe_policy)638 static bool shouldRetryWithCppModule(Target &target, ExecutionPolicy exe_policy) {
639   // Top-level expression don't yet support importing C++ modules.
640   if (exe_policy == ExecutionPolicy::eExecutionPolicyTopLevel)
641     return false;
642   return target.GetImportStdModule() == eImportStdModuleFallback;
643 }
644 
Parse(DiagnosticManager & diagnostic_manager,ExecutionContext & exe_ctx,lldb_private::ExecutionPolicy execution_policy,bool keep_result_in_memory,bool generate_debug_info)645 bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
646                                 ExecutionContext &exe_ctx,
647                                 lldb_private::ExecutionPolicy execution_policy,
648                                 bool keep_result_in_memory,
649                                 bool generate_debug_info) {
650   Log *log = GetLog(LLDBLog::Expressions);
651 
652   if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false))
653     return false;
654 
655   LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
656 
657   ////////////////////////////////////
658   // Set up the target and compiler
659   //
660 
661   Target *target = exe_ctx.GetTargetPtr();
662 
663   if (!target) {
664     diagnostic_manager.PutString(lldb::eSeverityError, "invalid target");
665     return false;
666   }
667 
668   //////////////////////////
669   // Parse the expression
670   //
671 
672   bool parse_success = TryParse(diagnostic_manager, exe_ctx, execution_policy,
673                                 keep_result_in_memory, generate_debug_info);
674   // If the expression failed to parse, check if retrying parsing with a loaded
675   // C++ module is possible.
676   if (!parse_success && shouldRetryWithCppModule(*target, execution_policy)) {
677     // Load the loaded C++ modules.
678     SetupCppModuleImports(exe_ctx);
679     // If we did load any modules, then retry parsing.
680     if (!m_imported_cpp_modules.empty()) {
681       // Create a dedicated diagnostic manager for the second parse attempt.
682       // These diagnostics are only returned to the caller if using the fallback
683       // actually succeeded in getting the expression to parse. This prevents
684       // that module-specific issues regress diagnostic quality with the
685       // fallback mode.
686       DiagnosticManager retry_manager;
687       // The module imports are injected into the source code wrapper,
688       // so recreate those.
689       CreateSourceCode(retry_manager, exe_ctx, m_imported_cpp_modules,
690                        /*for_completion*/ false);
691       parse_success = TryParse(retry_manager, exe_ctx, execution_policy,
692                                keep_result_in_memory, generate_debug_info);
693       // Return the parse diagnostics if we were successful.
694       if (parse_success)
695         diagnostic_manager = std::move(retry_manager);
696     }
697   }
698   if (!parse_success)
699     return false;
700 
701   if (m_execution_unit_sp) {
702     bool register_execution_unit = false;
703 
704     if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
705       register_execution_unit = true;
706     }
707 
708     // If there is more than one external function in the execution unit, it
709     // needs to keep living even if it's not top level, because the result
710     // could refer to that function.
711 
712     if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
713       register_execution_unit = true;
714     }
715 
716     if (register_execution_unit) {
717       if (auto *persistent_state =
718               exe_ctx.GetTargetPtr()->GetPersistentExpressionStateForLanguage(
719                   m_language.AsLanguageType()))
720         persistent_state->RegisterExecutionUnit(m_execution_unit_sp);
721     }
722   }
723 
724   if (generate_debug_info) {
725     lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
726 
727     if (jit_module_sp) {
728       ConstString const_func_name(FunctionName());
729       FileSpec jit_file;
730       jit_file.SetFilename(const_func_name);
731       jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
732       m_jit_module_wp = jit_module_sp;
733       target->GetImages().Append(jit_module_sp);
734     }
735   }
736 
737   Process *process = exe_ctx.GetProcessPtr();
738   if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
739     m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
740   return true;
741 }
742 
743 /// Converts an absolute position inside a given code string into
744 /// a column/line pair.
745 ///
746 /// \param[in] abs_pos
747 ///     A absolute position in the code string that we want to convert
748 ///     to a column/line pair.
749 ///
750 /// \param[in] code
751 ///     A multi-line string usually representing source code.
752 ///
753 /// \param[out] line
754 ///     The line in the code that contains the given absolute position.
755 ///     The first line in the string is indexed as 1.
756 ///
757 /// \param[out] column
758 ///     The column in the line that contains the absolute position.
759 ///     The first character in a line is indexed as 0.
AbsPosToLineColumnPos(size_t abs_pos,llvm::StringRef code,unsigned & line,unsigned & column)760 static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code,
761                                   unsigned &line, unsigned &column) {
762   // Reset to code position to beginning of the file.
763   line = 0;
764   column = 0;
765 
766   assert(abs_pos <= code.size() && "Absolute position outside code string?");
767 
768   // We have to walk up to the position and count lines/columns.
769   for (std::size_t i = 0; i < abs_pos; ++i) {
770     // If we hit a line break, we go back to column 0 and enter a new line.
771     // We only handle \n because that's what we internally use to make new
772     // lines for our temporary code strings.
773     if (code[i] == '\n') {
774       ++line;
775       column = 0;
776       continue;
777     }
778     ++column;
779   }
780 }
781 
Complete(ExecutionContext & exe_ctx,CompletionRequest & request,unsigned complete_pos)782 bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
783                                    CompletionRequest &request,
784                                    unsigned complete_pos) {
785   Log *log = GetLog(LLDBLog::Expressions);
786 
787   // We don't want any visible feedback when completing an expression. Mostly
788   // because the results we get from an incomplete invocation are probably not
789   // correct.
790   DiagnosticManager diagnostic_manager;
791 
792   if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ true))
793     return false;
794 
795   LLDB_LOGF(log, "Parsing the following code:\n%s", m_transformed_text.c_str());
796 
797   //////////////////////////
798   // Parse the expression
799   //
800 
801   m_materializer_up = std::make_unique<Materializer>();
802 
803   ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
804 
805   auto on_exit = llvm::make_scope_exit([this]() { ResetDeclMap(); });
806 
807   if (!DeclMap()->WillParse(exe_ctx, GetMaterializer())) {
808     diagnostic_manager.PutString(
809         lldb::eSeverityError,
810         "current process state is unsuitable for expression parsing");
811 
812     return false;
813   }
814 
815   if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
816     DeclMap()->SetLookupsEnabled(true);
817   }
818 
819   ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
820                                false);
821 
822   // We have to find the source code location where the user text is inside
823   // the transformed expression code. When creating the transformed text, we
824   // already stored the absolute position in the m_transformed_text string. The
825   // only thing left to do is to transform it into the line:column format that
826   // Clang expects.
827 
828   // The line and column of the user expression inside the transformed source
829   // code.
830   unsigned user_expr_line, user_expr_column;
831   if (m_user_expression_start_pos)
832     AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text,
833                           user_expr_line, user_expr_column);
834   else
835     return false;
836 
837   // The actual column where we have to complete is the start column of the
838   // user expression + the offset inside the user code that we were given.
839   const unsigned completion_column = user_expr_column + complete_pos;
840   parser.Complete(request, user_expr_line, completion_column, complete_pos);
841 
842   return true;
843 }
844 
GetCppObjectPointer(lldb::StackFrameSP frame_sp,llvm::StringRef object_name,Status & err)845 lldb::addr_t ClangUserExpression::GetCppObjectPointer(
846     lldb::StackFrameSP frame_sp, llvm::StringRef object_name, Status &err) {
847   auto valobj_sp =
848       GetObjectPointerValueObject(std::move(frame_sp), object_name, err);
849 
850   // We're inside a C++ class method. This could potentially be an unnamed
851   // lambda structure. If the lambda captured a "this", that should be
852   // the object pointer.
853   if (auto thisChildSP = valobj_sp->GetChildMemberWithName("this")) {
854     valobj_sp = thisChildSP;
855   }
856 
857   if (!err.Success() || !valobj_sp.get())
858     return LLDB_INVALID_ADDRESS;
859 
860   lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
861 
862   if (ret == LLDB_INVALID_ADDRESS) {
863     err.SetErrorStringWithFormatv(
864         "Couldn't load '{0}' because its value couldn't be evaluated",
865         object_name);
866     return LLDB_INVALID_ADDRESS;
867   }
868 
869   return ret;
870 }
871 
AddArguments(ExecutionContext & exe_ctx,std::vector<lldb::addr_t> & args,lldb::addr_t struct_address,DiagnosticManager & diagnostic_manager)872 bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
873                                        std::vector<lldb::addr_t> &args,
874                                        lldb::addr_t struct_address,
875                                        DiagnosticManager &diagnostic_manager) {
876   lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
877   lldb::addr_t cmd_ptr = LLDB_INVALID_ADDRESS;
878 
879   if (m_needs_object_ptr) {
880     lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
881     if (!frame_sp)
882       return true;
883 
884     if (!m_in_cplusplus_method && !m_in_objectivec_method) {
885       diagnostic_manager.PutString(
886           lldb::eSeverityError,
887           "need object pointer but don't know the language");
888       return false;
889     }
890 
891     static constexpr llvm::StringLiteral g_cplusplus_object_name("this");
892     static constexpr llvm::StringLiteral g_objc_object_name("self");
893     llvm::StringRef object_name =
894         m_in_cplusplus_method ? g_cplusplus_object_name : g_objc_object_name;
895 
896     Status object_ptr_error;
897 
898     if (m_ctx_obj) {
899       AddressType address_type;
900       object_ptr = m_ctx_obj->GetAddressOf(false, &address_type);
901       if (object_ptr == LLDB_INVALID_ADDRESS ||
902           address_type != eAddressTypeLoad)
903         object_ptr_error.SetErrorString("Can't get context object's "
904                                         "debuggee address");
905     } else {
906       if (m_in_cplusplus_method) {
907         object_ptr =
908             GetCppObjectPointer(frame_sp, object_name, object_ptr_error);
909       } else {
910         object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
911       }
912     }
913 
914     if (!object_ptr_error.Success()) {
915       exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Format(
916           "warning: `{0}' is not accessible (substituting 0). {1}\n",
917           object_name, object_ptr_error.AsCString());
918       object_ptr = 0;
919     }
920 
921     if (m_in_objectivec_method) {
922       static constexpr llvm::StringLiteral cmd_name("_cmd");
923 
924       cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
925 
926       if (!object_ptr_error.Success()) {
927         diagnostic_manager.Printf(
928             lldb::eSeverityWarning,
929             "couldn't get cmd pointer (substituting NULL): %s",
930             object_ptr_error.AsCString());
931         cmd_ptr = 0;
932       }
933     }
934 
935     args.push_back(object_ptr);
936 
937     if (m_in_objectivec_method)
938       args.push_back(cmd_ptr);
939 
940     args.push_back(struct_address);
941   } else {
942     args.push_back(struct_address);
943   }
944   return true;
945 }
946 
GetResultAfterDematerialization(ExecutionContextScope * exe_scope)947 lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization(
948     ExecutionContextScope *exe_scope) {
949   return m_result_delegate.GetVariable();
950 }
951 
952 char ClangUserExpression::ClangUserExpressionHelper::ID;
953 
ResetDeclMap(ExecutionContext & exe_ctx,Materializer::PersistentVariableDelegate & delegate,bool keep_result_in_memory,ValueObject * ctx_obj)954 void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
955     ExecutionContext &exe_ctx,
956     Materializer::PersistentVariableDelegate &delegate,
957     bool keep_result_in_memory,
958     ValueObject *ctx_obj) {
959   std::shared_ptr<ClangASTImporter> ast_importer;
960   auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
961       lldb::eLanguageTypeC);
962   if (state) {
963     auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
964     ast_importer = persistent_vars->GetClangASTImporter();
965   }
966   m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
967       keep_result_in_memory, &delegate, exe_ctx.GetTargetSP(), ast_importer,
968       ctx_obj);
969 }
970 
971 clang::ASTConsumer *
ASTTransformer(clang::ASTConsumer * passthrough)972 ClangUserExpression::ClangUserExpressionHelper::ASTTransformer(
973     clang::ASTConsumer *passthrough) {
974   m_result_synthesizer_up = std::make_unique<ASTResultSynthesizer>(
975       passthrough, m_top_level, m_target);
976 
977   return m_result_synthesizer_up.get();
978 }
979 
CommitPersistentDecls()980 void ClangUserExpression::ClangUserExpressionHelper::CommitPersistentDecls() {
981   if (m_result_synthesizer_up) {
982     m_result_synthesizer_up->CommitPersistentDecls();
983   }
984 }
985 
GetName()986 ConstString ClangUserExpression::ResultDelegate::GetName() {
987   return m_persistent_state->GetNextPersistentVariableName(false);
988 }
989 
DidDematerialize(lldb::ExpressionVariableSP & variable)990 void ClangUserExpression::ResultDelegate::DidDematerialize(
991     lldb::ExpressionVariableSP &variable) {
992   m_variable = variable;
993 }
994 
RegisterPersistentState(PersistentExpressionState * persistent_state)995 void ClangUserExpression::ResultDelegate::RegisterPersistentState(
996     PersistentExpressionState *persistent_state) {
997   m_persistent_state = persistent_state;
998 }
999 
GetVariable()1000 lldb::ExpressionVariableSP &ClangUserExpression::ResultDelegate::GetVariable() {
1001   return m_variable;
1002 }
1003