Branch data Line data Source code
1 : : /* Declarations for variables relating to reading the source file.
2 : : Used by parsers, lexical analyzers, and error message routines.
3 : : Copyright (C) 1993-2025 Free Software Foundation, Inc.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef GCC_INPUT_H
22 : : #define GCC_INPUT_H
23 : :
24 : : #include "line-map.h"
25 : :
26 : : class file_cache;
27 : :
28 : : extern GTY(()) class line_maps *line_table;
29 : : extern GTY(()) class line_maps *saved_line_table;
30 : :
31 : : /* A value which will never be used to represent a real location. */
32 : : #define UNKNOWN_LOCATION ((location_t) 0)
33 : :
34 : : /* The location for declarations in "<built-in>" */
35 : : #define BUILTINS_LOCATION ((location_t) 1)
36 : :
37 : : /* Returns the translated string referring to the special location. */
38 : : const char *special_fname_builtin ();
39 : :
40 : : /* line-map.cc reserves RESERVED_LOCATION_COUNT to the user. Ensure
41 : : both UNKNOWN_LOCATION and BUILTINS_LOCATION fit into that. */
42 : : STATIC_ASSERT (BUILTINS_LOCATION < RESERVED_LOCATION_COUNT);
43 : :
44 : : /* Hasher for 'location_t' values satisfying '!RESERVED_LOCATION_P', thus able
45 : : to use 'UNKNOWN_LOCATION'/'BUILTINS_LOCATION' as spare values for
46 : : 'Empty'/'Deleted'. */
47 : : /* Per PR103157 "'gengtype': 'typedef' causing infinite-recursion code to be
48 : : generated", don't use
49 : : typedef int_hash<location_t, UNKNOWN_LOCATION, BUILTINS_LOCATION>
50 : : location_hash;
51 : : here.
52 : :
53 : : It works for a single-use case, but when using a 'struct'-based variant
54 : : struct location_hash
55 : : : int_hash<location_t, UNKNOWN_LOCATION, BUILTINS_LOCATION> {};
56 : : in more than one place, 'gengtype' generates duplicate functions (thus:
57 : : "error: redefinition of 'void gt_ggc_mx(location_hash&)'" etc.).
58 : : Attempting to mark that one up with GTY options, we run into a 'gengtype'
59 : : "parse error: expected '{', have '<'", which probably falls into category
60 : : "understanding of C++ is limited", as documented in 'gcc/doc/gty.texi'.
61 : :
62 : : Thus, use a plain ol' '#define':
63 : : */
64 : : #define location_hash int_hash<location_t, UNKNOWN_LOCATION, BUILTINS_LOCATION>
65 : :
66 : : extern bool is_location_from_builtin_token (location_t);
67 : : extern expanded_location expand_location (location_t);
68 : :
69 : : class cpp_char_column_policy;
70 : :
71 : : extern int
72 : : location_compute_display_column (file_cache &fc,
73 : : expanded_location exploc,
74 : : const cpp_char_column_policy &policy);
75 : :
76 : : /* A class capturing the bounds of a buffer, to allow for run-time
77 : : bounds-checking in a checked build. */
78 : :
79 : : class char_span
80 : : {
81 : : public:
82 : 1652116 : char_span (const char *ptr, size_t n_elts) : m_ptr (ptr), m_n_elts (n_elts) {}
83 : :
84 : : /* Test for a non-NULL pointer. */
85 : 935800 : operator bool() const { return m_ptr; }
86 : :
87 : : /* Get length, not including any 0-terminator (which may not be,
88 : : in fact, present). */
89 : 910047 : size_t length () const { return m_n_elts; }
90 : :
91 : 716200 : const char *get_buffer () const { return m_ptr; }
92 : :
93 : 3322922 : char operator[] (int idx) const
94 : : {
95 : 3322922 : gcc_assert (idx >= 0);
96 : 3322922 : gcc_assert ((size_t)idx < m_n_elts);
97 : 3322922 : return m_ptr[idx];
98 : : }
99 : :
100 : 38520 : char_span subspan (int offset, int n_elts) const
101 : : {
102 : 38520 : gcc_assert (offset >= 0);
103 : 38520 : gcc_assert (offset < (int)m_n_elts);
104 : 38520 : gcc_assert (n_elts >= 0);
105 : 38520 : gcc_assert (offset + n_elts <= (int)m_n_elts);
106 : 38520 : return char_span (m_ptr + offset, n_elts);
107 : : }
108 : :
109 : 37355 : char *xstrdup () const
110 : : {
111 : 37355 : return ::xstrndup (m_ptr, m_n_elts);
112 : : }
113 : :
114 : : private:
115 : : const char *m_ptr;
116 : : size_t m_n_elts;
117 : : };
118 : :
119 : : extern char *
120 : : get_source_text_between (file_cache &, location_t, location_t);
121 : :
122 : : /* Forward decl of slot within file_cache, so that the definition doesn't
123 : : need to be in this header. */
124 : : class file_cache_slot;
125 : :
126 : : /* A cache of source files for use when emitting diagnostics
127 : : (and in a few places in the C/C++ frontends).
128 : :
129 : : Results are only valid until the next call to the cache, as
130 : : slots can be evicted.
131 : :
132 : : Filenames are stored by pointer, and so must outlive the cache
133 : : instance. */
134 : :
135 : : class file_cache
136 : : {
137 : : public:
138 : : file_cache ();
139 : : ~file_cache ();
140 : :
141 : : void dump (FILE *out, int indent) const;
142 : : void DEBUG_FUNCTION dump () const;
143 : :
144 : : file_cache_slot *lookup_or_add_file (const char *file_path);
145 : : void forcibly_evict_file (const char *file_path);
146 : :
147 : : /* See comments in diagnostic.h about the input conversion context. */
148 : : struct input_context
149 : : {
150 : : diagnostic_input_charset_callback ccb;
151 : : bool should_skip_bom;
152 : : };
153 : : void initialize_input_context (diagnostic_input_charset_callback ccb,
154 : : bool should_skip_bom);
155 : :
156 : : char_span get_source_file_content (const char *file_path);
157 : : char_span get_source_line (const char *file_path, int line);
158 : : bool missing_trailing_newline_p (const char *file_path);
159 : :
160 : : void add_buffered_content (const char *file_path,
161 : : const char *buffer,
162 : : size_t sz);
163 : :
164 : : void tune (size_t num_file_slots, size_t lines);
165 : :
166 : : private:
167 : : file_cache_slot *evicted_cache_tab_entry (unsigned *highest_use_count);
168 : : file_cache_slot *add_file (const char *file_path);
169 : : file_cache_slot *lookup_file (const char *file_path);
170 : :
171 : : private:
172 : : size_t m_num_file_slots;
173 : : file_cache_slot *m_file_slots;
174 : : input_context m_input_context;
175 : : };
176 : :
177 : : extern expanded_location
178 : : expand_location_to_spelling_point (location_t,
179 : : enum location_aspect aspect
180 : : = LOCATION_ASPECT_CARET);
181 : : extern location_t expansion_point_location_if_in_system_header (location_t);
182 : : extern location_t expansion_point_location (location_t);
183 : :
184 : : extern location_t input_location;
185 : :
186 : : extern location_t location_with_discriminator (location_t, int);
187 : : extern bool has_discriminator (location_t);
188 : : extern int get_discriminator_from_loc (location_t);
189 : :
190 : : #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
191 : : #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
192 : : #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
193 : : #define LOCATION_LOCUS(LOC) \
194 : : ((IS_ADHOC_LOC (LOC)) ? get_location_from_adhoc_loc (line_table, LOC) \
195 : : : (LOC))
196 : : #define LOCATION_BLOCK(LOC) \
197 : : ((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (line_table, (LOC)) \
198 : : : NULL))
199 : : #define RESERVED_LOCATION_P(LOC) \
200 : : (LOCATION_LOCUS (LOC) < RESERVED_LOCATION_COUNT)
201 : :
202 : : /* Return a positive value if LOCATION is the locus of a token that is
203 : : located in a system header, O otherwise. It returns 1 if LOCATION
204 : : is the locus of a token that is located in a system header, and 2
205 : : if LOCATION is the locus of a token located in a C system header
206 : : that therefore needs to be extern "C" protected in C++.
207 : :
208 : : Note that this function returns 1 if LOCATION belongs to a token
209 : : that is part of a macro replacement-list defined in a system
210 : : header, but expanded in a non-system file. */
211 : :
212 : : inline int
213 : 1106057589 : in_system_header_at (location_t loc)
214 : : {
215 : 1106057589 : return linemap_location_in_system_header_p (line_table, loc);
216 : : }
217 : :
218 : : /* Return true if LOCATION is the locus of a token that
219 : : comes from a macro expansion, false otherwise. */
220 : :
221 : : inline bool
222 : 3777944 : from_macro_expansion_at (location_t loc)
223 : : {
224 : 3777944 : return linemap_location_from_macro_expansion_p (line_table, loc);
225 : : }
226 : :
227 : : /* Return true if LOCATION is the locus of a token that comes from
228 : : a macro definition, false otherwise. This differs from from_macro_expansion_at
229 : : in its treatment of macro arguments, for which this returns false. */
230 : :
231 : : inline bool
232 : 1456 : from_macro_definition_at (location_t loc)
233 : : {
234 : 1456 : return linemap_location_from_macro_definition_p (line_table, loc);
235 : : }
236 : :
237 : : inline location_t
238 : 2770669457 : get_pure_location (location_t loc)
239 : : {
240 : 2770669457 : return get_pure_location (line_table, loc);
241 : : }
242 : :
243 : : /* Get the start of any range encoded within location LOC. */
244 : :
245 : : inline location_t
246 : 598255693 : get_start (location_t loc)
247 : : {
248 : 598255693 : return get_range_from_loc (line_table, loc).m_start;
249 : : }
250 : :
251 : : /* Get the endpoint of any range encoded within location LOC. */
252 : :
253 : : inline location_t
254 : 664786876 : get_finish (location_t loc)
255 : : {
256 : 664786876 : return get_range_from_loc (line_table, loc).m_finish;
257 : : }
258 : :
259 : : extern location_t make_location (location_t caret,
260 : : location_t start, location_t finish);
261 : : extern location_t make_location (location_t caret, source_range src_range);
262 : :
263 : : void dump_line_table_statistics (void);
264 : :
265 : : void dump_location_info (FILE *stream);
266 : :
267 : : class GTY(()) string_concat
268 : : {
269 : : public:
270 : : string_concat (int num, location_t *locs);
271 : :
272 : : int m_num;
273 : : location_t * GTY ((atomic)) m_locs;
274 : : };
275 : :
276 : : class GTY(()) string_concat_db
277 : : {
278 : : public:
279 : : string_concat_db ();
280 : : void record_string_concatenation (int num, location_t *locs);
281 : :
282 : : bool get_string_concatenation (location_t loc,
283 : : int *out_num,
284 : : location_t **out_locs);
285 : :
286 : : private:
287 : : static location_t get_key_loc (location_t loc);
288 : :
289 : : /* For the fields to be private, we must grant access to the
290 : : generated code in gtype-desc.cc. */
291 : :
292 : : friend void ::gt_ggc_mx_string_concat_db (void *x_p);
293 : : friend void ::gt_pch_nx_string_concat_db (void *x_p);
294 : : friend void ::gt_pch_p_16string_concat_db (void *this_obj, void *x_p,
295 : : gt_pointer_operator op,
296 : : void *cookie);
297 : :
298 : : hash_map <location_hash, string_concat *> *m_table;
299 : : };
300 : :
301 : : #endif
|