1//===-- SBValue.cpp -------------------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/API/SBValue.h" 10#include "lldb/Utility/Instrumentation.h" 11 12#include "lldb/API/SBDeclaration.h" 13#include "lldb/API/SBStream.h" 14#include "lldb/API/SBTypeFilter.h" 15#include "lldb/API/SBTypeFormat.h" 16#include "lldb/API/SBTypeSummary.h" 17#include "lldb/API/SBTypeSynthetic.h" 18 19#include "lldb/Breakpoint/Watchpoint.h" 20#include "lldb/Core/Declaration.h" 21#include "lldb/Core/Module.h" 22#include "lldb/Core/Section.h" 23#include "lldb/Core/Value.h" 24#include "lldb/Core/ValueObject.h" 25#include "lldb/Core/ValueObjectConstResult.h" 26#include "lldb/DataFormatters/DataVisualization.h" 27#include "lldb/DataFormatters/DumpValueObjectOptions.h" 28#include "lldb/Symbol/Block.h" 29#include "lldb/Symbol/ObjectFile.h" 30#include "lldb/Symbol/Type.h" 31#include "lldb/Symbol/Variable.h" 32#include "lldb/Symbol/VariableList.h" 33#include "lldb/Target/ExecutionContext.h" 34#include "lldb/Target/Process.h" 35#include "lldb/Target/StackFrame.h" 36#include "lldb/Target/Target.h" 37#include "lldb/Target/Thread.h" 38#include "lldb/Utility/DataExtractor.h" 39#include "lldb/Utility/Scalar.h" 40#include "lldb/Utility/Stream.h" 41 42#include "lldb/API/SBDebugger.h" 43#include "lldb/API/SBExpressionOptions.h" 44#include "lldb/API/SBFrame.h" 45#include "lldb/API/SBProcess.h" 46#include "lldb/API/SBTarget.h" 47#include "lldb/API/SBThread.h" 48 49#include <memory> 50 51using namespace lldb; 52using namespace lldb_private; 53 54class ValueImpl { 55public: 56 ValueImpl() = default; 57 58 ValueImpl(lldb::ValueObjectSP in_valobj_sp, 59 lldb::DynamicValueType use_dynamic, bool use_synthetic, 60 const char *name = nullptr) 61 : m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic), 62 m_name(name) { 63 if (in_valobj_sp) { 64 if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable( 65 lldb::eNoDynamicValues, false))) { 66 if (!m_name.IsEmpty()) 67 m_valobj_sp->SetName(m_name); 68 } 69 } 70 } 71 72 ValueImpl(const ValueImpl &rhs) = default; 73 74 ValueImpl &operator=(const ValueImpl &rhs) { 75 if (this != &rhs) { 76 m_valobj_sp = rhs.m_valobj_sp; 77 m_use_dynamic = rhs.m_use_dynamic; 78 m_use_synthetic = rhs.m_use_synthetic; 79 m_name = rhs.m_name; 80 } 81 return *this; 82 } 83 84 bool IsValid() { 85 if (m_valobj_sp.get() == nullptr) 86 return false; 87 else { 88 // FIXME: This check is necessary but not sufficient. We for sure don't 89 // want to touch SBValues whose owning 90 // targets have gone away. This check is a little weak in that it 91 // enforces that restriction when you call IsValid, but since IsValid 92 // doesn't lock the target, you have no guarantee that the SBValue won't 93 // go invalid after you call this... Also, an SBValue could depend on 94 // data from one of the modules in the target, and those could go away 95 // independently of the target, for instance if a module is unloaded. 96 // But right now, neither SBValues nor ValueObjects know which modules 97 // they depend on. So I have no good way to make that check without 98 // tracking that in all the ValueObject subclasses. 99 TargetSP target_sp = m_valobj_sp->GetTargetSP(); 100 return target_sp && target_sp->IsValid(); 101 } 102 } 103 104 lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; } 105 106 lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker, 107 std::unique_lock<std::recursive_mutex> &lock, 108 Status &error) { 109 if (!m_valobj_sp) { 110 error.SetErrorString("invalid value object"); 111 return m_valobj_sp; 112 } 113 114 lldb::ValueObjectSP value_sp = m_valobj_sp; 115 116 Target *target = value_sp->GetTargetSP().get(); 117 // If this ValueObject holds an error, then it is valuable for that. 118 if (value_sp->GetError().Fail()) 119 return value_sp; 120 121 if (!target) 122 return ValueObjectSP(); 123 124 lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); 125 126 ProcessSP process_sp(value_sp->GetProcessSP()); 127 if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) { 128 // We don't allow people to play around with ValueObject if the process 129 // is running. If you want to look at values, pause the process, then 130 // look. 131 error.SetErrorString("process must be stopped."); 132 return ValueObjectSP(); 133 } 134 135 if (m_use_dynamic != eNoDynamicValues) { 136 ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic); 137 if (dynamic_sp) 138 value_sp = dynamic_sp; 139 } 140 141 if (m_use_synthetic) { 142 ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(); 143 if (synthetic_sp) 144 value_sp = synthetic_sp; 145 } 146 147 if (!value_sp) 148 error.SetErrorString("invalid value object"); 149 if (!m_name.IsEmpty()) 150 value_sp->SetName(m_name); 151 152 return value_sp; 153 } 154 155 void SetUseDynamic(lldb::DynamicValueType use_dynamic) { 156 m_use_dynamic = use_dynamic; 157 } 158 159 void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; } 160 161 lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; } 162 163 bool GetUseSynthetic() { return m_use_synthetic; } 164 165 // All the derived values that we would make from the m_valobj_sp will share 166 // the ExecutionContext with m_valobj_sp, so we don't need to do the 167 // calculations in GetSP to return the Target, Process, Thread or Frame. It 168 // is convenient to provide simple accessors for these, which I do here. 169 TargetSP GetTargetSP() { 170 if (m_valobj_sp) 171 return m_valobj_sp->GetTargetSP(); 172 else 173 return TargetSP(); 174 } 175 176 ProcessSP GetProcessSP() { 177 if (m_valobj_sp) 178 return m_valobj_sp->GetProcessSP(); 179 else 180 return ProcessSP(); 181 } 182 183 ThreadSP GetThreadSP() { 184 if (m_valobj_sp) 185 return m_valobj_sp->GetThreadSP(); 186 else 187 return ThreadSP(); 188 } 189 190 StackFrameSP GetFrameSP() { 191 if (m_valobj_sp) 192 return m_valobj_sp->GetFrameSP(); 193 else 194 return StackFrameSP(); 195 } 196 197private: 198 lldb::ValueObjectSP m_valobj_sp; 199 lldb::DynamicValueType m_use_dynamic; 200 bool m_use_synthetic; 201 ConstString m_name; 202}; 203 204class ValueLocker { 205public: 206 ValueLocker() = default; 207 208 ValueObjectSP GetLockedSP(ValueImpl &in_value) { 209 return in_value.GetSP(m_stop_locker, m_lock, m_lock_error); 210 } 211 212 Status &GetError() { return m_lock_error; } 213 214private: 215 Process::StopLocker m_stop_locker; 216 std::unique_lock<std::recursive_mutex> m_lock; 217 Status m_lock_error; 218}; 219 220SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); } 221 222SBValue::SBValue(const lldb::ValueObjectSP &value_sp) { 223 LLDB_INSTRUMENT_VA(this, value_sp); 224 225 SetSP(value_sp); 226} 227 228SBValue::SBValue(const SBValue &rhs) { 229 LLDB_INSTRUMENT_VA(this, rhs); 230 231 SetSP(rhs.m_opaque_sp); 232} 233 234SBValue &SBValue::operator=(const SBValue &rhs) { 235 LLDB_INSTRUMENT_VA(this, rhs); 236 237 if (this != &rhs) { 238 SetSP(rhs.m_opaque_sp); 239 } 240 return *this; 241} 242 243SBValue::~SBValue() = default; 244 245bool SBValue::IsValid() { 246 LLDB_INSTRUMENT_VA(this); 247 return this->operator bool(); 248} 249SBValue::operator bool() const { 250 LLDB_INSTRUMENT_VA(this); 251 252 // If this function ever changes to anything that does more than just check 253 // if the opaque shared pointer is non NULL, then we need to update all "if 254 // (m_opaque_sp)" code in this file. 255 return m_opaque_sp.get() != nullptr && m_opaque_sp->IsValid() && 256 m_opaque_sp->GetRootSP().get() != nullptr; 257} 258 259void SBValue::Clear() { 260 LLDB_INSTRUMENT_VA(this); 261 262 m_opaque_sp.reset(); 263} 264 265SBError SBValue::GetError() { 266 LLDB_INSTRUMENT_VA(this); 267 268 SBError sb_error; 269 270 ValueLocker locker; 271 lldb::ValueObjectSP value_sp(GetSP(locker)); 272 if (value_sp) 273 sb_error.SetError(value_sp->GetError()); 274 else 275 sb_error.SetErrorStringWithFormat("error: %s", 276 locker.GetError().AsCString()); 277 278 return sb_error; 279} 280 281user_id_t SBValue::GetID() { 282 LLDB_INSTRUMENT_VA(this); 283 284 ValueLocker locker; 285 lldb::ValueObjectSP value_sp(GetSP(locker)); 286 if (value_sp) 287 return value_sp->GetID(); 288 return LLDB_INVALID_UID; 289} 290 291const char *SBValue::GetName() { 292 LLDB_INSTRUMENT_VA(this); 293 294 ValueLocker locker; 295 lldb::ValueObjectSP value_sp(GetSP(locker)); 296 if (!value_sp) 297 return nullptr; 298 299 return value_sp->GetName().GetCString(); 300} 301 302const char *SBValue::GetTypeName() { 303 LLDB_INSTRUMENT_VA(this); 304 305 ValueLocker locker; 306 lldb::ValueObjectSP value_sp(GetSP(locker)); 307 if (!value_sp) 308 return nullptr; 309 310 return value_sp->GetQualifiedTypeName().GetCString(); 311} 312 313const char *SBValue::GetDisplayTypeName() { 314 LLDB_INSTRUMENT_VA(this); 315 316 ValueLocker locker; 317 lldb::ValueObjectSP value_sp(GetSP(locker)); 318 if (!value_sp) 319 return nullptr; 320 321 return value_sp->GetDisplayTypeName().GetCString(); 322} 323 324size_t SBValue::GetByteSize() { 325 LLDB_INSTRUMENT_VA(this); 326 327 size_t result = 0; 328 329 ValueLocker locker; 330 lldb::ValueObjectSP value_sp(GetSP(locker)); 331 if (value_sp) { 332 result = value_sp->GetByteSize().value_or(0); 333 } 334 335 return result; 336} 337 338bool SBValue::IsInScope() { 339 LLDB_INSTRUMENT_VA(this); 340 341 bool result = false; 342 343 ValueLocker locker; 344 lldb::ValueObjectSP value_sp(GetSP(locker)); 345 if (value_sp) { 346 result = value_sp->IsInScope(); 347 } 348 349 return result; 350} 351 352const char *SBValue::GetValue() { 353 LLDB_INSTRUMENT_VA(this); 354 355 ValueLocker locker; 356 lldb::ValueObjectSP value_sp(GetSP(locker)); 357 if (!value_sp) 358 return nullptr; 359 return ConstString(value_sp->GetValueAsCString()).GetCString(); 360} 361 362ValueType SBValue::GetValueType() { 363 LLDB_INSTRUMENT_VA(this); 364 365 ValueType result = eValueTypeInvalid; 366 ValueLocker locker; 367 lldb::ValueObjectSP value_sp(GetSP(locker)); 368 if (value_sp) 369 result = value_sp->GetValueType(); 370 371 return result; 372} 373 374const char *SBValue::GetObjectDescription() { 375 LLDB_INSTRUMENT_VA(this); 376 377 ValueLocker locker; 378 lldb::ValueObjectSP value_sp(GetSP(locker)); 379 if (!value_sp) 380 return nullptr; 381 382 return ConstString(value_sp->GetObjectDescription()).GetCString(); 383} 384 385SBType SBValue::GetType() { 386 LLDB_INSTRUMENT_VA(this); 387 388 SBType sb_type; 389 ValueLocker locker; 390 lldb::ValueObjectSP value_sp(GetSP(locker)); 391 TypeImplSP type_sp; 392 if (value_sp) { 393 type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl()); 394 sb_type.SetSP(type_sp); 395 } 396 397 return sb_type; 398} 399 400bool SBValue::GetValueDidChange() { 401 LLDB_INSTRUMENT_VA(this); 402 403 bool result = false; 404 ValueLocker locker; 405 lldb::ValueObjectSP value_sp(GetSP(locker)); 406 if (value_sp) { 407 if (value_sp->UpdateValueIfNeeded(false)) 408 result = value_sp->GetValueDidChange(); 409 } 410 411 return result; 412} 413 414const char *SBValue::GetSummary() { 415 LLDB_INSTRUMENT_VA(this); 416 417 ValueLocker locker; 418 lldb::ValueObjectSP value_sp(GetSP(locker)); 419 if (!value_sp) 420 return nullptr; 421 422 return ConstString(value_sp->GetSummaryAsCString()).GetCString(); 423} 424 425const char *SBValue::GetSummary(lldb::SBStream &stream, 426 lldb::SBTypeSummaryOptions &options) { 427 LLDB_INSTRUMENT_VA(this, stream, options); 428 429 ValueLocker locker; 430 lldb::ValueObjectSP value_sp(GetSP(locker)); 431 if (value_sp) { 432 std::string buffer; 433 if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty()) 434 stream.Printf("%s", buffer.c_str()); 435 } 436 return ConstString(stream.GetData()).GetCString(); 437} 438 439const char *SBValue::GetLocation() { 440 LLDB_INSTRUMENT_VA(this); 441 442 ValueLocker locker; 443 lldb::ValueObjectSP value_sp(GetSP(locker)); 444 if (!value_sp) 445 return nullptr; 446 447 return ConstString(value_sp->GetLocationAsCString()).GetCString(); 448} 449 450// Deprecated - use the one that takes an lldb::SBError 451bool SBValue::SetValueFromCString(const char *value_str) { 452 LLDB_INSTRUMENT_VA(this, value_str); 453 454 lldb::SBError dummy; 455 return SetValueFromCString(value_str, dummy); 456} 457 458bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) { 459 LLDB_INSTRUMENT_VA(this, value_str, error); 460 461 bool success = false; 462 ValueLocker locker; 463 lldb::ValueObjectSP value_sp(GetSP(locker)); 464 if (value_sp) { 465 success = value_sp->SetValueFromCString(value_str, error.ref()); 466 } else 467 error.SetErrorStringWithFormat("Could not get value: %s", 468 locker.GetError().AsCString()); 469 470 return success; 471} 472 473lldb::SBTypeFormat SBValue::GetTypeFormat() { 474 LLDB_INSTRUMENT_VA(this); 475 476 lldb::SBTypeFormat format; 477 ValueLocker locker; 478 lldb::ValueObjectSP value_sp(GetSP(locker)); 479 if (value_sp) { 480 if (value_sp->UpdateValueIfNeeded(true)) { 481 lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat(); 482 if (format_sp) 483 format.SetSP(format_sp); 484 } 485 } 486 return format; 487} 488 489lldb::SBTypeSummary SBValue::GetTypeSummary() { 490 LLDB_INSTRUMENT_VA(this); 491 492 lldb::SBTypeSummary summary; 493 ValueLocker locker; 494 lldb::ValueObjectSP value_sp(GetSP(locker)); 495 if (value_sp) { 496 if (value_sp->UpdateValueIfNeeded(true)) { 497 lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat(); 498 if (summary_sp) 499 summary.SetSP(summary_sp); 500 } 501 } 502 return summary; 503} 504 505lldb::SBTypeFilter SBValue::GetTypeFilter() { 506 LLDB_INSTRUMENT_VA(this); 507 508 lldb::SBTypeFilter filter; 509 ValueLocker locker; 510 lldb::ValueObjectSP value_sp(GetSP(locker)); 511 if (value_sp) { 512 if (value_sp->UpdateValueIfNeeded(true)) { 513 lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren(); 514 515 if (synthetic_sp && !synthetic_sp->IsScripted()) { 516 TypeFilterImplSP filter_sp = 517 std::static_pointer_cast<TypeFilterImpl>(synthetic_sp); 518 filter.SetSP(filter_sp); 519 } 520 } 521 } 522 return filter; 523} 524 525lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() { 526 LLDB_INSTRUMENT_VA(this); 527 528 lldb::SBTypeSynthetic synthetic; 529 ValueLocker locker; 530 lldb::ValueObjectSP value_sp(GetSP(locker)); 531 if (value_sp) { 532 if (value_sp->UpdateValueIfNeeded(true)) { 533 lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren(); 534 535 if (children_sp && children_sp->IsScripted()) { 536 ScriptedSyntheticChildrenSP synth_sp = 537 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); 538 synthetic.SetSP(synth_sp); 539 } 540 } 541 } 542 return synthetic; 543} 544 545lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset, 546 SBType type) { 547 LLDB_INSTRUMENT_VA(this, name, offset, type); 548 549 lldb::SBValue sb_value; 550 ValueLocker locker; 551 lldb::ValueObjectSP value_sp(GetSP(locker)); 552 lldb::ValueObjectSP new_value_sp; 553 if (value_sp) { 554 TypeImplSP type_sp(type.GetSP()); 555 if (type.IsValid()) { 556 sb_value.SetSP(value_sp->GetSyntheticChildAtOffset( 557 offset, type_sp->GetCompilerType(false), true), 558 GetPreferDynamicValue(), GetPreferSyntheticValue(), name); 559 } 560 } 561 return sb_value; 562} 563 564lldb::SBValue SBValue::Cast(SBType type) { 565 LLDB_INSTRUMENT_VA(this, type); 566 567 lldb::SBValue sb_value; 568 ValueLocker locker; 569 lldb::ValueObjectSP value_sp(GetSP(locker)); 570 TypeImplSP type_sp(type.GetSP()); 571 if (value_sp && type_sp) 572 sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)), 573 GetPreferDynamicValue(), GetPreferSyntheticValue()); 574 return sb_value; 575} 576 577lldb::SBValue SBValue::CreateValueFromExpression(const char *name, 578 const char *expression) { 579 LLDB_INSTRUMENT_VA(this, name, expression); 580 581 SBExpressionOptions options; 582 options.ref().SetKeepInMemory(true); 583 return CreateValueFromExpression(name, expression, options); 584} 585 586lldb::SBValue SBValue::CreateValueFromExpression(const char *name, 587 const char *expression, 588 SBExpressionOptions &options) { 589 LLDB_INSTRUMENT_VA(this, name, expression, options); 590 591 lldb::SBValue sb_value; 592 ValueLocker locker; 593 lldb::ValueObjectSP value_sp(GetSP(locker)); 594 lldb::ValueObjectSP new_value_sp; 595 if (value_sp) { 596 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 597 new_value_sp = ValueObject::CreateValueObjectFromExpression( 598 name, expression, exe_ctx, options.ref()); 599 if (new_value_sp) 600 new_value_sp->SetName(ConstString(name)); 601 } 602 sb_value.SetSP(new_value_sp); 603 return sb_value; 604} 605 606lldb::SBValue SBValue::CreateValueFromAddress(const char *name, 607 lldb::addr_t address, 608 SBType sb_type) { 609 LLDB_INSTRUMENT_VA(this, name, address, sb_type); 610 611 lldb::SBValue sb_value; 612 ValueLocker locker; 613 lldb::ValueObjectSP value_sp(GetSP(locker)); 614 lldb::ValueObjectSP new_value_sp; 615 lldb::TypeImplSP type_impl_sp(sb_type.GetSP()); 616 if (value_sp && type_impl_sp) { 617 CompilerType ast_type(type_impl_sp->GetCompilerType(true)); 618 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 619 new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address, 620 exe_ctx, ast_type); 621 } 622 sb_value.SetSP(new_value_sp); 623 return sb_value; 624} 625 626lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data, 627 SBType sb_type) { 628 LLDB_INSTRUMENT_VA(this, name, data, sb_type); 629 630 lldb::SBValue sb_value; 631 lldb::ValueObjectSP new_value_sp; 632 ValueLocker locker; 633 lldb::ValueObjectSP value_sp(GetSP(locker)); 634 lldb::TypeImplSP type_impl_sp(sb_type.GetSP()); 635 if (value_sp && type_impl_sp) { 636 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); 637 new_value_sp = ValueObject::CreateValueObjectFromData( 638 name, **data, exe_ctx, type_impl_sp->GetCompilerType(true)); 639 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); 640 } 641 sb_value.SetSP(new_value_sp); 642 return sb_value; 643} 644 645SBValue SBValue::GetChildAtIndex(uint32_t idx) { 646 LLDB_INSTRUMENT_VA(this, idx); 647 648 const bool can_create_synthetic = false; 649 lldb::DynamicValueType use_dynamic = eNoDynamicValues; 650 TargetSP target_sp; 651 if (m_opaque_sp) 652 target_sp = m_opaque_sp->GetTargetSP(); 653 654 if (target_sp) 655 use_dynamic = target_sp->GetPreferDynamicValue(); 656 657 return GetChildAtIndex(idx, use_dynamic, can_create_synthetic); 658} 659 660SBValue SBValue::GetChildAtIndex(uint32_t idx, 661 lldb::DynamicValueType use_dynamic, 662 bool can_create_synthetic) { 663 LLDB_INSTRUMENT_VA(this, idx, use_dynamic, can_create_synthetic); 664 665 lldb::ValueObjectSP child_sp; 666 667 ValueLocker locker; 668 lldb::ValueObjectSP value_sp(GetSP(locker)); 669 if (value_sp) { 670 const bool can_create = true; 671 child_sp = value_sp->GetChildAtIndex(idx); 672 if (can_create_synthetic && !child_sp) { 673 child_sp = value_sp->GetSyntheticArrayMember(idx, can_create); 674 } 675 } 676 677 SBValue sb_value; 678 sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue()); 679 680 return sb_value; 681} 682 683uint32_t SBValue::GetIndexOfChildWithName(const char *name) { 684 LLDB_INSTRUMENT_VA(this, name); 685 686 uint32_t idx = UINT32_MAX; 687 ValueLocker locker; 688 lldb::ValueObjectSP value_sp(GetSP(locker)); 689 if (value_sp) { 690 idx = value_sp->GetIndexOfChildWithName(name); 691 } 692 return idx; 693} 694 695SBValue SBValue::GetChildMemberWithName(const char *name) { 696 LLDB_INSTRUMENT_VA(this, name); 697 698 lldb::DynamicValueType use_dynamic_value = eNoDynamicValues; 699 TargetSP target_sp; 700 if (m_opaque_sp) 701 target_sp = m_opaque_sp->GetTargetSP(); 702 703 if (target_sp) 704 use_dynamic_value = target_sp->GetPreferDynamicValue(); 705 return GetChildMemberWithName(name, use_dynamic_value); 706} 707 708SBValue 709SBValue::GetChildMemberWithName(const char *name, 710 lldb::DynamicValueType use_dynamic_value) { 711 LLDB_INSTRUMENT_VA(this, name, use_dynamic_value); 712 713 lldb::ValueObjectSP child_sp; 714 715 ValueLocker locker; 716 lldb::ValueObjectSP value_sp(GetSP(locker)); 717 if (value_sp) { 718 child_sp = value_sp->GetChildMemberWithName(name); 719 } 720 721 SBValue sb_value; 722 sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); 723 724 return sb_value; 725} 726 727lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) { 728 LLDB_INSTRUMENT_VA(this, use_dynamic); 729 730 SBValue value_sb; 731 if (IsValid()) { 732 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic, 733 m_opaque_sp->GetUseSynthetic())); 734 value_sb.SetSP(proxy_sp); 735 } 736 return value_sb; 737} 738 739lldb::SBValue SBValue::GetStaticValue() { 740 LLDB_INSTRUMENT_VA(this); 741 742 SBValue value_sb; 743 if (IsValid()) { 744 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), 745 eNoDynamicValues, 746 m_opaque_sp->GetUseSynthetic())); 747 value_sb.SetSP(proxy_sp); 748 } 749 return value_sb; 750} 751 752lldb::SBValue SBValue::GetNonSyntheticValue() { 753 LLDB_INSTRUMENT_VA(this); 754 755 SBValue value_sb; 756 if (IsValid()) { 757 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), 758 m_opaque_sp->GetUseDynamic(), false)); 759 value_sb.SetSP(proxy_sp); 760 } 761 return value_sb; 762} 763 764lldb::DynamicValueType SBValue::GetPreferDynamicValue() { 765 LLDB_INSTRUMENT_VA(this); 766 767 if (!IsValid()) 768 return eNoDynamicValues; 769 return m_opaque_sp->GetUseDynamic(); 770} 771 772void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) { 773 LLDB_INSTRUMENT_VA(this, use_dynamic); 774 775 if (IsValid()) 776 return m_opaque_sp->SetUseDynamic(use_dynamic); 777} 778 779bool SBValue::GetPreferSyntheticValue() { 780 LLDB_INSTRUMENT_VA(this); 781 782 if (!IsValid()) 783 return false; 784 return m_opaque_sp->GetUseSynthetic(); 785} 786 787void SBValue::SetPreferSyntheticValue(bool use_synthetic) { 788 LLDB_INSTRUMENT_VA(this, use_synthetic); 789 790 if (IsValid()) 791 return m_opaque_sp->SetUseSynthetic(use_synthetic); 792} 793 794bool SBValue::IsDynamic() { 795 LLDB_INSTRUMENT_VA(this); 796 797 ValueLocker locker; 798 lldb::ValueObjectSP value_sp(GetSP(locker)); 799 if (value_sp) 800 return value_sp->IsDynamic(); 801 return false; 802} 803 804bool SBValue::IsSynthetic() { 805 LLDB_INSTRUMENT_VA(this); 806 807 ValueLocker locker; 808 lldb::ValueObjectSP value_sp(GetSP(locker)); 809 if (value_sp) 810 return value_sp->IsSynthetic(); 811 return false; 812} 813 814bool SBValue::IsSyntheticChildrenGenerated() { 815 LLDB_INSTRUMENT_VA(this); 816 817 ValueLocker locker; 818 lldb::ValueObjectSP value_sp(GetSP(locker)); 819 if (value_sp) 820 return value_sp->IsSyntheticChildrenGenerated(); 821 return false; 822} 823 824void SBValue::SetSyntheticChildrenGenerated(bool is) { 825 LLDB_INSTRUMENT_VA(this, is); 826 827 ValueLocker locker; 828 lldb::ValueObjectSP value_sp(GetSP(locker)); 829 if (value_sp) 830 return value_sp->SetSyntheticChildrenGenerated(is); 831} 832 833lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) { 834 LLDB_INSTRUMENT_VA(this, expr_path); 835 836 lldb::ValueObjectSP child_sp; 837 ValueLocker locker; 838 lldb::ValueObjectSP value_sp(GetSP(locker)); 839 if (value_sp) { 840 // using default values for all the fancy options, just do it if you can 841 child_sp = value_sp->GetValueForExpressionPath(expr_path); 842 } 843 844 SBValue sb_value; 845 sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue()); 846 847 return sb_value; 848} 849 850int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) { 851 LLDB_INSTRUMENT_VA(this, error, fail_value); 852 853 error.Clear(); 854 ValueLocker locker; 855 lldb::ValueObjectSP value_sp(GetSP(locker)); 856 if (value_sp) { 857 bool success = true; 858 uint64_t ret_val = fail_value; 859 ret_val = value_sp->GetValueAsSigned(fail_value, &success); 860 if (!success) 861 error.SetErrorString("could not resolve value"); 862 return ret_val; 863 } else 864 error.SetErrorStringWithFormat("could not get SBValue: %s", 865 locker.GetError().AsCString()); 866 867 return fail_value; 868} 869 870uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) { 871 LLDB_INSTRUMENT_VA(this, error, fail_value); 872 873 error.Clear(); 874 ValueLocker locker; 875 lldb::ValueObjectSP value_sp(GetSP(locker)); 876 if (value_sp) { 877 bool success = true; 878 uint64_t ret_val = fail_value; 879 ret_val = value_sp->GetValueAsUnsigned(fail_value, &success); 880 if (!success) 881 error.SetErrorString("could not resolve value"); 882 return ret_val; 883 } else 884 error.SetErrorStringWithFormat("could not get SBValue: %s", 885 locker.GetError().AsCString()); 886 887 return fail_value; 888} 889 890int64_t SBValue::GetValueAsSigned(int64_t fail_value) { 891 LLDB_INSTRUMENT_VA(this, fail_value); 892 893 ValueLocker locker; 894 lldb::ValueObjectSP value_sp(GetSP(locker)); 895 if (value_sp) { 896 return value_sp->GetValueAsSigned(fail_value); 897 } 898 return fail_value; 899} 900 901uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) { 902 LLDB_INSTRUMENT_VA(this, fail_value); 903 904 ValueLocker locker; 905 lldb::ValueObjectSP value_sp(GetSP(locker)); 906 if (value_sp) { 907 return value_sp->GetValueAsUnsigned(fail_value); 908 } 909 return fail_value; 910} 911 912bool SBValue::MightHaveChildren() { 913 LLDB_INSTRUMENT_VA(this); 914 915 bool has_children = false; 916 ValueLocker locker; 917 lldb::ValueObjectSP value_sp(GetSP(locker)); 918 if (value_sp) 919 has_children = value_sp->MightHaveChildren(); 920 921 return has_children; 922} 923 924bool SBValue::IsRuntimeSupportValue() { 925 LLDB_INSTRUMENT_VA(this); 926 927 bool is_support = false; 928 ValueLocker locker; 929 lldb::ValueObjectSP value_sp(GetSP(locker)); 930 if (value_sp) 931 is_support = value_sp->IsRuntimeSupportValue(); 932 933 return is_support; 934} 935 936uint32_t SBValue::GetNumChildren() { 937 LLDB_INSTRUMENT_VA(this); 938 939 return GetNumChildren(UINT32_MAX); 940} 941 942uint32_t SBValue::GetNumChildren(uint32_t max) { 943 LLDB_INSTRUMENT_VA(this, max); 944 945 uint32_t num_children = 0; 946 947 ValueLocker locker; 948 lldb::ValueObjectSP value_sp(GetSP(locker)); 949 if (value_sp) 950 num_children = value_sp->GetNumChildren(max); 951 952 return num_children; 953} 954 955SBValue SBValue::Dereference() { 956 LLDB_INSTRUMENT_VA(this); 957 958 SBValue sb_value; 959 ValueLocker locker; 960 lldb::ValueObjectSP value_sp(GetSP(locker)); 961 if (value_sp) { 962 Status error; 963 sb_value = value_sp->Dereference(error); 964 } 965 966 return sb_value; 967} 968 969// Deprecated - please use GetType().IsPointerType() instead. 970bool SBValue::TypeIsPointerType() { 971 LLDB_INSTRUMENT_VA(this); 972 973 return GetType().IsPointerType(); 974} 975 976void *SBValue::GetOpaqueType() { 977 LLDB_INSTRUMENT_VA(this); 978 979 ValueLocker locker; 980 lldb::ValueObjectSP value_sp(GetSP(locker)); 981 if (value_sp) 982 return value_sp->GetCompilerType().GetOpaqueQualType(); 983 return nullptr; 984} 985 986lldb::SBTarget SBValue::GetTarget() { 987 LLDB_INSTRUMENT_VA(this); 988 989 SBTarget sb_target; 990 TargetSP target_sp; 991 if (m_opaque_sp) { 992 target_sp = m_opaque_sp->GetTargetSP(); 993 sb_target.SetSP(target_sp); 994 } 995 996 return sb_target; 997} 998 999lldb::SBProcess SBValue::GetProcess() { 1000 LLDB_INSTRUMENT_VA(this); 1001 1002 SBProcess sb_process; 1003 ProcessSP process_sp; 1004 if (m_opaque_sp) { 1005 process_sp = m_opaque_sp->GetProcessSP(); 1006 sb_process.SetSP(process_sp); 1007 } 1008 1009 return sb_process; 1010} 1011 1012lldb::SBThread SBValue::GetThread() { 1013 LLDB_INSTRUMENT_VA(this); 1014 1015 SBThread sb_thread; 1016 ThreadSP thread_sp; 1017 if (m_opaque_sp) { 1018 thread_sp = m_opaque_sp->GetThreadSP(); 1019 sb_thread.SetThread(thread_sp); 1020 } 1021 1022 return sb_thread; 1023} 1024 1025lldb::SBFrame SBValue::GetFrame() { 1026 LLDB_INSTRUMENT_VA(this); 1027 1028 SBFrame sb_frame; 1029 StackFrameSP frame_sp; 1030 if (m_opaque_sp) { 1031 frame_sp = m_opaque_sp->GetFrameSP(); 1032 sb_frame.SetFrameSP(frame_sp); 1033 } 1034 1035 return sb_frame; 1036} 1037 1038lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const { 1039 // IsValid means that the SBValue has a value in it. But that's not the 1040 // only time that ValueObjects are useful. We also want to return the value 1041 // if there's an error state in it. 1042 if (!m_opaque_sp || (!m_opaque_sp->IsValid() 1043 && (m_opaque_sp->GetRootSP() 1044 && !m_opaque_sp->GetRootSP()->GetError().Fail()))) { 1045 locker.GetError().SetErrorString("No value"); 1046 return ValueObjectSP(); 1047 } 1048 return locker.GetLockedSP(*m_opaque_sp.get()); 1049} 1050 1051lldb::ValueObjectSP SBValue::GetSP() const { 1052 LLDB_INSTRUMENT_VA(this); 1053 1054 ValueLocker locker; 1055 return GetSP(locker); 1056} 1057 1058void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; } 1059 1060void SBValue::SetSP(const lldb::ValueObjectSP &sp) { 1061 if (sp) { 1062 lldb::TargetSP target_sp(sp->GetTargetSP()); 1063 if (target_sp) { 1064 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); 1065 bool use_synthetic = 1066 target_sp->TargetProperties::GetEnableSyntheticValue(); 1067 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); 1068 } else 1069 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true)); 1070 } else 1071 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false)); 1072} 1073 1074void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1075 lldb::DynamicValueType use_dynamic) { 1076 if (sp) { 1077 lldb::TargetSP target_sp(sp->GetTargetSP()); 1078 if (target_sp) { 1079 bool use_synthetic = 1080 target_sp->TargetProperties::GetEnableSyntheticValue(); 1081 SetSP(sp, use_dynamic, use_synthetic); 1082 } else 1083 SetSP(sp, use_dynamic, true); 1084 } else 1085 SetSP(sp, use_dynamic, false); 1086} 1087 1088void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) { 1089 if (sp) { 1090 lldb::TargetSP target_sp(sp->GetTargetSP()); 1091 if (target_sp) { 1092 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); 1093 SetSP(sp, use_dynamic, use_synthetic); 1094 } else 1095 SetSP(sp, eNoDynamicValues, use_synthetic); 1096 } else 1097 SetSP(sp, eNoDynamicValues, use_synthetic); 1098} 1099 1100void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1101 lldb::DynamicValueType use_dynamic, bool use_synthetic) { 1102 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); 1103} 1104 1105void SBValue::SetSP(const lldb::ValueObjectSP &sp, 1106 lldb::DynamicValueType use_dynamic, bool use_synthetic, 1107 const char *name) { 1108 m_opaque_sp = 1109 ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name)); 1110} 1111 1112bool SBValue::GetExpressionPath(SBStream &description) { 1113 LLDB_INSTRUMENT_VA(this, description); 1114 1115 ValueLocker locker; 1116 lldb::ValueObjectSP value_sp(GetSP(locker)); 1117 if (value_sp) { 1118 value_sp->GetExpressionPath(description.ref()); 1119 return true; 1120 } 1121 return false; 1122} 1123 1124bool SBValue::GetExpressionPath(SBStream &description, 1125 bool qualify_cxx_base_classes) { 1126 LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes); 1127 1128 ValueLocker locker; 1129 lldb::ValueObjectSP value_sp(GetSP(locker)); 1130 if (value_sp) { 1131 value_sp->GetExpressionPath(description.ref()); 1132 return true; 1133 } 1134 return false; 1135} 1136 1137lldb::SBValue SBValue::EvaluateExpression(const char *expr) const { 1138 LLDB_INSTRUMENT_VA(this, expr); 1139 1140 ValueLocker locker; 1141 lldb::ValueObjectSP value_sp(GetSP(locker)); 1142 if (!value_sp) 1143 return SBValue(); 1144 1145 lldb::TargetSP target_sp = value_sp->GetTargetSP(); 1146 if (!target_sp) 1147 return SBValue(); 1148 1149 lldb::SBExpressionOptions options; 1150 options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue()); 1151 options.SetUnwindOnError(true); 1152 options.SetIgnoreBreakpoints(true); 1153 1154 return EvaluateExpression(expr, options, nullptr); 1155} 1156 1157lldb::SBValue 1158SBValue::EvaluateExpression(const char *expr, 1159 const SBExpressionOptions &options) const { 1160 LLDB_INSTRUMENT_VA(this, expr, options); 1161 1162 return EvaluateExpression(expr, options, nullptr); 1163} 1164 1165lldb::SBValue SBValue::EvaluateExpression(const char *expr, 1166 const SBExpressionOptions &options, 1167 const char *name) const { 1168 LLDB_INSTRUMENT_VA(this, expr, options, name); 1169 1170 if (!expr || expr[0] == '\0') { 1171 return SBValue(); 1172 } 1173 1174 1175 ValueLocker locker; 1176 lldb::ValueObjectSP value_sp(GetSP(locker)); 1177 if (!value_sp) { 1178 return SBValue(); 1179 } 1180 1181 lldb::TargetSP target_sp = value_sp->GetTargetSP(); 1182 if (!target_sp) { 1183 return SBValue(); 1184 } 1185 1186 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); 1187 ExecutionContext exe_ctx(target_sp.get()); 1188 1189 StackFrame *frame = exe_ctx.GetFramePtr(); 1190 if (!frame) { 1191 return SBValue(); 1192 } 1193 1194 ValueObjectSP res_val_sp; 1195 target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr, 1196 value_sp.get()); 1197 1198 if (name) 1199 res_val_sp->SetName(ConstString(name)); 1200 1201 SBValue result; 1202 result.SetSP(res_val_sp, options.GetFetchDynamicValue()); 1203 return result; 1204} 1205 1206bool SBValue::GetDescription(SBStream &description) { 1207 LLDB_INSTRUMENT_VA(this, description); 1208 1209 Stream &strm = description.ref(); 1210 1211 ValueLocker locker; 1212 lldb::ValueObjectSP value_sp(GetSP(locker)); 1213 if (value_sp) { 1214 DumpValueObjectOptions options; 1215 options.SetUseDynamicType(m_opaque_sp->GetUseDynamic()); 1216 options.SetUseSyntheticValue(m_opaque_sp->GetUseSynthetic()); 1217 value_sp->Dump(strm, options); 1218 } else { 1219 strm.PutCString("No value"); 1220 } 1221 1222 return true; 1223} 1224 1225lldb::Format SBValue::GetFormat() { 1226 LLDB_INSTRUMENT_VA(this); 1227 1228 ValueLocker locker; 1229 lldb::ValueObjectSP value_sp(GetSP(locker)); 1230 if (value_sp) 1231 return value_sp->GetFormat(); 1232 return eFormatDefault; 1233} 1234 1235void SBValue::SetFormat(lldb::Format format) { 1236 LLDB_INSTRUMENT_VA(this, format); 1237 1238 ValueLocker locker; 1239 lldb::ValueObjectSP value_sp(GetSP(locker)); 1240 if (value_sp) 1241 value_sp->SetFormat(format); 1242} 1243 1244lldb::SBValue SBValue::AddressOf() { 1245 LLDB_INSTRUMENT_VA(this); 1246 1247 SBValue sb_value; 1248 ValueLocker locker; 1249 lldb::ValueObjectSP value_sp(GetSP(locker)); 1250 if (value_sp) { 1251 Status error; 1252 sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(), 1253 GetPreferSyntheticValue()); 1254 } 1255 1256 return sb_value; 1257} 1258 1259lldb::addr_t SBValue::GetLoadAddress() { 1260 LLDB_INSTRUMENT_VA(this); 1261 1262 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1263 ValueLocker locker; 1264 lldb::ValueObjectSP value_sp(GetSP(locker)); 1265 if (value_sp) { 1266 TargetSP target_sp(value_sp->GetTargetSP()); 1267 if (target_sp) { 1268 const bool scalar_is_load_address = true; 1269 AddressType addr_type; 1270 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1271 if (addr_type == eAddressTypeFile) { 1272 ModuleSP module_sp(value_sp->GetModule()); 1273 if (!module_sp) 1274 value = LLDB_INVALID_ADDRESS; 1275 else { 1276 Address addr; 1277 module_sp->ResolveFileAddress(value, addr); 1278 value = addr.GetLoadAddress(target_sp.get()); 1279 } 1280 } else if (addr_type == eAddressTypeHost || 1281 addr_type == eAddressTypeInvalid) 1282 value = LLDB_INVALID_ADDRESS; 1283 } 1284 } 1285 1286 return value; 1287} 1288 1289lldb::SBAddress SBValue::GetAddress() { 1290 LLDB_INSTRUMENT_VA(this); 1291 1292 Address addr; 1293 ValueLocker locker; 1294 lldb::ValueObjectSP value_sp(GetSP(locker)); 1295 if (value_sp) { 1296 TargetSP target_sp(value_sp->GetTargetSP()); 1297 if (target_sp) { 1298 lldb::addr_t value = LLDB_INVALID_ADDRESS; 1299 const bool scalar_is_load_address = true; 1300 AddressType addr_type; 1301 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); 1302 if (addr_type == eAddressTypeFile) { 1303 ModuleSP module_sp(value_sp->GetModule()); 1304 if (module_sp) 1305 module_sp->ResolveFileAddress(value, addr); 1306 } else if (addr_type == eAddressTypeLoad) { 1307 // no need to check the return value on this.. if it can actually do 1308 // the resolve addr will be in the form (section,offset), otherwise it 1309 // will simply be returned as (NULL, value) 1310 addr.SetLoadAddress(value, target_sp.get()); 1311 } 1312 } 1313 } 1314 1315 return SBAddress(addr); 1316} 1317 1318lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) { 1319 LLDB_INSTRUMENT_VA(this, item_idx, item_count); 1320 1321 lldb::SBData sb_data; 1322 ValueLocker locker; 1323 lldb::ValueObjectSP value_sp(GetSP(locker)); 1324 if (value_sp) { 1325 TargetSP target_sp(value_sp->GetTargetSP()); 1326 if (target_sp) { 1327 DataExtractorSP data_sp(new DataExtractor()); 1328 value_sp->GetPointeeData(*data_sp, item_idx, item_count); 1329 if (data_sp->GetByteSize() > 0) 1330 *sb_data = data_sp; 1331 } 1332 } 1333 1334 return sb_data; 1335} 1336 1337lldb::SBData SBValue::GetData() { 1338 LLDB_INSTRUMENT_VA(this); 1339 1340 lldb::SBData sb_data; 1341 ValueLocker locker; 1342 lldb::ValueObjectSP value_sp(GetSP(locker)); 1343 if (value_sp) { 1344 DataExtractorSP data_sp(new DataExtractor()); 1345 Status error; 1346 value_sp->GetData(*data_sp, error); 1347 if (error.Success()) 1348 *sb_data = data_sp; 1349 } 1350 1351 return sb_data; 1352} 1353 1354bool SBValue::SetData(lldb::SBData &data, SBError &error) { 1355 LLDB_INSTRUMENT_VA(this, data, error); 1356 1357 ValueLocker locker; 1358 lldb::ValueObjectSP value_sp(GetSP(locker)); 1359 bool ret = true; 1360 1361 if (value_sp) { 1362 DataExtractor *data_extractor = data.get(); 1363 1364 if (!data_extractor) { 1365 error.SetErrorString("No data to set"); 1366 ret = false; 1367 } else { 1368 Status set_error; 1369 1370 value_sp->SetData(*data_extractor, set_error); 1371 1372 if (!set_error.Success()) { 1373 error.SetErrorStringWithFormat("Couldn't set data: %s", 1374 set_error.AsCString()); 1375 ret = false; 1376 } 1377 } 1378 } else { 1379 error.SetErrorStringWithFormat( 1380 "Couldn't set data: could not get SBValue: %s", 1381 locker.GetError().AsCString()); 1382 ret = false; 1383 } 1384 1385 return ret; 1386} 1387 1388lldb::SBValue SBValue::Clone(const char *new_name) { 1389 LLDB_INSTRUMENT_VA(this, new_name); 1390 1391 ValueLocker locker; 1392 lldb::ValueObjectSP value_sp(GetSP(locker)); 1393 1394 if (value_sp) 1395 return lldb::SBValue(value_sp->Clone(ConstString(new_name))); 1396 else 1397 return lldb::SBValue(); 1398} 1399 1400lldb::SBDeclaration SBValue::GetDeclaration() { 1401 LLDB_INSTRUMENT_VA(this); 1402 1403 ValueLocker locker; 1404 lldb::ValueObjectSP value_sp(GetSP(locker)); 1405 SBDeclaration decl_sb; 1406 if (value_sp) { 1407 Declaration decl; 1408 if (value_sp->GetDeclaration(decl)) 1409 decl_sb.SetDeclaration(decl); 1410 } 1411 return decl_sb; 1412} 1413 1414lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write, 1415 SBError &error) { 1416 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error); 1417 1418 SBWatchpoint sb_watchpoint; 1419 1420 // If the SBValue is not valid, there's no point in even trying to watch it. 1421 ValueLocker locker; 1422 lldb::ValueObjectSP value_sp(GetSP(locker)); 1423 TargetSP target_sp(GetTarget().GetSP()); 1424 if (value_sp && target_sp) { 1425 // Read and Write cannot both be false. 1426 if (!read && !write) 1427 return sb_watchpoint; 1428 1429 // If the value is not in scope, don't try and watch and invalid value 1430 if (!IsInScope()) 1431 return sb_watchpoint; 1432 1433 addr_t addr = GetLoadAddress(); 1434 if (addr == LLDB_INVALID_ADDRESS) 1435 return sb_watchpoint; 1436 size_t byte_size = GetByteSize(); 1437 if (byte_size == 0) 1438 return sb_watchpoint; 1439 1440 uint32_t watch_type = 0; 1441 if (read) { 1442 watch_type |= LLDB_WATCH_TYPE_READ; 1443 // read + write, the most likely intention 1444 // is to catch all writes to this, not just 1445 // value modifications. 1446 if (write) 1447 watch_type |= LLDB_WATCH_TYPE_WRITE; 1448 } else { 1449 if (write) 1450 watch_type |= LLDB_WATCH_TYPE_MODIFY; 1451 } 1452 1453 Status rc; 1454 CompilerType type(value_sp->GetCompilerType()); 1455 WatchpointSP watchpoint_sp = 1456 target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); 1457 error.SetError(rc); 1458 1459 if (watchpoint_sp) { 1460 sb_watchpoint.SetSP(watchpoint_sp); 1461 Declaration decl; 1462 if (value_sp->GetDeclaration(decl)) { 1463 if (decl.GetFile()) { 1464 StreamString ss; 1465 // True to show fullpath for declaration file. 1466 decl.DumpStopContext(&ss, true); 1467 watchpoint_sp->SetDeclInfo(std::string(ss.GetString())); 1468 } 1469 } 1470 } 1471 } else if (target_sp) { 1472 error.SetErrorStringWithFormat("could not get SBValue: %s", 1473 locker.GetError().AsCString()); 1474 } else { 1475 error.SetErrorString("could not set watchpoint, a target is required"); 1476 } 1477 1478 return sb_watchpoint; 1479} 1480 1481// FIXME: Remove this method impl (as well as the decl in .h) once it is no 1482// longer needed. 1483// Backward compatibility fix in the interim. 1484lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, 1485 bool write) { 1486 LLDB_INSTRUMENT_VA(this, resolve_location, read, write); 1487 1488 SBError error; 1489 return Watch(resolve_location, read, write, error); 1490} 1491 1492lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read, 1493 bool write, SBError &error) { 1494 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error); 1495 1496 SBWatchpoint sb_watchpoint; 1497 if (IsInScope() && GetType().IsPointerType()) 1498 sb_watchpoint = Dereference().Watch(resolve_location, read, write, error); 1499 return sb_watchpoint; 1500} 1501 1502lldb::SBValue SBValue::Persist() { 1503 LLDB_INSTRUMENT_VA(this); 1504 1505 ValueLocker locker; 1506 lldb::ValueObjectSP value_sp(GetSP(locker)); 1507 SBValue persisted_sb; 1508 if (value_sp) { 1509 persisted_sb.SetSP(value_sp->Persist()); 1510 } 1511 return persisted_sb; 1512} 1513 1514lldb::SBValue SBValue::GetVTable() { 1515 SBValue vtable_sb; 1516 ValueLocker locker; 1517 lldb::ValueObjectSP value_sp(GetSP(locker)); 1518 if (!value_sp) 1519 return vtable_sb; 1520 1521 vtable_sb.SetSP(value_sp->GetVTable()); 1522 return vtable_sb; 1523} 1524