]>
Commit | Line | Data |
---|---|---|
c87b25e6 | 1 | /* Map (unsigned int) keys to (source file, line, column) triples. |
7adcbafe | 2 | Copyright (C) 2001-2022 Free Software Foundation, Inc. |
d82fc108 NB |
3 | |
4 | This program is free software; you can redistribute it and/or modify it | |
5 | under the terms of the GNU General Public License as published by the | |
748086b7 | 6 | Free Software Foundation; either version 3, or (at your option) any |
d82fc108 NB |
7 | later version. |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
748086b7 JJ |
15 | along with this program; see the file COPYING3. If not see |
16 | <http://www.gnu.org/licenses/>. | |
d82fc108 NB |
17 | |
18 | In other words, you are welcome to use, share and improve this program. | |
19 | You are forbidden to forbid anyone else to use, share and improve | |
20 | what you give them. Help stamp out software-hoarding! */ | |
21 | ||
4f4e53dd PB |
22 | #ifndef LIBCPP_LINE_MAP_H |
23 | #define LIBCPP_LINE_MAP_H | |
d82fc108 | 24 | |
5ffeb913 TT |
25 | #ifndef GTY |
26 | #define GTY(x) /* nothing */ | |
27 | #endif | |
28 | ||
846b84fb DM |
29 | /* Both gcc and emacs number source *lines* starting at 1, but |
30 | they have differing conventions for *columns*. | |
31 | ||
32 | GCC uses a 1-based convention for source columns, | |
33 | whereas Emacs's M-x column-number-mode uses a 0-based convention. | |
34 | ||
35 | For example, an error in the initial, left-hand | |
36 | column of source line 3 is reported by GCC as: | |
37 | ||
38 | some-file.c:3:1: error: ...etc... | |
39 | ||
40 | On navigating to the location of that error in Emacs | |
41 | (e.g. via "next-error"), | |
42 | the locus is reported in the Mode Line | |
43 | (assuming M-x column-number-mode) as: | |
44 | ||
45 | some-file.c 10% (3, 0) | |
46 | ||
47 | i.e. "3:1:" in GCC corresponds to "(3, 0)" in Emacs. */ | |
48 | ||
49 | /* The type of line numbers. */ | |
50 | typedef unsigned int linenum_type; | |
51 | ||
200a8e1a DM |
52 | /* A type for doing arithmetic on line numbers. */ |
53 | typedef long long linenum_arith_t; | |
54 | ||
082284da DM |
55 | /* A function for for use by qsort for comparing line numbers. */ |
56 | ||
57 | inline int compare (linenum_type lhs, linenum_type rhs) | |
58 | { | |
200a8e1a | 59 | /* Avoid truncation issues by using linenum_arith_t for the comparison, |
082284da | 60 | and only consider the sign of the result. */ |
200a8e1a | 61 | linenum_arith_t diff = (linenum_arith_t)lhs - (linenum_arith_t)rhs; |
082284da DM |
62 | if (diff) |
63 | return diff > 0 ? 1 : -1; | |
64 | return 0; | |
65 | } | |
66 | ||
24c35f68 | 67 | /* Reason for creating a new line map with linemap_add. */ |
46427374 TT |
68 | enum lc_reason |
69 | { | |
24c35f68 NS |
70 | LC_ENTER = 0, /* Begin #include. */ |
71 | LC_LEAVE, /* Return to including file. */ | |
72 | LC_RENAME, /* Other reason for name change. */ | |
73 | LC_RENAME_VERBATIM, /* Likewise, but "" != stdin. */ | |
74 | LC_ENTER_MACRO, /* Begin macro expansion. */ | |
1f8ac759 | 75 | LC_MODULE, /* A (C++) Module. */ |
46427374 | 76 | /* FIXME: add support for stringize and paste. */ |
42a98b43 | 77 | LC_HWM /* High Water Mark. */ |
46427374 | 78 | }; |
47d89cf3 | 79 | |
620e594b | 80 | /* The typedef "location_t" is a key within the location database, |
ebedc9a3 DM |
81 | identifying a source location or macro expansion, along with range |
82 | information, and (optionally) a pointer for use by gcc. | |
c87b25e6 DM |
83 | |
84 | This key only has meaning in relation to a line_maps instance. Within | |
85 | gcc there is a single line_maps instance: "line_table", declared in | |
86 | gcc/input.h and defined in gcc/input.c. | |
87 | ||
88 | The values of the keys are intended to be internal to libcpp, | |
89 | but for ease-of-understanding the implementation, they are currently | |
90 | assigned as follows: | |
91 | ||
92 | Actual | Value | Meaning | |
93 | -----------+-------------------------------+------------------------------- | |
525ce910 DM |
94 | 0x00000000 | UNKNOWN_LOCATION (gcc/input.h)| Unknown/invalid location. |
95 | -----------+-------------------------------+------------------------------- | |
96 | 0x00000001 | BUILTINS_LOCATION | The location for declarations | |
97 | | (gcc/input.h) | in "<built-in>" | |
c87b25e6 DM |
98 | -----------+-------------------------------+------------------------------- |
99 | 0x00000002 | RESERVED_LOCATION_COUNT | The first location to be | |
100 | | (also | handed out, and the | |
101 | | ordmap[0]->start_location) | first line in ordmap 0 | |
102 | -----------+-------------------------------+------------------------------- | |
103 | | ordmap[1]->start_location | First line in ordmap 1 | |
ebedc9a3 DM |
104 | | ordmap[1]->start_location+32 | First column in that line |
105 | | (assuming range_bits == 5) | | |
106 | | ordmap[1]->start_location+64 | 2nd column in that line | |
107 | | ordmap[1]->start_location+4096| Second line in ordmap 1 | |
108 | | (assuming column_bits == 12) | |
109 | | | |
110 | | Subsequent lines are offset by (1 << column_bits), | |
111 | | e.g. 4096 for 12 bits, with a column value of 0 representing | |
112 | | "the whole line". | |
113 | | | |
114 | | Within a line, the low "range_bits" (typically 5) are used for | |
115 | | storing short ranges, so that there's an offset of | |
116 | | (1 << range_bits) between individual columns within a line, | |
117 | | typically 32. | |
118 | | The low range_bits store the offset of the end point from the | |
119 | | start point, and the start point is found by masking away | |
120 | | the range bits. | |
121 | | | |
122 | | For example: | |
123 | | ordmap[1]->start_location+64 "2nd column in that line" | |
124 | | above means a caret at that location, with a range | |
125 | | starting and finishing at the same place (the range bits | |
126 | | are 0), a range of length 1. | |
127 | | | |
128 | | By contrast: | |
129 | | ordmap[1]->start_location+68 | |
130 | | has range bits 0x4, meaning a caret with a range starting at | |
131 | | that location, but with endpoint 4 columns further on: a range | |
132 | | of length 5. | |
133 | | | |
134 | | Ranges that have caret != start, or have an endpoint too | |
135 | | far away to fit in range_bits are instead stored as ad-hoc | |
136 | | locations. Hence for range_bits == 5 we can compactly store | |
137 | | tokens of length <= 32 without needing to use the ad-hoc | |
138 | | table. | |
139 | | | |
140 | | This packing scheme means we effectively have | |
141 | | (column_bits - range_bits) | |
142 | | of bits for the columns, typically (12 - 5) = 7, for 128 | |
143 | | columns; longer line widths are accomodated by starting a | |
144 | | new ordmap with a higher column_bits. | |
145 | | | |
c87b25e6 DM |
146 | | ordmap[2]->start_location-1 | Final location in ordmap 1 |
147 | -----------+-------------------------------+------------------------------- | |
148 | | ordmap[2]->start_location | First line in ordmap 2 | |
149 | | ordmap[3]->start_location-1 | Final location in ordmap 2 | |
150 | -----------+-------------------------------+------------------------------- | |
151 | | | (etc) | |
152 | -----------+-------------------------------+------------------------------- | |
153 | | ordmap[n-1]->start_location | First line in final ord map | |
154 | | | (etc) | |
155 | | set->highest_location - 1 | Final location in that ordmap | |
156 | -----------+-------------------------------+------------------------------- | |
157 | | set->highest_location | Location of the where the next | |
158 | | | ordinary linemap would start | |
159 | -----------+-------------------------------+------------------------------- | |
160 | | | | |
161 | | VVVVVVVVVVVVVVVVVVVVVVVVVVV | |
162 | | Ordinary maps grow this way | |
163 | | | |
164 | | (unallocated integers) | |
165 | | | |
525ce910 DM |
166 | 0x60000000 | LINE_MAP_MAX_LOCATION_WITH_COLS |
167 | | Beyond this point, ordinary linemaps have 0 bits per column: | |
168 | | each increment of the value corresponds to a new source line. | |
169 | | | |
42a98b43 | 170 | 0x70000000 | LINE_MAP_MAX_LOCATION |
525ce910 DM |
171 | | Beyond the point, we give up on ordinary maps; attempts to |
172 | | create locations in them lead to UNKNOWN_LOCATION (0). | |
173 | | | |
174 | | (unallocated integers) | |
175 | | | |
c87b25e6 DM |
176 | | Macro maps grow this way |
177 | | ^^^^^^^^^^^^^^^^^^^^^^^^ | |
178 | | | | |
179 | -----------+-------------------------------+------------------------------- | |
180 | | LINEMAPS_MACRO_LOWEST_LOCATION| Locations within macro maps | |
181 | | macromap[m-1]->start_location | Start of last macro map | |
182 | | | | |
183 | -----------+-------------------------------+------------------------------- | |
184 | | macromap[m-2]->start_location | Start of penultimate macro map | |
185 | -----------+-------------------------------+------------------------------- | |
186 | | macromap[1]->start_location | Start of macro map 1 | |
187 | -----------+-------------------------------+------------------------------- | |
188 | | macromap[0]->start_location | Start of macro map 0 | |
620e594b | 189 | 0x7fffffff | MAX_LOCATION_T | Also used as a mask for |
525ce910 | 190 | | | accessing the ad-hoc data table |
c87b25e6 | 191 | -----------+-------------------------------+------------------------------- |
525ce910 DM |
192 | 0x80000000 | Start of ad-hoc values; the lower 31 bits are used as an index |
193 | ... | into the line_table->location_adhoc_data_map.data array. | |
c87b25e6 DM |
194 | 0xffffffff | UINT_MAX | |
195 | -----------+-------------------------------+------------------------------- | |
ba4ad400 | 196 | |
ebedc9a3 DM |
197 | Examples of location encoding. |
198 | ||
199 | Packed ranges | |
200 | ============= | |
201 | ||
202 | Consider encoding the location of a token "foo", seen underlined here | |
203 | on line 523, within an ordinary line_map that starts at line 500: | |
204 | ||
205 | 11111111112 | |
206 | 12345678901234567890 | |
207 | 522 | |
208 | 523 return foo + bar; | |
209 | ^~~ | |
210 | 524 | |
211 | ||
212 | The location's caret and start are both at line 523, column 11; the | |
213 | location's finish is on the same line, at column 13 (an offset of 2 | |
214 | columns, for length 3). | |
215 | ||
216 | Line 523 is offset 23 from the starting line of the ordinary line_map. | |
217 | ||
218 | caret == start, and the offset of the finish fits within 5 bits, so | |
219 | this can be stored as a packed range. | |
220 | ||
221 | This is encoded as: | |
222 | ordmap->start | |
223 | + (line_offset << ordmap->m_column_and_range_bits) | |
224 | + (column << ordmap->m_range_bits) | |
225 | + (range_offset); | |
226 | i.e. (for line offset 23, column 11, range offset 2): | |
227 | ordmap->start | |
228 | + (23 << 12) | |
229 | + (11 << 5) | |
230 | + 2; | |
231 | i.e.: | |
232 | ordmap->start + 0x17162 | |
233 | assuming that the line_map uses the default of 7 bits for columns and | |
234 | 5 bits for packed range (giving 12 bits for m_column_and_range_bits). | |
235 | ||
236 | ||
237 | "Pure" locations | |
238 | ================ | |
239 | ||
240 | These are a special case of the above, where | |
241 | caret == start == finish | |
242 | They are stored as packed ranges with offset == 0. | |
243 | For example, the location of the "f" of "foo" could be stored | |
244 | as above, but with range offset 0, giving: | |
245 | ordmap->start | |
246 | + (23 << 12) | |
247 | + (11 << 5) | |
248 | + 0; | |
249 | i.e.: | |
250 | ordmap->start + 0x17160 | |
251 | ||
252 | ||
253 | Unoptimized ranges | |
254 | ================== | |
255 | ||
256 | Consider encoding the location of the binary expression | |
257 | below: | |
258 | ||
259 | 11111111112 | |
260 | 12345678901234567890 | |
a01fc549 | 261 | 522 |
ebedc9a3 DM |
262 | 523 return foo + bar; |
263 | ~~~~^~~~~ | |
a01fc549 | 264 | 524 |
ebedc9a3 DM |
265 | |
266 | The location's caret is at the "+", line 523 column 15, but starts | |
267 | earlier, at the "f" of "foo" at column 11. The finish is at the "r" | |
268 | of "bar" at column 19. | |
269 | ||
270 | This can't be stored as a packed range since start != caret. | |
271 | Hence it is stored as an ad-hoc location e.g. 0x80000003. | |
272 | ||
273 | Stripping off the top bit gives us an index into the ad-hoc | |
274 | lookaside table: | |
275 | ||
276 | line_table->location_adhoc_data_map.data[0x3] | |
277 | ||
278 | from which the caret, start and finish can be looked up, | |
279 | encoded as "pure" locations: | |
280 | ||
281 | start == ordmap->start + (23 << 12) + (11 << 5) | |
282 | == ordmap->start + 0x17160 (as above; the "f" of "foo") | |
283 | ||
284 | caret == ordmap->start + (23 << 12) + (15 << 5) | |
285 | == ordmap->start + 0x171e0 | |
286 | ||
287 | finish == ordmap->start + (23 << 12) + (19 << 5) | |
288 | == ordmap->start + 0x17260 | |
289 | ||
620e594b | 290 | To further see how location_t works in practice, see the |
ebedc9a3 | 291 | worked example in libcpp/location-example.txt. */ |
620e594b | 292 | typedef unsigned int location_t; |
8b82c528 | 293 | |
6df8934f DM |
294 | /* Do not track column numbers higher than this one. As a result, the |
295 | range of column_bits is [12, 18] (or 0 if column numbers are | |
296 | disabled). */ | |
297 | const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12); | |
298 | ||
741d3be5 DM |
299 | /* Do not pack ranges if locations get higher than this. |
300 | If you change this, update: | |
301 | gcc.dg/plugin/location-overflow-test-*.c. */ | |
620e594b | 302 | const location_t LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES = 0x50000000; |
741d3be5 DM |
303 | |
304 | /* Do not track column numbers if locations get higher than this. | |
305 | If you change this, update: | |
306 | gcc.dg/plugin/location-overflow-test-*.c. */ | |
620e594b | 307 | const location_t LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000; |
741d3be5 | 308 | |
42a98b43 | 309 | /* Highest possible source location encoded within an ordinary map. */ |
620e594b | 310 | const location_t LINE_MAP_MAX_LOCATION = 0x70000000; |
42a98b43 | 311 | |
8a645150 DM |
312 | /* A range of source locations. |
313 | ||
314 | Ranges are closed: | |
315 | m_start is the first location within the range, | |
316 | m_finish is the last location within the range. | |
317 | ||
318 | We may need a more compact way to store these, but for now, | |
319 | let's do it the simple way, as a pair. */ | |
320 | struct GTY(()) source_range | |
321 | { | |
620e594b DM |
322 | location_t m_start; |
323 | location_t m_finish; | |
8a645150 | 324 | |
8a645150 DM |
325 | /* We avoid using constructors, since various structs that |
326 | don't yet have constructors will embed instances of | |
327 | source_range. */ | |
328 | ||
620e594b DM |
329 | /* Make a source_range from a location_t. */ |
330 | static source_range from_location (location_t loc) | |
8a645150 DM |
331 | { |
332 | source_range result; | |
333 | result.m_start = loc; | |
334 | result.m_finish = loc; | |
335 | return result; | |
336 | } | |
a87a86e1 | 337 | |
620e594b DM |
338 | /* Make a source_range from a pair of location_t. */ |
339 | static source_range from_locations (location_t start, | |
340 | location_t finish) | |
d672cded DM |
341 | { |
342 | source_range result; | |
343 | result.m_start = start; | |
344 | result.m_finish = finish; | |
345 | return result; | |
346 | } | |
8a645150 DM |
347 | }; |
348 | ||
5ffeb913 TT |
349 | /* Memory allocation function typedef. Works like xrealloc. */ |
350 | typedef void *(*line_map_realloc) (void *, size_t); | |
351 | ||
b9bd6f74 TT |
352 | /* Memory allocator function that returns the actual allocated size, |
353 | for a given requested allocation. */ | |
354 | typedef size_t (*line_map_round_alloc_size_func) (size_t); | |
355 | ||
0e50b624 DM |
356 | /* A line_map encodes a sequence of locations. |
357 | There are two kinds of maps. Ordinary maps and macro expansion | |
358 | maps, a.k.a macro maps. | |
359 | ||
360 | A macro map encodes source locations of tokens that are part of a | |
361 | macro replacement-list, at a macro expansion point. E.g, in: | |
362 | ||
363 | #define PLUS(A,B) A + B | |
364 | ||
365 | No macro map is going to be created there, because we are not at a | |
366 | macro expansion point. We are at a macro /definition/ point. So the | |
367 | locations of the tokens of the macro replacement-list (i.e, A + B) | |
368 | will be locations in an ordinary map, not a macro map. | |
369 | ||
370 | On the other hand, if we later do: | |
371 | ||
372 | int a = PLUS (1,2); | |
373 | ||
374 | The invocation of PLUS here is a macro expansion. So we are at a | |
375 | macro expansion point. The preprocessor expands PLUS (1,2) and | |
376 | replaces it with the tokens of its replacement-list: 1 + 2. A macro | |
377 | map is going to be created to hold (or rather to map, haha ...) the | |
378 | locations of the tokens 1, + and 2. The macro map also records the | |
379 | location of the expansion point of PLUS. That location is mapped in | |
380 | the map that is active right before the location of the invocation | |
381 | of PLUS. */ | |
42a98b43 NS |
382 | |
383 | /* This contains GTY mark-up to support precompiled headers. | |
384 | line_map is an abstract class, only derived objects exist. */ | |
385 | struct GTY((tag ("0"), desc ("MAP_ORDINARY_P (&%h) ? 1 : 2"))) line_map { | |
620e594b | 386 | location_t start_location; |
0e50b624 | 387 | |
42a98b43 | 388 | /* Size and alignment is (usually) 4 bytes. */ |
0e50b624 DM |
389 | }; |
390 | ||
46427374 TT |
391 | /* An ordinary line map encodes physical source locations. Those |
392 | physical source locations are called "spelling locations". | |
393 | ||
394 | Physical source file TO_FILE at line TO_LINE at column 0 is represented | |
12f9df4e | 395 | by the logical START_LOCATION. TO_LINE+L at column C is represented by |
ebedc9a3 DM |
396 | START_LOCATION+(L*(1<<m_column_and_range_bits))+(C*1<<m_range_bits), as |
397 | long as C<(1<<effective range bits), and the result_location is less than | |
398 | the next line_map's start_location. | |
12f9df4e PB |
399 | (The top line is line 1 and the leftmost column is column 1; line/column 0 |
400 | means "entire file/line" or "unknown line/column" or "not applicable".) | |
46427374 | 401 | |
620e594b | 402 | The highest possible source location is MAX_LOCATION_T. */ |
0e50b624 | 403 | struct GTY((tag ("1"))) line_map_ordinary : public line_map { |
42a98b43 | 404 | /* Base class is 4 bytes. */ |
46427374 | 405 | |
42a98b43 NS |
406 | /* 4 bytes of integers, each 1 byte for easy extraction/insertion. */ |
407 | ||
408 | /* The reason for creation of this line map. */ | |
409 | ENUM_BITFIELD (lc_reason) reason : 8; | |
46427374 TT |
410 | |
411 | /* SYSP is one for a system header, two for a C system header file | |
412 | that therefore needs to be extern "C" protected in C++, and zero | |
413 | otherwise. This field isn't really needed now that it's in | |
414 | cpp_buffer. */ | |
47d89cf3 | 415 | unsigned char sysp; |
46427374 | 416 | |
620e594b | 417 | /* Number of the low-order location_t bits used for column numbers |
ebedc9a3 DM |
418 | and ranges. */ |
419 | unsigned int m_column_and_range_bits : 8; | |
420 | ||
421 | /* Number of the low-order "column" bits used for storing short ranges | |
422 | inline, rather than in the ad-hoc table. | |
423 | MSB LSB | |
424 | 31 0 | |
425 | +-------------------------+-------------------------------------------+ | |
426 | | |<---map->column_and_range_bits (e.g. 12)-->| | |
427 | +-------------------------+-----------------------+-------------------+ | |
428 | | | column_and_range_bits | map->range_bits | | |
429 | | | - range_bits | | | |
430 | +-------------------------+-----------------------+-------------------+ | |
431 | | row bits | effective column bits | short range bits | | |
432 | | | (e.g. 7) | (e.g. 5) | | |
433 | +-------------------------+-----------------------+-------------------+ */ | |
434 | unsigned int m_range_bits : 8; | |
42a98b43 NS |
435 | |
436 | /* Pointer alignment boundary on both 32 and 64-bit systems. */ | |
437 | ||
438 | const char *to_file; | |
439 | linenum_type to_line; | |
440 | ||
f10a9135 NS |
441 | /* Location from whence this line map was included. For regular |
442 | #includes, this location will be the last location of a map. For | |
1f8ac759 NS |
443 | outermost file, this is 0. For modules it could be anywhere |
444 | within a map. */ | |
620e594b | 445 | location_t included_from; |
42a98b43 NS |
446 | |
447 | /* Size is 20 or 24 bytes, no padding */ | |
d82fc108 NB |
448 | }; |
449 | ||
46427374 TT |
450 | /* This is the highest possible source location encoded within an |
451 | ordinary or macro map. */ | |
620e594b | 452 | const location_t MAX_LOCATION_T = 0x7FFFFFFF; |
46427374 TT |
453 | |
454 | struct cpp_hashnode; | |
455 | ||
456 | /* A macro line map encodes location of tokens coming from a macro | |
457 | expansion. | |
458 | ||
46427374 TT |
459 | The offset from START_LOCATION is used to index into |
460 | MACRO_LOCATIONS; this holds the original location of the token. */ | |
0e50b624 | 461 | struct GTY((tag ("2"))) line_map_macro : public line_map { |
42a98b43 | 462 | /* Base is 4 bytes. */ |
46427374 TT |
463 | |
464 | /* The number of tokens inside the replacement-list of MACRO. */ | |
465 | unsigned int n_tokens; | |
466 | ||
42a98b43 NS |
467 | /* Pointer alignment boundary. */ |
468 | ||
469 | /* The cpp macro whose expansion gave birth to this macro map. */ | |
470 | struct cpp_hashnode * | |
471 | GTY ((nested_ptr (union tree_node, | |
472 | "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", | |
473 | "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"))) | |
474 | macro; | |
475 | ||
46427374 TT |
476 | /* This array of location is actually an array of pairs of |
477 | locations. The elements inside it thus look like: | |
478 | ||
479 | x0,y0, x1,y1, x2,y2, ...., xn,yn. | |
480 | ||
481 | where n == n_tokens; | |
482 | ||
483 | Remember that these xI,yI are collected when libcpp is about to | |
484 | expand a given macro. | |
485 | ||
486 | yI is the location in the macro definition, either of the token | |
487 | itself or of a macro parameter that it replaces. | |
488 | ||
489 | Imagine this: | |
490 | ||
491 | #define PLUS(A, B) A + B <--- #1 | |
492 | ||
493 | int a = PLUS (1,2); <--- #2 | |
494 | ||
495 | There is a macro map for the expansion of PLUS in #2. PLUS is | |
496 | expanded into its expansion-list. The expansion-list is the | |
497 | replacement-list of PLUS where the macro parameters are replaced | |
498 | with their arguments. So the replacement-list of PLUS is made of | |
499 | the tokens: | |
500 | ||
501 | A, +, B | |
502 | ||
503 | and the expansion-list is made of the tokens: | |
504 | ||
505 | 1, +, 2 | |
506 | ||
507 | Let's consider the case of token "+". Its y1 [yI for I == 1] is | |
508 | its spelling location in #1. | |
509 | ||
510 | y0 (thus for token "1") is the spelling location of A in #1. | |
511 | ||
512 | And y2 (of token "2") is the spelling location of B in #1. | |
513 | ||
514 | When the token is /not/ an argument for a macro, xI is the same | |
515 | location as yI. Otherwise, xI is the location of the token | |
516 | outside this macro expansion. If this macro was expanded from | |
517 | another macro expansion, xI is a virtual location representing | |
518 | the token in that macro expansion; otherwise, it is the spelling | |
519 | location of the token. | |
520 | ||
521 | Note that a virtual location is a location returned by | |
522 | linemap_add_macro_token. It encodes the relevant locations (x,y | |
7d9641cc | 523 | pairs) of that token across the macro expansions from which it |
46427374 TT |
524 | (the token) might come from. |
525 | ||
526 | In the example above x1 (for token "+") is going to be the same | |
527 | as y1. x0 is the spelling location for the argument token "1", | |
528 | and x2 is the spelling location for the argument token "2". */ | |
620e594b | 529 | location_t * GTY((atomic)) macro_locations; |
46427374 TT |
530 | |
531 | /* This is the location of the expansion point of the current macro | |
532 | map. It's the location of the macro name. That location is held | |
533 | by the map that was current right before the current one. It | |
534 | could have been either a macro or an ordinary map, depending on | |
535 | if we are in a nested expansion context not. */ | |
620e594b | 536 | location_t expansion; |
42a98b43 NS |
537 | |
538 | /* Size is 20 or 32 (4 bytes padding on 64-bit). */ | |
46427374 TT |
539 | }; |
540 | ||
22d66382 | 541 | #if CHECKING_P && (GCC_VERSION >= 2007) |
60c12095 DM |
542 | |
543 | /* Assertion macro to be used in line-map code. */ | |
544 | #define linemap_assert(EXPR) \ | |
545 | do { \ | |
546 | if (! (EXPR)) \ | |
547 | abort (); \ | |
548 | } while (0) | |
549 | ||
550 | /* Assert that becomes a conditional expression when checking is disabled at | |
551 | compilation time. Use this for conditions that should not happen but if | |
552 | they happen, it is better to handle them gracefully rather than crash | |
553 | randomly later. | |
554 | Usage: | |
555 | ||
556 | if (linemap_assert_fails(EXPR)) handle_error(); */ | |
557 | #define linemap_assert_fails(EXPR) __extension__ \ | |
558 | ({linemap_assert (EXPR); false;}) | |
559 | ||
60c12095 DM |
560 | #else |
561 | /* Include EXPR, so that unused variable warnings do not occur. */ | |
562 | #define linemap_assert(EXPR) ((void)(0 && (EXPR))) | |
563 | #define linemap_assert_fails(EXPR) (! (EXPR)) | |
60c12095 DM |
564 | #endif |
565 | ||
11743148 | 566 | /* Get whether location LOC is an ordinary location. */ |
87bacc2b NS |
567 | |
568 | inline bool | |
620e594b | 569 | IS_ORDINARY_LOC (location_t loc) |
87bacc2b NS |
570 | { |
571 | return loc < LINE_MAP_MAX_LOCATION; | |
572 | } | |
573 | ||
11743148 EB |
574 | /* Get whether location LOC is an ad-hoc location. */ |
575 | ||
87bacc2b | 576 | inline bool |
620e594b | 577 | IS_ADHOC_LOC (location_t loc) |
87bacc2b | 578 | { |
620e594b | 579 | return loc > MAX_LOCATION_T; |
87bacc2b NS |
580 | } |
581 | ||
42a98b43 NS |
582 | /* Categorize line map kinds. */ |
583 | ||
584 | inline bool | |
585 | MAP_ORDINARY_P (const line_map *map) | |
586 | { | |
87bacc2b | 587 | return IS_ORDINARY_LOC (map->start_location); |
42a98b43 NS |
588 | } |
589 | ||
60c12095 DM |
590 | /* Return TRUE if MAP encodes locations coming from a macro |
591 | replacement-list at macro expansion point. */ | |
592 | bool | |
99b1c316 | 593 | linemap_macro_expansion_map_p (const line_map *); |
60c12095 | 594 | |
0501dbd9 | 595 | /* Assert that MAP encodes locations of tokens that are not part of |
0e50b624 DM |
596 | the replacement-list of a macro expansion, downcasting from |
597 | line_map * to line_map_ordinary *. */ | |
598 | ||
599 | inline line_map_ordinary * | |
99b1c316 | 600 | linemap_check_ordinary (line_map *map) |
0501dbd9 | 601 | { |
42a98b43 | 602 | linemap_assert (MAP_ORDINARY_P (map)); |
0e50b624 | 603 | return (line_map_ordinary *)map; |
0501dbd9 DM |
604 | } |
605 | ||
606 | /* Assert that MAP encodes locations of tokens that are not part of | |
0e50b624 DM |
607 | the replacement-list of a macro expansion, downcasting from |
608 | const line_map * to const line_map_ordinary *. */ | |
0501dbd9 | 609 | |
0e50b624 | 610 | inline const line_map_ordinary * |
99b1c316 | 611 | linemap_check_ordinary (const line_map *map) |
0501dbd9 | 612 | { |
42a98b43 | 613 | linemap_assert (MAP_ORDINARY_P (map)); |
0e50b624 DM |
614 | return (const line_map_ordinary *)map; |
615 | } | |
616 | ||
617 | /* Assert that MAP is a macro expansion and downcast to the appropriate | |
618 | subclass. */ | |
619 | ||
620 | inline line_map_macro *linemap_check_macro (line_map *map) | |
621 | { | |
42a98b43 | 622 | linemap_assert (!MAP_ORDINARY_P (map)); |
0e50b624 DM |
623 | return (line_map_macro *)map; |
624 | } | |
625 | ||
626 | /* Assert that MAP is a macro expansion and downcast to the appropriate | |
627 | subclass. */ | |
628 | ||
629 | inline const line_map_macro * | |
630 | linemap_check_macro (const line_map *map) | |
631 | { | |
42a98b43 | 632 | linemap_assert (!MAP_ORDINARY_P (map)); |
0e50b624 | 633 | return (const line_map_macro *)map; |
0501dbd9 DM |
634 | } |
635 | ||
c819ed29 | 636 | /* Read the start location of MAP. */ |
0501dbd9 | 637 | |
620e594b | 638 | inline location_t |
0501dbd9 DM |
639 | MAP_START_LOCATION (const line_map *map) |
640 | { | |
641 | return map->start_location; | |
642 | } | |
643 | ||
0501dbd9 DM |
644 | /* Get the starting line number of ordinary map MAP. */ |
645 | ||
646 | inline linenum_type | |
0e50b624 | 647 | ORDINARY_MAP_STARTING_LINE_NUMBER (const line_map_ordinary *ord_map) |
0501dbd9 | 648 | { |
0e50b624 | 649 | return ord_map->to_line; |
0501dbd9 DM |
650 | } |
651 | ||
0501dbd9 DM |
652 | /* Return a positive value if map encodes locations from a system |
653 | header, 0 otherwise. Returns 1 if ordinary map MAP encodes locations | |
654 | in a system header and 2 if it encodes locations in a C system header | |
655 | that therefore needs to be extern "C" protected in C++. */ | |
656 | ||
657 | inline unsigned char | |
0e50b624 | 658 | ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map) |
0501dbd9 | 659 | { |
0e50b624 | 660 | return ord_map->sysp; |
0501dbd9 DM |
661 | } |
662 | ||
1f8ac759 NS |
663 | /* TRUE if this line map is for a module (not a source file). */ |
664 | ||
665 | inline bool | |
666 | MAP_MODULE_P (const line_map *map) | |
667 | { | |
668 | return (MAP_ORDINARY_P (map) | |
669 | && linemap_check_ordinary (map)->reason == LC_MODULE); | |
670 | } | |
671 | ||
0501dbd9 DM |
672 | /* Get the filename of ordinary map MAP. */ |
673 | ||
674 | inline const char * | |
0e50b624 | 675 | ORDINARY_MAP_FILE_NAME (const line_map_ordinary *ord_map) |
0501dbd9 | 676 | { |
0e50b624 | 677 | return ord_map->to_file; |
0501dbd9 DM |
678 | } |
679 | ||
0501dbd9 DM |
680 | /* Get the cpp macro whose expansion gave birth to macro map MAP. */ |
681 | ||
682 | inline cpp_hashnode * | |
0e50b624 | 683 | MACRO_MAP_MACRO (const line_map_macro *macro_map) |
0501dbd9 | 684 | { |
0e50b624 | 685 | return macro_map->macro; |
0501dbd9 | 686 | } |
46427374 | 687 | |
0501dbd9 DM |
688 | /* Get the number of tokens inside the replacement-list of the macro |
689 | that led to macro map MAP. */ | |
46427374 | 690 | |
0501dbd9 | 691 | inline unsigned int |
0e50b624 | 692 | MACRO_MAP_NUM_MACRO_TOKENS (const line_map_macro *macro_map) |
0501dbd9 | 693 | { |
0e50b624 | 694 | return macro_map->n_tokens; |
0501dbd9 | 695 | } |
46427374 | 696 | |
0501dbd9 DM |
697 | /* Get the array of pairs of locations within macro map MAP. |
698 | See the declaration of line_map_macro for more information. */ | |
46427374 | 699 | |
620e594b | 700 | inline location_t * |
0e50b624 | 701 | MACRO_MAP_LOCATIONS (const line_map_macro *macro_map) |
0501dbd9 | 702 | { |
0e50b624 | 703 | return macro_map->macro_locations; |
0501dbd9 | 704 | } |
46427374 | 705 | |
0501dbd9 DM |
706 | /* Get the location of the expansion point of the macro map MAP. */ |
707 | ||
620e594b | 708 | inline location_t |
0e50b624 | 709 | MACRO_MAP_EXPANSION_POINT_LOCATION (const line_map_macro *macro_map) |
0501dbd9 | 710 | { |
0e50b624 | 711 | return macro_map->expansion; |
0501dbd9 DM |
712 | } |
713 | ||
46427374 TT |
714 | /* The abstraction of a set of location maps. There can be several |
715 | types of location maps. This abstraction contains the attributes | |
0e50b624 DM |
716 | that are independent from the type of the map. |
717 | ||
718 | Essentially this is just a vector of T_linemap_subclass, | |
719 | which can only ever grow in size. */ | |
720 | ||
721 | struct GTY(()) maps_info_ordinary { | |
722 | /* This array contains the "ordinary" line maps, for all | |
723 | events other than macro expansion | |
724 | (e.g. when a new preprocessing unit starts or ends). */ | |
725 | line_map_ordinary * GTY ((length ("%h.used"))) maps; | |
726 | ||
727 | /* The total number of allocated maps. */ | |
728 | unsigned int allocated; | |
729 | ||
730 | /* The number of elements used in maps. This number is smaller | |
731 | or equal to ALLOCATED. */ | |
732 | unsigned int used; | |
733 | ||
9158f0ba | 734 | mutable unsigned int cache; |
0e50b624 DM |
735 | }; |
736 | ||
737 | struct GTY(()) maps_info_macro { | |
738 | /* This array contains the macro line maps. | |
739 | A macro line map is created whenever a macro expansion occurs. */ | |
740 | line_map_macro * GTY ((length ("%h.used"))) maps; | |
46427374 TT |
741 | |
742 | /* The total number of allocated maps. */ | |
d82fc108 | 743 | unsigned int allocated; |
46427374 TT |
744 | |
745 | /* The number of elements used in maps. This number is smaller | |
746 | or equal to ALLOCATED. */ | |
d82fc108 | 747 | unsigned int used; |
fde84349 | 748 | |
9158f0ba | 749 | mutable unsigned int cache; |
46427374 TT |
750 | }; |
751 | ||
ebedc9a3 DM |
752 | /* Data structure to associate a source_range together with an arbitrary |
753 | data pointer with a source location. */ | |
52187008 | 754 | struct GTY(()) location_adhoc_data { |
620e594b | 755 | location_t locus; |
ebedc9a3 | 756 | source_range src_range; |
52187008 | 757 | void * GTY((skip)) data; |
5368224f DC |
758 | }; |
759 | ||
760 | struct htab; | |
761 | ||
762 | /* The following data structure encodes a location with some adhoc data | |
763 | and maps it to a new unsigned integer (called an adhoc location) | |
764 | that replaces the original location to represent the mapping. | |
765 | ||
766 | The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the | |
767 | highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as | |
768 | the original location. Once identified as the adhoc_loc, the lower 31 | |
769 | bits of the integer is used to index the location_adhoc_data array, | |
770 | in which the locus and associated data is stored. */ | |
771 | ||
52187008 DC |
772 | struct GTY(()) location_adhoc_data_map { |
773 | struct htab * GTY((skip)) htab; | |
620e594b | 774 | location_t curr_loc; |
5368224f | 775 | unsigned int allocated; |
52187008 | 776 | struct location_adhoc_data GTY((length ("%h.allocated"))) *data; |
5368224f DC |
777 | }; |
778 | ||
46427374 | 779 | /* A set of chronological line_map structures. */ |
6c1dae73 MS |
780 | class GTY(()) line_maps { |
781 | public: | |
2be1b796 DM |
782 | |
783 | ~line_maps (); | |
46427374 | 784 | |
0e50b624 | 785 | maps_info_ordinary info_ordinary; |
46427374 | 786 | |
0e50b624 | 787 | maps_info_macro info_macro; |
9132fbb7 | 788 | |
d8693c6f NB |
789 | /* Depth of the include stack, including the current file. */ |
790 | unsigned int depth; | |
791 | ||
5993019d NB |
792 | /* If true, prints an include trace a la -H. */ |
793 | bool trace_includes; | |
12f9df4e | 794 | |
620e594b DM |
795 | /* Highest location_t "given out". */ |
796 | location_t highest_location; | |
12f9df4e | 797 | |
620e594b DM |
798 | /* Start of line of highest location_t "given out". */ |
799 | location_t highest_line; | |
500bee0a | 800 | |
12f9df4e | 801 | /* The maximum column number we can quickly allocate. Higher numbers |
9ac97460 | 802 | may require allocating a new line_map. */ |
12f9df4e | 803 | unsigned int max_column_hint; |
5ffeb913 | 804 | |
24c35f68 | 805 | /* The allocator to use when resizing 'maps', defaults to xrealloc. */ |
fe7c3ecf | 806 | line_map_realloc GTY((callback)) reallocator; |
b9bd6f74 TT |
807 | |
808 | /* The allocators' function used to know the actual size it | |
809 | allocated, for a certain allocation size requested. */ | |
fe7c3ecf | 810 | line_map_round_alloc_size_func GTY((callback)) round_alloc_size; |
5368224f | 811 | |
52187008 | 812 | struct location_adhoc_data_map location_adhoc_data_map; |
c468587a DS |
813 | |
814 | /* The special location value that is used as spelling location for | |
815 | built-in tokens. */ | |
620e594b | 816 | location_t builtin_location; |
c3388e62 DM |
817 | |
818 | /* True if we've seen a #line or # 44 "file" directive. */ | |
819 | bool seen_line_directive; | |
ebedc9a3 DM |
820 | |
821 | /* The default value of range_bits in ordinary line maps. */ | |
822 | unsigned int default_range_bits; | |
823 | ||
824 | unsigned int num_optimized_ranges; | |
825 | unsigned int num_unoptimized_ranges; | |
d82fc108 NB |
826 | }; |
827 | ||
46427374 TT |
828 | /* Returns the number of allocated maps so far. MAP_KIND shall be TRUE |
829 | if we are interested in macro maps, FALSE otherwise. */ | |
0501dbd9 DM |
830 | inline unsigned int |
831 | LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind) | |
832 | { | |
0e50b624 DM |
833 | if (map_kind) |
834 | return set->info_macro.allocated; | |
835 | else | |
836 | return set->info_ordinary.allocated; | |
0501dbd9 DM |
837 | } |
838 | ||
839 | /* As above, but by reference (e.g. as an lvalue). */ | |
840 | ||
841 | inline unsigned int & | |
842 | LINEMAPS_ALLOCATED (line_maps *set, bool map_kind) | |
843 | { | |
0e50b624 DM |
844 | if (map_kind) |
845 | return set->info_macro.allocated; | |
846 | else | |
847 | return set->info_ordinary.allocated; | |
0501dbd9 | 848 | } |
46427374 TT |
849 | |
850 | /* Returns the number of used maps so far. MAP_KIND shall be TRUE if | |
851 | we are interested in macro maps, FALSE otherwise.*/ | |
0501dbd9 DM |
852 | inline unsigned int |
853 | LINEMAPS_USED (const line_maps *set, bool map_kind) | |
854 | { | |
0e50b624 DM |
855 | if (map_kind) |
856 | return set->info_macro.used; | |
857 | else | |
858 | return set->info_ordinary.used; | |
0501dbd9 DM |
859 | } |
860 | ||
861 | /* As above, but by reference (e.g. as an lvalue). */ | |
862 | ||
863 | inline unsigned int & | |
864 | LINEMAPS_USED (line_maps *set, bool map_kind) | |
865 | { | |
0e50b624 DM |
866 | if (map_kind) |
867 | return set->info_macro.used; | |
868 | else | |
869 | return set->info_ordinary.used; | |
0501dbd9 | 870 | } |
46427374 TT |
871 | |
872 | /* Returns the index of the last map that was looked up with | |
873 | linemap_lookup. MAP_KIND shall be TRUE if we are interested in | |
874 | macro maps, FALSE otherwise. */ | |
0501dbd9 | 875 | inline unsigned int & |
9158f0ba | 876 | LINEMAPS_CACHE (const line_maps *set, bool map_kind) |
0501dbd9 | 877 | { |
0e50b624 DM |
878 | if (map_kind) |
879 | return set->info_macro.cache; | |
880 | else | |
881 | return set->info_ordinary.cache; | |
0501dbd9 | 882 | } |
46427374 TT |
883 | |
884 | /* Return the map at a given index. */ | |
0501dbd9 DM |
885 | inline line_map * |
886 | LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index) | |
887 | { | |
0e50b624 DM |
888 | if (map_kind) |
889 | return &set->info_macro.maps[index]; | |
890 | else | |
891 | return &set->info_ordinary.maps[index]; | |
0501dbd9 | 892 | } |
46427374 TT |
893 | |
894 | /* Returns the last map used in the line table SET. MAP_KIND | |
895 | shall be TRUE if we are interested in macro maps, FALSE | |
896 | otherwise.*/ | |
0501dbd9 DM |
897 | inline line_map * |
898 | LINEMAPS_LAST_MAP (const line_maps *set, bool map_kind) | |
899 | { | |
900 | return LINEMAPS_MAP_AT (set, map_kind, | |
901 | LINEMAPS_USED (set, map_kind) - 1); | |
902 | } | |
46427374 TT |
903 | |
904 | /* Returns the last map that was allocated in the line table SET. | |
905 | MAP_KIND shall be TRUE if we are interested in macro maps, FALSE | |
906 | otherwise.*/ | |
0501dbd9 DM |
907 | inline line_map * |
908 | LINEMAPS_LAST_ALLOCATED_MAP (const line_maps *set, bool map_kind) | |
909 | { | |
910 | return LINEMAPS_MAP_AT (set, map_kind, | |
911 | LINEMAPS_ALLOCATED (set, map_kind) - 1); | |
912 | } | |
46427374 TT |
913 | |
914 | /* Returns a pointer to the memory region where ordinary maps are | |
915 | allocated in the line table SET. */ | |
0e50b624 | 916 | inline line_map_ordinary * |
0501dbd9 DM |
917 | LINEMAPS_ORDINARY_MAPS (const line_maps *set) |
918 | { | |
0e50b624 | 919 | return set->info_ordinary.maps; |
0501dbd9 | 920 | } |
46427374 TT |
921 | |
922 | /* Returns the INDEXth ordinary map. */ | |
0e50b624 | 923 | inline line_map_ordinary * |
0501dbd9 DM |
924 | LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, int index) |
925 | { | |
9158f0ba NS |
926 | linemap_assert (index >= 0 |
927 | && (unsigned int)index < LINEMAPS_USED (set, false)); | |
928 | return (line_map_ordinary *)LINEMAPS_MAP_AT (set, false, index); | |
0501dbd9 | 929 | } |
46427374 TT |
930 | |
931 | /* Return the number of ordinary maps allocated in the line table | |
932 | SET. */ | |
0501dbd9 DM |
933 | inline unsigned int |
934 | LINEMAPS_ORDINARY_ALLOCATED (const line_maps *set) | |
935 | { | |
936 | return LINEMAPS_ALLOCATED (set, false); | |
937 | } | |
46427374 TT |
938 | |
939 | /* Return the number of ordinary maps used in the line table SET. */ | |
0501dbd9 DM |
940 | inline unsigned int |
941 | LINEMAPS_ORDINARY_USED (const line_maps *set) | |
942 | { | |
943 | return LINEMAPS_USED (set, false); | |
944 | } | |
46427374 TT |
945 | |
946 | /* Return the index of the last ordinary map that was looked up with | |
947 | linemap_lookup. */ | |
0501dbd9 | 948 | inline unsigned int & |
9158f0ba | 949 | LINEMAPS_ORDINARY_CACHE (const line_maps *set) |
0501dbd9 DM |
950 | { |
951 | return LINEMAPS_CACHE (set, false); | |
952 | } | |
46427374 TT |
953 | |
954 | /* Returns a pointer to the last ordinary map used in the line table | |
955 | SET. */ | |
0e50b624 | 956 | inline line_map_ordinary * |
0501dbd9 DM |
957 | LINEMAPS_LAST_ORDINARY_MAP (const line_maps *set) |
958 | { | |
0e50b624 | 959 | return (line_map_ordinary *)LINEMAPS_LAST_MAP (set, false); |
0501dbd9 | 960 | } |
46427374 TT |
961 | |
962 | /* Returns a pointer to the last ordinary map allocated the line table | |
963 | SET. */ | |
0e50b624 | 964 | inline line_map_ordinary * |
0501dbd9 DM |
965 | LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP (const line_maps *set) |
966 | { | |
0e50b624 | 967 | return (line_map_ordinary *)LINEMAPS_LAST_ALLOCATED_MAP (set, false); |
0501dbd9 | 968 | } |
46427374 | 969 | |
7d9641cc | 970 | /* Returns a pointer to the beginning of the region where macro maps |
5764ee3c | 971 | are allocated. */ |
0e50b624 | 972 | inline line_map_macro * |
0501dbd9 DM |
973 | LINEMAPS_MACRO_MAPS (const line_maps *set) |
974 | { | |
0e50b624 | 975 | return set->info_macro.maps; |
0501dbd9 | 976 | } |
46427374 TT |
977 | |
978 | /* Returns the INDEXth macro map. */ | |
0e50b624 | 979 | inline line_map_macro * |
0501dbd9 DM |
980 | LINEMAPS_MACRO_MAP_AT (const line_maps *set, int index) |
981 | { | |
9158f0ba NS |
982 | linemap_assert (index >= 0 |
983 | && (unsigned int)index < LINEMAPS_USED (set, true)); | |
984 | return (line_map_macro *)LINEMAPS_MAP_AT (set, true, index); | |
0501dbd9 | 985 | } |
46427374 TT |
986 | |
987 | /* Returns the number of macro maps that were allocated in the line | |
988 | table SET. */ | |
0501dbd9 DM |
989 | inline unsigned int |
990 | LINEMAPS_MACRO_ALLOCATED (const line_maps *set) | |
991 | { | |
992 | return LINEMAPS_ALLOCATED (set, true); | |
993 | } | |
46427374 TT |
994 | |
995 | /* Returns the number of macro maps used in the line table SET. */ | |
0501dbd9 DM |
996 | inline unsigned int |
997 | LINEMAPS_MACRO_USED (const line_maps *set) | |
998 | { | |
999 | return LINEMAPS_USED (set, true); | |
1000 | } | |
46427374 | 1001 | |
9158f0ba | 1002 | /* Return the index of the last macro map that was looked up with |
46427374 | 1003 | linemap_lookup. */ |
0501dbd9 | 1004 | inline unsigned int & |
9158f0ba | 1005 | LINEMAPS_MACRO_CACHE (const line_maps *set) |
0501dbd9 DM |
1006 | { |
1007 | return LINEMAPS_CACHE (set, true); | |
1008 | } | |
46427374 TT |
1009 | |
1010 | /* Returns the last macro map used in the line table SET. */ | |
0e50b624 | 1011 | inline line_map_macro * |
0501dbd9 DM |
1012 | LINEMAPS_LAST_MACRO_MAP (const line_maps *set) |
1013 | { | |
0e50b624 | 1014 | return (line_map_macro *)LINEMAPS_LAST_MAP (set, true); |
0501dbd9 DM |
1015 | } |
1016 | ||
1017 | /* Returns the lowest location [of a token resulting from macro | |
1018 | expansion] encoded in this line table. */ | |
620e594b | 1019 | inline location_t |
0501dbd9 DM |
1020 | LINEMAPS_MACRO_LOWEST_LOCATION (const line_maps *set) |
1021 | { | |
1022 | return LINEMAPS_MACRO_USED (set) | |
1023 | ? MAP_START_LOCATION (LINEMAPS_LAST_MACRO_MAP (set)) | |
620e594b | 1024 | : MAX_LOCATION_T + 1; |
0501dbd9 | 1025 | } |
46427374 TT |
1026 | |
1027 | /* Returns the last macro map allocated in the line table SET. */ | |
0e50b624 | 1028 | inline line_map_macro * |
0501dbd9 DM |
1029 | LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set) |
1030 | { | |
0e50b624 | 1031 | return (line_map_macro *)LINEMAPS_LAST_ALLOCATED_MAP (set, true); |
0501dbd9 | 1032 | } |
46427374 | 1033 | |
7cf3f604 NS |
1034 | extern location_t get_combined_adhoc_loc (line_maps *, location_t, |
1035 | source_range, void *); | |
99b1c316 MS |
1036 | extern void *get_data_from_adhoc_loc (const line_maps *, location_t); |
1037 | extern location_t get_location_from_adhoc_loc (const line_maps *, | |
7cf3f604 | 1038 | location_t); |
5368224f | 1039 | |
620e594b | 1040 | extern source_range get_range_from_loc (line_maps *set, location_t loc); |
ebedc9a3 | 1041 | |
ebedc9a3 DM |
1042 | /* Get whether location LOC is a "pure" location, or |
1043 | whether it is an ad-hoc location, or embeds range information. */ | |
1044 | ||
1045 | bool | |
620e594b | 1046 | pure_location_p (line_maps *set, location_t loc); |
ebedc9a3 | 1047 | |
2aa51413 DM |
1048 | /* Given location LOC within SET, strip away any packed range information |
1049 | or ad-hoc information. */ | |
1050 | ||
7cf3f604 | 1051 | extern location_t get_pure_location (line_maps *set, location_t loc); |
2aa51413 | 1052 | |
0501dbd9 DM |
1053 | /* Combine LOC and BLOCK, giving a combined adhoc location. */ |
1054 | ||
620e594b | 1055 | inline location_t |
99b1c316 | 1056 | COMBINE_LOCATION_DATA (class line_maps *set, |
620e594b | 1057 | location_t loc, |
ebedc9a3 | 1058 | source_range src_range, |
0501dbd9 DM |
1059 | void *block) |
1060 | { | |
ebedc9a3 | 1061 | return get_combined_adhoc_loc (set, loc, src_range, block); |
0501dbd9 | 1062 | } |
5368224f | 1063 | |
99b1c316 | 1064 | extern void rebuild_location_adhoc_htab (class line_maps *); |
52187008 | 1065 | |
c468587a DS |
1066 | /* Initialize a line map set. SET is the line map set to initialize |
1067 | and BUILTIN_LOCATION is the special location value to be used as | |
1068 | spelling location for built-in tokens. This BUILTIN_LOCATION has | |
1069 | to be strictly less than RESERVED_LOCATION_COUNT. */ | |
99b1c316 | 1070 | extern void linemap_init (class line_maps *set, |
620e594b | 1071 | location_t builtin_location); |
d82fc108 | 1072 | |
9ac97460 | 1073 | /* Check for and warn about line_maps entered but not exited. */ |
12f9df4e | 1074 | |
99b1c316 | 1075 | extern void linemap_check_files_exited (class line_maps *); |
12f9df4e | 1076 | |
620e594b | 1077 | /* Return a location_t for the start (i.e. column==0) of |
12f9df4e PB |
1078 | (physical) line TO_LINE in the current source file (as in the |
1079 | most recent linemap_add). MAX_COLUMN_HINT is the highest column | |
1080 | number we expect to use in this line (but it does not change | |
9ac97460 | 1081 | the highest_location). */ |
12f9df4e | 1082 | |
620e594b | 1083 | extern location_t linemap_line_start |
99b1c316 | 1084 | (class line_maps *set, linenum_type to_line, unsigned int max_column_hint); |
12f9df4e | 1085 | |
1f8ac759 NS |
1086 | /* Allocate a raw block of line maps, zero initialized. */ |
1087 | extern line_map *line_map_new_raw (line_maps *, bool, unsigned); | |
1088 | ||
d82fc108 | 1089 | /* Add a mapping of logical source line to physical source file and |
46427374 TT |
1090 | line number. This function creates an "ordinary map", which is a |
1091 | map that records locations of tokens that are not part of macro | |
1092 | replacement-lists present at a macro expansion point. | |
9074464c GK |
1093 | |
1094 | The text pointed to by TO_FILE must have a lifetime | |
46427374 | 1095 | at least as long as the lifetime of SET. An empty |
9074464c | 1096 | TO_FILE means standard input. If reason is LC_LEAVE, and |
47d89cf3 NB |
1097 | TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their |
1098 | natural values considering the file we are returning to. | |
d82fc108 | 1099 | |
a2981930 | 1100 | A call to this function can relocate the previous set of |
42dcba34 | 1101 | maps, so any stored line_map pointers should not be used. */ |
99b1c316 MS |
1102 | extern const line_map *linemap_add |
1103 | (class line_maps *, enum lc_reason, unsigned int sysp, | |
1bb64668 | 1104 | const char *to_file, linenum_type to_line); |
d82fc108 | 1105 | |
1f8ac759 NS |
1106 | /* Create a macro map. A macro map encodes source locations of tokens |
1107 | that are part of a macro replacement-list, at a macro expansion | |
1108 | point. See the extensive comments of struct line_map and struct | |
1109 | line_map_macro, in line-map.h. | |
1110 | ||
1111 | This map shall be created when the macro is expanded. The map | |
1112 | encodes the source location of the expansion point of the macro as | |
1113 | well as the "original" source location of each token that is part | |
1114 | of the macro replacement-list. If a macro is defined but never | |
1115 | expanded, it has no macro map. SET is the set of maps the macro | |
1116 | map should be part of. MACRO_NODE is the macro which the new macro | |
1117 | map should encode source locations for. EXPANSION is the location | |
1118 | of the expansion point of MACRO. For function-like macros | |
1119 | invocations, it's best to make it point to the closing parenthesis | |
1120 | of the macro, rather than the the location of the first character | |
1121 | of the macro. NUM_TOKENS is the number of tokens that are part of | |
1122 | the replacement-list of MACRO. */ | |
1123 | const line_map_macro *linemap_enter_macro (line_maps *, cpp_hashnode *, | |
1124 | location_t, unsigned int); | |
1125 | ||
1126 | /* Create a source location for a module. The creator must either do | |
1127 | this after the TU is tokenized, or deal with saving and restoring | |
1128 | map state. */ | |
1129 | ||
1130 | extern location_t linemap_module_loc | |
1131 | (line_maps *, location_t from, const char *name); | |
1132 | extern void linemap_module_reparent | |
1133 | (line_maps *, location_t loc, location_t new_parent); | |
1134 | ||
f207eed6 NS |
1135 | /* Restore the linemap state such that the map at LWM-1 continues. |
1136 | Return start location of the new map. */ | |
1137 | extern unsigned linemap_module_restore | |
1f8ac759 NS |
1138 | (line_maps *, unsigned lwm); |
1139 | ||
46427374 TT |
1140 | /* Given a logical source location, returns the map which the |
1141 | corresponding (source file, line, column) triplet can be deduced | |
1142 | from. Since the set is built chronologically, the logical lines are | |
1143 | monotonic increasing, and so the list is sorted and we can use a | |
1144 | binary search. If no line map have been allocated yet, this | |
1145 | function returns NULL. */ | |
99b1c316 | 1146 | extern const line_map *linemap_lookup |
9158f0ba | 1147 | (const line_maps *, location_t); |
d82fc108 | 1148 | |
1f8ac759 NS |
1149 | unsigned linemap_lookup_macro_index (const line_maps *, location_t); |
1150 | ||
7d9641cc | 1151 | /* Returns TRUE if the line table set tracks token locations across |
46427374 | 1152 | macro expansion, FALSE otherwise. */ |
99b1c316 | 1153 | bool linemap_tracks_macro_expansion_locs_p (class line_maps *); |
46427374 | 1154 | |
46427374 | 1155 | /* Return the name of the macro associated to MACRO_MAP. */ |
0e50b624 | 1156 | const char* linemap_map_get_macro_name (const line_map_macro *); |
46427374 TT |
1157 | |
1158 | /* Return a positive value if LOCATION is the locus of a token that is | |
1159 | located in a system header, O otherwise. It returns 1 if LOCATION | |
1160 | is the locus of a token that is located in a system header, and 2 | |
1161 | if LOCATION is the locus of a token located in a C system header | |
1162 | that therefore needs to be extern "C" protected in C++. | |
1163 | ||
1164 | Note that this function returns 1 if LOCATION belongs to a token | |
1165 | that is part of a macro replacement-list defined in a system | |
1166 | header, but expanded in a non-system file. */ | |
99b1c316 | 1167 | int linemap_location_in_system_header_p (class line_maps *, |
620e594b | 1168 | location_t); |
46427374 | 1169 | |
63cb3926 JM |
1170 | /* Return TRUE if LOCATION is a source code location of a token that is part of |
1171 | a macro expansion, FALSE otherwise. */ | |
99b1c316 | 1172 | bool linemap_location_from_macro_expansion_p (const line_maps *, |
620e594b | 1173 | location_t); |
46427374 | 1174 | |
63cb3926 JM |
1175 | /* TRUE if LOCATION is a source code location of a token that is part of the |
1176 | definition of a macro, FALSE otherwise. */ | |
99b1c316 | 1177 | bool linemap_location_from_macro_definition_p (class line_maps *, |
620e594b | 1178 | location_t); |
63cb3926 | 1179 | |
b4f3232d DM |
1180 | /* With the precondition that LOCATION is the locus of a token that is |
1181 | an argument of a function-like macro MACRO_MAP and appears in the | |
1182 | expansion of MACRO_MAP, return the locus of that argument in the | |
1183 | context of the caller of MACRO_MAP. */ | |
1184 | ||
620e594b DM |
1185 | extern location_t linemap_macro_map_loc_unwind_toward_spelling |
1186 | (line_maps *set, const line_map_macro *macro_map, location_t location); | |
b4f3232d | 1187 | |
620e594b | 1188 | /* location_t values from 0 to RESERVED_LOCATION_COUNT-1 will |
96c169e1 JJ |
1189 | be reserved for libcpp user as special values, no token from libcpp |
1190 | will contain any of those locations. */ | |
620e594b | 1191 | const location_t RESERVED_LOCATION_COUNT = 2; |
96c169e1 | 1192 | |
620e594b | 1193 | /* Converts a map and a location_t to source line. */ |
0501dbd9 | 1194 | inline linenum_type |
620e594b | 1195 | SOURCE_LINE (const line_map_ordinary *ord_map, location_t loc) |
0501dbd9 | 1196 | { |
0e50b624 | 1197 | return ((loc - ord_map->start_location) |
ebedc9a3 | 1198 | >> ord_map->m_column_and_range_bits) + ord_map->to_line; |
0501dbd9 | 1199 | } |
46427374 | 1200 | |
620e594b | 1201 | /* Convert a map and location_t to source column number. */ |
0501dbd9 | 1202 | inline linenum_type |
620e594b | 1203 | SOURCE_COLUMN (const line_map_ordinary *ord_map, location_t loc) |
0501dbd9 | 1204 | { |
0e50b624 | 1205 | return ((loc - ord_map->start_location) |
ebedc9a3 | 1206 | & ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits; |
0501dbd9 DM |
1207 | } |
1208 | ||
46427374 | 1209 | |
620e594b | 1210 | inline location_t |
f10a9135 | 1211 | linemap_included_from (const line_map_ordinary *ord_map) |
0501dbd9 | 1212 | { |
f10a9135 | 1213 | return ord_map->included_from; |
0501dbd9 | 1214 | } |
46427374 | 1215 | |
f10a9135 NS |
1216 | /* The linemap containing the included-from location of MAP. */ |
1217 | const line_map_ordinary *linemap_included_from_linemap | |
1218 | (line_maps *set, const line_map_ordinary *map); | |
0501dbd9 DM |
1219 | |
1220 | /* True if the map is at the bottom of the include stack. */ | |
1221 | ||
1222 | inline bool | |
0e50b624 | 1223 | MAIN_FILE_P (const line_map_ordinary *ord_map) |
0501dbd9 | 1224 | { |
f10a9135 | 1225 | return ord_map->included_from == 0; |
0501dbd9 | 1226 | } |
46427374 | 1227 | |
620e594b | 1228 | /* Encode and return a location_t from a column number. The |
46427374 TT |
1229 | source line considered is the last source line used to call |
1230 | linemap_line_start, i.e, the last source line which a location was | |
1231 | encoded from. */ | |
620e594b | 1232 | extern location_t |
99b1c316 | 1233 | linemap_position_for_column (class line_maps *, unsigned int); |
46427374 TT |
1234 | |
1235 | /* Encode and return a source location from a given line and | |
1236 | column. */ | |
620e594b | 1237 | location_t |
ebedc9a3 DM |
1238 | linemap_position_for_line_and_column (line_maps *set, |
1239 | const line_map_ordinary *, | |
3aac0952 MLI |
1240 | linenum_type, unsigned int); |
1241 | ||
620e594b | 1242 | /* Encode and return a location_t starting from location LOC and |
3aa34c1d MLI |
1243 | shifting it by OFFSET columns. This function does not support |
1244 | virtual locations. */ | |
620e594b | 1245 | location_t |
99b1c316 | 1246 | linemap_position_for_loc_and_offset (class line_maps *set, |
620e594b | 1247 | location_t loc, |
3aa34c1d MLI |
1248 | unsigned int offset); |
1249 | ||
46427374 | 1250 | /* Return the file this map is for. */ |
0501dbd9 | 1251 | inline const char * |
0e50b624 | 1252 | LINEMAP_FILE (const line_map_ordinary *ord_map) |
0501dbd9 | 1253 | { |
0e50b624 | 1254 | return ord_map->to_file; |
0501dbd9 | 1255 | } |
46427374 TT |
1256 | |
1257 | /* Return the line number this map started encoding location from. */ | |
0501dbd9 | 1258 | inline linenum_type |
0e50b624 | 1259 | LINEMAP_LINE (const line_map_ordinary *ord_map) |
0501dbd9 | 1260 | { |
0e50b624 | 1261 | return ord_map->to_line; |
0501dbd9 | 1262 | } |
46427374 TT |
1263 | |
1264 | /* Return a positive value if map encodes locations from a system | |
1265 | header, 0 otherwise. Returns 1 if MAP encodes locations in a | |
1266 | system header and 2 if it encodes locations in a C system header | |
1267 | that therefore needs to be extern "C" protected in C++. */ | |
0501dbd9 | 1268 | inline unsigned char |
0e50b624 | 1269 | LINEMAP_SYSP (const line_map_ordinary *ord_map) |
0501dbd9 | 1270 | { |
0e50b624 | 1271 | return ord_map->sysp; |
0501dbd9 | 1272 | } |
46427374 | 1273 | |
4839de55 PP |
1274 | const struct line_map *first_map_in_common (line_maps *set, |
1275 | location_t loc0, | |
1276 | location_t loc1, | |
1277 | location_t *res_loc0, | |
1278 | location_t *res_loc1); | |
1279 | ||
46427374 TT |
1280 | /* Return a positive value if PRE denotes the location of a token that |
1281 | comes before the token of POST, 0 if PRE denotes the location of | |
1282 | the same token as the token for POST, and a negative value | |
1283 | otherwise. */ | |
99b1c316 | 1284 | int linemap_compare_locations (class line_maps *set, |
620e594b DM |
1285 | location_t pre, |
1286 | location_t post); | |
46427374 TT |
1287 | |
1288 | /* Return TRUE if LOC_A denotes the location a token that comes | |
1289 | topogically before the token denoted by location LOC_B, or if they | |
1290 | are equal. */ | |
0501dbd9 | 1291 | inline bool |
99b1c316 | 1292 | linemap_location_before_p (class line_maps *set, |
620e594b DM |
1293 | location_t loc_a, |
1294 | location_t loc_b) | |
0501dbd9 DM |
1295 | { |
1296 | return linemap_compare_locations (set, loc_a, loc_b) >= 0; | |
1297 | } | |
46427374 TT |
1298 | |
1299 | typedef struct | |
1300 | { | |
1301 | /* The name of the source file involved. */ | |
1302 | const char *file; | |
1303 | ||
1304 | /* The line-location in the source file. */ | |
1305 | int line; | |
1306 | ||
1307 | int column; | |
1308 | ||
5368224f DC |
1309 | void *data; |
1310 | ||
46427374 TT |
1311 | /* In a system header?. */ |
1312 | bool sysp; | |
1313 | } expanded_location; | |
1314 | ||
96e6ae57 DM |
1315 | class range_label; |
1316 | ||
85204e23 DM |
1317 | /* A hint to diagnostic_show_locus on how to print a source range within a |
1318 | rich_location. | |
1319 | ||
1320 | Typically this is SHOW_RANGE_WITH_CARET for the 0th range, and | |
1321 | SHOW_RANGE_WITHOUT_CARET for subsequent ranges, | |
1322 | but the Fortran frontend uses SHOW_RANGE_WITH_CARET repeatedly for | |
1323 | printing things like: | |
1324 | ||
1325 | x = x + y | |
1326 | 1 2 | |
1327 | Error: Shapes for operands at (1) and (2) are not conformable | |
1328 | ||
1329 | where "1" and "2" are notionally carets. */ | |
1330 | ||
1331 | enum range_display_kind | |
1332 | { | |
1333 | /* Show the pertinent source line(s), the caret, and underline(s). */ | |
1334 | SHOW_RANGE_WITH_CARET, | |
1335 | ||
1336 | /* Show the pertinent source line(s) and underline(s), but don't | |
1337 | show the caret (just an underline). */ | |
1338 | SHOW_RANGE_WITHOUT_CARET, | |
1339 | ||
1340 | /* Just show the source lines; don't show the range itself. | |
1341 | This is for use when displaying some line-insertion fix-it hints (for | |
1342 | showing the user context on the change, for when it doesn't make sense | |
1343 | to highlight the first column on the next line). */ | |
1344 | SHOW_LINES_WITHOUT_RANGE | |
1345 | }; | |
1346 | ||
40499f81 | 1347 | /* A location within a rich_location: a caret&range, with |
96e6ae57 DM |
1348 | the caret potentially flagged for display, and an optional |
1349 | label. */ | |
40499f81 | 1350 | |
8a645150 DM |
1351 | struct location_range |
1352 | { | |
620e594b | 1353 | location_t m_loc; |
8a645150 | 1354 | |
85204e23 | 1355 | enum range_display_kind m_range_display_kind; |
96e6ae57 DM |
1356 | |
1357 | /* If non-NULL, the label for this range. */ | |
1358 | const range_label *m_label; | |
8a645150 DM |
1359 | }; |
1360 | ||
b816477a DM |
1361 | /* A partially-embedded vec for use within rich_location for storing |
1362 | ranges and fix-it hints. | |
1363 | ||
1364 | Elements [0..NUM_EMBEDDED) are allocated within m_embed, after | |
1365 | that they are within the dynamically-allocated m_extra. | |
1366 | ||
1367 | This allows for static allocation in the common case, whilst | |
1368 | supporting the rarer case of an arbitrary number of elements. | |
1369 | ||
1370 | Dynamic allocation is not performed unless it's needed. */ | |
1371 | ||
1372 | template <typename T, int NUM_EMBEDDED> | |
1373 | class semi_embedded_vec | |
1374 | { | |
1375 | public: | |
1376 | semi_embedded_vec (); | |
1377 | ~semi_embedded_vec (); | |
1378 | ||
1379 | unsigned int count () const { return m_num; } | |
1380 | T& operator[] (int idx); | |
1381 | const T& operator[] (int idx) const; | |
1382 | ||
1383 | void push (const T&); | |
1384 | void truncate (int len); | |
1385 | ||
1386 | private: | |
1387 | int m_num; | |
1388 | T m_embedded[NUM_EMBEDDED]; | |
1389 | int m_alloc; | |
1390 | T *m_extra; | |
1391 | }; | |
1392 | ||
1393 | /* Constructor for semi_embedded_vec. In particular, no dynamic allocation | |
1394 | is done. */ | |
1395 | ||
1396 | template <typename T, int NUM_EMBEDDED> | |
1397 | semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec () | |
1398 | : m_num (0), m_alloc (0), m_extra (NULL) | |
1399 | { | |
1400 | } | |
1401 | ||
1402 | /* semi_embedded_vec's dtor. Release any dynamically-allocated memory. */ | |
1403 | ||
1404 | template <typename T, int NUM_EMBEDDED> | |
1405 | semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec () | |
1406 | { | |
1407 | XDELETEVEC (m_extra); | |
1408 | } | |
1409 | ||
1410 | /* Look up element IDX, mutably. */ | |
1411 | ||
1412 | template <typename T, int NUM_EMBEDDED> | |
1413 | T& | |
1414 | semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) | |
1415 | { | |
1416 | linemap_assert (idx < m_num); | |
1417 | if (idx < NUM_EMBEDDED) | |
1418 | return m_embedded[idx]; | |
1419 | else | |
1420 | { | |
1421 | linemap_assert (m_extra != NULL); | |
1422 | return m_extra[idx - NUM_EMBEDDED]; | |
1423 | } | |
1424 | } | |
1425 | ||
1426 | /* Look up element IDX (const). */ | |
1427 | ||
1428 | template <typename T, int NUM_EMBEDDED> | |
1429 | const T& | |
1430 | semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) const | |
1431 | { | |
1432 | linemap_assert (idx < m_num); | |
1433 | if (idx < NUM_EMBEDDED) | |
1434 | return m_embedded[idx]; | |
1435 | else | |
1436 | { | |
1437 | linemap_assert (m_extra != NULL); | |
1438 | return m_extra[idx - NUM_EMBEDDED]; | |
1439 | } | |
1440 | } | |
1441 | ||
1442 | /* Append VALUE to the end of the semi_embedded_vec. */ | |
1443 | ||
1444 | template <typename T, int NUM_EMBEDDED> | |
1445 | void | |
1446 | semi_embedded_vec<T, NUM_EMBEDDED>::push (const T& value) | |
1447 | { | |
1448 | int idx = m_num++; | |
1449 | if (idx < NUM_EMBEDDED) | |
1450 | m_embedded[idx] = value; | |
1451 | else | |
1452 | { | |
1453 | /* Offset "idx" to be an index within m_extra. */ | |
1454 | idx -= NUM_EMBEDDED; | |
1455 | if (NULL == m_extra) | |
1456 | { | |
1457 | linemap_assert (m_alloc == 0); | |
1458 | m_alloc = 16; | |
1459 | m_extra = XNEWVEC (T, m_alloc); | |
1460 | } | |
1461 | else if (idx >= m_alloc) | |
1462 | { | |
1463 | linemap_assert (m_alloc > 0); | |
1464 | m_alloc *= 2; | |
1465 | m_extra = XRESIZEVEC (T, m_extra, m_alloc); | |
1466 | } | |
1467 | linemap_assert (m_extra); | |
1468 | linemap_assert (idx < m_alloc); | |
1469 | m_extra[idx] = value; | |
1470 | } | |
1471 | } | |
1472 | ||
1473 | /* Truncate to length LEN. No deallocation is performed. */ | |
1474 | ||
1475 | template <typename T, int NUM_EMBEDDED> | |
1476 | void | |
1477 | semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len) | |
1478 | { | |
1479 | linemap_assert (len <= m_num); | |
1480 | m_num = len; | |
1481 | } | |
1482 | ||
a87a86e1 | 1483 | class fixit_hint; |
4bc1899b | 1484 | class diagnostic_path; |
a87a86e1 | 1485 | |
8a645150 | 1486 | /* A "rich" source code location, for use when printing diagnostics. |
40499f81 DM |
1487 | A rich_location has one or more carets&ranges, where the carets |
1488 | are optional. These are referred to as "ranges" from here. | |
1489 | Typically the zeroth range has a caret; other ranges sometimes | |
1490 | have carets. | |
8a645150 DM |
1491 | |
1492 | The "primary" location of a rich_location is the caret of range 0, | |
1493 | used for determining the line/column when printing diagnostic | |
1494 | text, such as: | |
1495 | ||
1496 | some-file.c:3:1: error: ...etc... | |
1497 | ||
1498 | Additional ranges may be added to help the user identify other | |
1499 | pertinent clauses in a diagnostic. | |
1500 | ||
96e6ae57 DM |
1501 | Ranges can (optionally) be given labels via class range_label. |
1502 | ||
8a645150 DM |
1503 | rich_location instances are intended to be allocated on the stack |
1504 | when generating diagnostics, and to be short-lived. | |
1505 | ||
1506 | Examples of rich locations | |
1507 | -------------------------- | |
1508 | ||
1509 | Example A | |
1510 | ********* | |
1511 | int i = "foo"; | |
1512 | ^ | |
1513 | This "rich" location is simply a single range (range 0), with | |
1514 | caret = start = finish at the given point. | |
1515 | ||
1516 | Example B | |
1517 | ********* | |
1518 | a = (foo && bar) | |
1519 | ~~~~~^~~~~~~ | |
1520 | This rich location has a single range (range 0), with the caret | |
1521 | at the first "&", and the start/finish at the parentheses. | |
1522 | Compare with example C below. | |
1523 | ||
1524 | Example C | |
1525 | ********* | |
1526 | a = (foo && bar) | |
1527 | ~~~ ^~ ~~~ | |
1528 | This rich location has three ranges: | |
1529 | - Range 0 has its caret and start location at the first "&" and | |
1530 | end at the second "&. | |
1531 | - Range 1 has its start and finish at the "f" and "o" of "foo"; | |
1532 | the caret is not flagged for display, but is perhaps at the "f" | |
1533 | of "foo". | |
1534 | - Similarly, range 2 has its start and finish at the "b" and "r" of | |
1535 | "bar"; the caret is not flagged for display, but is perhaps at the | |
1536 | "b" of "bar". | |
1537 | Compare with example B above. | |
1538 | ||
1539 | Example D (Fortran frontend) | |
1540 | **************************** | |
1541 | x = x + y | |
1542 | 1 2 | |
1543 | This rich location has range 0 at "1", and range 1 at "2". | |
1544 | Both are flagged for caret display. Both ranges have start/finish | |
1545 | equal to their caret point. The frontend overrides the diagnostic | |
1546 | context's default caret character for these ranges. | |
1547 | ||
96e6ae57 DM |
1548 | Example E (range labels) |
1549 | ************************ | |
8a645150 DM |
1550 | printf ("arg0: %i arg1: %s arg2: %i", |
1551 | ^~ | |
96e6ae57 DM |
1552 | | |
1553 | const char * | |
8a645150 DM |
1554 | 100, 101, 102); |
1555 | ~~~ | |
96e6ae57 DM |
1556 | | |
1557 | int | |
8a645150 DM |
1558 | This rich location has two ranges: |
1559 | - range 0 is at the "%s" with start = caret = "%" and finish at | |
96e6ae57 | 1560 | the "s". It has a range_label ("const char *"). |
8a645150 | 1561 | - range 1 has start/finish covering the "101" and is not flagged for |
96e6ae57 DM |
1562 | caret printing. The caret is at the start of "101", where its |
1563 | range_label is printed ("int"). | |
254830ba DM |
1564 | |
1565 | Fix-it hints | |
1566 | ------------ | |
1567 | ||
1568 | Rich locations can also contain "fix-it hints", giving suggestions | |
1569 | for the user on how to edit their code to fix a problem. These | |
1570 | can be expressed as insertions, replacements, and removals of text. | |
1571 | The edits by default are relative to the zeroth range within the | |
1572 | rich_location, but optionally they can be expressed relative to | |
1573 | other locations (using various overloaded methods of the form | |
1574 | rich_location::add_fixit_*). | |
1575 | ||
1576 | For example: | |
1577 | ||
1578 | Example F: fix-it hint: insert_before | |
1579 | ************************************* | |
1580 | ptr = arr[0]; | |
1581 | ^~~~~~ | |
1582 | & | |
1583 | This rich location has a single range (range 0) covering "arr[0]", | |
1584 | with the caret at the start. The rich location has a single | |
1585 | insertion fix-it hint, inserted before range 0, added via | |
1586 | richloc.add_fixit_insert_before ("&"); | |
1587 | ||
1588 | Example G: multiple fix-it hints: insert_before and insert_after | |
1589 | **************************************************************** | |
1590 | #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2) | |
1591 | ^~~~ ^~~~ ^~~~ | |
1592 | ( ) ( ) ( ) | |
1593 | This rich location has three ranges, covering "arg0", "arg1", | |
1594 | and "arg2", all with caret-printing enabled. | |
1595 | The rich location has 6 insertion fix-it hints: each arg | |
1596 | has a pair of insertion fix-it hints, suggesting wrapping | |
1597 | them with parentheses: one a '(' inserted before, | |
1598 | the other a ')' inserted after, added via | |
1599 | richloc.add_fixit_insert_before (LOC, "("); | |
1600 | and | |
1601 | richloc.add_fixit_insert_after (LOC, ")"); | |
1602 | ||
1603 | Example H: fix-it hint: removal | |
1604 | ******************************* | |
1605 | struct s {int i};; | |
1606 | ^ | |
1607 | - | |
1608 | This rich location has a single range at the stray trailing | |
1609 | semicolon, along with a single removal fix-it hint, covering | |
1610 | the same range, added via: | |
1611 | richloc.add_fixit_remove (); | |
1612 | ||
1613 | Example I: fix-it hint: replace | |
1614 | ******************************* | |
1615 | c = s.colour; | |
1616 | ^~~~~~ | |
1617 | color | |
1618 | This rich location has a single range (range 0) covering "colour", | |
1619 | and a single "replace" fix-it hint, covering the same range, | |
1620 | added via | |
1621 | richloc.add_fixit_replace ("color"); | |
1622 | ||
85204e23 DM |
1623 | Example J: fix-it hint: line insertion |
1624 | ************************************** | |
1625 | ||
1626 | 3 | #include <stddef.h> | |
1627 | + |+#include <stdio.h> | |
1628 | 4 | int the_next_line; | |
1629 | ||
1630 | This rich location has a single range at line 4 column 1, marked | |
1631 | with SHOW_LINES_WITHOUT_RANGE (to avoid printing a meaningless caret | |
1632 | on the "i" of int). It has a insertion fix-it hint of the string | |
1633 | "#include <stdio.h>\n". | |
1634 | ||
254830ba DM |
1635 | Adding a fix-it hint can fail: for example, attempts to insert content |
1636 | at the transition between two line maps may fail due to there being no | |
620e594b | 1637 | location_t value to express the new location. |
254830ba DM |
1638 | |
1639 | Attempts to add a fix-it hint within a macro expansion will fail. | |
1640 | ||
ad53f123 DM |
1641 | There is only limited support for newline characters in fix-it hints: |
1642 | only hints with newlines which insert an entire new line are permitted, | |
1643 | inserting at the start of a line, and finishing with a newline | |
1644 | (with no interior newline characters). Other attempts to add | |
1645 | fix-it hints containing newline characters will fail. | |
c7a980b8 DM |
1646 | Similarly, attempts to delete or replace a range *affecting* multiple |
1647 | lines will fail. | |
31316208 | 1648 | |
254830ba DM |
1649 | The rich_location API handles these failures gracefully, so that |
1650 | diagnostics can attempt to add fix-it hints without each needing | |
1651 | extensive checking. | |
1652 | ||
1653 | Fix-it hints within a rich_location are "atomic": if any hints can't | |
1654 | be applied, none of them will be (tracked by the m_seen_impossible_fixit | |
1655 | flag), and no fix-its hints will be displayed for that rich_location. | |
1656 | This implies that diagnostic messages need to be worded in such a way | |
1657 | that they make sense whether or not the fix-it hints are displayed, | |
1658 | or that richloc.seen_impossible_fixit_p () should be checked before | |
1659 | issuing the diagnostics. */ | |
8a645150 DM |
1660 | |
1661 | class rich_location | |
1662 | { | |
1663 | public: | |
1664 | /* Constructors. */ | |
1665 | ||
1666 | /* Constructing from a location. */ | |
620e594b | 1667 | rich_location (line_maps *set, location_t loc, |
96e6ae57 | 1668 | const range_label *label = NULL); |
8a645150 | 1669 | |
a87a86e1 DM |
1670 | /* Destructor. */ |
1671 | ~rich_location (); | |
1672 | ||
e4d2305a MS |
1673 | /* The class manages the memory pointed to by the elements of |
1674 | the M_FIXIT_HINTS vector and is not meant to be copied or | |
1675 | assigned. */ | |
1676 | rich_location (const rich_location &) = delete; | |
1677 | void operator= (const rich_location &) = delete; | |
1678 | ||
8a645150 | 1679 | /* Accessors. */ |
620e594b DM |
1680 | location_t get_loc () const { return get_loc (0); } |
1681 | location_t get_loc (unsigned int idx) const; | |
8a645150 DM |
1682 | |
1683 | void | |
620e594b | 1684 | add_range (location_t loc, |
85204e23 DM |
1685 | enum range_display_kind range_display_kind |
1686 | = SHOW_RANGE_WITHOUT_CARET, | |
96e6ae57 | 1687 | const range_label *label = NULL); |
8a645150 DM |
1688 | |
1689 | void | |
620e594b | 1690 | set_range (unsigned int idx, location_t loc, |
85204e23 | 1691 | enum range_display_kind range_display_kind); |
8a645150 | 1692 | |
b816477a | 1693 | unsigned int get_num_locations () const { return m_ranges.count (); } |
8a645150 | 1694 | |
b816477a DM |
1695 | const location_range *get_range (unsigned int idx) const; |
1696 | location_range *get_range (unsigned int idx); | |
8a645150 | 1697 | |
40499f81 | 1698 | expanded_location get_expanded_location (unsigned int idx); |
8a645150 DM |
1699 | |
1700 | void | |
1701 | override_column (int column); | |
1702 | ||
a87a86e1 | 1703 | /* Fix-it hints. */ |
f9087798 DM |
1704 | |
1705 | /* Methods for adding insertion fix-it hints. */ | |
1706 | ||
254830ba DM |
1707 | /* Suggest inserting NEW_CONTENT immediately before the primary |
1708 | range's start. */ | |
f9087798 | 1709 | void |
254830ba | 1710 | add_fixit_insert_before (const char *new_content); |
f9087798 | 1711 | |
254830ba | 1712 | /* Suggest inserting NEW_CONTENT immediately before the start of WHERE. */ |
a87a86e1 | 1713 | void |
620e594b | 1714 | add_fixit_insert_before (location_t where, |
254830ba DM |
1715 | const char *new_content); |
1716 | ||
1717 | /* Suggest inserting NEW_CONTENT immediately after the end of the primary | |
1718 | range. */ | |
1719 | void | |
1720 | add_fixit_insert_after (const char *new_content); | |
1721 | ||
1722 | /* Suggest inserting NEW_CONTENT immediately after the end of WHERE. */ | |
1723 | void | |
620e594b | 1724 | add_fixit_insert_after (location_t where, |
254830ba | 1725 | const char *new_content); |
a87a86e1 | 1726 | |
f9087798 DM |
1727 | /* Methods for adding removal fix-it hints. */ |
1728 | ||
1729 | /* Suggest removing the content covered by range 0. */ | |
1730 | void | |
1731 | add_fixit_remove (); | |
1732 | ||
1733 | /* Suggest removing the content covered between the start and finish | |
1734 | of WHERE. */ | |
1735 | void | |
620e594b | 1736 | add_fixit_remove (location_t where); |
f9087798 DM |
1737 | |
1738 | /* Suggest removing the content covered by SRC_RANGE. */ | |
a87a86e1 DM |
1739 | void |
1740 | add_fixit_remove (source_range src_range); | |
1741 | ||
f9087798 DM |
1742 | /* Methods for adding "replace" fix-it hints. */ |
1743 | ||
1744 | /* Suggest replacing the content covered by range 0 with NEW_CONTENT. */ | |
1745 | void | |
1746 | add_fixit_replace (const char *new_content); | |
1747 | ||
1748 | /* Suggest replacing the content between the start and finish of | |
1749 | WHERE with NEW_CONTENT. */ | |
1750 | void | |
620e594b | 1751 | add_fixit_replace (location_t where, |
f9087798 DM |
1752 | const char *new_content); |
1753 | ||
1754 | /* Suggest replacing the content covered by SRC_RANGE with | |
1755 | NEW_CONTENT. */ | |
a87a86e1 DM |
1756 | void |
1757 | add_fixit_replace (source_range src_range, | |
1758 | const char *new_content); | |
1759 | ||
b816477a | 1760 | unsigned int get_num_fixit_hints () const { return m_fixit_hints.count (); } |
a87a86e1 | 1761 | fixit_hint *get_fixit_hint (int idx) const { return m_fixit_hints[idx]; } |
ee908516 | 1762 | fixit_hint *get_last_fixit_hint () const; |
c65236d6 | 1763 | bool seen_impossible_fixit_p () const { return m_seen_impossible_fixit; } |
ee908516 | 1764 | |
b09649fd DM |
1765 | /* Set this if the fix-it hints are not suitable to be |
1766 | automatically applied. | |
1767 | ||
1768 | For example, if you are suggesting more than one | |
1769 | mutually exclusive solution to a problem, then | |
1770 | it doesn't make sense to apply all of the solutions; | |
1771 | manual intervention is required. | |
1772 | ||
1773 | If set, then the fix-it hints in the rich_location will | |
1774 | be printed, but will not be added to generated patches, | |
1775 | or affect the modified version of the file. */ | |
1776 | void fixits_cannot_be_auto_applied () | |
1777 | { | |
1778 | m_fixits_cannot_be_auto_applied = true; | |
1779 | } | |
1780 | ||
1781 | bool fixits_can_be_auto_applied_p () const | |
1782 | { | |
1783 | return !m_fixits_cannot_be_auto_applied; | |
1784 | } | |
1785 | ||
4bc1899b DM |
1786 | /* An optional path through the code. */ |
1787 | const diagnostic_path *get_path () const { return m_path; } | |
1788 | void set_path (const diagnostic_path *path) { m_path = path; } | |
1789 | ||
bd5e882c DM |
1790 | /* A flag for hinting that the diagnostic involves character encoding |
1791 | issues, and thus that it will be helpful to the user if we show some | |
1792 | representation of how the characters in the pertinent source lines | |
1793 | are encoded. | |
1794 | The default is false (i.e. do not escape). | |
1795 | When set to true, non-ASCII bytes in the pertinent source lines will | |
1796 | be escaped in a manner controlled by the user-supplied option | |
1797 | -fdiagnostics-escape-format=, so that the user can better understand | |
1798 | what's going on with the encoding in their source file. */ | |
1799 | bool escape_on_output_p () const { return m_escape_on_output; } | |
1800 | void set_escape_on_output (bool flag) { m_escape_on_output = flag; } | |
1801 | ||
ee908516 | 1802 | private: |
620e594b | 1803 | bool reject_impossible_fixit (location_t where); |
254830ba | 1804 | void stop_supporting_fixits (); |
620e594b DM |
1805 | void maybe_add_fixit (location_t start, |
1806 | location_t next_loc, | |
338035aa | 1807 | const char *new_content); |
a87a86e1 | 1808 | |
8a645150 | 1809 | public: |
b816477a | 1810 | static const int STATICALLY_ALLOCATED_RANGES = 3; |
8a645150 DM |
1811 | |
1812 | protected: | |
ee908516 | 1813 | line_maps *m_line_table; |
b816477a | 1814 | semi_embedded_vec <location_range, STATICALLY_ALLOCATED_RANGES> m_ranges; |
8a645150 | 1815 | |
40499f81 DM |
1816 | int m_column_override; |
1817 | ||
8a645150 DM |
1818 | bool m_have_expanded_location; |
1819 | expanded_location m_expanded_location; | |
a87a86e1 | 1820 | |
b816477a DM |
1821 | static const int MAX_STATIC_FIXIT_HINTS = 2; |
1822 | semi_embedded_vec <fixit_hint *, MAX_STATIC_FIXIT_HINTS> m_fixit_hints; | |
1823 | ||
ee908516 | 1824 | bool m_seen_impossible_fixit; |
b09649fd | 1825 | bool m_fixits_cannot_be_auto_applied; |
4bc1899b DM |
1826 | |
1827 | const diagnostic_path *m_path; | |
bd5e882c | 1828 | bool m_escape_on_output; |
a87a86e1 DM |
1829 | }; |
1830 | ||
96e6ae57 DM |
1831 | /* A struct for the result of range_label::get_text: a NUL-terminated buffer |
1832 | of localized text, and a flag to determine if the caller should "free" the | |
1833 | buffer. */ | |
1834 | ||
6c1dae73 | 1835 | class label_text |
96e6ae57 | 1836 | { |
6c1dae73 | 1837 | public: |
96e6ae57 DM |
1838 | label_text () |
1839 | : m_buffer (NULL), m_caller_owned (false) | |
1840 | {} | |
1841 | ||
96e6ae57 DM |
1842 | void maybe_free () |
1843 | { | |
1844 | if (m_caller_owned) | |
1845 | free (m_buffer); | |
1846 | } | |
1847 | ||
d68f5d45 DM |
1848 | /* Create a label_text instance that borrows BUFFER from a |
1849 | longer-lived owner. */ | |
1850 | static label_text borrow (const char *buffer) | |
1851 | { | |
1852 | return label_text (const_cast <char *> (buffer), false); | |
1853 | } | |
1854 | ||
1855 | /* Create a label_text instance that takes ownership of BUFFER. */ | |
1856 | static label_text take (char *buffer) | |
1857 | { | |
1858 | return label_text (buffer, true); | |
1859 | } | |
1860 | ||
1861 | /* Take ownership of the buffer, copying if necessary. */ | |
1862 | char *take_or_copy () | |
1863 | { | |
1864 | if (m_caller_owned) | |
1865 | return m_buffer; | |
1866 | else | |
1867 | return xstrdup (m_buffer); | |
1868 | } | |
1869 | ||
96e6ae57 DM |
1870 | char *m_buffer; |
1871 | bool m_caller_owned; | |
d68f5d45 DM |
1872 | |
1873 | private: | |
1874 | label_text (char *buffer, bool owned) | |
1875 | : m_buffer (buffer), m_caller_owned (owned) | |
1876 | {} | |
96e6ae57 DM |
1877 | }; |
1878 | ||
1879 | /* Abstract base class for labelling a range within a rich_location | |
1880 | (e.g. for labelling expressions with their type). | |
1881 | ||
1882 | Generating the text could require non-trivial work, so this work | |
1883 | is delayed (via the "get_text" virtual function) until the diagnostic | |
1884 | printing code "knows" it needs it, thus avoiding doing it e.g. for | |
1885 | warnings that are filtered by command-line flags. This virtual | |
1886 | function also isolates libcpp and the diagnostics subsystem from | |
1887 | the front-end and middle-end-specific code for generating the text | |
1888 | for the labels. | |
1889 | ||
1890 | Like the rich_location instances they annotate, range_label instances | |
1891 | are intended to be allocated on the stack when generating diagnostics, | |
1892 | and to be short-lived. */ | |
1893 | ||
1894 | class range_label | |
1895 | { | |
1896 | public: | |
1897 | virtual ~range_label () {} | |
1898 | ||
9c4a4b3c DM |
1899 | /* Get localized text for the label. |
1900 | The RANGE_IDX is provided, allowing for range_label instances to be | |
1901 | shared by multiple ranges if need be (the "flyweight" design pattern). */ | |
1902 | virtual label_text get_text (unsigned range_idx) const = 0; | |
96e6ae57 DM |
1903 | }; |
1904 | ||
338035aa DM |
1905 | /* A fix-it hint: a suggested insertion, replacement, or deletion of text. |
1906 | We handle these three types of edit with one class, by representing | |
1907 | them as replacement of a half-open range: | |
1908 | [start, next_loc) | |
1909 | Insertions have start == next_loc: "replace" the empty string at the | |
1910 | start location with the new string. | |
ad53f123 DM |
1911 | Deletions are replacement with the empty string. |
1912 | ||
1913 | There is only limited support for newline characters in fix-it hints | |
1914 | as noted above in the comment for class rich_location. | |
1915 | A fixit_hint instance can have at most one newline character; if | |
1916 | present, the newline character must be the final character of | |
1917 | the content (preventing e.g. fix-its that split a pre-existing line). */ | |
a87a86e1 | 1918 | |
338035aa | 1919 | class fixit_hint |
a87a86e1 DM |
1920 | { |
1921 | public: | |
620e594b DM |
1922 | fixit_hint (location_t start, |
1923 | location_t next_loc, | |
338035aa DM |
1924 | const char *new_content); |
1925 | ~fixit_hint () { free (m_bytes); } | |
a87a86e1 | 1926 | |
3d4f9f87 | 1927 | bool affects_line_p (const char *file, int line) const; |
620e594b DM |
1928 | location_t get_start_loc () const { return m_start; } |
1929 | location_t get_next_loc () const { return m_next_loc; } | |
1930 | bool maybe_append (location_t start, | |
1931 | location_t next_loc, | |
338035aa | 1932 | const char *new_content); |
a87a86e1 | 1933 | |
a87a86e1 DM |
1934 | const char *get_string () const { return m_bytes; } |
1935 | size_t get_length () const { return m_len; } | |
1936 | ||
338035aa DM |
1937 | bool insertion_p () const { return m_start == m_next_loc; } |
1938 | ||
ad53f123 DM |
1939 | bool ends_with_newline_p () const; |
1940 | ||
a87a86e1 | 1941 | private: |
338035aa DM |
1942 | /* We don't use source_range here since, unlike most places, |
1943 | this is a half-open/half-closed range: | |
1944 | [start, next_loc) | |
1945 | so that we can support insertion via start == next_loc. */ | |
620e594b DM |
1946 | location_t m_start; |
1947 | location_t m_next_loc; | |
a87a86e1 DM |
1948 | char *m_bytes; |
1949 | size_t m_len; | |
1950 | }; | |
1951 | ||
1952 | ||
46427374 TT |
1953 | /* This is enum is used by the function linemap_resolve_location |
1954 | below. The meaning of the values is explained in the comment of | |
1955 | that function. */ | |
1956 | enum location_resolution_kind | |
1957 | { | |
1958 | LRK_MACRO_EXPANSION_POINT, | |
1959 | LRK_SPELLING_LOCATION, | |
1960 | LRK_MACRO_DEFINITION_LOCATION | |
1961 | }; | |
1962 | ||
1963 | /* Resolve a virtual location into either a spelling location, an | |
1964 | expansion point location or a token argument replacement point | |
1965 | location. Return the map that encodes the virtual location as well | |
1966 | as the resolved location. | |
1967 | ||
1968 | If LOC is *NOT* the location of a token resulting from the | |
1969 | expansion of a macro, then the parameter LRK (which stands for | |
1970 | Location Resolution Kind) is ignored and the resulting location | |
1971 | just equals the one given in argument. | |
1972 | ||
1973 | Now if LOC *IS* the location of a token resulting from the | |
1974 | expansion of a macro, this is what happens. | |
1975 | ||
1976 | * If LRK is set to LRK_MACRO_EXPANSION_POINT | |
1977 | ------------------------------- | |
1978 | ||
1979 | The virtual location is resolved to the first macro expansion point | |
1980 | that led to this macro expansion. | |
1981 | ||
1982 | * If LRK is set to LRK_SPELLING_LOCATION | |
1983 | ------------------------------------- | |
1984 | ||
1985 | The virtual location is resolved to the locus where the token has | |
1986 | been spelled in the source. This can follow through all the macro | |
1987 | expansions that led to the token. | |
1988 | ||
1989 | * If LRK is set to LRK_MACRO_DEFINITION_LOCATION | |
1990 | -------------------------------------- | |
1991 | ||
1992 | The virtual location is resolved to the locus of the token in the | |
1993 | context of the macro definition. | |
1994 | ||
1995 | If LOC is the locus of a token that is an argument of a | |
1996 | function-like macro [replacing a parameter in the replacement list | |
1997 | of the macro] the virtual location is resolved to the locus of the | |
1998 | parameter that is replaced, in the context of the definition of the | |
1999 | macro. | |
2000 | ||
2001 | If LOC is the locus of a token that is not an argument of a | |
2002 | function-like macro, then the function behaves as if LRK was set to | |
2003 | LRK_SPELLING_LOCATION. | |
2004 | ||
2005 | If LOC_MAP is not NULL, *LOC_MAP is set to the map encoding the | |
1d72e96f | 2006 | returned location. Note that if the returned location wasn't originally |
84756fd4 DS |
2007 | encoded by a map, the *MAP is set to NULL. This can happen if LOC |
2008 | resolves to a location reserved for the client code, like | |
2009 | UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */ | |
46427374 | 2010 | |
99b1c316 | 2011 | location_t linemap_resolve_location (class line_maps *, |
620e594b DM |
2012 | location_t loc, |
2013 | enum location_resolution_kind lrk, | |
2014 | const line_map_ordinary **loc_map); | |
46427374 TT |
2015 | |
2016 | /* Suppose that LOC is the virtual location of a token coming from the | |
2017 | expansion of a macro M. This function then steps up to get the | |
2018 | location L of the point where M got expanded. If L is a spelling | |
2019 | location inside a macro expansion M', then this function returns | |
2020 | the point where M' was expanded. LOC_MAP is an output parameter. | |
c4ca1a09 | 2021 | When non-NULL, *LOC_MAP is set to the map of the returned |
46427374 | 2022 | location. */ |
99b1c316 | 2023 | location_t linemap_unwind_toward_expansion (class line_maps *, |
620e594b | 2024 | location_t loc, |
99b1c316 | 2025 | const line_map **loc_map); |
46427374 | 2026 | |
c4ca1a09 DS |
2027 | /* If LOC is the virtual location of a token coming from the expansion |
2028 | of a macro M and if its spelling location is reserved (e.g, a | |
2029 | location for a built-in token), then this function unwinds (using | |
2030 | linemap_unwind_toward_expansion) the location until a location that | |
2031 | is not reserved and is not in a system header is reached. In other | |
2032 | words, this unwinds the reserved location until a location that is | |
2033 | in real source code is reached. | |
2034 | ||
2035 | Otherwise, if the spelling location for LOC is not reserved or if | |
2036 | LOC doesn't come from the expansion of a macro, the function | |
2037 | returns LOC as is and *MAP is not touched. | |
2038 | ||
2039 | *MAP is set to the map of the returned location if the later is | |
2040 | different from LOC. */ | |
99b1c316 | 2041 | location_t linemap_unwind_to_first_non_reserved_loc (class line_maps *, |
620e594b | 2042 | location_t loc, |
99b1c316 | 2043 | const line_map **map); |
c4ca1a09 | 2044 | |
46427374 | 2045 | /* Expand source code location LOC and return a user readable source |
84756fd4 DS |
2046 | code location. LOC must be a spelling (non-virtual) location. If |
2047 | it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source | |
2048 | location is returned. */ | |
99b1c316 MS |
2049 | expanded_location linemap_expand_location (class line_maps *, |
2050 | const line_map *, | |
620e594b | 2051 | location_t loc); |
46427374 | 2052 | |
64a1a422 TT |
2053 | /* Statistics about maps allocation and usage as returned by |
2054 | linemap_get_statistics. */ | |
2055 | struct linemap_stats | |
2056 | { | |
d17687f6 DS |
2057 | long num_ordinary_maps_allocated; |
2058 | long num_ordinary_maps_used; | |
2059 | long ordinary_maps_allocated_size; | |
2060 | long ordinary_maps_used_size; | |
2061 | long num_expanded_macros; | |
2062 | long num_macro_tokens; | |
2063 | long num_macro_maps_used; | |
2064 | long macro_maps_allocated_size; | |
2065 | long macro_maps_used_size; | |
2066 | long macro_maps_locations_size; | |
2067 | long duplicated_macro_maps_locations_size; | |
ee015909 DM |
2068 | long adhoc_table_size; |
2069 | long adhoc_table_entries_used; | |
64a1a422 TT |
2070 | }; |
2071 | ||
7ecc3eb9 DS |
2072 | /* Return the highest location emitted for a given file for which |
2073 | there is a line map in SET. FILE_NAME is the file name to | |
2074 | consider. If the function returns TRUE, *LOC is set to the highest | |
2075 | location emitted for that file. */ | |
99b1c316 | 2076 | bool linemap_get_file_highest_location (class line_maps * set, |
7ecc3eb9 | 2077 | const char *file_name, |
620e594b | 2078 | location_t *loc); |
7ecc3eb9 | 2079 | |
64a1a422 TT |
2080 | /* Compute and return statistics about the memory consumption of some |
2081 | parts of the line table SET. */ | |
99b1c316 | 2082 | void linemap_get_statistics (line_maps *, struct linemap_stats *); |
64a1a422 | 2083 | |
847e697a TT |
2084 | /* Dump debugging information about source location LOC into the file |
2085 | stream STREAM. SET is the line map set LOC comes from. */ | |
99b1c316 | 2086 | void linemap_dump_location (line_maps *, location_t, FILE *); |
847e697a | 2087 | |
8dcf72a8 DN |
2088 | /* Dump line map at index IX in line table SET to STREAM. If STREAM |
2089 | is NULL, use stderr. IS_MACRO is true if the caller wants to | |
2090 | dump a macro map, false otherwise. */ | |
99b1c316 | 2091 | void linemap_dump (FILE *, line_maps *, unsigned, bool); |
8dcf72a8 DN |
2092 | |
2093 | /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used. | |
2094 | NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO | |
2095 | specifies how many macro maps to dump. */ | |
99b1c316 | 2096 | void line_table_dump (FILE *, line_maps *, unsigned int, unsigned int); |
8dcf72a8 | 2097 | |
620e594b | 2098 | /* An enum for distinguishing the various parts within a location_t. */ |
c471c6ed DM |
2099 | |
2100 | enum location_aspect | |
2101 | { | |
2102 | LOCATION_ASPECT_CARET, | |
2103 | LOCATION_ASPECT_START, | |
2104 | LOCATION_ASPECT_FINISH | |
2105 | }; | |
2106 | ||
620e594b | 2107 | /* The rich_location class requires a way to expand location_t instances. |
8a645150 DM |
2108 | We would directly use expand_location_to_spelling_point, which is |
2109 | implemented in gcc/input.c, but we also need to use it for rich_location | |
2110 | within genmatch.c. | |
2111 | Hence we require client code of libcpp to implement the following | |
2112 | symbol. */ | |
2113 | extern expanded_location | |
620e594b | 2114 | linemap_client_expand_location_to_spelling_point (location_t, |
c471c6ed | 2115 | enum location_aspect); |
8a645150 | 2116 | |
4f4e53dd | 2117 | #endif /* !LIBCPP_LINE_MAP_H */ |