]> git.ipfire.org Git - thirdparty/gcc.git/blame - libcpp/line-map.cc
x86: Handle V16BF in ix86_avx256_split_vector_move_misalign
[thirdparty/gcc.git] / libcpp / line-map.cc
CommitLineData
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
4This program is free software; you can redistribute it and/or modify it
5under the terms of the GNU General Public License as published by the
748086b7 6Free Software Foundation; either version 3, or (at your option) any
d82fc108
NB
7later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
748086b7
JJ
15along 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
22#include "config.h"
23#include "system.h"
24#include "line-map.h"
46427374
TT
25#include "cpplib.h"
26#include "internal.h"
5368224f 27#include "hashtab.h"
d82fc108 28
99b1c316 29static void trace_include (const line_maps *, const line_map_ordinary *);
9158f0ba 30static const line_map_ordinary * linemap_ordinary_map_lookup (const line_maps *,
620e594b 31 location_t);
9158f0ba 32static const line_map_macro* linemap_macro_map_lookup (const line_maps *,
620e594b
DM
33 location_t);
34static location_t linemap_macro_map_loc_to_def_point
35(const line_map_macro *, location_t);
36static location_t linemap_macro_map_loc_to_exp_point
37(const line_map_macro *, location_t);
38static location_t linemap_macro_loc_to_spelling_point
99b1c316 39(line_maps *, location_t, const line_map_ordinary **);
620e594b
DM
40static location_t linemap_macro_loc_to_def_point (line_maps *,
41 location_t,
42 const line_map_ordinary **);
43static location_t linemap_macro_loc_to_exp_point (line_maps *,
44 location_t,
45 const line_map_ordinary **);
5993019d 46
e53b6e56 47/* Counters defined in macro.cc. */
64a1a422
TT
48extern unsigned num_expanded_macros_counter;
49extern unsigned num_macro_tokens_counter;
50
2be1b796
DM
51/* Destructor for class line_maps.
52 Ensure non-GC-managed memory is released. */
53
54line_maps::~line_maps ()
55{
c3684b7b
MS
56 if (location_adhoc_data_map.htab)
57 htab_delete (location_adhoc_data_map.htab);
2be1b796
DM
58}
59
5368224f
DC
60/* Hash function for location_adhoc_data hashtable. */
61
62static hashval_t
63location_adhoc_data_hash (const void *l)
64{
65 const struct location_adhoc_data *lb =
66 (const struct location_adhoc_data *) l;
ebedc9a3
DM
67 return ((hashval_t) lb->locus
68 + (hashval_t) lb->src_range.m_start
69 + (hashval_t) lb->src_range.m_finish
70 + (size_t) lb->data);
5368224f
DC
71}
72
73/* Compare function for location_adhoc_data hashtable. */
74
75static int
76location_adhoc_data_eq (const void *l1, const void *l2)
77{
78 const struct location_adhoc_data *lb1 =
79 (const struct location_adhoc_data *) l1;
80 const struct location_adhoc_data *lb2 =
81 (const struct location_adhoc_data *) l2;
ebedc9a3
DM
82 return (lb1->locus == lb2->locus
83 && lb1->src_range.m_start == lb2->src_range.m_start
84 && lb1->src_range.m_finish == lb2->src_range.m_finish
85 && lb1->data == lb2->data);
5368224f
DC
86}
87
88/* Update the hashtable when location_adhoc_data is reallocated. */
89
90static int
91location_adhoc_data_update (void **slot, void *data)
92{
6d522731
JJ
93 *((char **) slot)
94 = (char *) ((uintptr_t) *((char **) slot) + *((ptrdiff_t *) data));
5368224f
DC
95 return 1;
96}
97
52187008
DC
98/* Rebuild the hash table from the location adhoc data. */
99
100void
99b1c316 101rebuild_location_adhoc_htab (line_maps *set)
52187008
DC
102{
103 unsigned i;
104 set->location_adhoc_data_map.htab =
105 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
106 for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
107 htab_find_slot (set->location_adhoc_data_map.htab,
108 set->location_adhoc_data_map.data + i, INSERT);
109}
110
ebedc9a3
DM
111/* Helper function for get_combined_adhoc_loc.
112 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
620e594b 113 within a location_t, without needing to use an ad-hoc location. */
ebedc9a3
DM
114
115static bool
99b1c316 116can_be_stored_compactly_p (line_maps *set,
620e594b 117 location_t locus,
ebedc9a3
DM
118 source_range src_range,
119 void *data)
120{
121 /* If there's an ad-hoc pointer, we can't store it directly in the
620e594b 122 location_t, we need the lookaside. */
ebedc9a3
DM
123 if (data)
124 return false;
125
126 /* We only store ranges that begin at the locus and that are sufficiently
127 "sane". */
128 if (src_range.m_start != locus)
129 return false;
130
131 if (src_range.m_finish < src_range.m_start)
132 return false;
133
134 if (src_range.m_start < RESERVED_LOCATION_COUNT)
135 return false;
136
c7df95d8 137 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
ebedc9a3
DM
138 return false;
139
140 /* All 3 locations must be within ordinary maps, typically, the same
141 ordinary map. */
620e594b 142 location_t lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
ebedc9a3
DM
143 if (locus >= lowest_macro_loc)
144 return false;
145 if (src_range.m_start >= lowest_macro_loc)
146 return false;
147 if (src_range.m_finish >= lowest_macro_loc)
148 return false;
149
150 /* Passed all tests. */
151 return true;
152}
153
5368224f
DC
154/* Combine LOCUS and DATA to a combined adhoc loc. */
155
620e594b 156location_t
99b1c316 157get_combined_adhoc_loc (line_maps *set,
620e594b 158 location_t locus,
ebedc9a3
DM
159 source_range src_range,
160 void *data)
5368224f
DC
161{
162 struct location_adhoc_data lb;
163 struct location_adhoc_data **slot;
164
5368224f 165 if (IS_ADHOC_LOC (locus))
e6fc8353 166 locus = get_location_from_adhoc_loc (set, locus);
5368224f
DC
167 if (locus == 0 && data == NULL)
168 return 0;
ebedc9a3
DM
169
170 /* Any ordinary locations ought to be "pure" at this point: no
171 compressed ranges. */
172 linemap_assert (locus < RESERVED_LOCATION_COUNT
c7df95d8 173 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
ebedc9a3
DM
174 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
175 || pure_location_p (set, locus));
176
177 /* Consider short-range optimization. */
178 if (can_be_stored_compactly_p (set, locus, src_range, data))
179 {
180 /* The low bits ought to be clear. */
181 linemap_assert (pure_location_p (set, locus));
182 const line_map *map = linemap_lookup (set, locus);
183 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
184 unsigned int int_diff = src_range.m_finish - src_range.m_start;
185 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
186 if (col_diff < (1U << ordmap->m_range_bits))
187 {
620e594b 188 location_t packed = locus | col_diff;
ebedc9a3
DM
189 set->num_optimized_ranges++;
190 return packed;
191 }
192 }
193
329590d7 194 /* We can also compactly store locations
ebedc9a3 195 when locus == start == finish (and data is NULL). */
329590d7 196 if (locus == src_range.m_start
ebedc9a3
DM
197 && locus == src_range.m_finish
198 && !data)
199 return locus;
200
201 if (!data)
202 set->num_unoptimized_ranges++;
203
5368224f 204 lb.locus = locus;
ebedc9a3 205 lb.src_range = src_range;
5368224f
DC
206 lb.data = data;
207 slot = (struct location_adhoc_data **)
208 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
209 if (*slot == NULL)
210 {
211 if (set->location_adhoc_data_map.curr_loc >=
212 set->location_adhoc_data_map.allocated)
213 {
214 char *orig_data = (char *) set->location_adhoc_data_map.data;
6d522731 215 ptrdiff_t offset;
8ac16127
MG
216 /* Cast away extern "C" from the type of xrealloc. */
217 line_map_realloc reallocator = (set->reallocator
218 ? set->reallocator
219 : (line_map_realloc) xrealloc);
52187008
DC
220
221 if (set->location_adhoc_data_map.allocated == 0)
222 set->location_adhoc_data_map.allocated = 128;
223 else
224 set->location_adhoc_data_map.allocated *= 2;
225 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
226 reallocator (set->location_adhoc_data_map.data,
227 set->location_adhoc_data_map.allocated
228 * sizeof (struct location_adhoc_data));
5368224f 229 offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
52187008
DC
230 if (set->location_adhoc_data_map.allocated > 128)
231 htab_traverse (set->location_adhoc_data_map.htab,
232 location_adhoc_data_update, &offset);
5368224f
DC
233 }
234 *slot = set->location_adhoc_data_map.data
235 + set->location_adhoc_data_map.curr_loc;
acf601ae
JJ
236 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
237 = lb;
5368224f
DC
238 }
239 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
240}
241
242/* Return the data for the adhoc loc. */
243
244void *
99b1c316 245get_data_from_adhoc_loc (const class line_maps *set, location_t loc)
5368224f
DC
246{
247 linemap_assert (IS_ADHOC_LOC (loc));
620e594b 248 return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
5368224f
DC
249}
250
251/* Return the location for the adhoc loc. */
252
620e594b 253location_t
99b1c316 254get_location_from_adhoc_loc (const class line_maps *set, location_t loc)
5368224f
DC
255{
256 linemap_assert (IS_ADHOC_LOC (loc));
620e594b 257 return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;
5368224f
DC
258}
259
ebedc9a3
DM
260/* Return the source_range for adhoc location LOC. */
261
262static source_range
99b1c316 263get_range_from_adhoc_loc (const class line_maps *set, location_t loc)
ebedc9a3
DM
264{
265 linemap_assert (IS_ADHOC_LOC (loc));
620e594b 266 return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].src_range;
ebedc9a3
DM
267}
268
269/* Get the source_range of location LOC, either from the ad-hoc
270 lookaside table, or embedded inside LOC itself. */
271
272source_range
99b1c316 273get_range_from_loc (line_maps *set,
620e594b 274 location_t loc)
ebedc9a3
DM
275{
276 if (IS_ADHOC_LOC (loc))
277 return get_range_from_adhoc_loc (set, loc);
278
279 /* For ordinary maps, extract packed range. */
280 if (loc >= RESERVED_LOCATION_COUNT
281 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
c7df95d8 282 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
ebedc9a3
DM
283 {
284 const line_map *map = linemap_lookup (set, loc);
285 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
286 source_range result;
287 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
288 result.m_start = loc - offset;
289 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
290 return result;
291 }
292
293 return source_range::from_location (loc);
294}
295
296/* Get whether location LOC is a "pure" location, or
297 whether it is an ad-hoc location, or embeds range information. */
298
299bool
620e594b 300pure_location_p (line_maps *set, location_t loc)
ebedc9a3
DM
301{
302 if (IS_ADHOC_LOC (loc))
303 return false;
304
305 const line_map *map = linemap_lookup (set, loc);
cf806c7d
L
306 if (map == NULL)
307 return true;
ebedc9a3
DM
308 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
309
310 if (loc & ((1U << ordmap->m_range_bits) - 1))
311 return false;
312
313 return true;
314}
315
2aa51413
DM
316/* Given location LOC within SET, strip away any packed range information
317 or ad-hoc information. */
318
620e594b
DM
319location_t
320get_pure_location (line_maps *set, location_t loc)
2aa51413
DM
321{
322 if (IS_ADHOC_LOC (loc))
e6fc8353 323 loc = get_location_from_adhoc_loc (set, loc);
2aa51413
DM
324
325 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
326 return loc;
327
328 if (loc < RESERVED_LOCATION_COUNT)
329 return loc;
330
331 const line_map *map = linemap_lookup (set, loc);
332 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
333
334 return loc & ~((1 << ordmap->m_range_bits) - 1);
335}
336
d82fc108
NB
337/* Initialize a line map set. */
338
339void
99b1c316 340linemap_init (line_maps *set,
620e594b 341 location_t builtin_location)
d82fc108 342{
fe74f9b4
RB
343#if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
344 /* PR33916, needed to fix PR82939. */
99b1c316 345 memset (set, 0, sizeof (line_maps));
fe74f9b4 346#else
b2ff7457 347 new (set) line_maps();
fe74f9b4 348#endif
e81c3c4d
NS
349 /* Set default reallocator (used for initial alloc too). */
350 set->reallocator = xrealloc;
96c169e1
JJ
351 set->highest_location = RESERVED_LOCATION_COUNT - 1;
352 set->highest_line = RESERVED_LOCATION_COUNT - 1;
52187008
DC
353 set->location_adhoc_data_map.htab =
354 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
c468587a 355 set->builtin_location = builtin_location;
d82fc108
NB
356}
357
f10a9135
NS
358/* Return the ordinary line map from whence MAP was included. Returns
359 NULL if MAP was not an include. */
360
361const line_map_ordinary *
362linemap_included_from_linemap (line_maps *set, const line_map_ordinary *map)
363{
364 return linemap_ordinary_map_lookup (set, linemap_included_from (map));
365}
366
9ac97460 367/* Check for and warn about line_maps entered but not exited. */
12f9df4e
PB
368
369void
99b1c316 370linemap_check_files_exited (line_maps *set)
12f9df4e 371{
12f9df4e
PB
372 /* Depending upon whether we are handling preprocessed input or
373 not, this can be a user error or an ICE. */
f10a9135 374 for (const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
46427374 375 ! MAIN_FILE_P (map);
f10a9135 376 map = linemap_included_from_linemap (set, map))
e53b6e56 377 fprintf (stderr, "line-map.cc: file \"%s\" entered but not left\n",
46427374 378 ORDINARY_MAP_FILE_NAME (map));
12f9df4e 379}
d82fc108 380
1f8ac759 381/* Create NUM zero-initialized maps of type MACRO_P. */
46427374 382
1f8ac759
NS
383line_map *
384line_map_new_raw (line_maps *set, bool macro_p, unsigned num)
d82fc108 385{
e81c3c4d
NS
386 unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
387 unsigned num_maps_used = LINEMAPS_USED (set, macro_p);
1f8ac759
NS
388
389 if (num > num_maps_allocated - num_maps_used)
fde84349 390 {
e81c3c4d
NS
391 /* We need more space! */
392 if (!num_maps_allocated)
393 num_maps_allocated = 128;
1f8ac759
NS
394 if (num_maps_allocated < num_maps_used + num)
395 num_maps_allocated = num_maps_used + num;
e81c3c4d
NS
396 num_maps_allocated *= 2;
397
398 size_t size_of_a_map;
399 void *buffer;
400 if (macro_p)
401 {
402 size_of_a_map = sizeof (line_map_macro);
403 buffer = set->info_macro.maps;
404 }
405 else
406 {
407 size_of_a_map = sizeof (line_map_ordinary);
408 buffer = set->info_ordinary.maps;
409 }
0e50b624 410
b9bd6f74
TT
411 /* We are going to execute some dance to try to reduce the
412 overhead of the memory allocator, in case we are using the
e53b6e56 413 ggc-page.cc one.
b9bd6f74
TT
414
415 The actual size of memory we are going to get back from the
e81c3c4d
NS
416 allocator may well be larger than what we ask for. Use this
417 hook to find what that size is. */
418 size_t alloc_size
419 = set->round_alloc_size (num_maps_allocated * size_of_a_map);
b9bd6f74
TT
420
421 /* Now alloc_size contains the exact memory size we would get if
422 we have asked for the initial alloc_size amount of memory.
e81c3c4d
NS
423 Let's get back to the number of map that amounts to. */
424 unsigned num_maps = alloc_size / size_of_a_map;
425 buffer = set->reallocator (buffer, num_maps * size_of_a_map);
426 memset ((char *)buffer + num_maps_used * size_of_a_map, 0,
427 (num_maps - num_maps_used) * size_of_a_map);
428 if (macro_p)
429 set->info_macro.maps = (line_map_macro *)buffer;
0e50b624 430 else
e81c3c4d
NS
431 set->info_ordinary.maps = (line_map_ordinary *)buffer;
432 LINEMAPS_ALLOCATED (set, macro_p) = num_maps;
0e50b624 433 }
46427374 434
e81c3c4d
NS
435 line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used]
436 : (line_map *)&set->info_ordinary.maps[num_maps_used]);
1f8ac759
NS
437 LINEMAPS_USED (set, macro_p) += num;
438
439 return result;
440}
441
442/* Create a new line map in the line map set SET, and return it.
443 REASON is the reason of creating the map. It determines the type
444 of map created (ordinary or macro map). Note that ordinary maps and
445 macro maps are allocated in different memory location. */
446
447static struct line_map *
448new_linemap (line_maps *set, location_t start_location)
449{
450 line_map *result = line_map_new_raw (set,
451 start_location >= LINE_MAP_MAX_LOCATION,
452 1);
42a98b43 453
e81c3c4d 454 result->start_location = start_location;
46427374 455
46427374 456 return result;
d82fc108
NB
457}
458
1f8ac759
NS
459/* Return the location of the last source line within an ordinary
460 map. */
461inline location_t
462LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
463{
464 return (((map[1].start_location - 1
465 - map->start_location)
466 & ~((1 << map->m_column_and_range_bits) - 1))
467 + map->start_location);
468}
469
d82fc108 470/* Add a mapping of logical source line to physical source file and
9074464c
GK
471 line number.
472
473 The text pointed to by TO_FILE must have a lifetime
474 at least as long as the final call to lookup_line (). An empty
475 TO_FILE means standard input. If reason is LC_LEAVE, and
476 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
477 natural values considering the file we are returning to.
d82fc108
NB
478
479 FROM_LINE should be monotonic increasing across calls to this
9074464c
GK
480 function. A call to this function can relocate the previous set of
481 maps, so any stored line_map pointers should not be used. */
d82fc108 482
47d89cf3 483const struct line_map *
99b1c316 484linemap_add (line_maps *set, enum lc_reason reason,
1bb64668 485 unsigned int sysp, const char *to_file, linenum_type to_line)
d82fc108 486{
ebedc9a3
DM
487 /* Generate a start_location above the current highest_location.
488 If possible, make the low range bits be zero. */
a926eeed
NS
489 location_t start_location = set->highest_location + 1;
490 unsigned range_bits = 0;
491 if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
492 range_bits = set->default_range_bits;
493 start_location += (1 << range_bits) - 1;
494 start_location &= ~((1 << range_bits) - 1);
d82fc108 495
42a98b43
NS
496 linemap_assert (!LINEMAPS_ORDINARY_USED (set)
497 || (start_location
498 >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
46427374
TT
499
500 /* When we enter the file for the first time reason cannot be
501 LC_RENAME. */
502 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
d82fc108 503
46427374
TT
504 /* If we are leaving the main file, return a NULL map. */
505 if (reason == LC_LEAVE
506 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
507 && to_file == NULL)
d82fc108 508 {
46427374
TT
509 set->depth--;
510 return NULL;
d82fc108
NB
511 }
512
0e50b624 513 linemap_assert (reason != LC_ENTER_MACRO);
cf806c7d
L
514
515 if (start_location >= LINE_MAP_MAX_LOCATION)
516 /* We ran out of line map space. */
517 start_location = 0;
518
42a98b43
NS
519 line_map_ordinary *map
520 = linemap_check_ordinary (new_linemap (set, start_location));
521 map->reason = reason;
d82fc108 522
c7f9c0b9 523 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
9074464c
GK
524 to_file = "<stdin>";
525
c7f9c0b9
JM
526 if (reason == LC_RENAME_VERBATIM)
527 reason = LC_RENAME;
528
f10a9135 529 const line_map_ordinary *from = NULL;
892a371f 530 if (reason == LC_LEAVE)
fde84349 531 {
46427374
TT
532 /* When we are just leaving an "included" file, and jump to the next
533 location inside the "includer" right after the #include
534 "included", this variable points the map in use right before the
535 #include "included", inside the same "includer" file. */
47d89cf3 536
3caf0ca1
BS
537 linemap_assert (!MAIN_FILE_P (map - 1));
538 /* (MAP - 1) points to the map we are leaving. The
539 map from which (MAP - 1) got included should be the map
540 that comes right before MAP in the same file. */
f10a9135 541 from = linemap_included_from_linemap (set, map - 1);
47d89cf3
NB
542
543 /* A TO_FILE of NULL is special - we use the natural values. */
3caf0ca1 544 if (to_file == NULL)
47d89cf3 545 {
46427374 546 to_file = ORDINARY_MAP_FILE_NAME (from);
12f9df4e 547 to_line = SOURCE_LINE (from, from[1].start_location);
46427374 548 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
fde84349 549 }
3caf0ca1
BS
550 else
551 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
552 to_file) == 0);
fde84349
NB
553 }
554
c819ed29 555 map->sysp = sysp;
c819ed29
DM
556 map->to_file = to_file;
557 map->to_line = to_line;
46427374 558 LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
a926eeed
NS
559 /* Do not store range_bits here. That's readjusted in
560 linemap_line_start. */
561 map->m_range_bits = map->m_column_and_range_bits = 0;
12f9df4e 562 set->highest_location = start_location;
500bee0a 563 set->highest_line = start_location;
12f9df4e 564 set->max_column_hint = 0;
47d89cf3 565
ebedc9a3
DM
566 /* This assertion is placed after set->highest_location has
567 been updated, since the latter affects
568 linemap_location_from_macro_expansion_p, which ultimately affects
569 pure_location_p. */
570 linemap_assert (pure_location_p (set, start_location));
571
fde84349 572 if (reason == LC_ENTER)
d8693c6f 573 {
f10a9135
NS
574 if (set->depth == 0)
575 map->included_from = 0;
576 else
577 /* The location of the end of the just-closed map. */
578 map->included_from
579 = (((map[0].start_location - 1 - map[-1].start_location)
580 & ~((1 << map[-1].m_column_and_range_bits) - 1))
581 + map[-1].start_location);
d8693c6f 582 set->depth++;
d8693c6f
NB
583 if (set->trace_includes)
584 trace_include (set, map);
585 }
d82fc108 586 else if (reason == LC_RENAME)
f10a9135 587 map->included_from = linemap_included_from (&map[-1]);
d82fc108 588 else if (reason == LC_LEAVE)
d8693c6f
NB
589 {
590 set->depth--;
f10a9135 591 map->included_from = linemap_included_from (from);
d8693c6f 592 }
5993019d 593
d82fc108
NB
594 return map;
595}
596
1f8ac759
NS
597/* Create a location for a module NAME imported at FROM. */
598
599location_t
600linemap_module_loc (line_maps *set, location_t from, const char *name)
601{
602 const line_map_ordinary *map
603 = linemap_check_ordinary (linemap_add (set, LC_MODULE, false, name, 0));
604 const_cast <line_map_ordinary *> (map)->included_from = from;
605
606 location_t loc = linemap_line_start (set, 0, 0);
607
608 return loc;
609}
610
611/* The linemap containing LOC is being reparented to be
612 imported/included from ADOPTOR. This can happen when an
613 indirectly imported module is then directly imported, or when
614 partitions are involved. */
615
616void
617linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor)
618{
619 const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc);
620 const_cast<line_map_ordinary *> (map)->included_from = adoptor;
621}
622
623/* A linemap at LWM-1 was interrupted to insert module locations & imports.
f207eed6
NS
624 Append a new map, continuing the interrupted one. Return the start location
625 of the new map, or 0 if failed (because we ran out of locations. */
1f8ac759 626
f207eed6 627unsigned
1f8ac759
NS
628linemap_module_restore (line_maps *set, unsigned lwm)
629{
f207eed6
NS
630 linemap_assert (lwm);
631
632 const line_map_ordinary *pre_map
633 = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1));
634 unsigned src_line = SOURCE_LINE (pre_map, LAST_SOURCE_LINE_LOCATION (pre_map));
635 location_t inc_at = pre_map->included_from;
636 if (const line_map_ordinary *post_map
637 = (linemap_check_ordinary
638 (linemap_add (set, LC_RENAME_VERBATIM,
639 ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map),
640 ORDINARY_MAP_FILE_NAME (pre_map), src_line))))
1f8ac759 641 {
f207eed6
NS
642 /* linemap_add will think we were included from the same as the preceeding
643 map. */
644 const_cast <line_map_ordinary *> (post_map)->included_from = inc_at;
645
646 return post_map->start_location;
1f8ac759 647 }
f207eed6
NS
648
649 return 0;
1f8ac759
NS
650}
651
7d9641cc 652/* Returns TRUE if the line table set tracks token locations across
46427374
TT
653 macro expansion, FALSE otherwise. */
654
655bool
99b1c316 656linemap_tracks_macro_expansion_locs_p (line_maps *set)
46427374
TT
657{
658 return LINEMAPS_MACRO_MAPS (set) != NULL;
659}
660
661/* Create a macro map. A macro map encodes source locations of tokens
662 that are part of a macro replacement-list, at a macro expansion
663 point. See the extensive comments of struct line_map and struct
664 line_map_macro, in line-map.h.
665
666 This map shall be created when the macro is expanded. The map
667 encodes the source location of the expansion point of the macro as
668 well as the "original" source location of each token that is part
669 of the macro replacement-list. If a macro is defined but never
670 expanded, it has no macro map. SET is the set of maps the macro
671 map should be part of. MACRO_NODE is the macro which the new macro
672 map should encode source locations for. EXPANSION is the location
673 of the expansion point of MACRO. For function-like macros
674 invocations, it's best to make it point to the closing parenthesis
675 of the macro, rather than the the location of the first character
676 of the macro. NUM_TOKENS is the number of tokens that are part of
677 the replacement-list of MACRO.
678
679 Note that when we run out of the integer space available for source
680 locations, this function returns NULL. In that case, callers of
681 this function cannot encode {line,column} pairs into locations of
682 macro tokens anymore. */
683
0e50b624 684const line_map_macro *
99b1c316 685linemap_enter_macro (class line_maps *set, struct cpp_hashnode *macro_node,
620e594b 686 location_t expansion, unsigned int num_tokens)
46427374 687{
620e594b 688 location_t start_location
c1b48b29 689 = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
46427374 690
42a98b43 691 if (start_location < LINE_MAP_MAX_LOCATION)
46427374
TT
692 /* We ran out of macro map space. */
693 return NULL;
694
c1b48b29 695 line_map_macro *map = linemap_check_macro (new_linemap (set, start_location));
46427374 696
c819ed29
DM
697 map->macro = macro_node;
698 map->n_tokens = num_tokens;
699 map->macro_locations
620e594b 700 = (location_t*) set->reallocator (NULL,
c1b48b29 701 2 * num_tokens
620e594b 702 * sizeof (location_t));
c819ed29 703 map->expansion = expansion;
46427374 704 memset (MACRO_MAP_LOCATIONS (map), 0,
620e594b 705 2 * num_tokens * sizeof (location_t));
46427374
TT
706
707 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
46427374
TT
708
709 return map;
710}
711
712/* Create and return a virtual location for a token that is part of a
713 macro expansion-list at a macro expansion point. See the comment
714 inside struct line_map_macro to see what an expansion-list exactly
715 is.
716
717 A call to this function must come after a call to
718 linemap_enter_macro.
719
720 MAP is the map into which the source location is created. TOKEN_NO
721 is the index of the token in the macro replacement-list, starting
722 at number 0.
723
724 ORIG_LOC is the location of the token outside of this macro
725 expansion. If the token comes originally from the macro
726 definition, it is the locus in the macro definition; otherwise it
727 is a location in the context of the caller of this macro expansion
728 (which is a virtual location or a source location if the caller is
729 itself a macro expansion or not).
730
3aac0952 731 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
46427374
TT
732 either of the token itself or of a macro parameter that it
733 replaces. */
734
620e594b 735location_t
0e50b624 736linemap_add_macro_token (const line_map_macro *map,
46427374 737 unsigned int token_no,
620e594b
DM
738 location_t orig_loc,
739 location_t orig_parm_replacement_loc)
46427374 740{
620e594b 741 location_t result;
46427374
TT
742
743 linemap_assert (linemap_macro_expansion_map_p (map));
744 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
745
746 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
747 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
748
749 result = MAP_START_LOCATION (map) + token_no;
750 return result;
751}
752
620e594b 753/* Return a location_t for the start (i.e. column==0) of
46427374
TT
754 (physical) line TO_LINE in the current source file (as in the
755 most recent linemap_add). MAX_COLUMN_HINT is the highest column
756 number we expect to use in this line (but it does not change
757 the highest_location). */
758
620e594b 759location_t
99b1c316 760linemap_line_start (line_maps *set, linenum_type to_line,
12f9df4e
PB
761 unsigned int max_column_hint)
762{
0e50b624 763 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
620e594b
DM
764 location_t highest = set->highest_location;
765 location_t r;
46427374
TT
766 linenum_type last_line =
767 SOURCE_LINE (map, set->highest_line);
12f9df4e
PB
768 int line_delta = to_line - last_line;
769 bool add_map = false;
ebedc9a3
DM
770 linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
771 int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
46427374 772
12f9df4e 773 if (line_delta < 0
46427374 774 || (line_delta > 10
ebedc9a3
DM
775 && line_delta * map->m_column_and_range_bits > 1000)
776 || (max_column_hint >= (1U << effective_column_bits))
777 || (max_column_hint <= 80 && effective_column_bits >= 10)
c7df95d8
DM
778 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
779 && map->m_range_bits > 0)
815facd3 780 || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
42a98b43 781 && (set->max_column_hint || highest >= LINE_MAP_MAX_LOCATION)))
43ba1c6c 782 add_map = true;
12f9df4e
PB
783 else
784 max_column_hint = set->max_column_hint;
785 if (add_map)
786 {
787 int column_bits;
ebedc9a3 788 int range_bits;
815facd3
MLI
789 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
790 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
12f9df4e 791 {
c1fc5047 792 /* If the column number is ridiculous or we've allocated a huge
620e594b 793 number of location_ts, give up on column numbers
ebedc9a3 794 (and on packed ranges). */
924b9276 795 max_column_hint = 1;
12f9df4e 796 column_bits = 0;
ebedc9a3 797 range_bits = 0;
42a98b43 798 if (highest >= LINE_MAP_MAX_LOCATION)
924b9276 799 goto overflowed;
12f9df4e
PB
800 }
801 else
802 {
803 column_bits = 7;
c7df95d8
DM
804 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
805 range_bits = set->default_range_bits;
806 else
807 range_bits = 0;
12f9df4e
PB
808 while (max_column_hint >= (1U << column_bits))
809 column_bits++;
810 max_column_hint = 1U << column_bits;
ebedc9a3 811 column_bits += range_bits;
12f9df4e 812 }
924b9276 813
c1fc5047
PB
814 /* Allocate the new line_map. However, if the current map only has a
815 single line we can sometimes just increase its column_bits instead. */
12f9df4e 816 if (line_delta < 0
46427374 817 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
5ccf1d8d 818 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
a4553534
DM
819 || ( /* We can't reuse the map if the line offset is sufficiently
820 large to cause overflow when computing location_t values. */
821 (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
a5f87af7
ML
822 >= (((uint64_t) 1)
823 << (CHAR_BIT * sizeof (linenum_type) - column_bits)))
c7df95d8 824 || range_bits < map->m_range_bits)
0e50b624
DM
825 map = linemap_check_ordinary
826 (const_cast <line_map *>
827 (linemap_add (set, LC_RENAME,
828 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
829 ORDINARY_MAP_FILE_NAME (map),
830 to_line)));
ebedc9a3
DM
831 map->m_column_and_range_bits = column_bits;
832 map->m_range_bits = range_bits;
46427374
TT
833 r = (MAP_START_LOCATION (map)
834 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
835 << column_bits));
12f9df4e
PB
836 }
837 else
ebedc9a3 838 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
46427374
TT
839
840 /* Locations of ordinary tokens are always lower than locations of
841 macro tokens. */
42a98b43 842 if (r >= LINE_MAP_MAX_LOCATION)
056f95ec 843 {
924b9276 844 overflowed:
056f95ec
NS
845 /* Remember we overflowed. */
846 set->highest_line = set->highest_location = LINE_MAP_MAX_LOCATION - 1;
924b9276
NS
847 /* No column numbers! */
848 set->max_column_hint = 1;
056f95ec
NS
849 return 0;
850 }
46427374 851
500bee0a 852 set->highest_line = r;
12f9df4e
PB
853 if (r > set->highest_location)
854 set->highest_location = r;
855 set->max_column_hint = max_column_hint;
ebedc9a3
DM
856
857 /* At this point, we expect one of:
858 (a) the normal case: a "pure" location with 0 range bits, or
859 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
860 columns anymore (or ranges), or
861 (c) we're in a region with a column hint exceeding
862 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
863 with column_bits == 0. */
864 linemap_assert (pure_location_p (set, r)
865 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
866 || map->m_column_and_range_bits == 0);
867 linemap_assert (SOURCE_LINE (map, r) == to_line);
12f9df4e
PB
868 return r;
869}
870
620e594b 871/* Encode and return a location_t from a column number. The
46427374
TT
872 source line considered is the last source line used to call
873 linemap_line_start, i.e, the last source line which a location was
874 encoded from. */
875
620e594b 876location_t
99b1c316 877linemap_position_for_column (line_maps *set, unsigned int to_column)
500bee0a 878{
620e594b 879 location_t r = set->highest_line;
46427374
TT
880
881 linemap_assert
882 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
883
500bee0a
PB
884 if (to_column >= set->max_column_hint)
885 {
815facd3
MLI
886 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
887 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
500bee0a 888 {
620e594b 889 /* Running low on location_ts - disable column numbers. */
500bee0a
PB
890 return r;
891 }
892 else
893 {
b9f4757f
DM
894 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
895 with some space to spare. This may or may not lead to a new
896 linemap being created. */
0e50b624 897 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
500bee0a 898 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
b9f4757f
DM
899 map = LINEMAPS_LAST_ORDINARY_MAP (set);
900 if (map->m_column_and_range_bits == 0)
901 {
902 /* ...then the linemap has column-tracking disabled,
903 presumably due to exceeding either
904 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
905 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
906 Return the start of the linemap, which encodes column 0, for
907 the whole line. */
908 return r;
909 }
500bee0a
PB
910 }
911 }
ebedc9a3
DM
912 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
913 r = r + (to_column << map->m_range_bits);
500bee0a
PB
914 if (r >= set->highest_location)
915 set->highest_location = r;
916 return r;
917}
918
46427374
TT
919/* Encode and return a source location from a given line and
920 column. */
d82fc108 921
620e594b 922location_t
ebedc9a3
DM
923linemap_position_for_line_and_column (line_maps *set,
924 const line_map_ordinary *ord_map,
46427374
TT
925 linenum_type line,
926 unsigned column)
927{
0e50b624 928 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
46427374 929
620e594b 930 location_t r = MAP_START_LOCATION (ord_map);
ebedc9a3
DM
931 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
932 << ord_map->m_column_and_range_bits);
933 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
934 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
935 << ord_map->m_range_bits);
620e594b 936 location_t upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
ebedc9a3
DM
937 if (r >= upper_limit)
938 r = upper_limit - 1;
939 if (r > set->highest_location)
940 set->highest_location = r;
941 return r;
46427374
TT
942}
943
620e594b 944/* Encode and return a location_t starting from location LOC and
7168133a 945 shifting it by COLUMN_OFFSET columns. This function does not support
3aa34c1d
MLI
946 virtual locations. */
947
620e594b 948location_t
99b1c316 949linemap_position_for_loc_and_offset (line_maps *set,
620e594b 950 location_t loc,
7168133a 951 unsigned int column_offset)
3aa34c1d 952{
0e50b624 953 const line_map_ordinary * map = NULL;
3aa34c1d 954
ebedc9a3 955 if (IS_ADHOC_LOC (loc))
e6fc8353 956 loc = get_location_from_adhoc_loc (set, loc);
ebedc9a3 957
3aa34c1d 958 /* This function does not support virtual locations yet. */
338035aa 959 if (linemap_location_from_macro_expansion_p (set, loc))
73bd8329 960 return loc;
3aa34c1d 961
7168133a 962 if (column_offset == 0
3aa34c1d
MLI
963 /* Adding an offset to a reserved location (like
964 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
965 sense. So let's leave the location intact in that case. */
966 || loc < RESERVED_LOCATION_COUNT)
967 return loc;
968
969 /* We find the real location and shift it. */
970 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
971 /* The new location (loc + offset) should be higher than the first
87b470b3
MLI
972 location encoded by MAP. This can fail if the line information
973 is messed up because of line directives (see PR66415). */
7168133a 974 if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
73bd8329 975 return loc;
3aa34c1d 976
87b470b3
MLI
977 linenum_type line = SOURCE_LINE (map, loc);
978 unsigned int column = SOURCE_COLUMN (map, loc);
979
3aa34c1d
MLI
980 /* If MAP is not the last line map of its set, then the new location
981 (loc + offset) should be less than the first location encoded by
87b470b3
MLI
982 the next line map of the set. Otherwise, we try to encode the
983 location in the next map. */
4acb3af3 984 for (; map != LINEMAPS_LAST_ORDINARY_MAP (set)
2f422b55 985 && (loc + (column_offset << map->m_range_bits)
4acb3af3
NS
986 >= MAP_START_LOCATION (map + 1)); map++)
987 /* If the next map is a different file, or starts in a higher line, we
988 cannot encode the location there. */
989 if ((map + 1)->reason != LC_RENAME
990 || line < ORDINARY_MAP_STARTING_LINE_NUMBER (map + 1)
991 || 0 != strcmp (LINEMAP_FILE (map + 1), LINEMAP_FILE (map)))
992 return loc;
3aa34c1d 993
7168133a 994 column += column_offset;
b9f4757f
DM
995
996 /* Bail out if the column is not representable within the existing
997 linemap. */
998 if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
73bd8329 999 return loc;
3aa34c1d 1000
620e594b 1001 location_t r =
7168133a 1002 linemap_position_for_line_and_column (set, map, line, column);
b93c0722
MLI
1003 if (linemap_assert_fails (r <= set->highest_location)
1004 || linemap_assert_fails (map == linemap_lookup (set, r)))
73bd8329
MLI
1005 return loc;
1006
3aa34c1d
MLI
1007 return r;
1008}
1009
46427374
TT
1010/* Given a virtual source location yielded by a map (either an
1011 ordinary or a macro map), returns that map. */
1012
1013const struct line_map*
9158f0ba 1014linemap_lookup (const line_maps *set, location_t line)
46427374 1015{
5368224f 1016 if (IS_ADHOC_LOC (line))
e6fc8353 1017 line = get_location_from_adhoc_loc (set, line);
46427374
TT
1018 if (linemap_location_from_macro_expansion_p (set, line))
1019 return linemap_macro_map_lookup (set, line);
1020 return linemap_ordinary_map_lookup (set, line);
1021}
1022
1023/* Given a source location yielded by an ordinary map, returns that
1024 map. Since the set is built chronologically, the logical lines are
1025 monotonic increasing, and so the list is sorted and we can use a
1026 binary search. */
1027
0e50b624 1028static const line_map_ordinary *
9158f0ba 1029linemap_ordinary_map_lookup (const line_maps *set, location_t line)
d82fc108 1030{
5368224f 1031 if (IS_ADHOC_LOC (line))
e6fc8353 1032 line = get_location_from_adhoc_loc (set, line);
5368224f 1033
46427374
TT
1034 if (set == NULL || line < RESERVED_LOCATION_COUNT)
1035 return NULL;
1036
a926eeed
NS
1037 unsigned mn = LINEMAPS_ORDINARY_CACHE (set);
1038 unsigned mx = LINEMAPS_ORDINARY_USED (set);
9158f0ba 1039
a926eeed 1040 const line_map_ordinary *cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
9ac97460 1041 /* We should get a segfault if no line_maps have been added yet. */
46427374 1042 if (line >= MAP_START_LOCATION (cached))
9132fbb7 1043 {
46427374 1044 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
9132fbb7
PB
1045 return cached;
1046 }
1047 else
1048 {
1049 mx = mn;
1050 mn = 0;
1051 }
d82fc108
NB
1052
1053 while (mx - mn > 1)
1054 {
a926eeed 1055 unsigned md = (mn + mx) / 2;
46427374 1056 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
d82fc108
NB
1057 mx = md;
1058 else
1059 mn = md;
1060 }
1061
46427374 1062 LINEMAPS_ORDINARY_CACHE (set) = mn;
a926eeed 1063 const line_map_ordinary *result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
46427374
TT
1064 linemap_assert (line >= MAP_START_LOCATION (result));
1065 return result;
1066}
1067
1068/* Given a source location yielded by a macro map, returns that map.
1069 Since the set is built chronologically, the logical lines are
1070 monotonic decreasing, and so the list is sorted and we can use a
1071 binary search. */
1072
0e50b624 1073static const line_map_macro *
9158f0ba 1074linemap_macro_map_lookup (const line_maps *set, location_t line)
46427374 1075{
5368224f 1076 if (IS_ADHOC_LOC (line))
e6fc8353 1077 line = get_location_from_adhoc_loc (set, line);
5368224f 1078
46427374
TT
1079 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1080
a926eeed 1081 if (set == NULL)
46427374
TT
1082 return NULL;
1083
1f8ac759
NS
1084 unsigned ix = linemap_lookup_macro_index (set, line);
1085 const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix);
1086 linemap_assert (MAP_START_LOCATION (result) <= line);
1087
1088 return result;
1089}
1090
1091unsigned
1092linemap_lookup_macro_index (const line_maps *set, location_t line)
1093{
a926eeed
NS
1094 unsigned mn = LINEMAPS_MACRO_CACHE (set);
1095 unsigned mx = LINEMAPS_MACRO_USED (set);
1096 const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1097
46427374
TT
1098 if (line >= MAP_START_LOCATION (cached))
1099 {
1f8ac759
NS
1100 if (line < (MAP_START_LOCATION (cached)
1101 + MACRO_MAP_NUM_MACRO_TOKENS (cached)))
1102 return mn;
46427374
TT
1103 mx = mn - 1;
1104 mn = 0;
1105 }
1106
3bb0c8db 1107 while (mn < mx)
46427374 1108 {
a926eeed 1109 unsigned md = (mx + mn) / 2;
46427374 1110 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
3bb0c8db 1111 mn = md + 1;
46427374
TT
1112 else
1113 mx = md;
3bb0c8db 1114 }
46427374
TT
1115
1116 LINEMAPS_MACRO_CACHE (set) = mx;
1f8ac759 1117 return mx;
46427374
TT
1118}
1119
1120/* Return TRUE if MAP encodes locations coming from a macro
1121 replacement-list at macro expansion point. */
1122
1123bool
1124linemap_macro_expansion_map_p (const struct line_map *map)
1125{
42a98b43 1126 return map && !MAP_ORDINARY_P (map);
46427374
TT
1127}
1128
1129/* If LOCATION is the locus of a token in a replacement-list of a
1130 macro expansion return the location of the macro expansion point.
1131
1132 Read the comments of struct line_map and struct line_map_macro in
1133 line-map.h to understand what a macro expansion point is. */
1134
620e594b 1135static location_t
0e50b624 1136linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
620e594b 1137 location_t location ATTRIBUTE_UNUSED)
46427374 1138{
46427374
TT
1139 linemap_assert (linemap_macro_expansion_map_p (map)
1140 && location >= MAP_START_LOCATION (map));
1141
1142 /* Make sure LOCATION is correct. */
411f92de
DS
1143 linemap_assert ((location - MAP_START_LOCATION (map))
1144 < MACRO_MAP_NUM_MACRO_TOKENS (map));
46427374
TT
1145
1146 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1147}
1148
3aac0952
MLI
1149/* LOCATION is the source location of a token that belongs to a macro
1150 replacement-list as part of the macro expansion denoted by MAP.
46427374 1151
3aac0952
MLI
1152 Return the location of the token at the definition point of the
1153 macro. */
1154
620e594b 1155static location_t
0e50b624 1156linemap_macro_map_loc_to_def_point (const line_map_macro *map,
620e594b 1157 location_t location)
46427374
TT
1158{
1159 unsigned token_no;
1160
1161 linemap_assert (linemap_macro_expansion_map_p (map)
1162 && location >= MAP_START_LOCATION (map));
1163 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1164
1165 token_no = location - MAP_START_LOCATION (map);
1166 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1167
1168 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1169
1170 return location;
1171}
1172
1173/* If LOCATION is the locus of a token that is an argument of a
1174 function-like macro M and appears in the expansion of M, return the
1175 locus of that argument in the context of the caller of M.
1176
1177 In other words, this returns the xI location presented in the
1178 comments of line_map_macro above. */
620e594b 1179location_t
ebedc9a3
DM
1180linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1181 const line_map_macro* map,
620e594b 1182 location_t location)
46427374
TT
1183{
1184 unsigned token_no;
1185
ebedc9a3
DM
1186 if (IS_ADHOC_LOC (location))
1187 location = get_location_from_adhoc_loc (set, location);
1188
46427374
TT
1189 linemap_assert (linemap_macro_expansion_map_p (map)
1190 && location >= MAP_START_LOCATION (map));
1191 linemap_assert (location >= RESERVED_LOCATION_COUNT);
ebedc9a3 1192 linemap_assert (!IS_ADHOC_LOC (location));
46427374
TT
1193
1194 token_no = location - MAP_START_LOCATION (map);
1195 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1196
1197 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1198
1199 return location;
1200}
1201
1202/* Return the source line number corresponding to source location
1203 LOCATION. SET is the line map set LOCATION comes from. If
1204 LOCATION is the source location of token that is part of the
1205 replacement-list of a macro expansion return the line number of the
1206 macro expansion point. */
1207
1208int
99b1c316 1209linemap_get_expansion_line (line_maps *set,
620e594b 1210 location_t location)
46427374 1211{
0e50b624 1212 const line_map_ordinary *map = NULL;
46427374 1213
5368224f 1214 if (IS_ADHOC_LOC (location))
e6fc8353 1215 location = get_location_from_adhoc_loc (set, location);
5368224f 1216
46427374
TT
1217 if (location < RESERVED_LOCATION_COUNT)
1218 return 0;
1219
1220 location =
1221 linemap_macro_loc_to_exp_point (set, location, &map);
1222
1223 return SOURCE_LINE (map, location);
1224}
1225
1226/* Return the path of the file corresponding to source code location
1227 LOCATION.
1228
1229 If LOCATION is the source location of token that is part of the
1230 replacement-list of a macro expansion return the file path of the
1231 macro expansion point.
1232
1233 SET is the line map set LOCATION comes from. */
1234
1235const char*
99b1c316 1236linemap_get_expansion_filename (line_maps *set,
620e594b 1237 location_t location)
46427374 1238{
0e50b624 1239 const struct line_map_ordinary *map = NULL;
46427374 1240
5368224f 1241 if (IS_ADHOC_LOC (location))
e6fc8353 1242 location = get_location_from_adhoc_loc (set, location);
5368224f 1243
46427374
TT
1244 if (location < RESERVED_LOCATION_COUNT)
1245 return NULL;
1246
8ba6ea87 1247 linemap_macro_loc_to_exp_point (set, location, &map);
46427374
TT
1248
1249 return LINEMAP_FILE (map);
1250}
1251
1252/* Return the name of the macro associated to MACRO_MAP. */
1253
1254const char*
0e50b624 1255linemap_map_get_macro_name (const line_map_macro *macro_map)
46427374
TT
1256{
1257 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1258 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1259}
1260
1261/* Return a positive value if LOCATION is the locus of a token that is
1262 located in a system header, O otherwise. It returns 1 if LOCATION
1263 is the locus of a token that is located in a system header, and 2
1264 if LOCATION is the locus of a token located in a C system header
1265 that therefore needs to be extern "C" protected in C++.
1266
1267 Note that this function returns 1 if LOCATION belongs to a token
1268 that is part of a macro replacement-list defined in a system
1269 header, but expanded in a non-system file. */
1270
1271int
99b1c316 1272linemap_location_in_system_header_p (line_maps *set,
620e594b 1273 location_t location)
46427374
TT
1274{
1275 const struct line_map *map = NULL;
1276
5368224f 1277 if (IS_ADHOC_LOC (location))
e6fc8353 1278 location = get_location_from_adhoc_loc (set, location);
5368224f 1279
84756fd4
DS
1280 if (location < RESERVED_LOCATION_COUNT)
1281 return false;
1282
7ca643e1
DS
1283 /* Let's look at where the token for LOCATION comes from. */
1284 while (true)
1285 {
1286 map = linemap_lookup (set, location);
1287 if (map != NULL)
1288 {
1289 if (!linemap_macro_expansion_map_p (map))
1290 /* It's a normal token. */
0e50b624 1291 return LINEMAP_SYSP (linemap_check_ordinary (map));
7ca643e1
DS
1292 else
1293 {
0e50b624
DM
1294 const line_map_macro *macro_map = linemap_check_macro (map);
1295
7ca643e1 1296 /* It's a token resulting from a macro expansion. */
620e594b 1297 location_t loc =
ebedc9a3 1298 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
7ca643e1
DS
1299 if (loc < RESERVED_LOCATION_COUNT)
1300 /* This token might come from a built-in macro. Let's
1301 look at where that macro got expanded. */
0e50b624 1302 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
7ca643e1
DS
1303 else
1304 location = loc;
1305 }
1306 }
1307 else
1308 break;
1309 }
1310 return false;
46427374
TT
1311}
1312
63cb3926
JM
1313/* Return TRUE if LOCATION is a source code location of a token that is part of
1314 a macro expansion, FALSE otherwise. */
46427374
TT
1315
1316bool
99b1c316 1317linemap_location_from_macro_expansion_p (const class line_maps *set,
620e594b 1318 location_t location)
46427374 1319{
5368224f 1320 if (IS_ADHOC_LOC (location))
e6fc8353 1321 location = get_location_from_adhoc_loc (set, location);
5368224f 1322
11743148 1323 return location >= LINEMAPS_MACRO_LOWEST_LOCATION (set);
46427374
TT
1324}
1325
1326/* Given two virtual locations *LOC0 and *LOC1, return the first
1327 common macro map in their macro expansion histories. Return NULL
1328 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1329 virtual location of the token inside the resulting macro. */
1330
1331static const struct line_map*
99b1c316 1332first_map_in_common_1 (line_maps *set,
620e594b
DM
1333 location_t *loc0,
1334 location_t *loc1)
46427374 1335{
620e594b 1336 location_t l0 = *loc0, l1 = *loc1;
19eda56d
ML
1337 const struct line_map *map0 = linemap_lookup (set, l0);
1338 if (IS_ADHOC_LOC (l0))
1339 l0 = get_location_from_adhoc_loc (set, l0);
1340
1341 const struct line_map *map1 = linemap_lookup (set, l1);
1342 if (IS_ADHOC_LOC (l1))
1343 l1 = get_location_from_adhoc_loc (set, l1);
46427374
TT
1344
1345 while (linemap_macro_expansion_map_p (map0)
1346 && linemap_macro_expansion_map_p (map1)
1347 && (map0 != map1))
1348 {
1349 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1350 {
0e50b624
DM
1351 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1352 l0);
46427374
TT
1353 map0 = linemap_lookup (set, l0);
1354 }
1355 else
1356 {
0e50b624
DM
1357 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1358 l1);
46427374
TT
1359 map1 = linemap_lookup (set, l1);
1360 }
1361 }
1362
1363 if (map0 == map1)
1364 {
1365 *loc0 = l0;
1366 *loc1 = l1;
1367 return map0;
1368 }
1369 return NULL;
1370}
1371
1372/* Given two virtual locations LOC0 and LOC1, return the first common
1373 macro map in their macro expansion histories. Return NULL if no
1374 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1375 virtual location of the token inside the resulting macro, upon
1376 return of a non-NULL result. */
1377
4839de55 1378const struct line_map*
99b1c316 1379first_map_in_common (line_maps *set,
620e594b
DM
1380 location_t loc0,
1381 location_t loc1,
1382 location_t *res_loc0,
1383 location_t *res_loc1)
46427374
TT
1384{
1385 *res_loc0 = loc0;
1386 *res_loc1 = loc1;
1387
1388 return first_map_in_common_1 (set, res_loc0, res_loc1);
1389}
1390
1391/* Return a positive value if PRE denotes the location of a token that
1392 comes before the token of POST, 0 if PRE denotes the location of
1393 the same token as the token for POST, and a negative value
1394 otherwise. */
1395
1396int
99b1c316 1397linemap_compare_locations (line_maps *set,
620e594b
DM
1398 location_t pre,
1399 location_t post)
46427374
TT
1400{
1401 bool pre_virtual_p, post_virtual_p;
620e594b 1402 location_t l0 = pre, l1 = post;
46427374 1403
acf601ae 1404 if (IS_ADHOC_LOC (l0))
196440f8 1405 l0 = get_location_from_adhoc_loc (set, l0);
acf601ae 1406 if (IS_ADHOC_LOC (l1))
196440f8 1407 l1 = get_location_from_adhoc_loc (set, l1);
acf601ae 1408
46427374
TT
1409 if (l0 == l1)
1410 return 0;
1411
1412 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1413 l0 = linemap_resolve_location (set, l0,
1414 LRK_MACRO_EXPANSION_POINT,
1415 NULL);
1416
1417 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1418 l1 = linemap_resolve_location (set, l1,
1419 LRK_MACRO_EXPANSION_POINT,
1420 NULL);
1421
1422 if (l0 == l1
1423 && pre_virtual_p
9e64426d 1424 && post_virtual_p)
46427374
TT
1425 {
1426 /* So pre and post represent two tokens that are present in a
1427 same macro expansion. Let's see if the token for pre was
1428 before the token for post in that expansion. */
46427374
TT
1429 const struct line_map *map =
1430 first_map_in_common (set, pre, post, &l0, &l1);
1431
1432 if (map == NULL)
9e64426d
JM
1433 /* This should not be possible while we have column information, but if
1434 we don't, the tokens could be from separate macro expansions on the
1435 same line. */
1436 gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS);
1437 else
1438 {
1439 unsigned i0 = l0 - MAP_START_LOCATION (map);
1440 unsigned i1 = l1 - MAP_START_LOCATION (map);
1441 return i1 - i0;
1442 }
46427374
TT
1443 }
1444
196440f8
DM
1445 if (IS_ADHOC_LOC (l0))
1446 l0 = get_location_from_adhoc_loc (set, l0);
1447 if (IS_ADHOC_LOC (l1))
1448 l1 = get_location_from_adhoc_loc (set, l1);
1449
46427374 1450 return l1 - l0;
d82fc108 1451}
fde84349 1452
5993019d
NB
1453/* Print an include trace, for e.g. the -H option of the preprocessor. */
1454
1455static void
99b1c316 1456trace_include (const class line_maps *set, const line_map_ordinary *map)
5993019d 1457{
d8693c6f 1458 unsigned int i = set->depth;
5993019d 1459
d8693c6f 1460 while (--i)
5993019d 1461 putc ('.', stderr);
46427374
TT
1462
1463 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1464}
1465
1466/* Return the spelling location of the token wherever it comes from,
1467 whether part of a macro definition or not.
1468
1469 This is a subroutine for linemap_resolve_location. */
1470
620e594b 1471static location_t
99b1c316 1472linemap_macro_loc_to_spelling_point (line_maps *set,
620e594b 1473 location_t location,
0e50b624 1474 const line_map_ordinary **original_map)
46427374 1475{
46427374
TT
1476 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1477
1478 while (true)
1479 {
42a98b43
NS
1480 const struct line_map *map = linemap_lookup (set, location);
1481 if (!map || MAP_ORDINARY_P (map))
1482 {
1483 if (original_map)
1484 *original_map = (const line_map_ordinary *)map;
1485 break;
1486 }
46427374 1487
42a98b43
NS
1488 location = linemap_macro_map_loc_unwind_toward_spelling
1489 (set, linemap_check_macro (map), location);
46427374
TT
1490 }
1491
46427374
TT
1492 return location;
1493}
1494
1495/* If LOCATION is the source location of a token that belongs to a
1496 macro replacement-list -- as part of a macro expansion -- then
1497 return the location of the token at the definition point of the
1498 macro. Otherwise, return LOCATION. SET is the set of maps
1499 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1500 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1501 returned location comes from.
1502
1503 This is a subroutine of linemap_resolve_location. */
1504
620e594b 1505static location_t
99b1c316 1506linemap_macro_loc_to_def_point (line_maps *set,
620e594b 1507 location_t location,
0e50b624 1508 const line_map_ordinary **original_map)
46427374 1509{
46427374
TT
1510 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1511
42a98b43 1512 for (;;)
46427374 1513 {
620e594b 1514 location_t caret_loc = location;
42a98b43
NS
1515 if (IS_ADHOC_LOC (caret_loc))
1516 caret_loc = get_location_from_adhoc_loc (set, caret_loc);
738f7c2e 1517
42a98b43
NS
1518 const line_map *map = linemap_lookup (set, caret_loc);
1519 if (!map || MAP_ORDINARY_P (map))
1520 {
1521 if (original_map)
1522 *original_map = (const line_map_ordinary *)map;
1523 break;
1524 }
46427374 1525
42a98b43
NS
1526 location = linemap_macro_map_loc_to_def_point
1527 (linemap_check_macro (map), caret_loc);
46427374
TT
1528 }
1529
46427374
TT
1530 return location;
1531}
1532
1533/* If LOCATION is the source location of a token that belongs to a
1534 macro replacement-list -- at a macro expansion point -- then return
1535 the location of the topmost expansion point of the macro. We say
1536 topmost because if we are in the context of a nested macro
1537 expansion, the function returns the source location of the first
1538 macro expansion that triggered the nested expansions.
1539
1540 Otherwise, return LOCATION. SET is the set of maps location come
1541 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1542 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1543 location comes from.
1544
1545 This is a subroutine of linemap_resolve_location. */
1546
620e594b 1547static location_t
99b1c316 1548linemap_macro_loc_to_exp_point (line_maps *set,
620e594b 1549 location_t location,
0e50b624 1550 const line_map_ordinary **original_map)
46427374
TT
1551{
1552 struct line_map *map;
1553
5368224f 1554 if (IS_ADHOC_LOC (location))
e6fc8353 1555 location = get_location_from_adhoc_loc (set, location);
5368224f 1556
46427374
TT
1557 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1558
1559 while (true)
1560 {
0e50b624 1561 map = const_cast <line_map *> (linemap_lookup (set, location));
46427374
TT
1562 if (!linemap_macro_expansion_map_p (map))
1563 break;
0e50b624
DM
1564 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1565 location);
46427374
TT
1566 }
1567
1568 if (original_map)
0e50b624 1569 *original_map = linemap_check_ordinary (map);
46427374
TT
1570 return location;
1571}
1572
1573/* Resolve a virtual location into either a spelling location, an
1574 expansion point location or a token argument replacement point
1575 location. Return the map that encodes the virtual location as well
1576 as the resolved location.
1577
1578 If LOC is *NOT* the location of a token resulting from the
1579 expansion of a macro, then the parameter LRK (which stands for
1580 Location Resolution Kind) is ignored and the resulting location
1581 just equals the one given in argument.
1582
1583 Now if LOC *IS* the location of a token resulting from the
1584 expansion of a macro, this is what happens.
1585
1586 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1587 -------------------------------
1588
1d72e96f
MLI
1589 The virtual location is resolved to the first macro expansion point
1590 that led to this macro expansion.
46427374
TT
1591
1592 * If LRK is set to LRK_SPELLING_LOCATION
1593 -------------------------------------
1594
1d72e96f
MLI
1595 The virtual location is resolved to the locus where the token has
1596 been spelled in the source. This can follow through all the macro
1597 expansions that led to the token.
46427374 1598
1d72e96f 1599 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
46427374
TT
1600 --------------------------------------
1601
1d72e96f
MLI
1602 The virtual location is resolved to the locus of the token in the
1603 context of the macro definition.
1604
46427374
TT
1605 If LOC is the locus of a token that is an argument of a
1606 function-like macro [replacing a parameter in the replacement list
1607 of the macro] the virtual location is resolved to the locus of the
1608 parameter that is replaced, in the context of the definition of the
1609 macro.
1610
1611 If LOC is the locus of a token that is not an argument of a
1612 function-like macro, then the function behaves as if LRK was set to
1613 LRK_SPELLING_LOCATION.
1614
3aac0952 1615 If MAP is not NULL, *MAP is set to the map encoding the
1d72e96f 1616 returned location. Note that if the returned location wasn't originally
3aac0952 1617 encoded by a map, then *MAP is set to NULL. This can happen if LOC
84756fd4
DS
1618 resolves to a location reserved for the client code, like
1619 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
46427374 1620
620e594b 1621location_t
99b1c316 1622linemap_resolve_location (line_maps *set,
620e594b 1623 location_t loc,
46427374 1624 enum location_resolution_kind lrk,
0e50b624 1625 const line_map_ordinary **map)
46427374 1626{
620e594b 1627 location_t locus = loc;
5368224f 1628 if (IS_ADHOC_LOC (loc))
e6fc8353 1629 locus = get_location_from_adhoc_loc (set, loc);
5368224f 1630
ebedc9a3 1631 if (locus < RESERVED_LOCATION_COUNT)
84756fd4
DS
1632 {
1633 /* A reserved location wasn't encoded in a map. Let's return a
1634 NULL map here, just like what linemap_ordinary_map_lookup
1635 does. */
1636 if (map)
1637 *map = NULL;
1638 return loc;
1639 }
46427374
TT
1640
1641 switch (lrk)
1642 {
1643 case LRK_MACRO_EXPANSION_POINT:
1644 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1645 break;
1646 case LRK_SPELLING_LOCATION:
1647 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1648 break;
1649 case LRK_MACRO_DEFINITION_LOCATION:
1650 loc = linemap_macro_loc_to_def_point (set, loc, map);
1651 break;
1652 default:
1653 abort ();
1654 }
1655 return loc;
1656}
1657
63cb3926
JM
1658/* TRUE if LOCATION is a source code location of a token that is part of the
1659 definition of a macro, FALSE otherwise. */
1660
1661bool
99b1c316 1662linemap_location_from_macro_definition_p (line_maps *set,
620e594b 1663 location_t loc)
63cb3926
JM
1664{
1665 if (IS_ADHOC_LOC (loc))
1666 loc = get_location_from_adhoc_loc (set, loc);
1667
1668 if (!linemap_location_from_macro_expansion_p (set, loc))
1669 return false;
1670
1671 while (true)
1672 {
1673 const struct line_map_macro *map
1674 = linemap_check_macro (linemap_lookup (set, loc));
1675
620e594b 1676 location_t s_loc
63cb3926
JM
1677 = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
1678 if (linemap_location_from_macro_expansion_p (set, s_loc))
1679 loc = s_loc;
1680 else
1681 {
620e594b 1682 location_t def_loc
63cb3926
JM
1683 = linemap_macro_map_loc_to_def_point (map, loc);
1684 return s_loc == def_loc;
1685 }
1686 }
1687}
1688
46427374
TT
1689/*
1690 Suppose that LOC is the virtual location of a token T coming from
1691 the expansion of a macro M. This function then steps up to get the
1692 location L of the point where M got expanded. If L is a spelling
1693 location inside a macro expansion M', then this function returns
1694 the locus of the point where M' was expanded. Said otherwise, this
1695 function returns the location of T in the context that triggered
1696 the expansion of M.
1697
1698 *LOC_MAP must be set to the map of LOC. This function then sets it
1699 to the map of the returned location. */
1700
620e594b 1701location_t
99b1c316 1702linemap_unwind_toward_expansion (line_maps *set,
620e594b 1703 location_t loc,
46427374
TT
1704 const struct line_map **map)
1705{
620e594b 1706 location_t resolved_location;
0e50b624 1707 const line_map_macro *macro_map = linemap_check_macro (*map);
46427374
TT
1708 const struct line_map *resolved_map;
1709
5368224f 1710 if (IS_ADHOC_LOC (loc))
e6fc8353 1711 loc = get_location_from_adhoc_loc (set, loc);
5368224f 1712
46427374 1713 resolved_location =
ebedc9a3 1714 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
46427374
TT
1715 resolved_map = linemap_lookup (set, resolved_location);
1716
1717 if (!linemap_macro_expansion_map_p (resolved_map))
1718 {
0e50b624 1719 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
46427374
TT
1720 resolved_map = linemap_lookup (set, resolved_location);
1721 }
1722
1723 *map = resolved_map;
1724 return resolved_location;
1725}
1726
c4ca1a09
DS
1727/* If LOC is the virtual location of a token coming from the expansion
1728 of a macro M and if its spelling location is reserved (e.g, a
1729 location for a built-in token), then this function unwinds (using
1730 linemap_unwind_toward_expansion) the location until a location that
7d9641cc 1731 is not reserved and is not in a system header is reached. In other
c4ca1a09
DS
1732 words, this unwinds the reserved location until a location that is
1733 in real source code is reached.
1734
1735 Otherwise, if the spelling location for LOC is not reserved or if
1736 LOC doesn't come from the expansion of a macro, the function
1737 returns LOC as is and *MAP is not touched.
1738
1739 *MAP is set to the map of the returned location if the later is
1740 different from LOC. */
620e594b 1741location_t
99b1c316 1742linemap_unwind_to_first_non_reserved_loc (line_maps *set,
620e594b 1743 location_t loc,
c4ca1a09
DS
1744 const struct line_map **map)
1745{
620e594b 1746 location_t resolved_loc;
0e50b624
DM
1747 const struct line_map *map0 = NULL;
1748 const line_map_ordinary *map1 = NULL;
c4ca1a09 1749
5368224f 1750 if (IS_ADHOC_LOC (loc))
e6fc8353 1751 loc = get_location_from_adhoc_loc (set, loc);
5368224f 1752
c4ca1a09
DS
1753 map0 = linemap_lookup (set, loc);
1754 if (!linemap_macro_expansion_map_p (map0))
1755 return loc;
1756
1757 resolved_loc = linemap_resolve_location (set, loc,
1758 LRK_SPELLING_LOCATION,
1759 &map1);
1760
1761 if (resolved_loc >= RESERVED_LOCATION_COUNT
1762 && !LINEMAP_SYSP (map1))
1763 return loc;
1764
1765 while (linemap_macro_expansion_map_p (map0)
1766 && (resolved_loc < RESERVED_LOCATION_COUNT
1767 || LINEMAP_SYSP (map1)))
1768 {
1769 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1770 resolved_loc = linemap_resolve_location (set, loc,
1771 LRK_SPELLING_LOCATION,
1772 &map1);
1773 }
1774
1775 if (map != NULL)
1776 *map = map0;
1777 return loc;
1778}
1779
46427374 1780/* Expand source code location LOC and return a user readable source
84756fd4
DS
1781 code location. LOC must be a spelling (non-virtual) location. If
1782 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1783 location is returned. */
46427374
TT
1784
1785expanded_location
99b1c316 1786linemap_expand_location (line_maps *set,
84756fd4 1787 const struct line_map *map,
620e594b 1788 location_t loc)
46427374
TT
1789
1790{
1791 expanded_location xloc;
1792
84756fd4 1793 memset (&xloc, 0, sizeof (xloc));
5368224f
DC
1794 if (IS_ADHOC_LOC (loc))
1795 {
e6fc8353
ML
1796 xloc.data = get_data_from_adhoc_loc (set, loc);
1797 loc = get_location_from_adhoc_loc (set, loc);
5368224f 1798 }
84756fd4
DS
1799
1800 if (loc < RESERVED_LOCATION_COUNT)
1801 /* The location for this token wasn't generated from a line map.
1802 It was probably a location for a builtin token, chosen by some
1803 client code. Let's not try to expand the location in that
1804 case. */;
1805 else if (map == NULL)
1806 /* We shouldn't be getting a NULL map with a location that is not
1807 reserved by the client code. */
1808 abort ();
1809 else
1810 {
1811 /* MAP must be an ordinary map and LOC must be non-virtual,
1812 encoded into this map, obviously; the accessors used on MAP
1813 below ensure it is ordinary. Let's just assert the
1814 non-virtualness of LOC here. */
1815 if (linemap_location_from_macro_expansion_p (set, loc))
1816 abort ();
46427374 1817
0e50b624
DM
1818 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1819
1820 xloc.file = LINEMAP_FILE (ord_map);
1821 xloc.line = SOURCE_LINE (ord_map, loc);
1822 xloc.column = SOURCE_COLUMN (ord_map, loc);
1823 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
84756fd4 1824 }
46427374 1825
46427374 1826 return xloc;
5993019d 1827}
847e697a 1828
8dcf72a8
DN
1829
1830/* Dump line map at index IX in line table SET to STREAM. If STREAM
1831 is NULL, use stderr. IS_MACRO is true if the caller wants to
1832 dump a macro map, false otherwise. */
1833
1834void
99b1c316 1835linemap_dump (FILE *stream, class line_maps *set, unsigned ix, bool is_macro)
8dcf72a8 1836{
42a98b43 1837 const char *const lc_reasons_v[LC_HWM]
8dcf72a8 1838 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1f8ac759 1839 "LC_ENTER_MACRO", "LC_MODULE" };
0e50b624 1840 const line_map *map;
42a98b43 1841 unsigned reason;
8dcf72a8
DN
1842
1843 if (stream == NULL)
1844 stream = stderr;
1845
1846 if (!is_macro)
42a98b43
NS
1847 {
1848 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1849 reason = linemap_check_ordinary (map)->reason;
1850 }
8dcf72a8 1851 else
42a98b43
NS
1852 {
1853 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1854 reason = LC_ENTER_MACRO;
1855 }
8dcf72a8
DN
1856
1857 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
42a98b43
NS
1858 ix, (void *) map, map->start_location,
1859 reason < LC_HWM ? lc_reasons_v[reason] : "???",
0e50b624
DM
1860 ((!is_macro
1861 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1862 ? "yes" : "no"));
8dcf72a8
DN
1863 if (!is_macro)
1864 {
0e50b624 1865 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
f10a9135
NS
1866 const line_map_ordinary *includer_map
1867 = linemap_included_from_linemap (set, ord_map);
8dcf72a8 1868
0e50b624
DM
1869 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1870 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
f10a9135
NS
1871 fprintf (stream, "Included from: [%d] %s\n",
1872 includer_map ? int (includer_map - set->info_ordinary.maps) : -1,
8dcf72a8
DN
1873 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1874 }
1875 else
0e50b624
DM
1876 {
1877 const line_map_macro *macro_map = linemap_check_macro (map);
1878 fprintf (stream, "Macro: %s (%u tokens)\n",
1879 linemap_map_get_macro_name (macro_map),
1880 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1881 }
8dcf72a8
DN
1882
1883 fprintf (stream, "\n");
1884}
1885
1886
847e697a
TT
1887/* Dump debugging information about source location LOC into the file
1888 stream STREAM. SET is the line map set LOC comes from. */
1889
1890void
99b1c316 1891linemap_dump_location (line_maps *set,
620e594b 1892 location_t loc,
847e697a
TT
1893 FILE *stream)
1894{
0e50b624 1895 const line_map_ordinary *map;
620e594b 1896 location_t location;
84756fd4
DS
1897 const char *path = "", *from = "";
1898 int l = -1, c = -1, s = -1, e = -1;
847e697a 1899
5368224f 1900 if (IS_ADHOC_LOC (loc))
e6fc8353 1901 loc = get_location_from_adhoc_loc (set, loc);
5368224f 1902
847e697a
TT
1903 if (loc == 0)
1904 return;
1905
1906 location =
1907 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
847e697a 1908
84756fd4
DS
1909 if (map == NULL)
1910 /* Only reserved locations can be tolerated in this case. */
1911 linemap_assert (location < RESERVED_LOCATION_COUNT);
847e697a 1912 else
84756fd4
DS
1913 {
1914 path = LINEMAP_FILE (map);
1915 l = SOURCE_LINE (map, location);
1916 c = SOURCE_COLUMN (map, location);
1917 s = LINEMAP_SYSP (map) != 0;
1918 e = location != loc;
1919 if (e)
1920 from = "N/A";
1921 else
f10a9135
NS
1922 {
1923 const line_map_ordinary *from_map
1924 = linemap_included_from_linemap (set, map);
1925 from = from_map ? LINEMAP_FILE (from_map) : "<NULL>";
1926 }
84756fd4 1927 }
847e697a
TT
1928
1929 /* P: path, L: line, C: column, S: in-system-header, M: map address,
84756fd4
DS
1930 E: macro expansion?, LOC: original location, R: resolved location */
1931 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1932 path, from, l, c, s, (void*)map, e, loc, location);
847e697a 1933}
64a1a422 1934
7ecc3eb9
DS
1935/* Return the highest location emitted for a given file for which
1936 there is a line map in SET. FILE_NAME is the file name to
1937 consider. If the function returns TRUE, *LOC is set to the highest
1938 location emitted for that file. */
1939
1940bool
99b1c316 1941linemap_get_file_highest_location (line_maps *set,
7ecc3eb9 1942 const char *file_name,
620e594b 1943 location_t *loc)
7ecc3eb9
DS
1944{
1945 /* If the set is empty or no ordinary map has been created then
1946 there is no file to look for ... */
1947 if (set == NULL || set->info_ordinary.used == 0)
1948 return false;
1949
1950 /* Now look for the last ordinary map created for FILE_NAME. */
1951 int i;
1952 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1953 {
0e50b624 1954 const char *fname = set->info_ordinary.maps[i].to_file;
7ecc3eb9
DS
1955 if (fname && !filename_cmp (fname, file_name))
1956 break;
1957 }
1958
1959 if (i < 0)
1960 return false;
1961
1962 /* The highest location for a given map is either the starting
1963 location of the next map minus one, or -- if the map is the
1964 latest one -- the highest location of the set. */
620e594b 1965 location_t result;
7ecc3eb9
DS
1966 if (i == (int) set->info_ordinary.used - 1)
1967 result = set->highest_location;
1968 else
1969 result = set->info_ordinary.maps[i + 1].start_location - 1;
1970
1971 *loc = result;
1972 return true;
1973}
1974
64a1a422
TT
1975/* Compute and return statistics about the memory consumption of some
1976 parts of the line table SET. */
1977
1978void
99b1c316 1979linemap_get_statistics (line_maps *set,
64a1a422
TT
1980 struct linemap_stats *s)
1981{
d17687f6 1982 long ordinary_maps_allocated_size, ordinary_maps_used_size,
64a1a422
TT
1983 macro_maps_allocated_size, macro_maps_used_size,
1984 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1985
0e50b624 1986 const line_map_macro *cur_map;
64a1a422
TT
1987
1988 ordinary_maps_allocated_size =
0e50b624 1989 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
64a1a422
TT
1990
1991 ordinary_maps_used_size =
0e50b624 1992 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
64a1a422
TT
1993
1994 macro_maps_allocated_size =
0e50b624 1995 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
64a1a422
TT
1996
1997 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1998 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1999 ++cur_map)
2000 {
2001 unsigned i;
2002
2003 linemap_assert (linemap_macro_expansion_map_p (cur_map));
2004
2005 macro_maps_locations_size +=
620e594b 2006 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (location_t);
64a1a422
TT
2007
2008 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
2009 {
2010 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
2011 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
2012 duplicated_macro_maps_locations_size +=
620e594b 2013 sizeof (location_t);
64a1a422
TT
2014 }
2015 }
2016
2017 macro_maps_used_size =
0e50b624 2018 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
64a1a422
TT
2019
2020 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
2021 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
2022 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
2023 s->ordinary_maps_used_size = ordinary_maps_used_size;
2024 s->num_expanded_macros = num_expanded_macros_counter;
2025 s->num_macro_tokens = num_macro_tokens_counter;
2026 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
2027 s->macro_maps_allocated_size = macro_maps_allocated_size;
2028 s->macro_maps_locations_size = macro_maps_locations_size;
2029 s->macro_maps_used_size = macro_maps_used_size;
2030 s->duplicated_macro_maps_locations_size =
2031 duplicated_macro_maps_locations_size;
ee015909
DM
2032 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
2033 * sizeof (struct location_adhoc_data));
2034 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
64a1a422 2035}
8dcf72a8
DN
2036
2037
2038/* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
2039 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
2040 specifies how many macro maps to dump. */
2041
2042void
99b1c316 2043line_table_dump (FILE *stream, class line_maps *set, unsigned int num_ordinary,
8dcf72a8
DN
2044 unsigned int num_macro)
2045{
2046 unsigned int i;
2047
2048 if (set == NULL)
2049 return;
2050
2051 if (stream == NULL)
2052 stream = stderr;
2053
2054 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
2055 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
2056 fprintf (stream, "Include stack depth: %d\n", set->depth);
2057 fprintf (stream, "Highest location: %u\n", set->highest_location);
2058
2059 if (num_ordinary)
2060 {
2061 fprintf (stream, "\nOrdinary line maps\n");
2062 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
2063 linemap_dump (stream, set, i, false);
2064 fprintf (stream, "\n");
2065 }
2066
2067 if (num_macro)
2068 {
2069 fprintf (stream, "\nMacro line maps\n");
2070 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
2071 linemap_dump (stream, set, i, true);
2072 fprintf (stream, "\n");
2073 }
2074}
8a645150
DM
2075
2076/* class rich_location. */
2077
2078/* Construct a rich_location with location LOC as its initial range. */
2079
620e594b 2080rich_location::rich_location (line_maps *set, location_t loc,
96e6ae57 2081 const range_label *label) :
ee908516 2082 m_line_table (set),
b816477a 2083 m_ranges (),
40499f81 2084 m_column_override (0),
a87a86e1 2085 m_have_expanded_location (false),
b09649fd 2086 m_seen_impossible_fixit (false),
4bc1899b 2087 m_fixits_cannot_be_auto_applied (false),
4288b57a
RB
2088 m_escape_on_output (false),
2089 m_fixit_hints (),
2090 m_path (NULL)
8a645150 2091{
85204e23 2092 add_range (loc, SHOW_RANGE_WITH_CARET, label);
8a645150
DM
2093}
2094
a87a86e1
DM
2095/* The destructor for class rich_location. */
2096
2097rich_location::~rich_location ()
2098{
b816477a
DM
2099 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2100 delete get_fixit_hint (i);
a87a86e1
DM
2101}
2102
40499f81
DM
2103/* Get location IDX within this rich_location. */
2104
620e594b 2105location_t
40499f81
DM
2106rich_location::get_loc (unsigned int idx) const
2107{
b816477a
DM
2108 const location_range *locrange = get_range (idx);
2109 return locrange->m_loc;
2110}
2111
2112/* Get range IDX within this rich_location. */
2113
2114const location_range *
2115rich_location::get_range (unsigned int idx) const
2116{
2117 return &m_ranges[idx];
2118}
2119
2120/* Mutable access to range IDX within this rich_location. */
2121
2122location_range *
2123rich_location::get_range (unsigned int idx)
2124{
2125 return &m_ranges[idx];
40499f81
DM
2126}
2127
2128/* Expand location IDX within this rich_location. */
8a645150
DM
2129/* Get an expanded_location for this rich_location's primary
2130 location. */
2131
2132expanded_location
40499f81 2133rich_location::get_expanded_location (unsigned int idx)
8a645150 2134{
40499f81
DM
2135 if (idx == 0)
2136 {
2137 /* Cache the expansion of the primary location. */
2138 if (!m_have_expanded_location)
2139 {
2140 m_expanded_location
c471c6ed
DM
2141 = linemap_client_expand_location_to_spelling_point
2142 (get_loc (0), LOCATION_ASPECT_CARET);
40499f81
DM
2143 if (m_column_override)
2144 m_expanded_location.column = m_column_override;
2145 m_have_expanded_location = true;
2146 }
2147
2148 return m_expanded_location;
2149 }
2150 else
c471c6ed
DM
2151 return linemap_client_expand_location_to_spelling_point
2152 (get_loc (idx), LOCATION_ASPECT_CARET);
8a645150
DM
2153}
2154
40499f81
DM
2155/* Set the column of the primary location, with 0 meaning
2156 "don't override it". */
8a645150
DM
2157
2158void
2159rich_location::override_column (int column)
2160{
40499f81
DM
2161 m_column_override = column;
2162 m_have_expanded_location = false;
8a645150
DM
2163}
2164
2165/* Add the given range. */
2166
2167void
620e594b 2168rich_location::add_range (location_t loc,
85204e23 2169 enum range_display_kind range_display_kind,
96e6ae57 2170 const range_label *label)
8a645150 2171{
b816477a
DM
2172 location_range range;
2173 range.m_loc = loc;
85204e23 2174 range.m_range_display_kind = range_display_kind;
96e6ae57 2175 range.m_label = label;
b816477a 2176 m_ranges.push (range);
8a645150
DM
2177}
2178
f79520bb 2179/* Add or overwrite the location given by IDX, setting its location to LOC,
85204e23 2180 and setting its m_range_display_kind to RANGE_DISPLAY_KIND.
8a645150 2181
f79520bb
DM
2182 It must either overwrite an existing location, or add one *exactly* on
2183 the end of the array.
8a645150 2184
f79520bb
DM
2185 This is primarily for use by gcc when implementing diagnostic format
2186 decoders e.g.
2187 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2188 (which writes the source location of a tree back into location 0 of
2189 the rich_location), and
2190 - the "%C" and "%L" format codes in the Fortran frontend. */
8a645150
DM
2191
2192void
620e594b 2193rich_location::set_range (unsigned int idx, location_t loc,
85204e23 2194 enum range_display_kind range_display_kind)
8a645150 2195{
8a645150
DM
2196 /* We can either overwrite an existing range, or add one exactly
2197 on the end of the array. */
b816477a 2198 linemap_assert (idx <= m_ranges.count ());
8a645150 2199
b816477a 2200 if (idx == m_ranges.count ())
85204e23 2201 add_range (loc, range_display_kind);
b816477a
DM
2202 else
2203 {
2204 location_range *locrange = get_range (idx);
2205 locrange->m_loc = loc;
85204e23 2206 locrange->m_range_display_kind = range_display_kind;
b816477a 2207 }
8a645150 2208
f79520bb 2209 if (idx == 0)
40499f81
DM
2210 /* Mark any cached value here as dirty. */
2211 m_have_expanded_location = false;
8a645150 2212}
a87a86e1 2213
f9087798
DM
2214/* Methods for adding insertion fix-it hints. */
2215
2216/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
254830ba 2217 immediately before the primary range's start location. */
f9087798
DM
2218
2219void
254830ba 2220rich_location::add_fixit_insert_before (const char *new_content)
f9087798 2221{
254830ba 2222 add_fixit_insert_before (get_loc (), new_content);
f9087798
DM
2223}
2224
a87a86e1 2225/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
254830ba 2226 immediately before the start of WHERE. */
a87a86e1
DM
2227
2228void
620e594b 2229rich_location::add_fixit_insert_before (location_t where,
254830ba 2230 const char *new_content)
a87a86e1 2231{
620e594b 2232 location_t start = get_range_from_loc (m_line_table, where).m_start;
338035aa 2233 maybe_add_fixit (start, start, new_content);
254830ba
DM
2234}
2235
2236/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2237 immediately after the primary range's end-point. */
2238
2239void
2240rich_location::add_fixit_insert_after (const char *new_content)
2241{
2242 add_fixit_insert_after (get_loc (), new_content);
2243}
2244
2245/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2246 immediately after the end-point of WHERE. */
2247
2248void
620e594b 2249rich_location::add_fixit_insert_after (location_t where,
254830ba
DM
2250 const char *new_content)
2251{
620e594b
DM
2252 location_t finish = get_range_from_loc (m_line_table, where).m_finish;
2253 location_t next_loc
254830ba
DM
2254 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2255
2256 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2257 its input value. */
2258 if (next_loc == finish)
2259 {
2260 stop_supporting_fixits ();
2261 return;
2262 }
2263
338035aa 2264 maybe_add_fixit (next_loc, next_loc, new_content);
a87a86e1
DM
2265}
2266
f9087798
DM
2267/* Methods for adding removal fix-it hints. */
2268
2269/* Add a fixit-hint, suggesting removal of the content covered
2270 by range 0. */
2271
2272void
2273rich_location::add_fixit_remove ()
2274{
2275 add_fixit_remove (get_loc ());
2276}
2277
2278/* Add a fixit-hint, suggesting removal of the content between
2279 the start and finish of WHERE. */
2280
2281void
620e594b 2282rich_location::add_fixit_remove (location_t where)
f9087798
DM
2283{
2284 source_range range = get_range_from_loc (m_line_table, where);
2285 add_fixit_remove (range);
2286}
2287
a87a86e1
DM
2288/* Add a fixit-hint, suggesting removal of the content at
2289 SRC_RANGE. */
2290
2291void
2292rich_location::add_fixit_remove (source_range src_range)
2293{
2ffe0809 2294 add_fixit_replace (src_range, "");
a87a86e1
DM
2295}
2296
f9087798
DM
2297/* Add a fixit-hint, suggesting replacement of the content covered
2298 by range 0 with NEW_CONTENT. */
2299
2300void
2301rich_location::add_fixit_replace (const char *new_content)
2302{
2303 add_fixit_replace (get_loc (), new_content);
2304}
2305
2306/* Methods for adding "replace" fix-it hints. */
2307
2308/* Add a fixit-hint, suggesting replacement of the content between
2309 the start and finish of WHERE with NEW_CONTENT. */
2310
2311void
620e594b 2312rich_location::add_fixit_replace (location_t where,
f9087798
DM
2313 const char *new_content)
2314{
2315 source_range range = get_range_from_loc (m_line_table, where);
2316 add_fixit_replace (range, new_content);
2317}
2318
a87a86e1
DM
2319/* Add a fixit-hint, suggesting replacement of the content at
2320 SRC_RANGE with NEW_CONTENT. */
2321
2322void
2323rich_location::add_fixit_replace (source_range src_range,
2324 const char *new_content)
2325{
620e594b
DM
2326 location_t start = get_pure_location (m_line_table, src_range.m_start);
2327 location_t finish = get_pure_location (m_line_table, src_range.m_finish);
ee908516 2328
338035aa 2329 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
620e594b 2330 location_t next_loc
338035aa
DM
2331 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2332 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2333 its input value. */
2334 if (next_loc == finish)
31316208
DM
2335 {
2336 stop_supporting_fixits ();
2337 return;
2338 }
338035aa 2339 finish = next_loc;
31316208 2340
338035aa 2341 maybe_add_fixit (start, finish, new_content);
a87a86e1
DM
2342}
2343
ee908516
DM
2344/* Get the last fix-it hint within this rich_location, or NULL if none. */
2345
2346fixit_hint *
2347rich_location::get_last_fixit_hint () const
2348{
b816477a
DM
2349 if (m_fixit_hints.count () > 0)
2350 return get_fixit_hint (m_fixit_hints.count () - 1);
ee908516
DM
2351 else
2352 return NULL;
2353}
2354
2355/* If WHERE is an "awkward" location, then mark this rich_location as not
2356 supporting fixits, purging any thay were already added, and return true.
2357
2358 Otherwise (the common case), return false. */
2359
2360bool
620e594b 2361rich_location::reject_impossible_fixit (location_t where)
ee908516
DM
2362{
2363 /* Fix-its within a rich_location should either all be suggested, or
2364 none of them should be suggested.
2365 Once we've rejected a fixit, we reject any more, even those
2366 with reasonable locations. */
2367 if (m_seen_impossible_fixit)
2368 return true;
2369
2370 if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
2371 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2372 return false;
2373
2374 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2375 location: either one that we can't obtain column information
2376 for (within an ordinary map), or one within a macro expansion. */
254830ba
DM
2377 stop_supporting_fixits ();
2378 return true;
2379}
2380
2381/* Mark this rich_location as not supporting fixits, purging any that were
2382 already added. */
2383
2384void
2385rich_location::stop_supporting_fixits ()
2386{
ee908516
DM
2387 m_seen_impossible_fixit = true;
2388
2389 /* Purge the rich_location of any fix-its that were already added. */
b816477a
DM
2390 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2391 delete get_fixit_hint (i);
2392 m_fixit_hints.truncate (0);
ee908516
DM
2393}
2394
338035aa
DM
2395/* Add HINT to the fix-it hints in this rich_location,
2396 consolidating into the prior fixit if possible. */
b816477a
DM
2397
2398void
620e594b
DM
2399rich_location::maybe_add_fixit (location_t start,
2400 location_t next_loc,
338035aa 2401 const char *new_content)
b816477a 2402{
338035aa
DM
2403 if (reject_impossible_fixit (start))
2404 return;
2405 if (reject_impossible_fixit (next_loc))
2406 return;
a87a86e1 2407
c7a980b8
DM
2408 /* Only allow fix-it hints that affect a single line in one file.
2409 Compare the end-points. */
2410 expanded_location exploc_start
c471c6ed
DM
2411 = linemap_client_expand_location_to_spelling_point (start,
2412 LOCATION_ASPECT_START);
c7a980b8 2413 expanded_location exploc_next_loc
c471c6ed
DM
2414 = linemap_client_expand_location_to_spelling_point (next_loc,
2415 LOCATION_ASPECT_START);
c7a980b8
DM
2416 /* They must be within the same file... */
2417 if (exploc_start.file != exploc_next_loc.file)
2418 {
2419 stop_supporting_fixits ();
2420 return;
2421 }
2422 /* ...and on the same line. */
2423 if (exploc_start.line != exploc_next_loc.line)
2424 {
2425 stop_supporting_fixits ();
2426 return;
2427 }
6df8934f
DM
2428 /* The columns must be in the correct order. This can fail if the
2429 endpoints straddle the boundary for which the linemap can represent
2430 columns (PR c/82050). */
2431 if (exploc_start.column > exploc_next_loc.column)
2432 {
2433 stop_supporting_fixits ();
2434 return;
2435 }
41fbacdd
DM
2436 /* If we have very long lines, tokens will eventually fall back to
2437 having column == 0.
2438 We can't handle fix-it hints that use such locations. */
2439 if (exploc_start.column == 0 || exploc_next_loc.column == 0)
2440 {
2441 stop_supporting_fixits ();
2442 return;
2443 }
c7a980b8 2444
ad53f123
DM
2445 const char *newline = strchr (new_content, '\n');
2446 if (newline)
338035aa 2447 {
ad53f123
DM
2448 /* For now, we can only support insertion of whole lines
2449 i.e. starts at start of line, and the newline is at the end of
2450 the insertion point. */
2451
2452 /* It must be an insertion, not a replacement/deletion. */
2453 if (start != next_loc)
2454 {
2455 stop_supporting_fixits ();
2456 return;
2457 }
2458
2459 /* The insertion must be at the start of a line. */
ad53f123
DM
2460 if (exploc_start.column != 1)
2461 {
2462 stop_supporting_fixits ();
2463 return;
2464 }
2465
2466 /* The newline must be at end of NEW_CONTENT.
2467 We could eventually split up fix-its at newlines if we wanted
2468 to allow more generality (e.g. to allow adding multiple lines
2469 with one add_fixit call. */
2470 if (newline[1] != '\0')
2471 {
2472 stop_supporting_fixits ();
2473 return;
2474 }
338035aa 2475 }
a87a86e1 2476
ad53f123
DM
2477 /* Consolidate neighboring fixits.
2478 Don't consolidate into newline-insertion fixits. */
338035aa 2479 fixit_hint *prev = get_last_fixit_hint ();
ad53f123 2480 if (prev && !prev->ends_with_newline_p ())
338035aa
DM
2481 if (prev->maybe_append (start, next_loc, new_content))
2482 return;
ee908516 2483
338035aa 2484 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
ee908516
DM
2485}
2486
338035aa 2487/* class fixit_hint. */
a87a86e1 2488
620e594b
DM
2489fixit_hint::fixit_hint (location_t start,
2490 location_t next_loc,
338035aa
DM
2491 const char *new_content)
2492: m_start (start),
2493 m_next_loc (next_loc),
a87a86e1
DM
2494 m_bytes (xstrdup (new_content)),
2495 m_len (strlen (new_content))
2496{
2497}
2498
338035aa 2499/* Does this fix-it hint affect the given line? */
a87a86e1
DM
2500
2501bool
338035aa 2502fixit_hint::affects_line_p (const char *file, int line) const
a87a86e1 2503{
338035aa 2504 expanded_location exploc_start
c471c6ed
DM
2505 = linemap_client_expand_location_to_spelling_point (m_start,
2506 LOCATION_ASPECT_START);
338035aa
DM
2507 if (file != exploc_start.file)
2508 return false;
2509 if (line < exploc_start.line)
2510 return false;
2511 expanded_location exploc_next_loc
c471c6ed
DM
2512 = linemap_client_expand_location_to_spelling_point (m_next_loc,
2513 LOCATION_ASPECT_START);
338035aa
DM
2514 if (file != exploc_next_loc.file)
2515 return false;
2516 if (line > exploc_next_loc.line)
2517 return false;
2518 return true;
a87a86e1 2519}
ee908516 2520
338035aa
DM
2521/* Method for consolidating fix-it hints, for use by
2522 rich_location::maybe_add_fixit.
2523 If possible, merge a pending fix-it hint with the given params
2524 into this one and return true.
ee908516
DM
2525 Otherwise return false. */
2526
2527bool
620e594b
DM
2528fixit_hint::maybe_append (location_t start,
2529 location_t next_loc,
338035aa 2530 const char *new_content)
ee908516 2531{
338035aa
DM
2532 /* For consolidation to be possible, START must be at this hint's
2533 m_next_loc. */
2534 if (start != m_next_loc)
ee908516
DM
2535 return false;
2536
338035aa
DM
2537 /* If so, we have neighboring replacements; merge them. */
2538 m_next_loc = next_loc;
ee908516
DM
2539 size_t extra_len = strlen (new_content);
2540 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2541 memcpy (m_bytes + m_len, new_content, extra_len);
2542 m_len += extra_len;
2543 m_bytes[m_len] = '\0';
2544 return true;
2545}
ad53f123
DM
2546
2547/* Return true iff this hint's content ends with a newline. */
2548
2549bool
2550fixit_hint::ends_with_newline_p () const
2551{
2552 if (m_len == 0)
2553 return false;
2554 return m_bytes[m_len - 1] == '\n';
2555}