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