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