aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Core/SourceManager.h
blob: 053badf64ddc0caad3ffd1e12ce239836613bd53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//===-- SourceManager.h -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_SourceManager_h_
#define liblldb_SourceManager_h_

#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
#include "lldb/lldb-forward.h" // for DebuggerSP, DebuggerWP, DataBufferSP

#include "llvm/Support/Chrono.h"

#include <cstdint> // for uint32_t, UINT32_MAX
#include <map>
#include <memory>
#include <stddef.h> // for size_t
#include <string>   // for string
#include <vector>

namespace lldb_private {
class RegularExpression;
}
namespace lldb_private {
class Stream;
}
namespace lldb_private {
class SymbolContextList;
}
namespace lldb_private {
class Target;
}

namespace lldb_private {

class SourceManager {
public:
#ifndef SWIG
  class File {
    friend bool operator==(const SourceManager::File &lhs,
                           const SourceManager::File &rhs);

  public:
    File(const FileSpec &file_spec, Target *target);
    File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp);
    ~File() = default;

    void UpdateIfNeeded();

    size_t DisplaySourceLines(uint32_t line, uint32_t column,
                              uint32_t context_before, uint32_t context_after,
                              Stream *s);
    void FindLinesMatchingRegex(RegularExpression &regex, uint32_t start_line,
                                uint32_t end_line,
                                std::vector<uint32_t> &match_lines);

    bool GetLine(uint32_t line_no, std::string &buffer);

    uint32_t GetLineOffset(uint32_t line);

    bool LineIsValid(uint32_t line);

    bool FileSpecMatches(const FileSpec &file_spec);

    const FileSpec &GetFileSpec() { return m_file_spec; }

    uint32_t GetSourceMapModificationID() const { return m_source_map_mod_id; }

    const char *PeekLineData(uint32_t line);

    uint32_t GetLineLength(uint32_t line, bool include_newline_chars);

    uint32_t GetNumLines();

  protected:
    bool CalculateLineOffsets(uint32_t line = UINT32_MAX);

    FileSpec m_file_spec_orig; // The original file spec that was used (can be
                               // different from m_file_spec)
    FileSpec m_file_spec; // The actually file spec being used (if the target
                          // has source mappings, this might be different from
                          // m_file_spec_orig)

    // Keep the modification time that this file data is valid for
    llvm::sys::TimePoint<> m_mod_time;

    // If the target uses path remappings, be sure to clear our notion of a
    // source file if the path modification ID changes
    uint32_t m_source_map_mod_id = 0;
    lldb::DataBufferSP m_data_sp;
    typedef std::vector<uint32_t> LineOffsets;
    LineOffsets m_offsets;
    lldb::DebuggerWP m_debugger_wp;

  private:
    void CommonInitializer(const FileSpec &file_spec, Target *target);
  };
#endif // SWIG

  typedef std::shared_ptr<File> FileSP;

#ifndef SWIG
  // The SourceFileCache class separates the source manager from the cache of
  // source files, so the
  // cache can be stored in the Debugger, but the source managers can be per
  // target.
  class SourceFileCache {
  public:
    SourceFileCache() = default;
    ~SourceFileCache() = default;

    void AddSourceFile(const FileSP &file_sp);
    FileSP FindSourceFile(const FileSpec &file_spec) const;

  protected:
    typedef std::map<FileSpec, FileSP> FileCache;
    FileCache m_file_cache;
  };
#endif // SWIG

  //------------------------------------------------------------------
  // Constructors and Destructors
  //------------------------------------------------------------------
  // A source manager can be made with a non-null target, in which case it can
  // use the path remappings to find
  // source files that are not in their build locations.  With no target it
  // won't be able to do this.
  SourceManager(const lldb::DebuggerSP &debugger_sp);
  SourceManager(const lldb::TargetSP &target_sp);

  ~SourceManager();

  FileSP GetLastFile() { return m_last_file_sp; }

  size_t
  DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line,
                                    uint32_t column, uint32_t context_before,
                                    uint32_t context_after,
                                    const char *current_line_cstr, Stream *s,
                                    const SymbolContextList *bp_locs = nullptr);

  // This variant uses the last file we visited.
  size_t DisplaySourceLinesWithLineNumbersUsingLastFile(
      uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
      const char *current_line_cstr, Stream *s,
      const SymbolContextList *bp_locs = nullptr);

  size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse,
                                    const SymbolContextList *bp_locs = nullptr);

  bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line);

  bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line);

  bool DefaultFileAndLineSet() { return (m_last_file_sp.get() != nullptr); }

  void FindLinesMatchingRegex(FileSpec &file_spec, RegularExpression &regex,
                              uint32_t start_line, uint32_t end_line,
                              std::vector<uint32_t> &match_lines);

  FileSP GetFile(const FileSpec &file_spec);

protected:
  FileSP m_last_file_sp;
  uint32_t m_last_line;
  uint32_t m_last_count;
  bool m_default_set;
  lldb::TargetWP m_target_wp;
  lldb::DebuggerWP m_debugger_wp;

private:
  DISALLOW_COPY_AND_ASSIGN(SourceManager);
};

bool operator==(const SourceManager::File &lhs, const SourceManager::File &rhs);

} // namespace lldb_private

#endif // liblldb_SourceManager_h_