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