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 = llvm::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 *this;
45 }
46 
47 void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) {
48   m_opaque_up = llvm::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 
78   return m_opaque_up.get() && m_opaque_up->IsValid();
79 }
80 
81 SBFileSpec SBLineEntry::GetFileSpec() const {
82   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFileSpec, SBLineEntry, GetFileSpec);
83 
84   SBFileSpec sb_file_spec;
85   if (m_opaque_up.get() && m_opaque_up->file)
86     sb_file_spec.SetFileSpec(m_opaque_up->file);
87 
88   return LLDB_RECORD_RESULT(sb_file_spec);
89 }
90 
91 uint32_t SBLineEntry::GetLine() const {
92   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBLineEntry, GetLine);
93 
94   uint32_t line = 0;
95   if (m_opaque_up)
96     line = m_opaque_up->line;
97 
98   return line;
99 }
100 
101 uint32_t SBLineEntry::GetColumn() const {
102   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBLineEntry, GetColumn);
103 
104   if (m_opaque_up)
105     return m_opaque_up->column;
106   return 0;
107 }
108 
109 void SBLineEntry::SetFileSpec(lldb::SBFileSpec filespec) {
110   LLDB_RECORD_METHOD(void, SBLineEntry, SetFileSpec, (lldb::SBFileSpec),
111                      filespec);
112 
113   if (filespec.IsValid())
114     ref().file = filespec.ref();
115   else
116     ref().file.Clear();
117 }
118 void SBLineEntry::SetLine(uint32_t line) {
119   LLDB_RECORD_METHOD(void, SBLineEntry, SetLine, (uint32_t), line);
120 
121   ref().line = line;
122 }
123 
124 void SBLineEntry::SetColumn(uint32_t column) {
125   LLDB_RECORD_METHOD(void, SBLineEntry, SetColumn, (uint32_t), column);
126 
127   ref().line = column;
128 }
129 
130 bool SBLineEntry::operator==(const SBLineEntry &rhs) const {
131   LLDB_RECORD_METHOD_CONST(
132       bool, SBLineEntry, operator==,(const lldb::SBLineEntry &), rhs);
133 
134   lldb_private::LineEntry *lhs_ptr = m_opaque_up.get();
135   lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_up.get();
136 
137   if (lhs_ptr && rhs_ptr)
138     return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) == 0;
139 
140   return lhs_ptr == rhs_ptr;
141 }
142 
143 bool SBLineEntry::operator!=(const SBLineEntry &rhs) const {
144   LLDB_RECORD_METHOD_CONST(
145       bool, SBLineEntry, operator!=,(const lldb::SBLineEntry &), rhs);
146 
147   lldb_private::LineEntry *lhs_ptr = m_opaque_up.get();
148   lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_up.get();
149 
150   if (lhs_ptr && rhs_ptr)
151     return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) != 0;
152 
153   return lhs_ptr != rhs_ptr;
154 }
155 
156 const lldb_private::LineEntry *SBLineEntry::operator->() const {
157   return m_opaque_up.get();
158 }
159 
160 lldb_private::LineEntry &SBLineEntry::ref() {
161   if (m_opaque_up == NULL)
162     m_opaque_up.reset(new lldb_private::LineEntry());
163   return *m_opaque_up;
164 }
165 
166 const lldb_private::LineEntry &SBLineEntry::ref() const { return *m_opaque_up; }
167 
168 bool SBLineEntry::GetDescription(SBStream &description) {
169   LLDB_RECORD_METHOD(bool, SBLineEntry, GetDescription, (lldb::SBStream &),
170                      description);
171 
172   Stream &strm = description.ref();
173 
174   if (m_opaque_up) {
175     char file_path[PATH_MAX * 2];
176     m_opaque_up->file.GetPath(file_path, sizeof(file_path));
177     strm.Printf("%s:%u", file_path, GetLine());
178     if (GetColumn() > 0)
179       strm.Printf(":%u", GetColumn());
180   } else
181     strm.PutCString("No value");
182 
183   return true;
184 }
185 
186 lldb_private::LineEntry *SBLineEntry::get() { return m_opaque_up.get(); }
187