diff options
Diffstat (limited to 'gcc/diagnostics/file-cache.h')
-rw-r--r-- | gcc/diagnostics/file-cache.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/gcc/diagnostics/file-cache.h b/gcc/diagnostics/file-cache.h new file mode 100644 index 0000000..832a960 --- /dev/null +++ b/gcc/diagnostics/file-cache.h @@ -0,0 +1,125 @@ +/* Caching input files for use by diagnostics. + Copyright (C) 2004-2025 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_DIAGNOSTICS_FILE_CACHE_H +#define GCC_DIAGNOSTICS_FILE_CACHE_H + +namespace diagnostics { + +/* A class capturing the bounds of a buffer, to allow for run-time + bounds-checking in a checked build. */ + +class char_span +{ + public: + char_span (const char *ptr, size_t n_elts) : m_ptr (ptr), m_n_elts (n_elts) {} + + /* Test for a non-NULL pointer. */ + operator bool() const { return m_ptr; } + + /* Get length, not including any 0-terminator (which may not be, + in fact, present). */ + size_t length () const { return m_n_elts; } + + const char *get_buffer () const { return m_ptr; } + + char operator[] (int idx) const + { + gcc_assert (idx >= 0); + gcc_assert ((size_t)idx < m_n_elts); + return m_ptr[idx]; + } + + char_span subspan (int offset, int n_elts) const + { + gcc_assert (offset >= 0); + gcc_assert (offset < (int)m_n_elts); + gcc_assert (n_elts >= 0); + gcc_assert (offset + n_elts <= (int)m_n_elts); + return char_span (m_ptr + offset, n_elts); + } + + char *xstrdup () const + { + return ::xstrndup (m_ptr, m_n_elts); + } + + private: + const char *m_ptr; + size_t m_n_elts; +}; + +/* Forward decl of slot within file_cache, so that the definition doesn't + need to be in this header. */ +class file_cache_slot; + +/* A cache of source files for use when emitting diagnostics + (and in a few places in the C/C++ frontends). + + Results are only valid until the next call to the cache, as + slots can be evicted. + + Filenames are stored by pointer, and so must outlive the cache + instance. */ + +class file_cache +{ + public: + file_cache (); + ~file_cache (); + + void dump (FILE *out, int indent) const; + void DEBUG_FUNCTION dump () const; + + file_cache_slot *lookup_or_add_file (const char *file_path); + void forcibly_evict_file (const char *file_path); + + /* See comments in diagnostic.h about the input conversion context. */ + struct input_context + { + diagnostic_input_charset_callback ccb; + bool should_skip_bom; + }; + void initialize_input_context (diagnostic_input_charset_callback ccb, + bool should_skip_bom); + + char_span get_source_file_content (const char *file_path); + char_span get_source_line (const char *file_path, int line); + bool missing_trailing_newline_p (const char *file_path); + + void add_buffered_content (const char *file_path, + const char *buffer, + size_t sz); + + void tune (size_t num_file_slots, size_t lines); + + private: + file_cache_slot *evicted_cache_tab_entry (unsigned *highest_use_count); + file_cache_slot *add_file (const char *file_path); + file_cache_slot *lookup_file (const char *file_path); + + private: + size_t m_num_file_slots; + file_cache_slot *m_file_slots; + input_context m_input_context; +}; + +} // namespace diagnostics + +#endif // #ifndef GCC_DIAGNOSTICS_FILE_CACHE_H |