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
18using namespace lldb;
19using namespace lldb_private;
20
21SBSymbolContext::SBSymbolContext() { LLDB_INSTRUMENT_VA(this); }
22
23SBSymbolContext::SBSymbolContext(const SymbolContext &sc)
24    : m_opaque_up(std::make_unique<SymbolContext>(sc)) {
25  LLDB_INSTRUMENT_VA(this, sc);
26}
27
28SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) {
29  LLDB_INSTRUMENT_VA(this, rhs);
30
31  m_opaque_up = clone(rhs.m_opaque_up);
32}
33
34SBSymbolContext::~SBSymbolContext() = default;
35
36const 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
44bool SBSymbolContext::IsValid() const {
45  LLDB_INSTRUMENT_VA(this);
46  return this->operator bool();
47}
48SBSymbolContext::operator bool() const {
49  LLDB_INSTRUMENT_VA(this);
50
51  return m_opaque_up != nullptr;
52}
53
54SBModule 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
67SBCompileUnit SBSymbolContext::GetCompileUnit() {
68  LLDB_INSTRUMENT_VA(this);
69
70  return SBCompileUnit(m_opaque_up ? m_opaque_up->comp_unit : nullptr);
71}
72
73SBFunction 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
86SBBlock SBSymbolContext::GetBlock() {
87  LLDB_INSTRUMENT_VA(this);
88
89  return SBBlock(m_opaque_up ? m_opaque_up->block : nullptr);
90}
91
92SBLineEntry 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
102SBSymbol 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
115void SBSymbolContext::SetModule(lldb::SBModule module) {
116  LLDB_INSTRUMENT_VA(this, module);
117
118  ref().module_sp = module.GetSP();
119}
120
121void SBSymbolContext::SetCompileUnit(lldb::SBCompileUnit compile_unit) {
122  LLDB_INSTRUMENT_VA(this, compile_unit);
123
124  ref().comp_unit = compile_unit.get();
125}
126
127void SBSymbolContext::SetFunction(lldb::SBFunction function) {
128  LLDB_INSTRUMENT_VA(this, function);
129
130  ref().function = function.get();
131}
132
133void SBSymbolContext::SetBlock(lldb::SBBlock block) {
134  LLDB_INSTRUMENT_VA(this, block);
135
136  ref().block = block.GetPtr();
137}
138
139void 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
148void SBSymbolContext::SetSymbol(lldb::SBSymbol symbol) {
149  LLDB_INSTRUMENT_VA(this, symbol);
150
151  ref().symbol = symbol.get();
152}
153
154lldb_private::SymbolContext *SBSymbolContext::operator->() const {
155  return m_opaque_up.get();
156}
157
158const lldb_private::SymbolContext &SBSymbolContext::operator*() const {
159  assert(m_opaque_up.get());
160  return *m_opaque_up;
161}
162
163lldb_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
169lldb_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
175lldb_private::SymbolContext *SBSymbolContext::get() const {
176  return m_opaque_up.get();
177}
178
179bool 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
192SBSymbolContext
193SBSymbolContext::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