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