1 //===-- SBLineEntry.cpp -----------------------------------------*- C++ -*-===//
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/SBLineEntry.h"
10 #include "SBReproducerPrivate.h"
11 #include "Utils.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/Host/PosixApi.h"
14 #include "lldb/Symbol/LineEntry.h"
15 #include "lldb/Utility/StreamString.h"
16 
17 #include <limits.h>
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 SBLineEntry::SBLineEntry() : m_opaque_up() {
23   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBLineEntry);
24 }
25 
26 SBLineEntry::SBLineEntry(const SBLineEntry &rhs) : m_opaque_up() {
27   LLDB_RECORD_CONSTRUCTOR(SBLineEntry, (const lldb::SBLineEntry &), rhs);
28 
29   m_opaque_up = clone(rhs.m_opaque_up);
30 }
31 
32 SBLineEntry::SBLineEntry(const lldb_private::LineEntry *lldb_object_ptr)
33     : m_opaque_up() {
34   if (lldb_object_ptr)
35     m_opaque_up = std::make_unique<LineEntry>(*lldb_object_ptr);
36 }
37 
38 const SBLineEntry &SBLineEntry::operator=(const SBLineEntry &rhs) {
39   LLDB_RECORD_METHOD(const lldb::SBLineEntry &,
40                      SBLineEntry, operator=,(const lldb::SBLineEntry &), rhs);
41 
42   if (this != &rhs)
43     m_opaque_up = clone(rhs.m_opaque_up);
44   return LLDB_RECORD_RESULT(*this);
45 }
46 
47 void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) {
48   m_opaque_up = std::make_unique<LineEntry>(lldb_object_ref);
49 }
50 
51 SBLineEntry::~SBLineEntry() {}
52 
53 SBAddress SBLineEntry::GetStartAddress() const {
54   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBLineEntry,
55                                    GetStartAddress);
56 
57   SBAddress sb_address;
58   if (m_opaque_up)
59     sb_address.SetAddress(&m_opaque_up->range.GetBaseAddress());
60 
61   return LLDB_RECORD_RESULT(sb_address);
62 }
63 
64 SBAddress SBLineEntry::GetEndAddress() const {
65   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBLineEntry, GetEndAddress);
66 
67   SBAddress sb_address;
68   if (m_opaque_up) {
69     sb_address.SetAddress(&m_opaque_up->range.GetBaseAddress());
70     sb_address.OffsetAddress(m_opaque_up->range.GetByteSize());
71   }
72   return LLDB_RECORD_RESULT(sb_address);
73 }
74 
75 bool SBLineEntry::IsValid() const {
76   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBLineEntry, IsValid);
77   return this->operator bool();
78 }
79 SBLineEntry::operator bool() const {
80   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBLineEntry, operator bool);
81 
82   return m_opaque_up.get() && m_opaque_up->IsValid();
83 }
84 
85 SBFileSpec SBLineEntry::GetFileSpec() const {
86   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFileSpec, SBLineEntry, GetFileSpec);
87 
88   SBFileSpec sb_file_spec;
89   if (m_opaque_up.get() && m_opaque_up->file)
90     sb_file_spec.SetFileSpec(m_opaque_up->file);
91 
92   return LLDB_RECORD_RESULT(sb_file_spec);
93 }
94 
95 uint32_t SBLineEntry::GetLine() const {
96   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBLineEntry, GetLine);
97 
98   uint32_t line = 0;
99   if (m_opaque_up)
100     line = m_opaque_up->line;
101 
102   return line;
103 }
104 
105 uint32_t SBLineEntry::GetColumn() const {
106   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBLineEntry, GetColumn);
107 
108   if (m_opaque_up)
109     return m_opaque_up->column;
110   return 0;
111 }
112 
113 void SBLineEntry::SetFileSpec(lldb::SBFileSpec filespec) {
114   LLDB_RECORD_METHOD(void, SBLineEntry, SetFileSpec, (lldb::SBFileSpec),
115                      filespec);
116 
117   if (filespec.IsValid())
118     ref().file = filespec.ref();
119   else
120     ref().file.Clear();
121 }
122 void SBLineEntry::SetLine(uint32_t line) {
123   LLDB_RECORD_METHOD(void, SBLineEntry, SetLine, (uint32_t), line);
124 
125   ref().line = line;
126 }
127 
128 void SBLineEntry::SetColumn(uint32_t column) {
129   LLDB_RECORD_METHOD(void, SBLineEntry, SetColumn, (uint32_t), column);
130 
131   ref().line = column;
132 }
133 
134 bool SBLineEntry::operator==(const SBLineEntry &rhs) const {
135   LLDB_RECORD_METHOD_CONST(
136       bool, SBLineEntry, operator==,(const lldb::SBLineEntry &), rhs);
137 
138   lldb_private::LineEntry *lhs_ptr = m_opaque_up.get();
139   lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_up.get();
140 
141   if (lhs_ptr && rhs_ptr)
142     return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) == 0;
143 
144   return lhs_ptr == rhs_ptr;
145 }
146 
147 bool SBLineEntry::operator!=(const SBLineEntry &rhs) const {
148   LLDB_RECORD_METHOD_CONST(
149       bool, SBLineEntry, operator!=,(const lldb::SBLineEntry &), rhs);
150 
151   lldb_private::LineEntry *lhs_ptr = m_opaque_up.get();
152   lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_up.get();
153 
154   if (lhs_ptr && rhs_ptr)
155     return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) != 0;
156 
157   return lhs_ptr != rhs_ptr;
158 }
159 
160 const lldb_private::LineEntry *SBLineEntry::operator->() const {
161   return m_opaque_up.get();
162 }
163 
164 lldb_private::LineEntry &SBLineEntry::ref() {
165   if (m_opaque_up == nullptr)
166     m_opaque_up.reset(new lldb_private::LineEntry());
167   return *m_opaque_up;
168 }
169 
170 const lldb_private::LineEntry &SBLineEntry::ref() const { return *m_opaque_up; }
171 
172 bool SBLineEntry::GetDescription(SBStream &description) {
173   LLDB_RECORD_METHOD(bool, SBLineEntry, GetDescription, (lldb::SBStream &),
174                      description);
175 
176   Stream &strm = description.ref();
177 
178   if (m_opaque_up) {
179     char file_path[PATH_MAX * 2];
180     m_opaque_up->file.GetPath(file_path, sizeof(file_path));
181     strm.Printf("%s:%u", file_path, GetLine());
182     if (GetColumn() > 0)
183       strm.Printf(":%u", GetColumn());
184   } else
185     strm.PutCString("No value");
186 
187   return true;
188 }
189 
190 lldb_private::LineEntry *SBLineEntry::get() { return m_opaque_up.get(); }
191 
192 namespace lldb_private {
193 namespace repro {
194 
195 template <>
196 void RegisterMethods<SBLineEntry>(Registry &R) {
197   LLDB_REGISTER_CONSTRUCTOR(SBLineEntry, ());
198   LLDB_REGISTER_CONSTRUCTOR(SBLineEntry, (const lldb::SBLineEntry &));
199   LLDB_REGISTER_METHOD(const lldb::SBLineEntry &,
200                        SBLineEntry, operator=,(const lldb::SBLineEntry &));
201   LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBLineEntry, GetStartAddress,
202                              ());
203   LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBLineEntry, GetEndAddress, ());
204   LLDB_REGISTER_METHOD_CONST(bool, SBLineEntry, IsValid, ());
205   LLDB_REGISTER_METHOD_CONST(bool, SBLineEntry, operator bool, ());
206   LLDB_REGISTER_METHOD_CONST(lldb::SBFileSpec, SBLineEntry, GetFileSpec, ());
207   LLDB_REGISTER_METHOD_CONST(uint32_t, SBLineEntry, GetLine, ());
208   LLDB_REGISTER_METHOD_CONST(uint32_t, SBLineEntry, GetColumn, ());
209   LLDB_REGISTER_METHOD(void, SBLineEntry, SetFileSpec, (lldb::SBFileSpec));
210   LLDB_REGISTER_METHOD(void, SBLineEntry, SetLine, (uint32_t));
211   LLDB_REGISTER_METHOD(void, SBLineEntry, SetColumn, (uint32_t));
212   LLDB_REGISTER_METHOD_CONST(
213       bool, SBLineEntry, operator==,(const lldb::SBLineEntry &));
214   LLDB_REGISTER_METHOD_CONST(
215       bool, SBLineEntry, operator!=,(const lldb::SBLineEntry &));
216   LLDB_REGISTER_METHOD(bool, SBLineEntry, GetDescription, (lldb::SBStream &));
217 }
218 
219 }
220 }
221