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::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); 343 return GetChildAtIndex (idx, use_dynamic_value); 344 } 345 346 SBValue 347 SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic) 348 { 349 lldb::ValueObjectSP child_sp; 350 351 if (m_opaque_sp) 352 { 353 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 354 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 355 356 child_sp = m_opaque_sp->GetChildAtIndex (idx, true); 357 if (use_dynamic != lldb::eNoDynamicValues) 358 { 359 if (child_sp) 360 { 361 lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic); 362 if (dynamic_sp) 363 child_sp = dynamic_sp; 364 } 365 } 366 } 367 368 SBValue sb_value (child_sp); 369 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 370 if (log) 371 log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", m_opaque_sp.get(), idx, sb_value.get()); 372 373 return sb_value; 374 } 375 376 uint32_t 377 SBValue::GetIndexOfChildWithName (const char *name) 378 { 379 uint32_t idx = UINT32_MAX; 380 if (m_opaque_sp) 381 { 382 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 383 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 384 385 idx = m_opaque_sp->GetIndexOfChildWithName (ConstString(name)); 386 } 387 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 388 if (log) 389 { 390 if (idx == UINT32_MAX) 391 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", m_opaque_sp.get(), name, idx); 392 else 393 log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", m_opaque_sp.get(), name, idx); 394 } 395 return idx; 396 } 397 398 SBValue 399 SBValue::GetChildMemberWithName (const char *name) 400 { 401 lldb::DynamicValueType use_dynamic_value = m_opaque_sp->GetUpdatePoint().GetTarget()->GetPreferDynamicValue(); 402 return GetChildMemberWithName (name, use_dynamic_value); 403 } 404 405 SBValue 406 SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) 407 { 408 lldb::ValueObjectSP child_sp; 409 const ConstString str_name (name); 410 411 412 if (m_opaque_sp) 413 { 414 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 415 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 416 child_sp = m_opaque_sp->GetChildMemberWithName (str_name, true); 417 if (use_dynamic_value != lldb::eNoDynamicValues) 418 { 419 if (child_sp) 420 { 421 lldb::ValueObjectSP dynamic_sp = child_sp->GetDynamicValue (use_dynamic_value); 422 if (dynamic_sp) 423 child_sp = dynamic_sp; 424 } 425 } 426 } 427 428 SBValue sb_value (child_sp); 429 430 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 431 if (log) 432 log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", m_opaque_sp.get(), name, sb_value.get()); 433 434 return sb_value; 435 } 436 437 438 uint32_t 439 SBValue::GetNumChildren () 440 { 441 uint32_t num_children = 0; 442 443 if (m_opaque_sp) 444 { 445 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 446 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 447 448 num_children = m_opaque_sp->GetNumChildren(); 449 } 450 451 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 452 if (log) 453 log->Printf ("SBValue(%p)::GetNumChildren () => %u", m_opaque_sp.get(), num_children); 454 455 return num_children; 456 } 457 458 459 SBValue 460 SBValue::Dereference () 461 { 462 SBValue sb_value; 463 if (m_opaque_sp) 464 { 465 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 466 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 467 468 Error error; 469 sb_value = m_opaque_sp->Dereference (error); 470 } 471 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 472 if (log) 473 log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", m_opaque_sp.get(), sb_value.get()); 474 475 return sb_value; 476 } 477 478 bool 479 SBValue::TypeIsPointerType () 480 { 481 bool is_ptr_type = false; 482 483 if (m_opaque_sp) 484 { 485 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 486 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 487 488 is_ptr_type = m_opaque_sp->IsPointerType(); 489 } 490 491 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 492 if (log) 493 log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", m_opaque_sp.get(), is_ptr_type); 494 495 496 return is_ptr_type; 497 } 498 499 void * 500 SBValue::GetOpaqueType() 501 { 502 if (m_opaque_sp) 503 { 504 if (m_opaque_sp->GetUpdatePoint().GetTarget()) 505 Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex()); 506 507 return m_opaque_sp->GetClangType(); 508 } 509 return NULL; 510 } 511 512 // Mimic shared pointer... 513 lldb_private::ValueObject * 514 SBValue::get() const 515 { 516 return m_opaque_sp.get(); 517 } 518 519 lldb_private::ValueObject * 520 SBValue::operator->() const 521 { 522 return m_opaque_sp.get(); 523 } 524 525 lldb::ValueObjectSP & 526 SBValue::operator*() 527 { 528 return m_opaque_sp; 529 } 530 531 const lldb::ValueObjectSP & 532 SBValue::operator*() const 533 { 534 return m_opaque_sp; 535 } 536 537 bool 538 SBValue::GetExpressionPath (SBStream &description) 539 { 540 if (m_opaque_sp) 541 { 542 m_opaque_sp->GetExpressionPath (description.ref(), false); 543 return true; 544 } 545 return false; 546 } 547 548 bool 549 SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) 550 { 551 if (m_opaque_sp) 552 { 553 m_opaque_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); 554 return true; 555 } 556 return false; 557 } 558 559 bool 560 SBValue::GetDescription (SBStream &description) 561 { 562 if (m_opaque_sp) 563 { 564 // Don't call all these APIs and cause more logging! 565 // const char *name = GetName(); 566 // const char *type_name = GetTypeName (); 567 // size_t byte_size = GetByteSize (); 568 // uint32_t num_children = GetNumChildren (); 569 // bool is_stale = ValueIsStale (); 570 // description.Printf ("name: '%s', type: %s, size: %d", (name != NULL ? name : "<unknown name>"), 571 // (type_name != NULL ? type_name : "<unknown type name>"), (int) byte_size); 572 // if (num_children > 0) 573 // description.Printf (", num_children: %d", num_children); 574 // 575 // if (is_stale) 576 // description.Printf (" [value is stale]"); 577 578 description.Printf ("name: '%s'", m_opaque_sp->GetName().GetCString()); 579 } 580 else 581 description.Printf ("No value"); 582 583 return true; 584 } 585 586 lldb::Format 587 SBValue::GetFormat () const 588 { 589 if (m_opaque_sp) 590 return m_opaque_sp->GetFormat(); 591 return eFormatDefault; 592 } 593 594 void 595 SBValue::SetFormat (lldb::Format format) 596 { 597 if (m_opaque_sp) 598 m_opaque_sp->SetFormat(format); 599 } 600 601