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 "ASTResultSynthesizer.h"
20 #include "ASTStructExtractor.h"
21 #include "ClangExpressionDeclMap.h"
22 #include "ClangExpressionHelper.h"
23 #include "ClangExpressionVariable.h"
24 #include "IRForTarget.h"
25 
26 #include "lldb/Core/Address.h"
27 #include "lldb/Core/ClangForward.h"
28 #include "lldb/Expression/LLVMUserExpression.h"
29 #include "lldb/Expression/Materializer.h"
30 #include "lldb/Target/ExecutionContext.h"
31 #include "lldb/lldb-forward.h"
32 #include "lldb/lldb-private.h"
33 
34 namespace lldb_private {
35 
36 //----------------------------------------------------------------------
37 /// @class ClangUserExpression ClangUserExpression.h
38 /// "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 public:
48   enum { kDefaultTimeout = 500000u };
49 
50   class ClangUserExpressionHelper : public ClangExpressionHelper {
51   public:
52     ClangUserExpressionHelper(Target &target, bool top_level)
53         : m_target(target), m_top_level(top_level) {}
54 
55     ~ClangUserExpressionHelper() override = default;
56 
57     //------------------------------------------------------------------
58     /// Return the object that the parser should use when resolving external
59     /// values.  May be NULL if everything should be self-contained.
60     //------------------------------------------------------------------
61     ClangExpressionDeclMap *DeclMap() override {
62       return m_expr_decl_map_up.get();
63     }
64 
65     void ResetDeclMap() { m_expr_decl_map_up.reset(); }
66 
67     void ResetDeclMap(ExecutionContext &exe_ctx,
68                       Materializer::PersistentVariableDelegate &result_delegate,
69                       bool keep_result_in_memory);
70 
71     //------------------------------------------------------------------
72     /// Return the object that the parser should allow to access ASTs.
73     /// May be NULL if the ASTs do not need to be transformed.
74     ///
75     /// @param[in] passthrough
76     ///     The ASTConsumer that the returned transformer should send
77     ///     the ASTs to after transformation.
78     //------------------------------------------------------------------
79     clang::ASTConsumer *
80     ASTTransformer(clang::ASTConsumer *passthrough) override;
81 
82     void CommitPersistentDecls() override;
83 
84   private:
85     Target &m_target;
86     std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
87     std::unique_ptr<ASTStructExtractor> m_struct_extractor_up; ///< The class
88                                                                ///that generates
89                                                                ///the argument
90                                                                ///struct layout.
91     std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
92     bool m_top_level;
93   };
94 
95   //------------------------------------------------------------------
96   /// Constructor
97   ///
98   /// @param[in] expr
99   ///     The expression to parse.
100   ///
101   /// @param[in] expr_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   ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
115                       llvm::StringRef prefix, lldb::LanguageType language,
116                       ResultType desired_type,
117                       const EvaluateExpressionOptions &options);
118 
119   ~ClangUserExpression() override;
120 
121   //------------------------------------------------------------------
122   /// Parse the expression
123   ///
124   /// @param[in] diagnostic_manager
125   ///     A diagnostic manager to report parse errors and warnings to.
126   ///
127   /// @param[in] exe_ctx
128   ///     The execution context to use when looking up entities that
129   ///     are needed for parsing (locations of functions, types of
130   ///     variables, persistent variables, etc.)
131   ///
132   /// @param[in] execution_policy
133   ///     Determines whether interpretation is possible or mandatory.
134   ///
135   /// @param[in] keep_result_in_memory
136   ///     True if the resulting persistent variable should reside in
137   ///     target memory, if applicable.
138   ///
139   /// @return
140   ///     True on success (no errors); false otherwise.
141   //------------------------------------------------------------------
142   bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
143              lldb_private::ExecutionPolicy execution_policy,
144              bool keep_result_in_memory, bool generate_debug_info) override;
145 
146   ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
147     return &m_type_system_helper;
148   }
149 
150   ClangExpressionDeclMap *DeclMap() { return m_type_system_helper.DeclMap(); }
151 
152   void ResetDeclMap() { m_type_system_helper.ResetDeclMap(); }
153 
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);
159   }
160 
161   lldb::ExpressionVariableSP
162   GetResultAfterDematerialization(ExecutionContextScope *exe_scope) override;
163 
164 private:
165   //------------------------------------------------------------------
166   /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the
167   /// environment.
168   //------------------------------------------------------------------
169 
170   void ScanContext(ExecutionContext &exe_ctx,
171                    lldb_private::Error &err) override;
172 
173   bool AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args,
174                     lldb::addr_t struct_address,
175                     DiagnosticManager &diagnostic_manager) override;
176 
177   ClangUserExpressionHelper m_type_system_helper;
178 
179   class ResultDelegate : public Materializer::PersistentVariableDelegate {
180   public:
181     ResultDelegate();
182     ConstString GetName() override;
183     void DidDematerialize(lldb::ExpressionVariableSP &variable) override;
184 
185     void RegisterPersistentState(PersistentExpressionState *persistent_state);
186     lldb::ExpressionVariableSP &GetVariable();
187 
188   private:
189     PersistentExpressionState *m_persistent_state;
190     lldb::ExpressionVariableSP m_variable;
191   };
192 
193   ResultDelegate m_result_delegate;
194 };
195 
196 } // namespace lldb_private
197 
198 #endif // liblldb_ClangUserExpression_h_
199