SourceManager.h revision 341825
1//===-- SourceManager.h -----------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_SourceManager_h_
11#define liblldb_SourceManager_h_
12
13#include "lldb/Utility/FileSpec.h"
14#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
15#include "lldb/lldb-forward.h" // for DebuggerSP, DebuggerWP, DataBufferSP
16
17#include "llvm/Support/Chrono.h"
18
19#include <cstdint> // for uint32_t, UINT32_MAX
20#include <map>
21#include <memory>
22#include <stddef.h> // for size_t
23#include <string>   // for string
24#include <vector>
25
26namespace lldb_private {
27class RegularExpression;
28}
29namespace lldb_private {
30class Stream;
31}
32namespace lldb_private {
33class SymbolContextList;
34}
35namespace lldb_private {
36class Target;
37}
38
39namespace lldb_private {
40
41class SourceManager {
42public:
43#ifndef SWIG
44  class File {
45    friend bool operator==(const SourceManager::File &lhs,
46                           const SourceManager::File &rhs);
47
48  public:
49    File(const FileSpec &file_spec, Target *target);
50    File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp);
51    ~File() = default;
52
53    void UpdateIfNeeded();
54
55    size_t DisplaySourceLines(uint32_t line, uint32_t column,
56                              uint32_t context_before, uint32_t context_after,
57                              Stream *s);
58    void FindLinesMatchingRegex(RegularExpression &regex, uint32_t start_line,
59                                uint32_t end_line,
60                                std::vector<uint32_t> &match_lines);
61
62    bool GetLine(uint32_t line_no, std::string &buffer);
63
64    uint32_t GetLineOffset(uint32_t line);
65
66    bool LineIsValid(uint32_t line);
67
68    bool FileSpecMatches(const FileSpec &file_spec);
69
70    const FileSpec &GetFileSpec() { return m_file_spec; }
71
72    uint32_t GetSourceMapModificationID() const { return m_source_map_mod_id; }
73
74    const char *PeekLineData(uint32_t line);
75
76    uint32_t GetLineLength(uint32_t line, bool include_newline_chars);
77
78    uint32_t GetNumLines();
79
80  protected:
81    bool CalculateLineOffsets(uint32_t line = UINT32_MAX);
82
83    FileSpec m_file_spec_orig; // The original file spec that was used (can be
84                               // different from m_file_spec)
85    FileSpec m_file_spec; // The actually file spec being used (if the target
86                          // has source mappings, this might be different from
87                          // m_file_spec_orig)
88
89    // Keep the modification time that this file data is valid for
90    llvm::sys::TimePoint<> m_mod_time;
91
92    // If the target uses path remappings, be sure to clear our notion of a
93    // source file if the path modification ID changes
94    uint32_t m_source_map_mod_id = 0;
95    lldb::DataBufferSP m_data_sp;
96    typedef std::vector<uint32_t> LineOffsets;
97    LineOffsets m_offsets;
98    lldb::DebuggerWP m_debugger_wp;
99
100  private:
101    void CommonInitializer(const FileSpec &file_spec, Target *target);
102  };
103#endif // SWIG
104
105  typedef std::shared_ptr<File> FileSP;
106
107#ifndef SWIG
108  // The SourceFileCache class separates the source manager from the cache of
109  // source files, so the cache can be stored in the Debugger, but the source
110  // managers can be per target.
111  class SourceFileCache {
112  public:
113    SourceFileCache() = default;
114    ~SourceFileCache() = default;
115
116    void AddSourceFile(const FileSP &file_sp);
117    FileSP FindSourceFile(const FileSpec &file_spec) const;
118
119  protected:
120    typedef std::map<FileSpec, FileSP> FileCache;
121    FileCache m_file_cache;
122  };
123#endif // SWIG
124
125  //------------------------------------------------------------------
126  // Constructors and Destructors
127  //------------------------------------------------------------------
128  // A source manager can be made with a non-null target, in which case it can
129  // use the path remappings to find
130  // source files that are not in their build locations.  With no target it
131  // won't be able to do this.
132  SourceManager(const lldb::DebuggerSP &debugger_sp);
133  SourceManager(const lldb::TargetSP &target_sp);
134
135  ~SourceManager();
136
137  FileSP GetLastFile() { return m_last_file_sp; }
138
139  size_t
140  DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line,
141                                    uint32_t column, uint32_t context_before,
142                                    uint32_t context_after,
143                                    const char *current_line_cstr, Stream *s,
144                                    const SymbolContextList *bp_locs = nullptr);
145
146  // This variant uses the last file we visited.
147  size_t DisplaySourceLinesWithLineNumbersUsingLastFile(
148      uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
149      const char *current_line_cstr, Stream *s,
150      const SymbolContextList *bp_locs = nullptr);
151
152  size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse,
153                                    const SymbolContextList *bp_locs = nullptr);
154
155  bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line);
156
157  bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line);
158
159  bool DefaultFileAndLineSet() { return (m_last_file_sp.get() != nullptr); }
160
161  void FindLinesMatchingRegex(FileSpec &file_spec, RegularExpression &regex,
162                              uint32_t start_line, uint32_t end_line,
163                              std::vector<uint32_t> &match_lines);
164
165  FileSP GetFile(const FileSpec &file_spec);
166
167protected:
168  FileSP m_last_file_sp;
169  uint32_t m_last_line;
170  uint32_t m_last_count;
171  bool m_default_set;
172  lldb::TargetWP m_target_wp;
173  lldb::DebuggerWP m_debugger_wp;
174
175private:
176  DISALLOW_COPY_AND_ASSIGN(SourceManager);
177};
178
179bool operator==(const SourceManager::File &lhs, const SourceManager::File &rhs);
180
181} // namespace lldb_private
182
183#endif // liblldb_SourceManager_h_
184