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