LLDB  mainline
ClangUserExpression.cpp
Go to the documentation of this file.
1 //===-- ClangUserExpression.cpp ---------------------------------*- C++ -*-===//
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 <stdio.h>
10 #if HAVE_SYS_TYPES_H
11 #include <sys/types.h>
12 #endif
13 
14 #include <cstdlib>
15 #include <map>
16 #include <string>
17 
18 #include "ClangUserExpression.h"
19 
20 #include "ASTResultSynthesizer.h"
21 #include "ClangDiagnostic.h"
22 #include "ClangExpressionDeclMap.h"
23 #include "ClangExpressionParser.h"
25 #include "ClangModulesDeclVendor.h"
27 
28 #include "lldb/Core/Debugger.h"
29 #include "lldb/Core/Module.h"
30 #include "lldb/Core/StreamFile.h"
36 #include "lldb/Host/HostInfo.h"
37 #include "lldb/Symbol/Block.h"
41 #include "lldb/Symbol/Function.h"
42 #include "lldb/Symbol/ObjectFile.h"
44 #include "lldb/Symbol/Type.h"
47 #include "lldb/Target/Process.h"
48 #include "lldb/Target/StackFrame.h"
49 #include "lldb/Target/Target.h"
50 #include "lldb/Target/ThreadPlan.h"
53 #include "lldb/Utility/Log.h"
55 
56 #include "clang/AST/DeclCXX.h"
57 #include "clang/AST/DeclObjC.h"
58 
59 #include "llvm/ADT/ScopeExit.h"
60 
61 using namespace lldb_private;
62 
64  ExecutionContextScope &exe_scope, llvm::StringRef expr,
65  llvm::StringRef prefix, lldb::LanguageType language,
66  ResultType desired_type, const EvaluateExpressionOptions &options,
67  ValueObject *ctx_obj)
68  : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
69  options, eKindClangUserExpression),
70  m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() ==
72  m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) {
73  switch (m_language) {
75  m_allow_cxx = true;
76  break;
78  m_allow_objc = true;
79  break;
81  default:
82  m_allow_cxx = true;
83  m_allow_objc = true;
84  break;
85  }
86 }
87 
89 
90 void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {
92 
93  if (log)
94  log->Printf("ClangUserExpression::ScanContext()");
95 
96  m_target = exe_ctx.GetTargetPtr();
97 
98  if (!(m_allow_cxx || m_allow_objc)) {
99  if (log)
100  log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
101  return;
102  }
103 
104  StackFrame *frame = exe_ctx.GetFramePtr();
105  if (frame == NULL) {
106  if (log)
107  log->Printf(" [CUE::SC] Null stack frame");
108  return;
109  }
110 
111  SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
112  lldb::eSymbolContextBlock);
113 
114  if (!sym_ctx.function) {
115  if (log)
116  log->Printf(" [CUE::SC] Null function");
117  return;
118  }
119 
120  // Find the block that defines the function represented by "sym_ctx"
121  Block *function_block = sym_ctx.GetFunctionBlock();
122 
123  if (!function_block) {
124  if (log)
125  log->Printf(" [CUE::SC] Null function block");
126  return;
127  }
128 
129  CompilerDeclContext decl_context = function_block->GetDeclContext();
130 
131  if (!decl_context) {
132  if (log)
133  log->Printf(" [CUE::SC] Null decl context");
134  return;
135  }
136 
137  if (m_ctx_obj) {
138  switch (m_ctx_obj->GetObjectRuntimeLanguage()) {
147  m_in_cplusplus_method = true;
148  break;
151  m_in_objectivec_method = true;
152  break;
153  default:
154  break;
155  }
156  m_needs_object_ptr = true;
157  } else if (clang::CXXMethodDecl *method_decl =
159  if (m_allow_cxx && method_decl->isInstance()) {
161  lldb::VariableListSP variable_list_sp(
162  function_block->GetBlockVariableList(true));
163 
164  const char *thisErrorString = "Stopped in a C++ method, but 'this' "
165  "isn't available; pretending we are in a "
166  "generic context";
167 
168  if (!variable_list_sp) {
169  err.SetErrorString(thisErrorString);
170  return;
171  }
172 
173  lldb::VariableSP this_var_sp(
174  variable_list_sp->FindVariable(ConstString("this")));
175 
176  if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
177  !this_var_sp->LocationIsValidForFrame(frame)) {
178  err.SetErrorString(thisErrorString);
179  return;
180  }
181  }
182 
183  m_in_cplusplus_method = true;
184  m_needs_object_ptr = true;
185  }
186  } else if (clang::ObjCMethodDecl *method_decl =
188  decl_context)) {
189  if (m_allow_objc) {
191  lldb::VariableListSP variable_list_sp(
192  function_block->GetBlockVariableList(true));
193 
194  const char *selfErrorString = "Stopped in an Objective-C method, but "
195  "'self' isn't available; pretending we "
196  "are in a generic context";
197 
198  if (!variable_list_sp) {
199  err.SetErrorString(selfErrorString);
200  return;
201  }
202 
203  lldb::VariableSP self_variable_sp =
204  variable_list_sp->FindVariable(ConstString("self"));
205 
206  if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
207  !self_variable_sp->LocationIsValidForFrame(frame)) {
208  err.SetErrorString(selfErrorString);
209  return;
210  }
211  }
212 
213  m_in_objectivec_method = true;
214  m_needs_object_ptr = true;
215 
216  if (!method_decl->isInstanceMethod())
217  m_in_static_method = true;
218  }
219  } else if (clang::FunctionDecl *function_decl =
221  // We might also have a function that said in the debug information that it
222  // captured an object pointer. The best way to deal with getting to the
223  // ivars at present is by pretending that this is a method of a class in
224  // whatever runtime the debug info says the object pointer belongs to. Do
225  // that here.
226 
227  ClangASTMetadata *metadata =
228  ClangASTContext::DeclContextGetMetaData(decl_context, function_decl);
229  if (metadata && metadata->HasObjectPtr()) {
230  lldb::LanguageType language = metadata->GetObjectPtrLanguage();
231  if (language == lldb::eLanguageTypeC_plus_plus) {
233  lldb::VariableListSP variable_list_sp(
234  function_block->GetBlockVariableList(true));
235 
236  const char *thisErrorString = "Stopped in a context claiming to "
237  "capture a C++ object pointer, but "
238  "'this' isn't available; pretending we "
239  "are in a generic context";
240 
241  if (!variable_list_sp) {
242  err.SetErrorString(thisErrorString);
243  return;
244  }
245 
246  lldb::VariableSP this_var_sp(
247  variable_list_sp->FindVariable(ConstString("this")));
248 
249  if (!this_var_sp || !this_var_sp->IsInScope(frame) ||
250  !this_var_sp->LocationIsValidForFrame(frame)) {
251  err.SetErrorString(thisErrorString);
252  return;
253  }
254  }
255 
256  m_in_cplusplus_method = true;
257  m_needs_object_ptr = true;
258  } else if (language == lldb::eLanguageTypeObjC) {
260  lldb::VariableListSP variable_list_sp(
261  function_block->GetBlockVariableList(true));
262 
263  const char *selfErrorString =
264  "Stopped in a context claiming to capture an Objective-C object "
265  "pointer, but 'self' isn't available; pretending we are in a "
266  "generic context";
267 
268  if (!variable_list_sp) {
269  err.SetErrorString(selfErrorString);
270  return;
271  }
272 
273  lldb::VariableSP self_variable_sp =
274  variable_list_sp->FindVariable(ConstString("self"));
275 
276  if (!self_variable_sp || !self_variable_sp->IsInScope(frame) ||
277  !self_variable_sp->LocationIsValidForFrame(frame)) {
278  err.SetErrorString(selfErrorString);
279  return;
280  }
281 
282  Type *self_type = self_variable_sp->GetType();
283 
284  if (!self_type) {
285  err.SetErrorString(selfErrorString);
286  return;
287  }
288 
289  CompilerType self_clang_type = self_type->GetForwardCompilerType();
290 
291  if (!self_clang_type) {
292  err.SetErrorString(selfErrorString);
293  return;
294  }
295 
296  if (ClangASTContext::IsObjCClassType(self_clang_type)) {
297  return;
299  self_clang_type)) {
300  m_in_objectivec_method = true;
301  m_needs_object_ptr = true;
302  } else {
303  err.SetErrorString(selfErrorString);
304  return;
305  }
306  } else {
307  m_in_objectivec_method = true;
308  m_needs_object_ptr = true;
309  }
310  }
311  }
312  }
313 }
314 
315 // This is a really nasty hack, meant to fix Objective-C expressions of the
316 // form (int)[myArray count]. Right now, because the type information for
317 // count is not available, [myArray count] returns id, which can't be directly
318 // cast to int without causing a clang error.
319 static void ApplyObjcCastHack(std::string &expr) {
320 #define OBJC_CAST_HACK_FROM "(int)["
321 #define OBJC_CAST_HACK_TO "(int)(long long)["
322 
323  size_t from_offset;
324 
325  while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
326  expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1,
328 
329 #undef OBJC_CAST_HACK_TO
330 #undef OBJC_CAST_HACK_FROM
331 }
332 
333 bool ClangUserExpression::SetupPersistentState(DiagnosticManager &diagnostic_manager,
334  ExecutionContext &exe_ctx) {
335  if (Target *target = exe_ctx.GetTargetPtr()) {
336  if (PersistentExpressionState *persistent_state =
337  target->GetPersistentExpressionStateForLanguage(
339  m_result_delegate.RegisterPersistentState(persistent_state);
340  } else {
341  diagnostic_manager.PutString(
343  "couldn't start parsing (no persistent data)");
344  return false;
345  }
346  } else {
347  diagnostic_manager.PutString(eDiagnosticSeverityError,
348  "error: couldn't start parsing (no target)");
349  return false;
350  }
351  return true;
352 }
353 
354 static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
355  if (ClangModulesDeclVendor *decl_vendor =
356  target->GetClangModulesDeclVendor()) {
357  const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
358  llvm::cast<ClangPersistentVariables>(
361  ->GetHandLoadedClangModules();
362  ClangModulesDeclVendor::ModuleVector modules_for_macros;
363 
364  for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
365  modules_for_macros.push_back(module);
366  }
367 
368  if (target->GetEnableAutoImportClangModules()) {
369  if (StackFrame *frame = exe_ctx.GetFramePtr()) {
370  if (Block *block = frame->GetFrameBlock()) {
371  SymbolContext sc;
372 
373  block->CalculateSymbolContext(&sc);
374 
375  if (sc.comp_unit) {
376  StreamString error_stream;
377 
378  decl_vendor->AddModulesForCompileUnit(
379  *sc.comp_unit, modules_for_macros, error_stream);
380  }
381  }
382  }
383  }
384  }
385 }
386 
387 void ClangUserExpression::UpdateLanguageForExpr(
388  DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
389  std::vector<std::string> modules_to_import, bool for_completion) {
391 
392  std::string prefix = m_expr_prefix;
393 
396  } else {
397  std::unique_ptr<ClangExpressionSourceCode> source_code(
399  m_expr_text.c_str()));
400 
402  m_expr_lang = lldb::eLanguageTypeC_plus_plus;
403  else if (m_in_objectivec_method)
404  m_expr_lang = lldb::eLanguageTypeObjC;
405  else
406  m_expr_lang = lldb::eLanguageTypeC;
407 
408  if (!source_code->GetText(m_transformed_text, m_expr_lang,
409  m_in_static_method, exe_ctx, !m_ctx_obj,
410  for_completion, modules_to_import)) {
411  diagnostic_manager.PutString(eDiagnosticSeverityError,
412  "couldn't construct expression body");
413  return;
414  }
415 
416  // Find and store the start position of the original code inside the
417  // transformed code. We need this later for the code completion.
418  std::size_t original_start;
419  std::size_t original_end;
420  bool found_bounds = source_code->GetOriginalBodyBounds(
421  m_transformed_text, m_expr_lang, original_start, original_end);
422  if (found_bounds)
423  m_user_expression_start_pos = original_start;
424  }
425 }
426 
428  switch (language) {
434  return true;
435  default:
436  return false;
437  }
438 }
439 
440 std::vector<std::string>
441 ClangUserExpression::GetModulesToImport(ExecutionContext &exe_ctx) {
443 
445  return {};
446 
447  Target *target = exe_ctx.GetTargetPtr();
448  if (!target || !target->GetEnableImportStdModule())
449  return {};
450 
451  StackFrame *frame = exe_ctx.GetFramePtr();
452  if (!frame)
453  return {};
454 
455  Block *block = frame->GetFrameBlock();
456  if (!block)
457  return {};
458 
459  SymbolContext sc;
460  block->CalculateSymbolContext(&sc);
461  if (!sc.comp_unit)
462  return {};
463 
464  if (log) {
465  for (const SourceModule &m : sc.comp_unit->GetImportedModules()) {
466  LLDB_LOG(log, "Found module in compile unit: {0:$[.]} - include dir: {1}",
467  llvm::make_range(m.path.begin(), m.path.end()), m.search_path);
468  }
469  }
470 
471  for (const SourceModule &m : sc.comp_unit->GetImportedModules())
472  m_include_directories.push_back(m.search_path);
473 
474  // Check if we imported 'std' or any of its submodules.
475  // We currently don't support importing any other modules in the expression
476  // parser.
477  for (const SourceModule &m : sc.comp_unit->GetImportedModules())
478  if (!m.path.empty() && m.path.front() == "std")
479  return {"std"};
480 
481  return {};
482 }
483 
484 bool ClangUserExpression::PrepareForParsing(
485  DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
486  bool for_completion) {
488 
489  InstallContext(exe_ctx);
490 
491  if (!SetupPersistentState(diagnostic_manager, exe_ctx))
492  return false;
493 
494  Status err;
495  ScanContext(exe_ctx, err);
496 
497  if (!err.Success()) {
498  diagnostic_manager.PutString(eDiagnosticSeverityWarning, err.AsCString());
499  }
500 
501  ////////////////////////////////////
502  // Generate the expression
503  //
504 
506 
507  SetupDeclVendor(exe_ctx, m_target);
508 
509  std::vector<std::string> used_modules = GetModulesToImport(exe_ctx);
510  m_imported_cpp_modules = !used_modules.empty();
511 
512  LLDB_LOG(log, "List of imported modules in expression: {0}",
513  llvm::make_range(used_modules.begin(), used_modules.end()));
514 
515  UpdateLanguageForExpr(diagnostic_manager, exe_ctx, used_modules,
516  for_completion);
517  return true;
518 }
519 
521  ExecutionContext &exe_ctx,
522  lldb_private::ExecutionPolicy execution_policy,
523  bool keep_result_in_memory,
524  bool generate_debug_info) {
526 
527  if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ false))
528  return false;
529 
530  if (log)
531  log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
532 
533  ////////////////////////////////////
534  // Set up the target and compiler
535  //
536 
537  Target *target = exe_ctx.GetTargetPtr();
538 
539  if (!target) {
540  diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
541  return false;
542  }
543 
544  //////////////////////////
545  // Parse the expression
546  //
547 
548  m_materializer_up.reset(new Materializer());
549 
550  ResetDeclMap(exe_ctx, m_result_delegate, keep_result_in_memory);
551 
552  auto on_exit = llvm::make_scope_exit([this]() { ResetDeclMap(); });
553 
554  if (!DeclMap()->WillParse(exe_ctx, m_materializer_up.get())) {
555  diagnostic_manager.PutString(
557  "current process state is unsuitable for expression parsing");
558  return false;
559  }
560 
562  DeclMap()->SetLookupsEnabled(true);
563  }
564 
565  Process *process = exe_ctx.GetProcessPtr();
566  ExecutionContextScope *exe_scope = process;
567 
568  if (!exe_scope)
569  exe_scope = exe_ctx.GetTargetPtr();
570 
571  // We use a shared pointer here so we can use the original parser - if it
572  // succeeds or the rewrite parser we might make if it fails. But the
573  // parser_sp will never be empty.
574 
575  ClangExpressionParser parser(exe_scope, *this, generate_debug_info,
576  m_include_directories);
577 
578  unsigned num_errors = 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 (parser.RewriteExpression(diagnostic_manager)) {
585  size_t fixed_start;
586  size_t fixed_end;
587  const std::string &fixed_expression =
588  diagnostic_manager.GetFixedExpression();
590  fixed_expression, m_expr_lang, fixed_start, fixed_end))
591  m_fixed_text =
592  fixed_expression.substr(fixed_start, fixed_end - fixed_start);
593  }
594  }
595  return false;
596  }
597 
598  //////////////////////////////////////////////////////////////////////////////
599  // Prepare the output of the parser for execution, evaluating it statically
600  // if possible
601  //
602 
603  {
604  Status jit_error = parser.PrepareForExecution(
606  m_can_interpret, execution_policy);
607 
608  if (!jit_error.Success()) {
609  const char *error_cstr = jit_error.AsCString();
610  if (error_cstr && error_cstr[0])
611  diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr);
612  else
613  diagnostic_manager.PutString(eDiagnosticSeverityError,
614  "expression can't be interpreted or run");
615  return false;
616  }
617  }
618 
619  if (exe_ctx.GetProcessPtr() && execution_policy == eExecutionPolicyTopLevel) {
620  Status static_init_error =
622 
623  if (!static_init_error.Success()) {
624  const char *error_cstr = static_init_error.AsCString();
625  if (error_cstr && error_cstr[0])
626  diagnostic_manager.Printf(eDiagnosticSeverityError,
627  "couldn't run static initializers: %s\n",
628  error_cstr);
629  else
630  diagnostic_manager.PutString(eDiagnosticSeverityError,
631  "couldn't run static initializers\n");
632  return false;
633  }
634  }
635 
636  if (m_execution_unit_sp) {
637  bool register_execution_unit = false;
638 
640  register_execution_unit = true;
641  }
642 
643  // If there is more than one external function in the execution unit, it
644  // needs to keep living even if it's not top level, because the result
645  // could refer to that function.
646 
647  if (m_execution_unit_sp->GetJittedFunctions().size() > 1) {
648  register_execution_unit = true;
649  }
650 
651  if (register_execution_unit) {
652  llvm::cast<PersistentExpressionState>(
654  m_language))
655  ->RegisterExecutionUnit(m_execution_unit_sp);
656  }
657  }
658 
659  if (generate_debug_info) {
660  lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
661 
662  if (jit_module_sp) {
663  ConstString const_func_name(FunctionName());
664  FileSpec jit_file;
665  jit_file.GetFilename() = const_func_name;
666  jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
667  m_jit_module_wp = jit_module_sp;
668  target->GetImages().Append(jit_module_sp);
669  }
670  }
671 
672  if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
673  m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
674  return true;
675 }
676 
677 /// Converts an absolute position inside a given code string into
678 /// a column/line pair.
679 ///
680 /// \param[in] abs_pos
681 /// A absolute position in the code string that we want to convert
682 /// to a column/line pair.
683 ///
684 /// \param[in] code
685 /// A multi-line string usually representing source code.
686 ///
687 /// \param[out] line
688 /// The line in the code that contains the given absolute position.
689 /// The first line in the string is indexed as 1.
690 ///
691 /// \param[out] column
692 /// The column in the line that contains the absolute position.
693 /// The first character in a line is indexed as 0.
694 static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code,
695  unsigned &line, unsigned &column) {
696  // Reset to code position to beginning of the file.
697  line = 0;
698  column = 0;
699 
700  assert(abs_pos <= code.size() && "Absolute position outside code string?");
701 
702  // We have to walk up to the position and count lines/columns.
703  for (std::size_t i = 0; i < abs_pos; ++i) {
704  // If we hit a line break, we go back to column 0 and enter a new line.
705  // We only handle \n because that's what we internally use to make new
706  // lines for our temporary code strings.
707  if (code[i] == '\n') {
708  ++line;
709  column = 0;
710  continue;
711  }
712  ++column;
713  }
714 }
715 
717  CompletionRequest &request,
718  unsigned complete_pos) {
720 
721  // We don't want any visible feedback when completing an expression. Mostly
722  // because the results we get from an incomplete invocation are probably not
723  // correct.
724  DiagnosticManager diagnostic_manager;
725 
726  if (!PrepareForParsing(diagnostic_manager, exe_ctx, /*for_completion*/ true))
727  return false;
728 
729  if (log)
730  log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
731 
732  //////////////////////////
733  // Parse the expression
734  //
735 
736  m_materializer_up.reset(new Materializer());
737 
738  ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
739 
740  auto on_exit = llvm::make_scope_exit([this]() { ResetDeclMap(); });
741 
742  if (!DeclMap()->WillParse(exe_ctx, m_materializer_up.get())) {
743  diagnostic_manager.PutString(
745  "current process state is unsuitable for expression parsing");
746 
747  return false;
748  }
749 
751  DeclMap()->SetLookupsEnabled(true);
752  }
753 
754  Process *process = exe_ctx.GetProcessPtr();
755  ExecutionContextScope *exe_scope = process;
756 
757  if (!exe_scope)
758  exe_scope = exe_ctx.GetTargetPtr();
759 
760  ClangExpressionParser parser(exe_scope, *this, false);
761 
762  // We have to find the source code location where the user text is inside
763  // the transformed expression code. When creating the transformed text, we
764  // already stored the absolute position in the m_transformed_text string. The
765  // only thing left to do is to transform it into the line:column format that
766  // Clang expects.
767 
768  // The line and column of the user expression inside the transformed source
769  // code.
770  unsigned user_expr_line, user_expr_column;
771  if (m_user_expression_start_pos.hasValue())
772  AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text,
773  user_expr_line, user_expr_column);
774  else
775  return false;
776 
777  // The actual column where we have to complete is the start column of the
778  // user expression + the offset inside the user code that we were given.
779  const unsigned completion_column = user_expr_column + complete_pos;
780  parser.Complete(request, user_expr_line, completion_column, complete_pos);
781 
782  return true;
783 }
784 
785 bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
786  std::vector<lldb::addr_t> &args,
787  lldb::addr_t struct_address,
788  DiagnosticManager &diagnostic_manager) {
789  lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
791 
792  if (m_needs_object_ptr) {
793  lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
794  if (!frame_sp)
795  return true;
796 
797  ConstString object_name;
798 
799  if (m_in_cplusplus_method) {
800  object_name.SetCString("this");
801  } else if (m_in_objectivec_method) {
802  object_name.SetCString("self");
803  } else {
804  diagnostic_manager.PutString(
806  "need object pointer but don't know the language");
807  return false;
808  }
809 
810  Status object_ptr_error;
811 
812  if (m_ctx_obj) {
813  AddressType address_type;
814  object_ptr = m_ctx_obj->GetAddressOf(false, &address_type);
815  if (object_ptr == LLDB_INVALID_ADDRESS ||
816  address_type != eAddressTypeLoad)
817  object_ptr_error.SetErrorString("Can't get context object's "
818  "debuggee address");
819  } else
820  object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
821 
822  if (!object_ptr_error.Success()) {
823  exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
824  "warning: `%s' is not accessible (substituting 0)\n",
825  object_name.AsCString());
826  object_ptr = 0;
827  }
828 
830  ConstString cmd_name("_cmd");
831 
832  cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
833 
834  if (!object_ptr_error.Success()) {
835  diagnostic_manager.Printf(
837  "couldn't get cmd pointer (substituting NULL): %s",
838  object_ptr_error.AsCString());
839  cmd_ptr = 0;
840  }
841  }
842 
843  args.push_back(object_ptr);
844 
846  args.push_back(cmd_ptr);
847 
848  args.push_back(struct_address);
849  } else {
850  args.push_back(struct_address);
851  }
852  return true;
853 }
854 
856  ExecutionContextScope *exe_scope) {
857  return m_result_delegate.GetVariable();
858 }
859 
861  ExecutionContext &exe_ctx,
863  bool keep_result_in_memory,
864  ValueObject *ctx_obj) {
865  m_expr_decl_map_up.reset(
866  new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx,
867  ctx_obj));
868 }
869 
870 clang::ASTConsumer *
872  clang::ASTConsumer *passthrough) {
873  m_result_synthesizer_up.reset(
874  new ASTResultSynthesizer(passthrough, m_top_level, m_target));
875 
876  return m_result_synthesizer_up.get();
877 }
878 
880  if (m_result_synthesizer_up) {
881  m_result_synthesizer_up->CommitPersistentDecls();
882  }
883 }
884 
885 ConstString ClangUserExpression::ResultDelegate::GetName() {
886  auto prefix = m_persistent_state->GetPersistentVariablePrefix();
887  return m_persistent_state->GetNextPersistentVariableName(*m_target_sp,
888  prefix);
889 }
890 
891 void ClangUserExpression::ResultDelegate::DidDematerialize(
892  lldb::ExpressionVariableSP &variable) {
893  m_variable = variable;
894 }
895 
896 void ClangUserExpression::ResultDelegate::RegisterPersistentState(
897  PersistentExpressionState *persistent_state) {
898  m_persistent_state = persistent_state;
899 }
900 
901 lldb::ExpressionVariableSP &ClangUserExpression::ResultDelegate::GetVariable() {
902  return m_variable;
903 }
static ClangExpressionSourceCode * CreateWrapped(const char *prefix, const char *body)
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:369
bool m_allow_cxx
True if the language allows C++.
lldb::addr_t m_jit_start_addr
An expression might have a process, but it doesn&#39;t need to (e.g.
Definition: Expression.h:104
void SetLookupsEnabled(bool lookups_enabled)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
bool GetEnableAutoImportClangModules() const
Definition: Target.cpp:3902
lldb::ExpressionVariableSP GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override
static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target)
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
static clang::FunctionDecl * DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc)
const std::string & GetFixedExpression()
static bool SupportsCxxModuleImport(lldb::LanguageType language)
virtual lldb::LanguageType GetObjectRuntimeLanguage()
A file utility class.
Definition: FileSpec.h:55
bool GetEnableImportStdModule() const
Definition: Target.cpp:3908
static lldb::addr_t GetObjectPointer(lldb::StackFrameSP frame_sp, ConstString &object_name, Status &err)
CompileUnit * comp_unit
The CompileUnit for a given query.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
lldb::VariableListSP GetBlockVariableList(bool can_create)
Get the variable list for this block only.
Definition: Block.cpp:387
static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code, unsigned &line, unsigned &column)
Converts an absolute position inside a given code string into a column/line pair. ...
lldb::LanguageType Language() override
Return the language that should be used when parsing.
static bool GetOriginalBodyBounds(std::string transformed_text, lldb::LanguageType wrapping_language, size_t &start_loc, size_t &end_loc)
A class that describes a single lexical block.
Definition: Block.h:41
#define LLDB_LOG(log,...)
Definition: Log.h:209
std::string m_expr_prefix
The text of the translation-level definitions, as provided by the user.
std::string m_transformed_text
The text of the expression, as send to the parser.
Status PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, lldb_private::ExecutionPolicy execution_policy) override
Ready an already-parsed expression for execution, possibly evaluating it statically.
const std::vector< SourceModule > & GetImportedModules()
Get the compile unit&#39;s imported module list.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
std::string m_expr_text
The text of the expression, as typed by the user.
EvaluateExpressionOptions m_options
Additional options provided by the user.
bool Complete(CompletionRequest &request, unsigned line, unsigned pos, unsigned typed_pos) override
Attempts to find possible command line completions for the given expression.
lldb::LanguageType GetObjectPtrLanguage() const
std::unique_ptr< Materializer > m_materializer_up
The materializer to use when running the expression.
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame&#39;s current pc value.
Definition: StackFrame.cpp:267
Function * function
The Function for a given query.
"lldb/Utility/ArgCompletionRequest.h"
bool m_in_objectivec_method
True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was i...
static bool IsObjCClassType(const CompilerType &type)
Target * GetTargetPtr() const
Returns a pointer to the target object.
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
Block * GetFunctionBlock()
Find a block that defines the function represented by this symbol context.
lldb::StreamSP GetAsyncOutputStream()
Definition: Debugger.cpp:1149
LanguageType
Programming language type.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
std::shared_ptr< IRExecutionUnit > m_execution_unit_sp
The execution unit the expression is stored in.
"lldb/Expression/ASTResultSynthesizer.h" Adds a result variable declaration to the ASTs for an expres...
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:57
virtual lldb::addr_t GetAddressOf(bool scalar_is_load_address=true, AddressType *address_type=nullptr)
bool m_enforce_valid_object
True if the expression parser should enforce the presence of a valid class pointer.
#define OBJC_CAST_HACK_TO
bool m_in_static_method
True if the expression is compiled as a static (or class) method (currently true if it...
unsigned Parse(DiagnosticManager &diagnostic_manager) override
Parse a single expression and convert it to IR using Clang.
bool m_can_interpret
True if the expression could be evaluated statically; false otherwise.
static bool IsObjCObjectPointerType(const CompilerType &type, CompilerType *target_type=nullptr)
const lldb::StackFrameSP & GetFrameSP() const
Get accessor to get the frame shared pointer.
size_t Printf(DiagnosticSeverity severity, const char *format,...) __attribute__((format(printf
bool m_needs_object_ptr
was parsed when exe_ctx was in an Objective-C class method).
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
Block * GetFrameBlock()
Get the current lexical scope block for this StackFrame, if possible.
Definition: StackFrame.cpp:242
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
Process * GetProcessPtr() const
Returns a pointer to the process object.
size_t size_t PutString(DiagnosticSeverity severity, llvm::StringRef str)
clang::ASTConsumer * ASTTransformer(clang::ASTConsumer *passthrough) override
Return the object that the parser should allow to access ASTs.
lldb::ProcessWP m_jit_process_wp
Expression&#39;s always have to have a target...
Definition: Expression.h:101
bool RewriteExpression(DiagnosticManager &diagnostic_manager) override
Try to use the FixIts in the diagnostic_manager to rewrite the expression.
bool Success() const
Test for success condition.
Definition: Status.cpp:287
void CalculateSymbolContext(SymbolContext *sc) override
Reconstruct the object&#39;s symbol context into sc.
Definition: Block.cpp:126
ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options, ValueObject *ctx_obj)
Constructor.
bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) override
Parse the expression.
static ClangASTMetadata * DeclContextGetMetaData(const CompilerDeclContext &dc, const void *object)
CompilerType GetForwardCompilerType()
Definition: Type.cpp:610
CompilerDeclContext GetDeclContext()
Definition: Block.cpp:470
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
Target * m_target
The target for storing persistent data like types and variables.
lldb::addr_t m_jit_end_addr
The address of the JITted function within the JIT allocation.
Definition: Expression.h:107
void InstallContext(ExecutionContext &exe_ctx)
Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
uint64_t addr_t
Definition: lldb-types.h:83
bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request, unsigned complete_pos) override
Attempts to find possible command line completions for the given (possible incomplete) user expressio...
A uniqued constant string class.
Definition: ConstString.h:38
"lldb/Expression/LLVMUserExpression.h" Encapsulates a one-time expression for use in lldb...
Unknown or invalid language value.
Target & GetTargetRef() const
Returns a reference to the target object.
Non-standardized C, such as K&R.
#define OBJC_CAST_HACK_FROM
bool WillParse(ExecutionContext &exe_ctx, Materializer *materializer)
Enable the state needed for parsing and IR transformation.
std::string m_fixed_text
The text of the expression with fix-its applied.
"lldb/Expression/ClangExpressionParser.h" Encapsulates an instance of Clang that can parse expression...
static void ApplyObjcCastHack(std::string &expr)
static clang::ObjCMethodDecl * DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc)
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
Address is an address as in the current target inferior process.
ClangModulesDeclVendor * GetClangModulesDeclVendor()
Definition: Target.cpp:2488
Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx)
Run all static initializers for an execution unit.
ClangExpressionDeclMap * DeclMap()
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
bool m_allow_objc
True if the language allows Objective-C.
ExecutionPolicy
Expression execution policies.
const char * FunctionName() override
Return the function name that should be used for executing the expression.
bool m_in_cplusplus_method
in order to generate the expression as a method.
"lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are defined in LLDB&#39;s debug in...
lldb::LanguageType m_language
The language to use when parsing (eLanguageTypeUnknown means use defaults)
PersistentExpressionState * GetPersistentExpressionStateForLanguage(lldb::LanguageType language)
Definition: Target.cpp:2206
This base class provides an interface to stack frames.
Definition: StackFrame.h:40
Debugger & GetDebugger()
Definition: Target.h:974
Information needed to import a source-language module.
Definition: SourceModule.h:18
static clang::CXXMethodDecl * DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc)
An error handling class.
Definition: Status.h:44
ExecutionPolicy GetExecutionPolicy() const
Definition: Target.h:258
void SetCString(const char *cstr)
Set the C string value.