LLDB  mainline
ClangUtilityFunction.cpp
Go to the documentation of this file.
1 //===-- ClangUtilityFunction.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 "lldb/Host/Config.h"
10 
11 #include "ClangUtilityFunction.h"
12 #include "ClangExpressionDeclMap.h"
13 #include "ClangExpressionParser.h"
16 
17 #include <stdio.h>
18 #if HAVE_SYS_TYPES_H
19 #include <sys/types.h>
20 #endif
21 
22 
23 #include "lldb/Core/Module.h"
24 #include "lldb/Core/StreamFile.h"
26 #include "lldb/Host/Host.h"
28 #include "lldb/Target/Target.h"
30 #include "lldb/Utility/Log.h"
31 #include "lldb/Utility/Stream.h"
32 
33 using namespace lldb_private;
34 
36 
37 /// Constructor
38 ///
39 /// \param[in] text
40 /// The text of the function. Must be a full translation unit.
41 ///
42 /// \param[in] name
43 /// The name of the function, as used in the text.
45  const char *text, const char *name)
46  : UtilityFunction(exe_scope, text, name) {
48  if (text && text[0])
49  m_function_text.append(text);
50 }
51 
53 
54 /// Install the utility function into a process
55 ///
56 /// \param[in] diagnostic_manager
57 /// A diagnostic manager to report errors and warnings to.
58 ///
59 /// \param[in] exe_ctx
60 /// The execution context to install the utility function to.
61 ///
62 /// \return
63 /// True on success (no errors); false otherwise.
65  ExecutionContext &exe_ctx) {
67  diagnostic_manager.PutString(eDiagnosticSeverityWarning,
68  "already installed");
69  return false;
70  }
71 
72  ////////////////////////////////////
73  // Set up the target and compiler
74  //
75 
76  Target *target = exe_ctx.GetTargetPtr();
77 
78  if (!target) {
79  diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
80  return false;
81  }
82 
83  Process *process = exe_ctx.GetProcessPtr();
84 
85  if (!process) {
86  diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid process");
87  return false;
88  }
89 
90  //////////////////////////
91  // Parse the expression
92  //
93 
94  bool keep_result_in_memory = false;
95 
96  ResetDeclMap(exe_ctx, keep_result_in_memory);
97 
98  if (!DeclMap()->WillParse(exe_ctx, nullptr)) {
99  diagnostic_manager.PutString(
101  "current process state is unsuitable for expression parsing");
102  return false;
103  }
104 
105  const bool generate_debug_info = true;
106  ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
107  generate_debug_info);
108 
109  unsigned num_errors = parser.Parse(diagnostic_manager);
110 
111  if (num_errors) {
112  ResetDeclMap();
113 
114  return false;
115  }
116 
117  //////////////////////////////////
118  // JIT the output of the parser
119  //
120 
121  bool can_interpret = false; // should stay that way
122 
123  Status jit_error = parser.PrepareForExecution(
125  can_interpret, eExecutionPolicyAlways);
126 
128  m_jit_process_wp = process->shared_from_this();
129  if (parser.GetGenerateDebugInfo()) {
130  lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
131 
132  if (jit_module_sp) {
133  ConstString const_func_name(FunctionName());
134  FileSpec jit_file;
135  jit_file.GetFilename() = const_func_name;
136  jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
137  m_jit_module_wp = jit_module_sp;
138  target->GetImages().Append(jit_module_sp);
139  }
140  }
141  }
142 
143  DeclMap()->DidParse();
144 
145  ResetDeclMap();
146 
147  if (jit_error.Success()) {
148  return true;
149  } else {
150  const char *error_cstr = jit_error.AsCString();
151  if (error_cstr && error_cstr[0]) {
152  diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
153  } else {
154  diagnostic_manager.PutString(eDiagnosticSeverityError,
155  "expression can't be interpreted or run");
156  }
157  return false;
158  }
159 }
160 
162  ExecutionContext &exe_ctx, bool keep_result_in_memory) {
163  std::shared_ptr<ClangASTImporter> ast_importer;
164  auto *state = exe_ctx.GetTargetSP()->GetPersistentExpressionStateForLanguage(
166  if (state) {
167  auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state);
168  ast_importer = persistent_vars->GetClangASTImporter();
169  }
170  m_expr_decl_map_up = std::make_unique<ClangExpressionDeclMap>(
171  keep_result_in_memory, nullptr, exe_ctx.GetTargetSP(), ast_importer,
172  nullptr);
173 }
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:341
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:96
A class that represents a running process on the host machine.
const lldb::TargetSP & GetTargetSP() const
Get accessor to get the target shared pointer.
std::string m_function_text
The text of the function.
A file utility class.
Definition: FileSpec.h:56
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void DidParse()
Disable the state needed for parsing and IR transformation.
std::shared_ptr< IRExecutionUnit > m_execution_unit_sp
unsigned Parse(DiagnosticManager &diagnostic_manager)
Parse a single expression and convert it to IR using Clang.
Target * GetTargetPtr() const
Returns a pointer to the target object.
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
bool Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override
Install the utility function into a process.
size_t void PutString(DiagnosticSeverity severity, llvm::StringRef str)
size_t Printf(DiagnosticSeverity severity, const char *format,...) __attribute__((format(printf
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
A plug-in interface definition class for debugging a process.
Definition: Process.h:362
Process * GetProcessPtr() const
Returns a pointer to the process object.
lldb::ProcessWP m_jit_process_wp
Expression&#39;s always have to have a target...
Definition: Expression.h:93
bool Success() const
Test for success condition.
Definition: Status.cpp:288
const char * FunctionName() override
Return the function name that should be used for executing the expression.
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:900
lldb::addr_t m_jit_end_addr
The address of the JITted function within the JIT allocation.
Definition: Expression.h:99
A uniqued constant string class.
Definition: ConstString.h:40
ClangUtilityFunction(ExecutionContextScope &exe_scope, const char *text, const char *name)
Constructor.
Non-standardized C, such as K&R.
"lldb/Expression/ClangExpressionParser.h" Encapsulates an instance of Clang that can parse expression...
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:131
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
ExecutionContextScope * GetBestExecutionContextScope() const
ClangExpressionDeclMap * DeclMap()
An error handling class.
Definition: Status.h:44