1 //===-- ClangUserExpression.h -----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_ClangUserExpression_h_
11 #define liblldb_ClangUserExpression_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <vector>
16 
17 // Other libraries and framework includes
18 // Project includes
19 #include "ASTStructExtractor.h"
20 #include "ASTResultSynthesizer.h"
21 #include "ClangExpressionDeclMap.h"
22 #include "ClangExpressionHelper.h"
23 #include "ClangExpressionVariable.h"
24 #include "IRForTarget.h"
25 
26 #include "lldb/lldb-forward.h"
27 #include "lldb/lldb-private.h"
28 #include "lldb/Core/Address.h"
29 #include "lldb/Core/ClangForward.h"
30 #include "lldb/Expression/LLVMUserExpression.h"
31 #include "lldb/Expression/Materializer.h"
32 #include "lldb/Target/ExecutionContext.h"
33 
34 namespace lldb_private
35 {
36 
37 //----------------------------------------------------------------------
38 /// @class ClangUserExpression ClangUserExpression.h "lldb/Expression/ClangUserExpression.h"
39 /// @brief Encapsulates a single expression for use with Clang
40 ///
41 /// LLDB uses expressions for various purposes, notably to call functions
42 /// and as a backend for the expr command.  ClangUserExpression encapsulates
43 /// the objects needed to parse and interpret or JIT an expression.  It
44 /// uses the Clang parser to produce LLVM IR from the expression.
45 //----------------------------------------------------------------------
46 class ClangUserExpression : public LLVMUserExpression
47 {
48 public:
49     enum { kDefaultTimeout = 500000u };
50 
51     class ClangUserExpressionHelper : public ClangExpressionHelper
52     {
53     public:
54         ClangUserExpressionHelper(Target &target, bool top_level) : m_target(target), m_top_level(top_level) {}
55 
56         ~ClangUserExpressionHelper() override = default;
57 
58         //------------------------------------------------------------------
59         /// Return the object that the parser should use when resolving external
60         /// values.  May be NULL if everything should be self-contained.
61         //------------------------------------------------------------------
62         ClangExpressionDeclMap *
63         DeclMap() override
64         {
65             return m_expr_decl_map_up.get();
66         }
67 
68         void
69         ResetDeclMap()
70         {
71             m_expr_decl_map_up.reset();
72         }
73 
74         void
75         ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory);
76 
77         //------------------------------------------------------------------
78         /// Return the object that the parser should allow to access ASTs.
79         /// May be NULL if the ASTs do not need to be transformed.
80         ///
81         /// @param[in] passthrough
82         ///     The ASTConsumer that the returned transformer should send
83         ///     the ASTs to after transformation.
84         //------------------------------------------------------------------
85         clang::ASTConsumer *
86         ASTTransformer(clang::ASTConsumer *passthrough) override;
87 
88         void
89         CommitPersistentDecls() override;
90 
91     private:
92         Target &m_target;
93         std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
94         std::unique_ptr<ASTStructExtractor>
95             m_struct_extractor_up; ///< The class that generates the argument struct layout.
96         std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
97         bool m_top_level;
98     };
99 
100     //------------------------------------------------------------------
101     /// Constructor
102     ///
103     /// @param[in] expr
104     ///     The expression to parse.
105     ///
106     /// @param[in] expr_prefix
107     ///     If non-NULL, a C string containing translation-unit level
108     ///     definitions to be included when the expression is parsed.
109     ///
110     /// @param[in] language
111     ///     If not eLanguageTypeUnknown, a language to use when parsing
112     ///     the expression.  Currently restricted to those languages
113     ///     supported by Clang.
114     ///
115     /// @param[in] desired_type
116     ///     If not eResultTypeAny, the type to use for the expression
117     ///     result.
118     //------------------------------------------------------------------
119     ClangUserExpression (ExecutionContextScope &exe_scope,
120                          const char *expr,
121                          const char *expr_prefix,
122                          lldb::LanguageType language,
123                          ResultType desired_type,
124                          const EvaluateExpressionOptions &options);
125 
126     ~ClangUserExpression() override;
127 
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     //------------------------------------------------------------------
149     bool
150     Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
151           lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory,
152           bool generate_debug_info) override;
153 
154     ExpressionTypeSystemHelper *
155     GetTypeSystemHelper () override
156     {
157         return &m_type_system_helper;
158     }
159 
160     ClangExpressionDeclMap *
161     DeclMap ()
162     {
163         return m_type_system_helper.DeclMap();
164     }
165 
166     void
167     ResetDeclMap ()
168     {
169         m_type_system_helper.ResetDeclMap();
170     }
171 
172     void
173     ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory)
174     {
175         m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate, keep_result_in_memory);
176     }
177 
178     lldb::ExpressionVariableSP
179     GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
180 
181 private:
182     //------------------------------------------------------------------
183     /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
184     //------------------------------------------------------------------
185 
186     void
187     ScanContext (ExecutionContext &exe_ctx,
188                  lldb_private::Error &err) override;
189 
190     bool
191     AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address,
192                  DiagnosticManager &diagnostic_manager) override;
193 
194     ClangUserExpressionHelper m_type_system_helper;
195 
196     class ResultDelegate : public Materializer::PersistentVariableDelegate
197     {
198     public:
199         ResultDelegate();
200         ConstString GetName() override;
201         void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
202 
203         void RegisterPersistentState(PersistentExpressionState *persistent_state);
204         lldb::ExpressionVariableSP &GetVariable();
205 
206     private:
207         PersistentExpressionState *m_persistent_state;
208         lldb::ExpressionVariableSP m_variable;
209     };
210 
211     ResultDelegate                                          m_result_delegate;
212 };
213 
214 } // namespace lldb_private
215 
216 #endif // liblldb_ClangUserExpression_h_
217