Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / API / SBValue.cpp
blob34d01d759ba55a44ca77b9af453892d6551955b3
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 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBValue.h"
10 #include "lldb/Utility/Instrumentation.h"
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"
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/Symbol/Block.h"
28 #include "lldb/Symbol/ObjectFile.h"
29 #include "lldb/Symbol/Type.h"
30 #include "lldb/Symbol/Variable.h"
31 #include "lldb/Symbol/VariableList.h"
32 #include "lldb/Target/ExecutionContext.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/StackFrame.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "lldb/Utility/DataExtractor.h"
38 #include "lldb/Utility/Scalar.h"
39 #include "lldb/Utility/Stream.h"
41 #include "lldb/API/SBDebugger.h"
42 #include "lldb/API/SBExpressionOptions.h"
43 #include "lldb/API/SBFrame.h"
44 #include "lldb/API/SBProcess.h"
45 #include "lldb/API/SBTarget.h"
46 #include "lldb/API/SBThread.h"
48 #include <memory>
50 using namespace lldb;
51 using namespace lldb_private;
53 class ValueImpl {
54 public:
55 ValueImpl() = default;
57 ValueImpl(lldb::ValueObjectSP in_valobj_sp,
58 lldb::DynamicValueType use_dynamic, bool use_synthetic,
59 const char *name = nullptr)
60 : m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
61 m_name(name) {
62 if (in_valobj_sp) {
63 if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(
64 lldb::eNoDynamicValues, false))) {
65 if (!m_name.IsEmpty())
66 m_valobj_sp->SetName(m_name);
71 ValueImpl(const ValueImpl &rhs) = default;
73 ValueImpl &operator=(const ValueImpl &rhs) {
74 if (this != &rhs) {
75 m_valobj_sp = rhs.m_valobj_sp;
76 m_use_dynamic = rhs.m_use_dynamic;
77 m_use_synthetic = rhs.m_use_synthetic;
78 m_name = rhs.m_name;
80 return *this;
83 bool IsValid() {
84 if (m_valobj_sp.get() == nullptr)
85 return false;
86 else {
87 // FIXME: This check is necessary but not sufficient. We for sure don't
88 // want to touch SBValues whose owning
89 // targets have gone away. This check is a little weak in that it
90 // enforces that restriction when you call IsValid, but since IsValid
91 // doesn't lock the target, you have no guarantee that the SBValue won't
92 // go invalid after you call this... Also, an SBValue could depend on
93 // data from one of the modules in the target, and those could go away
94 // independently of the target, for instance if a module is unloaded.
95 // But right now, neither SBValues nor ValueObjects know which modules
96 // they depend on. So I have no good way to make that check without
97 // tracking that in all the ValueObject subclasses.
98 TargetSP target_sp = m_valobj_sp->GetTargetSP();
99 return target_sp && target_sp->IsValid();
103 lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; }
105 lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker,
106 std::unique_lock<std::recursive_mutex> &lock,
107 Status &error) {
108 if (!m_valobj_sp) {
109 error.SetErrorString("invalid value object");
110 return m_valobj_sp;
113 lldb::ValueObjectSP value_sp = m_valobj_sp;
115 Target *target = value_sp->GetTargetSP().get();
116 // If this ValueObject holds an error, then it is valuable for that.
117 if (value_sp->GetError().Fail())
118 return value_sp;
120 if (!target)
121 return ValueObjectSP();
123 lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
125 ProcessSP process_sp(value_sp->GetProcessSP());
126 if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) {
127 // We don't allow people to play around with ValueObject if the process
128 // is running. If you want to look at values, pause the process, then
129 // look.
130 error.SetErrorString("process must be stopped.");
131 return ValueObjectSP();
134 if (m_use_dynamic != eNoDynamicValues) {
135 ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic);
136 if (dynamic_sp)
137 value_sp = dynamic_sp;
140 if (m_use_synthetic) {
141 ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
142 if (synthetic_sp)
143 value_sp = synthetic_sp;
146 if (!value_sp)
147 error.SetErrorString("invalid value object");
148 if (!m_name.IsEmpty())
149 value_sp->SetName(m_name);
151 return value_sp;
154 void SetUseDynamic(lldb::DynamicValueType use_dynamic) {
155 m_use_dynamic = use_dynamic;
158 void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; }
160 lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; }
162 bool GetUseSynthetic() { return m_use_synthetic; }
164 // All the derived values that we would make from the m_valobj_sp will share
165 // the ExecutionContext with m_valobj_sp, so we don't need to do the
166 // calculations in GetSP to return the Target, Process, Thread or Frame. It
167 // is convenient to provide simple accessors for these, which I do here.
168 TargetSP GetTargetSP() {
169 if (m_valobj_sp)
170 return m_valobj_sp->GetTargetSP();
171 else
172 return TargetSP();
175 ProcessSP GetProcessSP() {
176 if (m_valobj_sp)
177 return m_valobj_sp->GetProcessSP();
178 else
179 return ProcessSP();
182 ThreadSP GetThreadSP() {
183 if (m_valobj_sp)
184 return m_valobj_sp->GetThreadSP();
185 else
186 return ThreadSP();
189 StackFrameSP GetFrameSP() {
190 if (m_valobj_sp)
191 return m_valobj_sp->GetFrameSP();
192 else
193 return StackFrameSP();
196 private:
197 lldb::ValueObjectSP m_valobj_sp;
198 lldb::DynamicValueType m_use_dynamic;
199 bool m_use_synthetic;
200 ConstString m_name;
203 class ValueLocker {
204 public:
205 ValueLocker() = default;
207 ValueObjectSP GetLockedSP(ValueImpl &in_value) {
208 return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
211 Status &GetError() { return m_lock_error; }
213 private:
214 Process::StopLocker m_stop_locker;
215 std::unique_lock<std::recursive_mutex> m_lock;
216 Status m_lock_error;
219 SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); }
221 SBValue::SBValue(const lldb::ValueObjectSP &value_sp) {
222 LLDB_INSTRUMENT_VA(this, value_sp);
224 SetSP(value_sp);
227 SBValue::SBValue(const SBValue &rhs) {
228 LLDB_INSTRUMENT_VA(this, rhs);
230 SetSP(rhs.m_opaque_sp);
233 SBValue &SBValue::operator=(const SBValue &rhs) {
234 LLDB_INSTRUMENT_VA(this, rhs);
236 if (this != &rhs) {
237 SetSP(rhs.m_opaque_sp);
239 return *this;
242 SBValue::~SBValue() = default;
244 bool SBValue::IsValid() {
245 LLDB_INSTRUMENT_VA(this);
246 return this->operator bool();
248 SBValue::operator bool() const {
249 LLDB_INSTRUMENT_VA(this);
251 // If this function ever changes to anything that does more than just check
252 // if the opaque shared pointer is non NULL, then we need to update all "if
253 // (m_opaque_sp)" code in this file.
254 return m_opaque_sp.get() != nullptr && m_opaque_sp->IsValid() &&
255 m_opaque_sp->GetRootSP().get() != nullptr;
258 void SBValue::Clear() {
259 LLDB_INSTRUMENT_VA(this);
261 m_opaque_sp.reset();
264 SBError SBValue::GetError() {
265 LLDB_INSTRUMENT_VA(this);
267 SBError sb_error;
269 ValueLocker locker;
270 lldb::ValueObjectSP value_sp(GetSP(locker));
271 if (value_sp)
272 sb_error.SetError(value_sp->GetError());
273 else
274 sb_error.SetErrorStringWithFormat("error: %s",
275 locker.GetError().AsCString());
277 return sb_error;
280 user_id_t SBValue::GetID() {
281 LLDB_INSTRUMENT_VA(this);
283 ValueLocker locker;
284 lldb::ValueObjectSP value_sp(GetSP(locker));
285 if (value_sp)
286 return value_sp->GetID();
287 return LLDB_INVALID_UID;
290 const char *SBValue::GetName() {
291 LLDB_INSTRUMENT_VA(this);
293 ValueLocker locker;
294 lldb::ValueObjectSP value_sp(GetSP(locker));
295 if (!value_sp)
296 return nullptr;
298 return value_sp->GetName().GetCString();
301 const char *SBValue::GetTypeName() {
302 LLDB_INSTRUMENT_VA(this);
304 ValueLocker locker;
305 lldb::ValueObjectSP value_sp(GetSP(locker));
306 if (!value_sp)
307 return nullptr;
309 return value_sp->GetQualifiedTypeName().GetCString();
312 const char *SBValue::GetDisplayTypeName() {
313 LLDB_INSTRUMENT_VA(this);
315 ValueLocker locker;
316 lldb::ValueObjectSP value_sp(GetSP(locker));
317 if (!value_sp)
318 return nullptr;
320 return value_sp->GetDisplayTypeName().GetCString();
323 size_t SBValue::GetByteSize() {
324 LLDB_INSTRUMENT_VA(this);
326 size_t result = 0;
328 ValueLocker locker;
329 lldb::ValueObjectSP value_sp(GetSP(locker));
330 if (value_sp) {
331 result = value_sp->GetByteSize().value_or(0);
334 return result;
337 bool SBValue::IsInScope() {
338 LLDB_INSTRUMENT_VA(this);
340 bool result = false;
342 ValueLocker locker;
343 lldb::ValueObjectSP value_sp(GetSP(locker));
344 if (value_sp) {
345 result = value_sp->IsInScope();
348 return result;
351 const char *SBValue::GetValue() {
352 LLDB_INSTRUMENT_VA(this);
354 ValueLocker locker;
355 lldb::ValueObjectSP value_sp(GetSP(locker));
356 if (!value_sp)
357 return nullptr;
358 return ConstString(value_sp->GetValueAsCString()).GetCString();
361 ValueType SBValue::GetValueType() {
362 LLDB_INSTRUMENT_VA(this);
364 ValueType result = eValueTypeInvalid;
365 ValueLocker locker;
366 lldb::ValueObjectSP value_sp(GetSP(locker));
367 if (value_sp)
368 result = value_sp->GetValueType();
370 return result;
373 const char *SBValue::GetObjectDescription() {
374 LLDB_INSTRUMENT_VA(this);
376 ValueLocker locker;
377 lldb::ValueObjectSP value_sp(GetSP(locker));
378 if (!value_sp)
379 return nullptr;
381 return ConstString(value_sp->GetObjectDescription()).GetCString();
384 SBType SBValue::GetType() {
385 LLDB_INSTRUMENT_VA(this);
387 SBType sb_type;
388 ValueLocker locker;
389 lldb::ValueObjectSP value_sp(GetSP(locker));
390 TypeImplSP type_sp;
391 if (value_sp) {
392 type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl());
393 sb_type.SetSP(type_sp);
396 return sb_type;
399 bool SBValue::GetValueDidChange() {
400 LLDB_INSTRUMENT_VA(this);
402 bool result = false;
403 ValueLocker locker;
404 lldb::ValueObjectSP value_sp(GetSP(locker));
405 if (value_sp) {
406 if (value_sp->UpdateValueIfNeeded(false))
407 result = value_sp->GetValueDidChange();
410 return result;
413 const char *SBValue::GetSummary() {
414 LLDB_INSTRUMENT_VA(this);
416 ValueLocker locker;
417 lldb::ValueObjectSP value_sp(GetSP(locker));
418 if (!value_sp)
419 return nullptr;
421 return ConstString(value_sp->GetSummaryAsCString()).GetCString();
424 const char *SBValue::GetSummary(lldb::SBStream &stream,
425 lldb::SBTypeSummaryOptions &options) {
426 LLDB_INSTRUMENT_VA(this, stream, options);
428 ValueLocker locker;
429 lldb::ValueObjectSP value_sp(GetSP(locker));
430 if (value_sp) {
431 std::string buffer;
432 if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
433 stream.Printf("%s", buffer.c_str());
435 return ConstString(stream.GetData()).GetCString();
438 const char *SBValue::GetLocation() {
439 LLDB_INSTRUMENT_VA(this);
441 ValueLocker locker;
442 lldb::ValueObjectSP value_sp(GetSP(locker));
443 if (!value_sp)
444 return nullptr;
446 return ConstString(value_sp->GetLocationAsCString()).GetCString();
449 // Deprecated - use the one that takes an lldb::SBError
450 bool SBValue::SetValueFromCString(const char *value_str) {
451 LLDB_INSTRUMENT_VA(this, value_str);
453 lldb::SBError dummy;
454 return SetValueFromCString(value_str, dummy);
457 bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) {
458 LLDB_INSTRUMENT_VA(this, value_str, error);
460 bool success = false;
461 ValueLocker locker;
462 lldb::ValueObjectSP value_sp(GetSP(locker));
463 if (value_sp) {
464 success = value_sp->SetValueFromCString(value_str, error.ref());
465 } else
466 error.SetErrorStringWithFormat("Could not get value: %s",
467 locker.GetError().AsCString());
469 return success;
472 lldb::SBTypeFormat SBValue::GetTypeFormat() {
473 LLDB_INSTRUMENT_VA(this);
475 lldb::SBTypeFormat format;
476 ValueLocker locker;
477 lldb::ValueObjectSP value_sp(GetSP(locker));
478 if (value_sp) {
479 if (value_sp->UpdateValueIfNeeded(true)) {
480 lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat();
481 if (format_sp)
482 format.SetSP(format_sp);
485 return format;
488 lldb::SBTypeSummary SBValue::GetTypeSummary() {
489 LLDB_INSTRUMENT_VA(this);
491 lldb::SBTypeSummary summary;
492 ValueLocker locker;
493 lldb::ValueObjectSP value_sp(GetSP(locker));
494 if (value_sp) {
495 if (value_sp->UpdateValueIfNeeded(true)) {
496 lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat();
497 if (summary_sp)
498 summary.SetSP(summary_sp);
501 return summary;
504 lldb::SBTypeFilter SBValue::GetTypeFilter() {
505 LLDB_INSTRUMENT_VA(this);
507 lldb::SBTypeFilter filter;
508 ValueLocker locker;
509 lldb::ValueObjectSP value_sp(GetSP(locker));
510 if (value_sp) {
511 if (value_sp->UpdateValueIfNeeded(true)) {
512 lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren();
514 if (synthetic_sp && !synthetic_sp->IsScripted()) {
515 TypeFilterImplSP filter_sp =
516 std::static_pointer_cast<TypeFilterImpl>(synthetic_sp);
517 filter.SetSP(filter_sp);
521 return filter;
524 lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() {
525 LLDB_INSTRUMENT_VA(this);
527 lldb::SBTypeSynthetic synthetic;
528 ValueLocker locker;
529 lldb::ValueObjectSP value_sp(GetSP(locker));
530 if (value_sp) {
531 if (value_sp->UpdateValueIfNeeded(true)) {
532 lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren();
534 if (children_sp && children_sp->IsScripted()) {
535 ScriptedSyntheticChildrenSP synth_sp =
536 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
537 synthetic.SetSP(synth_sp);
541 return synthetic;
544 lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset,
545 SBType type) {
546 LLDB_INSTRUMENT_VA(this, name, offset, type);
548 lldb::SBValue sb_value;
549 ValueLocker locker;
550 lldb::ValueObjectSP value_sp(GetSP(locker));
551 lldb::ValueObjectSP new_value_sp;
552 if (value_sp) {
553 TypeImplSP type_sp(type.GetSP());
554 if (type.IsValid()) {
555 sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(
556 offset, type_sp->GetCompilerType(false), true),
557 GetPreferDynamicValue(), GetPreferSyntheticValue(), name);
560 return sb_value;
563 lldb::SBValue SBValue::Cast(SBType type) {
564 LLDB_INSTRUMENT_VA(this, type);
566 lldb::SBValue sb_value;
567 ValueLocker locker;
568 lldb::ValueObjectSP value_sp(GetSP(locker));
569 TypeImplSP type_sp(type.GetSP());
570 if (value_sp && type_sp)
571 sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)),
572 GetPreferDynamicValue(), GetPreferSyntheticValue());
573 return sb_value;
576 lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
577 const char *expression) {
578 LLDB_INSTRUMENT_VA(this, name, expression);
580 SBExpressionOptions options;
581 options.ref().SetKeepInMemory(true);
582 return CreateValueFromExpression(name, expression, options);
585 lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
586 const char *expression,
587 SBExpressionOptions &options) {
588 LLDB_INSTRUMENT_VA(this, name, expression, options);
590 lldb::SBValue sb_value;
591 ValueLocker locker;
592 lldb::ValueObjectSP value_sp(GetSP(locker));
593 lldb::ValueObjectSP new_value_sp;
594 if (value_sp) {
595 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
596 new_value_sp = ValueObject::CreateValueObjectFromExpression(
597 name, expression, exe_ctx, options.ref());
598 if (new_value_sp)
599 new_value_sp->SetName(ConstString(name));
601 sb_value.SetSP(new_value_sp);
602 return sb_value;
605 lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
606 lldb::addr_t address,
607 SBType sb_type) {
608 LLDB_INSTRUMENT_VA(this, name, address, sb_type);
610 lldb::SBValue sb_value;
611 ValueLocker locker;
612 lldb::ValueObjectSP value_sp(GetSP(locker));
613 lldb::ValueObjectSP new_value_sp;
614 lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
615 if (value_sp && type_impl_sp) {
616 CompilerType ast_type(type_impl_sp->GetCompilerType(true));
617 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
618 new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address,
619 exe_ctx, ast_type);
621 sb_value.SetSP(new_value_sp);
622 return sb_value;
625 lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
626 SBType sb_type) {
627 LLDB_INSTRUMENT_VA(this, name, data, sb_type);
629 lldb::SBValue sb_value;
630 lldb::ValueObjectSP new_value_sp;
631 ValueLocker locker;
632 lldb::ValueObjectSP value_sp(GetSP(locker));
633 lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
634 if (value_sp && type_impl_sp) {
635 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
636 new_value_sp = ValueObject::CreateValueObjectFromData(
637 name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
638 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
640 sb_value.SetSP(new_value_sp);
641 return sb_value;
644 SBValue SBValue::GetChildAtIndex(uint32_t idx) {
645 LLDB_INSTRUMENT_VA(this, idx);
647 const bool can_create_synthetic = false;
648 lldb::DynamicValueType use_dynamic = eNoDynamicValues;
649 TargetSP target_sp;
650 if (m_opaque_sp)
651 target_sp = m_opaque_sp->GetTargetSP();
653 if (target_sp)
654 use_dynamic = target_sp->GetPreferDynamicValue();
656 return GetChildAtIndex(idx, use_dynamic, can_create_synthetic);
659 SBValue SBValue::GetChildAtIndex(uint32_t idx,
660 lldb::DynamicValueType use_dynamic,
661 bool can_create_synthetic) {
662 LLDB_INSTRUMENT_VA(this, idx, use_dynamic, can_create_synthetic);
664 lldb::ValueObjectSP child_sp;
666 ValueLocker locker;
667 lldb::ValueObjectSP value_sp(GetSP(locker));
668 if (value_sp) {
669 const bool can_create = true;
670 child_sp = value_sp->GetChildAtIndex(idx);
671 if (can_create_synthetic && !child_sp) {
672 child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
676 SBValue sb_value;
677 sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue());
679 return sb_value;
682 uint32_t SBValue::GetIndexOfChildWithName(const char *name) {
683 LLDB_INSTRUMENT_VA(this, name);
685 uint32_t idx = UINT32_MAX;
686 ValueLocker locker;
687 lldb::ValueObjectSP value_sp(GetSP(locker));
688 if (value_sp) {
689 idx = value_sp->GetIndexOfChildWithName(name);
691 return idx;
694 SBValue SBValue::GetChildMemberWithName(const char *name) {
695 LLDB_INSTRUMENT_VA(this, name);
697 lldb::DynamicValueType use_dynamic_value = eNoDynamicValues;
698 TargetSP target_sp;
699 if (m_opaque_sp)
700 target_sp = m_opaque_sp->GetTargetSP();
702 if (target_sp)
703 use_dynamic_value = target_sp->GetPreferDynamicValue();
704 return GetChildMemberWithName(name, use_dynamic_value);
707 SBValue
708 SBValue::GetChildMemberWithName(const char *name,
709 lldb::DynamicValueType use_dynamic_value) {
710 LLDB_INSTRUMENT_VA(this, name, use_dynamic_value);
712 lldb::ValueObjectSP child_sp;
714 ValueLocker locker;
715 lldb::ValueObjectSP value_sp(GetSP(locker));
716 if (value_sp) {
717 child_sp = value_sp->GetChildMemberWithName(name);
720 SBValue sb_value;
721 sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());
723 return sb_value;
726 lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
727 LLDB_INSTRUMENT_VA(this, use_dynamic);
729 SBValue value_sb;
730 if (IsValid()) {
731 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic,
732 m_opaque_sp->GetUseSynthetic()));
733 value_sb.SetSP(proxy_sp);
735 return value_sb;
738 lldb::SBValue SBValue::GetStaticValue() {
739 LLDB_INSTRUMENT_VA(this);
741 SBValue value_sb;
742 if (IsValid()) {
743 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
744 eNoDynamicValues,
745 m_opaque_sp->GetUseSynthetic()));
746 value_sb.SetSP(proxy_sp);
748 return value_sb;
751 lldb::SBValue SBValue::GetNonSyntheticValue() {
752 LLDB_INSTRUMENT_VA(this);
754 SBValue value_sb;
755 if (IsValid()) {
756 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
757 m_opaque_sp->GetUseDynamic(), false));
758 value_sb.SetSP(proxy_sp);
760 return value_sb;
763 lldb::DynamicValueType SBValue::GetPreferDynamicValue() {
764 LLDB_INSTRUMENT_VA(this);
766 if (!IsValid())
767 return eNoDynamicValues;
768 return m_opaque_sp->GetUseDynamic();
771 void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) {
772 LLDB_INSTRUMENT_VA(this, use_dynamic);
774 if (IsValid())
775 return m_opaque_sp->SetUseDynamic(use_dynamic);
778 bool SBValue::GetPreferSyntheticValue() {
779 LLDB_INSTRUMENT_VA(this);
781 if (!IsValid())
782 return false;
783 return m_opaque_sp->GetUseSynthetic();
786 void SBValue::SetPreferSyntheticValue(bool use_synthetic) {
787 LLDB_INSTRUMENT_VA(this, use_synthetic);
789 if (IsValid())
790 return m_opaque_sp->SetUseSynthetic(use_synthetic);
793 bool SBValue::IsDynamic() {
794 LLDB_INSTRUMENT_VA(this);
796 ValueLocker locker;
797 lldb::ValueObjectSP value_sp(GetSP(locker));
798 if (value_sp)
799 return value_sp->IsDynamic();
800 return false;
803 bool SBValue::IsSynthetic() {
804 LLDB_INSTRUMENT_VA(this);
806 ValueLocker locker;
807 lldb::ValueObjectSP value_sp(GetSP(locker));
808 if (value_sp)
809 return value_sp->IsSynthetic();
810 return false;
813 bool SBValue::IsSyntheticChildrenGenerated() {
814 LLDB_INSTRUMENT_VA(this);
816 ValueLocker locker;
817 lldb::ValueObjectSP value_sp(GetSP(locker));
818 if (value_sp)
819 return value_sp->IsSyntheticChildrenGenerated();
820 return false;
823 void SBValue::SetSyntheticChildrenGenerated(bool is) {
824 LLDB_INSTRUMENT_VA(this, is);
826 ValueLocker locker;
827 lldb::ValueObjectSP value_sp(GetSP(locker));
828 if (value_sp)
829 return value_sp->SetSyntheticChildrenGenerated(is);
832 lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) {
833 LLDB_INSTRUMENT_VA(this, expr_path);
835 lldb::ValueObjectSP child_sp;
836 ValueLocker locker;
837 lldb::ValueObjectSP value_sp(GetSP(locker));
838 if (value_sp) {
839 // using default values for all the fancy options, just do it if you can
840 child_sp = value_sp->GetValueForExpressionPath(expr_path);
843 SBValue sb_value;
844 sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue());
846 return sb_value;
849 int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) {
850 LLDB_INSTRUMENT_VA(this, error, fail_value);
852 error.Clear();
853 ValueLocker locker;
854 lldb::ValueObjectSP value_sp(GetSP(locker));
855 if (value_sp) {
856 bool success = true;
857 uint64_t ret_val = fail_value;
858 ret_val = value_sp->GetValueAsSigned(fail_value, &success);
859 if (!success)
860 error.SetErrorString("could not resolve value");
861 return ret_val;
862 } else
863 error.SetErrorStringWithFormat("could not get SBValue: %s",
864 locker.GetError().AsCString());
866 return fail_value;
869 uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) {
870 LLDB_INSTRUMENT_VA(this, error, fail_value);
872 error.Clear();
873 ValueLocker locker;
874 lldb::ValueObjectSP value_sp(GetSP(locker));
875 if (value_sp) {
876 bool success = true;
877 uint64_t ret_val = fail_value;
878 ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
879 if (!success)
880 error.SetErrorString("could not resolve value");
881 return ret_val;
882 } else
883 error.SetErrorStringWithFormat("could not get SBValue: %s",
884 locker.GetError().AsCString());
886 return fail_value;
889 int64_t SBValue::GetValueAsSigned(int64_t fail_value) {
890 LLDB_INSTRUMENT_VA(this, fail_value);
892 ValueLocker locker;
893 lldb::ValueObjectSP value_sp(GetSP(locker));
894 if (value_sp) {
895 return value_sp->GetValueAsSigned(fail_value);
897 return fail_value;
900 uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
901 LLDB_INSTRUMENT_VA(this, fail_value);
903 ValueLocker locker;
904 lldb::ValueObjectSP value_sp(GetSP(locker));
905 if (value_sp) {
906 return value_sp->GetValueAsUnsigned(fail_value);
908 return fail_value;
911 bool SBValue::MightHaveChildren() {
912 LLDB_INSTRUMENT_VA(this);
914 bool has_children = false;
915 ValueLocker locker;
916 lldb::ValueObjectSP value_sp(GetSP(locker));
917 if (value_sp)
918 has_children = value_sp->MightHaveChildren();
920 return has_children;
923 bool SBValue::IsRuntimeSupportValue() {
924 LLDB_INSTRUMENT_VA(this);
926 bool is_support = false;
927 ValueLocker locker;
928 lldb::ValueObjectSP value_sp(GetSP(locker));
929 if (value_sp)
930 is_support = value_sp->IsRuntimeSupportValue();
932 return is_support;
935 uint32_t SBValue::GetNumChildren() {
936 LLDB_INSTRUMENT_VA(this);
938 return GetNumChildren(UINT32_MAX);
941 uint32_t SBValue::GetNumChildren(uint32_t max) {
942 LLDB_INSTRUMENT_VA(this, max);
944 uint32_t num_children = 0;
946 ValueLocker locker;
947 lldb::ValueObjectSP value_sp(GetSP(locker));
948 if (value_sp)
949 num_children = value_sp->GetNumChildren(max);
951 return num_children;
954 SBValue SBValue::Dereference() {
955 LLDB_INSTRUMENT_VA(this);
957 SBValue sb_value;
958 ValueLocker locker;
959 lldb::ValueObjectSP value_sp(GetSP(locker));
960 if (value_sp) {
961 Status error;
962 sb_value = value_sp->Dereference(error);
965 return sb_value;
968 // Deprecated - please use GetType().IsPointerType() instead.
969 bool SBValue::TypeIsPointerType() {
970 LLDB_INSTRUMENT_VA(this);
972 return GetType().IsPointerType();
975 void *SBValue::GetOpaqueType() {
976 LLDB_INSTRUMENT_VA(this);
978 ValueLocker locker;
979 lldb::ValueObjectSP value_sp(GetSP(locker));
980 if (value_sp)
981 return value_sp->GetCompilerType().GetOpaqueQualType();
982 return nullptr;
985 lldb::SBTarget SBValue::GetTarget() {
986 LLDB_INSTRUMENT_VA(this);
988 SBTarget sb_target;
989 TargetSP target_sp;
990 if (m_opaque_sp) {
991 target_sp = m_opaque_sp->GetTargetSP();
992 sb_target.SetSP(target_sp);
995 return sb_target;
998 lldb::SBProcess SBValue::GetProcess() {
999 LLDB_INSTRUMENT_VA(this);
1001 SBProcess sb_process;
1002 ProcessSP process_sp;
1003 if (m_opaque_sp) {
1004 process_sp = m_opaque_sp->GetProcessSP();
1005 sb_process.SetSP(process_sp);
1008 return sb_process;
1011 lldb::SBThread SBValue::GetThread() {
1012 LLDB_INSTRUMENT_VA(this);
1014 SBThread sb_thread;
1015 ThreadSP thread_sp;
1016 if (m_opaque_sp) {
1017 thread_sp = m_opaque_sp->GetThreadSP();
1018 sb_thread.SetThread(thread_sp);
1021 return sb_thread;
1024 lldb::SBFrame SBValue::GetFrame() {
1025 LLDB_INSTRUMENT_VA(this);
1027 SBFrame sb_frame;
1028 StackFrameSP frame_sp;
1029 if (m_opaque_sp) {
1030 frame_sp = m_opaque_sp->GetFrameSP();
1031 sb_frame.SetFrameSP(frame_sp);
1034 return sb_frame;
1037 lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const {
1038 // IsValid means that the SBValue has a value in it. But that's not the
1039 // only time that ValueObjects are useful. We also want to return the value
1040 // if there's an error state in it.
1041 if (!m_opaque_sp || (!m_opaque_sp->IsValid()
1042 && (m_opaque_sp->GetRootSP()
1043 && !m_opaque_sp->GetRootSP()->GetError().Fail()))) {
1044 locker.GetError().SetErrorString("No value");
1045 return ValueObjectSP();
1047 return locker.GetLockedSP(*m_opaque_sp.get());
1050 lldb::ValueObjectSP SBValue::GetSP() const {
1051 LLDB_INSTRUMENT_VA(this);
1053 ValueLocker locker;
1054 return GetSP(locker);
1057 void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; }
1059 void SBValue::SetSP(const lldb::ValueObjectSP &sp) {
1060 if (sp) {
1061 lldb::TargetSP target_sp(sp->GetTargetSP());
1062 if (target_sp) {
1063 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1064 bool use_synthetic =
1065 target_sp->TargetProperties::GetEnableSyntheticValue();
1066 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1067 } else
1068 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true));
1069 } else
1070 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false));
1073 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1074 lldb::DynamicValueType use_dynamic) {
1075 if (sp) {
1076 lldb::TargetSP target_sp(sp->GetTargetSP());
1077 if (target_sp) {
1078 bool use_synthetic =
1079 target_sp->TargetProperties::GetEnableSyntheticValue();
1080 SetSP(sp, use_dynamic, use_synthetic);
1081 } else
1082 SetSP(sp, use_dynamic, true);
1083 } else
1084 SetSP(sp, use_dynamic, false);
1087 void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) {
1088 if (sp) {
1089 lldb::TargetSP target_sp(sp->GetTargetSP());
1090 if (target_sp) {
1091 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1092 SetSP(sp, use_dynamic, use_synthetic);
1093 } else
1094 SetSP(sp, eNoDynamicValues, use_synthetic);
1095 } else
1096 SetSP(sp, eNoDynamicValues, use_synthetic);
1099 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1100 lldb::DynamicValueType use_dynamic, bool use_synthetic) {
1101 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1104 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1105 lldb::DynamicValueType use_dynamic, bool use_synthetic,
1106 const char *name) {
1107 m_opaque_sp =
1108 ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name));
1111 bool SBValue::GetExpressionPath(SBStream &description) {
1112 LLDB_INSTRUMENT_VA(this, description);
1114 ValueLocker locker;
1115 lldb::ValueObjectSP value_sp(GetSP(locker));
1116 if (value_sp) {
1117 value_sp->GetExpressionPath(description.ref());
1118 return true;
1120 return false;
1123 bool SBValue::GetExpressionPath(SBStream &description,
1124 bool qualify_cxx_base_classes) {
1125 LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes);
1127 ValueLocker locker;
1128 lldb::ValueObjectSP value_sp(GetSP(locker));
1129 if (value_sp) {
1130 value_sp->GetExpressionPath(description.ref());
1131 return true;
1133 return false;
1136 lldb::SBValue SBValue::EvaluateExpression(const char *expr) const {
1137 LLDB_INSTRUMENT_VA(this, expr);
1139 ValueLocker locker;
1140 lldb::ValueObjectSP value_sp(GetSP(locker));
1141 if (!value_sp)
1142 return SBValue();
1144 lldb::TargetSP target_sp = value_sp->GetTargetSP();
1145 if (!target_sp)
1146 return SBValue();
1148 lldb::SBExpressionOptions options;
1149 options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
1150 options.SetUnwindOnError(true);
1151 options.SetIgnoreBreakpoints(true);
1153 return EvaluateExpression(expr, options, nullptr);
1156 lldb::SBValue
1157 SBValue::EvaluateExpression(const char *expr,
1158 const SBExpressionOptions &options) const {
1159 LLDB_INSTRUMENT_VA(this, expr, options);
1161 return EvaluateExpression(expr, options, nullptr);
1164 lldb::SBValue SBValue::EvaluateExpression(const char *expr,
1165 const SBExpressionOptions &options,
1166 const char *name) const {
1167 LLDB_INSTRUMENT_VA(this, expr, options, name);
1169 if (!expr || expr[0] == '\0') {
1170 return SBValue();
1174 ValueLocker locker;
1175 lldb::ValueObjectSP value_sp(GetSP(locker));
1176 if (!value_sp) {
1177 return SBValue();
1180 lldb::TargetSP target_sp = value_sp->GetTargetSP();
1181 if (!target_sp) {
1182 return SBValue();
1185 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
1186 ExecutionContext exe_ctx(target_sp.get());
1188 StackFrame *frame = exe_ctx.GetFramePtr();
1189 if (!frame) {
1190 return SBValue();
1193 ValueObjectSP res_val_sp;
1194 target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr,
1195 value_sp.get());
1197 if (name)
1198 res_val_sp->SetName(ConstString(name));
1200 SBValue result;
1201 result.SetSP(res_val_sp, options.GetFetchDynamicValue());
1202 return result;
1205 bool SBValue::GetDescription(SBStream &description) {
1206 LLDB_INSTRUMENT_VA(this, description);
1208 Stream &strm = description.ref();
1210 ValueLocker locker;
1211 lldb::ValueObjectSP value_sp(GetSP(locker));
1212 if (value_sp)
1213 value_sp->Dump(strm);
1214 else
1215 strm.PutCString("No value");
1217 return true;
1220 lldb::Format SBValue::GetFormat() {
1221 LLDB_INSTRUMENT_VA(this);
1223 ValueLocker locker;
1224 lldb::ValueObjectSP value_sp(GetSP(locker));
1225 if (value_sp)
1226 return value_sp->GetFormat();
1227 return eFormatDefault;
1230 void SBValue::SetFormat(lldb::Format format) {
1231 LLDB_INSTRUMENT_VA(this, format);
1233 ValueLocker locker;
1234 lldb::ValueObjectSP value_sp(GetSP(locker));
1235 if (value_sp)
1236 value_sp->SetFormat(format);
1239 lldb::SBValue SBValue::AddressOf() {
1240 LLDB_INSTRUMENT_VA(this);
1242 SBValue sb_value;
1243 ValueLocker locker;
1244 lldb::ValueObjectSP value_sp(GetSP(locker));
1245 if (value_sp) {
1246 Status error;
1247 sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(),
1248 GetPreferSyntheticValue());
1251 return sb_value;
1254 lldb::addr_t SBValue::GetLoadAddress() {
1255 LLDB_INSTRUMENT_VA(this);
1257 lldb::addr_t value = LLDB_INVALID_ADDRESS;
1258 ValueLocker locker;
1259 lldb::ValueObjectSP value_sp(GetSP(locker));
1260 if (value_sp) {
1261 TargetSP target_sp(value_sp->GetTargetSP());
1262 if (target_sp) {
1263 const bool scalar_is_load_address = true;
1264 AddressType addr_type;
1265 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1266 if (addr_type == eAddressTypeFile) {
1267 ModuleSP module_sp(value_sp->GetModule());
1268 if (!module_sp)
1269 value = LLDB_INVALID_ADDRESS;
1270 else {
1271 Address addr;
1272 module_sp->ResolveFileAddress(value, addr);
1273 value = addr.GetLoadAddress(target_sp.get());
1275 } else if (addr_type == eAddressTypeHost ||
1276 addr_type == eAddressTypeInvalid)
1277 value = LLDB_INVALID_ADDRESS;
1281 return value;
1284 lldb::SBAddress SBValue::GetAddress() {
1285 LLDB_INSTRUMENT_VA(this);
1287 Address addr;
1288 ValueLocker locker;
1289 lldb::ValueObjectSP value_sp(GetSP(locker));
1290 if (value_sp) {
1291 TargetSP target_sp(value_sp->GetTargetSP());
1292 if (target_sp) {
1293 lldb::addr_t value = LLDB_INVALID_ADDRESS;
1294 const bool scalar_is_load_address = true;
1295 AddressType addr_type;
1296 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1297 if (addr_type == eAddressTypeFile) {
1298 ModuleSP module_sp(value_sp->GetModule());
1299 if (module_sp)
1300 module_sp->ResolveFileAddress(value, addr);
1301 } else if (addr_type == eAddressTypeLoad) {
1302 // no need to check the return value on this.. if it can actually do
1303 // the resolve addr will be in the form (section,offset), otherwise it
1304 // will simply be returned as (NULL, value)
1305 addr.SetLoadAddress(value, target_sp.get());
1310 return SBAddress(addr);
1313 lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
1314 LLDB_INSTRUMENT_VA(this, item_idx, item_count);
1316 lldb::SBData sb_data;
1317 ValueLocker locker;
1318 lldb::ValueObjectSP value_sp(GetSP(locker));
1319 if (value_sp) {
1320 TargetSP target_sp(value_sp->GetTargetSP());
1321 if (target_sp) {
1322 DataExtractorSP data_sp(new DataExtractor());
1323 value_sp->GetPointeeData(*data_sp, item_idx, item_count);
1324 if (data_sp->GetByteSize() > 0)
1325 *sb_data = data_sp;
1329 return sb_data;
1332 lldb::SBData SBValue::GetData() {
1333 LLDB_INSTRUMENT_VA(this);
1335 lldb::SBData sb_data;
1336 ValueLocker locker;
1337 lldb::ValueObjectSP value_sp(GetSP(locker));
1338 if (value_sp) {
1339 DataExtractorSP data_sp(new DataExtractor());
1340 Status error;
1341 value_sp->GetData(*data_sp, error);
1342 if (error.Success())
1343 *sb_data = data_sp;
1346 return sb_data;
1349 bool SBValue::SetData(lldb::SBData &data, SBError &error) {
1350 LLDB_INSTRUMENT_VA(this, data, error);
1352 ValueLocker locker;
1353 lldb::ValueObjectSP value_sp(GetSP(locker));
1354 bool ret = true;
1356 if (value_sp) {
1357 DataExtractor *data_extractor = data.get();
1359 if (!data_extractor) {
1360 error.SetErrorString("No data to set");
1361 ret = false;
1362 } else {
1363 Status set_error;
1365 value_sp->SetData(*data_extractor, set_error);
1367 if (!set_error.Success()) {
1368 error.SetErrorStringWithFormat("Couldn't set data: %s",
1369 set_error.AsCString());
1370 ret = false;
1373 } else {
1374 error.SetErrorStringWithFormat(
1375 "Couldn't set data: could not get SBValue: %s",
1376 locker.GetError().AsCString());
1377 ret = false;
1380 return ret;
1383 lldb::SBValue SBValue::Clone(const char *new_name) {
1384 LLDB_INSTRUMENT_VA(this, new_name);
1386 ValueLocker locker;
1387 lldb::ValueObjectSP value_sp(GetSP(locker));
1389 if (value_sp)
1390 return lldb::SBValue(value_sp->Clone(ConstString(new_name)));
1391 else
1392 return lldb::SBValue();
1395 lldb::SBDeclaration SBValue::GetDeclaration() {
1396 LLDB_INSTRUMENT_VA(this);
1398 ValueLocker locker;
1399 lldb::ValueObjectSP value_sp(GetSP(locker));
1400 SBDeclaration decl_sb;
1401 if (value_sp) {
1402 Declaration decl;
1403 if (value_sp->GetDeclaration(decl))
1404 decl_sb.SetDeclaration(decl);
1406 return decl_sb;
1409 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write,
1410 SBError &error) {
1411 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
1413 SBWatchpoint sb_watchpoint;
1415 // If the SBValue is not valid, there's no point in even trying to watch it.
1416 ValueLocker locker;
1417 lldb::ValueObjectSP value_sp(GetSP(locker));
1418 TargetSP target_sp(GetTarget().GetSP());
1419 if (value_sp && target_sp) {
1420 // Read and Write cannot both be false.
1421 if (!read && !write)
1422 return sb_watchpoint;
1424 // If the value is not in scope, don't try and watch and invalid value
1425 if (!IsInScope())
1426 return sb_watchpoint;
1428 addr_t addr = GetLoadAddress();
1429 if (addr == LLDB_INVALID_ADDRESS)
1430 return sb_watchpoint;
1431 size_t byte_size = GetByteSize();
1432 if (byte_size == 0)
1433 return sb_watchpoint;
1435 uint32_t watch_type = 0;
1436 if (read) {
1437 watch_type |= LLDB_WATCH_TYPE_READ;
1438 // read + write, the most likely intention
1439 // is to catch all writes to this, not just
1440 // value modifications.
1441 if (write)
1442 watch_type |= LLDB_WATCH_TYPE_WRITE;
1443 } else {
1444 if (write)
1445 watch_type |= LLDB_WATCH_TYPE_MODIFY;
1448 Status rc;
1449 CompilerType type(value_sp->GetCompilerType());
1450 WatchpointSP watchpoint_sp =
1451 target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
1452 error.SetError(rc);
1454 if (watchpoint_sp) {
1455 sb_watchpoint.SetSP(watchpoint_sp);
1456 Declaration decl;
1457 if (value_sp->GetDeclaration(decl)) {
1458 if (decl.GetFile()) {
1459 StreamString ss;
1460 // True to show fullpath for declaration file.
1461 decl.DumpStopContext(&ss, true);
1462 watchpoint_sp->SetDeclInfo(std::string(ss.GetString()));
1466 } else if (target_sp) {
1467 error.SetErrorStringWithFormat("could not get SBValue: %s",
1468 locker.GetError().AsCString());
1469 } else {
1470 error.SetErrorString("could not set watchpoint, a target is required");
1473 return sb_watchpoint;
1476 // FIXME: Remove this method impl (as well as the decl in .h) once it is no
1477 // longer needed.
1478 // Backward compatibility fix in the interim.
1479 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read,
1480 bool write) {
1481 LLDB_INSTRUMENT_VA(this, resolve_location, read, write);
1483 SBError error;
1484 return Watch(resolve_location, read, write, error);
1487 lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read,
1488 bool write, SBError &error) {
1489 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
1491 SBWatchpoint sb_watchpoint;
1492 if (IsInScope() && GetType().IsPointerType())
1493 sb_watchpoint = Dereference().Watch(resolve_location, read, write, error);
1494 return sb_watchpoint;
1497 lldb::SBValue SBValue::Persist() {
1498 LLDB_INSTRUMENT_VA(this);
1500 ValueLocker locker;
1501 lldb::ValueObjectSP value_sp(GetSP(locker));
1502 SBValue persisted_sb;
1503 if (value_sp) {
1504 persisted_sb.SetSP(value_sp->Persist());
1506 return persisted_sb;
1509 lldb::SBValue SBValue::GetVTable() {
1510 SBValue vtable_sb;
1511 ValueLocker locker;
1512 lldb::ValueObjectSP value_sp(GetSP(locker));
1513 if (!value_sp)
1514 return vtable_sb;
1516 vtable_sb.SetSP(value_sp->GetVTable());
1517 return vtable_sb;