ClangExpressionVariable.h revision bdcb6abaa287df2c5f312c51d993c1d0b0cb120c
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-include.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(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 { 102 } 103 104 TypeFromParser m_parser_type; ///< The type of the variable according to the parser 105 const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable 106 llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue 107 lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable 108 109 private: 110 DISALLOW_COPY_AND_ASSIGN (ParserVars); 111 }; 112 //---------------------------------------------------------------------- 113 /// Make this variable usable by the parser by allocating space for 114 /// parser-specific variables 115 //---------------------------------------------------------------------- 116 void 117 EnableParserVars() 118 { 119 if (!m_parser_vars.get()) 120 m_parser_vars.reset(new struct ParserVars); 121 } 122 123 //---------------------------------------------------------------------- 124 /// Deallocate parser-specific variables 125 //---------------------------------------------------------------------- 126 void 127 DisableParserVars() 128 { 129 m_parser_vars.reset(); 130 } 131 132 //---------------------------------------------------------------------- 133 /// The following values are valid if the variable is used by JIT code 134 //---------------------------------------------------------------------- 135 struct JITVars { 136 JITVars () : 137 m_alignment (0), 138 m_size (0), 139 m_offset (0) 140 { 141 } 142 143 off_t m_alignment; ///< The required alignment of the variable, in bytes 144 size_t m_size; ///< The space required for the variable, in bytes 145 off_t m_offset; ///< The offset of the variable in the struct, in bytes 146 }; 147 148 //---------------------------------------------------------------------- 149 /// Make this variable usable for materializing for the JIT by allocating 150 /// space for JIT-specific variables 151 //---------------------------------------------------------------------- 152 void 153 EnableJITVars() 154 { 155 if (!m_jit_vars.get()) 156 m_jit_vars.reset(new struct JITVars); 157 } 158 159 //---------------------------------------------------------------------- 160 /// Deallocate JIT-specific variables 161 //---------------------------------------------------------------------- 162 void 163 DisableJITVars() 164 { 165 m_jit_vars.reset(); 166 } 167 168 //---------------------------------------------------------------------- 169 /// Return the variable's size in bytes 170 //---------------------------------------------------------------------- 171 size_t 172 GetByteSize (); 173 174 const ConstString & 175 GetName(); 176 177 lldb::RegisterInfo * 178 GetRegisterInfo(); 179 180 void 181 SetRegisterInfo (const lldb::RegisterInfo *reg_info); 182 183 lldb::clang_type_t 184 GetClangType (); 185 186 void 187 SetClangType (lldb::clang_type_t); 188 189 clang::ASTContext * 190 GetClangAST (); 191 192 void 193 SetClangAST (clang::ASTContext *ast); 194 195 TypeFromUser 196 GetTypeFromUser (); 197 198 uint8_t * 199 GetValueBytes (); 200 201 void 202 SetName (const ConstString &name); 203 204 void 205 ValueUpdated (); 206 207 typedef lldb::SharedPtr<ValueObjectConstResult>::Type ValueObjectConstResultSP; 208 209 //---------------------------------------------------------------------- 210 /// Members 211 //---------------------------------------------------------------------- 212 std::auto_ptr<ParserVars> m_parser_vars; 213 std::auto_ptr<JITVars> m_jit_vars; 214 215 enum Flags 216 { 217 EVNone = 0, 218 EVIsLLDBAllocated = 1 << 0, ///< This variable is resident in a location specifically allocated for it by LLDB in the target process 219 EVIsProgramReference = 1 << 1, ///< This variable is a reference to a (possibly invalid) area managed by the target program 220 EVNeedsAllocation = 1 << 2, ///< Space for this variable has yet to be allocated in the target process 221 EVIsFreezeDried = 1 << 3, ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results) 222 EVNeedsFreezeDry = 1 << 4, ///< Copy from m_live_sp to m_frozen_sp during dematerialization 223 EVKeepInTarget = 1 << 5 ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it 224 }; 225 226 uint16_t m_flags; // takes elements of Flags 227 228 lldb::ValueObjectSP m_frozen_sp; 229 lldb::ValueObjectSP m_live_sp; 230private: 231 DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable); 232}; 233 234//---------------------------------------------------------------------- 235/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 236/// @brief A list of variable references. 237/// 238/// This class stores variables internally, acting as the permanent store. 239//---------------------------------------------------------------------- 240class ClangExpressionVariableList 241{ 242public: 243 //---------------------------------------------------------------------- 244 /// Implementation of methods in ClangExpressionVariableListBase 245 //---------------------------------------------------------------------- 246 size_t 247 GetSize() 248 { 249 return m_variables.size(); 250 } 251 252 lldb::ClangExpressionVariableSP 253 GetVariableAtIndex(size_t index) 254 { 255 lldb::ClangExpressionVariableSP var_sp; 256 if (index < m_variables.size()) 257 var_sp = m_variables[index]; 258 return var_sp; 259 } 260 261 size_t 262 AddVariable (const lldb::ClangExpressionVariableSP &var_sp) 263 { 264 m_variables.push_back(var_sp); 265 return m_variables.size() - 1; 266 } 267 268 bool 269 ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp) 270 { 271 const size_t size = m_variables.size(); 272 for (size_t index = 0; index < size; ++index) 273 { 274 if (m_variables[index].get() == var_sp.get()) 275 return true; 276 } 277 return false; 278 } 279 280 //---------------------------------------------------------------------- 281 /// Finds a variable by name in the list. 282 /// 283 /// @param[in] name 284 /// The name of the requested variable. 285 /// 286 /// @return 287 /// The variable requested, or NULL if that variable is not in the list. 288 //---------------------------------------------------------------------- 289 lldb::ClangExpressionVariableSP 290 GetVariable (const ConstString &name) 291 { 292 lldb::ClangExpressionVariableSP var_sp; 293 for (size_t index = 0, size = GetSize(); index < size; ++index) 294 { 295 var_sp = GetVariableAtIndex(index); 296 if (var_sp->GetName() == name) 297 return var_sp; 298 } 299 var_sp.reset(); 300 return var_sp; 301 } 302 303 lldb::ClangExpressionVariableSP 304 GetVariable (const char *name) 305 { 306 lldb::ClangExpressionVariableSP var_sp; 307 if (name && name[0]) 308 { 309 for (size_t index = 0, size = GetSize(); index < size; ++index) 310 { 311 var_sp = GetVariableAtIndex(index); 312 const char *var_name_cstr = var_sp->GetName().GetCString(); 313 if (::strcmp (var_name_cstr, name) == 0) 314 return var_sp; 315 } 316 var_sp.reset(); 317 } 318 return var_sp; 319 } 320 321 //---------------------------------------------------------------------- 322 /// Finds a variable by NamedDecl 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 clang::NamedDecl *decl) 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->m_parser_vars.get() && var_sp->m_parser_vars->m_named_decl == decl) 338 return var_sp; 339 } 340 var_sp.reset(); 341 return var_sp; 342 } 343 344 //---------------------------------------------------------------------- 345 /// Create a new variable in the list and return its index 346 //---------------------------------------------------------------------- 347 lldb::ClangExpressionVariableSP 348 CreateVariable (lldb::ByteOrder byte_order, uint32_t addr_byte_size) 349 { 350 lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(byte_order, addr_byte_size)); 351 m_variables.push_back(var_sp); 352 return var_sp; 353 } 354 355 lldb::ClangExpressionVariableSP 356 CreateVariable(const lldb::ValueObjectSP &valobj_sp) 357 { 358 lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp)); 359 m_variables.push_back(var_sp); 360 return var_sp; 361 } 362 363 364 365 lldb::ClangExpressionVariableSP 366 CreateVariable (const ConstString &name, 367 const TypeFromUser& user_type, 368 lldb::ByteOrder byte_order, 369 uint32_t addr_byte_size) 370 { 371 lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(byte_order, addr_byte_size)); 372 var_sp->SetName (name); 373 var_sp->SetClangType (user_type.GetOpaqueQualType()); 374 var_sp->SetClangAST (user_type.GetASTContext()); 375 m_variables.push_back(var_sp); 376 return var_sp; 377 } 378 379private: 380 std::vector <lldb::ClangExpressionVariableSP> m_variables; 381}; 382 383 384} // namespace lldb_private 385 386#endif // liblldb_ClangExpressionVariable_h_ 387