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