1 //===-- SBSymbolContext.cpp -----------------------------------------------===//
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 "Utils.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Symbol/Function.h"
14 #include "lldb/Symbol/Symbol.h"
15 #include "lldb/Symbol/SymbolContext.h"
16 #include "lldb/Utility/Instrumentation.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 SBSymbolContext::SBSymbolContext() { LLDB_INSTRUMENT_VA(this); }
22 
23 SBSymbolContext::SBSymbolContext(const SymbolContext &sc)
24     : m_opaque_up(std::make_unique<SymbolContext>(sc)) {
25   LLDB_INSTRUMENT_VA(this, sc);
26 }
27 
28 SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) {
29   LLDB_INSTRUMENT_VA(this, rhs);
30 
31   m_opaque_up = clone(rhs.m_opaque_up);
32 }
33 
34 SBSymbolContext::~SBSymbolContext() = default;
35 
36 const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) {
37   LLDB_INSTRUMENT_VA(this, rhs);
38 
39   if (this != &rhs)
40     m_opaque_up = clone(rhs.m_opaque_up);
41   return *this;
42 }
43 
44 bool SBSymbolContext::IsValid() const {
45   LLDB_INSTRUMENT_VA(this);
46   return this->operator bool();
47 }
48 SBSymbolContext::operator bool() const {
49   LLDB_INSTRUMENT_VA(this);
50 
51   return m_opaque_up != nullptr;
52 }
53 
54 SBModule SBSymbolContext::GetModule() {
55   LLDB_INSTRUMENT_VA(this);
56 
57   SBModule sb_module;
58   ModuleSP module_sp;
59   if (m_opaque_up) {
60     module_sp = m_opaque_up->module_sp;
61     sb_module.SetSP(module_sp);
62   }
63 
64   return sb_module;
65 }
66 
67 SBCompileUnit SBSymbolContext::GetCompileUnit() {
68   LLDB_INSTRUMENT_VA(this);
69 
70   return SBCompileUnit(m_opaque_up ? m_opaque_up->comp_unit : nullptr);
71 }
72 
73 SBFunction SBSymbolContext::GetFunction() {
74   LLDB_INSTRUMENT_VA(this);
75 
76   Function *function = nullptr;
77 
78   if (m_opaque_up)
79     function = m_opaque_up->function;
80 
81   SBFunction sb_function(function);
82 
83   return sb_function;
84 }
85 
86 SBBlock SBSymbolContext::GetBlock() {
87   LLDB_INSTRUMENT_VA(this);
88 
89   return SBBlock(m_opaque_up ? m_opaque_up->block : nullptr);
90 }
91 
92 SBLineEntry SBSymbolContext::GetLineEntry() {
93   LLDB_INSTRUMENT_VA(this);
94 
95   SBLineEntry sb_line_entry;
96   if (m_opaque_up)
97     sb_line_entry.SetLineEntry(m_opaque_up->line_entry);
98 
99   return sb_line_entry;
100 }
101 
102 SBSymbol SBSymbolContext::GetSymbol() {
103   LLDB_INSTRUMENT_VA(this);
104 
105   Symbol *symbol = nullptr;
106 
107   if (m_opaque_up)
108     symbol = m_opaque_up->symbol;
109 
110   SBSymbol sb_symbol(symbol);
111 
112   return sb_symbol;
113 }
114 
115 void SBSymbolContext::SetModule(lldb::SBModule module) {
116   LLDB_INSTRUMENT_VA(this, module);
117 
118   ref().module_sp = module.GetSP();
119 }
120 
121 void SBSymbolContext::SetCompileUnit(lldb::SBCompileUnit compile_unit) {
122   LLDB_INSTRUMENT_VA(this, compile_unit);
123 
124   ref().comp_unit = compile_unit.get();
125 }
126 
127 void SBSymbolContext::SetFunction(lldb::SBFunction function) {
128   LLDB_INSTRUMENT_VA(this, function);
129 
130   ref().function = function.get();
131 }
132 
133 void SBSymbolContext::SetBlock(lldb::SBBlock block) {
134   LLDB_INSTRUMENT_VA(this, block);
135 
136   ref().block = block.GetPtr();
137 }
138 
139 void SBSymbolContext::SetLineEntry(lldb::SBLineEntry line_entry) {
140   LLDB_INSTRUMENT_VA(this, line_entry);
141 
142   if (line_entry.IsValid())
143     ref().line_entry = line_entry.ref();
144   else
145     ref().line_entry.Clear();
146 }
147 
148 void SBSymbolContext::SetSymbol(lldb::SBSymbol symbol) {
149   LLDB_INSTRUMENT_VA(this, symbol);
150 
151   ref().symbol = symbol.get();
152 }
153 
154 lldb_private::SymbolContext *SBSymbolContext::operator->() const {
155   return m_opaque_up.get();
156 }
157 
158 const lldb_private::SymbolContext &SBSymbolContext::operator*() const {
159   assert(m_opaque_up.get());
160   return *m_opaque_up;
161 }
162 
163 lldb_private::SymbolContext &SBSymbolContext::operator*() {
164   if (m_opaque_up == nullptr)
165     m_opaque_up = std::make_unique<SymbolContext>();
166   return *m_opaque_up;
167 }
168 
169 lldb_private::SymbolContext &SBSymbolContext::ref() {
170   if (m_opaque_up == nullptr)
171     m_opaque_up = std::make_unique<SymbolContext>();
172   return *m_opaque_up;
173 }
174 
175 lldb_private::SymbolContext *SBSymbolContext::get() const {
176   return m_opaque_up.get();
177 }
178 
179 bool SBSymbolContext::GetDescription(SBStream &description) {
180   LLDB_INSTRUMENT_VA(this, description);
181 
182   Stream &strm = description.ref();
183 
184   if (m_opaque_up) {
185     m_opaque_up->GetDescription(&strm, lldb::eDescriptionLevelFull, nullptr);
186   } else
187     strm.PutCString("No value");
188 
189   return true;
190 }
191 
192 SBSymbolContext
193 SBSymbolContext::GetParentOfInlinedScope(const SBAddress &curr_frame_pc,
194                                          SBAddress &parent_frame_addr) const {
195   LLDB_INSTRUMENT_VA(this, curr_frame_pc, parent_frame_addr);
196 
197   SBSymbolContext sb_sc;
198   if (m_opaque_up.get() && curr_frame_pc.IsValid()) {
199     if (m_opaque_up->GetParentOfInlinedScope(curr_frame_pc.ref(), sb_sc.ref(),
200                                              parent_frame_addr.ref()))
201       return sb_sc;
202   }
203   return SBSymbolContext();
204 }
205