]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/input.c
backport: As described in http://gcc.gnu.org/ml/gcc/2012-08/msg00015.html...
[thirdparty/gcc.git] / gcc / input.c
CommitLineData
447924ef 1/* Data and functions related to line maps and input files.
92b05e72 2 Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011, 2012
447924ef
JM
3 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "intl.h"
25#include "input.h"
26
27/* Current position in real source file. */
28
29location_t input_location;
30
31struct line_maps *line_table;
32
84756fd4
DS
33/* Expand the source location LOC into a human readable location. If
34 LOC resolves to a builtin location, the file name of the readable
7eb918cc
DS
35 location is set to the string "<built-in>". If EXPANSION_POINT_P is
36 TRUE and LOC is virtual, then it is resolved to the expansion
37 point of the involved macro. Otherwise, it is resolved to the
c4ca1a09
DS
38 spelling location of the token.
39
40 When resolving to the spelling location of the token, if the
41 resulting location is for a built-in location (that is, it has no
42 associated line/column) in the context of a macro expansion, the
43 returned location is the first one (while unwinding the macro
44 location towards its expansion point) that is in real source
45 code. */
7eb918cc
DS
46
47static expanded_location
48expand_location_1 (source_location loc,
49 bool expansion_point_p)
447924ef
JM
50{
51 expanded_location xloc;
84756fd4 52 const struct line_map *map;
c4ca1a09
DS
53 enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
54
55 memset (&xloc, 0, sizeof (xloc));
84756fd4 56
c4ca1a09
DS
57 if (loc >= RESERVED_LOCATION_COUNT)
58 {
59 if (!expansion_point_p)
60 {
61 /* We want to resolve LOC to its spelling location.
62
63 But if that spelling location is a reserved location that
64 appears in the context of a macro expansion (like for a
65 location for a built-in token), let's consider the first
66 location (toward the expansion point) that is not reserved;
67 that is, the first location that is in real source code. */
68 loc = linemap_unwind_to_first_non_reserved_loc (line_table,
69 loc, &map);
70 lrk = LRK_SPELLING_LOCATION;
71 }
72 loc = linemap_resolve_location (line_table, loc,
73 lrk, &map);
74 xloc = linemap_expand_location (line_table, map, loc);
75 }
84756fd4 76
447924ef 77 if (loc <= BUILTINS_LOCATION)
84756fd4
DS
78 xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
79
447924ef
JM
80 return xloc;
81}
64a1a422 82
9fec0042
MLI
83/* Reads one line from file into a static buffer. */
84static const char *
85read_line (FILE *file)
86{
87 static char *string;
88 static size_t string_len;
89 size_t pos = 0;
90 char *ptr;
91
92 if (!string_len)
93 {
94 string_len = 200;
95 string = XNEWVEC (char, string_len);
96 }
97
98 while ((ptr = fgets (string + pos, string_len - pos, file)))
99 {
100 size_t len = strlen (string + pos);
101
102 if (string[pos + len - 1] == '\n')
103 {
104 string[pos + len - 1] = 0;
105 return string;
106 }
107 pos += len;
92b05e72
JJ
108 string = XRESIZEVEC (char, string, string_len * 2);
109 string_len *= 2;
9fec0042
MLI
110 }
111
112 return pos ? string : NULL;
113}
114
115/* Return the physical source line that corresponds to xloc in a
116 buffer that is statically allocated. The newline is replaced by
117 the null character. */
118
119const char *
6399c0ab 120location_get_source_line (expanded_location xloc)
9fec0042
MLI
121{
122 const char *buffer;
123 int lines = 1;
124 FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
125 if (!stream)
126 return NULL;
127
128 while ((buffer = read_line (stream)) && lines < xloc.line)
129 lines++;
130
131 fclose (stream);
132 return buffer;
133}
134
7eb918cc
DS
135/* Expand the source location LOC into a human readable location. If
136 LOC is virtual, it resolves to the expansion point of the involved
137 macro. If LOC resolves to a builtin location, the file name of the
138 readable location is set to the string "<built-in>". */
139
140expanded_location
141expand_location (source_location loc)
142{
143 return expand_location_1 (loc, /*expansion_point_p=*/true);
144}
145
146/* Expand the source location LOC into a human readable location. If
147 LOC is virtual, it resolves to the expansion location of the
148 relevant macro. If LOC resolves to a builtin location, the file
149 name of the readable location is set to the string
150 "<built-in>". */
151
152expanded_location
153expand_location_to_spelling_point (source_location loc)
154{
155 return expand_location_1 (loc, /*expansion_piont_p=*/false);
156}
157
073a8998 158/* If LOCATION is in a system header and if it's a virtual location for
70dc395a
DS
159 a token coming from the expansion of a macro M, unwind it to the
160 location of the expansion point of M. Otherwise, just return
161 LOCATION.
162
163 This is used for instance when we want to emit diagnostics about a
164 token that is located in a macro that is itself defined in a system
165 header -- e.g for the NULL macro. In that case, if LOCATION is
166 passed to diagnostics emitting functions like warning_at as is, no
167 diagnostic won't be emitted. */
168
169source_location
170expansion_point_location_if_in_system_header (source_location location)
171{
172 if (in_system_header_at (location))
173 location = linemap_resolve_location (line_table, location,
174 LRK_MACRO_EXPANSION_POINT,
175 NULL);
176 return location;
177}
7eb918cc 178
64a1a422
TT
179#define ONE_K 1024
180#define ONE_M (ONE_K * ONE_K)
181
182/* Display a number as an integer multiple of either:
183 - 1024, if said integer is >= to 10 K (in base 2)
184 - 1024 * 1024, if said integer is >= 10 M in (base 2)
185 */
186#define SCALE(x) ((unsigned long) ((x) < 10 * ONE_K \
187 ? (x) \
188 : ((x) < 10 * ONE_M \
189 ? (x) / ONE_K \
190 : (x) / ONE_M)))
191
192/* For a given integer, display either:
193 - the character 'k', if the number is higher than 10 K (in base 2)
194 but strictly lower than 10 M (in base 2)
195 - the character 'M' if the number is higher than 10 M (in base2)
196 - the charcter ' ' if the number is strictly lower than 10 K */
197#define STAT_LABEL(x) ((x) < 10 * ONE_K ? ' ' : ((x) < 10 * ONE_M ? 'k' : 'M'))
198
199/* Display an integer amount as multiple of 1K or 1M (in base 2).
200 Display the correct unit (either k, M, or ' ') after the amout, as
201 well. */
202#define FORMAT_AMOUNT(size) SCALE (size), STAT_LABEL (size)
203
204/* Dump statistics to stderr about the memory usage of the line_table
205 set of line maps. This also displays some statistics about macro
206 expansion. */
207
208void
209dump_line_table_statistics (void)
210{
211 struct linemap_stats s;
d17687f6 212 long total_used_map_size,
64a1a422
TT
213 macro_maps_size,
214 total_allocated_map_size;
215
216 memset (&s, 0, sizeof (s));
217
218 linemap_get_statistics (line_table, &s);
219
220 macro_maps_size = s.macro_maps_used_size
221 + s.macro_maps_locations_size;
222
223 total_allocated_map_size = s.ordinary_maps_allocated_size
224 + s.macro_maps_allocated_size
225 + s.macro_maps_locations_size;
226
227 total_used_map_size = s.ordinary_maps_used_size
228 + s.macro_maps_used_size
229 + s.macro_maps_locations_size;
230
d17687f6 231 fprintf (stderr, "Number of expanded macros: %5ld\n",
64a1a422
TT
232 s.num_expanded_macros);
233 if (s.num_expanded_macros != 0)
d17687f6 234 fprintf (stderr, "Average number of tokens per macro expansion: %5ld\n",
64a1a422
TT
235 s.num_macro_tokens / s.num_expanded_macros);
236 fprintf (stderr,
237 "\nLine Table allocations during the "
238 "compilation process\n");
d17687f6 239 fprintf (stderr, "Number of ordinary maps used: %5ld%c\n",
64a1a422
TT
240 SCALE (s.num_ordinary_maps_used),
241 STAT_LABEL (s.num_ordinary_maps_used));
d17687f6 242 fprintf (stderr, "Ordinary map used size: %5ld%c\n",
64a1a422
TT
243 SCALE (s.ordinary_maps_used_size),
244 STAT_LABEL (s.ordinary_maps_used_size));
d17687f6 245 fprintf (stderr, "Number of ordinary maps allocated: %5ld%c\n",
64a1a422
TT
246 SCALE (s.num_ordinary_maps_allocated),
247 STAT_LABEL (s.num_ordinary_maps_allocated));
d17687f6 248 fprintf (stderr, "Ordinary maps allocated size: %5ld%c\n",
64a1a422
TT
249 SCALE (s.ordinary_maps_allocated_size),
250 STAT_LABEL (s.ordinary_maps_allocated_size));
d17687f6 251 fprintf (stderr, "Number of macro maps used: %5ld%c\n",
64a1a422
TT
252 SCALE (s.num_macro_maps_used),
253 STAT_LABEL (s.num_macro_maps_used));
d17687f6 254 fprintf (stderr, "Macro maps used size: %5ld%c\n",
64a1a422
TT
255 SCALE (s.macro_maps_used_size),
256 STAT_LABEL (s.macro_maps_used_size));
d17687f6 257 fprintf (stderr, "Macro maps locations size: %5ld%c\n",
64a1a422
TT
258 SCALE (s.macro_maps_locations_size),
259 STAT_LABEL (s.macro_maps_locations_size));
d17687f6 260 fprintf (stderr, "Macro maps size: %5ld%c\n",
64a1a422
TT
261 SCALE (macro_maps_size),
262 STAT_LABEL (macro_maps_size));
d17687f6 263 fprintf (stderr, "Duplicated maps locations size: %5ld%c\n",
64a1a422
TT
264 SCALE (s.duplicated_macro_maps_locations_size),
265 STAT_LABEL (s.duplicated_macro_maps_locations_size));
d17687f6 266 fprintf (stderr, "Total allocated maps size: %5ld%c\n",
64a1a422
TT
267 SCALE (total_allocated_map_size),
268 STAT_LABEL (total_allocated_map_size));
d17687f6 269 fprintf (stderr, "Total used maps size: %5ld%c\n",
64a1a422
TT
270 SCALE (total_used_map_size),
271 STAT_LABEL (total_used_map_size));
272 fprintf (stderr, "\n");
273}