ClangExpressionVariable.h revision cec32bbcad3e99d7f797072e5e160453e29890ac
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 <map> 20#include <string> 21#include <vector> 22 23// Other libraries and framework includes 24// Project includes 25#include "lldb/lldb-public.h" 26#include "lldb/Core/ClangForward.h" 27#include "lldb/Core/ConstString.h" 28#include "lldb/Symbol/TaggedASTType.h" 29 30namespace llvm { 31 class Value; 32} 33 34namespace lldb_private { 35 36class ClangExpressionVariableList; 37class ValueObjectConstResult; 38 39//---------------------------------------------------------------------- 40/// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 41/// @brief Encapsulates one variable for the expression parser. 42/// 43/// The expression parser uses variables in three different contexts: 44/// 45/// First, it stores persistent variables along with the process for use 46/// in expressions. These persistent variables contain their own data 47/// and are typed. 48/// 49/// Second, in an interpreted expression, it stores the local variables 50/// for the expression along with the expression. These variables 51/// contain their own data and are typed. 52/// 53/// Third, in a JIT-compiled expression, it stores the variables that 54/// the expression needs to have materialized and dematerialized at each 55/// execution. These do not contain their own data but are named and 56/// typed. 57/// 58/// This class supports all of these use cases using simple type 59/// polymorphism, and provides necessary support methods. Its interface 60/// is RTTI-neutral. 61//---------------------------------------------------------------------- 62class ClangExpressionVariable 63{ 64public: 65 ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size); 66 67 ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp); 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 GetValueObject(); 89 90 //---------------------------------------------------------------------- 91 /// The following values should not live beyond parsing 92 //---------------------------------------------------------------------- 93 class ParserVars 94 { 95 public: 96 97 ParserVars() : 98 m_parser_type(), 99 m_named_decl (NULL), 100 m_llvm_value (NULL), 101 m_lldb_value (NULL), 102 m_lldb_var (), 103 m_lldb_sym (NULL) 104 { 105 } 106 107 TypeFromParser m_parser_type; ///< The type of the variable according to the parser 108 const clang::NamedDecl *m_named_decl; ///< The Decl corresponding to this variable 109 llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue 110 lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable 111 lldb::VariableSP m_lldb_var; ///< The original variable for this variable 112 const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol 113 }; 114 115private: 116 typedef std::map <uint64_t, ParserVars> ParserVarMap; 117 ParserVarMap m_parser_vars; 118 119public: 120 //---------------------------------------------------------------------- 121 /// Make this variable usable by the parser by allocating space for 122 /// parser-specific variables 123 //---------------------------------------------------------------------- 124 void 125 EnableParserVars(uint64_t parser_id) 126 { 127 m_parser_vars.insert(std::make_pair(parser_id, ParserVars())); 128 } 129 130 //---------------------------------------------------------------------- 131 /// Deallocate parser-specific variables 132 //---------------------------------------------------------------------- 133 void 134 DisableParserVars(uint64_t parser_id) 135 { 136 m_parser_vars.erase(parser_id); 137 } 138 139 //---------------------------------------------------------------------- 140 /// Access parser-specific variables 141 //---------------------------------------------------------------------- 142 ParserVars * 143 GetParserVars(uint64_t parser_id) 144 { 145 ParserVarMap::iterator i = m_parser_vars.find(parser_id); 146 147 if (i == m_parser_vars.end()) 148 return NULL; 149 else 150 return &i->second; 151 } 152 153 //---------------------------------------------------------------------- 154 /// The following values are valid if the variable is used by JIT code 155 //---------------------------------------------------------------------- 156 struct JITVars { 157 JITVars () : 158 m_alignment (0), 159 m_size (0), 160 m_offset (0) 161 { 162 } 163 164 off_t m_alignment; ///< The required alignment of the variable, in bytes 165 size_t m_size; ///< The space required for the variable, in bytes 166 off_t m_offset; ///< The offset of the variable in the struct, in bytes 167 }; 168 169private: 170 typedef std::map <uint64_t, JITVars> JITVarMap; 171 JITVarMap m_jit_vars; 172 173public: 174 //---------------------------------------------------------------------- 175 /// Make this variable usable for materializing for the JIT by allocating 176 /// space for JIT-specific variables 177 //---------------------------------------------------------------------- 178 void 179 EnableJITVars(uint64_t parser_id) 180 { 181 m_jit_vars.insert(std::make_pair(parser_id, JITVars())); 182 } 183 184 //---------------------------------------------------------------------- 185 /// Deallocate JIT-specific variables 186 //---------------------------------------------------------------------- 187 void 188 DisableJITVars(uint64_t parser_id) 189 { 190 m_jit_vars.erase(parser_id); 191 } 192 193 JITVars *GetJITVars(uint64_t parser_id) 194 { 195 JITVarMap::iterator i = m_jit_vars.find(parser_id); 196 197 if (i == m_jit_vars.end()) 198 return NULL; 199 else 200 return &i->second; 201 } 202 203 //---------------------------------------------------------------------- 204 /// Return the variable's size in bytes 205 //---------------------------------------------------------------------- 206 size_t 207 GetByteSize (); 208 209 const ConstString & 210 GetName(); 211 212 RegisterInfo * 213 GetRegisterInfo(); 214 215 void 216 SetRegisterInfo (const RegisterInfo *reg_info); 217 218 lldb::clang_type_t 219 GetClangType (); 220 221 void 222 SetClangType (lldb::clang_type_t); 223 224 clang::ASTContext * 225 GetClangAST (); 226 227 void 228 SetClangAST (clang::ASTContext *ast); 229 230 TypeFromUser 231 GetTypeFromUser (); 232 233 uint8_t * 234 GetValueBytes (); 235 236 void 237 SetName (const ConstString &name); 238 239 void 240 ValueUpdated (); 241 242 // this function is used to copy the address-of m_live_sp into m_frozen_sp 243 // this is necessary because the results of certain cast and pointer-arithmetic 244 // operations (such as those described in bugzilla issues 11588 and 11618) generate 245 // frozen objcts that do not have a valid address-of, which can be troublesome when 246 // using synthetic children providers. transferring the address-of the live object 247 // solves these issues and provides the expected user-level behavior 248 void 249 TransferAddress (bool force = false); 250 251 typedef STD_SHARED_PTR(ValueObjectConstResult) ValueObjectConstResultSP; 252 253 //---------------------------------------------------------------------- 254 /// Members 255 //---------------------------------------------------------------------- 256 enum Flags 257 { 258 EVNone = 0, 259 EVIsLLDBAllocated = 1 << 0, ///< This variable is resident in a location specifically allocated for it by LLDB in the target process 260 EVIsProgramReference = 1 << 1, ///< This variable is a reference to a (possibly invalid) area managed by the target program 261 EVNeedsAllocation = 1 << 2, ///< Space for this variable has yet to be allocated in the target process 262 EVIsFreezeDried = 1 << 3, ///< This variable's authoritative version is in m_frozen_sp (for example, for statically-computed results) 263 EVNeedsFreezeDry = 1 << 4, ///< Copy from m_live_sp to m_frozen_sp during dematerialization 264 EVKeepInTarget = 1 << 5, ///< Keep the allocation after the expression is complete rather than freeze drying its contents and freeing it 265 EVTypeIsReference = 1 << 6, ///< The original type of this variable is a reference, so materialize the value rather than the location 266 EVUnknownType = 1 << 7, ///< This is a symbol of unknown type, and the type must be resolved after parsing is complete 267 EVBareRegister = 1 << 8 ///< This variable is a direct reference to $pc or some other entity. 268 }; 269 270 typedef uint16_t FlagType; 271 272 FlagType m_flags; // takes elements of Flags 273 274 lldb::ValueObjectSP m_frozen_sp; 275 lldb::ValueObjectSP m_live_sp; 276 277 DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable); 278}; 279 280//---------------------------------------------------------------------- 281/// @class ClangExpressionVariableListBase ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 282/// @brief A list of variable references. 283/// 284/// This class stores variables internally, acting as the permanent store. 285//---------------------------------------------------------------------- 286class ClangExpressionVariableList 287{ 288public: 289 //---------------------------------------------------------------------- 290 /// Implementation of methods in ClangExpressionVariableListBase 291 //---------------------------------------------------------------------- 292 size_t 293 GetSize() 294 { 295 return m_variables.size(); 296 } 297 298 lldb::ClangExpressionVariableSP 299 GetVariableAtIndex(size_t index) 300 { 301 lldb::ClangExpressionVariableSP var_sp; 302 if (index < m_variables.size()) 303 var_sp = m_variables[index]; 304 return var_sp; 305 } 306 307 size_t 308 AddVariable (const lldb::ClangExpressionVariableSP &var_sp) 309 { 310 m_variables.push_back(var_sp); 311 return m_variables.size() - 1; 312 } 313 314 bool 315 ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp) 316 { 317 const size_t size = m_variables.size(); 318 for (size_t index = 0; index < size; ++index) 319 { 320 if (m_variables[index].get() == var_sp.get()) 321 return true; 322 } 323 return false; 324 } 325 326 //---------------------------------------------------------------------- 327 /// Finds a variable by name in the list. 328 /// 329 /// @param[in] name 330 /// The name of the requested variable. 331 /// 332 /// @return 333 /// The variable requested, or NULL if that variable is not in the list. 334 //---------------------------------------------------------------------- 335 lldb::ClangExpressionVariableSP 336 GetVariable (const ConstString &name) 337 { 338 lldb::ClangExpressionVariableSP var_sp; 339 for (size_t index = 0, size = GetSize(); index < size; ++index) 340 { 341 var_sp = GetVariableAtIndex(index); 342 if (var_sp->GetName() == name) 343 return var_sp; 344 } 345 var_sp.reset(); 346 return var_sp; 347 } 348 349 lldb::ClangExpressionVariableSP 350 GetVariable (const char *name) 351 { 352 lldb::ClangExpressionVariableSP var_sp; 353 if (name && name[0]) 354 { 355 for (size_t index = 0, size = GetSize(); index < size; ++index) 356 { 357 var_sp = GetVariableAtIndex(index); 358 const char *var_name_cstr = var_sp->GetName().GetCString(); 359 if (!var_name_cstr || !name) 360 continue; 361 if (::strcmp (var_name_cstr, name) == 0) 362 return var_sp; 363 } 364 var_sp.reset(); 365 } 366 return var_sp; 367 } 368 369 //---------------------------------------------------------------------- 370 /// Finds a variable by NamedDecl in the list. 371 /// 372 /// @param[in] name 373 /// The name of the requested variable. 374 /// 375 /// @return 376 /// The variable requested, or NULL if that variable is not in the list. 377 //---------------------------------------------------------------------- 378 lldb::ClangExpressionVariableSP 379 GetVariable (const clang::NamedDecl *decl, uint64_t parser_id) 380 { 381 lldb::ClangExpressionVariableSP var_sp; 382 for (size_t index = 0, size = GetSize(); index < size; ++index) 383 { 384 var_sp = GetVariableAtIndex(index); 385 386 ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(parser_id); 387 388 if (parser_vars && parser_vars->m_named_decl == decl) 389 return var_sp; 390 } 391 var_sp.reset(); 392 return var_sp; 393 } 394 395 //---------------------------------------------------------------------- 396 /// Create a new variable in the list and return its index 397 //---------------------------------------------------------------------- 398 lldb::ClangExpressionVariableSP 399 CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size) 400 { 401 lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size)); 402 m_variables.push_back(var_sp); 403 return var_sp; 404 } 405 406 lldb::ClangExpressionVariableSP 407 CreateVariable(const lldb::ValueObjectSP &valobj_sp) 408 { 409 lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(valobj_sp)); 410 m_variables.push_back(var_sp); 411 return var_sp; 412 } 413 414 lldb::ClangExpressionVariableSP 415 CreateVariable (ExecutionContextScope *exe_scope, 416 const ConstString &name, 417 const TypeFromUser& user_type, 418 lldb::ByteOrder byte_order, 419 uint32_t addr_byte_size) 420 { 421 lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size)); 422 var_sp->SetName (name); 423 var_sp->SetClangType (user_type.GetOpaqueQualType()); 424 var_sp->SetClangAST (user_type.GetASTContext()); 425 m_variables.push_back(var_sp); 426 return var_sp; 427 } 428 429 void 430 RemoveVariable (lldb::ClangExpressionVariableSP var_sp) 431 { 432 for (std::vector<lldb::ClangExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end(); 433 vi != ve; 434 ++vi) 435 { 436 if (vi->get() == var_sp.get()) 437 { 438 m_variables.erase(vi); 439 return; 440 } 441 } 442 } 443 444 void 445 Clear() 446 { 447 m_variables.clear(); 448 } 449 450private: 451 std::vector <lldb::ClangExpressionVariableSP> m_variables; 452}; 453 454 455} // namespace lldb_private 456 457#endif // liblldb_ClangExpressionVariable_h_ 458