1 //===-- SBSymbolContext.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/SBSymbolContext.h"
10 #include "SBReproducerPrivate.h"
11 #include "Utils.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Symbol/Function.h"
15 #include "lldb/Symbol/Symbol.h"
16 #include "lldb/Symbol/SymbolContext.h"
17 #include "lldb/Utility/Log.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 SBSymbolContext::SBSymbolContext() : m_opaque_up() {
23   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBSymbolContext);
24 }
25 
26 SBSymbolContext::SBSymbolContext(const SymbolContext *sc_ptr) : m_opaque_up() {
27   LLDB_RECORD_CONSTRUCTOR(SBSymbolContext,
28                           (const lldb_private::SymbolContext *), sc_ptr);
29 
30   if (sc_ptr)
31     m_opaque_up = llvm::make_unique<SymbolContext>(*sc_ptr);
32 }
33 
34 SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_up() {
35   LLDB_RECORD_CONSTRUCTOR(SBSymbolContext, (const lldb::SBSymbolContext &),
36                           rhs);
37 
38   m_opaque_up = clone(rhs.m_opaque_up);
39 }
40 
41 SBSymbolContext::~SBSymbolContext() {}
42 
43 const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) {
44   LLDB_RECORD_METHOD(const lldb::SBSymbolContext &,
45                      SBSymbolContext, operator=,(const lldb::SBSymbolContext &),
46                      rhs);
47 
48   if (this != &rhs)
49     m_opaque_up = clone(rhs.m_opaque_up);
50   return *this;
51 }
52 
53 void SBSymbolContext::SetSymbolContext(const SymbolContext *sc_ptr) {
54   if (sc_ptr)
55     m_opaque_up = llvm::make_unique<SymbolContext>(*sc_ptr);
56   else
57     m_opaque_up->Clear(true);
58 }
59 
60 bool SBSymbolContext::IsValid() const {
61   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBSymbolContext, IsValid);
62 
63   return m_opaque_up != NULL;
64 }
65 
66 SBModule SBSymbolContext::GetModule() {
67   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBModule, SBSymbolContext, GetModule);
68 
69   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
70 
71   SBModule sb_module;
72   ModuleSP module_sp;
73   if (m_opaque_up) {
74     module_sp = m_opaque_up->module_sp;
75     sb_module.SetSP(module_sp);
76   }
77 
78   if (log) {
79     SBStream sstr;
80     sb_module.GetDescription(sstr);
81     log->Printf("SBSymbolContext(%p)::GetModule () => SBModule(%p): %s",
82                 static_cast<void *>(m_opaque_up.get()),
83                 static_cast<void *>(module_sp.get()), sstr.GetData());
84   }
85 
86   return LLDB_RECORD_RESULT(sb_module);
87 }
88 
89 SBCompileUnit SBSymbolContext::GetCompileUnit() {
90   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCompileUnit, SBSymbolContext,
91                              GetCompileUnit);
92 
93   return LLDB_RECORD_RESULT(
94       SBCompileUnit(m_opaque_up ? m_opaque_up->comp_unit : NULL));
95 }
96 
97 SBFunction SBSymbolContext::GetFunction() {
98   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFunction, SBSymbolContext, GetFunction);
99 
100   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
101 
102   Function *function = NULL;
103 
104   if (m_opaque_up)
105     function = m_opaque_up->function;
106 
107   SBFunction sb_function(function);
108 
109   if (log)
110     log->Printf("SBSymbolContext(%p)::GetFunction () => SBFunction(%p)",
111                 static_cast<void *>(m_opaque_up.get()),
112                 static_cast<void *>(function));
113 
114   return LLDB_RECORD_RESULT(sb_function);
115 }
116 
117 SBBlock SBSymbolContext::GetBlock() {
118   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock, SBSymbolContext, GetBlock);
119 
120   return LLDB_RECORD_RESULT(SBBlock(m_opaque_up ? m_opaque_up->block : NULL));
121 }
122 
123 SBLineEntry SBSymbolContext::GetLineEntry() {
124   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBLineEntry, SBSymbolContext, GetLineEntry);
125 
126   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
127 
128   SBLineEntry sb_line_entry;
129   if (m_opaque_up)
130     sb_line_entry.SetLineEntry(m_opaque_up->line_entry);
131 
132   if (log) {
133     log->Printf("SBSymbolContext(%p)::GetLineEntry () => SBLineEntry(%p)",
134                 static_cast<void *>(m_opaque_up.get()),
135                 static_cast<void *>(sb_line_entry.get()));
136   }
137 
138   return LLDB_RECORD_RESULT(sb_line_entry);
139 }
140 
141 SBSymbol SBSymbolContext::GetSymbol() {
142   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSymbol, SBSymbolContext, GetSymbol);
143 
144   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
145 
146   Symbol *symbol = NULL;
147 
148   if (m_opaque_up)
149     symbol = m_opaque_up->symbol;
150 
151   SBSymbol sb_symbol(symbol);
152 
153   if (log)
154     log->Printf("SBSymbolContext(%p)::GetSymbol () => SBSymbol(%p)",
155                 static_cast<void *>(m_opaque_up.get()),
156                 static_cast<void *>(symbol));
157 
158   return LLDB_RECORD_RESULT(sb_symbol);
159 }
160 
161 void SBSymbolContext::SetModule(lldb::SBModule module) {
162   LLDB_RECORD_METHOD(void, SBSymbolContext, SetModule, (lldb::SBModule),
163                      module);
164 
165   ref().module_sp = module.GetSP();
166 }
167 
168 void SBSymbolContext::SetCompileUnit(lldb::SBCompileUnit compile_unit) {
169   LLDB_RECORD_METHOD(void, SBSymbolContext, SetCompileUnit,
170                      (lldb::SBCompileUnit), compile_unit);
171 
172   ref().comp_unit = compile_unit.get();
173 }
174 
175 void SBSymbolContext::SetFunction(lldb::SBFunction function) {
176   LLDB_RECORD_METHOD(void, SBSymbolContext, SetFunction, (lldb::SBFunction),
177                      function);
178 
179   ref().function = function.get();
180 }
181 
182 void SBSymbolContext::SetBlock(lldb::SBBlock block) {
183   LLDB_RECORD_METHOD(void, SBSymbolContext, SetBlock, (lldb::SBBlock), block);
184 
185   ref().block = block.GetPtr();
186 }
187 
188 void SBSymbolContext::SetLineEntry(lldb::SBLineEntry line_entry) {
189   LLDB_RECORD_METHOD(void, SBSymbolContext, SetLineEntry, (lldb::SBLineEntry),
190                      line_entry);
191 
192   if (line_entry.IsValid())
193     ref().line_entry = line_entry.ref();
194   else
195     ref().line_entry.Clear();
196 }
197 
198 void SBSymbolContext::SetSymbol(lldb::SBSymbol symbol) {
199   LLDB_RECORD_METHOD(void, SBSymbolContext, SetSymbol, (lldb::SBSymbol),
200                      symbol);
201 
202   ref().symbol = symbol.get();
203 }
204 
205 lldb_private::SymbolContext *SBSymbolContext::operator->() const {
206   return m_opaque_up.get();
207 }
208 
209 const lldb_private::SymbolContext &SBSymbolContext::operator*() const {
210   assert(m_opaque_up.get());
211   return *m_opaque_up;
212 }
213 
214 lldb_private::SymbolContext &SBSymbolContext::operator*() {
215   if (m_opaque_up == NULL)
216     m_opaque_up.reset(new SymbolContext);
217   return *m_opaque_up;
218 }
219 
220 lldb_private::SymbolContext &SBSymbolContext::ref() {
221   if (m_opaque_up == NULL)
222     m_opaque_up.reset(new SymbolContext);
223   return *m_opaque_up;
224 }
225 
226 lldb_private::SymbolContext *SBSymbolContext::get() const {
227   return m_opaque_up.get();
228 }
229 
230 bool SBSymbolContext::GetDescription(SBStream &description) {
231   LLDB_RECORD_METHOD(bool, SBSymbolContext, GetDescription, (lldb::SBStream &),
232                      description);
233 
234   Stream &strm = description.ref();
235 
236   if (m_opaque_up) {
237     m_opaque_up->GetDescription(&strm, lldb::eDescriptionLevelFull, NULL);
238   } else
239     strm.PutCString("No value");
240 
241   return true;
242 }
243 
244 SBSymbolContext
245 SBSymbolContext::GetParentOfInlinedScope(const SBAddress &curr_frame_pc,
246                                          SBAddress &parent_frame_addr) const {
247   LLDB_RECORD_METHOD_CONST(lldb::SBSymbolContext, SBSymbolContext,
248                            GetParentOfInlinedScope,
249                            (const lldb::SBAddress &, lldb::SBAddress &),
250                            curr_frame_pc, parent_frame_addr);
251 
252   SBSymbolContext sb_sc;
253   if (m_opaque_up.get() && curr_frame_pc.IsValid()) {
254     if (m_opaque_up->GetParentOfInlinedScope(curr_frame_pc.ref(), sb_sc.ref(),
255                                              parent_frame_addr.ref()))
256       return LLDB_RECORD_RESULT(sb_sc);
257   }
258   return LLDB_RECORD_RESULT(SBSymbolContext());
259 }
260