i386: move alignment defaults to processor_costs.
[official-gcc.git] / libcpp / line-map.c
blob73d94443090004ebba1cda5fcab42ef5ca652d3d
1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2018 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3, or (at your option) any
7 later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>.
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! */
22 #include "config.h"
23 #include "system.h"
24 #include "line-map.h"
25 #include "cpplib.h"
26 #include "internal.h"
27 #include "hashtab.h"
29 static void trace_include (const struct line_maps *, const line_map_ordinary *);
30 static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
31 source_location);
32 static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
33 source_location);
34 static source_location linemap_macro_map_loc_to_def_point
35 (const line_map_macro *, source_location);
36 static source_location linemap_macro_map_loc_to_exp_point
37 (const line_map_macro *, source_location);
38 static source_location linemap_macro_loc_to_spelling_point
39 (struct line_maps *, source_location, const line_map_ordinary **);
40 static source_location linemap_macro_loc_to_def_point (struct line_maps *,
41 source_location,
42 const line_map_ordinary **);
43 static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
44 source_location,
45 const line_map_ordinary **);
47 /* Counters defined in macro.c. */
48 extern unsigned num_expanded_macros_counter;
49 extern unsigned num_macro_tokens_counter;
51 /* Destructor for class line_maps.
52 Ensure non-GC-managed memory is released. */
54 line_maps::~line_maps ()
56 if (location_adhoc_data_map.htab)
57 htab_delete (location_adhoc_data_map.htab);
60 /* Hash function for location_adhoc_data hashtable. */
62 static hashval_t
63 location_adhoc_data_hash (const void *l)
65 const struct location_adhoc_data *lb =
66 (const struct location_adhoc_data *) l;
67 return ((hashval_t) lb->locus
68 + (hashval_t) lb->src_range.m_start
69 + (hashval_t) lb->src_range.m_finish
70 + (size_t) lb->data);
73 /* Compare function for location_adhoc_data hashtable. */
75 static int
76 location_adhoc_data_eq (const void *l1, const void *l2)
78 const struct location_adhoc_data *lb1 =
79 (const struct location_adhoc_data *) l1;
80 const struct location_adhoc_data *lb2 =
81 (const struct location_adhoc_data *) l2;
82 return (lb1->locus == lb2->locus
83 && lb1->src_range.m_start == lb2->src_range.m_start
84 && lb1->src_range.m_finish == lb2->src_range.m_finish
85 && lb1->data == lb2->data);
88 /* Update the hashtable when location_adhoc_data is reallocated. */
90 static int
91 location_adhoc_data_update (void **slot, void *data)
93 *((char **) slot)
94 = (char *) ((uintptr_t) *((char **) slot) + *((ptrdiff_t *) data));
95 return 1;
98 /* Rebuild the hash table from the location adhoc data. */
100 void
101 rebuild_location_adhoc_htab (struct line_maps *set)
103 unsigned i;
104 set->location_adhoc_data_map.htab =
105 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
106 for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
107 htab_find_slot (set->location_adhoc_data_map.htab,
108 set->location_adhoc_data_map.data + i, INSERT);
111 /* Helper function for get_combined_adhoc_loc.
112 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
113 within a source_location, without needing to use an ad-hoc location. */
115 static bool
116 can_be_stored_compactly_p (struct line_maps *set,
117 source_location locus,
118 source_range src_range,
119 void *data)
121 /* If there's an ad-hoc pointer, we can't store it directly in the
122 source_location, we need the lookaside. */
123 if (data)
124 return false;
126 /* We only store ranges that begin at the locus and that are sufficiently
127 "sane". */
128 if (src_range.m_start != locus)
129 return false;
131 if (src_range.m_finish < src_range.m_start)
132 return false;
134 if (src_range.m_start < RESERVED_LOCATION_COUNT)
135 return false;
137 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
138 return false;
140 /* All 3 locations must be within ordinary maps, typically, the same
141 ordinary map. */
142 source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
143 if (locus >= lowest_macro_loc)
144 return false;
145 if (src_range.m_start >= lowest_macro_loc)
146 return false;
147 if (src_range.m_finish >= lowest_macro_loc)
148 return false;
150 /* Passed all tests. */
151 return true;
154 /* Combine LOCUS and DATA to a combined adhoc loc. */
156 source_location
157 get_combined_adhoc_loc (struct line_maps *set,
158 source_location locus,
159 source_range src_range,
160 void *data)
162 struct location_adhoc_data lb;
163 struct location_adhoc_data **slot;
165 if (IS_ADHOC_LOC (locus))
166 locus
167 = set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
168 if (locus == 0 && data == NULL)
169 return 0;
171 /* Any ordinary locations ought to be "pure" at this point: no
172 compressed ranges. */
173 linemap_assert (locus < RESERVED_LOCATION_COUNT
174 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
175 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
176 || pure_location_p (set, locus));
178 /* Consider short-range optimization. */
179 if (can_be_stored_compactly_p (set, locus, src_range, data))
181 /* The low bits ought to be clear. */
182 linemap_assert (pure_location_p (set, locus));
183 const line_map *map = linemap_lookup (set, locus);
184 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
185 unsigned int int_diff = src_range.m_finish - src_range.m_start;
186 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
187 if (col_diff < (1U << ordmap->m_range_bits))
189 source_location packed = locus | col_diff;
190 set->num_optimized_ranges++;
191 return packed;
195 /* We can also compactly store locations
196 when locus == start == finish (and data is NULL). */
197 if (locus == src_range.m_start
198 && locus == src_range.m_finish
199 && !data)
200 return locus;
202 if (!data)
203 set->num_unoptimized_ranges++;
205 lb.locus = locus;
206 lb.src_range = src_range;
207 lb.data = data;
208 slot = (struct location_adhoc_data **)
209 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
210 if (*slot == NULL)
212 if (set->location_adhoc_data_map.curr_loc >=
213 set->location_adhoc_data_map.allocated)
215 char *orig_data = (char *) set->location_adhoc_data_map.data;
216 ptrdiff_t offset;
217 /* Cast away extern "C" from the type of xrealloc. */
218 line_map_realloc reallocator = (set->reallocator
219 ? set->reallocator
220 : (line_map_realloc) xrealloc);
222 if (set->location_adhoc_data_map.allocated == 0)
223 set->location_adhoc_data_map.allocated = 128;
224 else
225 set->location_adhoc_data_map.allocated *= 2;
226 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
227 reallocator (set->location_adhoc_data_map.data,
228 set->location_adhoc_data_map.allocated
229 * sizeof (struct location_adhoc_data));
230 offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
231 if (set->location_adhoc_data_map.allocated > 128)
232 htab_traverse (set->location_adhoc_data_map.htab,
233 location_adhoc_data_update, &offset);
235 *slot = set->location_adhoc_data_map.data
236 + set->location_adhoc_data_map.curr_loc;
237 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
238 = lb;
240 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
243 /* Return the data for the adhoc loc. */
245 void *
246 get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
248 linemap_assert (IS_ADHOC_LOC (loc));
249 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
252 /* Return the location for the adhoc loc. */
254 source_location
255 get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
257 linemap_assert (IS_ADHOC_LOC (loc));
258 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
261 /* Return the source_range for adhoc location LOC. */
263 static source_range
264 get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
266 linemap_assert (IS_ADHOC_LOC (loc));
267 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
270 /* Get the source_range of location LOC, either from the ad-hoc
271 lookaside table, or embedded inside LOC itself. */
273 source_range
274 get_range_from_loc (struct line_maps *set,
275 source_location loc)
277 if (IS_ADHOC_LOC (loc))
278 return get_range_from_adhoc_loc (set, loc);
280 /* For ordinary maps, extract packed range. */
281 if (loc >= RESERVED_LOCATION_COUNT
282 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
283 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
285 const line_map *map = linemap_lookup (set, loc);
286 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
287 source_range result;
288 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
289 result.m_start = loc - offset;
290 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
291 return result;
294 return source_range::from_location (loc);
297 /* Get whether location LOC is a "pure" location, or
298 whether it is an ad-hoc location, or embeds range information. */
300 bool
301 pure_location_p (line_maps *set, source_location loc)
303 if (IS_ADHOC_LOC (loc))
304 return false;
306 const line_map *map = linemap_lookup (set, loc);
307 if (map == NULL)
308 return true;
309 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
311 if (loc & ((1U << ordmap->m_range_bits) - 1))
312 return false;
314 return true;
317 /* Given location LOC within SET, strip away any packed range information
318 or ad-hoc information. */
320 source_location
321 get_pure_location (line_maps *set, source_location loc)
323 if (IS_ADHOC_LOC (loc))
325 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
327 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
328 return loc;
330 if (loc < RESERVED_LOCATION_COUNT)
331 return loc;
333 const line_map *map = linemap_lookup (set, loc);
334 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
336 return loc & ~((1 << ordmap->m_range_bits) - 1);
339 /* Initialize a line map set. */
341 void
342 linemap_init (struct line_maps *set,
343 source_location builtin_location)
345 #if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
346 /* PR33916, needed to fix PR82939. */
347 memset (set, 0, sizeof (struct line_maps));
348 #else
349 new (set) line_maps();
350 #endif
351 /* Set default reallocator (used for initial alloc too). */
352 set->reallocator = xrealloc;
353 set->highest_location = RESERVED_LOCATION_COUNT - 1;
354 set->highest_line = RESERVED_LOCATION_COUNT - 1;
355 set->location_adhoc_data_map.htab =
356 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
357 set->builtin_location = builtin_location;
360 /* Return the ordinary line map from whence MAP was included. Returns
361 NULL if MAP was not an include. */
363 const line_map_ordinary *
364 linemap_included_from_linemap (line_maps *set, const line_map_ordinary *map)
366 return linemap_ordinary_map_lookup (set, linemap_included_from (map));
369 /* Check for and warn about line_maps entered but not exited. */
371 void
372 linemap_check_files_exited (struct line_maps *set)
374 /* Depending upon whether we are handling preprocessed input or
375 not, this can be a user error or an ICE. */
376 for (const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
377 ! MAIN_FILE_P (map);
378 map = linemap_included_from_linemap (set, map))
379 fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
380 ORDINARY_MAP_FILE_NAME (map));
383 /* Create a new line map in the line map set SET, and return it.
384 REASON is the reason of creating the map. It determines the type
385 of map created (ordinary or macro map). Note that ordinary maps and
386 macro maps are allocated in different memory location. */
388 static struct line_map *
389 new_linemap (struct line_maps *set, source_location start_location)
391 bool macro_p = start_location >= LINE_MAP_MAX_LOCATION;
392 unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
393 unsigned num_maps_used = LINEMAPS_USED (set, macro_p);
395 if (num_maps_used == num_maps_allocated)
397 /* We need more space! */
398 if (!num_maps_allocated)
399 num_maps_allocated = 128;
400 num_maps_allocated *= 2;
402 size_t size_of_a_map;
403 void *buffer;
404 if (macro_p)
406 size_of_a_map = sizeof (line_map_macro);
407 buffer = set->info_macro.maps;
409 else
411 size_of_a_map = sizeof (line_map_ordinary);
412 buffer = set->info_ordinary.maps;
415 /* We are going to execute some dance to try to reduce the
416 overhead of the memory allocator, in case we are using the
417 ggc-page.c one.
419 The actual size of memory we are going to get back from the
420 allocator may well be larger than what we ask for. Use this
421 hook to find what that size is. */
422 size_t alloc_size
423 = set->round_alloc_size (num_maps_allocated * size_of_a_map);
425 /* Now alloc_size contains the exact memory size we would get if
426 we have asked for the initial alloc_size amount of memory.
427 Let's get back to the number of map that amounts to. */
428 unsigned num_maps = alloc_size / size_of_a_map;
429 buffer = set->reallocator (buffer, num_maps * size_of_a_map);
430 memset ((char *)buffer + num_maps_used * size_of_a_map, 0,
431 (num_maps - num_maps_used) * size_of_a_map);
432 if (macro_p)
433 set->info_macro.maps = (line_map_macro *)buffer;
434 else
435 set->info_ordinary.maps = (line_map_ordinary *)buffer;
436 LINEMAPS_ALLOCATED (set, macro_p) = num_maps;
439 line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used]
440 : (line_map *)&set->info_ordinary.maps[num_maps_used]);
441 LINEMAPS_USED (set, macro_p)++;
443 result->start_location = start_location;
445 return result;
448 /* Add a mapping of logical source line to physical source file and
449 line number.
451 The text pointed to by TO_FILE must have a lifetime
452 at least as long as the final call to lookup_line (). An empty
453 TO_FILE means standard input. If reason is LC_LEAVE, and
454 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
455 natural values considering the file we are returning to.
457 FROM_LINE should be monotonic increasing across calls to this
458 function. A call to this function can relocate the previous set of
459 maps, so any stored line_map pointers should not be used. */
461 const struct line_map *
462 linemap_add (struct line_maps *set, enum lc_reason reason,
463 unsigned int sysp, const char *to_file, linenum_type to_line)
465 /* Generate a start_location above the current highest_location.
466 If possible, make the low range bits be zero. */
467 source_location start_location;
468 if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
470 start_location = set->highest_location + (1 << set->default_range_bits);
471 if (set->default_range_bits)
472 start_location &= ~((1 << set->default_range_bits) - 1);
473 linemap_assert (0 == (start_location
474 & ((1 << set->default_range_bits) - 1)));
476 else
477 start_location = set->highest_location + 1;
479 linemap_assert (!LINEMAPS_ORDINARY_USED (set)
480 || (start_location
481 >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
483 /* When we enter the file for the first time reason cannot be
484 LC_RENAME. */
485 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
487 /* If we are leaving the main file, return a NULL map. */
488 if (reason == LC_LEAVE
489 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
490 && to_file == NULL)
492 set->depth--;
493 return NULL;
496 linemap_assert (reason != LC_ENTER_MACRO);
498 if (start_location >= LINE_MAP_MAX_LOCATION)
499 /* We ran out of line map space. */
500 start_location = 0;
502 line_map_ordinary *map
503 = linemap_check_ordinary (new_linemap (set, start_location));
504 map->reason = reason;
506 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
507 to_file = "<stdin>";
509 if (reason == LC_RENAME_VERBATIM)
510 reason = LC_RENAME;
512 const line_map_ordinary *from = NULL;
513 if (reason == LC_LEAVE)
515 /* When we are just leaving an "included" file, and jump to the next
516 location inside the "includer" right after the #include
517 "included", this variable points the map in use right before the
518 #include "included", inside the same "includer" file. */
520 linemap_assert (!MAIN_FILE_P (map - 1));
521 /* (MAP - 1) points to the map we are leaving. The
522 map from which (MAP - 1) got included should be the map
523 that comes right before MAP in the same file. */
524 from = linemap_included_from_linemap (set, map - 1);
526 /* A TO_FILE of NULL is special - we use the natural values. */
527 if (to_file == NULL)
529 to_file = ORDINARY_MAP_FILE_NAME (from);
530 to_line = SOURCE_LINE (from, from[1].start_location);
531 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
533 else
534 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
535 to_file) == 0);
538 map->sysp = sysp;
539 map->to_file = to_file;
540 map->to_line = to_line;
541 LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
542 map->m_column_and_range_bits = 0;
543 map->m_range_bits = 0;
544 set->highest_location = start_location;
545 set->highest_line = start_location;
546 set->max_column_hint = 0;
548 /* This assertion is placed after set->highest_location has
549 been updated, since the latter affects
550 linemap_location_from_macro_expansion_p, which ultimately affects
551 pure_location_p. */
552 linemap_assert (pure_location_p (set, start_location));
554 if (reason == LC_ENTER)
556 if (set->depth == 0)
557 map->included_from = 0;
558 else
559 /* The location of the end of the just-closed map. */
560 map->included_from
561 = (((map[0].start_location - 1 - map[-1].start_location)
562 & ~((1 << map[-1].m_column_and_range_bits) - 1))
563 + map[-1].start_location);
564 set->depth++;
565 if (set->trace_includes)
566 trace_include (set, map);
568 else if (reason == LC_RENAME)
569 map->included_from = linemap_included_from (&map[-1]);
570 else if (reason == LC_LEAVE)
572 set->depth--;
573 map->included_from = linemap_included_from (from);
576 return map;
579 /* Returns TRUE if the line table set tracks token locations across
580 macro expansion, FALSE otherwise. */
582 bool
583 linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
585 return LINEMAPS_MACRO_MAPS (set) != NULL;
588 /* Create a macro map. A macro map encodes source locations of tokens
589 that are part of a macro replacement-list, at a macro expansion
590 point. See the extensive comments of struct line_map and struct
591 line_map_macro, in line-map.h.
593 This map shall be created when the macro is expanded. The map
594 encodes the source location of the expansion point of the macro as
595 well as the "original" source location of each token that is part
596 of the macro replacement-list. If a macro is defined but never
597 expanded, it has no macro map. SET is the set of maps the macro
598 map should be part of. MACRO_NODE is the macro which the new macro
599 map should encode source locations for. EXPANSION is the location
600 of the expansion point of MACRO. For function-like macros
601 invocations, it's best to make it point to the closing parenthesis
602 of the macro, rather than the the location of the first character
603 of the macro. NUM_TOKENS is the number of tokens that are part of
604 the replacement-list of MACRO.
606 Note that when we run out of the integer space available for source
607 locations, this function returns NULL. In that case, callers of
608 this function cannot encode {line,column} pairs into locations of
609 macro tokens anymore. */
611 const line_map_macro *
612 linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
613 source_location expansion, unsigned int num_tokens)
615 line_map_macro *map;
616 source_location start_location;
617 /* Cast away extern "C" from the type of xrealloc. */
618 line_map_realloc reallocator = (set->reallocator
619 ? set->reallocator
620 : (line_map_realloc) xrealloc);
622 start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
624 if (start_location < LINE_MAP_MAX_LOCATION)
625 /* We ran out of macro map space. */
626 return NULL;
628 map = linemap_check_macro (new_linemap (set, start_location));
630 map->macro = macro_node;
631 map->n_tokens = num_tokens;
632 map->macro_locations
633 = (source_location*) reallocator (NULL,
634 2 * num_tokens
635 * sizeof (source_location));
636 map->expansion = expansion;
637 memset (MACRO_MAP_LOCATIONS (map), 0,
638 num_tokens * sizeof (source_location));
640 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
642 return map;
645 /* Create and return a virtual location for a token that is part of a
646 macro expansion-list at a macro expansion point. See the comment
647 inside struct line_map_macro to see what an expansion-list exactly
650 A call to this function must come after a call to
651 linemap_enter_macro.
653 MAP is the map into which the source location is created. TOKEN_NO
654 is the index of the token in the macro replacement-list, starting
655 at number 0.
657 ORIG_LOC is the location of the token outside of this macro
658 expansion. If the token comes originally from the macro
659 definition, it is the locus in the macro definition; otherwise it
660 is a location in the context of the caller of this macro expansion
661 (which is a virtual location or a source location if the caller is
662 itself a macro expansion or not).
664 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
665 either of the token itself or of a macro parameter that it
666 replaces. */
668 source_location
669 linemap_add_macro_token (const line_map_macro *map,
670 unsigned int token_no,
671 source_location orig_loc,
672 source_location orig_parm_replacement_loc)
674 source_location result;
676 linemap_assert (linemap_macro_expansion_map_p (map));
677 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
679 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
680 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
682 result = MAP_START_LOCATION (map) + token_no;
683 return result;
686 /* Return a source_location for the start (i.e. column==0) of
687 (physical) line TO_LINE in the current source file (as in the
688 most recent linemap_add). MAX_COLUMN_HINT is the highest column
689 number we expect to use in this line (but it does not change
690 the highest_location). */
692 source_location
693 linemap_line_start (struct line_maps *set, linenum_type to_line,
694 unsigned int max_column_hint)
696 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
697 source_location highest = set->highest_location;
698 source_location r;
699 linenum_type last_line =
700 SOURCE_LINE (map, set->highest_line);
701 int line_delta = to_line - last_line;
702 bool add_map = false;
703 linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
704 int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
706 if (line_delta < 0
707 || (line_delta > 10
708 && line_delta * map->m_column_and_range_bits > 1000)
709 || (max_column_hint >= (1U << effective_column_bits))
710 || (max_column_hint <= 80 && effective_column_bits >= 10)
711 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
712 && map->m_range_bits > 0)
713 || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
714 && (set->max_column_hint || highest >= LINE_MAP_MAX_LOCATION)))
715 add_map = true;
716 else
717 max_column_hint = set->max_column_hint;
718 if (add_map)
720 int column_bits;
721 int range_bits;
722 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
723 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
725 /* If the column number is ridiculous or we've allocated a huge
726 number of source_locations, give up on column numbers
727 (and on packed ranges). */
728 max_column_hint = 0;
729 column_bits = 0;
730 range_bits = 0;
731 if (highest >= LINE_MAP_MAX_LOCATION)
732 return 0;
734 else
736 column_bits = 7;
737 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
738 range_bits = set->default_range_bits;
739 else
740 range_bits = 0;
741 while (max_column_hint >= (1U << column_bits))
742 column_bits++;
743 max_column_hint = 1U << column_bits;
744 column_bits += range_bits;
746 /* Allocate the new line_map. However, if the current map only has a
747 single line we can sometimes just increase its column_bits instead. */
748 if (line_delta < 0
749 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
750 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
751 || range_bits < map->m_range_bits)
752 map = linemap_check_ordinary
753 (const_cast <line_map *>
754 (linemap_add (set, LC_RENAME,
755 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
756 ORDINARY_MAP_FILE_NAME (map),
757 to_line)));
758 map->m_column_and_range_bits = column_bits;
759 map->m_range_bits = range_bits;
760 r = (MAP_START_LOCATION (map)
761 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
762 << column_bits));
764 else
765 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
767 /* Locations of ordinary tokens are always lower than locations of
768 macro tokens. */
769 if (r >= LINE_MAP_MAX_LOCATION)
770 return 0;
772 set->highest_line = r;
773 if (r > set->highest_location)
774 set->highest_location = r;
775 set->max_column_hint = max_column_hint;
777 /* At this point, we expect one of:
778 (a) the normal case: a "pure" location with 0 range bits, or
779 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
780 columns anymore (or ranges), or
781 (c) we're in a region with a column hint exceeding
782 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
783 with column_bits == 0. */
784 linemap_assert (pure_location_p (set, r)
785 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
786 || map->m_column_and_range_bits == 0);
787 linemap_assert (SOURCE_LINE (map, r) == to_line);
788 return r;
791 /* Encode and return a source_location from a column number. The
792 source line considered is the last source line used to call
793 linemap_line_start, i.e, the last source line which a location was
794 encoded from. */
796 source_location
797 linemap_position_for_column (struct line_maps *set, unsigned int to_column)
799 source_location r = set->highest_line;
801 linemap_assert
802 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
804 if (to_column >= set->max_column_hint)
806 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
807 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
809 /* Running low on source_locations - disable column numbers. */
810 return r;
812 else
814 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
815 with some space to spare. This may or may not lead to a new
816 linemap being created. */
817 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
818 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
819 map = LINEMAPS_LAST_ORDINARY_MAP (set);
820 if (map->m_column_and_range_bits == 0)
822 /* ...then the linemap has column-tracking disabled,
823 presumably due to exceeding either
824 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
825 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
826 Return the start of the linemap, which encodes column 0, for
827 the whole line. */
828 return r;
832 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
833 r = r + (to_column << map->m_range_bits);
834 if (r >= set->highest_location)
835 set->highest_location = r;
836 return r;
839 /* Encode and return a source location from a given line and
840 column. */
842 source_location
843 linemap_position_for_line_and_column (line_maps *set,
844 const line_map_ordinary *ord_map,
845 linenum_type line,
846 unsigned column)
848 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
850 source_location r = MAP_START_LOCATION (ord_map);
851 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
852 << ord_map->m_column_and_range_bits);
853 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
854 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
855 << ord_map->m_range_bits);
856 source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
857 if (r >= upper_limit)
858 r = upper_limit - 1;
859 if (r > set->highest_location)
860 set->highest_location = r;
861 return r;
864 /* Encode and return a source_location starting from location LOC and
865 shifting it by COLUMN_OFFSET columns. This function does not support
866 virtual locations. */
868 source_location
869 linemap_position_for_loc_and_offset (struct line_maps *set,
870 source_location loc,
871 unsigned int column_offset)
873 const line_map_ordinary * map = NULL;
875 if (IS_ADHOC_LOC (loc))
876 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
878 /* This function does not support virtual locations yet. */
879 if (linemap_location_from_macro_expansion_p (set, loc))
880 return loc;
882 if (column_offset == 0
883 /* Adding an offset to a reserved location (like
884 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
885 sense. So let's leave the location intact in that case. */
886 || loc < RESERVED_LOCATION_COUNT)
887 return loc;
889 /* We find the real location and shift it. */
890 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
891 /* The new location (loc + offset) should be higher than the first
892 location encoded by MAP. This can fail if the line information
893 is messed up because of line directives (see PR66415). */
894 if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
895 return loc;
897 linenum_type line = SOURCE_LINE (map, loc);
898 unsigned int column = SOURCE_COLUMN (map, loc);
900 /* If MAP is not the last line map of its set, then the new location
901 (loc + offset) should be less than the first location encoded by
902 the next line map of the set. Otherwise, we try to encode the
903 location in the next map. */
904 while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
905 && (loc + (column_offset << map->m_range_bits)
906 >= MAP_START_LOCATION (&map[1])))
908 map = &map[1];
909 /* If the next map starts in a higher line, we cannot encode the
910 location there. */
911 if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
912 return loc;
915 column += column_offset;
917 /* Bail out if the column is not representable within the existing
918 linemap. */
919 if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
920 return loc;
922 source_location r =
923 linemap_position_for_line_and_column (set, map, line, column);
924 if (linemap_assert_fails (r <= set->highest_location)
925 || linemap_assert_fails (map == linemap_lookup (set, r)))
926 return loc;
928 return r;
931 /* Given a virtual source location yielded by a map (either an
932 ordinary or a macro map), returns that map. */
934 const struct line_map*
935 linemap_lookup (struct line_maps *set, source_location line)
937 if (IS_ADHOC_LOC (line))
938 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
939 if (linemap_location_from_macro_expansion_p (set, line))
940 return linemap_macro_map_lookup (set, line);
941 return linemap_ordinary_map_lookup (set, line);
944 /* Given a source location yielded by an ordinary map, returns that
945 map. Since the set is built chronologically, the logical lines are
946 monotonic increasing, and so the list is sorted and we can use a
947 binary search. */
949 static const line_map_ordinary *
950 linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
952 unsigned int md, mn, mx;
953 const line_map_ordinary *cached, *result;
955 if (IS_ADHOC_LOC (line))
956 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
958 if (set == NULL || line < RESERVED_LOCATION_COUNT)
959 return NULL;
961 mn = LINEMAPS_ORDINARY_CACHE (set);
962 mx = LINEMAPS_ORDINARY_USED (set);
964 cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
965 /* We should get a segfault if no line_maps have been added yet. */
966 if (line >= MAP_START_LOCATION (cached))
968 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
969 return cached;
971 else
973 mx = mn;
974 mn = 0;
977 while (mx - mn > 1)
979 md = (mn + mx) / 2;
980 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
981 mx = md;
982 else
983 mn = md;
986 LINEMAPS_ORDINARY_CACHE (set) = mn;
987 result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
988 linemap_assert (line >= MAP_START_LOCATION (result));
989 return result;
992 /* Given a source location yielded by a macro map, returns that map.
993 Since the set is built chronologically, the logical lines are
994 monotonic decreasing, and so the list is sorted and we can use a
995 binary search. */
997 static const line_map_macro *
998 linemap_macro_map_lookup (struct line_maps *set, source_location line)
1000 unsigned int md, mn, mx;
1001 const struct line_map_macro *cached, *result;
1003 if (IS_ADHOC_LOC (line))
1004 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
1006 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1008 if (set == NULL)
1009 return NULL;
1011 mn = LINEMAPS_MACRO_CACHE (set);
1012 mx = LINEMAPS_MACRO_USED (set);
1013 cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1015 if (line >= MAP_START_LOCATION (cached))
1017 if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
1018 return cached;
1019 mx = mn - 1;
1020 mn = 0;
1023 while (mn < mx)
1025 md = (mx + mn) / 2;
1026 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1027 mn = md + 1;
1028 else
1029 mx = md;
1032 LINEMAPS_MACRO_CACHE (set) = mx;
1033 result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
1034 linemap_assert (MAP_START_LOCATION (result) <= line);
1036 return result;
1039 /* Return TRUE if MAP encodes locations coming from a macro
1040 replacement-list at macro expansion point. */
1042 bool
1043 linemap_macro_expansion_map_p (const struct line_map *map)
1045 return map && !MAP_ORDINARY_P (map);
1048 /* If LOCATION is the locus of a token in a replacement-list of a
1049 macro expansion return the location of the macro expansion point.
1051 Read the comments of struct line_map and struct line_map_macro in
1052 line-map.h to understand what a macro expansion point is. */
1054 static source_location
1055 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1056 source_location location ATTRIBUTE_UNUSED)
1058 linemap_assert (linemap_macro_expansion_map_p (map)
1059 && location >= MAP_START_LOCATION (map));
1061 /* Make sure LOCATION is correct. */
1062 linemap_assert ((location - MAP_START_LOCATION (map))
1063 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1065 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1068 /* LOCATION is the source location of a token that belongs to a macro
1069 replacement-list as part of the macro expansion denoted by MAP.
1071 Return the location of the token at the definition point of the
1072 macro. */
1074 static source_location
1075 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1076 source_location location)
1078 unsigned token_no;
1080 linemap_assert (linemap_macro_expansion_map_p (map)
1081 && location >= MAP_START_LOCATION (map));
1082 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1084 token_no = location - MAP_START_LOCATION (map);
1085 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1087 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1089 return location;
1092 /* If LOCATION is the locus of a token that is an argument of a
1093 function-like macro M and appears in the expansion of M, return the
1094 locus of that argument in the context of the caller of M.
1096 In other words, this returns the xI location presented in the
1097 comments of line_map_macro above. */
1098 source_location
1099 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1100 const line_map_macro* map,
1101 source_location location)
1103 unsigned token_no;
1105 if (IS_ADHOC_LOC (location))
1106 location = get_location_from_adhoc_loc (set, location);
1108 linemap_assert (linemap_macro_expansion_map_p (map)
1109 && location >= MAP_START_LOCATION (map));
1110 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1111 linemap_assert (!IS_ADHOC_LOC (location));
1113 token_no = location - MAP_START_LOCATION (map);
1114 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1116 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1118 return location;
1121 /* Return the source line number corresponding to source location
1122 LOCATION. SET is the line map set LOCATION comes from. If
1123 LOCATION is the source location of token that is part of the
1124 replacement-list of a macro expansion return the line number of the
1125 macro expansion point. */
1128 linemap_get_expansion_line (struct line_maps *set,
1129 source_location location)
1131 const line_map_ordinary *map = NULL;
1133 if (IS_ADHOC_LOC (location))
1134 location = set->location_adhoc_data_map.data[location
1135 & MAX_SOURCE_LOCATION].locus;
1137 if (location < RESERVED_LOCATION_COUNT)
1138 return 0;
1140 location =
1141 linemap_macro_loc_to_exp_point (set, location, &map);
1143 return SOURCE_LINE (map, location);
1146 /* Return the path of the file corresponding to source code location
1147 LOCATION.
1149 If LOCATION is the source location of token that is part of the
1150 replacement-list of a macro expansion return the file path of the
1151 macro expansion point.
1153 SET is the line map set LOCATION comes from. */
1155 const char*
1156 linemap_get_expansion_filename (struct line_maps *set,
1157 source_location location)
1159 const struct line_map_ordinary *map = NULL;
1161 if (IS_ADHOC_LOC (location))
1162 location = set->location_adhoc_data_map.data[location
1163 & MAX_SOURCE_LOCATION].locus;
1165 if (location < RESERVED_LOCATION_COUNT)
1166 return NULL;
1168 location =
1169 linemap_macro_loc_to_exp_point (set, location, &map);
1171 return LINEMAP_FILE (map);
1174 /* Return the name of the macro associated to MACRO_MAP. */
1176 const char*
1177 linemap_map_get_macro_name (const line_map_macro *macro_map)
1179 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1180 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1183 /* Return a positive value if LOCATION is the locus of a token that is
1184 located in a system header, O otherwise. It returns 1 if LOCATION
1185 is the locus of a token that is located in a system header, and 2
1186 if LOCATION is the locus of a token located in a C system header
1187 that therefore needs to be extern "C" protected in C++.
1189 Note that this function returns 1 if LOCATION belongs to a token
1190 that is part of a macro replacement-list defined in a system
1191 header, but expanded in a non-system file. */
1194 linemap_location_in_system_header_p (struct line_maps *set,
1195 source_location location)
1197 const struct line_map *map = NULL;
1199 if (IS_ADHOC_LOC (location))
1200 location = set->location_adhoc_data_map.data[location
1201 & MAX_SOURCE_LOCATION].locus;
1203 if (location < RESERVED_LOCATION_COUNT)
1204 return false;
1206 /* Let's look at where the token for LOCATION comes from. */
1207 while (true)
1209 map = linemap_lookup (set, location);
1210 if (map != NULL)
1212 if (!linemap_macro_expansion_map_p (map))
1213 /* It's a normal token. */
1214 return LINEMAP_SYSP (linemap_check_ordinary (map));
1215 else
1217 const line_map_macro *macro_map = linemap_check_macro (map);
1219 /* It's a token resulting from a macro expansion. */
1220 source_location loc =
1221 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1222 if (loc < RESERVED_LOCATION_COUNT)
1223 /* This token might come from a built-in macro. Let's
1224 look at where that macro got expanded. */
1225 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1226 else
1227 location = loc;
1230 else
1231 break;
1233 return false;
1236 /* Return TRUE if LOCATION is a source code location of a token that is part of
1237 a macro expansion, FALSE otherwise. */
1239 bool
1240 linemap_location_from_macro_expansion_p (const struct line_maps *set,
1241 source_location location)
1243 if (IS_ADHOC_LOC (location))
1244 location = set->location_adhoc_data_map.data[location
1245 & MAX_SOURCE_LOCATION].locus;
1247 return location >= LINE_MAP_MAX_LOCATION;
1250 /* Given two virtual locations *LOC0 and *LOC1, return the first
1251 common macro map in their macro expansion histories. Return NULL
1252 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1253 virtual location of the token inside the resulting macro. */
1255 static const struct line_map*
1256 first_map_in_common_1 (struct line_maps *set,
1257 source_location *loc0,
1258 source_location *loc1)
1260 source_location l0 = *loc0, l1 = *loc1;
1261 const struct line_map *map0 = linemap_lookup (set, l0),
1262 *map1 = linemap_lookup (set, l1);
1264 while (linemap_macro_expansion_map_p (map0)
1265 && linemap_macro_expansion_map_p (map1)
1266 && (map0 != map1))
1268 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1270 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1271 l0);
1272 map0 = linemap_lookup (set, l0);
1274 else
1276 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1277 l1);
1278 map1 = linemap_lookup (set, l1);
1282 if (map0 == map1)
1284 *loc0 = l0;
1285 *loc1 = l1;
1286 return map0;
1288 return NULL;
1291 /* Given two virtual locations LOC0 and LOC1, return the first common
1292 macro map in their macro expansion histories. Return NULL if no
1293 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1294 virtual location of the token inside the resulting macro, upon
1295 return of a non-NULL result. */
1297 static const struct line_map*
1298 first_map_in_common (struct line_maps *set,
1299 source_location loc0,
1300 source_location loc1,
1301 source_location *res_loc0,
1302 source_location *res_loc1)
1304 *res_loc0 = loc0;
1305 *res_loc1 = loc1;
1307 return first_map_in_common_1 (set, res_loc0, res_loc1);
1310 /* Return a positive value if PRE denotes the location of a token that
1311 comes before the token of POST, 0 if PRE denotes the location of
1312 the same token as the token for POST, and a negative value
1313 otherwise. */
1316 linemap_compare_locations (struct line_maps *set,
1317 source_location pre,
1318 source_location post)
1320 bool pre_virtual_p, post_virtual_p;
1321 source_location l0 = pre, l1 = post;
1323 if (IS_ADHOC_LOC (l0))
1324 l0 = get_location_from_adhoc_loc (set, l0);
1325 if (IS_ADHOC_LOC (l1))
1326 l1 = get_location_from_adhoc_loc (set, l1);
1328 if (l0 == l1)
1329 return 0;
1331 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1332 l0 = linemap_resolve_location (set, l0,
1333 LRK_MACRO_EXPANSION_POINT,
1334 NULL);
1336 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1337 l1 = linemap_resolve_location (set, l1,
1338 LRK_MACRO_EXPANSION_POINT,
1339 NULL);
1341 if (l0 == l1
1342 && pre_virtual_p
1343 && post_virtual_p)
1345 /* So pre and post represent two tokens that are present in a
1346 same macro expansion. Let's see if the token for pre was
1347 before the token for post in that expansion. */
1348 unsigned i0, i1;
1349 const struct line_map *map =
1350 first_map_in_common (set, pre, post, &l0, &l1);
1352 if (map == NULL)
1353 /* This should not be possible. */
1354 abort ();
1356 i0 = l0 - MAP_START_LOCATION (map);
1357 i1 = l1 - MAP_START_LOCATION (map);
1358 return i1 - i0;
1361 if (IS_ADHOC_LOC (l0))
1362 l0 = get_location_from_adhoc_loc (set, l0);
1363 if (IS_ADHOC_LOC (l1))
1364 l1 = get_location_from_adhoc_loc (set, l1);
1366 return l1 - l0;
1369 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1371 static void
1372 trace_include (const struct line_maps *set, const line_map_ordinary *map)
1374 unsigned int i = set->depth;
1376 while (--i)
1377 putc ('.', stderr);
1379 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1382 /* Return the spelling location of the token wherever it comes from,
1383 whether part of a macro definition or not.
1385 This is a subroutine for linemap_resolve_location. */
1387 static source_location
1388 linemap_macro_loc_to_spelling_point (struct line_maps *set,
1389 source_location location,
1390 const line_map_ordinary **original_map)
1392 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1394 while (true)
1396 const struct line_map *map = linemap_lookup (set, location);
1397 if (!map || MAP_ORDINARY_P (map))
1399 if (original_map)
1400 *original_map = (const line_map_ordinary *)map;
1401 break;
1404 location = linemap_macro_map_loc_unwind_toward_spelling
1405 (set, linemap_check_macro (map), location);
1408 return location;
1411 /* If LOCATION is the source location of a token that belongs to a
1412 macro replacement-list -- as part of a macro expansion -- then
1413 return the location of the token at the definition point of the
1414 macro. Otherwise, return LOCATION. SET is the set of maps
1415 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1416 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1417 returned location comes from.
1419 This is a subroutine of linemap_resolve_location. */
1421 static source_location
1422 linemap_macro_loc_to_def_point (struct line_maps *set,
1423 source_location location,
1424 const line_map_ordinary **original_map)
1426 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1428 for (;;)
1430 source_location caret_loc = location;
1431 if (IS_ADHOC_LOC (caret_loc))
1432 caret_loc = get_location_from_adhoc_loc (set, caret_loc);
1434 const line_map *map = linemap_lookup (set, caret_loc);
1435 if (!map || MAP_ORDINARY_P (map))
1437 if (original_map)
1438 *original_map = (const line_map_ordinary *)map;
1439 break;
1442 location = linemap_macro_map_loc_to_def_point
1443 (linemap_check_macro (map), caret_loc);
1446 return location;
1449 /* If LOCATION is the source location of a token that belongs to a
1450 macro replacement-list -- at a macro expansion point -- then return
1451 the location of the topmost expansion point of the macro. We say
1452 topmost because if we are in the context of a nested macro
1453 expansion, the function returns the source location of the first
1454 macro expansion that triggered the nested expansions.
1456 Otherwise, return LOCATION. SET is the set of maps location come
1457 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1458 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1459 location comes from.
1461 This is a subroutine of linemap_resolve_location. */
1463 static source_location
1464 linemap_macro_loc_to_exp_point (struct line_maps *set,
1465 source_location location,
1466 const line_map_ordinary **original_map)
1468 struct line_map *map;
1470 if (IS_ADHOC_LOC (location))
1471 location = set->location_adhoc_data_map.data[location
1472 & MAX_SOURCE_LOCATION].locus;
1474 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1476 while (true)
1478 map = const_cast <line_map *> (linemap_lookup (set, location));
1479 if (!linemap_macro_expansion_map_p (map))
1480 break;
1481 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1482 location);
1485 if (original_map)
1486 *original_map = linemap_check_ordinary (map);
1487 return location;
1490 /* Resolve a virtual location into either a spelling location, an
1491 expansion point location or a token argument replacement point
1492 location. Return the map that encodes the virtual location as well
1493 as the resolved location.
1495 If LOC is *NOT* the location of a token resulting from the
1496 expansion of a macro, then the parameter LRK (which stands for
1497 Location Resolution Kind) is ignored and the resulting location
1498 just equals the one given in argument.
1500 Now if LOC *IS* the location of a token resulting from the
1501 expansion of a macro, this is what happens.
1503 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1504 -------------------------------
1506 The virtual location is resolved to the first macro expansion point
1507 that led to this macro expansion.
1509 * If LRK is set to LRK_SPELLING_LOCATION
1510 -------------------------------------
1512 The virtual location is resolved to the locus where the token has
1513 been spelled in the source. This can follow through all the macro
1514 expansions that led to the token.
1516 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1517 --------------------------------------
1519 The virtual location is resolved to the locus of the token in the
1520 context of the macro definition.
1522 If LOC is the locus of a token that is an argument of a
1523 function-like macro [replacing a parameter in the replacement list
1524 of the macro] the virtual location is resolved to the locus of the
1525 parameter that is replaced, in the context of the definition of the
1526 macro.
1528 If LOC is the locus of a token that is not an argument of a
1529 function-like macro, then the function behaves as if LRK was set to
1530 LRK_SPELLING_LOCATION.
1532 If MAP is not NULL, *MAP is set to the map encoding the
1533 returned location. Note that if the returned location wasn't originally
1534 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1535 resolves to a location reserved for the client code, like
1536 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1538 source_location
1539 linemap_resolve_location (struct line_maps *set,
1540 source_location loc,
1541 enum location_resolution_kind lrk,
1542 const line_map_ordinary **map)
1544 source_location locus = loc;
1545 if (IS_ADHOC_LOC (loc))
1546 locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1548 if (locus < RESERVED_LOCATION_COUNT)
1550 /* A reserved location wasn't encoded in a map. Let's return a
1551 NULL map here, just like what linemap_ordinary_map_lookup
1552 does. */
1553 if (map)
1554 *map = NULL;
1555 return loc;
1558 switch (lrk)
1560 case LRK_MACRO_EXPANSION_POINT:
1561 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1562 break;
1563 case LRK_SPELLING_LOCATION:
1564 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1565 break;
1566 case LRK_MACRO_DEFINITION_LOCATION:
1567 loc = linemap_macro_loc_to_def_point (set, loc, map);
1568 break;
1569 default:
1570 abort ();
1572 return loc;
1575 /* TRUE if LOCATION is a source code location of a token that is part of the
1576 definition of a macro, FALSE otherwise. */
1578 bool
1579 linemap_location_from_macro_definition_p (struct line_maps *set,
1580 source_location loc)
1582 if (IS_ADHOC_LOC (loc))
1583 loc = get_location_from_adhoc_loc (set, loc);
1585 if (!linemap_location_from_macro_expansion_p (set, loc))
1586 return false;
1588 while (true)
1590 const struct line_map_macro *map
1591 = linemap_check_macro (linemap_lookup (set, loc));
1593 source_location s_loc
1594 = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
1595 if (linemap_location_from_macro_expansion_p (set, s_loc))
1596 loc = s_loc;
1597 else
1599 source_location def_loc
1600 = linemap_macro_map_loc_to_def_point (map, loc);
1601 return s_loc == def_loc;
1607 Suppose that LOC is the virtual location of a token T coming from
1608 the expansion of a macro M. This function then steps up to get the
1609 location L of the point where M got expanded. If L is a spelling
1610 location inside a macro expansion M', then this function returns
1611 the locus of the point where M' was expanded. Said otherwise, this
1612 function returns the location of T in the context that triggered
1613 the expansion of M.
1615 *LOC_MAP must be set to the map of LOC. This function then sets it
1616 to the map of the returned location. */
1618 source_location
1619 linemap_unwind_toward_expansion (struct line_maps *set,
1620 source_location loc,
1621 const struct line_map **map)
1623 source_location resolved_location;
1624 const line_map_macro *macro_map = linemap_check_macro (*map);
1625 const struct line_map *resolved_map;
1627 if (IS_ADHOC_LOC (loc))
1628 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1630 resolved_location =
1631 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1632 resolved_map = linemap_lookup (set, resolved_location);
1634 if (!linemap_macro_expansion_map_p (resolved_map))
1636 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1637 resolved_map = linemap_lookup (set, resolved_location);
1640 *map = resolved_map;
1641 return resolved_location;
1644 /* If LOC is the virtual location of a token coming from the expansion
1645 of a macro M and if its spelling location is reserved (e.g, a
1646 location for a built-in token), then this function unwinds (using
1647 linemap_unwind_toward_expansion) the location until a location that
1648 is not reserved and is not in a system header is reached. In other
1649 words, this unwinds the reserved location until a location that is
1650 in real source code is reached.
1652 Otherwise, if the spelling location for LOC is not reserved or if
1653 LOC doesn't come from the expansion of a macro, the function
1654 returns LOC as is and *MAP is not touched.
1656 *MAP is set to the map of the returned location if the later is
1657 different from LOC. */
1658 source_location
1659 linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
1660 source_location loc,
1661 const struct line_map **map)
1663 source_location resolved_loc;
1664 const struct line_map *map0 = NULL;
1665 const line_map_ordinary *map1 = NULL;
1667 if (IS_ADHOC_LOC (loc))
1668 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1670 map0 = linemap_lookup (set, loc);
1671 if (!linemap_macro_expansion_map_p (map0))
1672 return loc;
1674 resolved_loc = linemap_resolve_location (set, loc,
1675 LRK_SPELLING_LOCATION,
1676 &map1);
1678 if (resolved_loc >= RESERVED_LOCATION_COUNT
1679 && !LINEMAP_SYSP (map1))
1680 return loc;
1682 while (linemap_macro_expansion_map_p (map0)
1683 && (resolved_loc < RESERVED_LOCATION_COUNT
1684 || LINEMAP_SYSP (map1)))
1686 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1687 resolved_loc = linemap_resolve_location (set, loc,
1688 LRK_SPELLING_LOCATION,
1689 &map1);
1692 if (map != NULL)
1693 *map = map0;
1694 return loc;
1697 /* Expand source code location LOC and return a user readable source
1698 code location. LOC must be a spelling (non-virtual) location. If
1699 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1700 location is returned. */
1702 expanded_location
1703 linemap_expand_location (struct line_maps *set,
1704 const struct line_map *map,
1705 source_location loc)
1708 expanded_location xloc;
1710 memset (&xloc, 0, sizeof (xloc));
1711 if (IS_ADHOC_LOC (loc))
1713 xloc.data
1714 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
1715 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1718 if (loc < RESERVED_LOCATION_COUNT)
1719 /* The location for this token wasn't generated from a line map.
1720 It was probably a location for a builtin token, chosen by some
1721 client code. Let's not try to expand the location in that
1722 case. */;
1723 else if (map == NULL)
1724 /* We shouldn't be getting a NULL map with a location that is not
1725 reserved by the client code. */
1726 abort ();
1727 else
1729 /* MAP must be an ordinary map and LOC must be non-virtual,
1730 encoded into this map, obviously; the accessors used on MAP
1731 below ensure it is ordinary. Let's just assert the
1732 non-virtualness of LOC here. */
1733 if (linemap_location_from_macro_expansion_p (set, loc))
1734 abort ();
1736 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1738 xloc.file = LINEMAP_FILE (ord_map);
1739 xloc.line = SOURCE_LINE (ord_map, loc);
1740 xloc.column = SOURCE_COLUMN (ord_map, loc);
1741 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1744 return xloc;
1748 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1749 is NULL, use stderr. IS_MACRO is true if the caller wants to
1750 dump a macro map, false otherwise. */
1752 void
1753 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
1755 const char *const lc_reasons_v[LC_HWM]
1756 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1757 "LC_ENTER_MACRO" };
1758 const line_map *map;
1759 unsigned reason;
1761 if (stream == NULL)
1762 stream = stderr;
1764 if (!is_macro)
1766 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1767 reason = linemap_check_ordinary (map)->reason;
1769 else
1771 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1772 reason = LC_ENTER_MACRO;
1775 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1776 ix, (void *) map, map->start_location,
1777 reason < LC_HWM ? lc_reasons_v[reason] : "???",
1778 ((!is_macro
1779 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1780 ? "yes" : "no"));
1781 if (!is_macro)
1783 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1784 const line_map_ordinary *includer_map
1785 = linemap_included_from_linemap (set, ord_map);
1787 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1788 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1789 fprintf (stream, "Included from: [%d] %s\n",
1790 includer_map ? int (includer_map - set->info_ordinary.maps) : -1,
1791 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1793 else
1795 const line_map_macro *macro_map = linemap_check_macro (map);
1796 fprintf (stream, "Macro: %s (%u tokens)\n",
1797 linemap_map_get_macro_name (macro_map),
1798 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1801 fprintf (stream, "\n");
1805 /* Dump debugging information about source location LOC into the file
1806 stream STREAM. SET is the line map set LOC comes from. */
1808 void
1809 linemap_dump_location (struct line_maps *set,
1810 source_location loc,
1811 FILE *stream)
1813 const line_map_ordinary *map;
1814 source_location location;
1815 const char *path = "", *from = "";
1816 int l = -1, c = -1, s = -1, e = -1;
1818 if (IS_ADHOC_LOC (loc))
1819 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1821 if (loc == 0)
1822 return;
1824 location =
1825 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1827 if (map == NULL)
1828 /* Only reserved locations can be tolerated in this case. */
1829 linemap_assert (location < RESERVED_LOCATION_COUNT);
1830 else
1832 path = LINEMAP_FILE (map);
1833 l = SOURCE_LINE (map, location);
1834 c = SOURCE_COLUMN (map, location);
1835 s = LINEMAP_SYSP (map) != 0;
1836 e = location != loc;
1837 if (e)
1838 from = "N/A";
1839 else
1841 const line_map_ordinary *from_map
1842 = linemap_included_from_linemap (set, map);
1843 from = from_map ? LINEMAP_FILE (from_map) : "<NULL>";
1847 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1848 E: macro expansion?, LOC: original location, R: resolved location */
1849 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1850 path, from, l, c, s, (void*)map, e, loc, location);
1853 /* Return the highest location emitted for a given file for which
1854 there is a line map in SET. FILE_NAME is the file name to
1855 consider. If the function returns TRUE, *LOC is set to the highest
1856 location emitted for that file. */
1858 bool
1859 linemap_get_file_highest_location (struct line_maps *set,
1860 const char *file_name,
1861 source_location *loc)
1863 /* If the set is empty or no ordinary map has been created then
1864 there is no file to look for ... */
1865 if (set == NULL || set->info_ordinary.used == 0)
1866 return false;
1868 /* Now look for the last ordinary map created for FILE_NAME. */
1869 int i;
1870 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1872 const char *fname = set->info_ordinary.maps[i].to_file;
1873 if (fname && !filename_cmp (fname, file_name))
1874 break;
1877 if (i < 0)
1878 return false;
1880 /* The highest location for a given map is either the starting
1881 location of the next map minus one, or -- if the map is the
1882 latest one -- the highest location of the set. */
1883 source_location result;
1884 if (i == (int) set->info_ordinary.used - 1)
1885 result = set->highest_location;
1886 else
1887 result = set->info_ordinary.maps[i + 1].start_location - 1;
1889 *loc = result;
1890 return true;
1893 /* Compute and return statistics about the memory consumption of some
1894 parts of the line table SET. */
1896 void
1897 linemap_get_statistics (struct line_maps *set,
1898 struct linemap_stats *s)
1900 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1901 macro_maps_allocated_size, macro_maps_used_size,
1902 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1904 const line_map_macro *cur_map;
1906 ordinary_maps_allocated_size =
1907 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1909 ordinary_maps_used_size =
1910 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1912 macro_maps_allocated_size =
1913 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1915 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1916 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1917 ++cur_map)
1919 unsigned i;
1921 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1923 macro_maps_locations_size +=
1924 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1926 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1928 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1929 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1930 duplicated_macro_maps_locations_size +=
1931 sizeof (source_location);
1935 macro_maps_used_size =
1936 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1938 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1939 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1940 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1941 s->ordinary_maps_used_size = ordinary_maps_used_size;
1942 s->num_expanded_macros = num_expanded_macros_counter;
1943 s->num_macro_tokens = num_macro_tokens_counter;
1944 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1945 s->macro_maps_allocated_size = macro_maps_allocated_size;
1946 s->macro_maps_locations_size = macro_maps_locations_size;
1947 s->macro_maps_used_size = macro_maps_used_size;
1948 s->duplicated_macro_maps_locations_size =
1949 duplicated_macro_maps_locations_size;
1950 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1951 * sizeof (struct location_adhoc_data));
1952 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1956 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1957 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1958 specifies how many macro maps to dump. */
1960 void
1961 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1962 unsigned int num_macro)
1964 unsigned int i;
1966 if (set == NULL)
1967 return;
1969 if (stream == NULL)
1970 stream = stderr;
1972 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1973 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1974 fprintf (stream, "Include stack depth: %d\n", set->depth);
1975 fprintf (stream, "Highest location: %u\n", set->highest_location);
1977 if (num_ordinary)
1979 fprintf (stream, "\nOrdinary line maps\n");
1980 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
1981 linemap_dump (stream, set, i, false);
1982 fprintf (stream, "\n");
1985 if (num_macro)
1987 fprintf (stream, "\nMacro line maps\n");
1988 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
1989 linemap_dump (stream, set, i, true);
1990 fprintf (stream, "\n");
1994 /* class rich_location. */
1996 /* Construct a rich_location with location LOC as its initial range. */
1998 rich_location::rich_location (line_maps *set, source_location loc,
1999 const range_label *label) :
2000 m_line_table (set),
2001 m_ranges (),
2002 m_column_override (0),
2003 m_have_expanded_location (false),
2004 m_fixit_hints (),
2005 m_seen_impossible_fixit (false),
2006 m_fixits_cannot_be_auto_applied (false)
2008 add_range (loc, SHOW_RANGE_WITH_CARET, label);
2011 /* The destructor for class rich_location. */
2013 rich_location::~rich_location ()
2015 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2016 delete get_fixit_hint (i);
2019 /* Get location IDX within this rich_location. */
2021 source_location
2022 rich_location::get_loc (unsigned int idx) const
2024 const location_range *locrange = get_range (idx);
2025 return locrange->m_loc;
2028 /* Get range IDX within this rich_location. */
2030 const location_range *
2031 rich_location::get_range (unsigned int idx) const
2033 return &m_ranges[idx];
2036 /* Mutable access to range IDX within this rich_location. */
2038 location_range *
2039 rich_location::get_range (unsigned int idx)
2041 return &m_ranges[idx];
2044 /* Expand location IDX within this rich_location. */
2045 /* Get an expanded_location for this rich_location's primary
2046 location. */
2048 expanded_location
2049 rich_location::get_expanded_location (unsigned int idx)
2051 if (idx == 0)
2053 /* Cache the expansion of the primary location. */
2054 if (!m_have_expanded_location)
2056 m_expanded_location
2057 = linemap_client_expand_location_to_spelling_point
2058 (get_loc (0), LOCATION_ASPECT_CARET);
2059 if (m_column_override)
2060 m_expanded_location.column = m_column_override;
2061 m_have_expanded_location = true;
2064 return m_expanded_location;
2066 else
2067 return linemap_client_expand_location_to_spelling_point
2068 (get_loc (idx), LOCATION_ASPECT_CARET);
2071 /* Set the column of the primary location, with 0 meaning
2072 "don't override it". */
2074 void
2075 rich_location::override_column (int column)
2077 m_column_override = column;
2078 m_have_expanded_location = false;
2081 /* Add the given range. */
2083 void
2084 rich_location::add_range (source_location loc,
2085 enum range_display_kind range_display_kind,
2086 const range_label *label)
2088 location_range range;
2089 range.m_loc = loc;
2090 range.m_range_display_kind = range_display_kind;
2091 range.m_label = label;
2092 m_ranges.push (range);
2095 /* Add or overwrite the location given by IDX, setting its location to LOC,
2096 and setting its m_range_display_kind to RANGE_DISPLAY_KIND.
2098 It must either overwrite an existing location, or add one *exactly* on
2099 the end of the array.
2101 This is primarily for use by gcc when implementing diagnostic format
2102 decoders e.g.
2103 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2104 (which writes the source location of a tree back into location 0 of
2105 the rich_location), and
2106 - the "%C" and "%L" format codes in the Fortran frontend. */
2108 void
2109 rich_location::set_range (unsigned int idx, source_location loc,
2110 enum range_display_kind range_display_kind)
2112 /* We can either overwrite an existing range, or add one exactly
2113 on the end of the array. */
2114 linemap_assert (idx <= m_ranges.count ());
2116 if (idx == m_ranges.count ())
2117 add_range (loc, range_display_kind);
2118 else
2120 location_range *locrange = get_range (idx);
2121 locrange->m_loc = loc;
2122 locrange->m_range_display_kind = range_display_kind;
2125 if (idx == 0)
2126 /* Mark any cached value here as dirty. */
2127 m_have_expanded_location = false;
2130 /* Methods for adding insertion fix-it hints. */
2132 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2133 immediately before the primary range's start location. */
2135 void
2136 rich_location::add_fixit_insert_before (const char *new_content)
2138 add_fixit_insert_before (get_loc (), new_content);
2141 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2142 immediately before the start of WHERE. */
2144 void
2145 rich_location::add_fixit_insert_before (source_location where,
2146 const char *new_content)
2148 source_location start = get_range_from_loc (m_line_table, where).m_start;
2149 maybe_add_fixit (start, start, new_content);
2152 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2153 immediately after the primary range's end-point. */
2155 void
2156 rich_location::add_fixit_insert_after (const char *new_content)
2158 add_fixit_insert_after (get_loc (), new_content);
2161 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2162 immediately after the end-point of WHERE. */
2164 void
2165 rich_location::add_fixit_insert_after (source_location where,
2166 const char *new_content)
2168 source_location finish = get_range_from_loc (m_line_table, where).m_finish;
2169 source_location next_loc
2170 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2172 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2173 its input value. */
2174 if (next_loc == finish)
2176 stop_supporting_fixits ();
2177 return;
2180 maybe_add_fixit (next_loc, next_loc, new_content);
2183 /* Methods for adding removal fix-it hints. */
2185 /* Add a fixit-hint, suggesting removal of the content covered
2186 by range 0. */
2188 void
2189 rich_location::add_fixit_remove ()
2191 add_fixit_remove (get_loc ());
2194 /* Add a fixit-hint, suggesting removal of the content between
2195 the start and finish of WHERE. */
2197 void
2198 rich_location::add_fixit_remove (source_location where)
2200 source_range range = get_range_from_loc (m_line_table, where);
2201 add_fixit_remove (range);
2204 /* Add a fixit-hint, suggesting removal of the content at
2205 SRC_RANGE. */
2207 void
2208 rich_location::add_fixit_remove (source_range src_range)
2210 add_fixit_replace (src_range, "");
2213 /* Add a fixit-hint, suggesting replacement of the content covered
2214 by range 0 with NEW_CONTENT. */
2216 void
2217 rich_location::add_fixit_replace (const char *new_content)
2219 add_fixit_replace (get_loc (), new_content);
2222 /* Methods for adding "replace" fix-it hints. */
2224 /* Add a fixit-hint, suggesting replacement of the content between
2225 the start and finish of WHERE with NEW_CONTENT. */
2227 void
2228 rich_location::add_fixit_replace (source_location where,
2229 const char *new_content)
2231 source_range range = get_range_from_loc (m_line_table, where);
2232 add_fixit_replace (range, new_content);
2235 /* Add a fixit-hint, suggesting replacement of the content at
2236 SRC_RANGE with NEW_CONTENT. */
2238 void
2239 rich_location::add_fixit_replace (source_range src_range,
2240 const char *new_content)
2242 source_location start = get_pure_location (m_line_table, src_range.m_start);
2243 source_location finish = get_pure_location (m_line_table, src_range.m_finish);
2245 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2246 source_location next_loc
2247 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2248 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2249 its input value. */
2250 if (next_loc == finish)
2252 stop_supporting_fixits ();
2253 return;
2255 finish = next_loc;
2257 maybe_add_fixit (start, finish, new_content);
2260 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2262 fixit_hint *
2263 rich_location::get_last_fixit_hint () const
2265 if (m_fixit_hints.count () > 0)
2266 return get_fixit_hint (m_fixit_hints.count () - 1);
2267 else
2268 return NULL;
2271 /* If WHERE is an "awkward" location, then mark this rich_location as not
2272 supporting fixits, purging any thay were already added, and return true.
2274 Otherwise (the common case), return false. */
2276 bool
2277 rich_location::reject_impossible_fixit (source_location where)
2279 /* Fix-its within a rich_location should either all be suggested, or
2280 none of them should be suggested.
2281 Once we've rejected a fixit, we reject any more, even those
2282 with reasonable locations. */
2283 if (m_seen_impossible_fixit)
2284 return true;
2286 if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
2287 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2288 return false;
2290 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2291 location: either one that we can't obtain column information
2292 for (within an ordinary map), or one within a macro expansion. */
2293 stop_supporting_fixits ();
2294 return true;
2297 /* Mark this rich_location as not supporting fixits, purging any that were
2298 already added. */
2300 void
2301 rich_location::stop_supporting_fixits ()
2303 m_seen_impossible_fixit = true;
2305 /* Purge the rich_location of any fix-its that were already added. */
2306 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2307 delete get_fixit_hint (i);
2308 m_fixit_hints.truncate (0);
2311 /* Add HINT to the fix-it hints in this rich_location,
2312 consolidating into the prior fixit if possible. */
2314 void
2315 rich_location::maybe_add_fixit (source_location start,
2316 source_location next_loc,
2317 const char *new_content)
2319 if (reject_impossible_fixit (start))
2320 return;
2321 if (reject_impossible_fixit (next_loc))
2322 return;
2324 /* Only allow fix-it hints that affect a single line in one file.
2325 Compare the end-points. */
2326 expanded_location exploc_start
2327 = linemap_client_expand_location_to_spelling_point (start,
2328 LOCATION_ASPECT_START);
2329 expanded_location exploc_next_loc
2330 = linemap_client_expand_location_to_spelling_point (next_loc,
2331 LOCATION_ASPECT_START);
2332 /* They must be within the same file... */
2333 if (exploc_start.file != exploc_next_loc.file)
2335 stop_supporting_fixits ();
2336 return;
2338 /* ...and on the same line. */
2339 if (exploc_start.line != exploc_next_loc.line)
2341 stop_supporting_fixits ();
2342 return;
2344 /* The columns must be in the correct order. This can fail if the
2345 endpoints straddle the boundary for which the linemap can represent
2346 columns (PR c/82050). */
2347 if (exploc_start.column > exploc_next_loc.column)
2349 stop_supporting_fixits ();
2350 return;
2353 const char *newline = strchr (new_content, '\n');
2354 if (newline)
2356 /* For now, we can only support insertion of whole lines
2357 i.e. starts at start of line, and the newline is at the end of
2358 the insertion point. */
2360 /* It must be an insertion, not a replacement/deletion. */
2361 if (start != next_loc)
2363 stop_supporting_fixits ();
2364 return;
2367 /* The insertion must be at the start of a line. */
2368 if (exploc_start.column != 1)
2370 stop_supporting_fixits ();
2371 return;
2374 /* The newline must be at end of NEW_CONTENT.
2375 We could eventually split up fix-its at newlines if we wanted
2376 to allow more generality (e.g. to allow adding multiple lines
2377 with one add_fixit call. */
2378 if (newline[1] != '\0')
2380 stop_supporting_fixits ();
2381 return;
2385 /* Consolidate neighboring fixits.
2386 Don't consolidate into newline-insertion fixits. */
2387 fixit_hint *prev = get_last_fixit_hint ();
2388 if (prev && !prev->ends_with_newline_p ())
2389 if (prev->maybe_append (start, next_loc, new_content))
2390 return;
2392 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
2395 /* class fixit_hint. */
2397 fixit_hint::fixit_hint (source_location start,
2398 source_location next_loc,
2399 const char *new_content)
2400 : m_start (start),
2401 m_next_loc (next_loc),
2402 m_bytes (xstrdup (new_content)),
2403 m_len (strlen (new_content))
2407 /* Does this fix-it hint affect the given line? */
2409 bool
2410 fixit_hint::affects_line_p (const char *file, int line) const
2412 expanded_location exploc_start
2413 = linemap_client_expand_location_to_spelling_point (m_start,
2414 LOCATION_ASPECT_START);
2415 if (file != exploc_start.file)
2416 return false;
2417 if (line < exploc_start.line)
2418 return false;
2419 expanded_location exploc_next_loc
2420 = linemap_client_expand_location_to_spelling_point (m_next_loc,
2421 LOCATION_ASPECT_START);
2422 if (file != exploc_next_loc.file)
2423 return false;
2424 if (line > exploc_next_loc.line)
2425 return false;
2426 return true;
2429 /* Method for consolidating fix-it hints, for use by
2430 rich_location::maybe_add_fixit.
2431 If possible, merge a pending fix-it hint with the given params
2432 into this one and return true.
2433 Otherwise return false. */
2435 bool
2436 fixit_hint::maybe_append (source_location start,
2437 source_location next_loc,
2438 const char *new_content)
2440 /* For consolidation to be possible, START must be at this hint's
2441 m_next_loc. */
2442 if (start != m_next_loc)
2443 return false;
2445 /* If so, we have neighboring replacements; merge them. */
2446 m_next_loc = next_loc;
2447 size_t extra_len = strlen (new_content);
2448 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2449 memcpy (m_bytes + m_len, new_content, extra_len);
2450 m_len += extra_len;
2451 m_bytes[m_len] = '\0';
2452 return true;
2455 /* Return true iff this hint's content ends with a newline. */
2457 bool
2458 fixit_hint::ends_with_newline_p () const
2460 if (m_len == 0)
2461 return false;
2462 return m_bytes[m_len - 1] == '\n';