1//===-- SBTypeSynthetic.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/SBTypeSynthetic.h"
10#include "lldb/Utility/Instrumentation.h"
11
12#include "lldb/API/SBStream.h"
13
14#include "lldb/DataFormatters/DataVisualization.h"
15
16using namespace lldb;
17using namespace lldb_private;
18
19SBTypeSynthetic::SBTypeSynthetic() { LLDB_INSTRUMENT_VA(this); }
20
21SBTypeSynthetic SBTypeSynthetic::CreateWithClassName(const char *data,
22                                                     uint32_t options) {
23  LLDB_INSTRUMENT_VA(data, options);
24
25  if (!data || data[0] == 0)
26    return SBTypeSynthetic();
27  return SBTypeSynthetic(ScriptedSyntheticChildrenSP(
28      new ScriptedSyntheticChildren(options, data, "")));
29}
30
31SBTypeSynthetic SBTypeSynthetic::CreateWithScriptCode(const char *data,
32                                                      uint32_t options) {
33  LLDB_INSTRUMENT_VA(data, options);
34
35  if (!data || data[0] == 0)
36    return SBTypeSynthetic();
37  return SBTypeSynthetic(ScriptedSyntheticChildrenSP(
38      new ScriptedSyntheticChildren(options, "", data)));
39}
40
41SBTypeSynthetic::SBTypeSynthetic(const lldb::SBTypeSynthetic &rhs)
42    : m_opaque_sp(rhs.m_opaque_sp) {
43  LLDB_INSTRUMENT_VA(this, rhs);
44}
45
46SBTypeSynthetic::~SBTypeSynthetic() = default;
47
48bool SBTypeSynthetic::IsValid() const {
49  LLDB_INSTRUMENT_VA(this);
50  return this->operator bool();
51}
52SBTypeSynthetic::operator bool() const {
53  LLDB_INSTRUMENT_VA(this);
54
55  return m_opaque_sp.get() != nullptr;
56}
57
58bool SBTypeSynthetic::IsClassCode() {
59  LLDB_INSTRUMENT_VA(this);
60
61  if (!IsValid())
62    return false;
63  const char *code = m_opaque_sp->GetPythonCode();
64  return (code && *code);
65}
66
67bool SBTypeSynthetic::IsClassName() {
68  LLDB_INSTRUMENT_VA(this);
69
70  if (!IsValid())
71    return false;
72  return !IsClassCode();
73}
74
75const char *SBTypeSynthetic::GetData() {
76  LLDB_INSTRUMENT_VA(this);
77
78  if (!IsValid())
79    return nullptr;
80  if (IsClassCode())
81    return ConstString(m_opaque_sp->GetPythonCode()).GetCString();
82
83  return ConstString(m_opaque_sp->GetPythonClassName()).GetCString();
84}
85
86void SBTypeSynthetic::SetClassName(const char *data) {
87  LLDB_INSTRUMENT_VA(this, data);
88
89  if (IsValid() && data && *data)
90    m_opaque_sp->SetPythonClassName(data);
91}
92
93void SBTypeSynthetic::SetClassCode(const char *data) {
94  LLDB_INSTRUMENT_VA(this, data);
95
96  if (IsValid() && data && *data)
97    m_opaque_sp->SetPythonCode(data);
98}
99
100uint32_t SBTypeSynthetic::GetOptions() {
101  LLDB_INSTRUMENT_VA(this);
102
103  if (!IsValid())
104    return lldb::eTypeOptionNone;
105  return m_opaque_sp->GetOptions();
106}
107
108void SBTypeSynthetic::SetOptions(uint32_t value) {
109  LLDB_INSTRUMENT_VA(this, value);
110
111  if (!CopyOnWrite_Impl())
112    return;
113  m_opaque_sp->SetOptions(value);
114}
115
116bool SBTypeSynthetic::GetDescription(lldb::SBStream &description,
117                                     lldb::DescriptionLevel description_level) {
118  LLDB_INSTRUMENT_VA(this, description, description_level);
119
120  if (m_opaque_sp) {
121    description.Printf("%s\n", m_opaque_sp->GetDescription().c_str());
122    return true;
123  }
124  return false;
125}
126
127lldb::SBTypeSynthetic &SBTypeSynthetic::
128operator=(const lldb::SBTypeSynthetic &rhs) {
129  LLDB_INSTRUMENT_VA(this, rhs);
130
131  if (this != &rhs) {
132    m_opaque_sp = rhs.m_opaque_sp;
133  }
134  return *this;
135}
136
137bool SBTypeSynthetic::operator==(lldb::SBTypeSynthetic &rhs) {
138  LLDB_INSTRUMENT_VA(this, rhs);
139
140  if (!IsValid())
141    return !rhs.IsValid();
142  return m_opaque_sp == rhs.m_opaque_sp;
143}
144
145bool SBTypeSynthetic::IsEqualTo(lldb::SBTypeSynthetic &rhs) {
146  LLDB_INSTRUMENT_VA(this, rhs);
147
148  if (!IsValid())
149    return !rhs.IsValid();
150
151  if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted())
152    return false;
153
154  if (IsClassCode() != rhs.IsClassCode())
155    return false;
156
157  if (strcmp(GetData(), rhs.GetData()))
158    return false;
159
160  return GetOptions() == rhs.GetOptions();
161}
162
163bool SBTypeSynthetic::operator!=(lldb::SBTypeSynthetic &rhs) {
164  LLDB_INSTRUMENT_VA(this, rhs);
165
166  if (!IsValid())
167    return !rhs.IsValid();
168  return m_opaque_sp != rhs.m_opaque_sp;
169}
170
171lldb::ScriptedSyntheticChildrenSP SBTypeSynthetic::GetSP() {
172  return m_opaque_sp;
173}
174
175void SBTypeSynthetic::SetSP(
176    const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) {
177  m_opaque_sp = TypeSynthetic_impl_sp;
178}
179
180SBTypeSynthetic::SBTypeSynthetic(
181    const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp)
182    : m_opaque_sp(TypeSynthetic_impl_sp) {}
183
184bool SBTypeSynthetic::CopyOnWrite_Impl() {
185  if (!IsValid())
186    return false;
187  if (m_opaque_sp.use_count() == 1)
188    return true;
189
190  ScriptedSyntheticChildrenSP new_sp(new ScriptedSyntheticChildren(
191      m_opaque_sp->GetOptions(), m_opaque_sp->GetPythonClassName(),
192      m_opaque_sp->GetPythonCode()));
193
194  SetSP(new_sp);
195
196  return true;
197}
198