]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/include/lldb/Expression/ClangExpressionVariable.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / include / lldb / Expression / ClangExpressionVariable.h
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 <map>
20 #include <string>
21 #include <vector>
22
23 // Other libraries and framework includes
24 // Project includes
25 #include "lldb/lldb-public.h"
26 #include "lldb/Core/ClangForward.h"
27 #include "lldb/Core/ConstString.h"
28 #include "lldb/Core/Value.h"
29 #include "lldb/Symbol/TaggedASTType.h"
30
31 namespace llvm {
32     class Value;
33 }
34
35 namespace lldb_private {
36
37 class ClangExpressionVariableList;
38 class ValueObjectConstResult;
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 //----------------------------------------------------------------------
63 class ClangExpressionVariable
64 {
65 public:
66     ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
67
68     ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
69
70     //----------------------------------------------------------------------
71     /// If the variable contains its own data, make a Value point at it.
72     /// If \a exe_ctx in not NULL, the value will be resolved in with
73     /// that execution context.
74     ///
75     /// @param[in] value
76     ///     The value to point at the data.
77     ///
78     /// @param[in] exe_ctx
79     ///     The execution context to use to resolve \a value.
80     ///
81     /// @return
82     ///     True on success; false otherwise (in particular, if this variable
83     ///     does not contain its own data).
84     //----------------------------------------------------------------------
85     bool
86     PointValueAtData(Value &value, ExecutionContext *exe_ctx);
87     
88     lldb::ValueObjectSP
89     GetValueObject();
90
91     //----------------------------------------------------------------------
92     /// The following values should not live beyond parsing
93     //----------------------------------------------------------------------
94     class ParserVars 
95     {
96     public:
97
98         ParserVars() :
99             m_parser_type(),
100             m_named_decl (NULL),
101             m_llvm_value (NULL),
102             m_lldb_value (),
103             m_lldb_var   (),
104             m_lldb_sym   (NULL)
105         {
106         }
107
108         TypeFromParser          m_parser_type;  ///< The type of the variable according to the parser
109         const clang::NamedDecl *m_named_decl;   ///< The Decl corresponding to this variable
110         llvm::Value            *m_llvm_value;   ///< The IR value corresponding to this variable; usually a GlobalValue
111         lldb_private::Value     m_lldb_value;   ///< The value found in LLDB for this variable
112         lldb::VariableSP        m_lldb_var;     ///< The original variable for this variable
113         const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
114     };
115     
116 private:
117     typedef std::map <uint64_t, ParserVars> ParserVarMap;
118     ParserVarMap m_parser_vars;
119
120 public:
121     //----------------------------------------------------------------------
122     /// Make this variable usable by the parser by allocating space for
123     /// parser-specific variables
124     //----------------------------------------------------------------------
125     void 
126     EnableParserVars(uint64_t parser_id)
127     {
128         m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
129     }
130     
131     //----------------------------------------------------------------------
132     /// Deallocate parser-specific variables
133     //----------------------------------------------------------------------
134     void
135     DisableParserVars(uint64_t parser_id)
136     {
137         m_parser_vars.erase(parser_id);
138     }
139     
140     //----------------------------------------------------------------------
141     /// Access parser-specific variables
142     //----------------------------------------------------------------------
143     ParserVars *
144     GetParserVars(uint64_t parser_id)
145     {
146         ParserVarMap::iterator i = m_parser_vars.find(parser_id);
147         
148         if (i == m_parser_vars.end())
149             return NULL;
150         else
151             return &i->second;
152     }
153     
154     //----------------------------------------------------------------------
155     /// The following values are valid if the variable is used by JIT code
156     //----------------------------------------------------------------------
157     struct JITVars {
158         JITVars () :
159             m_alignment (0),
160             m_size (0),
161             m_offset (0)
162         {
163         }
164
165         off_t   m_alignment;    ///< The required alignment of the variable, in bytes
166         size_t  m_size;         ///< The space required for the variable, in bytes
167         off_t   m_offset;       ///< The offset of the variable in the struct, in bytes
168     };
169     
170 private:
171     typedef std::map <uint64_t, JITVars> JITVarMap;
172     JITVarMap m_jit_vars;
173     
174 public:
175     //----------------------------------------------------------------------
176     /// Make this variable usable for materializing for the JIT by allocating 
177     /// space for JIT-specific variables
178     //----------------------------------------------------------------------
179     void 
180     EnableJITVars(uint64_t parser_id)
181     {
182         m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
183     }
184     
185     //----------------------------------------------------------------------
186     /// Deallocate JIT-specific variables
187     //----------------------------------------------------------------------
188     void 
189     DisableJITVars(uint64_t parser_id)
190     {
191         m_jit_vars.erase(parser_id);
192     }
193     
194     JITVars *GetJITVars(uint64_t parser_id)
195     {
196         JITVarMap::iterator i = m_jit_vars.find(parser_id);
197         
198         if (i == m_jit_vars.end())
199             return NULL;
200         else
201             return &i->second;
202     }
203         
204     //----------------------------------------------------------------------
205     /// Return the variable's size in bytes
206     //----------------------------------------------------------------------
207     size_t 
208     GetByteSize ();
209
210     const ConstString &
211     GetName();
212
213     RegisterInfo *
214     GetRegisterInfo();
215     
216     void
217     SetRegisterInfo (const RegisterInfo *reg_info);
218
219     ClangASTType
220     GetClangType ();
221     
222     void
223     SetClangType (const ClangASTType &clang_type);
224
225     TypeFromUser
226     GetTypeFromUser ();
227
228     uint8_t *
229     GetValueBytes ();
230     
231     void
232     SetName (const ConstString &name);
233
234     void
235     ValueUpdated ();
236     
237     // this function is used to copy the address-of m_live_sp into m_frozen_sp
238     // this is necessary because the results of certain cast and pointer-arithmetic
239     // operations (such as those described in bugzilla issues 11588 and 11618) generate
240     // frozen objcts that do not have a valid address-of, which can be troublesome when
241     // using synthetic children providers. transferring the address-of the live object
242     // solves these issues and provides the expected user-level behavior
243     void
244     TransferAddress (bool force = false);
245
246     typedef std::shared_ptr<ValueObjectConstResult> ValueObjectConstResultSP;
247
248     //----------------------------------------------------------------------
249     /// Members
250     //----------------------------------------------------------------------
251     enum Flags 
252     {
253         EVNone                  = 0,
254         EVIsLLDBAllocated       = 1 << 0,   ///< This variable is resident in a location specifically allocated for it by LLDB in the target process
255         EVIsProgramReference    = 1 << 1,   ///< This variable is a reference to a (possibly invalid) area managed by the target program
256         EVNeedsAllocation       = 1 << 2,   ///< Space for this variable has yet to be allocated in the target process
257         EVIsFreezeDried         = 1 << 3,   ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results)
258         EVNeedsFreezeDry        = 1 << 4,   ///< Copy from m_live_sp to m_frozen_sp during dematerialization
259         EVKeepInTarget          = 1 << 5,   ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it
260         EVTypeIsReference       = 1 << 6,   ///< The original type of this variable is a reference, so materialize the value rather than the location
261         EVUnknownType           = 1 << 7,   ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete
262         EVBareRegister          = 1 << 8    ///< This variable is a direct reference to $pc or some other entity.
263     };
264     
265     typedef uint16_t FlagType;
266     
267     FlagType m_flags; // takes elements of Flags
268     
269     lldb::ValueObjectSP m_frozen_sp;
270     lldb::ValueObjectSP m_live_sp;
271     
272     DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
273 };
274
275 //----------------------------------------------------------------------
276 /// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h"
277 /// @brief A list of variable references.
278 ///
279 /// This class stores variables internally, acting as the permanent store.
280 //----------------------------------------------------------------------
281 class ClangExpressionVariableList
282 {
283 public:
284     //----------------------------------------------------------------------
285     /// Implementation of methods in ClangExpressionVariableListBase
286     //----------------------------------------------------------------------
287     size_t 
288     GetSize()
289     {
290         return m_variables.size();
291     }
292     
293     lldb::ClangExpressionVariableSP
294     GetVariableAtIndex(size_t index)
295     {
296         lldb::ClangExpressionVariableSP var_sp;
297         if (index < m_variables.size())
298             var_sp = m_variables[index];
299         return var_sp;
300     }
301     
302     size_t
303     AddVariable (const lldb::ClangExpressionVariableSP &var_sp)
304     {
305         m_variables.push_back(var_sp);
306         return m_variables.size() - 1;
307     }
308
309     bool
310     ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp)
311     {
312         const size_t size = m_variables.size();
313         for (size_t index = 0; index < size; ++index)
314         {
315             if (m_variables[index].get() == var_sp.get())
316                 return true;
317         }
318         return false;
319     }
320
321     //----------------------------------------------------------------------
322     /// Finds a variable by name in the list.
323     ///
324     /// @param[in] name
325     ///     The name of the requested variable.
326     ///
327     /// @return
328     ///     The variable requested, or NULL if that variable is not in the list.
329     //----------------------------------------------------------------------
330     lldb::ClangExpressionVariableSP
331     GetVariable (const ConstString &name)
332     {
333         lldb::ClangExpressionVariableSP var_sp;
334         for (size_t index = 0, size = GetSize(); index < size; ++index)
335         {
336             var_sp = GetVariableAtIndex(index);
337             if (var_sp->GetName() == name)
338                 return var_sp;
339         }
340         var_sp.reset();
341         return var_sp;
342     }
343
344     lldb::ClangExpressionVariableSP
345     GetVariable (const char *name)
346     {
347         lldb::ClangExpressionVariableSP var_sp;
348         if (name && name[0])
349         {
350             for (size_t index = 0, size = GetSize(); index < size; ++index)
351             {
352                 var_sp = GetVariableAtIndex(index);
353                 const char *var_name_cstr = var_sp->GetName().GetCString();
354                 if (!var_name_cstr || !name)
355                     continue;
356                 if (::strcmp (var_name_cstr, name) == 0)
357                     return var_sp;
358             }
359             var_sp.reset();
360         }
361         return var_sp;
362     }
363     
364     //----------------------------------------------------------------------
365     /// Finds a variable by NamedDecl in the list.
366     ///
367     /// @param[in] name
368     ///     The name of the requested variable.
369     ///
370     /// @return
371     ///     The variable requested, or NULL if that variable is not in the list.
372     //----------------------------------------------------------------------
373     lldb::ClangExpressionVariableSP
374     GetVariable (const clang::NamedDecl *decl, uint64_t parser_id)
375     {
376         lldb::ClangExpressionVariableSP var_sp;
377         for (size_t index = 0, size = GetSize(); index < size; ++index)
378         {
379             var_sp = GetVariableAtIndex(index);
380             
381             ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(parser_id);
382             
383             if (parser_vars && parser_vars->m_named_decl == decl)
384                 return var_sp;
385         }
386         var_sp.reset();
387         return var_sp;
388     }
389
390     //----------------------------------------------------------------------
391     /// Create a new variable in the list and return its index
392     //----------------------------------------------------------------------
393     lldb::ClangExpressionVariableSP
394     CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
395     {
396         lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
397         m_variables.push_back(var_sp);
398         return var_sp;
399     }
400
401     lldb::ClangExpressionVariableSP
402     CreateVariable(const lldb::ValueObjectSP &valobj_sp)
403     {
404         lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp));
405         m_variables.push_back(var_sp);
406         return var_sp;
407     }
408
409     lldb::ClangExpressionVariableSP
410     CreateVariable (ExecutionContextScope *exe_scope,
411                     const ConstString &name, 
412                     const TypeFromUser& user_type,
413                     lldb::ByteOrder byte_order, 
414                     uint32_t addr_byte_size)
415     {
416         lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
417         var_sp->SetName (name);
418         var_sp->SetClangType (user_type);
419         m_variables.push_back(var_sp);
420         return var_sp;
421     }
422     
423     void
424     RemoveVariable (lldb::ClangExpressionVariableSP var_sp)
425     {
426         for (std::vector<lldb::ClangExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end();
427              vi != ve;
428              ++vi)
429         {
430             if (vi->get() == var_sp.get())
431             {
432                 m_variables.erase(vi);
433                 return;
434             }
435         }
436     }
437     
438     void
439     Clear()
440     {
441         m_variables.clear();
442     }
443
444 private:
445     std::vector <lldb::ClangExpressionVariableSP> m_variables;
446 };
447
448
449 } // namespace lldb_private
450
451 #endif  // liblldb_ClangExpressionVariable_h_