| /* Source locations within string literals. |
| Copyright (C) 2016-2019 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_SUBSTRING_LOCATIONS_H |
| #define GCC_SUBSTRING_LOCATIONS_H |
| |
| /* The substring_loc class encapsulates information on the source location |
| of a range of characters within a STRING_CST. |
| |
| If needed by a diagnostic, the actual location_t of the substring_loc |
| can be calculated by calling its get_location method. This calls a |
| langhook, since this is inherently frontend-specific. For the C family |
| of frontends, it calls back into libcpp to reparse the strings. This |
| gets the location information "on demand", rather than storing the |
| location information in the initial lex for every string. Thus the |
| substring_loc can also be thought of as a deferred call into libcpp, |
| to allow the non-trivial work of reparsing the string to be delayed |
| until we actually need it (to emit a diagnostic for a particular range |
| of characters). |
| |
| substring_loc::get_location returns NULL if it succeeds, or an |
| error message if it fails. Error messages are intended for GCC |
| developers (to help debugging) rather than for end-users. |
| |
| The easiest way to use a substring_loc is via the format_warning_* APIs, |
| which gracefully handle failure of substring_loc::get_location by using |
| the location of the string as a whole if substring-information is |
| unavailable. */ |
| |
| class substring_loc |
| { |
| public: |
| /* Constructor. FMT_STRING_LOC is the location of the string as |
| a whole. STRING_TYPE is the type of the string. It should be an |
| ARRAY_TYPE of INTEGER_TYPE, or a POINTER_TYPE to such an ARRAY_TYPE. |
| CARET_IDX, START_IDX, and END_IDX are offsets from the start |
| of the string data. */ |
| substring_loc (location_t fmt_string_loc, tree string_type, |
| int caret_idx, int start_idx, int end_idx) |
| : m_fmt_string_loc (fmt_string_loc), m_string_type (string_type), |
| m_caret_idx (caret_idx), m_start_idx (start_idx), m_end_idx (end_idx) {} |
| |
| void set_caret_index (int caret_idx) { m_caret_idx = caret_idx; } |
| |
| const char *get_location (location_t *out_loc) const; |
| |
| location_t get_fmt_string_loc () const { return m_fmt_string_loc; } |
| tree get_string_type () const { return m_string_type; } |
| int get_caret_idx () const { return m_caret_idx; } |
| int get_start_idx () const { return m_start_idx; } |
| int get_end_idx () const { return m_end_idx; } |
| |
| private: |
| location_t m_fmt_string_loc; |
| tree m_string_type; |
| int m_caret_idx; |
| int m_start_idx; |
| int m_end_idx; |
| }; |
| |
| /* A bundle of state for emitting a diagnostic relating to a format string. */ |
| |
| class format_string_diagnostic_t |
| { |
| public: |
| format_string_diagnostic_t (const substring_loc &fmt_loc, |
| const range_label *fmt_label, |
| location_t param_loc, |
| const range_label *param_label, |
| const char *corrected_substring); |
| |
| /* Functions for emitting a warning about a format string. */ |
| |
| bool emit_warning_va (int opt, const char *gmsgid, va_list *ap) const |
| ATTRIBUTE_GCC_DIAG (3, 0); |
| |
| bool emit_warning_n_va (int opt, unsigned HOST_WIDE_INT n, |
| const char *singular_gmsgid, |
| const char *plural_gmsgid, va_list *ap) const |
| ATTRIBUTE_GCC_DIAG (4, 0) ATTRIBUTE_GCC_DIAG (5, 0); |
| |
| bool emit_warning (int opt, const char *gmsgid, ...) const |
| ATTRIBUTE_GCC_DIAG (3, 4); |
| |
| bool emit_warning_n (int opt, unsigned HOST_WIDE_INT n, |
| const char *singular_gmsgid, |
| const char *plural_gmsgid, ...) const |
| ATTRIBUTE_GCC_DIAG (4, 6) ATTRIBUTE_GCC_DIAG (5, 6); |
| |
| private: |
| const substring_loc &m_fmt_loc; |
| const range_label *m_fmt_label; |
| location_t m_param_loc; |
| const range_label *m_param_label; |
| const char *m_corrected_substring; |
| }; |
| |
| |
| /* Implementation detail, for use when implementing |
| LANG_HOOKS_GET_SUBSTRING_LOCATION. */ |
| |
| extern const char *get_location_within_string (cpp_reader *pfile, |
| string_concat_db *concats, |
| location_t strloc, |
| enum cpp_ttype type, |
| int caret_idx, |
| int start_idx, int end_idx, |
| location_t *out_loc); |
| |
| #endif /* ! GCC_SUBSTRING_LOCATIONS_H */ |