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/Core/Value.h" 29 #include "lldb/Symbol/TaggedASTType.h" 30 31 namespace llvm { 32 class Value; 33 } 34 35 namespace lldb_private { 36 37 class ClangExpressionVariableList; 38 class ValueObjectConstResult; 39 40 //---------------------------------------------------------------------- 41 /// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" 42 /// @brief Encapsulates one variable for the expression parser. 43 /// 44 /// The expression parser uses variables in three different contexts: 45 /// 46 /// First, it stores persistent variables along with the process for use 47 /// in expressions. These persistent variables contain their own data 48 /// and are typed. 49 /// 50 /// Second, in an interpreted expression, it stores the local variables 51 /// for the expression along with the expression. These variables 52 /// contain their own data and are typed. 53 /// 54 /// Third, in a JIT-compiled expression, it stores the variables that 55 /// the expression needs to have materialized and dematerialized at each 56 /// execution. These do not contain their own data but are named and 57 /// typed. 58 /// 59 /// This class supports all of these use cases using simple type 60 /// polymorphism, and provides necessary support methods. Its interface 61 /// is RTTI-neutral. 62 //---------------------------------------------------------------------- 63 class ClangExpressionVariable 64 { 65 public: 66 ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size); 67 68 ClangExpressionVariable (ExecutionContextScope *exe_scope, 69 Value &value, 70 const ConstString &name, 71 uint16_t flags = EVNone); 72 73 ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp); 74 75 //---------------------------------------------------------------------- 76 /// If the variable contains its own data, make a Value point at it. 77 /// If \a exe_ctx in not NULL, the value will be resolved in with 78 /// that execution context. 79 /// 80 /// @param[in] value 81 /// The value to point at the data. 82 /// 83 /// @param[in] exe_ctx 84 /// The execution context to use to resolve \a value. 85 /// 86 /// @return 87 /// True on success; false otherwise (in particular, if this variable 88 /// does not contain its own data). 89 //---------------------------------------------------------------------- 90 bool 91 PointValueAtData(Value &value, ExecutionContext *exe_ctx); 92 93 lldb::ValueObjectSP 94 GetValueObject(); 95 96 //---------------------------------------------------------------------- 97 /// The following values should not live beyond parsing 98 //---------------------------------------------------------------------- 99 class ParserVars 100 { 101 public: 102 ParserVars()103 ParserVars() : 104 m_parser_type(), 105 m_named_decl (NULL), 106 m_llvm_value (NULL), 107 m_lldb_value (), 108 m_lldb_var (), 109 m_lldb_sym (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 lldb::VariableSP m_lldb_var; ///< The original variable for this variable 118 const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol 119 }; 120 121 private: 122 typedef std::map <uint64_t, ParserVars> ParserVarMap; 123 ParserVarMap m_parser_vars; 124 125 public: 126 //---------------------------------------------------------------------- 127 /// Make this variable usable by the parser by allocating space for 128 /// parser-specific variables 129 //---------------------------------------------------------------------- 130 void EnableParserVars(uint64_t parser_id)131 EnableParserVars(uint64_t parser_id) 132 { 133 m_parser_vars.insert(std::make_pair(parser_id, ParserVars())); 134 } 135 136 //---------------------------------------------------------------------- 137 /// Deallocate parser-specific variables 138 //---------------------------------------------------------------------- 139 void DisableParserVars(uint64_t parser_id)140 DisableParserVars(uint64_t parser_id) 141 { 142 m_parser_vars.erase(parser_id); 143 } 144 145 //---------------------------------------------------------------------- 146 /// Access parser-specific variables 147 //---------------------------------------------------------------------- 148 ParserVars * GetParserVars(uint64_t parser_id)149 GetParserVars(uint64_t parser_id) 150 { 151 ParserVarMap::iterator i = m_parser_vars.find(parser_id); 152 153 if (i == m_parser_vars.end()) 154 return NULL; 155 else 156 return &i->second; 157 } 158 159 //---------------------------------------------------------------------- 160 /// The following values are valid if the variable is used by JIT code 161 //---------------------------------------------------------------------- 162 struct JITVars { JITVarsJITVars163 JITVars () : 164 m_alignment (0), 165 m_size (0), 166 m_offset (0) 167 { 168 } 169 170 lldb::offset_t m_alignment; ///< The required alignment of the variable, in bytes 171 size_t m_size; ///< The space required for the variable, in bytes 172 lldb::offset_t m_offset; ///< The offset of the variable in the struct, in bytes 173 }; 174 175 private: 176 typedef std::map <uint64_t, JITVars> JITVarMap; 177 JITVarMap m_jit_vars; 178 179 public: 180 //---------------------------------------------------------------------- 181 /// Make this variable usable for materializing for the JIT by allocating 182 /// space for JIT-specific variables 183 //---------------------------------------------------------------------- 184 void EnableJITVars(uint64_t parser_id)185 EnableJITVars(uint64_t parser_id) 186 { 187 m_jit_vars.insert(std::make_pair(parser_id, JITVars())); 188 } 189 190 //---------------------------------------------------------------------- 191 /// Deallocate JIT-specific variables 192 //---------------------------------------------------------------------- 193 void DisableJITVars(uint64_t parser_id)194 DisableJITVars(uint64_t parser_id) 195 { 196 m_jit_vars.erase(parser_id); 197 } 198 GetJITVars(uint64_t parser_id)199 JITVars *GetJITVars(uint64_t parser_id) 200 { 201 JITVarMap::iterator i = m_jit_vars.find(parser_id); 202 203 if (i == m_jit_vars.end()) 204 return NULL; 205 else 206 return &i->second; 207 } 208 209 //---------------------------------------------------------------------- 210 /// Return the variable's size in bytes 211 //---------------------------------------------------------------------- 212 size_t 213 GetByteSize (); 214 215 const ConstString & 216 GetName(); 217 218 RegisterInfo * 219 GetRegisterInfo(); 220 221 void 222 SetRegisterInfo (const RegisterInfo *reg_info); 223 224 ClangASTType 225 GetClangType (); 226 227 void 228 SetClangType (const ClangASTType &clang_type); 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 objects 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 //---------------------------------------------------------------------- 286 class ClangExpressionVariableList 287 { 288 public: 289 //---------------------------------------------------------------------- 290 /// Implementation of methods in ClangExpressionVariableListBase 291 //---------------------------------------------------------------------- 292 size_t GetSize()293 GetSize() 294 { 295 return m_variables.size(); 296 } 297 298 lldb::ClangExpressionVariableSP GetVariableAtIndex(size_t index)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 AddVariable(const lldb::ClangExpressionVariableSP & var_sp)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 ContainsVariable(const lldb::ClangExpressionVariableSP & var_sp)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 GetVariable(const ConstString & name)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 GetVariable(const char * name)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 GetVariable(const clang::NamedDecl * decl,uint64_t parser_id)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 CreateVariable(ExecutionContextScope * exe_scope,lldb::ByteOrder byte_order,uint32_t addr_byte_size)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 CreateVariable(const lldb::ValueObjectSP & valobj_sp)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 CreateVariable(ExecutionContextScope * exe_scope,const ConstString & name,const TypeFromUser & user_type,lldb::ByteOrder byte_order,uint32_t addr_byte_size)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); 424 m_variables.push_back(var_sp); 425 return var_sp; 426 } 427 428 void RemoveVariable(lldb::ClangExpressionVariableSP var_sp)429 RemoveVariable (lldb::ClangExpressionVariableSP var_sp) 430 { 431 for (std::vector<lldb::ClangExpressionVariableSP>::iterator vi = m_variables.begin(), ve = m_variables.end(); 432 vi != ve; 433 ++vi) 434 { 435 if (vi->get() == var_sp.get()) 436 { 437 m_variables.erase(vi); 438 return; 439 } 440 } 441 } 442 443 void Clear()444 Clear() 445 { 446 m_variables.clear(); 447 } 448 449 private: 450 std::vector <lldb::ClangExpressionVariableSP> m_variables; 451 }; 452 453 454 } // namespace lldb_private 455 456 #endif // liblldb_ClangExpressionVariable_h_ 457