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