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