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