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 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
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
180 llvm::StringRef GetFilename() const { return m_filename; }
181
182private:
183 /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
184 /// environment.
185
186 /// Contains the actual parsing implementation.
187 /// The parameter have the same meaning as in ClangUserExpression::Parse.
188 /// \see ClangUserExpression::Parse
189 bool TryParse(DiagnosticManager &diagnostic_manager,
190 ExecutionContext &exe_ctx,
191 lldb_private::ExecutionPolicy execution_policy,
192 bool keep_result_in_memory, bool generate_debug_info);
193
195
196 void ScanContext(ExecutionContext &exe_ctx,
197 lldb_private::Status &err) override;
198
199 bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
200 lldb::addr_t struct_address,
201 DiagnosticManager &diagnostic_manager) override;
202
203 void CreateSourceCode(DiagnosticManager &diagnostic_manager,
204 ExecutionContext &exe_ctx,
205 std::vector<std::string> modules_to_import,
206 bool for_completion);
207
209 llvm::StringRef object_name, Status &err);
210
211 /// Defines how the current expression should be wrapped.
213 bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
214 ExecutionContext &exe_ctx);
215 bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
216 ExecutionContext &exe_ctx, bool for_completion);
217
219
221 public:
223 ConstString GetName() override;
224 void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
225
228
229 private:
233 };
234
235 /// The include directories that should be used when parsing the expression.
236 std::vector<std::string> m_include_directories;
237
238 /// The absolute character position in the transformed source code where the
239 /// user code (as typed by the user) starts. If the variable is empty, then we
240 /// were not able to calculate this position.
241 std::optional<size_t> m_user_expression_start_pos;
244 std::unique_ptr<ClangExpressionSourceCode> m_source_code;
245 /// The parser instance we used to parse the expression.
246 std::unique_ptr<ClangExpressionParser> m_parser;
247 /// File name used for the expression.
248 std::string m_filename;
249
250 /// The object (if any) in which context the expression is evaluated.
251 /// See the comment to `UserExpression::Evaluate` for details.
253
254 /// A list of module names that should be imported when parsing.
255 /// \see CppModuleConfiguration::GetImportedModules
256 std::vector<std::string> m_imported_cpp_modules;
257
258 /// True if the expression parser should enforce the presence of a valid class
259 /// pointer in order to generate the expression as a method.
261 /// True if the expression is compiled as a C++ member function (true if it
262 /// was parsed when exe_ctx was in a C++ method).
264 /// True if the expression is compiled as an Objective-C method (true if it
265 /// was parsed when exe_ctx was in an Objective-C method).
267 /// True if the expression is compiled as a static (or class) method
268 /// (currently true if it was parsed when exe_ctx was in an Objective-C class
269 /// method).
270 bool m_in_static_method = false;
271 /// True if "this" or "self" must be looked up and passed in. False if the
272 /// expression doesn't really use them and they can be NULL.
273 bool m_needs_object_ptr = false;
274};
275
276} // namespace lldb_private
277
278#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:118
@ Complete
Editing complete, returns the complete set of edited lines.
A class that represents a running process on the host machine.
ExecutionPolicy
Expression execution policies.
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
Definition: lldb-forward.h:424
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
Definition: lldb-forward.h:351
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:448
A type-erased pair of llvm::dwarf::SourceLanguageName and version.