1 /* Data and functions related to line maps and input files.
2 Copyright (C) 2004-2013 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
26 /* Current position in real source file. */
28 location_t input_location
;
30 struct line_maps
*line_table
;
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.
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
46 static expanded_location
47 expand_location_1 (source_location loc
,
48 bool expansion_point_p
)
50 expanded_location xloc
;
51 const struct line_map
*map
;
52 enum location_resolution_kind lrk
= LRK_MACRO_EXPANSION_POINT
;
55 if (IS_ADHOC_LOC (loc
))
57 block
= LOCATION_BLOCK (loc
);
58 loc
= LOCATION_LOCUS (loc
);
61 memset (&xloc
, 0, sizeof (xloc
));
63 if (loc
>= RESERVED_LOCATION_COUNT
)
65 if (!expansion_point_p
)
67 /* We want to resolve LOC to its spelling location.
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
,
76 lrk
= LRK_SPELLING_LOCATION
;
78 loc
= linemap_resolve_location (line_table
, loc
,
80 xloc
= linemap_expand_location (line_table
, map
, loc
);
84 if (loc
<= BUILTINS_LOCATION
)
85 xloc
.file
= loc
== UNKNOWN_LOCATION
? NULL
: _("<built-in>");
90 /* Reads one line from file into a static buffer. */
92 read_line (FILE *file
)
95 static size_t string_len
;
102 string
= XNEWVEC (char, string_len
);
105 while ((ptr
= fgets (string
+ pos
, string_len
- pos
, file
)))
107 size_t len
= strlen (string
+ pos
);
109 if (string
[pos
+ len
- 1] == '\n')
111 string
[pos
+ len
- 1] = 0;
115 string
= XRESIZEVEC (char, string
, string_len
* 2);
119 return pos
? string
: NULL
;
122 /* Return the physical source line that corresponds to xloc in a
123 buffer that is statically allocated. The newline is replaced by
124 the null character. */
127 location_get_source_line (expanded_location xloc
)
131 FILE *stream
= xloc
.file
? fopen (xloc
.file
, "r") : NULL
;
135 while ((buffer
= read_line (stream
)) && lines
< xloc
.line
)
142 /* Expand the source location LOC into a human readable location. If
143 LOC is virtual, it resolves to the expansion point of the involved
144 macro. If LOC resolves to a builtin location, the file name of the
145 readable location is set to the string "<built-in>". */
148 expand_location (source_location loc
)
150 return expand_location_1 (loc
, /*expansion_point_p=*/true);
153 /* Expand the source location LOC into a human readable location. If
154 LOC is virtual, it resolves to the expansion location of the
155 relevant macro. If LOC resolves to a builtin location, the file
156 name of the readable location is set to the string
160 expand_location_to_spelling_point (source_location loc
)
162 return expand_location_1 (loc
, /*expansion_piont_p=*/false);
165 /* If LOCATION is in a system header and if it's a virtual location for
166 a token coming from the expansion of a macro M, unwind it to the
167 location of the expansion point of M. Otherwise, just return
170 This is used for instance when we want to emit diagnostics about a
171 token that is located in a macro that is itself defined in a system
172 header -- e.g for the NULL macro. In that case, if LOCATION is
173 passed to diagnostics emitting functions like warning_at as is, no
174 diagnostic won't be emitted. */
177 expansion_point_location_if_in_system_header (source_location location
)
179 if (in_system_header_at (location
))
180 location
= linemap_resolve_location (line_table
, location
,
181 LRK_MACRO_EXPANSION_POINT
,
187 #define ONE_M (ONE_K * ONE_K)
189 /* Display a number as an integer multiple of either:
190 - 1024, if said integer is >= to 10 K (in base 2)
191 - 1024 * 1024, if said integer is >= 10 M in (base 2)
193 #define SCALE(x) ((unsigned long) ((x) < 10 * ONE_K \
195 : ((x) < 10 * ONE_M \
199 /* For a given integer, display either:
200 - the character 'k', if the number is higher than 10 K (in base 2)
201 but strictly lower than 10 M (in base 2)
202 - the character 'M' if the number is higher than 10 M (in base2)
203 - the charcter ' ' if the number is strictly lower than 10 K */
204 #define STAT_LABEL(x) ((x) < 10 * ONE_K ? ' ' : ((x) < 10 * ONE_M ? 'k' : 'M'))
206 /* Display an integer amount as multiple of 1K or 1M (in base 2).
207 Display the correct unit (either k, M, or ' ') after the amout, as
209 #define FORMAT_AMOUNT(size) SCALE (size), STAT_LABEL (size)
211 /* Dump statistics to stderr about the memory usage of the line_table
212 set of line maps. This also displays some statistics about macro
216 dump_line_table_statistics (void)
218 struct linemap_stats s
;
219 long total_used_map_size
,
221 total_allocated_map_size
;
223 memset (&s
, 0, sizeof (s
));
225 linemap_get_statistics (line_table
, &s
);
227 macro_maps_size
= s
.macro_maps_used_size
228 + s
.macro_maps_locations_size
;
230 total_allocated_map_size
= s
.ordinary_maps_allocated_size
231 + s
.macro_maps_allocated_size
232 + s
.macro_maps_locations_size
;
234 total_used_map_size
= s
.ordinary_maps_used_size
235 + s
.macro_maps_used_size
236 + s
.macro_maps_locations_size
;
238 fprintf (stderr
, "Number of expanded macros: %5ld\n",
239 s
.num_expanded_macros
);
240 if (s
.num_expanded_macros
!= 0)
241 fprintf (stderr
, "Average number of tokens per macro expansion: %5ld\n",
242 s
.num_macro_tokens
/ s
.num_expanded_macros
);
244 "\nLine Table allocations during the "
245 "compilation process\n");
246 fprintf (stderr
, "Number of ordinary maps used: %5ld%c\n",
247 SCALE (s
.num_ordinary_maps_used
),
248 STAT_LABEL (s
.num_ordinary_maps_used
));
249 fprintf (stderr
, "Ordinary map used size: %5ld%c\n",
250 SCALE (s
.ordinary_maps_used_size
),
251 STAT_LABEL (s
.ordinary_maps_used_size
));
252 fprintf (stderr
, "Number of ordinary maps allocated: %5ld%c\n",
253 SCALE (s
.num_ordinary_maps_allocated
),
254 STAT_LABEL (s
.num_ordinary_maps_allocated
));
255 fprintf (stderr
, "Ordinary maps allocated size: %5ld%c\n",
256 SCALE (s
.ordinary_maps_allocated_size
),
257 STAT_LABEL (s
.ordinary_maps_allocated_size
));
258 fprintf (stderr
, "Number of macro maps used: %5ld%c\n",
259 SCALE (s
.num_macro_maps_used
),
260 STAT_LABEL (s
.num_macro_maps_used
));
261 fprintf (stderr
, "Macro maps used size: %5ld%c\n",
262 SCALE (s
.macro_maps_used_size
),
263 STAT_LABEL (s
.macro_maps_used_size
));
264 fprintf (stderr
, "Macro maps locations size: %5ld%c\n",
265 SCALE (s
.macro_maps_locations_size
),
266 STAT_LABEL (s
.macro_maps_locations_size
));
267 fprintf (stderr
, "Macro maps size: %5ld%c\n",
268 SCALE (macro_maps_size
),
269 STAT_LABEL (macro_maps_size
));
270 fprintf (stderr
, "Duplicated maps locations size: %5ld%c\n",
271 SCALE (s
.duplicated_macro_maps_locations_size
),
272 STAT_LABEL (s
.duplicated_macro_maps_locations_size
));
273 fprintf (stderr
, "Total allocated maps size: %5ld%c\n",
274 SCALE (total_allocated_map_size
),
275 STAT_LABEL (total_allocated_map_size
));
276 fprintf (stderr
, "Total used maps size: %5ld%c\n",
277 SCALE (total_used_map_size
),
278 STAT_LABEL (total_used_map_size
));
279 fprintf (stderr
, "\n");