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 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 SBTypeSynthetic::SBTypeSynthetic() { LLDB_INSTRUMENT_VA(this); }
20 
21 SBTypeSynthetic 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 
31 SBTypeSynthetic 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 
41 SBTypeSynthetic::SBTypeSynthetic(const lldb::SBTypeSynthetic &rhs)
42     : m_opaque_sp(rhs.m_opaque_sp) {
43   LLDB_INSTRUMENT_VA(this, rhs);
44 }
45 
46 SBTypeSynthetic::~SBTypeSynthetic() = default;
47 
48 bool SBTypeSynthetic::IsValid() const {
49   LLDB_INSTRUMENT_VA(this);
50   return this->operator bool();
51 }
52 SBTypeSynthetic::operator bool() const {
53   LLDB_INSTRUMENT_VA(this);
54 
55   return m_opaque_sp.get() != nullptr;
56 }
57 
58 bool 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 
67 bool SBTypeSynthetic::IsClassName() {
68   LLDB_INSTRUMENT_VA(this);
69 
70   if (!IsValid())
71     return false;
72   return !IsClassCode();
73 }
74 
75 const 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 
86 void 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 
93 void 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 
100 uint32_t SBTypeSynthetic::GetOptions() {
101   LLDB_INSTRUMENT_VA(this);
102 
103   if (!IsValid())
104     return lldb::eTypeOptionNone;
105   return m_opaque_sp->GetOptions();
106 }
107 
108 void 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 
116 bool 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 
127 lldb::SBTypeSynthetic &SBTypeSynthetic::
128 operator=(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 
137 bool 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 
145 bool 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 
163 bool 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 
171 lldb::ScriptedSyntheticChildrenSP SBTypeSynthetic::GetSP() {
172   return m_opaque_sp;
173 }
174 
175 void SBTypeSynthetic::SetSP(
176     const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) {
177   m_opaque_sp = TypeSynthetic_impl_sp;
178 }
179 
180 SBTypeSynthetic::SBTypeSynthetic(
181     const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp)
182     : m_opaque_sp(TypeSynthetic_impl_sp) {}
183 
184 bool SBTypeSynthetic::CopyOnWrite_Impl() {
185   if (!IsValid())
186     return false;
187   if (m_opaque_sp.unique())
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