LLDB mainline
ClangUserExpression.h
Go to the documentation of this file.
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
16#include "ASTStructExtractor.h"
21#include "IRForTarget.h"
22
23#include "lldb/Core/Address.h"
27#include "lldb/lldb-forward.h"
28#include "lldb/lldb-private.h"
29
30namespace lldb_private {
31
32class 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.
43 // LLVM RTTI support
44 static char ID;
45
46public:
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
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.
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,
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:
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;
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 eLanguageTypeUnknown, a language to use when parsing
110 /// the 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, lldb::LanguageType language,
126 ResultType desired_type,
127 const EvaluateExpressionOptions &options,
128 ValueObject *ctx_obj);
129
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
159 return &m_type_system_helper;
160 }
161
163
165
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
176
177 /// Returns true iff this expression is using any imported C++ modules.
178 bool DidImportCxxModules() const { return !m_imported_cpp_modules.empty(); }
179
180private:
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
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
207 llvm::StringRef object_name, Status &err);
208
209 /// Defines how the current expression should be wrapped.
211 bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
212 ExecutionContext &exe_ctx);
213 bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
214 ExecutionContext &exe_ctx, bool for_completion);
215
217
219 public:
221 ConstString GetName() override;
222 void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
223
226
227 private:
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;
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.
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.
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).
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).
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
"lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are defined in LLDB's debug in...
WrapKind
The possible ways an expression can be wrapped.
"lldb/Expression/ClangPersistentVariables.h" Manages persistent values that need to be preserved betw...
ClangExpressionDeclMap * DeclMap() override
Return the object that the parser should use when resolving external values.
std::unique_ptr< ASTStructExtractor > m_struct_extractor_up
The class that generates the argument struct layout.
clang::ASTConsumer * ASTTransformer(clang::ASTConsumer *passthrough) override
Return the object that the parser should allow to access ASTs.
std::unique_ptr< ClangExpressionDeclMap > m_expr_decl_map_up
std::unique_ptr< ASTResultSynthesizer > m_result_synthesizer_up
void RegisterPersistentState(PersistentExpressionState *persistent_state)
void DidDematerialize(lldb::ExpressionVariableSP &variable) override
"lldb/Expression/ClangUserExpression.h" Encapsulates a single expression for use with Clang
bool isA(const void *ClassID) const override
bool m_enforce_valid_object
True if the expression parser should enforce the presence of a valid class pointer in order to genera...
std::string m_filename
File name used for the expression.
lldb::ExpressionVariableSP GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override
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...
void CreateSourceCode(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, std::vector< std::string > modules_to_import, bool for_completion)
static bool classof(const Expression *obj)
ClangExpressionSourceCode::WrapKind GetWrapKind() const
Defines how the current expression should be wrapped.
std::unique_ptr< ClangExpressionParser > m_parser
The parser instance we used to parse the expression.
void SetupCppModuleImports(ExecutionContext &exe_ctx)
bool PrepareForParsing(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, bool for_completion)
bool m_needs_object_ptr
True if "this" or "self" must be looked up and passed in.
ClangExpressionDeclMap * DeclMap()
ExpressionTypeSystemHelper * GetTypeSystemHelper() override
bool SetupPersistentState(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx)
bool m_in_static_method
True if the expression is compiled as a static (or class) method (currently true if it was parsed whe...
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.
bool TryParse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info)
Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
void ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory)
std::optional< size_t > m_user_expression_start_pos
The absolute character position in the transformed source code where the user code (as typed by the u...
bool DidImportCxxModules() const
Returns true iff this expression is using any imported C++ modules.
bool AddArguments(ExecutionContext &exe_ctx, std::vector< lldb::addr_t > &args, lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager) override
lldb::addr_t GetCppObjectPointer(lldb::StackFrameSP frame, llvm::StringRef object_name, Status &err)
std::unique_ptr< ClangExpressionSourceCode > m_source_code
std::vector< std::string > m_imported_cpp_modules
A list of module names that should be imported when parsing.
ClangUserExpressionHelper m_type_system_helper
ClangPersistentVariables * m_clang_state
void ScanContext(ExecutionContext &exe_ctx, lldb_private::Status &err) override
bool m_in_cplusplus_method
True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was i...
std::vector< std::string > m_include_directories
The include directories that should be used when parsing the expression.
ValueObject * m_ctx_obj
The object (if any) in which context the expression is evaluated.
"lldb/Utility/ArgCompletionRequest.h"
A uniqued constant string class.
Definition: ConstString.h:40
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
"lldb/Expression/ExpressionTypeSystemHelper.h" A helper object that the Expression can pass to its Ex...
Encapsulates a single expression for use in lldb.
Definition: Expression.h:31
virtual bool isA(const void *ClassID) const =0
"lldb/Expression/LLVMUserExpression.h" Encapsulates a one-time expression for use in lldb.
bool isA(const void *ClassID) const override
An error handling class.
Definition: Status.h:44
@ Complete
Editing complete, returns the complete set of edited lines.
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
ExecutionPolicy
Expression execution policies.
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
Definition: lldb-forward.h:412
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
Definition: lldb-forward.h:343
LanguageType
Programming language type.
uint64_t addr_t
Definition: lldb-types.h:79
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:436