Fix ceil_log2(0) (PR 86644)
[official-gcc.git] / libcpp / line-map.c
bloba1a765f14fd108ec8d653fe5c81d69511f953c1d
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 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
309 if (loc & ((1U << ordmap->m_range_bits) - 1))
310 return false;
312 return true;
315 /* Given location LOC within SET, strip away any packed range information
316 or ad-hoc information. */
318 source_location
319 get_pure_location (line_maps *set, source_location loc)
321 if (IS_ADHOC_LOC (loc))
323 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
325 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
326 return loc;
328 if (loc < RESERVED_LOCATION_COUNT)
329 return loc;
331 const line_map *map = linemap_lookup (set, loc);
332 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
334 return loc & ~((1 << ordmap->m_range_bits) - 1);
337 /* Initialize a line map set. */
339 void
340 linemap_init (struct line_maps *set,
341 source_location builtin_location)
343 #if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
344 /* PR33916, needed to fix PR82939. */
345 memset (set, 0, sizeof (struct line_maps));
346 #else
347 new (set) line_maps();
348 #endif
349 set->highest_location = RESERVED_LOCATION_COUNT - 1;
350 set->highest_line = RESERVED_LOCATION_COUNT - 1;
351 set->location_adhoc_data_map.htab =
352 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
353 set->builtin_location = builtin_location;
356 /* Check for and warn about line_maps entered but not exited. */
358 void
359 linemap_check_files_exited (struct line_maps *set)
361 const line_map_ordinary *map;
362 /* Depending upon whether we are handling preprocessed input or
363 not, this can be a user error or an ICE. */
364 for (map = LINEMAPS_LAST_ORDINARY_MAP (set);
365 ! MAIN_FILE_P (map);
366 map = INCLUDED_FROM (set, map))
367 fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
368 ORDINARY_MAP_FILE_NAME (map));
371 /* Create a new line map in the line map set SET, and return it.
372 REASON is the reason of creating the map. It determines the type
373 of map created (ordinary or macro map). Note that ordinary maps and
374 macro maps are allocated in different memory location. */
376 static struct line_map *
377 new_linemap (struct line_maps *set, source_location start_location)
379 struct line_map *result;
380 bool macro_map_p = start_location >= LINE_MAP_MAX_LOCATION;
382 if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
384 /* We ran out of allocated line maps. Let's allocate more. */
385 size_t alloc_size;
387 /* Cast away extern "C" from the type of xrealloc. */
388 line_map_realloc reallocator = (set->reallocator
389 ? set->reallocator
390 : (line_map_realloc) xrealloc);
391 line_map_round_alloc_size_func round_alloc_size =
392 set->round_alloc_size;
394 size_t map_size = (macro_map_p
395 ? sizeof (line_map_macro)
396 : sizeof (line_map_ordinary));
398 /* We are going to execute some dance to try to reduce the
399 overhead of the memory allocator, in case we are using the
400 ggc-page.c one.
402 The actual size of memory we are going to get back from the
403 allocator is the smallest power of 2 that is greater than the
404 size we requested. So let's consider that size then. */
406 alloc_size =
407 (2 * LINEMAPS_ALLOCATED (set, macro_map_p) + 256)
408 * map_size;
410 /* Get the actual size of memory that is going to be allocated
411 by the allocator. */
412 alloc_size = round_alloc_size (alloc_size);
414 /* Now alloc_size contains the exact memory size we would get if
415 we have asked for the initial alloc_size amount of memory.
416 Let's get back to the number of macro map that amounts
417 to. */
418 LINEMAPS_ALLOCATED (set, macro_map_p) =
419 alloc_size / map_size;
421 /* And now let's really do the re-allocation. */
422 if (macro_map_p)
424 set->info_macro.maps
425 = (line_map_macro *) (*reallocator) (set->info_macro.maps,
426 (LINEMAPS_ALLOCATED (set, macro_map_p)
427 * map_size));
428 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
430 else
432 set->info_ordinary.maps =
433 (line_map_ordinary *) (*reallocator) (set->info_ordinary.maps,
434 (LINEMAPS_ALLOCATED (set, macro_map_p)
435 * map_size));
436 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
438 memset (result, 0,
439 ((LINEMAPS_ALLOCATED (set, macro_map_p)
440 - LINEMAPS_USED (set, macro_map_p))
441 * map_size));
443 else
445 if (macro_map_p)
446 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
447 else
448 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
451 result->start_location = start_location;
453 LINEMAPS_USED (set, macro_map_p)++;
455 return result;
458 /* Add a mapping of logical source line to physical source file and
459 line number.
461 The text pointed to by TO_FILE must have a lifetime
462 at least as long as the final call to lookup_line (). An empty
463 TO_FILE means standard input. If reason is LC_LEAVE, and
464 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
465 natural values considering the file we are returning to.
467 FROM_LINE should be monotonic increasing across calls to this
468 function. A call to this function can relocate the previous set of
469 maps, so any stored line_map pointers should not be used. */
471 const struct line_map *
472 linemap_add (struct line_maps *set, enum lc_reason reason,
473 unsigned int sysp, const char *to_file, linenum_type to_line)
475 /* Generate a start_location above the current highest_location.
476 If possible, make the low range bits be zero. */
477 source_location start_location;
478 if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
480 start_location = set->highest_location + (1 << set->default_range_bits);
481 if (set->default_range_bits)
482 start_location &= ~((1 << set->default_range_bits) - 1);
483 linemap_assert (0 == (start_location
484 & ((1 << set->default_range_bits) - 1)));
486 else
487 start_location = set->highest_location + 1;
489 linemap_assert (!LINEMAPS_ORDINARY_USED (set)
490 || (start_location
491 >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
493 /* When we enter the file for the first time reason cannot be
494 LC_RENAME. */
495 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
497 /* If we are leaving the main file, return a NULL map. */
498 if (reason == LC_LEAVE
499 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
500 && to_file == NULL)
502 set->depth--;
503 return NULL;
506 linemap_assert (reason != LC_ENTER_MACRO);
507 line_map_ordinary *map
508 = linemap_check_ordinary (new_linemap (set, start_location));
509 map->reason = reason;
511 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
512 to_file = "<stdin>";
514 if (reason == LC_RENAME_VERBATIM)
515 reason = LC_RENAME;
517 if (reason == LC_LEAVE)
519 /* When we are just leaving an "included" file, and jump to the next
520 location inside the "includer" right after the #include
521 "included", this variable points the map in use right before the
522 #include "included", inside the same "includer" file. */
523 line_map_ordinary *from;
525 linemap_assert (!MAIN_FILE_P (map - 1));
526 /* (MAP - 1) points to the map we are leaving. The
527 map from which (MAP - 1) got included should be the map
528 that comes right before MAP in the same file. */
529 from = INCLUDED_FROM (set, map - 1);
531 /* A TO_FILE of NULL is special - we use the natural values. */
532 if (to_file == NULL)
534 to_file = ORDINARY_MAP_FILE_NAME (from);
535 to_line = SOURCE_LINE (from, from[1].start_location);
536 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
538 else
539 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
540 to_file) == 0);
543 map->sysp = sysp;
544 map->to_file = to_file;
545 map->to_line = to_line;
546 LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
547 map->m_column_and_range_bits = 0;
548 map->m_range_bits = 0;
549 set->highest_location = start_location;
550 set->highest_line = start_location;
551 set->max_column_hint = 0;
553 /* This assertion is placed after set->highest_location has
554 been updated, since the latter affects
555 linemap_location_from_macro_expansion_p, which ultimately affects
556 pure_location_p. */
557 linemap_assert (pure_location_p (set, start_location));
559 if (reason == LC_ENTER)
561 map->included_from =
562 set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
563 set->depth++;
564 if (set->trace_includes)
565 trace_include (set, map);
567 else if (reason == LC_RENAME)
568 map->included_from = ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
569 else if (reason == LC_LEAVE)
571 set->depth--;
572 map->included_from =
573 ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
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 unsigned includer_ix;
1785 const line_map_ordinary *includer_map;
1787 includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
1788 includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
1789 ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
1790 : NULL;
1792 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1793 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1794 fprintf (stream, "Included from: [%d] %s\n", includer_ix,
1795 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1797 else
1799 const line_map_macro *macro_map = linemap_check_macro (map);
1800 fprintf (stream, "Macro: %s (%u tokens)\n",
1801 linemap_map_get_macro_name (macro_map),
1802 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1805 fprintf (stream, "\n");
1809 /* Dump debugging information about source location LOC into the file
1810 stream STREAM. SET is the line map set LOC comes from. */
1812 void
1813 linemap_dump_location (struct line_maps *set,
1814 source_location loc,
1815 FILE *stream)
1817 const line_map_ordinary *map;
1818 source_location location;
1819 const char *path = "", *from = "";
1820 int l = -1, c = -1, s = -1, e = -1;
1822 if (IS_ADHOC_LOC (loc))
1823 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1825 if (loc == 0)
1826 return;
1828 location =
1829 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1831 if (map == NULL)
1832 /* Only reserved locations can be tolerated in this case. */
1833 linemap_assert (location < RESERVED_LOCATION_COUNT);
1834 else
1836 path = LINEMAP_FILE (map);
1837 l = SOURCE_LINE (map, location);
1838 c = SOURCE_COLUMN (map, location);
1839 s = LINEMAP_SYSP (map) != 0;
1840 e = location != loc;
1841 if (e)
1842 from = "N/A";
1843 else
1844 from = (INCLUDED_FROM (set, map))
1845 ? LINEMAP_FILE (INCLUDED_FROM (set, map))
1846 : "<NULL>";
1849 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1850 E: macro expansion?, LOC: original location, R: resolved location */
1851 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1852 path, from, l, c, s, (void*)map, e, loc, location);
1855 /* Return the highest location emitted for a given file for which
1856 there is a line map in SET. FILE_NAME is the file name to
1857 consider. If the function returns TRUE, *LOC is set to the highest
1858 location emitted for that file. */
1860 bool
1861 linemap_get_file_highest_location (struct line_maps *set,
1862 const char *file_name,
1863 source_location *loc)
1865 /* If the set is empty or no ordinary map has been created then
1866 there is no file to look for ... */
1867 if (set == NULL || set->info_ordinary.used == 0)
1868 return false;
1870 /* Now look for the last ordinary map created for FILE_NAME. */
1871 int i;
1872 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1874 const char *fname = set->info_ordinary.maps[i].to_file;
1875 if (fname && !filename_cmp (fname, file_name))
1876 break;
1879 if (i < 0)
1880 return false;
1882 /* The highest location for a given map is either the starting
1883 location of the next map minus one, or -- if the map is the
1884 latest one -- the highest location of the set. */
1885 source_location result;
1886 if (i == (int) set->info_ordinary.used - 1)
1887 result = set->highest_location;
1888 else
1889 result = set->info_ordinary.maps[i + 1].start_location - 1;
1891 *loc = result;
1892 return true;
1895 /* Compute and return statistics about the memory consumption of some
1896 parts of the line table SET. */
1898 void
1899 linemap_get_statistics (struct line_maps *set,
1900 struct linemap_stats *s)
1902 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1903 macro_maps_allocated_size, macro_maps_used_size,
1904 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1906 const line_map_macro *cur_map;
1908 ordinary_maps_allocated_size =
1909 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1911 ordinary_maps_used_size =
1912 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1914 macro_maps_allocated_size =
1915 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1917 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1918 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1919 ++cur_map)
1921 unsigned i;
1923 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1925 macro_maps_locations_size +=
1926 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1928 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1930 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1931 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1932 duplicated_macro_maps_locations_size +=
1933 sizeof (source_location);
1937 macro_maps_used_size =
1938 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1940 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1941 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1942 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1943 s->ordinary_maps_used_size = ordinary_maps_used_size;
1944 s->num_expanded_macros = num_expanded_macros_counter;
1945 s->num_macro_tokens = num_macro_tokens_counter;
1946 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1947 s->macro_maps_allocated_size = macro_maps_allocated_size;
1948 s->macro_maps_locations_size = macro_maps_locations_size;
1949 s->macro_maps_used_size = macro_maps_used_size;
1950 s->duplicated_macro_maps_locations_size =
1951 duplicated_macro_maps_locations_size;
1952 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1953 * sizeof (struct location_adhoc_data));
1954 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1958 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1959 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1960 specifies how many macro maps to dump. */
1962 void
1963 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1964 unsigned int num_macro)
1966 unsigned int i;
1968 if (set == NULL)
1969 return;
1971 if (stream == NULL)
1972 stream = stderr;
1974 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1975 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1976 fprintf (stream, "Include stack depth: %d\n", set->depth);
1977 fprintf (stream, "Highest location: %u\n", set->highest_location);
1979 if (num_ordinary)
1981 fprintf (stream, "\nOrdinary line maps\n");
1982 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
1983 linemap_dump (stream, set, i, false);
1984 fprintf (stream, "\n");
1987 if (num_macro)
1989 fprintf (stream, "\nMacro line maps\n");
1990 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
1991 linemap_dump (stream, set, i, true);
1992 fprintf (stream, "\n");
1996 /* class rich_location. */
1998 /* Construct a rich_location with location LOC as its initial range. */
2000 rich_location::rich_location (line_maps *set, source_location loc) :
2001 m_line_table (set),
2002 m_ranges (),
2003 m_column_override (0),
2004 m_have_expanded_location (false),
2005 m_fixit_hints (),
2006 m_seen_impossible_fixit (false),
2007 m_fixits_cannot_be_auto_applied (false)
2009 add_range (loc, true);
2012 /* The destructor for class rich_location. */
2014 rich_location::~rich_location ()
2016 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2017 delete get_fixit_hint (i);
2020 /* Get location IDX within this rich_location. */
2022 source_location
2023 rich_location::get_loc (unsigned int idx) const
2025 const location_range *locrange = get_range (idx);
2026 return locrange->m_loc;
2029 /* Get range IDX within this rich_location. */
2031 const location_range *
2032 rich_location::get_range (unsigned int idx) const
2034 return &m_ranges[idx];
2037 /* Mutable access to range IDX within this rich_location. */
2039 location_range *
2040 rich_location::get_range (unsigned int idx)
2042 return &m_ranges[idx];
2045 /* Expand location IDX within this rich_location. */
2046 /* Get an expanded_location for this rich_location's primary
2047 location. */
2049 expanded_location
2050 rich_location::get_expanded_location (unsigned int idx)
2052 if (idx == 0)
2054 /* Cache the expansion of the primary location. */
2055 if (!m_have_expanded_location)
2057 m_expanded_location
2058 = linemap_client_expand_location_to_spelling_point
2059 (get_loc (0), LOCATION_ASPECT_CARET);
2060 if (m_column_override)
2061 m_expanded_location.column = m_column_override;
2062 m_have_expanded_location = true;
2065 return m_expanded_location;
2067 else
2068 return linemap_client_expand_location_to_spelling_point
2069 (get_loc (idx), LOCATION_ASPECT_CARET);
2072 /* Set the column of the primary location, with 0 meaning
2073 "don't override it". */
2075 void
2076 rich_location::override_column (int column)
2078 m_column_override = column;
2079 m_have_expanded_location = false;
2082 /* Add the given range. */
2084 void
2085 rich_location::add_range (source_location loc, bool show_caret_p)
2087 location_range range;
2088 range.m_loc = loc;
2089 range.m_show_caret_p = show_caret_p;
2090 m_ranges.push (range);
2093 /* Add or overwrite the location given by IDX, setting its location to LOC,
2094 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2096 It must either overwrite an existing location, or add one *exactly* on
2097 the end of the array.
2099 This is primarily for use by gcc when implementing diagnostic format
2100 decoders e.g.
2101 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2102 (which writes the source location of a tree back into location 0 of
2103 the rich_location), and
2104 - the "%C" and "%L" format codes in the Fortran frontend. */
2106 void
2107 rich_location::set_range (unsigned int idx, source_location loc,
2108 bool show_caret_p)
2110 /* We can either overwrite an existing range, or add one exactly
2111 on the end of the array. */
2112 linemap_assert (idx <= m_ranges.count ());
2114 if (idx == m_ranges.count ())
2115 add_range (loc, show_caret_p);
2116 else
2118 location_range *locrange = get_range (idx);
2119 locrange->m_loc = loc;
2120 locrange->m_show_caret_p = show_caret_p;
2123 if (idx == 0)
2124 /* Mark any cached value here as dirty. */
2125 m_have_expanded_location = false;
2128 /* Methods for adding insertion fix-it hints. */
2130 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2131 immediately before the primary range's start location. */
2133 void
2134 rich_location::add_fixit_insert_before (const char *new_content)
2136 add_fixit_insert_before (get_loc (), new_content);
2139 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2140 immediately before the start of WHERE. */
2142 void
2143 rich_location::add_fixit_insert_before (source_location where,
2144 const char *new_content)
2146 source_location start = get_range_from_loc (m_line_table, where).m_start;
2147 maybe_add_fixit (start, start, new_content);
2150 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2151 immediately after the primary range's end-point. */
2153 void
2154 rich_location::add_fixit_insert_after (const char *new_content)
2156 add_fixit_insert_after (get_loc (), new_content);
2159 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2160 immediately after the end-point of WHERE. */
2162 void
2163 rich_location::add_fixit_insert_after (source_location where,
2164 const char *new_content)
2166 source_location finish = get_range_from_loc (m_line_table, where).m_finish;
2167 source_location next_loc
2168 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2170 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2171 its input value. */
2172 if (next_loc == finish)
2174 stop_supporting_fixits ();
2175 return;
2178 maybe_add_fixit (next_loc, next_loc, new_content);
2181 /* Methods for adding removal fix-it hints. */
2183 /* Add a fixit-hint, suggesting removal of the content covered
2184 by range 0. */
2186 void
2187 rich_location::add_fixit_remove ()
2189 add_fixit_remove (get_loc ());
2192 /* Add a fixit-hint, suggesting removal of the content between
2193 the start and finish of WHERE. */
2195 void
2196 rich_location::add_fixit_remove (source_location where)
2198 source_range range = get_range_from_loc (m_line_table, where);
2199 add_fixit_remove (range);
2202 /* Add a fixit-hint, suggesting removal of the content at
2203 SRC_RANGE. */
2205 void
2206 rich_location::add_fixit_remove (source_range src_range)
2208 add_fixit_replace (src_range, "");
2211 /* Add a fixit-hint, suggesting replacement of the content covered
2212 by range 0 with NEW_CONTENT. */
2214 void
2215 rich_location::add_fixit_replace (const char *new_content)
2217 add_fixit_replace (get_loc (), new_content);
2220 /* Methods for adding "replace" fix-it hints. */
2222 /* Add a fixit-hint, suggesting replacement of the content between
2223 the start and finish of WHERE with NEW_CONTENT. */
2225 void
2226 rich_location::add_fixit_replace (source_location where,
2227 const char *new_content)
2229 source_range range = get_range_from_loc (m_line_table, where);
2230 add_fixit_replace (range, new_content);
2233 /* Add a fixit-hint, suggesting replacement of the content at
2234 SRC_RANGE with NEW_CONTENT. */
2236 void
2237 rich_location::add_fixit_replace (source_range src_range,
2238 const char *new_content)
2240 source_location start = get_pure_location (m_line_table, src_range.m_start);
2241 source_location finish = get_pure_location (m_line_table, src_range.m_finish);
2243 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2244 source_location next_loc
2245 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2246 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2247 its input value. */
2248 if (next_loc == finish)
2250 stop_supporting_fixits ();
2251 return;
2253 finish = next_loc;
2255 maybe_add_fixit (start, finish, new_content);
2258 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2260 fixit_hint *
2261 rich_location::get_last_fixit_hint () const
2263 if (m_fixit_hints.count () > 0)
2264 return get_fixit_hint (m_fixit_hints.count () - 1);
2265 else
2266 return NULL;
2269 /* If WHERE is an "awkward" location, then mark this rich_location as not
2270 supporting fixits, purging any thay were already added, and return true.
2272 Otherwise (the common case), return false. */
2274 bool
2275 rich_location::reject_impossible_fixit (source_location where)
2277 /* Fix-its within a rich_location should either all be suggested, or
2278 none of them should be suggested.
2279 Once we've rejected a fixit, we reject any more, even those
2280 with reasonable locations. */
2281 if (m_seen_impossible_fixit)
2282 return true;
2284 if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
2285 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2286 return false;
2288 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2289 location: either one that we can't obtain column information
2290 for (within an ordinary map), or one within a macro expansion. */
2291 stop_supporting_fixits ();
2292 return true;
2295 /* Mark this rich_location as not supporting fixits, purging any that were
2296 already added. */
2298 void
2299 rich_location::stop_supporting_fixits ()
2301 m_seen_impossible_fixit = true;
2303 /* Purge the rich_location of any fix-its that were already added. */
2304 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2305 delete get_fixit_hint (i);
2306 m_fixit_hints.truncate (0);
2309 /* Add HINT to the fix-it hints in this rich_location,
2310 consolidating into the prior fixit if possible. */
2312 void
2313 rich_location::maybe_add_fixit (source_location start,
2314 source_location next_loc,
2315 const char *new_content)
2317 if (reject_impossible_fixit (start))
2318 return;
2319 if (reject_impossible_fixit (next_loc))
2320 return;
2322 /* Only allow fix-it hints that affect a single line in one file.
2323 Compare the end-points. */
2324 expanded_location exploc_start
2325 = linemap_client_expand_location_to_spelling_point (start,
2326 LOCATION_ASPECT_START);
2327 expanded_location exploc_next_loc
2328 = linemap_client_expand_location_to_spelling_point (next_loc,
2329 LOCATION_ASPECT_START);
2330 /* They must be within the same file... */
2331 if (exploc_start.file != exploc_next_loc.file)
2333 stop_supporting_fixits ();
2334 return;
2336 /* ...and on the same line. */
2337 if (exploc_start.line != exploc_next_loc.line)
2339 stop_supporting_fixits ();
2340 return;
2342 /* The columns must be in the correct order. This can fail if the
2343 endpoints straddle the boundary for which the linemap can represent
2344 columns (PR c/82050). */
2345 if (exploc_start.column > exploc_next_loc.column)
2347 stop_supporting_fixits ();
2348 return;
2351 const char *newline = strchr (new_content, '\n');
2352 if (newline)
2354 /* For now, we can only support insertion of whole lines
2355 i.e. starts at start of line, and the newline is at the end of
2356 the insertion point. */
2358 /* It must be an insertion, not a replacement/deletion. */
2359 if (start != next_loc)
2361 stop_supporting_fixits ();
2362 return;
2365 /* The insertion must be at the start of a line. */
2366 if (exploc_start.column != 1)
2368 stop_supporting_fixits ();
2369 return;
2372 /* The newline must be at end of NEW_CONTENT.
2373 We could eventually split up fix-its at newlines if we wanted
2374 to allow more generality (e.g. to allow adding multiple lines
2375 with one add_fixit call. */
2376 if (newline[1] != '\0')
2378 stop_supporting_fixits ();
2379 return;
2383 /* Consolidate neighboring fixits.
2384 Don't consolidate into newline-insertion fixits. */
2385 fixit_hint *prev = get_last_fixit_hint ();
2386 if (prev && !prev->ends_with_newline_p ())
2387 if (prev->maybe_append (start, next_loc, new_content))
2388 return;
2390 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
2393 /* class fixit_hint. */
2395 fixit_hint::fixit_hint (source_location start,
2396 source_location next_loc,
2397 const char *new_content)
2398 : m_start (start),
2399 m_next_loc (next_loc),
2400 m_bytes (xstrdup (new_content)),
2401 m_len (strlen (new_content))
2405 /* Does this fix-it hint affect the given line? */
2407 bool
2408 fixit_hint::affects_line_p (const char *file, int line) const
2410 expanded_location exploc_start
2411 = linemap_client_expand_location_to_spelling_point (m_start,
2412 LOCATION_ASPECT_START);
2413 if (file != exploc_start.file)
2414 return false;
2415 if (line < exploc_start.line)
2416 return false;
2417 expanded_location exploc_next_loc
2418 = linemap_client_expand_location_to_spelling_point (m_next_loc,
2419 LOCATION_ASPECT_START);
2420 if (file != exploc_next_loc.file)
2421 return false;
2422 if (line > exploc_next_loc.line)
2423 return false;
2424 return true;
2427 /* Method for consolidating fix-it hints, for use by
2428 rich_location::maybe_add_fixit.
2429 If possible, merge a pending fix-it hint with the given params
2430 into this one and return true.
2431 Otherwise return false. */
2433 bool
2434 fixit_hint::maybe_append (source_location start,
2435 source_location next_loc,
2436 const char *new_content)
2438 /* For consolidation to be possible, START must be at this hint's
2439 m_next_loc. */
2440 if (start != m_next_loc)
2441 return false;
2443 /* If so, we have neighboring replacements; merge them. */
2444 m_next_loc = next_loc;
2445 size_t extra_len = strlen (new_content);
2446 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2447 memcpy (m_bytes + m_len, new_content, extra_len);
2448 m_len += extra_len;
2449 m_bytes[m_len] = '\0';
2450 return true;
2453 /* Return true iff this hint's content ends with a newline. */
2455 bool
2456 fixit_hint::ends_with_newline_p () const
2458 if (m_len == 0)
2459 return false;
2460 return m_bytes[m_len - 1] == '\n';