ClangExpressionVariable.h revision 66ed2fbeaf588fe4105a1305f7e956dcf9fbe299
1//===-- ClangExpressionVariable.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_ClangExpressionVariable_h_
11#define liblldb_ClangExpressionVariable_h_
12
13// C Includes
14#include <signal.h>
15#include <stdint.h>
16
17// C++ Includes
18#include <string>
19#include <vector>
20
21// Other libraries and framework includes
22// Project includes
23#include "lldb/Core/ClangForward.h"
24#include "lldb/Symbol/TaggedASTType.h"
25
26namespace llvm {
27    class Value;
28}
29
30namespace lldb_private {
31
32class ClangExpressionVariableStore;
33class DataBufferHeap;
34class ExecutionContext;
35class Stream;
36class Value;
37
38//----------------------------------------------------------------------
39/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
40/// @brief Encapsulates one variable for the expression parser.
41///
42/// The expression parser uses variables in three different contexts:
43///
44/// First, it stores persistent variables along with the process for use
45/// in expressions.  These persistent variables contain their own data
46/// and are typed.
47///
48/// Second, in an interpreted expression, it stores the local variables
49/// for the expression along with the expression.  These variables
50/// contain their own data and are typed.
51///
52/// Third, in a JIT-compiled expression, it stores the variables that
53/// the expression needs to have materialized and dematerialized at each
54/// execution.  These do not contain their own data but are named and
55/// typed.
56///
57/// This class supports all of these use cases using simple type
58/// polymorphism, and provides necessary support methods.  Its interface
59/// is RTTI-neutral.
60//----------------------------------------------------------------------
61struct ClangExpressionVariable
62{
63    ClangExpressionVariable();
64
65    ClangExpressionVariable(const ClangExpressionVariable &cev);
66
67    //----------------------------------------------------------------------
68    /// If the variable contains its own data, make a Value point at it.
69    /// If \a exe_ctx in not NULL, the value will be resolved in with
70    /// that execution context.
71    ///
72    /// @param[in] value
73    ///     The value to point at the data.
74    ///
75    /// @param[in] exe_ctx
76    ///     The execution context to use to resolve \a value.
77    ///
78    /// @return
79    ///     True on success; false otherwise (in particular, if this variable
80    ///     does not contain its own data).
81    //----------------------------------------------------------------------
82    bool
83    PointValueAtData(Value &value, ExecutionContext *exe_ctx);
84
85    lldb::ValueObjectSP
86    GetExpressionResult (ExecutionContext *exe_ctx);
87
88    //----------------------------------------------------------------------
89    /// The following values should stay valid for the life of the variable
90    //----------------------------------------------------------------------
91    std::string             m_name;         ///< The name of the variable
92    TypeFromUser            m_user_type;    ///< The type of the variable according to some LLDB context; NULL if the type hasn't yet been migrated to one
93
94    //----------------------------------------------------------------------
95    /// The following values indicate where the variable originally came from
96    //----------------------------------------------------------------------
97    ClangExpressionVariableStore   *m_store;    ///< The store containing the variable
98    uint64_t                        m_index;    ///< The index of the variable in the store
99
100    //----------------------------------------------------------------------
101    /// The following values should not live beyond parsing
102    //----------------------------------------------------------------------
103    struct ParserVars {
104
105        ParserVars() :
106            m_parser_type(),
107            m_named_decl (NULL),
108            m_llvm_value (NULL),
109            m_lldb_value (NULL)
110        {
111        }
112
113        TypeFromParser          m_parser_type;  ///< The type of the variable according to the parser
114        const clang::NamedDecl *m_named_decl;   ///< The Decl corresponding to this variable
115        llvm::Value            *m_llvm_value;   ///< The IR value corresponding to this variable; usually a GlobalValue
116        lldb_private::Value    *m_lldb_value;   ///< The value found in LLDB for this variable
117    };
118    std::auto_ptr<ParserVars> m_parser_vars;
119
120    //----------------------------------------------------------------------
121    /// Make this variable usable by the parser by allocating space for
122    /// parser-specific variables
123    //----------------------------------------------------------------------
124    void EnableParserVars()
125    {
126        if (!m_parser_vars.get())
127            m_parser_vars.reset(new struct ParserVars);
128    }
129
130    //----------------------------------------------------------------------
131    /// Deallocate parser-specific variables
132    //----------------------------------------------------------------------
133    void DisableParserVars()
134    {
135        m_parser_vars.reset();
136    }
137
138    //----------------------------------------------------------------------
139    /// The following values are valid if the variable is used by JIT code
140    //----------------------------------------------------------------------
141    struct JITVars {
142        JITVars () :
143            m_alignment (0),
144            m_size (0),
145            m_offset (0)
146        {
147        }
148
149        off_t   m_alignment;    ///< The required alignment of the variable, in bytes
150        size_t  m_size;         ///< The space required for the variable, in bytes
151        off_t   m_offset;       ///< The offset of the variable in the struct, in bytes
152    };
153    std::auto_ptr<JITVars> m_jit_vars;
154
155    //----------------------------------------------------------------------
156    /// Make this variable usable for materializing for the JIT by allocating
157    /// space for JIT-specific variables
158    //----------------------------------------------------------------------
159    void EnableJITVars()
160    {
161        if (!m_jit_vars.get())
162            m_jit_vars.reset(new struct JITVars);
163    }
164
165    //----------------------------------------------------------------------
166    /// Deallocate JIT-specific variables
167    //----------------------------------------------------------------------
168    void DisableJITVars()
169    {
170        m_jit_vars.reset();
171    }
172
173    lldb::DataBufferSP m_data_sp;
174
175    //----------------------------------------------------------------------
176    /// Make this variable usable for storing its data internally by
177    /// allocating data-specific variables
178    //----------------------------------------------------------------------
179    void
180    EnableDataVars();
181
182    //----------------------------------------------------------------------
183    /// Deallocate data-specific variables
184    //----------------------------------------------------------------------
185    void DisableDataVars();
186
187    //----------------------------------------------------------------------
188    /// Return the variable's size in bytes
189    //----------------------------------------------------------------------
190    size_t Size ()
191    {
192        return (m_user_type.GetClangTypeBitWidth () + 7) / 8;
193    }
194};
195
196//----------------------------------------------------------------------
197/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
198/// @brief Manages variables that the expression parser uses.
199///
200/// The expression parser uses variable lists in various contexts, as
201/// discuessed at ClangExpressionVariable.  This abstract class contains
202/// the basic functions for managing a list of variables.  Its subclasses
203/// store pointers to variables or variables, depending on whether they
204/// are backing stores or merely transient repositories.
205//----------------------------------------------------------------------
206class ClangExpressionVariableListBase
207{
208public:
209    //----------------------------------------------------------------------
210    /// Return the number of variables in the list
211    //----------------------------------------------------------------------
212    virtual uint64_t Size() = 0;
213
214    //----------------------------------------------------------------------
215    /// Return the variable at the given index in the list
216    //----------------------------------------------------------------------
217    virtual ClangExpressionVariable &VariableAtIndex(uint64_t index) = 0;
218
219    //----------------------------------------------------------------------
220    /// Add a new variable and return its index
221    //----------------------------------------------------------------------
222    virtual uint64_t AddVariable(ClangExpressionVariable& var) = 0;
223
224    //----------------------------------------------------------------------
225    /// Finds a variable by name in the list.
226    ///
227    /// @param[in] name
228    ///     The name of the requested variable.
229    ///
230    /// @return
231    ///     The variable requested, or NULL if that variable is not in the list.
232    //----------------------------------------------------------------------
233    ClangExpressionVariable *GetVariable (const char *name)
234    {
235        for (uint64_t index = 0, size = Size(); index < size; ++index)
236        {
237            ClangExpressionVariable &candidate (VariableAtIndex(index));
238            if (!candidate.m_name.compare(name))
239                return &candidate;
240        }
241        return NULL;
242    }
243
244    //----------------------------------------------------------------------
245    /// Finds a variable by NamedDecl in the list.
246    ///
247    /// @param[in] name
248    ///     The name of the requested variable.
249    ///
250    /// @return
251    ///     The variable requested, or NULL if that variable is not in the list.
252    //----------------------------------------------------------------------
253    ClangExpressionVariable *GetVariable (const clang::NamedDecl *decl)
254    {
255        for (uint64_t index = 0, size = Size(); index < size; ++index)
256        {
257            ClangExpressionVariable &candidate (VariableAtIndex(index));
258            if (candidate.m_parser_vars.get() &&
259                candidate.m_parser_vars->m_named_decl == decl)
260                return &candidate;
261        }
262        return NULL;
263    }
264};
265
266//----------------------------------------------------------------------
267/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
268/// @brief A list of variable references.
269///
270/// This class stores variables internally, acting as the permanent store.
271//----------------------------------------------------------------------
272class ClangExpressionVariableStore : public ClangExpressionVariableListBase
273{
274public:
275    //----------------------------------------------------------------------
276    /// Implementation of methods in ClangExpressionVariableListBase
277    //----------------------------------------------------------------------
278    uint64_t Size()
279    {
280        return m_variables.size();
281    }
282
283    ClangExpressionVariable &VariableAtIndex(uint64_t index)
284    {
285        return m_variables[index];
286    }
287
288    uint64_t AddVariable(ClangExpressionVariable &var)
289    {
290        m_variables.push_back(var);
291        return m_variables.size() - 1;
292    }
293
294    //----------------------------------------------------------------------
295    /// Create a new variable in the list and return its index
296    //----------------------------------------------------------------------
297    uint64_t CreateVariable()
298    {
299        uint64_t index = m_variables.size();
300
301        m_variables.push_back(ClangExpressionVariable());
302        m_variables[index].m_store = this;
303        m_variables[index].m_index = index;
304
305        return index;
306    }
307private:
308    std::vector <ClangExpressionVariable> m_variables;
309};
310
311//----------------------------------------------------------------------
312/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
313/// @brief A list of variable references.
314///
315/// This class stores references to variables stored elsewhere.
316//----------------------------------------------------------------------
317class ClangExpressionVariableList : public ClangExpressionVariableListBase
318{
319public:
320    //----------------------------------------------------------------------
321    /// Implementation of methods in ClangExpressionVariableListBase
322    //----------------------------------------------------------------------
323    uint64_t Size()
324    {
325        return m_references.size();
326    }
327
328    ClangExpressionVariable &VariableAtIndex(uint64_t index)
329    {
330        return m_references[index].first->VariableAtIndex(m_references[index].second);
331    }
332
333    uint64_t AddVariable(ClangExpressionVariable &var)
334    {
335        m_references.push_back(ClangExpressionVariableRef(var.m_store, var.m_index));
336        return m_references.size() - 1;
337    }
338private:
339    typedef std::pair <ClangExpressionVariableStore *, uint64_t>
340    ClangExpressionVariableRef;
341
342    std::vector <ClangExpressionVariableRef> m_references;
343};
344
345} // namespace lldb_private
346
347#endif  // liblldb_ClangExpressionVariable_h_
348