1 //===-- ClangUserExpression.h -----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_ClangUserExpression_h_
10 #define liblldb_ClangUserExpression_h_
14 #include "ASTResultSynthesizer.h"
15 #include "ASTStructExtractor.h"
16 #include "ClangExpressionDeclMap.h"
17 #include "ClangExpressionHelper.h"
18 #include "ClangExpressionVariable.h"
19 #include "IRForTarget.h"
21 #include "lldb/Core/Address.h"
22 #include "lldb/Core/ClangForward.h"
23 #include "lldb/Expression/LLVMUserExpression.h"
24 #include "lldb/Expression/Materializer.h"
25 #include "lldb/Target/ExecutionContext.h"
26 #include "lldb/lldb-forward.h"
27 #include "lldb/lldb-private.h"
29 namespace lldb_private {
31 /// \class ClangUserExpression ClangUserExpression.h
32 /// "lldb/Expression/ClangUserExpression.h" Encapsulates a single expression
33 /// for use with Clang
35 /// LLDB uses expressions for various purposes, notably to call functions
36 /// and as a backend for the expr command. ClangUserExpression encapsulates
37 /// the objects needed to parse and interpret or JIT an expression. It uses
38 /// the Clang parser to produce LLVM IR from the expression.
39 class ClangUserExpression : public LLVMUserExpression {
41 /// LLVM-style RTTI support.
42 static bool classof(const Expression *E) {
43 return E->getKind() == eKindClangUserExpression;
46 enum { kDefaultTimeout = 500000u };
48 class ClangUserExpressionHelper : public ClangExpressionHelper {
50 ClangUserExpressionHelper(Target &target, bool top_level)
51 : m_target(target), m_top_level(top_level) {}
53 ~ClangUserExpressionHelper() override = default;
55 /// Return the object that the parser should use when resolving external
56 /// values. May be NULL if everything should be self-contained.
57 ClangExpressionDeclMap *DeclMap() override {
58 return m_expr_decl_map_up.get();
61 void ResetDeclMap() { m_expr_decl_map_up.reset(); }
63 void ResetDeclMap(ExecutionContext &exe_ctx,
64 Materializer::PersistentVariableDelegate &result_delegate,
65 bool keep_result_in_memory,
66 ValueObject *ctx_obj);
68 /// Return the object that the parser should allow to access ASTs. May be
69 /// NULL if the ASTs do not need to be transformed.
71 /// \param[in] passthrough
72 /// The ASTConsumer that the returned transformer should send
73 /// the ASTs to after transformation.
75 ASTTransformer(clang::ASTConsumer *passthrough) override;
77 void CommitPersistentDecls() override;
81 std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
82 std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
86 std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
93 /// The expression to parse.
95 /// \param[in] expr_prefix
96 /// If non-NULL, a C string containing translation-unit level
97 /// definitions to be included when the expression is parsed.
99 /// \param[in] language
100 /// If not eLanguageTypeUnknown, a language to use when parsing
101 /// the expression. Currently restricted to those languages
102 /// supported by Clang.
104 /// \param[in] desired_type
105 /// If not eResultTypeAny, the type to use for the expression
108 /// \param[in] ctx_obj
109 /// The object (if any) in which context the expression
110 /// must be evaluated. For details see the comment to
111 /// `UserExpression::Evaluate`.
112 ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
113 llvm::StringRef prefix, lldb::LanguageType language,
114 ResultType desired_type,
115 const EvaluateExpressionOptions &options,
116 ValueObject *ctx_obj);
118 ~ClangUserExpression() override;
120 /// Parse the expression
122 /// \param[in] diagnostic_manager
123 /// A diagnostic manager to report parse errors and warnings to.
125 /// \param[in] exe_ctx
126 /// The execution context to use when looking up entities that
127 /// are needed for parsing (locations of functions, types of
128 /// variables, persistent variables, etc.)
130 /// \param[in] execution_policy
131 /// Determines whether interpretation is possible or mandatory.
133 /// \param[in] keep_result_in_memory
134 /// True if the resulting persistent variable should reside in
135 /// target memory, if applicable.
138 /// True on success (no errors); false otherwise.
139 bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
140 lldb_private::ExecutionPolicy execution_policy,
141 bool keep_result_in_memory, bool generate_debug_info) override;
143 bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request,
144 unsigned complete_pos) override;
146 ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
147 return &m_type_system_helper;
150 ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
152 void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
154 void ResetDeclMap(ExecutionContext &exe_ctx,
155 Materializer::PersistentVariableDelegate &result_delegate,
156 bool keep_result_in_memory) {
157 m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
158 keep_result_in_memory,
162 lldb::ExpressionVariableSP
163 GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
165 bool DidImportCxxModules() const { return m_imported_cpp_modules; }
168 /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
171 void ScanContext(ExecutionContext &exe_ctx,
172 lldb_private::Status &err) override;
174 bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
175 lldb::addr_t struct_address,
176 DiagnosticManager &diagnostic_manager) override;
178 std::vector<std::string> GetModulesToImport(ExecutionContext &exe_ctx);
179 void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager,
180 ExecutionContext &exe_ctx,
181 std::vector<std::string> modules_to_import,
182 bool for_completion);
183 bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
184 ExecutionContext &exe_ctx);
185 bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
186 ExecutionContext &exe_ctx, bool for_completion);
188 ClangUserExpressionHelper m_type_system_helper;
190 class ResultDelegate : public Materializer::PersistentVariableDelegate {
192 ResultDelegate(lldb::TargetSP target) : m_target_sp(target) {}
193 ConstString GetName() override;
194 void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
196 void RegisterPersistentState(PersistentExpressionState *persistent_state);
197 lldb::ExpressionVariableSP &GetVariable();
200 PersistentExpressionState *m_persistent_state;
201 lldb::ExpressionVariableSP m_variable;
202 lldb::TargetSP m_target_sp;
205 /// The language type of the current expression.
206 lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown;
207 /// The include directories that should be used when parsing the expression.
208 std::vector<ConstString> m_include_directories;
210 /// The absolute character position in the transformed source code where the
211 /// user code (as typed by the user) starts. If the variable is empty, then we
212 /// were not able to calculate this position.
213 llvm::Optional<size_t> m_user_expression_start_pos;
214 ResultDelegate m_result_delegate;
216 /// The object (if any) in which context the expression is evaluated.
217 /// See the comment to `UserExpression::Evaluate` for details.
218 ValueObject *m_ctx_obj;
220 /// True iff this expression explicitly imported C++ modules.
221 bool m_imported_cpp_modules = false;
224 } // namespace lldb_private
226 #endif // liblldb_ClangUserExpression_h_