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:
56 ClangUserExpressionHelper(Target &target, bool top_level)
57 : m_target(target), m_top_level(top_level) {}
58
59 ~ClangUserExpressionHelper() override = default;
60
61 /// Return the object that the parser should use when resolving external
62 /// values. May be NULL if everything should be self-contained.
64 return m_expr_decl_map_up.get();
65 }
66
67 void ResetDeclMap() { m_expr_decl_map_up.reset(); }
68
69 void ResetDeclMap(ExecutionContext &exe_ctx,
71 bool keep_result_in_memory,
72 ValueObject *ctx_obj);
73
74 /// Return the object that the parser should allow to access ASTs. May be
75 /// NULL if the ASTs do not need to be transformed.
76 ///
77 /// \param[in] passthrough
78 /// The ASTConsumer that the returned transformer should send
79 /// the ASTs to after transformation.
80 clang::ASTConsumer *
81 ASTTransformer(clang::ASTConsumer *passthrough) override;
82
83 void CommitPersistentDecls() override;
84
85 private:
87 std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
88 std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
89 ///that generates
90 ///the argument
91 ///struct layout.
92 std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
94 };
95
96 /// Constructor
97 ///
98 /// \param[in] expr
99 /// The expression to parse.
100 ///
101 /// \param[in] prefix
102 /// If non-NULL, a C string containing translation-unit level
103 /// definitions to be included when the expression is parsed.
104 ///
105 /// \param[in] language
106 /// If not eLanguageTypeUnknown, a language to use when parsing
107 /// the expression. Currently restricted to those languages
108 /// supported by Clang.
109 ///
110 /// \param[in] desired_type
111 /// If not eResultTypeAny, the type to use for the expression
112 /// result.
113 ///
114 /// \param[in] options
115 /// Additional options for the expression.
116 ///
117 /// \param[in] ctx_obj
118 /// The object (if any) in which context the expression
119 /// must be evaluated. For details see the comment to
120 /// `UserExpression::Evaluate`.
121 ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
122 llvm::StringRef prefix, lldb::LanguageType language,
123 ResultType desired_type,
124 const EvaluateExpressionOptions &options,
125 ValueObject *ctx_obj);
126
128
129 /// Parse the expression
130 ///
131 /// \param[in] diagnostic_manager
132 /// A diagnostic manager to report parse errors and warnings to.
133 ///
134 /// \param[in] exe_ctx
135 /// The execution context to use when looking up entities that
136 /// are needed for parsing (locations of functions, types of
137 /// variables, persistent variables, etc.)
138 ///
139 /// \param[in] execution_policy
140 /// Determines whether interpretation is possible or mandatory.
141 ///
142 /// \param[in] keep_result_in_memory
143 /// True if the resulting persistent variable should reside in
144 /// target memory, if applicable.
145 ///
146 /// \return
147 /// True on success (no errors); false otherwise.
148 bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
149 lldb_private::ExecutionPolicy execution_policy,
150 bool keep_result_in_memory, bool generate_debug_info) override;
151
152 bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request,
153 unsigned complete_pos) override;
154
156 return &m_type_system_helper;
157 }
158
160
162
165 bool keep_result_in_memory) {
166 m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
167 keep_result_in_memory,
168 m_ctx_obj);
169 }
170
171 lldb::ExpressionVariableSP
173
174 /// Returns true iff this expression is using any imported C++ modules.
175 bool DidImportCxxModules() const { return !m_imported_cpp_modules.empty(); }
176
177private:
178 /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
179 /// environment.
180
181 /// Contains the actual parsing implementation.
182 /// The parameter have the same meaning as in ClangUserExpression::Parse.
183 /// \see ClangUserExpression::Parse
184 bool TryParse(DiagnosticManager &diagnostic_manager,
185 ExecutionContextScope *exe_scope, ExecutionContext &exe_ctx,
186 lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
187 bool generate_debug_info);
188
190
191 void ScanContext(ExecutionContext &exe_ctx,
192 lldb_private::Status &err) override;
193
194 bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
195 lldb::addr_t struct_address,
196 DiagnosticManager &diagnostic_manager) override;
197
198 void CreateSourceCode(DiagnosticManager &diagnostic_manager,
199 ExecutionContext &exe_ctx,
200 std::vector<std::string> modules_to_import,
201 bool for_completion);
202
203 lldb::addr_t GetCppObjectPointer(lldb::StackFrameSP frame,
204 ConstString &object_name, Status &err);
205
206 /// Defines how the current expression should be wrapped.
208 bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
209 ExecutionContext &exe_ctx);
210 bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
211 ExecutionContext &exe_ctx, bool for_completion);
212
214
216 public:
217 ResultDelegate(lldb::TargetSP target) : m_target_sp(target) {}
218 ConstString GetName() override;
219 void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
220
222 lldb::ExpressionVariableSP &GetVariable();
223
224 private:
226 lldb::ExpressionVariableSP m_variable;
227 lldb::TargetSP m_target_sp;
228 };
229
230 /// The include directories that should be used when parsing the expression.
231 std::vector<std::string> m_include_directories;
232
233 /// The absolute character position in the transformed source code where the
234 /// user code (as typed by the user) starts. If the variable is empty, then we
235 /// were not able to calculate this position.
236 std::optional<size_t> m_user_expression_start_pos;
239 std::unique_ptr<ClangExpressionSourceCode> m_source_code;
240 /// The parser instance we used to parse the expression.
241 std::unique_ptr<ClangExpressionParser> m_parser;
242 /// File name used for the expression.
243 std::string m_filename;
244
245 /// The object (if any) in which context the expression is evaluated.
246 /// See the comment to `UserExpression::Evaluate` for details.
248
249 /// A list of module names that should be imported when parsing.
250 /// \see CppModuleConfiguration::GetImportedModules
251 std::vector<std::string> m_imported_cpp_modules;
252
253 /// True if the expression parser should enforce the presence of a valid class
254 /// pointer in order to generate the expression as a method.
256 /// True if the expression is compiled as a C++ member function (true if it
257 /// was parsed when exe_ctx was in a C++ method).
259 /// True if the expression is compiled as an Objective-C method (true if it
260 /// was parsed when exe_ctx was in an Objective-C method).
262 /// True if the expression is compiled as a static (or class) method
263 /// (currently true if it was parsed when exe_ctx was in an Objective-C class
264 /// method).
265 bool m_in_static_method = false;
266 /// True if "this" or "self" must be looked up and passed in. False if the
267 /// expression doesn't really use them and they can be NULL.
268 bool m_needs_object_ptr = false;
269};
270
271} // namespace lldb_private
272
273#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)
lldb::addr_t GetCppObjectPointer(lldb::StackFrameSP frame, ConstString &object_name, Status &err)
ClangExpressionSourceCode::WrapKind GetWrapKind() const
Defines how the current expression should be wrapped.
bool TryParse(DiagnosticManager &diagnostic_manager, ExecutionContextScope *exe_scope, 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.
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.
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
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:39
"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:33
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
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
ExecutionPolicy
Expression execution policies.
LanguageType
Programming language type.
uint64_t addr_t
Definition: lldb-types.h:79