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 ®ex, 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 ®ex, 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