ClangExpressionVariable.h revision 1ddd9fe72bd9e22f40ad28f25b3a139a9326ae98
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/lldb-types.h" 24#include "lldb/Core/ClangForward.h" 25#include "lldb/Core/ConstString.h" 26#include "lldb/Symbol/TaggedASTType.h" 27 28namespace llvm { 29 class Value; 30} 31 32namespace lldb_private { 33 34class ClangExpressionVariableStore; 35class DataBufferHeap; 36class ExecutionContext; 37class Stream; 38class Value; 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//---------------------------------------------------------------------- 63struct ClangExpressionVariable 64{ 65 ClangExpressionVariable(); 66 67 ClangExpressionVariable(const ClangExpressionVariable &cev); 68 69 //---------------------------------------------------------------------- 70 /// If the variable contains its own data, make a Value point at it. 71 /// If \a exe_ctx in not NULL, the value will be resolved in with 72 /// that execution context. 73 /// 74 /// @param[in] value 75 /// The value to point at the data. 76 /// 77 /// @param[in] exe_ctx 78 /// The execution context to use to resolve \a value. 79 /// 80 /// @return 81 /// True on success; false otherwise (in particular, if this variable 82 /// does not contain its own data). 83 //---------------------------------------------------------------------- 84 bool 85 PointValueAtData(Value &value, ExecutionContext *exe_ctx); 86 87 lldb::ValueObjectSP 88 GetExpressionResult (ExecutionContext *exe_ctx); 89 90 //---------------------------------------------------------------------- 91 /// The following values should stay valid for the life of the variable 92 //---------------------------------------------------------------------- 93 ConstString m_name; ///< The name of the variable 94 TypeFromUser m_user_type; ///< The type of the variable according to some LLDB context; 95 ///< NULL if the type hasn't yet been migrated to one 96 97 const lldb::RegisterInfo *m_register_info; ///< if non-NULL, LLDB's information for the register this value is stored in. Only used for register values 98 99 //---------------------------------------------------------------------- 100 /// The following values indicate where the variable originally came from 101 //---------------------------------------------------------------------- 102 ClangExpressionVariableStore *m_store; ///< The store containing the variable 103 uint64_t m_index; ///< The index of the variable in the store 104 105 //---------------------------------------------------------------------- 106 /// The following values should not live beyond parsing 107 //---------------------------------------------------------------------- 108 struct ParserVars { 109 110 ParserVars() : 111 m_parser_type(), 112 m_named_decl (NULL), 113 m_llvm_value (NULL), 114 m_lldb_value (NULL) 115 { 116 } 117 118 TypeFromParser m_parser_type; ///< The type of the variable according to the parser 119 const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable 120 llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue 121 lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable 122 }; 123 std::auto_ptr<ParserVars> m_parser_vars; 124 125 //---------------------------------------------------------------------- 126 /// Make this variable usable by the parser by allocating space for 127 /// parser-specific variables 128 //---------------------------------------------------------------------- 129 void EnableParserVars() 130 { 131 if (!m_parser_vars.get()) 132 m_parser_vars.reset(new struct ParserVars); 133 } 134 135 //---------------------------------------------------------------------- 136 /// Deallocate parser-specific variables 137 //---------------------------------------------------------------------- 138 void DisableParserVars() 139 { 140 m_parser_vars.reset(); 141 } 142 143 //---------------------------------------------------------------------- 144 /// The following values are valid if the variable is used by JIT code 145 //---------------------------------------------------------------------- 146 struct JITVars { 147 JITVars () : 148 m_alignment (0), 149 m_size (0), 150 m_offset (0) 151 { 152 } 153 154 off_t m_alignment; ///< The required alignment of the variable, in bytes 155 size_t m_size; ///< The space required for the variable, in bytes 156 off_t m_offset; ///< The offset of the variable in the struct, in bytes 157 }; 158 std::auto_ptr<JITVars> m_jit_vars; 159 160 //---------------------------------------------------------------------- 161 /// Make this variable usable for materializing for the JIT by allocating 162 /// space for JIT-specific variables 163 //---------------------------------------------------------------------- 164 void EnableJITVars() 165 { 166 if (!m_jit_vars.get()) 167 m_jit_vars.reset(new struct JITVars); 168 } 169 170 //---------------------------------------------------------------------- 171 /// Deallocate JIT-specific variables 172 //---------------------------------------------------------------------- 173 void DisableJITVars() 174 { 175 m_jit_vars.reset(); 176 } 177 178 lldb::DataBufferSP m_data_sp; 179 180 //---------------------------------------------------------------------- 181 /// Make this variable usable for storing its data internally by 182 /// allocating data-specific variables 183 //---------------------------------------------------------------------- 184 void 185 EnableDataVars(); 186 187 //---------------------------------------------------------------------- 188 /// Deallocate data-specific variables 189 //---------------------------------------------------------------------- 190 void DisableDataVars(); 191 192 //---------------------------------------------------------------------- 193 /// Return the variable's size in bytes 194 //---------------------------------------------------------------------- 195 size_t Size () 196 { 197 return (m_user_type.GetClangTypeBitWidth () + 7) / 8; 198 } 199}; 200 201//---------------------------------------------------------------------- 202/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 203/// @brief Manages variables that the expression parser uses. 204/// 205/// The expression parser uses variable lists in various contexts, as 206/// discuessed at ClangExpressionVariable. This abstract class contains 207/// the basic functions for managing a list of variables. Its subclasses 208/// store pointers to variables or variables, depending on whether they 209/// are backing stores or merely transient repositories. 210//---------------------------------------------------------------------- 211class ClangExpressionVariableListBase 212{ 213public: 214 //---------------------------------------------------------------------- 215 /// Return the number of variables in the list 216 //---------------------------------------------------------------------- 217 virtual uint64_t Size() = 0; 218 219 //---------------------------------------------------------------------- 220 /// Return the variable at the given index in the list 221 //---------------------------------------------------------------------- 222 virtual ClangExpressionVariable &VariableAtIndex(uint64_t index) = 0; 223 224 //---------------------------------------------------------------------- 225 /// Add a new variable and return its index 226 //---------------------------------------------------------------------- 227 virtual uint64_t AddVariable(ClangExpressionVariable& var) = 0; 228 229 //---------------------------------------------------------------------- 230 /// Finds a variable by name in the list. 231 /// 232 /// @param[in] name 233 /// The name of the requested variable. 234 /// 235 /// @return 236 /// The variable requested, or NULL if that variable is not in the list. 237 //---------------------------------------------------------------------- 238 ClangExpressionVariable *GetVariable (const ConstString &name) 239 { 240 for (uint64_t index = 0, size = Size(); index < size; ++index) 241 { 242 ClangExpressionVariable &candidate (VariableAtIndex(index)); 243 if (candidate.m_name == name) 244 return &candidate; 245 } 246 return NULL; 247 } 248 249 //---------------------------------------------------------------------- 250 /// Finds a variable by NamedDecl in the list. 251 /// 252 /// @param[in] name 253 /// The name of the requested variable. 254 /// 255 /// @return 256 /// The variable requested, or NULL if that variable is not in the list. 257 //---------------------------------------------------------------------- 258 ClangExpressionVariable *GetVariable (const clang::NamedDecl *decl) 259 { 260 for (uint64_t index = 0, size = Size(); index < size; ++index) 261 { 262 ClangExpressionVariable &candidate (VariableAtIndex(index)); 263 if (candidate.m_parser_vars.get() && 264 candidate.m_parser_vars->m_named_decl == decl) 265 return &candidate; 266 } 267 return NULL; 268 } 269}; 270 271//---------------------------------------------------------------------- 272/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 273/// @brief A list of variable references. 274/// 275/// This class stores variables internally, acting as the permanent store. 276//---------------------------------------------------------------------- 277class ClangExpressionVariableStore : public ClangExpressionVariableListBase 278{ 279public: 280 //---------------------------------------------------------------------- 281 /// Implementation of methods in ClangExpressionVariableListBase 282 //---------------------------------------------------------------------- 283 uint64_t Size() 284 { 285 return m_variables.size(); 286 } 287 288 ClangExpressionVariable &VariableAtIndex(uint64_t index) 289 { 290 return m_variables[index]; 291 } 292 293 uint64_t AddVariable(ClangExpressionVariable &var) 294 { 295 m_variables.push_back(var); 296 return m_variables.size() - 1; 297 } 298 299 //---------------------------------------------------------------------- 300 /// Create a new variable in the list and return its index 301 //---------------------------------------------------------------------- 302 uint64_t CreateVariable() 303 { 304 uint64_t index = m_variables.size(); 305 306 m_variables.push_back(ClangExpressionVariable()); 307 m_variables[index].m_store = this; 308 m_variables[index].m_index = index; 309 310 return index; 311 } 312private: 313 std::vector <ClangExpressionVariable> m_variables; 314}; 315 316//---------------------------------------------------------------------- 317/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 318/// @brief A list of variable references. 319/// 320/// This class stores references to variables stored elsewhere. 321//---------------------------------------------------------------------- 322class ClangExpressionVariableList : public ClangExpressionVariableListBase 323{ 324public: 325 //---------------------------------------------------------------------- 326 /// Implementation of methods in ClangExpressionVariableListBase 327 //---------------------------------------------------------------------- 328 uint64_t Size() 329 { 330 return m_references.size(); 331 } 332 333 ClangExpressionVariable &VariableAtIndex(uint64_t index) 334 { 335 return m_references[index].first->VariableAtIndex(m_references[index].second); 336 } 337 338 uint64_t AddVariable(ClangExpressionVariable &var) 339 { 340 m_references.push_back(ClangExpressionVariableRef(var.m_store, var.m_index)); 341 return m_references.size() - 1; 342 } 343private: 344 typedef std::pair <ClangExpressionVariableStore *, uint64_t> 345 ClangExpressionVariableRef; 346 347 std::vector <ClangExpressionVariableRef> m_references; 348}; 349 350} // namespace lldb_private 351 352#endif // liblldb_ClangExpressionVariable_h_ 353