aboutsummaryrefslogtreecommitdiff
path: root/gcc/diagnostics/file-cache.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/diagnostics/file-cache.h')
-rw-r--r--gcc/diagnostics/file-cache.h125
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