Make expand_location resolve to locus in main source file
[platform/upstream/gcc.git] / gcc / input.c
1 /* Data and functions related to line maps and input files.
2    Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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
10 version.
11
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
15 for more details.
16
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/>.  */
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
29 location_t input_location;
30
31 struct line_maps *line_table;
32
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.  */
39
40 static expanded_location
41 expand_location_1 (source_location loc,
42                    bool expansion_point_p)
43 {
44   expanded_location xloc;
45   const struct line_map *map;
46
47   loc = linemap_resolve_location (line_table, loc,
48                                   expansion_point_p
49                                   ? LRK_MACRO_EXPANSION_POINT
50                                   : LRK_SPELLING_LOCATION, &map);
51   xloc = linemap_expand_location (line_table, map, loc);
52
53   if (loc <= BUILTINS_LOCATION)
54     xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
55
56   return xloc;
57 }
58
59 /* Reads one line from file into a static buffer.  */
60 static const char *
61 read_line (FILE *file)
62 {
63   static char *string;
64   static size_t string_len;
65   size_t pos = 0;
66   char *ptr;
67
68   if (!string_len)
69     {
70       string_len = 200;
71       string = XNEWVEC (char, string_len);
72     }
73
74   while ((ptr = fgets (string + pos, string_len - pos, file)))
75     {
76       size_t len = strlen (string + pos);
77
78       if (string[pos + len - 1] == '\n')
79         {
80           string[pos + len - 1] = 0;
81           return string;
82         }
83       pos += len;
84       ptr = XNEWVEC (char, string_len * 2);
85       if (ptr)
86         {
87           memcpy (ptr, string, pos);
88           string = ptr;
89           string_len += 2;
90         }
91       else
92         pos = 0;
93     }
94       
95   return pos ? string : NULL;
96 }
97
98 /* Return the physical source line that corresponds to xloc in a
99    buffer that is statically allocated.  The newline is replaced by
100    the null character.  */
101
102 const char *
103 location_get_source_line(expanded_location xloc)
104 {
105   const char *buffer;
106   int lines = 1;
107   FILE *stream = xloc.file ? fopen (xloc.file, "r") : NULL;
108   if (!stream)
109     return NULL;
110
111   while ((buffer = read_line (stream)) && lines < xloc.line)
112     lines++;
113
114   fclose (stream);
115   return buffer;
116 }
117
118 /* Expand the source location LOC into a human readable location.  If
119    LOC is virtual, it resolves to the expansion point of the involved
120    macro.  If LOC resolves to a builtin location, the file name of the
121    readable location is set to the string "<built-in>".  */
122
123 expanded_location
124 expand_location (source_location loc)
125 {
126   return expand_location_1 (loc, /*expansion_point_p=*/true);
127 }
128
129 /* Expand the source location LOC into a human readable location.  If
130    LOC is virtual, it resolves to the expansion location of the
131    relevant macro.  If LOC resolves to a builtin location, the file
132    name of the readable location is set to the string
133    "<built-in>".  */
134
135 expanded_location
136 expand_location_to_spelling_point (source_location loc)
137 {
138   return expand_location_1 (loc, /*expansion_piont_p=*/false);
139 }
140
141
142 #define ONE_K 1024
143 #define ONE_M (ONE_K * ONE_K)
144
145 /* Display a number as an integer multiple of either:
146    - 1024, if said integer is >= to 10 K (in base 2)
147    - 1024 * 1024, if said integer is >= 10 M in (base 2)
148  */
149 #define SCALE(x) ((unsigned long) ((x) < 10 * ONE_K \
150                   ? (x) \
151                   : ((x) < 10 * ONE_M \
152                      ? (x) / ONE_K \
153                      : (x) / ONE_M)))
154
155 /* For a given integer, display either:
156    - the character 'k', if the number is higher than 10 K (in base 2)
157      but strictly lower than 10 M (in base 2)
158    - the character 'M' if the number is higher than 10 M (in base2)
159    - the charcter ' ' if the number is strictly lower  than 10 K  */
160 #define STAT_LABEL(x) ((x) < 10 * ONE_K ? ' ' : ((x) < 10 * ONE_M ? 'k' : 'M'))
161
162 /* Display an integer amount as multiple of 1K or 1M (in base 2).
163    Display the correct unit (either k, M, or ' ') after the amout, as
164    well.  */
165 #define FORMAT_AMOUNT(size) SCALE (size), STAT_LABEL (size)
166
167 /* Dump statistics to stderr about the memory usage of the line_table
168    set of line maps.  This also displays some statistics about macro
169    expansion.  */
170
171 void
172 dump_line_table_statistics (void)
173 {
174   struct linemap_stats s;
175   long total_used_map_size,
176     macro_maps_size,
177     total_allocated_map_size;
178
179   memset (&s, 0, sizeof (s));
180
181   linemap_get_statistics (line_table, &s);
182
183   macro_maps_size = s.macro_maps_used_size
184     + s.macro_maps_locations_size;
185
186   total_allocated_map_size = s.ordinary_maps_allocated_size
187     + s.macro_maps_allocated_size
188     + s.macro_maps_locations_size;
189
190   total_used_map_size = s.ordinary_maps_used_size
191     + s.macro_maps_used_size
192     + s.macro_maps_locations_size;
193
194   fprintf (stderr, "Number of expanded macros:                     %5ld\n",
195            s.num_expanded_macros);
196   if (s.num_expanded_macros != 0)
197     fprintf (stderr, "Average number of tokens per macro expansion:  %5ld\n",
198              s.num_macro_tokens / s.num_expanded_macros);
199   fprintf (stderr,
200            "\nLine Table allocations during the "
201            "compilation process\n");
202   fprintf (stderr, "Number of ordinary maps used:        %5ld%c\n",
203            SCALE (s.num_ordinary_maps_used),
204            STAT_LABEL (s.num_ordinary_maps_used));
205   fprintf (stderr, "Ordinary map used size:              %5ld%c\n",
206            SCALE (s.ordinary_maps_used_size),
207            STAT_LABEL (s.ordinary_maps_used_size));
208   fprintf (stderr, "Number of ordinary maps allocated:   %5ld%c\n",
209            SCALE (s.num_ordinary_maps_allocated),
210            STAT_LABEL (s.num_ordinary_maps_allocated));
211   fprintf (stderr, "Ordinary maps allocated size:        %5ld%c\n",
212            SCALE (s.ordinary_maps_allocated_size),
213            STAT_LABEL (s.ordinary_maps_allocated_size));
214   fprintf (stderr, "Number of macro maps used:           %5ld%c\n",
215            SCALE (s.num_macro_maps_used),
216            STAT_LABEL (s.num_macro_maps_used));
217   fprintf (stderr, "Macro maps used size:                %5ld%c\n",
218            SCALE (s.macro_maps_used_size),
219            STAT_LABEL (s.macro_maps_used_size));
220   fprintf (stderr, "Macro maps locations size:           %5ld%c\n",
221            SCALE (s.macro_maps_locations_size),
222            STAT_LABEL (s.macro_maps_locations_size));
223   fprintf (stderr, "Macro maps size:                     %5ld%c\n",
224            SCALE (macro_maps_size),
225            STAT_LABEL (macro_maps_size));
226   fprintf (stderr, "Duplicated maps locations size:      %5ld%c\n",
227            SCALE (s.duplicated_macro_maps_locations_size),
228            STAT_LABEL (s.duplicated_macro_maps_locations_size));
229   fprintf (stderr, "Total allocated maps size:           %5ld%c\n",
230            SCALE (total_allocated_map_size),
231            STAT_LABEL (total_allocated_map_size));
232   fprintf (stderr, "Total used maps size:                %5ld%c\n",
233            SCALE (total_used_map_size),
234            STAT_LABEL (total_used_map_size));
235   fprintf (stderr, "\n");
236 }