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/Utility/ReproducerInstrumentation.h"
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/API/SBTarget.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_RECORD_CONSTRUCTOR(SBSourceManager, (const lldb::SBDebugger &),
75                           debugger);
76 
77   m_opaque_up = std::make_unique<SourceManagerImpl>(debugger.get_sp());
78 }
79 
80 SBSourceManager::SBSourceManager(const SBTarget &target) {
81   LLDB_RECORD_CONSTRUCTOR(SBSourceManager, (const lldb::SBTarget &), target);
82 
83   m_opaque_up = std::make_unique<SourceManagerImpl>(target.GetSP());
84 }
85 
86 SBSourceManager::SBSourceManager(const SBSourceManager &rhs) {
87   LLDB_RECORD_CONSTRUCTOR(SBSourceManager, (const lldb::SBSourceManager &),
88                           rhs);
89 
90   if (&rhs == this)
91     return;
92 
93   m_opaque_up = std::make_unique<SourceManagerImpl>(*(rhs.m_opaque_up.get()));
94 }
95 
96 const lldb::SBSourceManager &SBSourceManager::
97 operator=(const lldb::SBSourceManager &rhs) {
98   LLDB_RECORD_METHOD(const lldb::SBSourceManager &,
99                      SBSourceManager, operator=,(const lldb::SBSourceManager &),
100                      rhs);
101 
102   m_opaque_up = std::make_unique<SourceManagerImpl>(*(rhs.m_opaque_up.get()));
103   return *this;
104 }
105 
106 SBSourceManager::~SBSourceManager() = default;
107 
108 size_t SBSourceManager::DisplaySourceLinesWithLineNumbers(
109     const SBFileSpec &file, uint32_t line, uint32_t context_before,
110     uint32_t context_after, const char *current_line_cstr, SBStream &s) {
111   LLDB_RECORD_METHOD(size_t, SBSourceManager, DisplaySourceLinesWithLineNumbers,
112                      (const lldb::SBFileSpec &, uint32_t, uint32_t, uint32_t,
113                       const char *, lldb::SBStream &),
114                      file, line, context_before, context_after,
115                      current_line_cstr, s);
116 
117   const uint32_t column = 0;
118   return DisplaySourceLinesWithLineNumbersAndColumn(
119       file.ref(), line, column, context_before, context_after,
120       current_line_cstr, s);
121 }
122 
123 size_t SBSourceManager::DisplaySourceLinesWithLineNumbersAndColumn(
124     const SBFileSpec &file, uint32_t line, uint32_t column,
125     uint32_t context_before, uint32_t context_after,
126     const char *current_line_cstr, SBStream &s) {
127   LLDB_RECORD_METHOD(
128       size_t, SBSourceManager, DisplaySourceLinesWithLineNumbersAndColumn,
129       (const lldb::SBFileSpec &, uint32_t, uint32_t, uint32_t, uint32_t,
130        const char *, lldb::SBStream &),
131       file, line, column, context_before, context_after, current_line_cstr, s);
132 
133   if (m_opaque_up == nullptr)
134     return 0;
135 
136   return m_opaque_up->DisplaySourceLinesWithLineNumbers(
137       file.ref(), line, column, context_before, context_after,
138       current_line_cstr, s.get());
139 }
140