ClangExpressionVariable.h revision 8c12720c108cd5e7ed792596749218d8400f647e
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        lldb_private::Value    *m_lldb_value;   ///< The value found in LLDB for this variable
93    };
94    std::auto_ptr<ParserVars> m_parser_vars;
95
96    //----------------------------------------------------------------------
97    /// Make this variable usable by the parser by allocating space for
98    /// parser-specific variables
99    //----------------------------------------------------------------------
100    void EnableParserVars()
101    {
102        if (!m_parser_vars.get())
103            m_parser_vars.reset(new struct ParserVars);
104    }
105
106    //----------------------------------------------------------------------
107    /// Deallocate parser-specific variables
108    //----------------------------------------------------------------------
109    void DisableParserVars()
110    {
111        m_parser_vars.reset();
112    }
113
114    //----------------------------------------------------------------------
115    /// The following values are valid if the variable is used by JIT code
116    //----------------------------------------------------------------------
117    struct JITVars {
118        off_t   m_alignment;    ///< The required alignment of the variable, in bytes
119        size_t  m_size;         ///< The space required for the variable, in bytes
120        off_t   m_offset;       ///< The offset of the variable in the struct, in bytes
121    };
122    std::auto_ptr<JITVars> m_jit_vars;
123
124    //----------------------------------------------------------------------
125    /// Make this variable usable for materializing for the JIT by allocating
126    /// space for JIT-specific variables
127    //----------------------------------------------------------------------
128    void EnableJITVars()
129    {
130        if (!m_jit_vars.get())
131            m_jit_vars.reset(new struct JITVars);
132    }
133
134    //----------------------------------------------------------------------
135    /// Deallocate JIT-specific variables
136    //----------------------------------------------------------------------
137    void DisableJITVars()
138    {
139        m_jit_vars.reset();
140    }
141
142    //----------------------------------------------------------------------
143    /// The following values are valid if the value contains its own data
144    //----------------------------------------------------------------------
145    struct DataVars {
146        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
147    };
148    std::auto_ptr<DataVars> m_data_vars;
149
150    //----------------------------------------------------------------------
151    /// Make this variable usable for storing its data internally by
152    /// allocating data-specific variables
153    //----------------------------------------------------------------------
154    void EnableDataVars()
155    {
156        if (!m_jit_vars.get())
157            m_data_vars.reset(new struct DataVars);
158    }
159
160    //----------------------------------------------------------------------
161    /// Deallocate data-specific variables
162    //----------------------------------------------------------------------
163    void DisableDataVars();
164
165    //----------------------------------------------------------------------
166    /// Return the variable's size in bytes
167    //----------------------------------------------------------------------
168    size_t Size ()
169    {
170        return (m_user_type.GetClangTypeBitWidth () + 7) / 8;
171    }
172
173    //----------------------------------------------------------------------
174    /// Pretty-print the variable, assuming it contains its own data
175    ///
176    /// @param[in] output_stream
177    ///     The stream to pretty-print on.
178    ///
179    /// @param[in] exe_ctx
180    ///     The execution context to use when resolving the contents of the
181    ///     variable.
182    ///
183    /// @param[in] format
184    ///     The format to print the variable in
185    ///
186    /// @param[in] show_types
187    ///     If true, print the type of the variable
188    ///
189    /// @param[in] show_summary
190    ///     If true, print a summary of the variable's type
191    ///
192    /// @param[in] verbose
193    ///     If true, be verbose in printing the value of the variable
194    ///
195    /// @return
196    ///     An Error describing the result of the operation.  If Error::Success()
197    ///     returns true, the pretty printing completed successfully.
198    //----------------------------------------------------------------------
199    Error Print(Stream &output_stream,
200                ExecutionContext &exe_ctx,
201                lldb::Format format,
202                bool show_types,
203                bool show_summary,
204                bool verbose);
205};
206
207//----------------------------------------------------------------------
208/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
209/// @brief Manages variables that the expression parser uses.
210///
211/// The expression parser uses variable lists in various contexts, as
212/// discuessed at ClangExpressionVariable.  This abstract class contains
213/// the basic functions for managing a list of variables.  Its subclasses
214/// store pointers to variables or variables, depending on whether they
215/// are backing stores or merely transient repositories.
216//----------------------------------------------------------------------
217class ClangExpressionVariableListBase
218{
219public:
220    //----------------------------------------------------------------------
221    /// Return the number of variables in the list
222    //----------------------------------------------------------------------
223    virtual uint64_t Size() = 0;
224
225    //----------------------------------------------------------------------
226    /// Return the variable at the given index in the list
227    //----------------------------------------------------------------------
228    virtual ClangExpressionVariable &VariableAtIndex(uint64_t index) = 0;
229
230    //----------------------------------------------------------------------
231    /// Add a new variable and return its index
232    //----------------------------------------------------------------------
233    virtual uint64_t AddVariable(ClangExpressionVariable& var) = 0;
234
235    //----------------------------------------------------------------------
236    /// Finds a variable by name in the list.
237    ///
238    /// @param[in] name
239    ///     The name of the requested variable.
240    ///
241    /// @return
242    ///     The variable requested, or NULL if that variable is not in the list.
243    //----------------------------------------------------------------------
244    ClangExpressionVariable *GetVariable (const char *name)
245    {
246        for (uint64_t index = 0, size = Size(); index < size; ++index)
247        {
248            ClangExpressionVariable &candidate (VariableAtIndex(index));
249            if (!candidate.m_name.compare(name))
250                return &candidate;
251        }
252        return NULL;
253    }
254
255    //----------------------------------------------------------------------
256    /// Finds a variable by NamedDecl in the list.
257    ///
258    /// @param[in] name
259    ///     The name of the requested variable.
260    ///
261    /// @return
262    ///     The variable requested, or NULL if that variable is not in the list.
263    //----------------------------------------------------------------------
264    ClangExpressionVariable *GetVariable (const clang::NamedDecl *decl)
265    {
266        for (uint64_t index = 0, size = Size(); index < size; ++index)
267        {
268            ClangExpressionVariable &candidate (VariableAtIndex(index));
269            if (candidate.m_parser_vars.get() &&
270                candidate.m_parser_vars->m_named_decl == decl)
271                return &candidate;
272        }
273        return NULL;
274    }
275};
276
277//----------------------------------------------------------------------
278/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
279/// @brief A list of variable references.
280///
281/// This class stores references to variables stored elsewhere.
282//----------------------------------------------------------------------
283class ClangExpressionVariableList : public ClangExpressionVariableListBase
284{
285public:
286    //----------------------------------------------------------------------
287    /// Implementation of methods in ClangExpressionVariableListBase
288    //----------------------------------------------------------------------
289    uint64_t Size()
290    {
291        return m_variables.size();
292    }
293
294    ClangExpressionVariable &VariableAtIndex(uint64_t index)
295    {
296        return *m_variables[index];
297    }
298
299    uint64_t AddVariable(ClangExpressionVariable &var)
300    {
301        m_variables.push_back(&var);
302        return m_variables.size() - 1;
303    }
304private:
305    std::vector <ClangExpressionVariable*> m_variables;
306};
307
308//----------------------------------------------------------------------
309/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
310/// @brief A list of variable references.
311///
312/// This class stores variables internally, acting as the permanent store.
313//----------------------------------------------------------------------
314class ClangExpressionVariableStore : public ClangExpressionVariableListBase
315{
316public:
317    //----------------------------------------------------------------------
318    /// Implementation of methods in ClangExpressionVariableListBase
319    //----------------------------------------------------------------------
320    uint64_t Size()
321    {
322        return m_variables.size();
323    }
324
325    ClangExpressionVariable &VariableAtIndex(uint64_t index)
326    {
327        return m_variables[index];
328    }
329
330    uint64_t AddVariable(ClangExpressionVariable &var)
331    {
332        m_variables.push_back(var);
333        return m_variables.size() - 1;
334    }
335
336    //----------------------------------------------------------------------
337    /// Create a new variable in the list and return its index
338    //----------------------------------------------------------------------
339    uint64_t CreateVariable()
340    {
341        m_variables.push_back(ClangExpressionVariable());
342        return m_variables.size() - 1;
343    }
344private:
345    std::vector <ClangExpressionVariable> m_variables;
346};
347
348} // namespace lldb_private
349
350#endif  // liblldb_ClangExpressionVariable_h_
351