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 user_id_t 86 SBValue::GetID() 87 { 88 if (m_opaque_sp) 89 return m_opaque_sp->GetID(); 90 return LLDB_INVALID_UID; 91 } 92 93 const char * 94 SBValue::GetName() 95 { 96 97 const char *name = NULL; 98 if (m_opaque_sp) 99 name = m_opaque_sp->GetName().GetCString(); 100 101 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 102 if (log) 103 { 104 if (name) 105 log->Printf ("SBValue(%p)::GetName () => \"%s\"", m_opaque_sp.get(), name); 106 else 107 log->Printf ("SBValue(%p)::GetName () => NULL", m_opaque_sp.get(), name); 108 } 109 110 return name; 111 } 112 113 const char * 114 SBValue::GetTypeName () 115 { 116 const char *name = NULL; 117 if (m_opaque_sp) 118 name = m_opaque_sp->GetTypeName().GetCString(); 119 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 120 if (log) 121 { 122 if (name) 123 log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", m_opaque_sp.get(), name); 124 else 125 log->Printf ("SBValue(%p)::GetTypeName () => NULL", m_opaque_sp.get()); 126 } 127 128 return name; 129 } 130 131 size_t 132 SBValue::GetByteSize () 133 { 134 size_t result = 0; 135 136 if (m_opaque_sp) 137 result = m_opaque_sp->GetByteSize(); 138 139 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 140 if (log) 141 log->Printf ("SBValue(%p)::GetByteSize () => %zu", m_opaque_sp.get(), result); 142 143 return result; 144 } 145 146 bool 147 SBValue::IsInScope (const SBFrame &sb_frame) 148 { 149 return IsInScope(); 150 } 151 152 bool 153 SBValue::IsInScope () 154 { 155 bool result = false; 156 157 if (m_opaque_sp) 158 { 159 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 160 { 161 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 162 result = m_opaque_sp->IsInScope (); 163 } 164 } 165 166 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 167 if (log) 168 log->Printf ("SBValue(%p)::IsInScope () => %i", m_opaque_sp.get(), result); 169 170 return result; 171 } 172 173 const char * 174 SBValue::GetValue (const SBFrame &sb_frame) 175 { 176 return GetValue(); 177 } 178 179 const char * 180 SBValue::GetValue () 181 { 182 const char *cstr = NULL; 183 if (m_opaque_sp) 184 { 185 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 186 { 187 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 188 cstr = m_opaque_sp->GetValueAsCString (); 189 } 190 } 191 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 192 if (log) 193 { 194 if (cstr) 195 log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr); 196 else 197 log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get()); 198 } 199 200 return cstr; 201 } 202 203 ValueType 204 SBValue::GetValueType () 205 { 206 ValueType result = eValueTypeInvalid; 207 if (m_opaque_sp) 208 result = m_opaque_sp->GetValueType(); 209 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 210 if (log) 211 { 212 switch (result) 213 { 214 case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", m_opaque_sp.get()); break; 215 case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", m_opaque_sp.get()); break; 216 case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", m_opaque_sp.get()); break; 217 case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", m_opaque_sp.get()); break; 218 case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", m_opaque_sp.get()); break; 219 case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", m_opaque_sp.get()); break; 220 case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", m_opaque_sp.get()); break; 221 case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", m_opaque_sp.get()); break; 222 default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", m_opaque_sp.get(), result); break; 223 } 224 } 225 return result; 226 } 227 228 const char * 229 SBValue::GetObjectDescription (const SBFrame &sb_frame) 230 { 231 return GetObjectDescription (); 232 } 233 234 const char * 235 SBValue::GetObjectDescription () 236 { 237 const char *cstr = NULL; 238 if (m_opaque_sp) 239 { 240 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 241 { 242 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 243 cstr = m_opaque_sp->GetObjectDescription (); 244 } 245 } 246 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 247 if (log) 248 { 249 if (cstr) 250 log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr); 251 else 252 log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get()); 253 } 254 return cstr; 255 } 256 257 bool 258 SBValue::GetValueDidChange (const SBFrame &sb_frame) 259 { 260 return GetValueDidChange (); 261 } 262 263 bool 264 SBValue::GetValueDidChange () 265 { 266 bool result = false; 267 if (m_opaque_sp) 268 { 269 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 270 { 271 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 272 result = m_opaque_sp->GetValueDidChange (); 273 } 274 } 275 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 276 if (log) 277 log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result); 278 279 return result; 280 } 281 282 const char * 283 SBValue::GetSummary (const SBFrame &sb_frame) 284 { 285 return GetSummary (); 286 } 287 288 const char * 289 SBValue::GetSummary () 290 { 291 const char *cstr = NULL; 292 if (m_opaque_sp) 293 { 294 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 295 { 296 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 297 cstr = m_opaque_sp->GetSummaryAsCString(); 298 } 299 } 300 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 301 if (log) 302 { 303 if (cstr) 304 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 305 else 306 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 307 } 308 return cstr; 309 } 310 311 const char * 312 SBValue::GetLocation (const SBFrame &sb_frame) 313 { 314 return GetLocation (); 315 } 316 317 const char * 318 SBValue::GetLocation () 319 { 320 const char *cstr = NULL; 321 if (m_opaque_sp) 322 { 323 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 324 { 325 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 326 cstr = m_opaque_sp->GetLocationAsCString(); 327 } 328 } 329 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 330 if (log) 331 { 332 if (cstr) 333 log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr); 334 else 335 log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get()); 336 } 337 return cstr; 338 } 339 340 bool 341 SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str) 342 { 343 return SetValueFromCString (value_str); 344 } 345 346 bool 347 SBValue::SetValueFromCString (const char *value_str) 348 { 349 bool success = false; 350 if (m_opaque_sp) 351 { 352 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 353 { 354 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 355 success = m_opaque_sp->SetValueFromCString (value_str); 356 } 357 } 358 return success; 359 } 360 361 SBValue 362 SBValue::GetChildAtIndex (uint32_t idx) 363 { 364 if (m_opaque_sp) 365 { 366 lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); 367 return GetChildAtIndex (idx, use_dynamic_value); 368 } 369 else 370 return GetChildAtIndex (idx, eNoDynamicValues); 371 } 372 373 SBValue 374 SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic) 375 { 376 lldb::ValueObjectSP child_sp; 377 378 if (m_opaque_sp) 379 { 380 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 381 { 382 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 383 384 child_sp = m_opaque_sp->GetChildAtIndex (idx, true); 385 if (use_dynamic != lldb::eNoDynamicValues) 386 { 387 if (child_sp) 388 { 389 lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic); 390 if (dynamic_sp) 391 child_sp = dynamic_sp; 392 } 393 } 394 } 395 } 396 397 SBValue sb_value (child_sp); 398 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 399 if (log) 400 log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); 401 402 return sb_value; 403 } 404 405 uint32_t 406 SBValue::GetIndexOfChildWithName (const char *name) 407 { 408 uint32_t idx = UINT32_MAX; 409 if (m_opaque_sp) 410 { 411 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 412 { 413 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 414 415 idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); 416 } 417 } 418 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 419 if (log) 420 { 421 if (idx == UINT32_MAX) 422 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx); 423 else 424 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); 425 } 426 return idx; 427 } 428 429 SBValue 430 SBValue::GetChildMemberWithName (const char *name) 431 { 432 if (m_opaque_sp) 433 { 434 lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); 435 return GetChildMemberWithName (name, use_dynamic_value); 436 } 437 else 438 return GetChildMemberWithName (name, eNoDynamicValues); 439 } 440 441 SBValue 442 SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) 443 { 444 lldb::ValueObjectSP child_sp; 445 const ConstString str_name (name); 446 447 448 if (m_opaque_sp) 449 { 450 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 451 { 452 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 453 child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); 454 if (use_dynamic_value != lldb::eNoDynamicValues) 455 { 456 if (child_sp) 457 { 458 lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); 459 if (dynamic_sp) 460 child_sp = dynamic_sp; 461 } 462 } 463 } 464 } 465 466 SBValue sb_value (child_sp); 467 468 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 469 if (log) 470 log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); 471 472 return sb_value; 473 } 474 475 476 uint32_t 477 SBValue::GetNumChildren () 478 { 479 uint32_t num_children = 0; 480 481 if (m_opaque_sp) 482 { 483 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 484 { 485 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 486 487 num_children = m_opaque_sp->GetNumChildren(); 488 } 489 } 490 491 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 492 if (log) 493 log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); 494 495 return num_children; 496 } 497 498 499 SBValue 500 SBValue::Dereference () 501 { 502 SBValue sb_value; 503 if (m_opaque_sp) 504 { 505 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 506 { 507 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 508 509 Error error; 510 sb_value = m_opaque_sp->Dereference (error); 511 } 512 } 513 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 514 if (log) 515 log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 516 517 return sb_value; 518 } 519 520 bool 521 SBValue::TypeIsPointerType () 522 { 523 bool is_ptr_type = false; 524 525 if (m_opaque_sp) 526 { 527 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 528 { 529 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 530 531 is_ptr_type = m_opaque_sp->IsPointerType(); 532 } 533 } 534 535 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 536 if (log) 537 log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); 538 539 540 return is_ptr_type; 541 } 542 543 void * 544 SBValue::GetOpaqueType() 545 { 546 if (m_opaque_sp) 547 { 548 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 549 { 550 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 551 552 return m_opaque_sp->GetClangType(); 553 } 554 } 555 return NULL; 556 } 557 558 // Mimic shared pointer... 559 lldb_private::ValueObject * 560 SBValue::get() const 561 { 562 return m_opaque_sp.get(); 563 } 564 565 lldb_private::ValueObject * 566 SBValue::operator->() const 567 { 568 return m_opaque_sp.get(); 569 } 570 571 lldb::ValueObjectSP & 572 SBValue::operator*() 573 { 574 return m_opaque_sp; 575 } 576 577 const lldb::ValueObjectSP & 578 SBValue::operator*() const 579 { 580 return m_opaque_sp; 581 } 582 583 bool 584 SBValue::GetExpressionPath (SBStream &description) 585 { 586 if (m_opaque_sp) 587 { 588 m_opaque_sp->GetExpressionPath (description.ref(), false); 589 return true; 590 } 591 return false; 592 } 593 594 bool 595 SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) 596 { 597 if (m_opaque_sp) 598 { 599 m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); 600 return true; 601 } 602 return false; 603 } 604 605 bool 606 SBValue::GetDescription (SBStream &description) 607 { 608 if (m_opaque_sp) 609 { 610 uint32_t ptr_depth = 0; 611 uint32_t curr_depth = 0; 612 uint32_t max_depth = UINT32_MAX; 613 bool show_types = false; 614 bool show_location = false; 615 bool use_objc = false; 616 lldb::DynamicValueType use_dynamic = eNoDynamicValues; 617 bool scope_already_checked = false; 618 bool flat_output = false; 619 ValueObject::DumpValueObject (description.ref(), 620 m_opaque_sp.get(), 621 m_opaque_sp->GetName().GetCString(), 622 ptr_depth, 623 curr_depth, 624 max_depth, 625 show_types, show_location, 626 use_objc, 627 use_dynamic, 628 scope_already_checked, 629 flat_output); 630 } 631 else 632 description.Printf ("No value"); 633 634 return true; 635 } 636 637 lldb::Format 638 SBValue::GetFormat () const 639 { 640 if (m_opaque_sp) 641 return m_opaque_sp->GetFormat(); 642 return eFormatDefault; 643 } 644 645 void 646 SBValue::SetFormat (lldb::Format format) 647 { 648 if (m_opaque_sp) 649 m_opaque_sp->SetFormat(format); 650 } 651 652