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