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