1 //===-- SBLineEntry.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <limits.h>
11 
12 #include "lldb/API/SBLineEntry.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/Core/Log.h"
15 #include "lldb/Core/StreamString.h"
16 #include "lldb/Symbol/LineEntry.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 SBLineEntry::SBLineEntry() : m_opaque_ap() {}
22 
23 SBLineEntry::SBLineEntry(const SBLineEntry &rhs) : m_opaque_ap() {
24   if (rhs.IsValid())
25     ref() = rhs.ref();
26 }
27 
28 SBLineEntry::SBLineEntry(const lldb_private::LineEntry *lldb_object_ptr)
29     : m_opaque_ap() {
30   if (lldb_object_ptr)
31     ref() = *lldb_object_ptr;
32 }
33 
34 const SBLineEntry &SBLineEntry::operator=(const SBLineEntry &rhs) {
35   if (this != &rhs) {
36     if (rhs.IsValid())
37       ref() = rhs.ref();
38     else
39       m_opaque_ap.reset();
40   }
41   return *this;
42 }
43 
44 void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) {
45   ref() = lldb_object_ref;
46 }
47 
48 SBLineEntry::~SBLineEntry() {}
49 
50 SBAddress SBLineEntry::GetStartAddress() const {
51   SBAddress sb_address;
52   if (m_opaque_ap.get())
53     sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress());
54 
55   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
56   if (log) {
57     StreamString sstr;
58     const Address *addr = sb_address.get();
59     if (addr)
60       addr->Dump(&sstr, NULL, Address::DumpStyleModuleWithFileAddress,
61                  Address::DumpStyleInvalid, 4);
62     log->Printf("SBLineEntry(%p)::GetStartAddress () => SBAddress (%p): %s",
63                 static_cast<void *>(m_opaque_ap.get()),
64                 static_cast<void *>(sb_address.get()), sstr.GetData());
65   }
66 
67   return sb_address;
68 }
69 
70 SBAddress SBLineEntry::GetEndAddress() const {
71   SBAddress sb_address;
72   if (m_opaque_ap.get()) {
73     sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress());
74     sb_address.OffsetAddress(m_opaque_ap->range.GetByteSize());
75   }
76   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
77   if (log) {
78     StreamString sstr;
79     const Address *addr = sb_address.get();
80     if (addr)
81       addr->Dump(&sstr, NULL, Address::DumpStyleModuleWithFileAddress,
82                  Address::DumpStyleInvalid, 4);
83     log->Printf("SBLineEntry(%p)::GetEndAddress () => SBAddress (%p): %s",
84                 static_cast<void *>(m_opaque_ap.get()),
85                 static_cast<void *>(sb_address.get()), sstr.GetData());
86   }
87   return sb_address;
88 }
89 
90 bool SBLineEntry::IsValid() const {
91   return m_opaque_ap.get() && m_opaque_ap->IsValid();
92 }
93 
94 SBFileSpec SBLineEntry::GetFileSpec() const {
95   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
96 
97   SBFileSpec sb_file_spec;
98   if (m_opaque_ap.get() && m_opaque_ap->file)
99     sb_file_spec.SetFileSpec(m_opaque_ap->file);
100 
101   if (log) {
102     SBStream sstr;
103     sb_file_spec.GetDescription(sstr);
104     log->Printf("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s",
105                 static_cast<void *>(m_opaque_ap.get()),
106                 static_cast<const void *>(sb_file_spec.get()), sstr.GetData());
107   }
108 
109   return sb_file_spec;
110 }
111 
112 uint32_t SBLineEntry::GetLine() const {
113   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
114 
115   uint32_t line = 0;
116   if (m_opaque_ap.get())
117     line = m_opaque_ap->line;
118 
119   if (log)
120     log->Printf("SBLineEntry(%p)::GetLine () => %u",
121                 static_cast<void *>(m_opaque_ap.get()), line);
122 
123   return line;
124 }
125 
126 uint32_t SBLineEntry::GetColumn() const {
127   if (m_opaque_ap.get())
128     return m_opaque_ap->column;
129   return 0;
130 }
131 
132 void SBLineEntry::SetFileSpec(lldb::SBFileSpec filespec) {
133   if (filespec.IsValid())
134     ref().file = filespec.ref();
135   else
136     ref().file.Clear();
137 }
138 void SBLineEntry::SetLine(uint32_t line) { ref().line = line; }
139 
140 void SBLineEntry::SetColumn(uint32_t column) { ref().line = column; }
141 
142 bool SBLineEntry::operator==(const SBLineEntry &rhs) const {
143   lldb_private::LineEntry *lhs_ptr = m_opaque_ap.get();
144   lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_ap.get();
145 
146   if (lhs_ptr && rhs_ptr)
147     return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) == 0;
148 
149   return lhs_ptr == rhs_ptr;
150 }
151 
152 bool SBLineEntry::operator!=(const SBLineEntry &rhs) const {
153   lldb_private::LineEntry *lhs_ptr = m_opaque_ap.get();
154   lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_ap.get();
155 
156   if (lhs_ptr && rhs_ptr)
157     return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) != 0;
158 
159   return lhs_ptr != rhs_ptr;
160 }
161 
162 const lldb_private::LineEntry *SBLineEntry::operator->() const {
163   return m_opaque_ap.get();
164 }
165 
166 lldb_private::LineEntry &SBLineEntry::ref() {
167   if (m_opaque_ap.get() == NULL)
168     m_opaque_ap.reset(new lldb_private::LineEntry());
169   return *m_opaque_ap;
170 }
171 
172 const lldb_private::LineEntry &SBLineEntry::ref() const { return *m_opaque_ap; }
173 
174 bool SBLineEntry::GetDescription(SBStream &description) {
175   Stream &strm = description.ref();
176 
177   if (m_opaque_ap.get()) {
178     char file_path[PATH_MAX * 2];
179     m_opaque_ap->file.GetPath(file_path, sizeof(file_path));
180     strm.Printf("%s:%u", file_path, GetLine());
181     if (GetColumn() > 0)
182       strm.Printf(":%u", GetColumn());
183   } else
184     strm.PutCString("No value");
185 
186   return true;
187 }
188 
189 lldb_private::LineEntry *SBLineEntry::get() { return m_opaque_ap.get(); }
190