]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/input.c
preprocessor/58580 - preprocessor goes OOM with warning for zero literals
[thirdparty/gcc.git] / gcc / input.c
1 /* Data and functions related to line maps and input files.
2 Copyright (C) 2004-2013 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "intl.h"
24 #include "input.h"
25
26 /* Current position in real source file. */
27
28 location_t input_location;
29
30 struct line_maps *line_table;
31
32 /* Expand the source location LOC into a human readable location. If
33 LOC resolves to a builtin location, the file name of the readable
34 location is set to the string "<built-in>". If EXPANSION_POINT_P is
35 TRUE and LOC is virtual, then it is resolved to the expansion
36 point of the involved macro. Otherwise, it is resolved to the
37 spelling location of the token.
38
39 When resolving to the spelling location of the token, if the
40 resulting location is for a built-in location (that is, it has no
41 associated line/column) in the context of a macro expansion, the
42 returned location is the first one (while unwinding the macro
43 location towards its expansion point) that is in real source
44 code. */
45
46 static expanded_location
47 expand_location_1 (source_location loc,
48 bool expansion_point_p)
49 {
50 expanded_location xloc;
51 const struct line_map *map;
52 enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
53 tree block = NULL;
54
55 if (IS_ADHOC_LOC (loc))
56 {
57 block = LOCATION_BLOCK (loc);
58 loc = LOCATION_LOCUS (loc);
59 }
60
61 memset (&xloc, 0, sizeof (xloc));
62
63 if (loc >= RESERVED_LOCATION_COUNT)
64 {
65 if (!expansion_point_p)
66 {
67 /* We want to resolve LOC to its spelling location.
68
69 But if that spelling location is a reserved location that
70 appears in the context of a macro expansion (like for a
71 location for a built-in token), let's consider the first
72 location (toward the expansion point) that is not reserved;
73 that is, the first location that is in real source code. */
74 loc = linemap_unwind_to_first_non_reserved_loc (line_table,
75 loc, &map);
76 lrk = LRK_SPELLING_LOCATION;
77 }
78 loc = linemap_resolve_location (line_table, loc,
79 lrk, &map);
80 xloc = linemap_expand_location (line_table, map, loc);
81 }
82
83 xloc.data = block;
84 if (loc <= BUILTINS_LOCATION)
85 xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
86
87 return xloc;
88 }
89
90 /* This function reads a line that might contain bytes whose value is
91 zero. It returns the number of bytes read. The 'end-of-line'
92 character found at the end of the line is not contained in the
93 returned buffer. Note that this function has been adapted from
94 getline() and _IO_getdelim() GNU C library functions. It's been
95 duplicated here because the getline() function is not necessarily
96 present on all platforms.
97
98 LINEPTR points to a buffer that is to contain the line read.
99
100 N points to the size of the the LINEPTR buffer.
101
102 FP points to the file to consider. */
103
104 static ssize_t
105 get_line (char **lineptr, size_t *n, FILE *fp)
106 {
107 ssize_t cur_len = 0, len;
108 char buf[16384];
109
110 if (lineptr == NULL || n == NULL)
111 return -1;
112
113 if (*lineptr == NULL || *n == 0)
114 {
115 *n = 120;
116 *lineptr = XNEWVEC (char, *n);
117 }
118
119 len = fread (buf, 1, sizeof buf, fp);
120 if (ferror (fp))
121 return -1;
122
123 for (;;)
124 {
125 size_t needed;
126 char *t = (char*) memchr (buf, '\n', len);
127 if (t != NULL) len = (t - buf);
128 if (__builtin_expect (len >= SSIZE_MAX - cur_len, 0))
129 return -1;
130 needed = cur_len + len + 1;
131 if (needed > *n)
132 {
133 char *new_lineptr;
134 if (needed < 2 * *n)
135 needed = 2 * *n;
136 new_lineptr = XRESIZEVEC (char, *lineptr, needed);
137 *lineptr = new_lineptr;
138 *n = needed;
139 }
140 memcpy (*lineptr + cur_len, buf, len);
141 cur_len += len;
142 if (t != NULL)
143 break;
144 len = fread (buf, 1, sizeof buf, fp);
145 if (ferror (fp))
146 return -1;
147 if (len == 0)
148 break;
149 }
150
151 if (cur_len)
152 (*lineptr)[cur_len] = '\0';
153 return cur_len;
154 }
155
156 /* Reads one line from FILE into a static buffer. If LINE_LENGTH is
157 *non-null LINE_LENGTH, will be set by this function to the length of
158 *the returned line. Note that the returned line can contain several
159 *zero bytes. Also note that the returned string is allocated in
160 *static storage that is going to be re-used by subsequent invocations
161 *of read_line. */
162 static const char *
163 read_line (FILE *file, int *line_length)
164 {
165 static char *string;
166 static size_t string_len;
167 int len;
168
169 len = get_line (&string, &string_len, file);
170 if (line_length)
171 *line_length = len;
172 return len ? string : NULL;
173 }
174
175 /* Return the physical source line that corresponds to xloc in a
176 buffer that is statically allocated. The newline is replaced by
177 the null character. Note that the line can contain several null
178 characters, so LINE_LEN, if non-null, points to the actual length
179 of the line. */
180
181 const char *
182 location_get_source_line (expanded_location xloc,
183 int *line_len)
184 {
185 const char *buffer = NULL, *ptr;
186 int lines = 0, len = 0;
187 FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
188 if (!stream)
189 return NULL;
190
191 while ((ptr = read_line (stream, &len)) && lines < xloc.line)
192 {
193 buffer = ptr;
194 lines++;
195 if (line_len)
196 *line_len = len;
197 }
198
199 fclose (stream);
200 return buffer;
201 }
202
203 /* Expand the source location LOC into a human readable location. If
204 LOC is virtual, it resolves to the expansion point of the involved
205 macro. If LOC resolves to a builtin location, the file name of the
206 readable location is set to the string "<built-in>". */
207
208 expanded_location
209 expand_location (source_location loc)
210 {
211 return expand_location_1 (loc, /*expansion_point_p=*/true);
212 }
213
214 /* Expand the source location LOC into a human readable location. If
215 LOC is virtual, it resolves to the expansion location of the
216 relevant macro. If LOC resolves to a builtin location, the file
217 name of the readable location is set to the string
218 "<built-in>". */
219
220 expanded_location
221 expand_location_to_spelling_point (source_location loc)
222 {
223 return expand_location_1 (loc, /*expansion_piont_p=*/false);
224 }
225
226 /* If LOCATION is in a system header and if it's a virtual location for
227 a token coming from the expansion of a macro M, unwind it to the
228 location of the expansion point of M. Otherwise, just return
229 LOCATION.
230
231 This is used for instance when we want to emit diagnostics about a
232 token that is located in a macro that is itself defined in a system
233 header -- e.g for the NULL macro. In that case, if LOCATION is
234 passed to diagnostics emitting functions like warning_at as is, no
235 diagnostic won't be emitted. */
236
237 source_location
238 expansion_point_location_if_in_system_header (source_location location)
239 {
240 if (in_system_header_at (location))
241 location = linemap_resolve_location (line_table, location,
242 LRK_MACRO_EXPANSION_POINT,
243 NULL);
244 return location;
245 }
246
247 #define ONE_K 1024
248 #define ONE_M (ONE_K * ONE_K)
249
250 /* Display a number as an integer multiple of either:
251 - 1024, if said integer is >= to 10 K (in base 2)
252 - 1024 * 1024, if said integer is >= 10 M in (base 2)
253 */
254 #define SCALE(x) ((unsigned long) ((x) < 10 * ONE_K \
255 ? (x) \
256 : ((x) < 10 * ONE_M \
257 ? (x) / ONE_K \
258 : (x) / ONE_M)))
259
260 /* For a given integer, display either:
261 - the character 'k', if the number is higher than 10 K (in base 2)
262 but strictly lower than 10 M (in base 2)
263 - the character 'M' if the number is higher than 10 M (in base2)
264 - the charcter ' ' if the number is strictly lower than 10 K */
265 #define STAT_LABEL(x) ((x) < 10 * ONE_K ? ' ' : ((x) < 10 * ONE_M ? 'k' : 'M'))
266
267 /* Display an integer amount as multiple of 1K or 1M (in base 2).
268 Display the correct unit (either k, M, or ' ') after the amout, as
269 well. */
270 #define FORMAT_AMOUNT(size) SCALE (size), STAT_LABEL (size)
271
272 /* Dump statistics to stderr about the memory usage of the line_table
273 set of line maps. This also displays some statistics about macro
274 expansion. */
275
276 void
277 dump_line_table_statistics (void)
278 {
279 struct linemap_stats s;
280 long total_used_map_size,
281 macro_maps_size,
282 total_allocated_map_size;
283
284 memset (&s, 0, sizeof (s));
285
286 linemap_get_statistics (line_table, &s);
287
288 macro_maps_size = s.macro_maps_used_size
289 + s.macro_maps_locations_size;
290
291 total_allocated_map_size = s.ordinary_maps_allocated_size
292 + s.macro_maps_allocated_size
293 + s.macro_maps_locations_size;
294
295 total_used_map_size = s.ordinary_maps_used_size
296 + s.macro_maps_used_size
297 + s.macro_maps_locations_size;
298
299 fprintf (stderr, "Number of expanded macros: %5ld\n",
300 s.num_expanded_macros);
301 if (s.num_expanded_macros != 0)
302 fprintf (stderr, "Average number of tokens per macro expansion: %5ld\n",
303 s.num_macro_tokens / s.num_expanded_macros);
304 fprintf (stderr,
305 "\nLine Table allocations during the "
306 "compilation process\n");
307 fprintf (stderr, "Number of ordinary maps used: %5ld%c\n",
308 SCALE (s.num_ordinary_maps_used),
309 STAT_LABEL (s.num_ordinary_maps_used));
310 fprintf (stderr, "Ordinary map used size: %5ld%c\n",
311 SCALE (s.ordinary_maps_used_size),
312 STAT_LABEL (s.ordinary_maps_used_size));
313 fprintf (stderr, "Number of ordinary maps allocated: %5ld%c\n",
314 SCALE (s.num_ordinary_maps_allocated),
315 STAT_LABEL (s.num_ordinary_maps_allocated));
316 fprintf (stderr, "Ordinary maps allocated size: %5ld%c\n",
317 SCALE (s.ordinary_maps_allocated_size),
318 STAT_LABEL (s.ordinary_maps_allocated_size));
319 fprintf (stderr, "Number of macro maps used: %5ld%c\n",
320 SCALE (s.num_macro_maps_used),
321 STAT_LABEL (s.num_macro_maps_used));
322 fprintf (stderr, "Macro maps used size: %5ld%c\n",
323 SCALE (s.macro_maps_used_size),
324 STAT_LABEL (s.macro_maps_used_size));
325 fprintf (stderr, "Macro maps locations size: %5ld%c\n",
326 SCALE (s.macro_maps_locations_size),
327 STAT_LABEL (s.macro_maps_locations_size));
328 fprintf (stderr, "Macro maps size: %5ld%c\n",
329 SCALE (macro_maps_size),
330 STAT_LABEL (macro_maps_size));
331 fprintf (stderr, "Duplicated maps locations size: %5ld%c\n",
332 SCALE (s.duplicated_macro_maps_locations_size),
333 STAT_LABEL (s.duplicated_macro_maps_locations_size));
334 fprintf (stderr, "Total allocated maps size: %5ld%c\n",
335 SCALE (total_allocated_map_size),
336 STAT_LABEL (total_allocated_map_size));
337 fprintf (stderr, "Total used maps size: %5ld%c\n",
338 SCALE (total_used_map_size),
339 STAT_LABEL (total_used_map_size));
340 fprintf (stderr, "\n");
341 }