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) :
55             m_target(target)
56         {
57         }
58 
59         ~ClangUserExpressionHelper() override = default;
60 
61         //------------------------------------------------------------------
62         /// Return the object that the parser should use when resolving external
63         /// values.  May be NULL if everything should be self-contained.
64         //------------------------------------------------------------------
65         ClangExpressionDeclMap *
66         DeclMap() override
67         {
68             return m_expr_decl_map_up.get();
69         }
70 
71         void
72         ResetDeclMap()
73         {
74             m_expr_decl_map_up.reset();
75         }
76 
77         void
78         ResetDeclMap (ExecutionContext & exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory);
79 
80         //------------------------------------------------------------------
81         /// Return the object that the parser should allow to access ASTs.
82         /// May be NULL if the ASTs do not need to be transformed.
83         ///
84         /// @param[in] passthrough
85         ///     The ASTConsumer that the returned transformer should send
86         ///     the ASTs to after transformation.
87         //------------------------------------------------------------------
88         clang::ASTConsumer *
89         ASTTransformer(clang::ASTConsumer *passthrough) override;
90 
91     private:
92         Target                                  &m_target;
93         std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
94         std::unique_ptr<ASTStructExtractor> m_struct_extractor_up;         ///< The class that generates the argument struct layout.
95         std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
96     };
97 
98     //------------------------------------------------------------------
99     /// Constructor
100     ///
101     /// @param[in] expr
102     ///     The expression to parse.
103     ///
104     /// @param[in] expr_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     ClangUserExpression (ExecutionContextScope &exe_scope,
118                          const char *expr,
119                          const char *expr_prefix,
120                          lldb::LanguageType language,
121                          ResultType desired_type,
122                          const EvaluateExpressionOptions &options);
123 
124     ~ClangUserExpression() override;
125 
126     //------------------------------------------------------------------
127     /// Parse the expression
128     ///
129     /// @param[in] error_stream
130     ///     A stream to print parse errors and warnings to.
131     ///
132     /// @param[in] exe_ctx
133     ///     The execution context to use when looking up entities that
134     ///     are needed for parsing (locations of functions, types of
135     ///     variables, persistent variables, etc.)
136     ///
137     /// @param[in] execution_policy
138     ///     Determines whether interpretation is possible or mandatory.
139     ///
140     /// @param[in] keep_result_in_memory
141     ///     True if the resulting persistent variable should reside in
142     ///     target memory, if applicable.
143     ///
144     /// @return
145     ///     True on success (no errors); false otherwise.
146     //------------------------------------------------------------------
147     bool
148     Parse (Stream &error_stream,
149            ExecutionContext &exe_ctx,
150            lldb_private::ExecutionPolicy execution_policy,
151            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,
192                   std::vector<lldb::addr_t> &args,
193                   lldb::addr_t struct_address,
194                   Stream &error_stream) override;
195 
196     ClangUserExpressionHelper   m_type_system_helper;
197 
198     class ResultDelegate : public Materializer::PersistentVariableDelegate
199     {
200     public:
201         ResultDelegate();
202         ConstString GetName() override;
203         void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
204 
205         void RegisterPersistentState(PersistentExpressionState *persistent_state);
206         lldb::ExpressionVariableSP &GetVariable();
207 
208     private:
209         PersistentExpressionState *m_persistent_state;
210         lldb::ExpressionVariableSP m_variable;
211     };
212 
213     ResultDelegate                                          m_result_delegate;
214 };
215 
216 } // namespace lldb_private
217 
218 #endif // liblldb_ClangUserExpression_h_
219