1 //===-- SBValue.cpp ---------------------------------------------*- 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 #include "lldb/API/SBValue.h" 11 #include "lldb/API/SBStream.h" 12 13 #include "lldb/Core/DataExtractor.h" 14 #include "lldb/Core/Log.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/Stream.h" 17 #include "lldb/Core/StreamFile.h" 18 #include "lldb/Core/Value.h" 19 #include "lldb/Core/ValueObject.h" 20 #include "lldb/Symbol/Block.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Symbol/Variable.h" 23 #include "lldb/Target/ExecutionContext.h" 24 #include "lldb/Target/Process.h" 25 #include "lldb/Target/StackFrame.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Target/Thread.h" 28 29 #include "lldb/API/SBProcess.h" 30 #include "lldb/API/SBTarget.h" 31 #include "lldb/API/SBThread.h" 32 #include "lldb/API/SBFrame.h" 33 #include "lldb/API/SBDebugger.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 SBValue::SBValue () : 39 m_opaque_sp () 40 { 41 } 42 43 SBValue::SBValue (const lldb::ValueObjectSP &value_sp) : 44 m_opaque_sp (value_sp) 45 { 46 } 47 48 SBValue::SBValue(const SBValue &rhs) : 49 m_opaque_sp (rhs.m_opaque_sp) 50 { 51 } 52 53 const SBValue & 54 SBValue::operator = (const SBValue &rhs) 55 { 56 if (this != &rhs) 57 m_opaque_sp = rhs.m_opaque_sp; 58 return *this; 59 } 60 61 SBValue::~SBValue() 62 { 63 } 64 65 bool 66 SBValue::IsValid () const 67 { 68 // If this function ever changes to anything that does more than just 69 // check if the opaque shared pointer is non NULL, then we need to update 70 // all "if (m_opaque_sp)" code in this file. 71 return m_opaque_sp.get() != NULL; 72 } 73 74 SBError 75 SBValue::GetError() 76 { 77 SBError sb_error; 78 79 if (m_opaque_sp.get()) 80 sb_error.SetError(m_opaque_sp->GetError()); 81 82 return sb_error; 83 } 84 85 const char * 86 SBValue::GetName() 87 { 88 89 const char *name = NULL; 90 if (m_opaque_sp) 91 name = m_opaque_sp->GetName().GetCString(); 92 93 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 94 if (log) 95 { 96 if (name) 97 log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name); 98 else 99 log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get(), name); 100 } 101 102 return name; 103 } 104 105 const char * 106 SBValue::GetTypeName () 107 { 108 const char *name = NULL; 109 if (m_opaque_sp) 110 name = m_opaque_sp->GetTypeName().GetCString(); 111 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 112 if (log) 113 { 114 if (name) 115 log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name); 116 else 117 log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get()); 118 } 119 120 return name; 121 } 122 123 size_t 124 SBValue::GetByteSize () 125 { 126 size_t result = 0; 127 128 if (m_opaque_sp) 129 result = m_opaque_sp->GetByteSize(); 130 131 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 132 if (log) 133 log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result); 134 135 return result; 136 } 137 138 bool 139 SBValue::IsInScope (const SBFrame &sb_frame) 140 { 141 return IsInScope(); 142 } 143 144 bool 145 SBValue::IsInScope () 146 { 147 bool result = false; 148 149 if (m_opaque_sp) 150 { 151 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 152 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 153 result = m_opaque_sp->IsInScope (); 154 } 155 156 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 157 if (log) 158 log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result); 159 160 return result; 161 } 162 163 const char * 164 SBValue::GetValue (const SBFrame &sb_frame) 165 { 166 return GetValue(); 167 } 168 169 const char * 170 SBValue::GetValue () 171 { 172 const char *cstr = NULL; 173 if (m_opaque_sp) 174 { 175 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 176 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 177 cstr = m_opaque_sp->GetValueAsCString (); 178 } 179 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 180 if (log) 181 { 182 if (cstr) 183 log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr); 184 else 185 log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get()); 186 } 187 188 return cstr; 189 } 190 191 ValueType 192 SBValue::GetValueType () 193 { 194 ValueType result = eValueTypeInvalid; 195 if (m_opaque_sp) 196 result = m_opaque_sp->GetValueType(); 197 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 198 if (log) 199 { 200 switch (result) 201 { 202 case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break; 203 case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break; 204 case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break; 205 case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break; 206 case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break; 207 case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break; 208 case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break; 209 case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break; 210 default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break; 211 } 212 } 213 return result; 214 } 215 216 const char * 217 SBValue::GetObjectDescription (const SBFrame &sb_frame) 218 { 219 return GetObjectDescription (); 220 } 221 222 const char * 223 SBValue::GetObjectDescription () 224 { 225 const char *cstr = NULL; 226 if (m_opaque_sp) 227 { 228 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 229 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 230 cstr = m_opaque_sp->GetObjectDescription (); 231 } 232 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 233 if (log) 234 { 235 if (cstr) 236 log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr); 237 else 238 log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get()); 239 } 240 return cstr; 241 } 242 243 bool 244 SBValue::GetValueDidChange (const SBFrame &sb_frame) 245 { 246 return GetValueDidChange (); 247 } 248 249 bool 250 SBValue::GetValueDidChange () 251 { 252 bool result = false; 253 if (m_opaque_sp) 254 { 255 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 256 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 257 result = m_opaque_sp->GetValueDidChange (); 258 } 259 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 260 if (log) 261 log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result); 262 263 return result; 264 } 265 266 const char * 267 SBValue::GetSummary (const SBFrame &sb_frame) 268 { 269 return GetSummary (); 270 } 271 272 const char * 273 SBValue::GetSummary () 274 { 275 const char *cstr = NULL; 276 if (m_opaque_sp) 277 { 278 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 279 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 280 cstr = m_opaque_sp->GetSummaryAsCString(); 281 } 282 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 283 if (log) 284 { 285 if (cstr) 286 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 287 else 288 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 289 } 290 return cstr; 291 } 292 293 const char * 294 SBValue::GetLocation (const SBFrame &sb_frame) 295 { 296 return GetLocation (); 297 } 298 299 const char * 300 SBValue::GetLocation () 301 { 302 const char *cstr = NULL; 303 if (m_opaque_sp) 304 { 305 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 306 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 307 cstr = m_opaque_sp->GetLocationAsCString(); 308 } 309 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 310 if (log) 311 { 312 if (cstr) 313 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 314 else 315 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 316 } 317 return cstr; 318 } 319 320 bool 321 SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str) 322 { 323 return SetValueFromCString (value_str); 324 } 325 326 bool 327 SBValue::SetValueFromCString (const char *value_str) 328 { 329 bool success = false; 330 if (m_opaque_sp) 331 { 332 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 333 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 334 success = m_opaque_sp->SetValueFromCString (value_str); 335 } 336 return success; 337 } 338 339 SBValue 340 SBValue::GetChildAtIndex (uint32_t idx) 341 { 342 lldb::ValueObjectSP child_sp; 343 344 if (m_opaque_sp) 345 { 346 child_sp = m_opaque_sp->GetChildAtIndex (idx, true); 347 } 348 349 SBValue sb_value (child_sp); 350 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 351 if (log) 352 log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); 353 354 return sb_value; 355 } 356 357 uint32_t 358 SBValue::GetIndexOfChildWithName (const char *name) 359 { 360 uint32_t idx = UINT32_MAX; 361 if (m_opaque_sp) 362 idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); 363 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 364 if (log) 365 { 366 if (idx == UINT32_MAX) 367 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx); 368 else 369 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); 370 } 371 return idx; 372 } 373 374 SBValue 375 SBValue::GetChildMemberWithName (const char *name) 376 { 377 lldb::ValueObjectSP child_sp; 378 const ConstString str_name (name); 379 380 if (m_opaque_sp) 381 { 382 child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); 383 } 384 385 SBValue sb_value (child_sp); 386 387 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 388 if (log) 389 log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); 390 391 return sb_value; 392 } 393 394 395 uint32_t 396 SBValue::GetNumChildren () 397 { 398 uint32_t num_children = 0; 399 400 if (m_opaque_sp) 401 num_children = m_opaque_sp->GetNumChildren(); 402 403 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 404 if (log) 405 log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); 406 407 return num_children; 408 } 409 410 411 SBValue 412 SBValue::Dereference () 413 { 414 SBValue sb_value; 415 if (m_opaque_sp) 416 { 417 Error error; 418 sb_value = m_opaque_sp->Dereference (error); 419 } 420 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 421 if (log) 422 log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 423 424 return sb_value; 425 } 426 427 bool 428 SBValue::TypeIsPointerType () 429 { 430 bool is_ptr_type = false; 431 432 if (m_opaque_sp) 433 is_ptr_type = m_opaque_sp->IsPointerType(); 434 435 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 436 if (log) 437 log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); 438 439 440 return is_ptr_type; 441 } 442 443 void * 444 SBValue::GetOpaqueType() 445 { 446 if (m_opaque_sp) 447 return m_opaque_sp->GetClangType(); 448 return NULL; 449 } 450 451 // Mimic shared pointer... 452 lldb_private::ValueObject * 453 SBValue::get() const 454 { 455 return m_opaque_sp.get(); 456 } 457 458 lldb_private::ValueObject * 459 SBValue::operator->() const 460 { 461 return m_opaque_sp.get(); 462 } 463 464 lldb::ValueObjectSP & 465 SBValue::operator*() 466 { 467 return m_opaque_sp; 468 } 469 470 const lldb::ValueObjectSP & 471 SBValue::operator*() const 472 { 473 return m_opaque_sp; 474 } 475 476 bool 477 SBValue::GetExpressionPath (SBStream &description) 478 { 479 if (m_opaque_sp) 480 { 481 m_opaque_sp->GetExpressionPath (description.ref(), false); 482 return true; 483 } 484 return false; 485 } 486 487 bool 488 SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) 489 { 490 if (m_opaque_sp) 491 { 492 m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); 493 return true; 494 } 495 return false; 496 } 497 498 bool 499 SBValue::GetDescription (SBStream &description) 500 { 501 if (m_opaque_sp) 502 { 503 // Don't call all these APIs and cause more logging! 504 // const char *name = GetName(); 505 // const char *type_name = GetTypeName (); 506 // size_t byte_size = GetByteSize (); 507 // uint32_t num_children = GetNumChildren (); 508 // bool is_stale = ValueIsStale (); 509 // description.Printf ("name: '%s', type: %s, size: %d", (name != NULL ? name : "<unknown name>"), 510 // (type_name != NULL ? type_name : "<unknown type name>"), (int) byte_size); 511 // if (num_children > 0) 512 // description.Printf (", num_children: %d", num_children); 513 // 514 // if (is_stale) 515 // description.Printf (" [value is stale]"); 516 517 description.Printf ("name: '%s'", m_opaque_sp->GetName().GetCString()); 518 } 519 else 520 description.Printf ("No value"); 521 522 return true; 523 } 524 525 lldb::Format 526 SBValue::GetFormat () const 527 { 528 if (m_opaque_sp) 529 return m_opaque_sp->GetFormat(); 530 return eFormatDefault; 531 } 532 533 void 534 SBValue::SetFormat (lldb::Format format) 535 { 536 if (m_opaque_sp) 537 m_opaque_sp->SetFormat(format); 538 } 539 540