* gnatvsn.ads: Bump copyright year.
[official-gcc.git] / libcpp / line-map.c
blob677acd6dd925e7428c8a85d09f6726785dd1e978
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 /* Highest possible source location encoded within an ordinary or
30 macro map. */
31 const source_location LINE_MAP_MAX_SOURCE_LOCATION = 0x70000000;
33 static void trace_include (const struct line_maps *, const line_map_ordinary *);
34 static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
35 source_location);
36 static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
37 source_location);
38 static source_location linemap_macro_map_loc_to_def_point
39 (const line_map_macro *, source_location);
40 static source_location linemap_macro_map_loc_to_exp_point
41 (const line_map_macro *, source_location);
42 static source_location linemap_macro_loc_to_spelling_point
43 (struct line_maps *, source_location, const line_map_ordinary **);
44 static source_location linemap_macro_loc_to_def_point (struct line_maps *,
45 source_location,
46 const line_map_ordinary **);
47 static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
48 source_location,
49 const line_map_ordinary **);
51 /* Counters defined in macro.c. */
52 extern unsigned num_expanded_macros_counter;
53 extern unsigned num_macro_tokens_counter;
55 /* Destructor for class line_maps.
56 Ensure non-GC-managed memory is released. */
58 line_maps::~line_maps ()
60 if (location_adhoc_data_map.htab)
61 htab_delete (location_adhoc_data_map.htab);
64 /* Hash function for location_adhoc_data hashtable. */
66 static hashval_t
67 location_adhoc_data_hash (const void *l)
69 const struct location_adhoc_data *lb =
70 (const struct location_adhoc_data *) l;
71 return ((hashval_t) lb->locus
72 + (hashval_t) lb->src_range.m_start
73 + (hashval_t) lb->src_range.m_finish
74 + (size_t) lb->data);
77 /* Compare function for location_adhoc_data hashtable. */
79 static int
80 location_adhoc_data_eq (const void *l1, const void *l2)
82 const struct location_adhoc_data *lb1 =
83 (const struct location_adhoc_data *) l1;
84 const struct location_adhoc_data *lb2 =
85 (const struct location_adhoc_data *) l2;
86 return (lb1->locus == lb2->locus
87 && lb1->src_range.m_start == lb2->src_range.m_start
88 && lb1->src_range.m_finish == lb2->src_range.m_finish
89 && lb1->data == lb2->data);
92 /* Update the hashtable when location_adhoc_data is reallocated. */
94 static int
95 location_adhoc_data_update (void **slot, void *data)
97 *((char **) slot)
98 = (char *) ((uintptr_t) *((char **) slot) + *((ptrdiff_t *) data));
99 return 1;
102 /* Rebuild the hash table from the location adhoc data. */
104 void
105 rebuild_location_adhoc_htab (struct line_maps *set)
107 unsigned i;
108 set->location_adhoc_data_map.htab =
109 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
110 for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
111 htab_find_slot (set->location_adhoc_data_map.htab,
112 set->location_adhoc_data_map.data + i, INSERT);
115 /* Helper function for get_combined_adhoc_loc.
116 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
117 within a source_location, without needing to use an ad-hoc location. */
119 static bool
120 can_be_stored_compactly_p (struct line_maps *set,
121 source_location locus,
122 source_range src_range,
123 void *data)
125 /* If there's an ad-hoc pointer, we can't store it directly in the
126 source_location, we need the lookaside. */
127 if (data)
128 return false;
130 /* We only store ranges that begin at the locus and that are sufficiently
131 "sane". */
132 if (src_range.m_start != locus)
133 return false;
135 if (src_range.m_finish < src_range.m_start)
136 return false;
138 if (src_range.m_start < RESERVED_LOCATION_COUNT)
139 return false;
141 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
142 return false;
144 /* All 3 locations must be within ordinary maps, typically, the same
145 ordinary map. */
146 source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
147 if (locus >= lowest_macro_loc)
148 return false;
149 if (src_range.m_start >= lowest_macro_loc)
150 return false;
151 if (src_range.m_finish >= lowest_macro_loc)
152 return false;
154 /* Passed all tests. */
155 return true;
158 /* Combine LOCUS and DATA to a combined adhoc loc. */
160 source_location
161 get_combined_adhoc_loc (struct line_maps *set,
162 source_location locus,
163 source_range src_range,
164 void *data)
166 struct location_adhoc_data lb;
167 struct location_adhoc_data **slot;
169 if (IS_ADHOC_LOC (locus))
170 locus
171 = set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
172 if (locus == 0 && data == NULL)
173 return 0;
175 /* Any ordinary locations ought to be "pure" at this point: no
176 compressed ranges. */
177 linemap_assert (locus < RESERVED_LOCATION_COUNT
178 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
179 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
180 || pure_location_p (set, locus));
182 /* Consider short-range optimization. */
183 if (can_be_stored_compactly_p (set, locus, src_range, data))
185 /* The low bits ought to be clear. */
186 linemap_assert (pure_location_p (set, locus));
187 const line_map *map = linemap_lookup (set, locus);
188 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
189 unsigned int int_diff = src_range.m_finish - src_range.m_start;
190 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
191 if (col_diff < (1U << ordmap->m_range_bits))
193 source_location packed = locus | col_diff;
194 set->num_optimized_ranges++;
195 return packed;
199 /* We can also compactly store locations
200 when locus == start == finish (and data is NULL). */
201 if (locus == src_range.m_start
202 && locus == src_range.m_finish
203 && !data)
204 return locus;
206 if (!data)
207 set->num_unoptimized_ranges++;
209 lb.locus = locus;
210 lb.src_range = src_range;
211 lb.data = data;
212 slot = (struct location_adhoc_data **)
213 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
214 if (*slot == NULL)
216 if (set->location_adhoc_data_map.curr_loc >=
217 set->location_adhoc_data_map.allocated)
219 char *orig_data = (char *) set->location_adhoc_data_map.data;
220 ptrdiff_t offset;
221 /* Cast away extern "C" from the type of xrealloc. */
222 line_map_realloc reallocator = (set->reallocator
223 ? set->reallocator
224 : (line_map_realloc) xrealloc);
226 if (set->location_adhoc_data_map.allocated == 0)
227 set->location_adhoc_data_map.allocated = 128;
228 else
229 set->location_adhoc_data_map.allocated *= 2;
230 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
231 reallocator (set->location_adhoc_data_map.data,
232 set->location_adhoc_data_map.allocated
233 * sizeof (struct location_adhoc_data));
234 offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
235 if (set->location_adhoc_data_map.allocated > 128)
236 htab_traverse (set->location_adhoc_data_map.htab,
237 location_adhoc_data_update, &offset);
239 *slot = set->location_adhoc_data_map.data
240 + set->location_adhoc_data_map.curr_loc;
241 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
242 = lb;
244 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
247 /* Return the data for the adhoc loc. */
249 void *
250 get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
252 linemap_assert (IS_ADHOC_LOC (loc));
253 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
256 /* Return the location for the adhoc loc. */
258 source_location
259 get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
261 linemap_assert (IS_ADHOC_LOC (loc));
262 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
265 /* Return the source_range for adhoc location LOC. */
267 static source_range
268 get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
270 linemap_assert (IS_ADHOC_LOC (loc));
271 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
274 /* Get the source_range of location LOC, either from the ad-hoc
275 lookaside table, or embedded inside LOC itself. */
277 source_range
278 get_range_from_loc (struct line_maps *set,
279 source_location loc)
281 if (IS_ADHOC_LOC (loc))
282 return get_range_from_adhoc_loc (set, loc);
284 /* For ordinary maps, extract packed range. */
285 if (loc >= RESERVED_LOCATION_COUNT
286 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
287 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
289 const line_map *map = linemap_lookup (set, loc);
290 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
291 source_range result;
292 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
293 result.m_start = loc - offset;
294 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
295 return result;
298 return source_range::from_location (loc);
301 /* Get whether location LOC is a "pure" location, or
302 whether it is an ad-hoc location, or embeds range information. */
304 bool
305 pure_location_p (line_maps *set, source_location loc)
307 if (IS_ADHOC_LOC (loc))
308 return false;
310 const line_map *map = linemap_lookup (set, loc);
311 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
313 if (loc & ((1U << ordmap->m_range_bits) - 1))
314 return false;
316 return true;
319 /* Given location LOC within SET, strip away any packed range information
320 or ad-hoc information. */
322 source_location
323 get_pure_location (line_maps *set, source_location loc)
325 if (IS_ADHOC_LOC (loc))
327 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
329 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
330 return loc;
332 if (loc < RESERVED_LOCATION_COUNT)
333 return loc;
335 const line_map *map = linemap_lookup (set, loc);
336 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
338 return loc & ~((1 << ordmap->m_range_bits) - 1);
341 /* Initialize a line map set. */
343 void
344 linemap_init (struct line_maps *set,
345 source_location builtin_location)
347 *set = line_maps ();
348 set->highest_location = RESERVED_LOCATION_COUNT - 1;
349 set->highest_line = RESERVED_LOCATION_COUNT - 1;
350 set->location_adhoc_data_map.htab =
351 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
352 set->builtin_location = builtin_location;
355 /* Check for and warn about line_maps entered but not exited. */
357 void
358 linemap_check_files_exited (struct line_maps *set)
360 const line_map_ordinary *map;
361 /* Depending upon whether we are handling preprocessed input or
362 not, this can be a user error or an ICE. */
363 for (map = LINEMAPS_LAST_ORDINARY_MAP (set);
364 ! MAIN_FILE_P (map);
365 map = INCLUDED_FROM (set, map))
366 fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
367 ORDINARY_MAP_FILE_NAME (map));
370 /* Create a new line map in the line map set SET, and return it.
371 REASON is the reason of creating the map. It determines the type
372 of map created (ordinary or macro map). Note that ordinary maps and
373 macro maps are allocated in different memory location. */
375 static struct line_map *
376 new_linemap (struct line_maps *set,
377 enum lc_reason reason)
379 /* Depending on this variable, a macro map would be allocated in a
380 different memory location than an ordinary map. */
381 bool macro_map_p = (reason == LC_ENTER_MACRO);
382 struct line_map *result;
384 if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
386 /* We ran out of allocated line maps. Let's allocate more. */
387 size_t alloc_size;
389 /* Cast away extern "C" from the type of xrealloc. */
390 line_map_realloc reallocator = (set->reallocator
391 ? set->reallocator
392 : (line_map_realloc) xrealloc);
393 line_map_round_alloc_size_func round_alloc_size =
394 set->round_alloc_size;
396 size_t map_size = (macro_map_p
397 ? sizeof (line_map_macro)
398 : sizeof (line_map_ordinary));
400 /* We are going to execute some dance to try to reduce the
401 overhead of the memory allocator, in case we are using the
402 ggc-page.c one.
404 The actual size of memory we are going to get back from the
405 allocator is the smallest power of 2 that is greater than the
406 size we requested. So let's consider that size then. */
408 alloc_size =
409 (2 * LINEMAPS_ALLOCATED (set, macro_map_p) + 256)
410 * map_size;
412 /* Get the actual size of memory that is going to be allocated
413 by the allocator. */
414 alloc_size = round_alloc_size (alloc_size);
416 /* Now alloc_size contains the exact memory size we would get if
417 we have asked for the initial alloc_size amount of memory.
418 Let's get back to the number of macro map that amounts
419 to. */
420 LINEMAPS_ALLOCATED (set, macro_map_p) =
421 alloc_size / map_size;
423 /* And now let's really do the re-allocation. */
424 if (macro_map_p)
426 set->info_macro.maps
427 = (line_map_macro *) (*reallocator) (set->info_macro.maps,
428 (LINEMAPS_ALLOCATED (set, macro_map_p)
429 * map_size));
430 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
432 else
434 set->info_ordinary.maps =
435 (line_map_ordinary *) (*reallocator) (set->info_ordinary.maps,
436 (LINEMAPS_ALLOCATED (set, macro_map_p)
437 * map_size));
438 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
440 memset (result, 0,
441 ((LINEMAPS_ALLOCATED (set, macro_map_p)
442 - LINEMAPS_USED (set, macro_map_p))
443 * map_size));
445 else
447 if (macro_map_p)
448 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
449 else
450 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
453 LINEMAPS_USED (set, macro_map_p)++;
455 result->reason = reason;
456 return result;
459 /* Add a mapping of logical source line to physical source file and
460 line number.
462 The text pointed to by TO_FILE must have a lifetime
463 at least as long as the final call to lookup_line (). An empty
464 TO_FILE means standard input. If reason is LC_LEAVE, and
465 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
466 natural values considering the file we are returning to.
468 FROM_LINE should be monotonic increasing across calls to this
469 function. A call to this function can relocate the previous set of
470 maps, so any stored line_map pointers should not be used. */
472 const struct line_map *
473 linemap_add (struct line_maps *set, enum lc_reason reason,
474 unsigned int sysp, const char *to_file, linenum_type to_line)
476 /* Generate a start_location above the current highest_location.
477 If possible, make the low range bits be zero. */
478 source_location start_location;
479 if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
481 start_location = set->highest_location + (1 << set->default_range_bits);
482 if (set->default_range_bits)
483 start_location &= ~((1 << set->default_range_bits) - 1);
484 linemap_assert (0 == (start_location
485 & ((1 << set->default_range_bits) - 1)));
487 else
488 start_location = set->highest_location + 1;
490 linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
491 && (start_location
492 < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));
494 /* When we enter the file for the first time reason cannot be
495 LC_RENAME. */
496 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
498 /* If we are leaving the main file, return a NULL map. */
499 if (reason == LC_LEAVE
500 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
501 && to_file == NULL)
503 set->depth--;
504 return NULL;
507 linemap_assert (reason != LC_ENTER_MACRO);
508 line_map_ordinary *map = linemap_check_ordinary (new_linemap (set, reason));
510 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
511 to_file = "<stdin>";
513 if (reason == LC_RENAME_VERBATIM)
514 reason = LC_RENAME;
516 if (reason == LC_LEAVE)
518 /* When we are just leaving an "included" file, and jump to the next
519 location inside the "includer" right after the #include
520 "included", this variable points the map in use right before the
521 #include "included", inside the same "includer" file. */
522 line_map_ordinary *from;
524 linemap_assert (!MAIN_FILE_P (map - 1));
525 /* (MAP - 1) points to the map we are leaving. The
526 map from which (MAP - 1) got included should be the map
527 that comes right before MAP in the same file. */
528 from = INCLUDED_FROM (set, map - 1);
530 /* A TO_FILE of NULL is special - we use the natural values. */
531 if (to_file == NULL)
533 to_file = ORDINARY_MAP_FILE_NAME (from);
534 to_line = SOURCE_LINE (from, from[1].start_location);
535 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
537 else
538 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
539 to_file) == 0);
542 map->sysp = sysp;
543 map->start_location = start_location;
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 <= set->highest_line
625 || start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
626 /* We ran out of macro map space. */
627 return NULL;
629 map = linemap_check_macro (new_linemap (set, LC_ENTER_MACRO));
631 map->start_location = start_location;
632 map->macro = macro_node;
633 map->n_tokens = num_tokens;
634 map->macro_locations
635 = (source_location*) reallocator (NULL,
636 2 * num_tokens
637 * sizeof (source_location));
638 map->expansion = expansion;
639 memset (MACRO_MAP_LOCATIONS (map), 0,
640 num_tokens * sizeof (source_location));
642 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
644 return map;
647 /* Create and return a virtual location for a token that is part of a
648 macro expansion-list at a macro expansion point. See the comment
649 inside struct line_map_macro to see what an expansion-list exactly
652 A call to this function must come after a call to
653 linemap_enter_macro.
655 MAP is the map into which the source location is created. TOKEN_NO
656 is the index of the token in the macro replacement-list, starting
657 at number 0.
659 ORIG_LOC is the location of the token outside of this macro
660 expansion. If the token comes originally from the macro
661 definition, it is the locus in the macro definition; otherwise it
662 is a location in the context of the caller of this macro expansion
663 (which is a virtual location or a source location if the caller is
664 itself a macro expansion or not).
666 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
667 either of the token itself or of a macro parameter that it
668 replaces. */
670 source_location
671 linemap_add_macro_token (const line_map_macro *map,
672 unsigned int token_no,
673 source_location orig_loc,
674 source_location orig_parm_replacement_loc)
676 source_location result;
678 linemap_assert (linemap_macro_expansion_map_p (map));
679 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
681 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
682 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
684 result = MAP_START_LOCATION (map) + token_no;
685 return result;
688 /* Return a source_location for the start (i.e. column==0) of
689 (physical) line TO_LINE in the current source file (as in the
690 most recent linemap_add). MAX_COLUMN_HINT is the highest column
691 number we expect to use in this line (but it does not change
692 the highest_location). */
694 source_location
695 linemap_line_start (struct line_maps *set, linenum_type to_line,
696 unsigned int max_column_hint)
698 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
699 source_location highest = set->highest_location;
700 source_location r;
701 linenum_type last_line =
702 SOURCE_LINE (map, set->highest_line);
703 int line_delta = to_line - last_line;
704 bool add_map = false;
705 linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
706 int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
708 if (line_delta < 0
709 || (line_delta > 10
710 && line_delta * map->m_column_and_range_bits > 1000)
711 || (max_column_hint >= (1U << effective_column_bits))
712 || (max_column_hint <= 80 && effective_column_bits >= 10)
713 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
714 && map->m_range_bits > 0)
715 || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
716 && (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
717 add_map = true;
718 else
719 max_column_hint = set->max_column_hint;
720 if (add_map)
722 int column_bits;
723 int range_bits;
724 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
725 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
727 /* If the column number is ridiculous or we've allocated a huge
728 number of source_locations, give up on column numbers
729 (and on packed ranges). */
730 max_column_hint = 0;
731 column_bits = 0;
732 range_bits = 0;
733 if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
734 return 0;
736 else
738 column_bits = 7;
739 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
740 range_bits = set->default_range_bits;
741 else
742 range_bits = 0;
743 while (max_column_hint >= (1U << column_bits))
744 column_bits++;
745 max_column_hint = 1U << column_bits;
746 column_bits += range_bits;
748 /* Allocate the new line_map. However, if the current map only has a
749 single line we can sometimes just increase its column_bits instead. */
750 if (line_delta < 0
751 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
752 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
753 || range_bits < map->m_range_bits)
754 map = linemap_check_ordinary
755 (const_cast <line_map *>
756 (linemap_add (set, LC_RENAME,
757 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
758 ORDINARY_MAP_FILE_NAME (map),
759 to_line)));
760 map->m_column_and_range_bits = column_bits;
761 map->m_range_bits = range_bits;
762 r = (MAP_START_LOCATION (map)
763 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
764 << column_bits));
766 else
767 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
769 /* Locations of ordinary tokens are always lower than locations of
770 macro tokens. */
771 if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
772 return 0;
774 set->highest_line = r;
775 if (r > set->highest_location)
776 set->highest_location = r;
777 set->max_column_hint = max_column_hint;
779 /* At this point, we expect one of:
780 (a) the normal case: a "pure" location with 0 range bits, or
781 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
782 columns anymore (or ranges), or
783 (c) we're in a region with a column hint exceeding
784 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
785 with column_bits == 0. */
786 linemap_assert (pure_location_p (set, r)
787 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
788 || map->m_column_and_range_bits == 0);
789 linemap_assert (SOURCE_LINE (map, r) == to_line);
790 return r;
793 /* Encode and return a source_location from a column number. The
794 source line considered is the last source line used to call
795 linemap_line_start, i.e, the last source line which a location was
796 encoded from. */
798 source_location
799 linemap_position_for_column (struct line_maps *set, unsigned int to_column)
801 source_location r = set->highest_line;
803 linemap_assert
804 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
806 if (to_column >= set->max_column_hint)
808 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
809 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
811 /* Running low on source_locations - disable column numbers. */
812 return r;
814 else
816 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
817 with some space to spare. This may or may not lead to a new
818 linemap being created. */
819 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
820 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
821 map = LINEMAPS_LAST_ORDINARY_MAP (set);
822 if (map->m_column_and_range_bits == 0)
824 /* ...then the linemap has column-tracking disabled,
825 presumably due to exceeding either
826 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
827 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
828 Return the start of the linemap, which encodes column 0, for
829 the whole line. */
830 return r;
834 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
835 r = r + (to_column << map->m_range_bits);
836 if (r >= set->highest_location)
837 set->highest_location = r;
838 return r;
841 /* Encode and return a source location from a given line and
842 column. */
844 source_location
845 linemap_position_for_line_and_column (line_maps *set,
846 const line_map_ordinary *ord_map,
847 linenum_type line,
848 unsigned column)
850 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
852 source_location r = MAP_START_LOCATION (ord_map);
853 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
854 << ord_map->m_column_and_range_bits);
855 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
856 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
857 << ord_map->m_range_bits);
858 source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
859 if (r >= upper_limit)
860 r = upper_limit - 1;
861 if (r > set->highest_location)
862 set->highest_location = r;
863 return r;
866 /* Encode and return a source_location starting from location LOC and
867 shifting it by COLUMN_OFFSET columns. This function does not support
868 virtual locations. */
870 source_location
871 linemap_position_for_loc_and_offset (struct line_maps *set,
872 source_location loc,
873 unsigned int column_offset)
875 const line_map_ordinary * map = NULL;
877 if (IS_ADHOC_LOC (loc))
878 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
880 /* This function does not support virtual locations yet. */
881 if (linemap_location_from_macro_expansion_p (set, loc))
882 return loc;
884 if (column_offset == 0
885 /* Adding an offset to a reserved location (like
886 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
887 sense. So let's leave the location intact in that case. */
888 || loc < RESERVED_LOCATION_COUNT)
889 return loc;
891 /* We find the real location and shift it. */
892 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
893 /* The new location (loc + offset) should be higher than the first
894 location encoded by MAP. This can fail if the line information
895 is messed up because of line directives (see PR66415). */
896 if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
897 return loc;
899 linenum_type line = SOURCE_LINE (map, loc);
900 unsigned int column = SOURCE_COLUMN (map, loc);
902 /* If MAP is not the last line map of its set, then the new location
903 (loc + offset) should be less than the first location encoded by
904 the next line map of the set. Otherwise, we try to encode the
905 location in the next map. */
906 while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
907 && (loc + (column_offset << map->m_range_bits)
908 >= MAP_START_LOCATION (&map[1])))
910 map = &map[1];
911 /* If the next map starts in a higher line, we cannot encode the
912 location there. */
913 if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
914 return loc;
917 column += column_offset;
919 /* Bail out if the column is not representable within the existing
920 linemap. */
921 if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
922 return loc;
924 source_location r =
925 linemap_position_for_line_and_column (set, map, line, column);
926 if (linemap_assert_fails (r <= set->highest_location)
927 || linemap_assert_fails (map == linemap_lookup (set, r)))
928 return loc;
930 return r;
933 /* Given a virtual source location yielded by a map (either an
934 ordinary or a macro map), returns that map. */
936 const struct line_map*
937 linemap_lookup (struct line_maps *set, source_location line)
939 if (IS_ADHOC_LOC (line))
940 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
941 if (linemap_location_from_macro_expansion_p (set, line))
942 return linemap_macro_map_lookup (set, line);
943 return linemap_ordinary_map_lookup (set, line);
946 /* Given a source location yielded by an ordinary map, returns that
947 map. Since the set is built chronologically, the logical lines are
948 monotonic increasing, and so the list is sorted and we can use a
949 binary search. */
951 static const line_map_ordinary *
952 linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
954 unsigned int md, mn, mx;
955 const line_map_ordinary *cached, *result;
957 if (IS_ADHOC_LOC (line))
958 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
960 if (set == NULL || line < RESERVED_LOCATION_COUNT)
961 return NULL;
963 mn = LINEMAPS_ORDINARY_CACHE (set);
964 mx = LINEMAPS_ORDINARY_USED (set);
966 cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
967 /* We should get a segfault if no line_maps have been added yet. */
968 if (line >= MAP_START_LOCATION (cached))
970 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
971 return cached;
973 else
975 mx = mn;
976 mn = 0;
979 while (mx - mn > 1)
981 md = (mn + mx) / 2;
982 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
983 mx = md;
984 else
985 mn = md;
988 LINEMAPS_ORDINARY_CACHE (set) = mn;
989 result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
990 linemap_assert (line >= MAP_START_LOCATION (result));
991 return result;
994 /* Given a source location yielded by a macro map, returns that map.
995 Since the set is built chronologically, the logical lines are
996 monotonic decreasing, and so the list is sorted and we can use a
997 binary search. */
999 static const line_map_macro *
1000 linemap_macro_map_lookup (struct line_maps *set, source_location line)
1002 unsigned int md, mn, mx;
1003 const struct line_map_macro *cached, *result;
1005 if (IS_ADHOC_LOC (line))
1006 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
1008 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1010 if (set == NULL)
1011 return NULL;
1013 mn = LINEMAPS_MACRO_CACHE (set);
1014 mx = LINEMAPS_MACRO_USED (set);
1015 cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1017 if (line >= MAP_START_LOCATION (cached))
1019 if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
1020 return cached;
1021 mx = mn - 1;
1022 mn = 0;
1025 while (mn < mx)
1027 md = (mx + mn) / 2;
1028 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1029 mn = md + 1;
1030 else
1031 mx = md;
1034 LINEMAPS_MACRO_CACHE (set) = mx;
1035 result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
1036 linemap_assert (MAP_START_LOCATION (result) <= line);
1038 return result;
1041 /* Return TRUE if MAP encodes locations coming from a macro
1042 replacement-list at macro expansion point. */
1044 bool
1045 linemap_macro_expansion_map_p (const struct line_map *map)
1047 if (!map)
1048 return false;
1049 return (map->reason == LC_ENTER_MACRO);
1052 /* If LOCATION is the locus of a token in a replacement-list of a
1053 macro expansion return the location of the macro expansion point.
1055 Read the comments of struct line_map and struct line_map_macro in
1056 line-map.h to understand what a macro expansion point is. */
1058 static source_location
1059 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1060 source_location location ATTRIBUTE_UNUSED)
1062 linemap_assert (linemap_macro_expansion_map_p (map)
1063 && location >= MAP_START_LOCATION (map));
1065 /* Make sure LOCATION is correct. */
1066 linemap_assert ((location - MAP_START_LOCATION (map))
1067 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1069 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1072 /* LOCATION is the source location of a token that belongs to a macro
1073 replacement-list as part of the macro expansion denoted by MAP.
1075 Return the location of the token at the definition point of the
1076 macro. */
1078 static source_location
1079 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1080 source_location location)
1082 unsigned token_no;
1084 linemap_assert (linemap_macro_expansion_map_p (map)
1085 && location >= MAP_START_LOCATION (map));
1086 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1088 token_no = location - MAP_START_LOCATION (map);
1089 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1091 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1093 return location;
1096 /* If LOCATION is the locus of a token that is an argument of a
1097 function-like macro M and appears in the expansion of M, return the
1098 locus of that argument in the context of the caller of M.
1100 In other words, this returns the xI location presented in the
1101 comments of line_map_macro above. */
1102 source_location
1103 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1104 const line_map_macro* map,
1105 source_location location)
1107 unsigned token_no;
1109 if (IS_ADHOC_LOC (location))
1110 location = get_location_from_adhoc_loc (set, location);
1112 linemap_assert (linemap_macro_expansion_map_p (map)
1113 && location >= MAP_START_LOCATION (map));
1114 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1115 linemap_assert (!IS_ADHOC_LOC (location));
1117 token_no = location - MAP_START_LOCATION (map);
1118 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1120 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1122 return location;
1125 /* Return the source line number corresponding to source location
1126 LOCATION. SET is the line map set LOCATION comes from. If
1127 LOCATION is the source location of token that is part of the
1128 replacement-list of a macro expansion return the line number of the
1129 macro expansion point. */
1132 linemap_get_expansion_line (struct line_maps *set,
1133 source_location location)
1135 const line_map_ordinary *map = NULL;
1137 if (IS_ADHOC_LOC (location))
1138 location = set->location_adhoc_data_map.data[location
1139 & MAX_SOURCE_LOCATION].locus;
1141 if (location < RESERVED_LOCATION_COUNT)
1142 return 0;
1144 location =
1145 linemap_macro_loc_to_exp_point (set, location, &map);
1147 return SOURCE_LINE (map, location);
1150 /* Return the path of the file corresponding to source code location
1151 LOCATION.
1153 If LOCATION is the source location of token that is part of the
1154 replacement-list of a macro expansion return the file path of the
1155 macro expansion point.
1157 SET is the line map set LOCATION comes from. */
1159 const char*
1160 linemap_get_expansion_filename (struct line_maps *set,
1161 source_location location)
1163 const struct line_map_ordinary *map = NULL;
1165 if (IS_ADHOC_LOC (location))
1166 location = set->location_adhoc_data_map.data[location
1167 & MAX_SOURCE_LOCATION].locus;
1169 if (location < RESERVED_LOCATION_COUNT)
1170 return NULL;
1172 location =
1173 linemap_macro_loc_to_exp_point (set, location, &map);
1175 return LINEMAP_FILE (map);
1178 /* Return the name of the macro associated to MACRO_MAP. */
1180 const char*
1181 linemap_map_get_macro_name (const line_map_macro *macro_map)
1183 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1184 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1187 /* Return a positive value if LOCATION is the locus of a token that is
1188 located in a system header, O otherwise. It returns 1 if LOCATION
1189 is the locus of a token that is located in a system header, and 2
1190 if LOCATION is the locus of a token located in a C system header
1191 that therefore needs to be extern "C" protected in C++.
1193 Note that this function returns 1 if LOCATION belongs to a token
1194 that is part of a macro replacement-list defined in a system
1195 header, but expanded in a non-system file. */
1198 linemap_location_in_system_header_p (struct line_maps *set,
1199 source_location location)
1201 const struct line_map *map = NULL;
1203 if (IS_ADHOC_LOC (location))
1204 location = set->location_adhoc_data_map.data[location
1205 & MAX_SOURCE_LOCATION].locus;
1207 if (location < RESERVED_LOCATION_COUNT)
1208 return false;
1210 /* Let's look at where the token for LOCATION comes from. */
1211 while (true)
1213 map = linemap_lookup (set, location);
1214 if (map != NULL)
1216 if (!linemap_macro_expansion_map_p (map))
1217 /* It's a normal token. */
1218 return LINEMAP_SYSP (linemap_check_ordinary (map));
1219 else
1221 const line_map_macro *macro_map = linemap_check_macro (map);
1223 /* It's a token resulting from a macro expansion. */
1224 source_location loc =
1225 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1226 if (loc < RESERVED_LOCATION_COUNT)
1227 /* This token might come from a built-in macro. Let's
1228 look at where that macro got expanded. */
1229 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1230 else
1231 location = loc;
1234 else
1235 break;
1237 return false;
1240 /* Return TRUE if LOCATION is a source code location of a token that is part of
1241 a macro expansion, FALSE otherwise. */
1243 bool
1244 linemap_location_from_macro_expansion_p (const struct line_maps *set,
1245 source_location location)
1247 if (IS_ADHOC_LOC (location))
1248 location = set->location_adhoc_data_map.data[location
1249 & MAX_SOURCE_LOCATION].locus;
1251 linemap_assert (location <= MAX_SOURCE_LOCATION
1252 && (set->highest_location
1253 < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
1254 if (set == NULL)
1255 return false;
1256 return (location > set->highest_location);
1259 /* Given two virtual locations *LOC0 and *LOC1, return the first
1260 common macro map in their macro expansion histories. Return NULL
1261 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1262 virtual location of the token inside the resulting macro. */
1264 static const struct line_map*
1265 first_map_in_common_1 (struct line_maps *set,
1266 source_location *loc0,
1267 source_location *loc1)
1269 source_location l0 = *loc0, l1 = *loc1;
1270 const struct line_map *map0 = linemap_lookup (set, l0),
1271 *map1 = linemap_lookup (set, l1);
1273 while (linemap_macro_expansion_map_p (map0)
1274 && linemap_macro_expansion_map_p (map1)
1275 && (map0 != map1))
1277 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1279 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1280 l0);
1281 map0 = linemap_lookup (set, l0);
1283 else
1285 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1286 l1);
1287 map1 = linemap_lookup (set, l1);
1291 if (map0 == map1)
1293 *loc0 = l0;
1294 *loc1 = l1;
1295 return map0;
1297 return NULL;
1300 /* Given two virtual locations LOC0 and LOC1, return the first common
1301 macro map in their macro expansion histories. Return NULL if no
1302 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1303 virtual location of the token inside the resulting macro, upon
1304 return of a non-NULL result. */
1306 static const struct line_map*
1307 first_map_in_common (struct line_maps *set,
1308 source_location loc0,
1309 source_location loc1,
1310 source_location *res_loc0,
1311 source_location *res_loc1)
1313 *res_loc0 = loc0;
1314 *res_loc1 = loc1;
1316 return first_map_in_common_1 (set, res_loc0, res_loc1);
1319 /* Return a positive value if PRE denotes the location of a token that
1320 comes before the token of POST, 0 if PRE denotes the location of
1321 the same token as the token for POST, and a negative value
1322 otherwise. */
1325 linemap_compare_locations (struct line_maps *set,
1326 source_location pre,
1327 source_location post)
1329 bool pre_virtual_p, post_virtual_p;
1330 source_location l0 = pre, l1 = post;
1332 if (IS_ADHOC_LOC (l0))
1333 l0 = get_location_from_adhoc_loc (set, l0);
1334 if (IS_ADHOC_LOC (l1))
1335 l1 = get_location_from_adhoc_loc (set, l1);
1337 if (l0 == l1)
1338 return 0;
1340 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1341 l0 = linemap_resolve_location (set, l0,
1342 LRK_MACRO_EXPANSION_POINT,
1343 NULL);
1345 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1346 l1 = linemap_resolve_location (set, l1,
1347 LRK_MACRO_EXPANSION_POINT,
1348 NULL);
1350 if (l0 == l1
1351 && pre_virtual_p
1352 && post_virtual_p)
1354 /* So pre and post represent two tokens that are present in a
1355 same macro expansion. Let's see if the token for pre was
1356 before the token for post in that expansion. */
1357 unsigned i0, i1;
1358 const struct line_map *map =
1359 first_map_in_common (set, pre, post, &l0, &l1);
1361 if (map == NULL)
1362 /* This should not be possible. */
1363 abort ();
1365 i0 = l0 - MAP_START_LOCATION (map);
1366 i1 = l1 - MAP_START_LOCATION (map);
1367 return i1 - i0;
1370 if (IS_ADHOC_LOC (l0))
1371 l0 = get_location_from_adhoc_loc (set, l0);
1372 if (IS_ADHOC_LOC (l1))
1373 l1 = get_location_from_adhoc_loc (set, l1);
1375 return l1 - l0;
1378 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1380 static void
1381 trace_include (const struct line_maps *set, const line_map_ordinary *map)
1383 unsigned int i = set->depth;
1385 while (--i)
1386 putc ('.', stderr);
1388 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1391 /* Return the spelling location of the token wherever it comes from,
1392 whether part of a macro definition or not.
1394 This is a subroutine for linemap_resolve_location. */
1396 static source_location
1397 linemap_macro_loc_to_spelling_point (struct line_maps *set,
1398 source_location location,
1399 const line_map_ordinary **original_map)
1401 struct line_map *map;
1402 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1404 while (true)
1406 map = const_cast <line_map *> (linemap_lookup (set, location));
1407 if (!linemap_macro_expansion_map_p (map))
1408 break;
1410 location
1411 = linemap_macro_map_loc_unwind_toward_spelling
1412 (set, linemap_check_macro (map),
1413 location);
1416 if (original_map)
1417 *original_map = linemap_check_ordinary (map);
1418 return location;
1421 /* If LOCATION is the source location of a token that belongs to a
1422 macro replacement-list -- as part of a macro expansion -- then
1423 return the location of the token at the definition point of the
1424 macro. Otherwise, return LOCATION. SET is the set of maps
1425 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1426 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1427 returned location comes from.
1429 This is a subroutine of linemap_resolve_location. */
1431 static source_location
1432 linemap_macro_loc_to_def_point (struct line_maps *set,
1433 source_location location,
1434 const line_map_ordinary **original_map)
1436 struct line_map *map;
1438 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1440 while (true)
1442 source_location caret_loc;
1443 if (IS_ADHOC_LOC (location))
1444 caret_loc = get_location_from_adhoc_loc (set, location);
1445 else
1446 caret_loc = location;
1448 map = const_cast <line_map *> (linemap_lookup (set, caret_loc));
1449 if (!linemap_macro_expansion_map_p (map))
1450 break;
1452 location =
1453 linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
1454 caret_loc);
1457 if (original_map)
1458 *original_map = linemap_check_ordinary (map);
1459 return location;
1462 /* If LOCATION is the source location of a token that belongs to a
1463 macro replacement-list -- at a macro expansion point -- then return
1464 the location of the topmost expansion point of the macro. We say
1465 topmost because if we are in the context of a nested macro
1466 expansion, the function returns the source location of the first
1467 macro expansion that triggered the nested expansions.
1469 Otherwise, return LOCATION. SET is the set of maps location come
1470 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1471 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1472 location comes from.
1474 This is a subroutine of linemap_resolve_location. */
1476 static source_location
1477 linemap_macro_loc_to_exp_point (struct line_maps *set,
1478 source_location location,
1479 const line_map_ordinary **original_map)
1481 struct line_map *map;
1483 if (IS_ADHOC_LOC (location))
1484 location = set->location_adhoc_data_map.data[location
1485 & MAX_SOURCE_LOCATION].locus;
1487 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1489 while (true)
1491 map = const_cast <line_map *> (linemap_lookup (set, location));
1492 if (!linemap_macro_expansion_map_p (map))
1493 break;
1494 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1495 location);
1498 if (original_map)
1499 *original_map = linemap_check_ordinary (map);
1500 return location;
1503 /* Resolve a virtual location into either a spelling location, an
1504 expansion point location or a token argument replacement point
1505 location. Return the map that encodes the virtual location as well
1506 as the resolved location.
1508 If LOC is *NOT* the location of a token resulting from the
1509 expansion of a macro, then the parameter LRK (which stands for
1510 Location Resolution Kind) is ignored and the resulting location
1511 just equals the one given in argument.
1513 Now if LOC *IS* the location of a token resulting from the
1514 expansion of a macro, this is what happens.
1516 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1517 -------------------------------
1519 The virtual location is resolved to the first macro expansion point
1520 that led to this macro expansion.
1522 * If LRK is set to LRK_SPELLING_LOCATION
1523 -------------------------------------
1525 The virtual location is resolved to the locus where the token has
1526 been spelled in the source. This can follow through all the macro
1527 expansions that led to the token.
1529 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1530 --------------------------------------
1532 The virtual location is resolved to the locus of the token in the
1533 context of the macro definition.
1535 If LOC is the locus of a token that is an argument of a
1536 function-like macro [replacing a parameter in the replacement list
1537 of the macro] the virtual location is resolved to the locus of the
1538 parameter that is replaced, in the context of the definition of the
1539 macro.
1541 If LOC is the locus of a token that is not an argument of a
1542 function-like macro, then the function behaves as if LRK was set to
1543 LRK_SPELLING_LOCATION.
1545 If MAP is not NULL, *MAP is set to the map encoding the
1546 returned location. Note that if the returned location wasn't originally
1547 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1548 resolves to a location reserved for the client code, like
1549 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1551 source_location
1552 linemap_resolve_location (struct line_maps *set,
1553 source_location loc,
1554 enum location_resolution_kind lrk,
1555 const line_map_ordinary **map)
1557 source_location locus = loc;
1558 if (IS_ADHOC_LOC (loc))
1559 locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1561 if (locus < RESERVED_LOCATION_COUNT)
1563 /* A reserved location wasn't encoded in a map. Let's return a
1564 NULL map here, just like what linemap_ordinary_map_lookup
1565 does. */
1566 if (map)
1567 *map = NULL;
1568 return loc;
1571 switch (lrk)
1573 case LRK_MACRO_EXPANSION_POINT:
1574 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1575 break;
1576 case LRK_SPELLING_LOCATION:
1577 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1578 break;
1579 case LRK_MACRO_DEFINITION_LOCATION:
1580 loc = linemap_macro_loc_to_def_point (set, loc, map);
1581 break;
1582 default:
1583 abort ();
1585 return loc;
1588 /* TRUE if LOCATION is a source code location of a token that is part of the
1589 definition of a macro, FALSE otherwise. */
1591 bool
1592 linemap_location_from_macro_definition_p (struct line_maps *set,
1593 source_location loc)
1595 if (IS_ADHOC_LOC (loc))
1596 loc = get_location_from_adhoc_loc (set, loc);
1598 if (!linemap_location_from_macro_expansion_p (set, loc))
1599 return false;
1601 while (true)
1603 const struct line_map_macro *map
1604 = linemap_check_macro (linemap_lookup (set, loc));
1606 source_location s_loc
1607 = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
1608 if (linemap_location_from_macro_expansion_p (set, s_loc))
1609 loc = s_loc;
1610 else
1612 source_location def_loc
1613 = linemap_macro_map_loc_to_def_point (map, loc);
1614 return s_loc == def_loc;
1620 Suppose that LOC is the virtual location of a token T coming from
1621 the expansion of a macro M. This function then steps up to get the
1622 location L of the point where M got expanded. If L is a spelling
1623 location inside a macro expansion M', then this function returns
1624 the locus of the point where M' was expanded. Said otherwise, this
1625 function returns the location of T in the context that triggered
1626 the expansion of M.
1628 *LOC_MAP must be set to the map of LOC. This function then sets it
1629 to the map of the returned location. */
1631 source_location
1632 linemap_unwind_toward_expansion (struct line_maps *set,
1633 source_location loc,
1634 const struct line_map **map)
1636 source_location resolved_location;
1637 const line_map_macro *macro_map = linemap_check_macro (*map);
1638 const struct line_map *resolved_map;
1640 if (IS_ADHOC_LOC (loc))
1641 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1643 resolved_location =
1644 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1645 resolved_map = linemap_lookup (set, resolved_location);
1647 if (!linemap_macro_expansion_map_p (resolved_map))
1649 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1650 resolved_map = linemap_lookup (set, resolved_location);
1653 *map = resolved_map;
1654 return resolved_location;
1657 /* If LOC is the virtual location of a token coming from the expansion
1658 of a macro M and if its spelling location is reserved (e.g, a
1659 location for a built-in token), then this function unwinds (using
1660 linemap_unwind_toward_expansion) the location until a location that
1661 is not reserved and is not in a system header is reached. In other
1662 words, this unwinds the reserved location until a location that is
1663 in real source code is reached.
1665 Otherwise, if the spelling location for LOC is not reserved or if
1666 LOC doesn't come from the expansion of a macro, the function
1667 returns LOC as is and *MAP is not touched.
1669 *MAP is set to the map of the returned location if the later is
1670 different from LOC. */
1671 source_location
1672 linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
1673 source_location loc,
1674 const struct line_map **map)
1676 source_location resolved_loc;
1677 const struct line_map *map0 = NULL;
1678 const line_map_ordinary *map1 = NULL;
1680 if (IS_ADHOC_LOC (loc))
1681 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1683 map0 = linemap_lookup (set, loc);
1684 if (!linemap_macro_expansion_map_p (map0))
1685 return loc;
1687 resolved_loc = linemap_resolve_location (set, loc,
1688 LRK_SPELLING_LOCATION,
1689 &map1);
1691 if (resolved_loc >= RESERVED_LOCATION_COUNT
1692 && !LINEMAP_SYSP (map1))
1693 return loc;
1695 while (linemap_macro_expansion_map_p (map0)
1696 && (resolved_loc < RESERVED_LOCATION_COUNT
1697 || LINEMAP_SYSP (map1)))
1699 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1700 resolved_loc = linemap_resolve_location (set, loc,
1701 LRK_SPELLING_LOCATION,
1702 &map1);
1705 if (map != NULL)
1706 *map = map0;
1707 return loc;
1710 /* Expand source code location LOC and return a user readable source
1711 code location. LOC must be a spelling (non-virtual) location. If
1712 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1713 location is returned. */
1715 expanded_location
1716 linemap_expand_location (struct line_maps *set,
1717 const struct line_map *map,
1718 source_location loc)
1721 expanded_location xloc;
1723 memset (&xloc, 0, sizeof (xloc));
1724 if (IS_ADHOC_LOC (loc))
1726 xloc.data
1727 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
1728 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1731 if (loc < RESERVED_LOCATION_COUNT)
1732 /* The location for this token wasn't generated from a line map.
1733 It was probably a location for a builtin token, chosen by some
1734 client code. Let's not try to expand the location in that
1735 case. */;
1736 else if (map == NULL)
1737 /* We shouldn't be getting a NULL map with a location that is not
1738 reserved by the client code. */
1739 abort ();
1740 else
1742 /* MAP must be an ordinary map and LOC must be non-virtual,
1743 encoded into this map, obviously; the accessors used on MAP
1744 below ensure it is ordinary. Let's just assert the
1745 non-virtualness of LOC here. */
1746 if (linemap_location_from_macro_expansion_p (set, loc))
1747 abort ();
1749 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1751 xloc.file = LINEMAP_FILE (ord_map);
1752 xloc.line = SOURCE_LINE (ord_map, loc);
1753 xloc.column = SOURCE_COLUMN (ord_map, loc);
1754 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1757 return xloc;
1761 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1762 is NULL, use stderr. IS_MACRO is true if the caller wants to
1763 dump a macro map, false otherwise. */
1765 void
1766 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
1768 const char *lc_reasons_v[LC_ENTER_MACRO + 1]
1769 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1770 "LC_ENTER_MACRO" };
1771 const char *reason;
1772 const line_map *map;
1774 if (stream == NULL)
1775 stream = stderr;
1777 if (!is_macro)
1778 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1779 else
1780 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1782 reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
1784 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1785 ix, (void *) map, map->start_location, reason,
1786 ((!is_macro
1787 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1788 ? "yes" : "no"));
1789 if (!is_macro)
1791 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1792 unsigned includer_ix;
1793 const line_map_ordinary *includer_map;
1795 includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
1796 includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
1797 ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
1798 : NULL;
1800 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1801 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1802 fprintf (stream, "Included from: [%d] %s\n", includer_ix,
1803 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1805 else
1807 const line_map_macro *macro_map = linemap_check_macro (map);
1808 fprintf (stream, "Macro: %s (%u tokens)\n",
1809 linemap_map_get_macro_name (macro_map),
1810 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1813 fprintf (stream, "\n");
1817 /* Dump debugging information about source location LOC into the file
1818 stream STREAM. SET is the line map set LOC comes from. */
1820 void
1821 linemap_dump_location (struct line_maps *set,
1822 source_location loc,
1823 FILE *stream)
1825 const line_map_ordinary *map;
1826 source_location location;
1827 const char *path = "", *from = "";
1828 int l = -1, c = -1, s = -1, e = -1;
1830 if (IS_ADHOC_LOC (loc))
1831 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1833 if (loc == 0)
1834 return;
1836 location =
1837 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1839 if (map == NULL)
1840 /* Only reserved locations can be tolerated in this case. */
1841 linemap_assert (location < RESERVED_LOCATION_COUNT);
1842 else
1844 path = LINEMAP_FILE (map);
1845 l = SOURCE_LINE (map, location);
1846 c = SOURCE_COLUMN (map, location);
1847 s = LINEMAP_SYSP (map) != 0;
1848 e = location != loc;
1849 if (e)
1850 from = "N/A";
1851 else
1852 from = (INCLUDED_FROM (set, map))
1853 ? LINEMAP_FILE (INCLUDED_FROM (set, map))
1854 : "<NULL>";
1857 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1858 E: macro expansion?, LOC: original location, R: resolved location */
1859 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1860 path, from, l, c, s, (void*)map, e, loc, location);
1863 /* Return the highest location emitted for a given file for which
1864 there is a line map in SET. FILE_NAME is the file name to
1865 consider. If the function returns TRUE, *LOC is set to the highest
1866 location emitted for that file. */
1868 bool
1869 linemap_get_file_highest_location (struct line_maps *set,
1870 const char *file_name,
1871 source_location *loc)
1873 /* If the set is empty or no ordinary map has been created then
1874 there is no file to look for ... */
1875 if (set == NULL || set->info_ordinary.used == 0)
1876 return false;
1878 /* Now look for the last ordinary map created for FILE_NAME. */
1879 int i;
1880 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1882 const char *fname = set->info_ordinary.maps[i].to_file;
1883 if (fname && !filename_cmp (fname, file_name))
1884 break;
1887 if (i < 0)
1888 return false;
1890 /* The highest location for a given map is either the starting
1891 location of the next map minus one, or -- if the map is the
1892 latest one -- the highest location of the set. */
1893 source_location result;
1894 if (i == (int) set->info_ordinary.used - 1)
1895 result = set->highest_location;
1896 else
1897 result = set->info_ordinary.maps[i + 1].start_location - 1;
1899 *loc = result;
1900 return true;
1903 /* Compute and return statistics about the memory consumption of some
1904 parts of the line table SET. */
1906 void
1907 linemap_get_statistics (struct line_maps *set,
1908 struct linemap_stats *s)
1910 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1911 macro_maps_allocated_size, macro_maps_used_size,
1912 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1914 const line_map_macro *cur_map;
1916 ordinary_maps_allocated_size =
1917 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1919 ordinary_maps_used_size =
1920 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1922 macro_maps_allocated_size =
1923 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1925 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1926 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1927 ++cur_map)
1929 unsigned i;
1931 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1933 macro_maps_locations_size +=
1934 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1936 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1938 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1939 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1940 duplicated_macro_maps_locations_size +=
1941 sizeof (source_location);
1945 macro_maps_used_size =
1946 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1948 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1949 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1950 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1951 s->ordinary_maps_used_size = ordinary_maps_used_size;
1952 s->num_expanded_macros = num_expanded_macros_counter;
1953 s->num_macro_tokens = num_macro_tokens_counter;
1954 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1955 s->macro_maps_allocated_size = macro_maps_allocated_size;
1956 s->macro_maps_locations_size = macro_maps_locations_size;
1957 s->macro_maps_used_size = macro_maps_used_size;
1958 s->duplicated_macro_maps_locations_size =
1959 duplicated_macro_maps_locations_size;
1960 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1961 * sizeof (struct location_adhoc_data));
1962 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1966 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1967 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1968 specifies how many macro maps to dump. */
1970 void
1971 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1972 unsigned int num_macro)
1974 unsigned int i;
1976 if (set == NULL)
1977 return;
1979 if (stream == NULL)
1980 stream = stderr;
1982 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1983 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1984 fprintf (stream, "Include stack depth: %d\n", set->depth);
1985 fprintf (stream, "Highest location: %u\n", set->highest_location);
1987 if (num_ordinary)
1989 fprintf (stream, "\nOrdinary line maps\n");
1990 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
1991 linemap_dump (stream, set, i, false);
1992 fprintf (stream, "\n");
1995 if (num_macro)
1997 fprintf (stream, "\nMacro line maps\n");
1998 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
1999 linemap_dump (stream, set, i, true);
2000 fprintf (stream, "\n");
2004 /* class rich_location. */
2006 /* Construct a rich_location with location LOC as its initial range. */
2008 rich_location::rich_location (line_maps *set, source_location loc) :
2009 m_line_table (set),
2010 m_ranges (),
2011 m_column_override (0),
2012 m_have_expanded_location (false),
2013 m_fixit_hints (),
2014 m_seen_impossible_fixit (false),
2015 m_fixits_cannot_be_auto_applied (false)
2017 add_range (loc, true);
2020 /* The destructor for class rich_location. */
2022 rich_location::~rich_location ()
2024 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2025 delete get_fixit_hint (i);
2028 /* Get location IDX within this rich_location. */
2030 source_location
2031 rich_location::get_loc (unsigned int idx) const
2033 const location_range *locrange = get_range (idx);
2034 return locrange->m_loc;
2037 /* Get range IDX within this rich_location. */
2039 const location_range *
2040 rich_location::get_range (unsigned int idx) const
2042 return &m_ranges[idx];
2045 /* Mutable access to range IDX within this rich_location. */
2047 location_range *
2048 rich_location::get_range (unsigned int idx)
2050 return &m_ranges[idx];
2053 /* Expand location IDX within this rich_location. */
2054 /* Get an expanded_location for this rich_location's primary
2055 location. */
2057 expanded_location
2058 rich_location::get_expanded_location (unsigned int idx)
2060 if (idx == 0)
2062 /* Cache the expansion of the primary location. */
2063 if (!m_have_expanded_location)
2065 m_expanded_location
2066 = linemap_client_expand_location_to_spelling_point
2067 (get_loc (0), LOCATION_ASPECT_CARET);
2068 if (m_column_override)
2069 m_expanded_location.column = m_column_override;
2070 m_have_expanded_location = true;
2073 return m_expanded_location;
2075 else
2076 return linemap_client_expand_location_to_spelling_point
2077 (get_loc (idx), LOCATION_ASPECT_CARET);
2080 /* Set the column of the primary location, with 0 meaning
2081 "don't override it". */
2083 void
2084 rich_location::override_column (int column)
2086 m_column_override = column;
2087 m_have_expanded_location = false;
2090 /* Add the given range. */
2092 void
2093 rich_location::add_range (source_location loc, bool show_caret_p)
2095 location_range range;
2096 range.m_loc = loc;
2097 range.m_show_caret_p = show_caret_p;
2098 m_ranges.push (range);
2101 /* Add or overwrite the location given by IDX, setting its location to LOC,
2102 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2104 It must either overwrite an existing location, or add one *exactly* on
2105 the end of the array.
2107 This is primarily for use by gcc when implementing diagnostic format
2108 decoders e.g.
2109 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2110 (which writes the source location of a tree back into location 0 of
2111 the rich_location), and
2112 - the "%C" and "%L" format codes in the Fortran frontend. */
2114 void
2115 rich_location::set_range (line_maps * /*set*/, unsigned int idx,
2116 source_location loc, bool show_caret_p)
2118 /* We can either overwrite an existing range, or add one exactly
2119 on the end of the array. */
2120 linemap_assert (idx <= m_ranges.count ());
2122 if (idx == m_ranges.count ())
2123 add_range (loc, show_caret_p);
2124 else
2126 location_range *locrange = get_range (idx);
2127 locrange->m_loc = loc;
2128 locrange->m_show_caret_p = show_caret_p;
2131 if (idx == 0)
2132 /* Mark any cached value here as dirty. */
2133 m_have_expanded_location = false;
2136 /* Methods for adding insertion fix-it hints. */
2138 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2139 immediately before the primary range's start location. */
2141 void
2142 rich_location::add_fixit_insert_before (const char *new_content)
2144 add_fixit_insert_before (get_loc (), new_content);
2147 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2148 immediately before the start of WHERE. */
2150 void
2151 rich_location::add_fixit_insert_before (source_location where,
2152 const char *new_content)
2154 source_location start = get_range_from_loc (m_line_table, where).m_start;
2155 maybe_add_fixit (start, start, new_content);
2158 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2159 immediately after the primary range's end-point. */
2161 void
2162 rich_location::add_fixit_insert_after (const char *new_content)
2164 add_fixit_insert_after (get_loc (), new_content);
2167 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2168 immediately after the end-point of WHERE. */
2170 void
2171 rich_location::add_fixit_insert_after (source_location where,
2172 const char *new_content)
2174 source_location finish = get_range_from_loc (m_line_table, where).m_finish;
2175 source_location next_loc
2176 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2178 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2179 its input value. */
2180 if (next_loc == finish)
2182 stop_supporting_fixits ();
2183 return;
2186 maybe_add_fixit (next_loc, next_loc, new_content);
2189 /* Methods for adding removal fix-it hints. */
2191 /* Add a fixit-hint, suggesting removal of the content covered
2192 by range 0. */
2194 void
2195 rich_location::add_fixit_remove ()
2197 add_fixit_remove (get_loc ());
2200 /* Add a fixit-hint, suggesting removal of the content between
2201 the start and finish of WHERE. */
2203 void
2204 rich_location::add_fixit_remove (source_location where)
2206 source_range range = get_range_from_loc (m_line_table, where);
2207 add_fixit_remove (range);
2210 /* Add a fixit-hint, suggesting removal of the content at
2211 SRC_RANGE. */
2213 void
2214 rich_location::add_fixit_remove (source_range src_range)
2216 add_fixit_replace (src_range, "");
2219 /* Add a fixit-hint, suggesting replacement of the content covered
2220 by range 0 with NEW_CONTENT. */
2222 void
2223 rich_location::add_fixit_replace (const char *new_content)
2225 add_fixit_replace (get_loc (), new_content);
2228 /* Methods for adding "replace" fix-it hints. */
2230 /* Add a fixit-hint, suggesting replacement of the content between
2231 the start and finish of WHERE with NEW_CONTENT. */
2233 void
2234 rich_location::add_fixit_replace (source_location where,
2235 const char *new_content)
2237 source_range range = get_range_from_loc (m_line_table, where);
2238 add_fixit_replace (range, new_content);
2241 /* Add a fixit-hint, suggesting replacement of the content at
2242 SRC_RANGE with NEW_CONTENT. */
2244 void
2245 rich_location::add_fixit_replace (source_range src_range,
2246 const char *new_content)
2248 source_location start = get_pure_location (m_line_table, src_range.m_start);
2249 source_location finish = get_pure_location (m_line_table, src_range.m_finish);
2251 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2252 source_location next_loc
2253 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2254 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2255 its input value. */
2256 if (next_loc == finish)
2258 stop_supporting_fixits ();
2259 return;
2261 finish = next_loc;
2263 maybe_add_fixit (start, finish, new_content);
2266 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2268 fixit_hint *
2269 rich_location::get_last_fixit_hint () const
2271 if (m_fixit_hints.count () > 0)
2272 return get_fixit_hint (m_fixit_hints.count () - 1);
2273 else
2274 return NULL;
2277 /* If WHERE is an "awkward" location, then mark this rich_location as not
2278 supporting fixits, purging any thay were already added, and return true.
2280 Otherwise (the common case), return false. */
2282 bool
2283 rich_location::reject_impossible_fixit (source_location where)
2285 /* Fix-its within a rich_location should either all be suggested, or
2286 none of them should be suggested.
2287 Once we've rejected a fixit, we reject any more, even those
2288 with reasonable locations. */
2289 if (m_seen_impossible_fixit)
2290 return true;
2292 if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
2293 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2294 return false;
2296 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2297 location: either one that we can't obtain column information
2298 for (within an ordinary map), or one within a macro expansion. */
2299 stop_supporting_fixits ();
2300 return true;
2303 /* Mark this rich_location as not supporting fixits, purging any that were
2304 already added. */
2306 void
2307 rich_location::stop_supporting_fixits ()
2309 m_seen_impossible_fixit = true;
2311 /* Purge the rich_location of any fix-its that were already added. */
2312 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2313 delete get_fixit_hint (i);
2314 m_fixit_hints.truncate (0);
2317 /* Add HINT to the fix-it hints in this rich_location,
2318 consolidating into the prior fixit if possible. */
2320 void
2321 rich_location::maybe_add_fixit (source_location start,
2322 source_location next_loc,
2323 const char *new_content)
2325 if (reject_impossible_fixit (start))
2326 return;
2327 if (reject_impossible_fixit (next_loc))
2328 return;
2330 /* Only allow fix-it hints that affect a single line in one file.
2331 Compare the end-points. */
2332 expanded_location exploc_start
2333 = linemap_client_expand_location_to_spelling_point (start,
2334 LOCATION_ASPECT_START);
2335 expanded_location exploc_next_loc
2336 = linemap_client_expand_location_to_spelling_point (next_loc,
2337 LOCATION_ASPECT_START);
2338 /* They must be within the same file... */
2339 if (exploc_start.file != exploc_next_loc.file)
2341 stop_supporting_fixits ();
2342 return;
2344 /* ...and on the same line. */
2345 if (exploc_start.line != exploc_next_loc.line)
2347 stop_supporting_fixits ();
2348 return;
2350 /* The columns must be in the correct order. This can fail if the
2351 endpoints straddle the boundary for which the linemap can represent
2352 columns (PR c/82050). */
2353 if (exploc_start.column > exploc_next_loc.column)
2355 stop_supporting_fixits ();
2356 return;
2359 const char *newline = strchr (new_content, '\n');
2360 if (newline)
2362 /* For now, we can only support insertion of whole lines
2363 i.e. starts at start of line, and the newline is at the end of
2364 the insertion point. */
2366 /* It must be an insertion, not a replacement/deletion. */
2367 if (start != next_loc)
2369 stop_supporting_fixits ();
2370 return;
2373 /* The insertion must be at the start of a line. */
2374 if (exploc_start.column != 1)
2376 stop_supporting_fixits ();
2377 return;
2380 /* The newline must be at end of NEW_CONTENT.
2381 We could eventually split up fix-its at newlines if we wanted
2382 to allow more generality (e.g. to allow adding multiple lines
2383 with one add_fixit call. */
2384 if (newline[1] != '\0')
2386 stop_supporting_fixits ();
2387 return;
2391 /* Consolidate neighboring fixits.
2392 Don't consolidate into newline-insertion fixits. */
2393 fixit_hint *prev = get_last_fixit_hint ();
2394 if (prev && !prev->ends_with_newline_p ())
2395 if (prev->maybe_append (start, next_loc, new_content))
2396 return;
2398 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
2401 /* class fixit_hint. */
2403 fixit_hint::fixit_hint (source_location start,
2404 source_location next_loc,
2405 const char *new_content)
2406 : m_start (start),
2407 m_next_loc (next_loc),
2408 m_bytes (xstrdup (new_content)),
2409 m_len (strlen (new_content))
2413 /* Does this fix-it hint affect the given line? */
2415 bool
2416 fixit_hint::affects_line_p (const char *file, int line) const
2418 expanded_location exploc_start
2419 = linemap_client_expand_location_to_spelling_point (m_start,
2420 LOCATION_ASPECT_START);
2421 if (file != exploc_start.file)
2422 return false;
2423 if (line < exploc_start.line)
2424 return false;
2425 expanded_location exploc_next_loc
2426 = linemap_client_expand_location_to_spelling_point (m_next_loc,
2427 LOCATION_ASPECT_START);
2428 if (file != exploc_next_loc.file)
2429 return false;
2430 if (line > exploc_next_loc.line)
2431 return false;
2432 return true;
2435 /* Method for consolidating fix-it hints, for use by
2436 rich_location::maybe_add_fixit.
2437 If possible, merge a pending fix-it hint with the given params
2438 into this one and return true.
2439 Otherwise return false. */
2441 bool
2442 fixit_hint::maybe_append (source_location start,
2443 source_location next_loc,
2444 const char *new_content)
2446 /* For consolidation to be possible, START must be at this hint's
2447 m_next_loc. */
2448 if (start != m_next_loc)
2449 return false;
2451 /* If so, we have neighboring replacements; merge them. */
2452 m_next_loc = next_loc;
2453 size_t extra_len = strlen (new_content);
2454 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2455 memcpy (m_bytes + m_len, new_content, extra_len);
2456 m_len += extra_len;
2457 m_bytes[m_len] = '\0';
2458 return true;
2461 /* Return true iff this hint's content ends with a newline. */
2463 bool
2464 fixit_hint::ends_with_newline_p () const
2466 if (m_len == 0)
2467 return false;
2468 return m_bytes[m_len - 1] == '\n';