Update change log
[platform/upstream/gcc48.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 /* Reads one line from file into a static buffer.  */
91 static const char *
92 read_line (FILE *file)
93 {
94   static char *string;
95   static size_t string_len;
96   size_t pos = 0;
97   char *ptr;
98
99   if (!string_len)
100     {
101       string_len = 200;
102       string = XNEWVEC (char, string_len);
103     }
104
105   while ((ptr = fgets (string + pos, string_len - pos, file)))
106     {
107       size_t len = strlen (string + pos);
108
109       if (string[pos + len - 1] == '\n')
110         {
111           string[pos + len - 1] = 0;
112           return string;
113         }
114       pos += len;
115       string = XRESIZEVEC (char, string, string_len * 2);
116       string_len *= 2;
117     }
118       
119   return pos ? string : NULL;
120 }
121
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.  */
125
126 const char *
127 location_get_source_line (expanded_location xloc)
128 {
129   const char *buffer;
130   int lines = 1;
131   FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
132   if (!stream)
133     return NULL;
134
135   while ((buffer = read_line (stream)) && lines < xloc.line)
136     lines++;
137
138   fclose (stream);
139   return buffer;
140 }
141
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>".  */
146
147 expanded_location
148 expand_location (source_location loc)
149 {
150   return expand_location_1 (loc, /*expansion_point_p=*/true);
151 }
152
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
157    "<built-in>".  */
158
159 expanded_location
160 expand_location_to_spelling_point (source_location loc)
161 {
162   return expand_location_1 (loc, /*expansion_piont_p=*/false);
163 }
164
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
168    LOCATION.
169
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.  */
175
176 source_location
177 expansion_point_location_if_in_system_header (source_location location)
178 {
179   if (in_system_header_at (location))
180     location = linemap_resolve_location (line_table, location,
181                                          LRK_MACRO_EXPANSION_POINT,
182                                          NULL);
183   return location;
184 }
185
186 #define ONE_K 1024
187 #define ONE_M (ONE_K * ONE_K)
188
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)
192  */
193 #define SCALE(x) ((unsigned long) ((x) < 10 * ONE_K \
194                   ? (x) \
195                   : ((x) < 10 * ONE_M \
196                      ? (x) / ONE_K \
197                      : (x) / ONE_M)))
198
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'))
205
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
208    well.  */
209 #define FORMAT_AMOUNT(size) SCALE (size), STAT_LABEL (size)
210
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
213    expansion.  */
214
215 void
216 dump_line_table_statistics (void)
217 {
218   struct linemap_stats s;
219   long total_used_map_size,
220     macro_maps_size,
221     total_allocated_map_size;
222
223   memset (&s, 0, sizeof (s));
224
225   linemap_get_statistics (line_table, &s);
226
227   macro_maps_size = s.macro_maps_used_size
228     + s.macro_maps_locations_size;
229
230   total_allocated_map_size = s.ordinary_maps_allocated_size
231     + s.macro_maps_allocated_size
232     + s.macro_maps_locations_size;
233
234   total_used_map_size = s.ordinary_maps_used_size
235     + s.macro_maps_used_size
236     + s.macro_maps_locations_size;
237
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);
243   fprintf (stderr,
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");
280 }