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