1 /* Data and functions related to line maps and input files.
2 Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
5 This file is part of GCC.
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
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
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/>. */
23 #include "coretypes.h"
27 /* Current position in real source file. */
29 location_t input_location
;
31 struct line_maps
*line_table
;
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
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
38 spelling location of the token.
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
47 static expanded_location
48 expand_location_1 (source_location loc
,
49 bool expansion_point_p
)
51 expanded_location xloc
;
52 const struct line_map
*map
;
53 enum location_resolution_kind lrk
= LRK_MACRO_EXPANSION_POINT
;
56 if (IS_ADHOC_LOC (loc
))
58 block
= LOCATION_BLOCK (loc
);
59 loc
= LOCATION_LOCUS (loc
);
62 memset (&xloc
, 0, sizeof (xloc
));
64 if (loc
>= RESERVED_LOCATION_COUNT
)
66 if (!expansion_point_p
)
68 /* We want to resolve LOC to its spelling location.
70 But if that spelling location is a reserved location that
71 appears in the context of a macro expansion (like for a
72 location for a built-in token), let's consider the first
73 location (toward the expansion point) that is not reserved;
74 that is, the first location that is in real source code. */
75 loc
= linemap_unwind_to_first_non_reserved_loc (line_table
,
77 lrk
= LRK_SPELLING_LOCATION
;
79 loc
= linemap_resolve_location (line_table
, loc
,
81 xloc
= linemap_expand_location (line_table
, map
, loc
);
85 if (loc
<= BUILTINS_LOCATION
)
86 xloc
.file
= loc
== UNKNOWN_LOCATION
? NULL
: _("<built-in>");
91 /* Reads one line from file into a static buffer. */
93 read_line (FILE *file
)
96 static size_t string_len
;
103 string
= XNEWVEC (char, string_len
);
106 while ((ptr
= fgets (string
+ pos
, string_len
- pos
, file
)))
108 size_t len
= strlen (string
+ pos
);
110 if (string
[pos
+ len
- 1] == '\n')
112 string
[pos
+ len
- 1] = 0;
116 string
= XRESIZEVEC (char, string
, string_len
* 2);
120 return pos
? string
: NULL
;
123 /* Return the physical source line that corresponds to xloc in a
124 buffer that is statically allocated. The newline is replaced by
125 the null character. */
128 location_get_source_line (expanded_location xloc
)
132 FILE *stream
= xloc
.file
? fopen (xloc
.file
, "r") : NULL
;
136 while ((buffer
= read_line (stream
)) && lines
< xloc
.line
)
143 /* Expand the source location LOC into a human readable location. If
144 LOC is virtual, it resolves to the expansion point of the involved
145 macro. If LOC resolves to a builtin location, the file name of the
146 readable location is set to the string "<built-in>". */
149 expand_location (source_location loc
)
151 return expand_location_1 (loc
, /*expansion_point_p=*/true);
154 /* Expand the source location LOC into a human readable location. If
155 LOC is virtual, it resolves to the expansion location of the
156 relevant macro. If LOC resolves to a builtin location, the file
157 name of the readable location is set to the string
161 expand_location_to_spelling_point (source_location loc
)
163 return expand_location_1 (loc
, /*expansion_piont_p=*/false);
166 /* If LOCATION is in a system header and if it's a virtual location for
167 a token coming from the expansion of a macro M, unwind it to the
168 location of the expansion point of M. Otherwise, just return
171 This is used for instance when we want to emit diagnostics about a
172 token that is located in a macro that is itself defined in a system
173 header -- e.g for the NULL macro. In that case, if LOCATION is
174 passed to diagnostics emitting functions like warning_at as is, no
175 diagnostic won't be emitted. */
178 expansion_point_location_if_in_system_header (source_location location
)
180 if (in_system_header_at (location
))
181 location
= linemap_resolve_location (line_table
, location
,
182 LRK_MACRO_EXPANSION_POINT
,
188 #define ONE_M (ONE_K * ONE_K)
190 /* Display a number as an integer multiple of either:
191 - 1024, if said integer is >= to 10 K (in base 2)
192 - 1024 * 1024, if said integer is >= 10 M in (base 2)
194 #define SCALE(x) ((unsigned long) ((x) < 10 * ONE_K \
196 : ((x) < 10 * ONE_M \
200 /* For a given integer, display either:
201 - the character 'k', if the number is higher than 10 K (in base 2)
202 but strictly lower than 10 M (in base 2)
203 - the character 'M' if the number is higher than 10 M (in base2)
204 - the charcter ' ' if the number is strictly lower than 10 K */
205 #define STAT_LABEL(x) ((x) < 10 * ONE_K ? ' ' : ((x) < 10 * ONE_M ? 'k' : 'M'))
207 /* Display an integer amount as multiple of 1K or 1M (in base 2).
208 Display the correct unit (either k, M, or ' ') after the amout, as
210 #define FORMAT_AMOUNT(size) SCALE (size), STAT_LABEL (size)
212 /* Dump statistics to stderr about the memory usage of the line_table
213 set of line maps. This also displays some statistics about macro
217 dump_line_table_statistics (void)
219 struct linemap_stats s
;
220 long total_used_map_size
,
222 total_allocated_map_size
;
224 memset (&s
, 0, sizeof (s
));
226 linemap_get_statistics (line_table
, &s
);
228 macro_maps_size
= s
.macro_maps_used_size
229 + s
.macro_maps_locations_size
;
231 total_allocated_map_size
= s
.ordinary_maps_allocated_size
232 + s
.macro_maps_allocated_size
233 + s
.macro_maps_locations_size
;
235 total_used_map_size
= s
.ordinary_maps_used_size
236 + s
.macro_maps_used_size
237 + s
.macro_maps_locations_size
;
239 fprintf (stderr
, "Number of expanded macros: %5ld\n",
240 s
.num_expanded_macros
);
241 if (s
.num_expanded_macros
!= 0)
242 fprintf (stderr
, "Average number of tokens per macro expansion: %5ld\n",
243 s
.num_macro_tokens
/ s
.num_expanded_macros
);
245 "\nLine Table allocations during the "
246 "compilation process\n");
247 fprintf (stderr
, "Number of ordinary maps used: %5ld%c\n",
248 SCALE (s
.num_ordinary_maps_used
),
249 STAT_LABEL (s
.num_ordinary_maps_used
));
250 fprintf (stderr
, "Ordinary map used size: %5ld%c\n",
251 SCALE (s
.ordinary_maps_used_size
),
252 STAT_LABEL (s
.ordinary_maps_used_size
));
253 fprintf (stderr
, "Number of ordinary maps allocated: %5ld%c\n",
254 SCALE (s
.num_ordinary_maps_allocated
),
255 STAT_LABEL (s
.num_ordinary_maps_allocated
));
256 fprintf (stderr
, "Ordinary maps allocated size: %5ld%c\n",
257 SCALE (s
.ordinary_maps_allocated_size
),
258 STAT_LABEL (s
.ordinary_maps_allocated_size
));
259 fprintf (stderr
, "Number of macro maps used: %5ld%c\n",
260 SCALE (s
.num_macro_maps_used
),
261 STAT_LABEL (s
.num_macro_maps_used
));
262 fprintf (stderr
, "Macro maps used size: %5ld%c\n",
263 SCALE (s
.macro_maps_used_size
),
264 STAT_LABEL (s
.macro_maps_used_size
));
265 fprintf (stderr
, "Macro maps locations size: %5ld%c\n",
266 SCALE (s
.macro_maps_locations_size
),
267 STAT_LABEL (s
.macro_maps_locations_size
));
268 fprintf (stderr
, "Macro maps size: %5ld%c\n",
269 SCALE (macro_maps_size
),
270 STAT_LABEL (macro_maps_size
));
271 fprintf (stderr
, "Duplicated maps locations size: %5ld%c\n",
272 SCALE (s
.duplicated_macro_maps_locations_size
),
273 STAT_LABEL (s
.duplicated_macro_maps_locations_size
));
274 fprintf (stderr
, "Total allocated maps size: %5ld%c\n",
275 SCALE (total_allocated_map_size
),
276 STAT_LABEL (total_allocated_map_size
));
277 fprintf (stderr
, "Total used maps size: %5ld%c\n",
278 SCALE (total_used_map_size
),
279 STAT_LABEL (total_used_map_size
));
280 fprintf (stderr
, "\n");