1 //===-- SBSourceManager.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/SBSourceManager.h"
10 #include "lldb/API/SBDebugger.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/API/SBTarget.h"
13 #include "lldb/Utility/Instrumentation.h"
14 
15 #include "lldb/API/SBFileSpec.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/SourceManager.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Utility/Stream.h"
20 
21 #include "lldb/Target/Target.h"
22 
23 namespace lldb_private {
24 class SourceManagerImpl {
25 public:
26   SourceManagerImpl(const lldb::DebuggerSP &debugger_sp)
27       : m_debugger_wp(debugger_sp) {}
28 
29   SourceManagerImpl(const lldb::TargetSP &target_sp) : m_target_wp(target_sp) {}
30 
31   SourceManagerImpl(const SourceManagerImpl &rhs) {
32     if (&rhs == this)
33       return;
34     m_debugger_wp = rhs.m_debugger_wp;
35     m_target_wp = rhs.m_target_wp;
36   }
37 
38   size_t DisplaySourceLinesWithLineNumbers(const lldb_private::FileSpec &file,
39                                            uint32_t line, uint32_t column,
40                                            uint32_t context_before,
41                                            uint32_t context_after,
42                                            const char *current_line_cstr,
43                                            lldb_private::Stream *s) {
44     if (!file)
45       return 0;
46 
47     lldb::TargetSP target_sp(m_target_wp.lock());
48     if (target_sp) {
49       return target_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers(
50           file, line, column, context_before, context_after, current_line_cstr,
51           s);
52     } else {
53       lldb::DebuggerSP debugger_sp(m_debugger_wp.lock());
54       if (debugger_sp) {
55         return debugger_sp->GetSourceManager()
56             .DisplaySourceLinesWithLineNumbers(file, line, column,
57                                                context_before, context_after,
58                                                current_line_cstr, s);
59       }
60     }
61     return 0;
62   }
63 
64 private:
65   lldb::DebuggerWP m_debugger_wp;
66   lldb::TargetWP m_target_wp;
67 };
68 }
69 
70 using namespace lldb;
71 using namespace lldb_private;
72 
73 SBSourceManager::SBSourceManager(const SBDebugger &debugger) {
74   LLDB_INSTRUMENT_VA(this, debugger);
75 
76   m_opaque_up = std::make_unique<SourceManagerImpl>(debugger.get_sp());
77 }
78 
79 SBSourceManager::SBSourceManager(const SBTarget &target) {
80   LLDB_INSTRUMENT_VA(this, target);
81 
82   m_opaque_up = std::make_unique<SourceManagerImpl>(target.GetSP());
83 }
84 
85 SBSourceManager::SBSourceManager(const SBSourceManager &rhs) {
86   LLDB_INSTRUMENT_VA(this, rhs);
87 
88   if (&rhs == this)
89     return;
90 
91   m_opaque_up = std::make_unique<SourceManagerImpl>(*(rhs.m_opaque_up.get()));
92 }
93 
94 const lldb::SBSourceManager &SBSourceManager::
95 operator=(const lldb::SBSourceManager &rhs) {
96   LLDB_INSTRUMENT_VA(this, rhs);
97 
98   m_opaque_up = std::make_unique<SourceManagerImpl>(*(rhs.m_opaque_up.get()));
99   return *this;
100 }
101 
102 SBSourceManager::~SBSourceManager() = default;
103 
104 size_t SBSourceManager::DisplaySourceLinesWithLineNumbers(
105     const SBFileSpec &file, uint32_t line, uint32_t context_before,
106     uint32_t context_after, const char *current_line_cstr, SBStream &s) {
107   LLDB_INSTRUMENT_VA(this, file, line, context_before, context_after,
108                      current_line_cstr, s);
109 
110   const uint32_t column = 0;
111   return DisplaySourceLinesWithLineNumbersAndColumn(
112       file.ref(), line, column, context_before, context_after,
113       current_line_cstr, s);
114 }
115 
116 size_t SBSourceManager::DisplaySourceLinesWithLineNumbersAndColumn(
117     const SBFileSpec &file, uint32_t line, uint32_t column,
118     uint32_t context_before, uint32_t context_after,
119     const char *current_line_cstr, SBStream &s) {
120   LLDB_INSTRUMENT_VA(this, file, line, column, context_before, context_after,
121                      current_line_cstr, s);
122 
123   if (m_opaque_up == nullptr)
124     return 0;
125 
126   return m_opaque_up->DisplaySourceLinesWithLineNumbers(
127       file.ref(), line, column, context_before, context_after,
128       current_line_cstr, s.get());
129 }
130