ClangExpressionVariable.h revision 696cf5f6f2a77b87a4b06cdf0f697749b494665f
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#include <string.h>
17
18// C++ Includes
19#include <string>
20#include <vector>
21
22// Other libraries and framework includes
23// Project includes
24#include "lldb/lldb-public.h"
25#include "lldb/Core/ClangForward.h"
26#include "lldb/Core/ConstString.h"
27#include "lldb/Symbol/TaggedASTType.h"
28
29namespace llvm {
30    class Value;
31}
32
33namespace lldb_private {
34
35class ClangExpressionVariableList;
36class ValueObjectConstResult;
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//----------------------------------------------------------------------
61class ClangExpressionVariable
62{
63public:
64    ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
65
66    ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
67
68    //----------------------------------------------------------------------
69    /// If the variable contains its own data, make a Value point at it.
70    /// If \a exe_ctx in not NULL, the value will be resolved in with
71    /// that execution context.
72    ///
73    /// @param[in] value
74    ///     The value to point at the data.
75    ///
76    /// @param[in] exe_ctx
77    ///     The execution context to use to resolve \a value.
78    ///
79    /// @return
80    ///     True on success; false otherwise (in particular, if this variable
81    ///     does not contain its own data).
82    //----------------------------------------------------------------------
83    bool
84    PointValueAtData(Value &value, ExecutionContext *exe_ctx);
85
86    lldb::ValueObjectSP
87    GetValueObject();
88
89    //----------------------------------------------------------------------
90    /// The following values should not live beyond parsing
91    //----------------------------------------------------------------------
92    class ParserVars
93    {
94    public:
95
96        ParserVars() :
97            m_parser_type(),
98            m_named_decl (NULL),
99            m_llvm_value (NULL),
100            m_lldb_value (NULL),
101            m_lldb_var   ()
102        {
103        }
104
105        TypeFromParser          m_parser_type;  ///< The type of the variable according to the parser
106        const clang::NamedDecl *m_named_decl;   ///< The Decl corresponding to this variable
107        llvm::Value            *m_llvm_value;   ///< The IR value corresponding to this variable; usually a GlobalValue
108        lldb_private::Value    *m_lldb_value;   ///< The value found in LLDB for this variable
109        lldb::VariableSP        m_lldb_var;     ///< The original variable for this variable
110
111    private:
112        DISALLOW_COPY_AND_ASSIGN (ParserVars);
113    };
114    //----------------------------------------------------------------------
115    /// Make this variable usable by the parser by allocating space for
116    /// parser-specific variables
117    //----------------------------------------------------------------------
118    void
119    EnableParserVars()
120    {
121        if (!m_parser_vars.get())
122            m_parser_vars.reset(new ParserVars);
123    }
124
125    //----------------------------------------------------------------------
126    /// Deallocate parser-specific variables
127    //----------------------------------------------------------------------
128    void
129    DisableParserVars()
130    {
131        m_parser_vars.reset();
132    }
133
134    //----------------------------------------------------------------------
135    /// The following values are valid if the variable is used by JIT code
136    //----------------------------------------------------------------------
137    struct JITVars {
138        JITVars () :
139            m_alignment (0),
140            m_size (0),
141            m_offset (0)
142        {
143        }
144
145        off_t   m_alignment;    ///< The required alignment of the variable, in bytes
146        size_t  m_size;         ///< The space required for the variable, in bytes
147        off_t   m_offset;       ///< The offset of the variable in the struct, in bytes
148    };
149
150    //----------------------------------------------------------------------
151    /// Make this variable usable for materializing for the JIT by allocating
152    /// space for JIT-specific variables
153    //----------------------------------------------------------------------
154    void
155    EnableJITVars()
156    {
157        if (!m_jit_vars.get())
158            m_jit_vars.reset(new struct JITVars);
159    }
160
161    //----------------------------------------------------------------------
162    /// Deallocate JIT-specific variables
163    //----------------------------------------------------------------------
164    void
165    DisableJITVars()
166    {
167        m_jit_vars.reset();
168    }
169
170    //----------------------------------------------------------------------
171    /// Return the variable's size in bytes
172    //----------------------------------------------------------------------
173    size_t
174    GetByteSize ();
175
176    const ConstString &
177    GetName();
178
179    RegisterInfo *
180    GetRegisterInfo();
181
182    void
183    SetRegisterInfo (const RegisterInfo *reg_info);
184
185    lldb::clang_type_t
186    GetClangType ();
187
188    void
189    SetClangType (lldb::clang_type_t);
190
191    clang::ASTContext *
192    GetClangAST ();
193
194    void
195    SetClangAST (clang::ASTContext *ast);
196
197    TypeFromUser
198    GetTypeFromUser ();
199
200    uint8_t *
201    GetValueBytes ();
202
203    void
204    SetName (const ConstString &name);
205
206    void
207    ValueUpdated ();
208
209    typedef lldb::SharedPtr<ValueObjectConstResult>::Type ValueObjectConstResultSP;
210
211    //----------------------------------------------------------------------
212    /// Members
213    //----------------------------------------------------------------------
214    std::auto_ptr<ParserVars> m_parser_vars;
215    std::auto_ptr<JITVars> m_jit_vars;
216
217    enum Flags
218    {
219        EVNone                  = 0,
220        EVIsLLDBAllocated       = 1 << 0,   ///< This variable is resident in a location specifically allocated for it by LLDB in the target process
221        EVIsProgramReference    = 1 << 1,   ///< This variable is a reference to a (possibly invalid) area managed by the target program
222        EVNeedsAllocation       = 1 << 2,   ///< Space for this variable has yet to be allocated in the target process
223        EVIsFreezeDried         = 1 << 3,   ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
224        EVNeedsFreezeDry        = 1 << 4,   ///< Copy from m_live_sp to m_frozen_sp during dematerialization
225        EVKeepInTarget          = 1 << 5    ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
226    };
227
228    uint16_t m_flags; // takes elements of Flags
229
230    lldb::ValueObjectSP m_frozen_sp;
231    lldb::ValueObjectSP m_live_sp;
232private:
233    DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
234};
235
236//----------------------------------------------------------------------
237/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
238/// @brief A list of variable references.
239///
240/// This class stores variables internally, acting as the permanent store.
241//----------------------------------------------------------------------
242class ClangExpressionVariableList
243{
244public:
245    //----------------------------------------------------------------------
246    /// Implementation of methods in ClangExpressionVariableListBase
247    //----------------------------------------------------------------------
248    size_t
249    GetSize()
250    {
251        return m_variables.size();
252    }
253
254    lldb::ClangExpressionVariableSP
255    GetVariableAtIndex(size_t index)
256    {
257        lldb::ClangExpressionVariableSP var_sp;
258        if (index < m_variables.size())
259            var_sp = m_variables[index];
260        return var_sp;
261    }
262
263    size_t
264    AddVariable (const lldb::ClangExpressionVariableSP &var_sp)
265    {
266        m_variables.push_back(var_sp);
267        return m_variables.size() - 1;
268    }
269
270    bool
271    ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp)
272    {
273        const size_t size = m_variables.size();
274        for (size_t index = 0; index < size; ++index)
275        {
276            if (m_variables[index].get() == var_sp.get())
277                return true;
278        }
279        return false;
280    }
281
282    //----------------------------------------------------------------------
283    /// Finds a variable by name in the list.
284    ///
285    /// @param[in] name
286    ///     The name of the requested variable.
287    ///
288    /// @return
289    ///     The variable requested, or NULL if that variable is not in the list.
290    //----------------------------------------------------------------------
291    lldb::ClangExpressionVariableSP
292    GetVariable (const ConstString &name)
293    {
294        lldb::ClangExpressionVariableSP var_sp;
295        for (size_t index = 0, size = GetSize(); index < size; ++index)
296        {
297            var_sp = GetVariableAtIndex(index);
298            if (var_sp->GetName() == name)
299                return var_sp;
300        }
301        var_sp.reset();
302        return var_sp;
303    }
304
305    lldb::ClangExpressionVariableSP
306    GetVariable (const char *name)
307    {
308        lldb::ClangExpressionVariableSP var_sp;
309        if (name && name[0])
310        {
311            for (size_t index = 0, size = GetSize(); index < size; ++index)
312            {
313                var_sp = GetVariableAtIndex(index);
314                const char *var_name_cstr = var_sp->GetName().GetCString();
315                if (::strcmp (var_name_cstr, name) == 0)
316                    return var_sp;
317            }
318            var_sp.reset();
319        }
320        return var_sp;
321    }
322
323    //----------------------------------------------------------------------
324    /// Finds a variable by NamedDecl in the list.
325    ///
326    /// @param[in] name
327    ///     The name of the requested variable.
328    ///
329    /// @return
330    ///     The variable requested, or NULL if that variable is not in the list.
331    //----------------------------------------------------------------------
332    lldb::ClangExpressionVariableSP
333    GetVariable (const clang::NamedDecl *decl)
334    {
335        lldb::ClangExpressionVariableSP var_sp;
336        for (size_t index = 0, size = GetSize(); index < size; ++index)
337        {
338            var_sp = GetVariableAtIndex(index);
339            if (var_sp->m_parser_vars.get() && var_sp->m_parser_vars->m_named_decl == decl)
340                return var_sp;
341        }
342        var_sp.reset();
343        return var_sp;
344    }
345
346    //----------------------------------------------------------------------
347    /// Create a new variable in the list and return its index
348    //----------------------------------------------------------------------
349    lldb::ClangExpressionVariableSP
350    CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
351    {
352        lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
353        m_variables.push_back(var_sp);
354        return var_sp;
355    }
356
357    lldb::ClangExpressionVariableSP
358    CreateVariable(const lldb::ValueObjectSP &valobj_sp)
359    {
360        lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp));
361        m_variables.push_back(var_sp);
362        return var_sp;
363    }
364
365
366
367    lldb::ClangExpressionVariableSP
368    CreateVariable (ExecutionContextScope *exe_scope,
369                    const ConstString &name,
370                    const TypeFromUser& user_type,
371                    lldb::ByteOrder byte_order,
372                    uint32_t addr_byte_size)
373    {
374        lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
375        var_sp->SetName (name);
376        var_sp->SetClangType (user_type.GetOpaqueQualType());
377        var_sp->SetClangAST (user_type.GetASTContext());
378        m_variables.push_back(var_sp);
379        return var_sp;
380    }
381
382private:
383    std::vector <lldb::ClangExpressionVariableSP> m_variables;
384};
385
386
387} // namespace lldb_private
388
389#endif  // liblldb_ClangExpressionVariable_h_
390