ClangExpressionVariable.h revision 434b7dde31ae8b59f20add4dd27e051dd71fbe2c
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        lldb_private::Symbol   *m_lldb_sym;     ///< The original symbol for this variable, if it was a symbol
111
112    private:
113        DISALLOW_COPY_AND_ASSIGN (ParserVars);
114    };
115    //----------------------------------------------------------------------
116    /// Make this variable usable by the parser by allocating space for
117    /// parser-specific variables
118    //----------------------------------------------------------------------
119    void
120    EnableParserVars()
121    {
122        if (!m_parser_vars.get())
123            m_parser_vars.reset(new ParserVars);
124    }
125
126    //----------------------------------------------------------------------
127    /// Deallocate parser-specific variables
128    //----------------------------------------------------------------------
129    void
130    DisableParserVars()
131    {
132        m_parser_vars.reset();
133    }
134
135    //----------------------------------------------------------------------
136    /// The following values are valid if the variable is used by JIT code
137    //----------------------------------------------------------------------
138    struct JITVars {
139        JITVars () :
140            m_alignment (0),
141            m_size (0),
142            m_offset (0)
143        {
144        }
145
146        off_t   m_alignment;    ///< The required alignment of the variable, in bytes
147        size_t  m_size;         ///< The space required for the variable, in bytes
148        off_t   m_offset;       ///< The offset of the variable in the struct, in bytes
149    };
150
151    //----------------------------------------------------------------------
152    /// Make this variable usable for materializing for the JIT by allocating
153    /// space for JIT-specific variables
154    //----------------------------------------------------------------------
155    void
156    EnableJITVars()
157    {
158        if (!m_jit_vars.get())
159            m_jit_vars.reset(new JITVars);
160    }
161
162    //----------------------------------------------------------------------
163    /// Deallocate JIT-specific variables
164    //----------------------------------------------------------------------
165    void
166    DisableJITVars()
167    {
168        m_jit_vars.reset();
169    }
170
171    //----------------------------------------------------------------------
172    /// Return the variable's size in bytes
173    //----------------------------------------------------------------------
174    size_t
175    GetByteSize ();
176
177    const ConstString &
178    GetName();
179
180    RegisterInfo *
181    GetRegisterInfo();
182
183    void
184    SetRegisterInfo (const RegisterInfo *reg_info);
185
186    lldb::clang_type_t
187    GetClangType ();
188
189    void
190    SetClangType (lldb::clang_type_t);
191
192    clang::ASTContext *
193    GetClangAST ();
194
195    void
196    SetClangAST (clang::ASTContext *ast);
197
198    TypeFromUser
199    GetTypeFromUser ();
200
201    uint8_t *
202    GetValueBytes ();
203
204    void
205    SetName (const ConstString &name);
206
207    void
208    ValueUpdated ();
209
210    typedef lldb::SharedPtr<ValueObjectConstResult>::Type ValueObjectConstResultSP;
211
212    //----------------------------------------------------------------------
213    /// Members
214    //----------------------------------------------------------------------
215    std::auto_ptr<ParserVars> m_parser_vars;
216    std::auto_ptr<JITVars> m_jit_vars;
217
218    enum Flags
219    {
220        EVNone                  = 0,
221        EVIsLLDBAllocated       = 1 << 0,   ///< This variable is resident in a location specifically allocated for it by LLDB in the target process
222        EVIsProgramReference    = 1 << 1,   ///< This variable is a reference to a (possibly invalid) area managed by the target program
223        EVNeedsAllocation       = 1 << 2,   ///< Space for this variable has yet to be allocated in the target process
224        EVIsFreezeDried         = 1 << 3,   ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
225        EVNeedsFreezeDry        = 1 << 4,   ///< Copy from m_live_sp to m_frozen_sp during dematerialization
226        EVKeepInTarget          = 1 << 5,   ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
227        EVTypeIsReference       = 1 << 6,   ///< The original type of this variable is a reference, so materialize the value rather than the location
228        EVUnknownType           = 1 << 7    ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
229    };
230
231    uint16_t m_flags; // takes elements of Flags
232
233    lldb::ValueObjectSP m_frozen_sp;
234    lldb::ValueObjectSP m_live_sp;
235private:
236    DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
237};
238
239//----------------------------------------------------------------------
240/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
241/// @brief A list of variable references.
242///
243/// This class stores variables internally, acting as the permanent store.
244//----------------------------------------------------------------------
245class ClangExpressionVariableList
246{
247public:
248    //----------------------------------------------------------------------
249    /// Implementation of methods in ClangExpressionVariableListBase
250    //----------------------------------------------------------------------
251    size_t
252    GetSize()
253    {
254        return m_variables.size();
255    }
256
257    lldb::ClangExpressionVariableSP
258    GetVariableAtIndex(size_t index)
259    {
260        lldb::ClangExpressionVariableSP var_sp;
261        if (index < m_variables.size())
262            var_sp = m_variables[index];
263        return var_sp;
264    }
265
266    size_t
267    AddVariable (const lldb::ClangExpressionVariableSP &var_sp)
268    {
269        m_variables.push_back(var_sp);
270        return m_variables.size() - 1;
271    }
272
273    bool
274    ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp)
275    {
276        const size_t size = m_variables.size();
277        for (size_t index = 0; index < size; ++index)
278        {
279            if (m_variables[index].get() == var_sp.get())
280                return true;
281        }
282        return false;
283    }
284
285    //----------------------------------------------------------------------
286    /// Finds a variable by name in the list.
287    ///
288    /// @param[in] name
289    ///     The name of the requested variable.
290    ///
291    /// @return
292    ///     The variable requested, or NULL if that variable is not in the list.
293    //----------------------------------------------------------------------
294    lldb::ClangExpressionVariableSP
295    GetVariable (const ConstString &name)
296    {
297        lldb::ClangExpressionVariableSP var_sp;
298        for (size_t index = 0, size = GetSize(); index < size; ++index)
299        {
300            var_sp = GetVariableAtIndex(index);
301            if (var_sp->GetName() == name)
302                return var_sp;
303        }
304        var_sp.reset();
305        return var_sp;
306    }
307
308    lldb::ClangExpressionVariableSP
309    GetVariable (const char *name)
310    {
311        lldb::ClangExpressionVariableSP var_sp;
312        if (name && name[0])
313        {
314            for (size_t index = 0, size = GetSize(); index < size; ++index)
315            {
316                var_sp = GetVariableAtIndex(index);
317                const char *var_name_cstr = var_sp->GetName().GetCString();
318                if (!var_name_cstr || !name)
319                    continue;
320                if (::strcmp (var_name_cstr, name) == 0)
321                    return var_sp;
322            }
323            var_sp.reset();
324        }
325        return var_sp;
326    }
327
328    //----------------------------------------------------------------------
329    /// Finds a variable by NamedDecl in the list.
330    ///
331    /// @param[in] name
332    ///     The name of the requested variable.
333    ///
334    /// @return
335    ///     The variable requested, or NULL if that variable is not in the list.
336    //----------------------------------------------------------------------
337    lldb::ClangExpressionVariableSP
338    GetVariable (const clang::NamedDecl *decl)
339    {
340        lldb::ClangExpressionVariableSP var_sp;
341        for (size_t index = 0, size = GetSize(); index < size; ++index)
342        {
343            var_sp = GetVariableAtIndex(index);
344            if (var_sp->m_parser_vars.get() && var_sp->m_parser_vars->m_named_decl == decl)
345                return var_sp;
346        }
347        var_sp.reset();
348        return var_sp;
349    }
350
351    //----------------------------------------------------------------------
352    /// Create a new variable in the list and return its index
353    //----------------------------------------------------------------------
354    lldb::ClangExpressionVariableSP
355    CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
356    {
357        lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
358        m_variables.push_back(var_sp);
359        return var_sp;
360    }
361
362    lldb::ClangExpressionVariableSP
363    CreateVariable(const lldb::ValueObjectSP &valobj_sp)
364    {
365        lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp));
366        m_variables.push_back(var_sp);
367        return var_sp;
368    }
369
370
371
372    lldb::ClangExpressionVariableSP
373    CreateVariable (ExecutionContextScope *exe_scope,
374                    const ConstString &name,
375                    const TypeFromUser& user_type,
376                    lldb::ByteOrder byte_order,
377                    uint32_t addr_byte_size)
378    {
379        lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
380        var_sp->SetName (name);
381        var_sp->SetClangType (user_type.GetOpaqueQualType());
382        var_sp->SetClangAST (user_type.GetASTContext());
383        m_variables.push_back(var_sp);
384        return var_sp;
385    }
386
387    void
388    Clear()
389    {
390        m_variables.clear();
391    }
392
393private:
394    std::vector <lldb::ClangExpressionVariableSP> m_variables;
395};
396
397
398} // namespace lldb_private
399
400#endif  // liblldb_ClangExpressionVariable_h_
401