1254721Semaste//===-- SourceManager.h -----------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#ifndef liblldb_SourceManager_h_
10254721Semaste#define liblldb_SourceManager_h_
11254721Semaste
12321369Sdim#include "lldb/Utility/FileSpec.h"
13344779Sdim#include "lldb/lldb-defines.h"
14344779Sdim#include "lldb/lldb-forward.h"
15314564Sdim
16314564Sdim#include "llvm/Support/Chrono.h"
17314564Sdim
18344779Sdim#include <cstdint>
19254721Semaste#include <map>
20296417Sdim#include <memory>
21344779Sdim#include <stddef.h>
22344779Sdim#include <string>
23254721Semaste#include <vector>
24254721Semaste
25254721Semastenamespace lldb_private {
26321369Sdimclass RegularExpression;
27321369Sdimclass Stream;
28321369Sdimclass SymbolContextList;
29321369Sdimclass Target;
30254721Semaste
31314564Sdimclass SourceManager {
32254721Semastepublic:
33314564Sdim  class File {
34314564Sdim    friend bool operator==(const SourceManager::File &lhs,
35314564Sdim                           const SourceManager::File &rhs);
36296417Sdim
37314564Sdim  public:
38314564Sdim    File(const FileSpec &file_spec, Target *target);
39314564Sdim    File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp);
40314564Sdim    ~File() = default;
41254721Semaste
42314564Sdim    void UpdateIfNeeded();
43296417Sdim
44344779Sdim    size_t DisplaySourceLines(uint32_t line, llvm::Optional<size_t> column,
45314564Sdim                              uint32_t context_before, uint32_t context_after,
46314564Sdim                              Stream *s);
47314564Sdim    void FindLinesMatchingRegex(RegularExpression &regex, uint32_t start_line,
48314564Sdim                                uint32_t end_line,
49254721Semaste                                std::vector<uint32_t> &match_lines);
50254721Semaste
51314564Sdim    bool GetLine(uint32_t line_no, std::string &buffer);
52254721Semaste
53314564Sdim    uint32_t GetLineOffset(uint32_t line);
54254721Semaste
55314564Sdim    bool LineIsValid(uint32_t line);
56254721Semaste
57314564Sdim    const FileSpec &GetFileSpec() { return m_file_spec; }
58262528Semaste
59314564Sdim    uint32_t GetSourceMapModificationID() const { return m_source_map_mod_id; }
60254721Semaste
61314564Sdim    const char *PeekLineData(uint32_t line);
62314564Sdim
63314564Sdim    uint32_t GetLineLength(uint32_t line, bool include_newline_chars);
64314564Sdim
65314564Sdim    uint32_t GetNumLines();
66314564Sdim
67314564Sdim  protected:
68314564Sdim    bool CalculateLineOffsets(uint32_t line = UINT32_MAX);
69314564Sdim
70314564Sdim    FileSpec m_file_spec_orig; // The original file spec that was used (can be
71314564Sdim                               // different from m_file_spec)
72314564Sdim    FileSpec m_file_spec; // The actually file spec being used (if the target
73314564Sdim                          // has source mappings, this might be different from
74314564Sdim                          // m_file_spec_orig)
75314564Sdim
76314564Sdim    // Keep the modification time that this file data is valid for
77314564Sdim    llvm::sys::TimePoint<> m_mod_time;
78314564Sdim
79314564Sdim    // If the target uses path remappings, be sure to clear our notion of a
80314564Sdim    // source file if the path modification ID changes
81314564Sdim    uint32_t m_source_map_mod_id = 0;
82314564Sdim    lldb::DataBufferSP m_data_sp;
83314564Sdim    typedef std::vector<uint32_t> LineOffsets;
84314564Sdim    LineOffsets m_offsets;
85314564Sdim    lldb::DebuggerWP m_debugger_wp;
86314564Sdim
87314564Sdim  private:
88314564Sdim    void CommonInitializer(const FileSpec &file_spec, Target *target);
89314564Sdim  };
90254721Semaste
91314564Sdim  typedef std::shared_ptr<File> FileSP;
92254721Semaste
93314564Sdim  // The SourceFileCache class separates the source manager from the cache of
94341825Sdim  // source files, so the cache can be stored in the Debugger, but the source
95341825Sdim  // managers can be per target.
96314564Sdim  class SourceFileCache {
97314564Sdim  public:
98314564Sdim    SourceFileCache() = default;
99314564Sdim    ~SourceFileCache() = default;
100314564Sdim
101314564Sdim    void AddSourceFile(const FileSP &file_sp);
102314564Sdim    FileSP FindSourceFile(const FileSpec &file_spec) const;
103314564Sdim
104314564Sdim  protected:
105314564Sdim    typedef std::map<FileSpec, FileSP> FileCache;
106314564Sdim    FileCache m_file_cache;
107314564Sdim  };
108254721Semaste
109314564Sdim  // Constructors and Destructors
110314564Sdim  // A source manager can be made with a non-null target, in which case it can
111314564Sdim  // use the path remappings to find
112314564Sdim  // source files that are not in their build locations.  With no target it
113314564Sdim  // won't be able to do this.
114314564Sdim  SourceManager(const lldb::DebuggerSP &debugger_sp);
115314564Sdim  SourceManager(const lldb::TargetSP &target_sp);
116254721Semaste
117314564Sdim  ~SourceManager();
118254721Semaste
119314564Sdim  FileSP GetLastFile() { return m_last_file_sp; }
120254721Semaste
121314564Sdim  size_t
122314564Sdim  DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line,
123314564Sdim                                    uint32_t column, uint32_t context_before,
124314564Sdim                                    uint32_t context_after,
125314564Sdim                                    const char *current_line_cstr, Stream *s,
126314564Sdim                                    const SymbolContextList *bp_locs = nullptr);
127254721Semaste
128314564Sdim  // This variant uses the last file we visited.
129314564Sdim  size_t DisplaySourceLinesWithLineNumbersUsingLastFile(
130314564Sdim      uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
131314564Sdim      const char *current_line_cstr, Stream *s,
132314564Sdim      const SymbolContextList *bp_locs = nullptr);
133254721Semaste
134314564Sdim  size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse,
135314564Sdim                                    const SymbolContextList *bp_locs = nullptr);
136254721Semaste
137314564Sdim  bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line);
138254721Semaste
139314564Sdim  bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line);
140254721Semaste
141314564Sdim  bool DefaultFileAndLineSet() { return (m_last_file_sp.get() != nullptr); }
142314564Sdim
143314564Sdim  void FindLinesMatchingRegex(FileSpec &file_spec, RegularExpression &regex,
144314564Sdim                              uint32_t start_line, uint32_t end_line,
145314564Sdim                              std::vector<uint32_t> &match_lines);
146314564Sdim
147314564Sdim  FileSP GetFile(const FileSpec &file_spec);
148314564Sdim
149254721Semasteprotected:
150314564Sdim  FileSP m_last_file_sp;
151314564Sdim  uint32_t m_last_line;
152314564Sdim  uint32_t m_last_count;
153314564Sdim  bool m_default_set;
154314564Sdim  lldb::TargetWP m_target_wp;
155314564Sdim  lldb::DebuggerWP m_debugger_wp;
156314564Sdim
157254721Semasteprivate:
158314564Sdim  DISALLOW_COPY_AND_ASSIGN(SourceManager);
159254721Semaste};
160254721Semaste
161314564Sdimbool operator==(const SourceManager::File &lhs, const SourceManager::File &rhs);
162296417Sdim
163254721Semaste} // namespace lldb_private
164254721Semaste
165296417Sdim#endif // liblldb_SourceManager_h_
166