1 //===-- SBTypeSynthetic.cpp -----------------------------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/API/SBTypeSynthetic.h"
11 #include "SBReproducerPrivate.h"
12 
13 #include "lldb/API/SBStream.h"
14 
15 #include "lldb/DataFormatters/DataVisualization.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 #ifndef LLDB_DISABLE_PYTHON
21 
22 SBTypeSynthetic::SBTypeSynthetic() : m_opaque_sp() {
23   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTypeSynthetic);
24 }
25 
26 SBTypeSynthetic SBTypeSynthetic::CreateWithClassName(const char *data,
27                                                      uint32_t options) {
28   LLDB_RECORD_STATIC_METHOD(lldb::SBTypeSynthetic, SBTypeSynthetic,
29                             CreateWithClassName, (const char *, uint32_t), data,
30                             options);
31 
32   if (!data || data[0] == 0)
33     return LLDB_RECORD_RESULT(SBTypeSynthetic());
34   return LLDB_RECORD_RESULT(SBTypeSynthetic(ScriptedSyntheticChildrenSP(
35       new ScriptedSyntheticChildren(options, data, ""))));
36 }
37 
38 SBTypeSynthetic SBTypeSynthetic::CreateWithScriptCode(const char *data,
39                                                       uint32_t options) {
40   LLDB_RECORD_STATIC_METHOD(lldb::SBTypeSynthetic, SBTypeSynthetic,
41                             CreateWithScriptCode, (const char *, uint32_t),
42                             data, options);
43 
44   if (!data || data[0] == 0)
45     return LLDB_RECORD_RESULT(SBTypeSynthetic());
46   return LLDB_RECORD_RESULT(SBTypeSynthetic(ScriptedSyntheticChildrenSP(
47       new ScriptedSyntheticChildren(options, "", data))));
48 }
49 
50 SBTypeSynthetic::SBTypeSynthetic(const lldb::SBTypeSynthetic &rhs)
51     : m_opaque_sp(rhs.m_opaque_sp) {
52   LLDB_RECORD_CONSTRUCTOR(SBTypeSynthetic, (const lldb::SBTypeSynthetic &),
53                           rhs);
54 }
55 
56 SBTypeSynthetic::~SBTypeSynthetic() {}
57 
58 bool SBTypeSynthetic::IsValid() const {
59   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTypeSynthetic, IsValid);
60 
61   return m_opaque_sp.get() != NULL;
62 }
63 
64 bool SBTypeSynthetic::IsClassCode() {
65   LLDB_RECORD_METHOD_NO_ARGS(bool, SBTypeSynthetic, IsClassCode);
66 
67   if (!IsValid())
68     return false;
69   const char *code = m_opaque_sp->GetPythonCode();
70   return (code && *code);
71 }
72 
73 bool SBTypeSynthetic::IsClassName() {
74   LLDB_RECORD_METHOD_NO_ARGS(bool, SBTypeSynthetic, IsClassName);
75 
76   if (!IsValid())
77     return false;
78   return !IsClassCode();
79 }
80 
81 const char *SBTypeSynthetic::GetData() {
82   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBTypeSynthetic, GetData);
83 
84   if (!IsValid())
85     return NULL;
86   if (IsClassCode())
87     return m_opaque_sp->GetPythonCode();
88   else
89     return m_opaque_sp->GetPythonClassName();
90 }
91 
92 void SBTypeSynthetic::SetClassName(const char *data) {
93   LLDB_RECORD_METHOD(void, SBTypeSynthetic, SetClassName, (const char *), data);
94 
95   if (IsValid() && data && *data)
96     m_opaque_sp->SetPythonClassName(data);
97 }
98 
99 void SBTypeSynthetic::SetClassCode(const char *data) {
100   LLDB_RECORD_METHOD(void, SBTypeSynthetic, SetClassCode, (const char *), data);
101 
102   if (IsValid() && data && *data)
103     m_opaque_sp->SetPythonCode(data);
104 }
105 
106 uint32_t SBTypeSynthetic::GetOptions() {
107   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBTypeSynthetic, GetOptions);
108 
109   if (!IsValid())
110     return lldb::eTypeOptionNone;
111   return m_opaque_sp->GetOptions();
112 }
113 
114 void SBTypeSynthetic::SetOptions(uint32_t value) {
115   LLDB_RECORD_METHOD(void, SBTypeSynthetic, SetOptions, (uint32_t), value);
116 
117   if (!CopyOnWrite_Impl())
118     return;
119   m_opaque_sp->SetOptions(value);
120 }
121 
122 bool SBTypeSynthetic::GetDescription(lldb::SBStream &description,
123                                      lldb::DescriptionLevel description_level) {
124   LLDB_RECORD_METHOD(bool, SBTypeSynthetic, GetDescription,
125                      (lldb::SBStream &, lldb::DescriptionLevel), description,
126                      description_level);
127 
128   if (m_opaque_sp) {
129     description.Printf("%s\n", m_opaque_sp->GetDescription().c_str());
130     return true;
131   }
132   return false;
133 }
134 
135 lldb::SBTypeSynthetic &SBTypeSynthetic::
136 operator=(const lldb::SBTypeSynthetic &rhs) {
137   LLDB_RECORD_METHOD(lldb::SBTypeSynthetic &,
138                      SBTypeSynthetic, operator=,(const lldb::SBTypeSynthetic &),
139                      rhs);
140 
141   if (this != &rhs) {
142     m_opaque_sp = rhs.m_opaque_sp;
143   }
144   return *this;
145 }
146 
147 bool SBTypeSynthetic::operator==(lldb::SBTypeSynthetic &rhs) {
148   LLDB_RECORD_METHOD(
149       bool, SBTypeSynthetic, operator==,(lldb::SBTypeSynthetic &), rhs);
150 
151   if (!IsValid())
152     return !rhs.IsValid();
153   return m_opaque_sp == rhs.m_opaque_sp;
154 }
155 
156 bool SBTypeSynthetic::IsEqualTo(lldb::SBTypeSynthetic &rhs) {
157   LLDB_RECORD_METHOD(bool, SBTypeSynthetic, IsEqualTo,
158                      (lldb::SBTypeSynthetic &), rhs);
159 
160   if (!IsValid())
161     return !rhs.IsValid();
162 
163   if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted())
164     return false;
165 
166   if (IsClassCode() != rhs.IsClassCode())
167     return false;
168 
169   if (strcmp(GetData(), rhs.GetData()))
170     return false;
171 
172   return GetOptions() == rhs.GetOptions();
173 }
174 
175 bool SBTypeSynthetic::operator!=(lldb::SBTypeSynthetic &rhs) {
176   LLDB_RECORD_METHOD(
177       bool, SBTypeSynthetic, operator!=,(lldb::SBTypeSynthetic &), rhs);
178 
179   if (!IsValid())
180     return !rhs.IsValid();
181   return m_opaque_sp != rhs.m_opaque_sp;
182 }
183 
184 lldb::ScriptedSyntheticChildrenSP SBTypeSynthetic::GetSP() {
185   return m_opaque_sp;
186 }
187 
188 void SBTypeSynthetic::SetSP(
189     const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) {
190   m_opaque_sp = TypeSynthetic_impl_sp;
191 }
192 
193 SBTypeSynthetic::SBTypeSynthetic(
194     const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp)
195     : m_opaque_sp(TypeSynthetic_impl_sp) {}
196 
197 bool SBTypeSynthetic::CopyOnWrite_Impl() {
198   if (!IsValid())
199     return false;
200   if (m_opaque_sp.unique())
201     return true;
202 
203   ScriptedSyntheticChildrenSP new_sp(new ScriptedSyntheticChildren(
204       m_opaque_sp->GetOptions(), m_opaque_sp->GetPythonClassName(),
205       m_opaque_sp->GetPythonCode()));
206 
207   SetSP(new_sp);
208 
209   return true;
210 }
211 
212 #endif // LLDB_DISABLE_PYTHON
213