Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
39654 views
1
//===-- ClangUserExpression.h -----------------------------------*- 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
#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
10
#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
11
12
#include <optional>
13
#include <vector>
14
15
#include "ASTResultSynthesizer.h"
16
#include "ASTStructExtractor.h"
17
#include "ClangExpressionDeclMap.h"
18
#include "ClangExpressionHelper.h"
19
#include "ClangExpressionSourceCode.h"
20
#include "ClangExpressionVariable.h"
21
#include "IRForTarget.h"
22
23
#include "lldb/Core/Address.h"
24
#include "lldb/Expression/LLVMUserExpression.h"
25
#include "lldb/Expression/Materializer.h"
26
#include "lldb/Target/ExecutionContext.h"
27
#include "lldb/lldb-forward.h"
28
#include "lldb/lldb-private.h"
29
30
namespace lldb_private {
31
32
class ClangExpressionParser;
33
34
/// \class ClangUserExpression ClangUserExpression.h
35
/// "lldb/Expression/ClangUserExpression.h" Encapsulates a single expression
36
/// for use with Clang
37
///
38
/// LLDB uses expressions for various purposes, notably to call functions
39
/// and as a backend for the expr command. ClangUserExpression encapsulates
40
/// the objects needed to parse and interpret or JIT an expression. It uses
41
/// the Clang parser to produce LLVM IR from the expression.
42
class ClangUserExpression : public LLVMUserExpression {
43
// LLVM RTTI support
44
static char ID;
45
46
public:
47
bool isA(const void *ClassID) const override {
48
return ClassID == &ID || LLVMUserExpression::isA(ClassID);
49
}
50
static bool classof(const Expression *obj) { return obj->isA(&ID); }
51
52
enum { kDefaultTimeout = 500000u };
53
54
class ClangUserExpressionHelper
55
: public llvm::RTTIExtends<ClangUserExpressionHelper,
56
ClangExpressionHelper> {
57
public:
58
// LLVM RTTI support
59
static char ID;
60
61
ClangUserExpressionHelper(Target &target, bool top_level)
62
: m_target(target), m_top_level(top_level) {}
63
64
/// Return the object that the parser should use when resolving external
65
/// values. May be NULL if everything should be self-contained.
66
ClangExpressionDeclMap *DeclMap() override {
67
return m_expr_decl_map_up.get();
68
}
69
70
void ResetDeclMap() { m_expr_decl_map_up.reset(); }
71
72
void ResetDeclMap(ExecutionContext &exe_ctx,
73
Materializer::PersistentVariableDelegate &result_delegate,
74
bool keep_result_in_memory,
75
ValueObject *ctx_obj);
76
77
/// Return the object that the parser should allow to access ASTs. May be
78
/// NULL if the ASTs do not need to be transformed.
79
///
80
/// \param[in] passthrough
81
/// The ASTConsumer that the returned transformer should send
82
/// the ASTs to after transformation.
83
clang::ASTConsumer *
84
ASTTransformer(clang::ASTConsumer *passthrough) override;
85
86
void CommitPersistentDecls() override;
87
88
private:
89
Target &m_target;
90
std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
91
std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
92
///that generates
93
///the argument
94
///struct layout.
95
std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
96
bool m_top_level;
97
};
98
99
/// Constructor
100
///
101
/// \param[in] expr
102
/// The expression to parse.
103
///
104
/// \param[in] prefix
105
/// If non-NULL, a C string containing translation-unit level
106
/// definitions to be included when the expression is parsed.
107
///
108
/// \param[in] language
109
/// If not unknown, a language to use when parsing the
110
/// expression. Currently restricted to those languages
111
/// supported by Clang.
112
///
113
/// \param[in] desired_type
114
/// If not eResultTypeAny, the type to use for the expression
115
/// result.
116
///
117
/// \param[in] options
118
/// Additional options for the expression.
119
///
120
/// \param[in] ctx_obj
121
/// The object (if any) in which context the expression
122
/// must be evaluated. For details see the comment to
123
/// `UserExpression::Evaluate`.
124
ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
125
llvm::StringRef prefix, SourceLanguage language,
126
ResultType desired_type,
127
const EvaluateExpressionOptions &options,
128
ValueObject *ctx_obj);
129
130
~ClangUserExpression() override;
131
132
/// Parse the expression
133
///
134
/// \param[in] diagnostic_manager
135
/// A diagnostic manager to report parse errors and warnings to.
136
///
137
/// \param[in] exe_ctx
138
/// The execution context to use when looking up entities that
139
/// are needed for parsing (locations of functions, types of
140
/// variables, persistent variables, etc.)
141
///
142
/// \param[in] execution_policy
143
/// Determines whether interpretation is possible or mandatory.
144
///
145
/// \param[in] keep_result_in_memory
146
/// True if the resulting persistent variable should reside in
147
/// target memory, if applicable.
148
///
149
/// \return
150
/// True on success (no errors); false otherwise.
151
bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
152
lldb_private::ExecutionPolicy execution_policy,
153
bool keep_result_in_memory, bool generate_debug_info) override;
154
155
bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request,
156
unsigned complete_pos) override;
157
158
ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
159
return &m_type_system_helper;
160
}
161
162
ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
163
164
void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
165
166
void ResetDeclMap(ExecutionContext &exe_ctx,
167
Materializer::PersistentVariableDelegate &result_delegate,
168
bool keep_result_in_memory) {
169
m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
170
keep_result_in_memory,
171
m_ctx_obj);
172
}
173
174
lldb::ExpressionVariableSP
175
GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
176
177
/// Returns true iff this expression is using any imported C++ modules.
178
bool DidImportCxxModules() const { return !m_imported_cpp_modules.empty(); }
179
180
private:
181
/// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
182
/// environment.
183
184
/// Contains the actual parsing implementation.
185
/// The parameter have the same meaning as in ClangUserExpression::Parse.
186
/// \see ClangUserExpression::Parse
187
bool TryParse(DiagnosticManager &diagnostic_manager,
188
ExecutionContext &exe_ctx,
189
lldb_private::ExecutionPolicy execution_policy,
190
bool keep_result_in_memory, bool generate_debug_info);
191
192
void SetupCppModuleImports(ExecutionContext &exe_ctx);
193
194
void ScanContext(ExecutionContext &exe_ctx,
195
lldb_private::Status &err) override;
196
197
bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
198
lldb::addr_t struct_address,
199
DiagnosticManager &diagnostic_manager) override;
200
201
void CreateSourceCode(DiagnosticManager &diagnostic_manager,
202
ExecutionContext &exe_ctx,
203
std::vector<std::string> modules_to_import,
204
bool for_completion);
205
206
lldb::addr_t GetCppObjectPointer(lldb::StackFrameSP frame,
207
llvm::StringRef object_name, Status &err);
208
209
/// Defines how the current expression should be wrapped.
210
ClangExpressionSourceCode::WrapKind GetWrapKind() const;
211
bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
212
ExecutionContext &exe_ctx);
213
bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
214
ExecutionContext &exe_ctx, bool for_completion);
215
216
ClangUserExpressionHelper m_type_system_helper;
217
218
class ResultDelegate : public Materializer::PersistentVariableDelegate {
219
public:
220
ResultDelegate(lldb::TargetSP target) : m_target_sp(target) {}
221
ConstString GetName() override;
222
void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
223
224
void RegisterPersistentState(PersistentExpressionState *persistent_state);
225
lldb::ExpressionVariableSP &GetVariable();
226
227
private:
228
PersistentExpressionState *m_persistent_state;
229
lldb::ExpressionVariableSP m_variable;
230
lldb::TargetSP m_target_sp;
231
};
232
233
/// The include directories that should be used when parsing the expression.
234
std::vector<std::string> m_include_directories;
235
236
/// The absolute character position in the transformed source code where the
237
/// user code (as typed by the user) starts. If the variable is empty, then we
238
/// were not able to calculate this position.
239
std::optional<size_t> m_user_expression_start_pos;
240
ResultDelegate m_result_delegate;
241
ClangPersistentVariables *m_clang_state;
242
std::unique_ptr<ClangExpressionSourceCode> m_source_code;
243
/// The parser instance we used to parse the expression.
244
std::unique_ptr<ClangExpressionParser> m_parser;
245
/// File name used for the expression.
246
std::string m_filename;
247
248
/// The object (if any) in which context the expression is evaluated.
249
/// See the comment to `UserExpression::Evaluate` for details.
250
ValueObject *m_ctx_obj;
251
252
/// A list of module names that should be imported when parsing.
253
/// \see CppModuleConfiguration::GetImportedModules
254
std::vector<std::string> m_imported_cpp_modules;
255
256
/// True if the expression parser should enforce the presence of a valid class
257
/// pointer in order to generate the expression as a method.
258
bool m_enforce_valid_object = true;
259
/// True if the expression is compiled as a C++ member function (true if it
260
/// was parsed when exe_ctx was in a C++ method).
261
bool m_in_cplusplus_method = false;
262
/// True if the expression is compiled as an Objective-C method (true if it
263
/// was parsed when exe_ctx was in an Objective-C method).
264
bool m_in_objectivec_method = false;
265
/// True if the expression is compiled as a static (or class) method
266
/// (currently true if it was parsed when exe_ctx was in an Objective-C class
267
/// method).
268
bool m_in_static_method = false;
269
/// True if "this" or "self" must be looked up and passed in. False if the
270
/// expression doesn't really use them and they can be NULL.
271
bool m_needs_object_ptr = false;
272
};
273
274
} // namespace lldb_private
275
276
#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGUSEREXPRESSION_H
277
278