PR c++/80560 - warn on undefined memory operations involving non-trivial types
[official-gcc.git] / libcpp / line-map.c
blob694137a736043b4029dd3be8fcb2d47beb0035cd
1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2017 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 /* Do not track column numbers higher than this one. As a result, the
30 range of column_bits is [12, 18] (or 0 if column numbers are
31 disabled). */
32 const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12);
34 /* Highest possible source location encoded within an ordinary or
35 macro map. */
36 const source_location LINE_MAP_MAX_SOURCE_LOCATION = 0x70000000;
38 static void trace_include (const struct line_maps *, const line_map_ordinary *);
39 static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
40 source_location);
41 static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
42 source_location);
43 static source_location linemap_macro_map_loc_to_def_point
44 (const line_map_macro *, source_location);
45 static source_location linemap_macro_map_loc_to_exp_point
46 (const line_map_macro *, source_location);
47 static source_location linemap_macro_loc_to_spelling_point
48 (struct line_maps *, source_location, const line_map_ordinary **);
49 static source_location linemap_macro_loc_to_def_point (struct line_maps *,
50 source_location,
51 const line_map_ordinary **);
52 static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
53 source_location,
54 const line_map_ordinary **);
56 /* Counters defined in macro.c. */
57 extern unsigned num_expanded_macros_counter;
58 extern unsigned num_macro_tokens_counter;
60 /* Destructor for class line_maps.
61 Ensure non-GC-managed memory is released. */
63 line_maps::~line_maps ()
65 if (location_adhoc_data_map.htab)
66 htab_delete (location_adhoc_data_map.htab);
69 /* Hash function for location_adhoc_data hashtable. */
71 static hashval_t
72 location_adhoc_data_hash (const void *l)
74 const struct location_adhoc_data *lb =
75 (const struct location_adhoc_data *) l;
76 return ((hashval_t) lb->locus
77 + (hashval_t) lb->src_range.m_start
78 + (hashval_t) lb->src_range.m_finish
79 + (size_t) lb->data);
82 /* Compare function for location_adhoc_data hashtable. */
84 static int
85 location_adhoc_data_eq (const void *l1, const void *l2)
87 const struct location_adhoc_data *lb1 =
88 (const struct location_adhoc_data *) l1;
89 const struct location_adhoc_data *lb2 =
90 (const struct location_adhoc_data *) l2;
91 return (lb1->locus == lb2->locus
92 && lb1->src_range.m_start == lb2->src_range.m_start
93 && lb1->src_range.m_finish == lb2->src_range.m_finish
94 && lb1->data == lb2->data);
97 /* Update the hashtable when location_adhoc_data is reallocated. */
99 static int
100 location_adhoc_data_update (void **slot, void *data)
102 *((char **) slot) += *((int64_t *) data);
103 return 1;
106 /* Rebuild the hash table from the location adhoc data. */
108 void
109 rebuild_location_adhoc_htab (struct line_maps *set)
111 unsigned i;
112 set->location_adhoc_data_map.htab =
113 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
114 for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
115 htab_find_slot (set->location_adhoc_data_map.htab,
116 set->location_adhoc_data_map.data + i, INSERT);
119 /* Helper function for get_combined_adhoc_loc.
120 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
121 within a source_location, without needing to use an ad-hoc location. */
123 static bool
124 can_be_stored_compactly_p (struct line_maps *set,
125 source_location locus,
126 source_range src_range,
127 void *data)
129 /* If there's an ad-hoc pointer, we can't store it directly in the
130 source_location, we need the lookaside. */
131 if (data)
132 return false;
134 /* We only store ranges that begin at the locus and that are sufficiently
135 "sane". */
136 if (src_range.m_start != locus)
137 return false;
139 if (src_range.m_finish < src_range.m_start)
140 return false;
142 if (src_range.m_start < RESERVED_LOCATION_COUNT)
143 return false;
145 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
146 return false;
148 /* All 3 locations must be within ordinary maps, typically, the same
149 ordinary map. */
150 source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
151 if (locus >= lowest_macro_loc)
152 return false;
153 if (src_range.m_start >= lowest_macro_loc)
154 return false;
155 if (src_range.m_finish >= lowest_macro_loc)
156 return false;
158 /* Passed all tests. */
159 return true;
162 /* Combine LOCUS and DATA to a combined adhoc loc. */
164 source_location
165 get_combined_adhoc_loc (struct line_maps *set,
166 source_location locus,
167 source_range src_range,
168 void *data)
170 struct location_adhoc_data lb;
171 struct location_adhoc_data **slot;
173 if (IS_ADHOC_LOC (locus))
174 locus
175 = set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
176 if (locus == 0 && data == NULL)
177 return 0;
179 /* Any ordinary locations ought to be "pure" at this point: no
180 compressed ranges. */
181 linemap_assert (locus < RESERVED_LOCATION_COUNT
182 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
183 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
184 || pure_location_p (set, locus));
186 /* Consider short-range optimization. */
187 if (can_be_stored_compactly_p (set, locus, src_range, data))
189 /* The low bits ought to be clear. */
190 linemap_assert (pure_location_p (set, locus));
191 const line_map *map = linemap_lookup (set, locus);
192 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
193 unsigned int int_diff = src_range.m_finish - src_range.m_start;
194 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
195 if (col_diff < (1U << ordmap->m_range_bits))
197 source_location packed = locus | col_diff;
198 set->num_optimized_ranges++;
199 return packed;
203 /* We can also compactly store locations
204 when locus == start == finish (and data is NULL). */
205 if (locus == src_range.m_start
206 && locus == src_range.m_finish
207 && !data)
208 return locus;
210 if (!data)
211 set->num_unoptimized_ranges++;
213 lb.locus = locus;
214 lb.src_range = src_range;
215 lb.data = data;
216 slot = (struct location_adhoc_data **)
217 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
218 if (*slot == NULL)
220 if (set->location_adhoc_data_map.curr_loc >=
221 set->location_adhoc_data_map.allocated)
223 char *orig_data = (char *) set->location_adhoc_data_map.data;
224 int64_t offset;
225 /* Cast away extern "C" from the type of xrealloc. */
226 line_map_realloc reallocator = (set->reallocator
227 ? set->reallocator
228 : (line_map_realloc) xrealloc);
230 if (set->location_adhoc_data_map.allocated == 0)
231 set->location_adhoc_data_map.allocated = 128;
232 else
233 set->location_adhoc_data_map.allocated *= 2;
234 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
235 reallocator (set->location_adhoc_data_map.data,
236 set->location_adhoc_data_map.allocated
237 * sizeof (struct location_adhoc_data));
238 offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
239 if (set->location_adhoc_data_map.allocated > 128)
240 htab_traverse (set->location_adhoc_data_map.htab,
241 location_adhoc_data_update, &offset);
243 *slot = set->location_adhoc_data_map.data
244 + set->location_adhoc_data_map.curr_loc;
245 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
246 = lb;
248 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
251 /* Return the data for the adhoc loc. */
253 void *
254 get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
256 linemap_assert (IS_ADHOC_LOC (loc));
257 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
260 /* Return the location for the adhoc loc. */
262 source_location
263 get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
265 linemap_assert (IS_ADHOC_LOC (loc));
266 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
269 /* Return the source_range for adhoc location LOC. */
271 static source_range
272 get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
274 linemap_assert (IS_ADHOC_LOC (loc));
275 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
278 /* Get the source_range of location LOC, either from the ad-hoc
279 lookaside table, or embedded inside LOC itself. */
281 source_range
282 get_range_from_loc (struct line_maps *set,
283 source_location loc)
285 if (IS_ADHOC_LOC (loc))
286 return get_range_from_adhoc_loc (set, loc);
288 /* For ordinary maps, extract packed range. */
289 if (loc >= RESERVED_LOCATION_COUNT
290 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
291 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
293 const line_map *map = linemap_lookup (set, loc);
294 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
295 source_range result;
296 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
297 result.m_start = loc - offset;
298 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
299 return result;
302 return source_range::from_location (loc);
305 /* Get whether location LOC is a "pure" location, or
306 whether it is an ad-hoc location, or embeds range information. */
308 bool
309 pure_location_p (line_maps *set, source_location loc)
311 if (IS_ADHOC_LOC (loc))
312 return false;
314 const line_map *map = linemap_lookup (set, loc);
315 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
317 if (loc & ((1U << ordmap->m_range_bits) - 1))
318 return false;
320 return true;
323 /* Given location LOC within SET, strip away any packed range information
324 or ad-hoc information. */
326 source_location
327 get_pure_location (line_maps *set, source_location loc)
329 if (IS_ADHOC_LOC (loc))
331 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
333 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
334 return loc;
336 if (loc < RESERVED_LOCATION_COUNT)
337 return loc;
339 const line_map *map = linemap_lookup (set, loc);
340 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
342 return loc & ~((1 << ordmap->m_range_bits) - 1);
345 /* Initialize a line map set. */
347 void
348 linemap_init (struct line_maps *set,
349 source_location builtin_location)
351 *set = line_maps ();
352 set->highest_location = RESERVED_LOCATION_COUNT - 1;
353 set->highest_line = RESERVED_LOCATION_COUNT - 1;
354 set->location_adhoc_data_map.htab =
355 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
356 set->builtin_location = builtin_location;
359 /* Check for and warn about line_maps entered but not exited. */
361 void
362 linemap_check_files_exited (struct line_maps *set)
364 const line_map_ordinary *map;
365 /* Depending upon whether we are handling preprocessed input or
366 not, this can be a user error or an ICE. */
367 for (map = LINEMAPS_LAST_ORDINARY_MAP (set);
368 ! MAIN_FILE_P (map);
369 map = INCLUDED_FROM (set, map))
370 fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
371 ORDINARY_MAP_FILE_NAME (map));
374 /* Create a new line map in the line map set SET, and return it.
375 REASON is the reason of creating the map. It determines the type
376 of map created (ordinary or macro map). Note that ordinary maps and
377 macro maps are allocated in different memory location. */
379 static struct line_map *
380 new_linemap (struct line_maps *set,
381 enum lc_reason reason)
383 /* Depending on this variable, a macro map would be allocated in a
384 different memory location than an ordinary map. */
385 bool macro_map_p = (reason == LC_ENTER_MACRO);
386 struct line_map *result;
388 if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
390 /* We ran out of allocated line maps. Let's allocate more. */
391 size_t alloc_size;
393 /* Cast away extern "C" from the type of xrealloc. */
394 line_map_realloc reallocator = (set->reallocator
395 ? set->reallocator
396 : (line_map_realloc) xrealloc);
397 line_map_round_alloc_size_func round_alloc_size =
398 set->round_alloc_size;
400 size_t map_size = (macro_map_p
401 ? sizeof (line_map_macro)
402 : sizeof (line_map_ordinary));
404 /* We are going to execute some dance to try to reduce the
405 overhead of the memory allocator, in case we are using the
406 ggc-page.c one.
408 The actual size of memory we are going to get back from the
409 allocator is the smallest power of 2 that is greater than the
410 size we requested. So let's consider that size then. */
412 alloc_size =
413 (2 * LINEMAPS_ALLOCATED (set, macro_map_p) + 256)
414 * map_size;
416 /* Get the actual size of memory that is going to be allocated
417 by the allocator. */
418 alloc_size = round_alloc_size (alloc_size);
420 /* Now alloc_size contains the exact memory size we would get if
421 we have asked for the initial alloc_size amount of memory.
422 Let's get back to the number of macro map that amounts
423 to. */
424 LINEMAPS_ALLOCATED (set, macro_map_p) =
425 alloc_size / map_size;
427 /* And now let's really do the re-allocation. */
428 if (macro_map_p)
430 set->info_macro.maps
431 = (line_map_macro *) (*reallocator) (set->info_macro.maps,
432 (LINEMAPS_ALLOCATED (set, macro_map_p)
433 * map_size));
434 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
436 else
438 set->info_ordinary.maps =
439 (line_map_ordinary *) (*reallocator) (set->info_ordinary.maps,
440 (LINEMAPS_ALLOCATED (set, macro_map_p)
441 * map_size));
442 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
444 memset (result, 0,
445 ((LINEMAPS_ALLOCATED (set, macro_map_p)
446 - LINEMAPS_USED (set, macro_map_p))
447 * map_size));
449 else
451 if (macro_map_p)
452 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
453 else
454 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
457 LINEMAPS_USED (set, macro_map_p)++;
459 result->reason = reason;
460 return result;
463 /* Add a mapping of logical source line to physical source file and
464 line number.
466 The text pointed to by TO_FILE must have a lifetime
467 at least as long as the final call to lookup_line (). An empty
468 TO_FILE means standard input. If reason is LC_LEAVE, and
469 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
470 natural values considering the file we are returning to.
472 FROM_LINE should be monotonic increasing across calls to this
473 function. A call to this function can relocate the previous set of
474 maps, so any stored line_map pointers should not be used. */
476 const struct line_map *
477 linemap_add (struct line_maps *set, enum lc_reason reason,
478 unsigned int sysp, const char *to_file, linenum_type to_line)
480 /* Generate a start_location above the current highest_location.
481 If possible, make the low range bits be zero. */
482 source_location start_location;
483 if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
485 start_location = set->highest_location + (1 << set->default_range_bits);
486 if (set->default_range_bits)
487 start_location &= ~((1 << set->default_range_bits) - 1);
488 linemap_assert (0 == (start_location
489 & ((1 << set->default_range_bits) - 1)));
491 else
492 start_location = set->highest_location + 1;
494 linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
495 && (start_location
496 < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));
498 /* When we enter the file for the first time reason cannot be
499 LC_RENAME. */
500 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
502 /* If we are leaving the main file, return a NULL map. */
503 if (reason == LC_LEAVE
504 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
505 && to_file == NULL)
507 set->depth--;
508 return NULL;
511 linemap_assert (reason != LC_ENTER_MACRO);
512 line_map_ordinary *map = linemap_check_ordinary (new_linemap (set, reason));
514 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
515 to_file = "<stdin>";
517 if (reason == LC_RENAME_VERBATIM)
518 reason = LC_RENAME;
520 if (reason == LC_LEAVE)
522 /* When we are just leaving an "included" file, and jump to the next
523 location inside the "includer" right after the #include
524 "included", this variable points the map in use right before the
525 #include "included", inside the same "includer" file. */
526 line_map_ordinary *from;
528 linemap_assert (!MAIN_FILE_P (map - 1));
529 /* (MAP - 1) points to the map we are leaving. The
530 map from which (MAP - 1) got included should be the map
531 that comes right before MAP in the same file. */
532 from = INCLUDED_FROM (set, map - 1);
534 /* A TO_FILE of NULL is special - we use the natural values. */
535 if (to_file == NULL)
537 to_file = ORDINARY_MAP_FILE_NAME (from);
538 to_line = SOURCE_LINE (from, from[1].start_location);
539 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
541 else
542 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
543 to_file) == 0);
546 map->sysp = sysp;
547 map->start_location = start_location;
548 map->to_file = to_file;
549 map->to_line = to_line;
550 LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
551 map->m_column_and_range_bits = 0;
552 map->m_range_bits = 0;
553 set->highest_location = start_location;
554 set->highest_line = start_location;
555 set->max_column_hint = 0;
557 /* This assertion is placed after set->highest_location has
558 been updated, since the latter affects
559 linemap_location_from_macro_expansion_p, which ultimately affects
560 pure_location_p. */
561 linemap_assert (pure_location_p (set, start_location));
563 if (reason == LC_ENTER)
565 map->included_from =
566 set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
567 set->depth++;
568 if (set->trace_includes)
569 trace_include (set, map);
571 else if (reason == LC_RENAME)
572 map->included_from = ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
573 else if (reason == LC_LEAVE)
575 set->depth--;
576 map->included_from =
577 ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
580 return map;
583 /* Returns TRUE if the line table set tracks token locations across
584 macro expansion, FALSE otherwise. */
586 bool
587 linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
589 return LINEMAPS_MACRO_MAPS (set) != NULL;
592 /* Create a macro map. A macro map encodes source locations of tokens
593 that are part of a macro replacement-list, at a macro expansion
594 point. See the extensive comments of struct line_map and struct
595 line_map_macro, in line-map.h.
597 This map shall be created when the macro is expanded. The map
598 encodes the source location of the expansion point of the macro as
599 well as the "original" source location of each token that is part
600 of the macro replacement-list. If a macro is defined but never
601 expanded, it has no macro map. SET is the set of maps the macro
602 map should be part of. MACRO_NODE is the macro which the new macro
603 map should encode source locations for. EXPANSION is the location
604 of the expansion point of MACRO. For function-like macros
605 invocations, it's best to make it point to the closing parenthesis
606 of the macro, rather than the the location of the first character
607 of the macro. NUM_TOKENS is the number of tokens that are part of
608 the replacement-list of MACRO.
610 Note that when we run out of the integer space available for source
611 locations, this function returns NULL. In that case, callers of
612 this function cannot encode {line,column} pairs into locations of
613 macro tokens anymore. */
615 const line_map_macro *
616 linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
617 source_location expansion, unsigned int num_tokens)
619 line_map_macro *map;
620 source_location start_location;
621 /* Cast away extern "C" from the type of xrealloc. */
622 line_map_realloc reallocator = (set->reallocator
623 ? set->reallocator
624 : (line_map_realloc) xrealloc);
626 start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
628 if (start_location <= set->highest_line
629 || start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
630 /* We ran out of macro map space. */
631 return NULL;
633 map = linemap_check_macro (new_linemap (set, LC_ENTER_MACRO));
635 map->start_location = start_location;
636 map->macro = macro_node;
637 map->n_tokens = num_tokens;
638 map->macro_locations
639 = (source_location*) reallocator (NULL,
640 2 * num_tokens
641 * sizeof (source_location));
642 map->expansion = expansion;
643 memset (MACRO_MAP_LOCATIONS (map), 0,
644 num_tokens * sizeof (source_location));
646 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
648 return map;
651 /* Create and return a virtual location for a token that is part of a
652 macro expansion-list at a macro expansion point. See the comment
653 inside struct line_map_macro to see what an expansion-list exactly
656 A call to this function must come after a call to
657 linemap_enter_macro.
659 MAP is the map into which the source location is created. TOKEN_NO
660 is the index of the token in the macro replacement-list, starting
661 at number 0.
663 ORIG_LOC is the location of the token outside of this macro
664 expansion. If the token comes originally from the macro
665 definition, it is the locus in the macro definition; otherwise it
666 is a location in the context of the caller of this macro expansion
667 (which is a virtual location or a source location if the caller is
668 itself a macro expansion or not).
670 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
671 either of the token itself or of a macro parameter that it
672 replaces. */
674 source_location
675 linemap_add_macro_token (const line_map_macro *map,
676 unsigned int token_no,
677 source_location orig_loc,
678 source_location orig_parm_replacement_loc)
680 source_location result;
682 linemap_assert (linemap_macro_expansion_map_p (map));
683 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
685 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
686 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
688 result = MAP_START_LOCATION (map) + token_no;
689 return result;
692 /* Return a source_location for the start (i.e. column==0) of
693 (physical) line TO_LINE in the current source file (as in the
694 most recent linemap_add). MAX_COLUMN_HINT is the highest column
695 number we expect to use in this line (but it does not change
696 the highest_location). */
698 source_location
699 linemap_line_start (struct line_maps *set, linenum_type to_line,
700 unsigned int max_column_hint)
702 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
703 source_location highest = set->highest_location;
704 source_location r;
705 linenum_type last_line =
706 SOURCE_LINE (map, set->highest_line);
707 int line_delta = to_line - last_line;
708 bool add_map = false;
709 linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
710 int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
712 if (line_delta < 0
713 || (line_delta > 10
714 && line_delta * map->m_column_and_range_bits > 1000)
715 || (max_column_hint >= (1U << effective_column_bits))
716 || (max_column_hint <= 80 && effective_column_bits >= 10)
717 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
718 && map->m_range_bits > 0)
719 || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
720 && (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
721 add_map = true;
722 else
723 max_column_hint = set->max_column_hint;
724 if (add_map)
726 int column_bits;
727 int range_bits;
728 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
729 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
731 /* If the column number is ridiculous or we've allocated a huge
732 number of source_locations, give up on column numbers
733 (and on packed ranges). */
734 max_column_hint = 0;
735 column_bits = 0;
736 range_bits = 0;
737 if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
738 return 0;
740 else
742 column_bits = 7;
743 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
744 range_bits = set->default_range_bits;
745 else
746 range_bits = 0;
747 while (max_column_hint >= (1U << column_bits))
748 column_bits++;
749 max_column_hint = 1U << column_bits;
750 column_bits += range_bits;
752 /* Allocate the new line_map. However, if the current map only has a
753 single line we can sometimes just increase its column_bits instead. */
754 if (line_delta < 0
755 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
756 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
757 || range_bits < map->m_range_bits)
758 map = linemap_check_ordinary
759 (const_cast <line_map *>
760 (linemap_add (set, LC_RENAME,
761 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
762 ORDINARY_MAP_FILE_NAME (map),
763 to_line)));
764 map->m_column_and_range_bits = column_bits;
765 map->m_range_bits = range_bits;
766 r = (MAP_START_LOCATION (map)
767 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
768 << column_bits));
770 else
771 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
773 /* Locations of ordinary tokens are always lower than locations of
774 macro tokens. */
775 if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
776 return 0;
778 set->highest_line = r;
779 if (r > set->highest_location)
780 set->highest_location = r;
781 set->max_column_hint = max_column_hint;
783 /* At this point, we expect one of:
784 (a) the normal case: a "pure" location with 0 range bits, or
785 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
786 columns anymore (or ranges), or
787 (c) we're in a region with a column hint exceeding
788 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
789 with column_bits == 0. */
790 linemap_assert (pure_location_p (set, r)
791 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
792 || map->m_column_and_range_bits == 0);
793 linemap_assert (SOURCE_LINE (map, r) == to_line);
794 return r;
797 /* Encode and return a source_location from a column number. The
798 source line considered is the last source line used to call
799 linemap_line_start, i.e, the last source line which a location was
800 encoded from. */
802 source_location
803 linemap_position_for_column (struct line_maps *set, unsigned int to_column)
805 source_location r = set->highest_line;
807 linemap_assert
808 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
810 if (to_column >= set->max_column_hint)
812 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
813 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
815 /* Running low on source_locations - disable column numbers. */
816 return r;
818 else
820 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
821 with some space to spare. This may or may not lead to a new
822 linemap being created. */
823 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
824 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
825 map = LINEMAPS_LAST_ORDINARY_MAP (set);
826 if (map->m_column_and_range_bits == 0)
828 /* ...then the linemap has column-tracking disabled,
829 presumably due to exceeding either
830 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
831 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
832 Return the start of the linemap, which encodes column 0, for
833 the whole line. */
834 return r;
838 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
839 r = r + (to_column << map->m_range_bits);
840 if (r >= set->highest_location)
841 set->highest_location = r;
842 return r;
845 /* Encode and return a source location from a given line and
846 column. */
848 source_location
849 linemap_position_for_line_and_column (line_maps *set,
850 const line_map_ordinary *ord_map,
851 linenum_type line,
852 unsigned column)
854 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
856 source_location r = MAP_START_LOCATION (ord_map);
857 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
858 << ord_map->m_column_and_range_bits);
859 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
860 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
861 << ord_map->m_range_bits);
862 source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
863 if (r >= upper_limit)
864 r = upper_limit - 1;
865 if (r > set->highest_location)
866 set->highest_location = r;
867 return r;
870 /* Encode and return a source_location starting from location LOC and
871 shifting it by COLUMN_OFFSET columns. This function does not support
872 virtual locations. */
874 source_location
875 linemap_position_for_loc_and_offset (struct line_maps *set,
876 source_location loc,
877 unsigned int column_offset)
879 const line_map_ordinary * map = NULL;
881 if (IS_ADHOC_LOC (loc))
882 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
884 /* This function does not support virtual locations yet. */
885 if (linemap_location_from_macro_expansion_p (set, loc))
886 return loc;
888 if (column_offset == 0
889 /* Adding an offset to a reserved location (like
890 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
891 sense. So let's leave the location intact in that case. */
892 || loc < RESERVED_LOCATION_COUNT)
893 return loc;
895 /* We find the real location and shift it. */
896 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
897 /* The new location (loc + offset) should be higher than the first
898 location encoded by MAP. This can fail if the line information
899 is messed up because of line directives (see PR66415). */
900 if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
901 return loc;
903 linenum_type line = SOURCE_LINE (map, loc);
904 unsigned int column = SOURCE_COLUMN (map, loc);
906 /* If MAP is not the last line map of its set, then the new location
907 (loc + offset) should be less than the first location encoded by
908 the next line map of the set. Otherwise, we try to encode the
909 location in the next map. */
910 while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
911 && (loc + (column_offset << map->m_range_bits)
912 >= MAP_START_LOCATION (&map[1])))
914 map = &map[1];
915 /* If the next map starts in a higher line, we cannot encode the
916 location there. */
917 if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
918 return loc;
921 column += column_offset;
923 /* Bail out if the column is not representable within the existing
924 linemap. */
925 if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
926 return loc;
928 source_location r =
929 linemap_position_for_line_and_column (set, map, line, column);
930 if (linemap_assert_fails (r <= set->highest_location)
931 || linemap_assert_fails (map == linemap_lookup (set, r)))
932 return loc;
934 return r;
937 /* Given a virtual source location yielded by a map (either an
938 ordinary or a macro map), returns that map. */
940 const struct line_map*
941 linemap_lookup (struct line_maps *set, source_location line)
943 if (IS_ADHOC_LOC (line))
944 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
945 if (linemap_location_from_macro_expansion_p (set, line))
946 return linemap_macro_map_lookup (set, line);
947 return linemap_ordinary_map_lookup (set, line);
950 /* Given a source location yielded by an ordinary map, returns that
951 map. Since the set is built chronologically, the logical lines are
952 monotonic increasing, and so the list is sorted and we can use a
953 binary search. */
955 static const line_map_ordinary *
956 linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
958 unsigned int md, mn, mx;
959 const line_map_ordinary *cached, *result;
961 if (IS_ADHOC_LOC (line))
962 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
964 if (set == NULL || line < RESERVED_LOCATION_COUNT)
965 return NULL;
967 mn = LINEMAPS_ORDINARY_CACHE (set);
968 mx = LINEMAPS_ORDINARY_USED (set);
970 cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
971 /* We should get a segfault if no line_maps have been added yet. */
972 if (line >= MAP_START_LOCATION (cached))
974 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
975 return cached;
977 else
979 mx = mn;
980 mn = 0;
983 while (mx - mn > 1)
985 md = (mn + mx) / 2;
986 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
987 mx = md;
988 else
989 mn = md;
992 LINEMAPS_ORDINARY_CACHE (set) = mn;
993 result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
994 linemap_assert (line >= MAP_START_LOCATION (result));
995 return result;
998 /* Given a source location yielded by a macro map, returns that map.
999 Since the set is built chronologically, the logical lines are
1000 monotonic decreasing, and so the list is sorted and we can use a
1001 binary search. */
1003 static const line_map_macro *
1004 linemap_macro_map_lookup (struct line_maps *set, source_location line)
1006 unsigned int md, mn, mx;
1007 const struct line_map_macro *cached, *result;
1009 if (IS_ADHOC_LOC (line))
1010 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
1012 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1014 if (set == NULL)
1015 return NULL;
1017 mn = LINEMAPS_MACRO_CACHE (set);
1018 mx = LINEMAPS_MACRO_USED (set);
1019 cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1021 if (line >= MAP_START_LOCATION (cached))
1023 if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
1024 return cached;
1025 mx = mn - 1;
1026 mn = 0;
1029 while (mn < mx)
1031 md = (mx + mn) / 2;
1032 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1033 mn = md + 1;
1034 else
1035 mx = md;
1038 LINEMAPS_MACRO_CACHE (set) = mx;
1039 result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
1040 linemap_assert (MAP_START_LOCATION (result) <= line);
1042 return result;
1045 /* Return TRUE if MAP encodes locations coming from a macro
1046 replacement-list at macro expansion point. */
1048 bool
1049 linemap_macro_expansion_map_p (const struct line_map *map)
1051 if (!map)
1052 return false;
1053 return (map->reason == LC_ENTER_MACRO);
1056 /* If LOCATION is the locus of a token in a replacement-list of a
1057 macro expansion return the location of the macro expansion point.
1059 Read the comments of struct line_map and struct line_map_macro in
1060 line-map.h to understand what a macro expansion point is. */
1062 static source_location
1063 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1064 source_location location ATTRIBUTE_UNUSED)
1066 linemap_assert (linemap_macro_expansion_map_p (map)
1067 && location >= MAP_START_LOCATION (map));
1069 /* Make sure LOCATION is correct. */
1070 linemap_assert ((location - MAP_START_LOCATION (map))
1071 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1073 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1076 /* LOCATION is the source location of a token that belongs to a macro
1077 replacement-list as part of the macro expansion denoted by MAP.
1079 Return the location of the token at the definition point of the
1080 macro. */
1082 static source_location
1083 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1084 source_location location)
1086 unsigned token_no;
1088 linemap_assert (linemap_macro_expansion_map_p (map)
1089 && location >= MAP_START_LOCATION (map));
1090 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1092 token_no = location - MAP_START_LOCATION (map);
1093 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1095 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1097 return location;
1100 /* If LOCATION is the locus of a token that is an argument of a
1101 function-like macro M and appears in the expansion of M, return the
1102 locus of that argument in the context of the caller of M.
1104 In other words, this returns the xI location presented in the
1105 comments of line_map_macro above. */
1106 source_location
1107 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1108 const line_map_macro* map,
1109 source_location location)
1111 unsigned token_no;
1113 if (IS_ADHOC_LOC (location))
1114 location = get_location_from_adhoc_loc (set, location);
1116 linemap_assert (linemap_macro_expansion_map_p (map)
1117 && location >= MAP_START_LOCATION (map));
1118 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1119 linemap_assert (!IS_ADHOC_LOC (location));
1121 token_no = location - MAP_START_LOCATION (map);
1122 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1124 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1126 return location;
1129 /* Return the source line number corresponding to source location
1130 LOCATION. SET is the line map set LOCATION comes from. If
1131 LOCATION is the source location of token that is part of the
1132 replacement-list of a macro expansion return the line number of the
1133 macro expansion point. */
1136 linemap_get_expansion_line (struct line_maps *set,
1137 source_location location)
1139 const line_map_ordinary *map = NULL;
1141 if (IS_ADHOC_LOC (location))
1142 location = set->location_adhoc_data_map.data[location
1143 & MAX_SOURCE_LOCATION].locus;
1145 if (location < RESERVED_LOCATION_COUNT)
1146 return 0;
1148 location =
1149 linemap_macro_loc_to_exp_point (set, location, &map);
1151 return SOURCE_LINE (map, location);
1154 /* Return the path of the file corresponding to source code location
1155 LOCATION.
1157 If LOCATION is the source location of token that is part of the
1158 replacement-list of a macro expansion return the file path of the
1159 macro expansion point.
1161 SET is the line map set LOCATION comes from. */
1163 const char*
1164 linemap_get_expansion_filename (struct line_maps *set,
1165 source_location location)
1167 const struct line_map_ordinary *map = NULL;
1169 if (IS_ADHOC_LOC (location))
1170 location = set->location_adhoc_data_map.data[location
1171 & MAX_SOURCE_LOCATION].locus;
1173 if (location < RESERVED_LOCATION_COUNT)
1174 return NULL;
1176 location =
1177 linemap_macro_loc_to_exp_point (set, location, &map);
1179 return LINEMAP_FILE (map);
1182 /* Return the name of the macro associated to MACRO_MAP. */
1184 const char*
1185 linemap_map_get_macro_name (const line_map_macro *macro_map)
1187 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1188 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1191 /* Return a positive value if LOCATION is the locus of a token that is
1192 located in a system header, O otherwise. It returns 1 if LOCATION
1193 is the locus of a token that is located in a system header, and 2
1194 if LOCATION is the locus of a token located in a C system header
1195 that therefore needs to be extern "C" protected in C++.
1197 Note that this function returns 1 if LOCATION belongs to a token
1198 that is part of a macro replacement-list defined in a system
1199 header, but expanded in a non-system file. */
1202 linemap_location_in_system_header_p (struct line_maps *set,
1203 source_location location)
1205 const struct line_map *map = NULL;
1207 if (IS_ADHOC_LOC (location))
1208 location = set->location_adhoc_data_map.data[location
1209 & MAX_SOURCE_LOCATION].locus;
1211 if (location < RESERVED_LOCATION_COUNT)
1212 return false;
1214 /* Let's look at where the token for LOCATION comes from. */
1215 while (true)
1217 map = linemap_lookup (set, location);
1218 if (map != NULL)
1220 if (!linemap_macro_expansion_map_p (map))
1221 /* It's a normal token. */
1222 return LINEMAP_SYSP (linemap_check_ordinary (map));
1223 else
1225 const line_map_macro *macro_map = linemap_check_macro (map);
1227 /* It's a token resulting from a macro expansion. */
1228 source_location loc =
1229 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1230 if (loc < RESERVED_LOCATION_COUNT)
1231 /* This token might come from a built-in macro. Let's
1232 look at where that macro got expanded. */
1233 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1234 else
1235 location = loc;
1238 else
1239 break;
1241 return false;
1244 /* Return TRUE if LOCATION is a source code location of a token that is part of
1245 a macro expansion, FALSE otherwise. */
1247 bool
1248 linemap_location_from_macro_expansion_p (const struct line_maps *set,
1249 source_location location)
1251 if (IS_ADHOC_LOC (location))
1252 location = set->location_adhoc_data_map.data[location
1253 & MAX_SOURCE_LOCATION].locus;
1255 linemap_assert (location <= MAX_SOURCE_LOCATION
1256 && (set->highest_location
1257 < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
1258 if (set == NULL)
1259 return false;
1260 return (location > set->highest_location);
1263 /* Given two virtual locations *LOC0 and *LOC1, return the first
1264 common macro map in their macro expansion histories. Return NULL
1265 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1266 virtual location of the token inside the resulting macro. */
1268 static const struct line_map*
1269 first_map_in_common_1 (struct line_maps *set,
1270 source_location *loc0,
1271 source_location *loc1)
1273 source_location l0 = *loc0, l1 = *loc1;
1274 const struct line_map *map0 = linemap_lookup (set, l0),
1275 *map1 = linemap_lookup (set, l1);
1277 while (linemap_macro_expansion_map_p (map0)
1278 && linemap_macro_expansion_map_p (map1)
1279 && (map0 != map1))
1281 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1283 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1284 l0);
1285 map0 = linemap_lookup (set, l0);
1287 else
1289 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1290 l1);
1291 map1 = linemap_lookup (set, l1);
1295 if (map0 == map1)
1297 *loc0 = l0;
1298 *loc1 = l1;
1299 return map0;
1301 return NULL;
1304 /* Given two virtual locations LOC0 and LOC1, return the first common
1305 macro map in their macro expansion histories. Return NULL if no
1306 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1307 virtual location of the token inside the resulting macro, upon
1308 return of a non-NULL result. */
1310 static const struct line_map*
1311 first_map_in_common (struct line_maps *set,
1312 source_location loc0,
1313 source_location loc1,
1314 source_location *res_loc0,
1315 source_location *res_loc1)
1317 *res_loc0 = loc0;
1318 *res_loc1 = loc1;
1320 return first_map_in_common_1 (set, res_loc0, res_loc1);
1323 /* Return a positive value if PRE denotes the location of a token that
1324 comes before the token of POST, 0 if PRE denotes the location of
1325 the same token as the token for POST, and a negative value
1326 otherwise. */
1329 linemap_compare_locations (struct line_maps *set,
1330 source_location pre,
1331 source_location post)
1333 bool pre_virtual_p, post_virtual_p;
1334 source_location l0 = pre, l1 = post;
1336 if (IS_ADHOC_LOC (l0))
1337 l0 = get_location_from_adhoc_loc (set, l0);
1338 if (IS_ADHOC_LOC (l1))
1339 l1 = get_location_from_adhoc_loc (set, l1);
1341 if (l0 == l1)
1342 return 0;
1344 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1345 l0 = linemap_resolve_location (set, l0,
1346 LRK_MACRO_EXPANSION_POINT,
1347 NULL);
1349 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1350 l1 = linemap_resolve_location (set, l1,
1351 LRK_MACRO_EXPANSION_POINT,
1352 NULL);
1354 if (l0 == l1
1355 && pre_virtual_p
1356 && post_virtual_p)
1358 /* So pre and post represent two tokens that are present in a
1359 same macro expansion. Let's see if the token for pre was
1360 before the token for post in that expansion. */
1361 unsigned i0, i1;
1362 const struct line_map *map =
1363 first_map_in_common (set, pre, post, &l0, &l1);
1365 if (map == NULL)
1366 /* This should not be possible. */
1367 abort ();
1369 i0 = l0 - MAP_START_LOCATION (map);
1370 i1 = l1 - MAP_START_LOCATION (map);
1371 return i1 - i0;
1374 if (IS_ADHOC_LOC (l0))
1375 l0 = get_location_from_adhoc_loc (set, l0);
1376 if (IS_ADHOC_LOC (l1))
1377 l1 = get_location_from_adhoc_loc (set, l1);
1379 return l1 - l0;
1382 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1384 static void
1385 trace_include (const struct line_maps *set, const line_map_ordinary *map)
1387 unsigned int i = set->depth;
1389 while (--i)
1390 putc ('.', stderr);
1392 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1395 /* Return the spelling location of the token wherever it comes from,
1396 whether part of a macro definition or not.
1398 This is a subroutine for linemap_resolve_location. */
1400 static source_location
1401 linemap_macro_loc_to_spelling_point (struct line_maps *set,
1402 source_location location,
1403 const line_map_ordinary **original_map)
1405 struct line_map *map;
1406 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1408 while (true)
1410 map = const_cast <line_map *> (linemap_lookup (set, location));
1411 if (!linemap_macro_expansion_map_p (map))
1412 break;
1414 location
1415 = linemap_macro_map_loc_unwind_toward_spelling
1416 (set, linemap_check_macro (map),
1417 location);
1420 if (original_map)
1421 *original_map = linemap_check_ordinary (map);
1422 return location;
1425 /* If LOCATION is the source location of a token that belongs to a
1426 macro replacement-list -- as part of a macro expansion -- then
1427 return the location of the token at the definition point of the
1428 macro. Otherwise, return LOCATION. SET is the set of maps
1429 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1430 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1431 returned location comes from.
1433 This is a subroutine of linemap_resolve_location. */
1435 static source_location
1436 linemap_macro_loc_to_def_point (struct line_maps *set,
1437 source_location location,
1438 const line_map_ordinary **original_map)
1440 struct line_map *map;
1442 if (IS_ADHOC_LOC (location))
1443 location = set->location_adhoc_data_map.data[location
1444 & MAX_SOURCE_LOCATION].locus;
1446 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1448 while (true)
1450 map = const_cast <line_map *> (linemap_lookup (set, location));
1451 if (!linemap_macro_expansion_map_p (map))
1452 break;
1454 location =
1455 linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
1456 location);
1459 if (original_map)
1460 *original_map = linemap_check_ordinary (map);
1461 return location;
1464 /* If LOCATION is the source location of a token that belongs to a
1465 macro replacement-list -- at a macro expansion point -- then return
1466 the location of the topmost expansion point of the macro. We say
1467 topmost because if we are in the context of a nested macro
1468 expansion, the function returns the source location of the first
1469 macro expansion that triggered the nested expansions.
1471 Otherwise, return LOCATION. SET is the set of maps location come
1472 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1473 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1474 location comes from.
1476 This is a subroutine of linemap_resolve_location. */
1478 static source_location
1479 linemap_macro_loc_to_exp_point (struct line_maps *set,
1480 source_location location,
1481 const line_map_ordinary **original_map)
1483 struct line_map *map;
1485 if (IS_ADHOC_LOC (location))
1486 location = set->location_adhoc_data_map.data[location
1487 & MAX_SOURCE_LOCATION].locus;
1489 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1491 while (true)
1493 map = const_cast <line_map *> (linemap_lookup (set, location));
1494 if (!linemap_macro_expansion_map_p (map))
1495 break;
1496 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1497 location);
1500 if (original_map)
1501 *original_map = linemap_check_ordinary (map);
1502 return location;
1505 /* Resolve a virtual location into either a spelling location, an
1506 expansion point location or a token argument replacement point
1507 location. Return the map that encodes the virtual location as well
1508 as the resolved location.
1510 If LOC is *NOT* the location of a token resulting from the
1511 expansion of a macro, then the parameter LRK (which stands for
1512 Location Resolution Kind) is ignored and the resulting location
1513 just equals the one given in argument.
1515 Now if LOC *IS* the location of a token resulting from the
1516 expansion of a macro, this is what happens.
1518 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1519 -------------------------------
1521 The virtual location is resolved to the first macro expansion point
1522 that led to this macro expansion.
1524 * If LRK is set to LRK_SPELLING_LOCATION
1525 -------------------------------------
1527 The virtual location is resolved to the locus where the token has
1528 been spelled in the source. This can follow through all the macro
1529 expansions that led to the token.
1531 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1532 --------------------------------------
1534 The virtual location is resolved to the locus of the token in the
1535 context of the macro definition.
1537 If LOC is the locus of a token that is an argument of a
1538 function-like macro [replacing a parameter in the replacement list
1539 of the macro] the virtual location is resolved to the locus of the
1540 parameter that is replaced, in the context of the definition of the
1541 macro.
1543 If LOC is the locus of a token that is not an argument of a
1544 function-like macro, then the function behaves as if LRK was set to
1545 LRK_SPELLING_LOCATION.
1547 If MAP is not NULL, *MAP is set to the map encoding the
1548 returned location. Note that if the returned location wasn't originally
1549 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1550 resolves to a location reserved for the client code, like
1551 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1553 source_location
1554 linemap_resolve_location (struct line_maps *set,
1555 source_location loc,
1556 enum location_resolution_kind lrk,
1557 const line_map_ordinary **map)
1559 source_location locus = loc;
1560 if (IS_ADHOC_LOC (loc))
1561 locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1563 if (locus < RESERVED_LOCATION_COUNT)
1565 /* A reserved location wasn't encoded in a map. Let's return a
1566 NULL map here, just like what linemap_ordinary_map_lookup
1567 does. */
1568 if (map)
1569 *map = NULL;
1570 return loc;
1573 switch (lrk)
1575 case LRK_MACRO_EXPANSION_POINT:
1576 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1577 break;
1578 case LRK_SPELLING_LOCATION:
1579 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1580 break;
1581 case LRK_MACRO_DEFINITION_LOCATION:
1582 loc = linemap_macro_loc_to_def_point (set, loc, map);
1583 break;
1584 default:
1585 abort ();
1587 return loc;
1590 /* TRUE if LOCATION is a source code location of a token that is part of the
1591 definition of a macro, FALSE otherwise. */
1593 bool
1594 linemap_location_from_macro_definition_p (struct line_maps *set,
1595 source_location loc)
1597 if (IS_ADHOC_LOC (loc))
1598 loc = get_location_from_adhoc_loc (set, loc);
1600 if (!linemap_location_from_macro_expansion_p (set, loc))
1601 return false;
1603 while (true)
1605 const struct line_map_macro *map
1606 = linemap_check_macro (linemap_lookup (set, loc));
1608 source_location s_loc
1609 = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
1610 if (linemap_location_from_macro_expansion_p (set, s_loc))
1611 loc = s_loc;
1612 else
1614 source_location def_loc
1615 = linemap_macro_map_loc_to_def_point (map, loc);
1616 return s_loc == def_loc;
1622 Suppose that LOC is the virtual location of a token T coming from
1623 the expansion of a macro M. This function then steps up to get the
1624 location L of the point where M got expanded. If L is a spelling
1625 location inside a macro expansion M', then this function returns
1626 the locus of the point where M' was expanded. Said otherwise, this
1627 function returns the location of T in the context that triggered
1628 the expansion of M.
1630 *LOC_MAP must be set to the map of LOC. This function then sets it
1631 to the map of the returned location. */
1633 source_location
1634 linemap_unwind_toward_expansion (struct line_maps *set,
1635 source_location loc,
1636 const struct line_map **map)
1638 source_location resolved_location;
1639 const line_map_macro *macro_map = linemap_check_macro (*map);
1640 const struct line_map *resolved_map;
1642 if (IS_ADHOC_LOC (loc))
1643 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1645 resolved_location =
1646 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1647 resolved_map = linemap_lookup (set, resolved_location);
1649 if (!linemap_macro_expansion_map_p (resolved_map))
1651 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1652 resolved_map = linemap_lookup (set, resolved_location);
1655 *map = resolved_map;
1656 return resolved_location;
1659 /* If LOC is the virtual location of a token coming from the expansion
1660 of a macro M and if its spelling location is reserved (e.g, a
1661 location for a built-in token), then this function unwinds (using
1662 linemap_unwind_toward_expansion) the location until a location that
1663 is not reserved and is not in a system header is reached. In other
1664 words, this unwinds the reserved location until a location that is
1665 in real source code is reached.
1667 Otherwise, if the spelling location for LOC is not reserved or if
1668 LOC doesn't come from the expansion of a macro, the function
1669 returns LOC as is and *MAP is not touched.
1671 *MAP is set to the map of the returned location if the later is
1672 different from LOC. */
1673 source_location
1674 linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
1675 source_location loc,
1676 const struct line_map **map)
1678 source_location resolved_loc;
1679 const struct line_map *map0 = NULL;
1680 const line_map_ordinary *map1 = NULL;
1682 if (IS_ADHOC_LOC (loc))
1683 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1685 map0 = linemap_lookup (set, loc);
1686 if (!linemap_macro_expansion_map_p (map0))
1687 return loc;
1689 resolved_loc = linemap_resolve_location (set, loc,
1690 LRK_SPELLING_LOCATION,
1691 &map1);
1693 if (resolved_loc >= RESERVED_LOCATION_COUNT
1694 && !LINEMAP_SYSP (map1))
1695 return loc;
1697 while (linemap_macro_expansion_map_p (map0)
1698 && (resolved_loc < RESERVED_LOCATION_COUNT
1699 || LINEMAP_SYSP (map1)))
1701 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1702 resolved_loc = linemap_resolve_location (set, loc,
1703 LRK_SPELLING_LOCATION,
1704 &map1);
1707 if (map != NULL)
1708 *map = map0;
1709 return loc;
1712 /* Expand source code location LOC and return a user readable source
1713 code location. LOC must be a spelling (non-virtual) location. If
1714 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1715 location is returned. */
1717 expanded_location
1718 linemap_expand_location (struct line_maps *set,
1719 const struct line_map *map,
1720 source_location loc)
1723 expanded_location xloc;
1725 memset (&xloc, 0, sizeof (xloc));
1726 if (IS_ADHOC_LOC (loc))
1728 xloc.data
1729 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
1730 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1733 if (loc < RESERVED_LOCATION_COUNT)
1734 /* The location for this token wasn't generated from a line map.
1735 It was probably a location for a builtin token, chosen by some
1736 client code. Let's not try to expand the location in that
1737 case. */;
1738 else if (map == NULL)
1739 /* We shouldn't be getting a NULL map with a location that is not
1740 reserved by the client code. */
1741 abort ();
1742 else
1744 /* MAP must be an ordinary map and LOC must be non-virtual,
1745 encoded into this map, obviously; the accessors used on MAP
1746 below ensure it is ordinary. Let's just assert the
1747 non-virtualness of LOC here. */
1748 if (linemap_location_from_macro_expansion_p (set, loc))
1749 abort ();
1751 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1753 xloc.file = LINEMAP_FILE (ord_map);
1754 xloc.line = SOURCE_LINE (ord_map, loc);
1755 xloc.column = SOURCE_COLUMN (ord_map, loc);
1756 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1759 return xloc;
1763 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1764 is NULL, use stderr. IS_MACRO is true if the caller wants to
1765 dump a macro map, false otherwise. */
1767 void
1768 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
1770 const char *lc_reasons_v[LC_ENTER_MACRO + 1]
1771 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1772 "LC_ENTER_MACRO" };
1773 const char *reason;
1774 const line_map *map;
1776 if (stream == NULL)
1777 stream = stderr;
1779 if (!is_macro)
1780 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1781 else
1782 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1784 reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
1786 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1787 ix, (void *) map, map->start_location, reason,
1788 ((!is_macro
1789 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1790 ? "yes" : "no"));
1791 if (!is_macro)
1793 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1794 unsigned includer_ix;
1795 const line_map_ordinary *includer_map;
1797 includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
1798 includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
1799 ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
1800 : NULL;
1802 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1803 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1804 fprintf (stream, "Included from: [%d] %s\n", includer_ix,
1805 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1807 else
1809 const line_map_macro *macro_map = linemap_check_macro (map);
1810 fprintf (stream, "Macro: %s (%u tokens)\n",
1811 linemap_map_get_macro_name (macro_map),
1812 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1815 fprintf (stream, "\n");
1819 /* Dump debugging information about source location LOC into the file
1820 stream STREAM. SET is the line map set LOC comes from. */
1822 void
1823 linemap_dump_location (struct line_maps *set,
1824 source_location loc,
1825 FILE *stream)
1827 const line_map_ordinary *map;
1828 source_location location;
1829 const char *path = "", *from = "";
1830 int l = -1, c = -1, s = -1, e = -1;
1832 if (IS_ADHOC_LOC (loc))
1833 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1835 if (loc == 0)
1836 return;
1838 location =
1839 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1841 if (map == NULL)
1842 /* Only reserved locations can be tolerated in this case. */
1843 linemap_assert (location < RESERVED_LOCATION_COUNT);
1844 else
1846 path = LINEMAP_FILE (map);
1847 l = SOURCE_LINE (map, location);
1848 c = SOURCE_COLUMN (map, location);
1849 s = LINEMAP_SYSP (map) != 0;
1850 e = location != loc;
1851 if (e)
1852 from = "N/A";
1853 else
1854 from = (INCLUDED_FROM (set, map))
1855 ? LINEMAP_FILE (INCLUDED_FROM (set, map))
1856 : "<NULL>";
1859 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1860 E: macro expansion?, LOC: original location, R: resolved location */
1861 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1862 path, from, l, c, s, (void*)map, e, loc, location);
1865 /* Return the highest location emitted for a given file for which
1866 there is a line map in SET. FILE_NAME is the file name to
1867 consider. If the function returns TRUE, *LOC is set to the highest
1868 location emitted for that file. */
1870 bool
1871 linemap_get_file_highest_location (struct line_maps *set,
1872 const char *file_name,
1873 source_location *loc)
1875 /* If the set is empty or no ordinary map has been created then
1876 there is no file to look for ... */
1877 if (set == NULL || set->info_ordinary.used == 0)
1878 return false;
1880 /* Now look for the last ordinary map created for FILE_NAME. */
1881 int i;
1882 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1884 const char *fname = set->info_ordinary.maps[i].to_file;
1885 if (fname && !filename_cmp (fname, file_name))
1886 break;
1889 if (i < 0)
1890 return false;
1892 /* The highest location for a given map is either the starting
1893 location of the next map minus one, or -- if the map is the
1894 latest one -- the highest location of the set. */
1895 source_location result;
1896 if (i == (int) set->info_ordinary.used - 1)
1897 result = set->highest_location;
1898 else
1899 result = set->info_ordinary.maps[i + 1].start_location - 1;
1901 *loc = result;
1902 return true;
1905 /* Compute and return statistics about the memory consumption of some
1906 parts of the line table SET. */
1908 void
1909 linemap_get_statistics (struct line_maps *set,
1910 struct linemap_stats *s)
1912 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1913 macro_maps_allocated_size, macro_maps_used_size,
1914 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1916 const line_map_macro *cur_map;
1918 ordinary_maps_allocated_size =
1919 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1921 ordinary_maps_used_size =
1922 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1924 macro_maps_allocated_size =
1925 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1927 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1928 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1929 ++cur_map)
1931 unsigned i;
1933 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1935 macro_maps_locations_size +=
1936 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1938 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1940 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1941 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1942 duplicated_macro_maps_locations_size +=
1943 sizeof (source_location);
1947 macro_maps_used_size =
1948 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1950 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1951 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1952 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1953 s->ordinary_maps_used_size = ordinary_maps_used_size;
1954 s->num_expanded_macros = num_expanded_macros_counter;
1955 s->num_macro_tokens = num_macro_tokens_counter;
1956 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1957 s->macro_maps_allocated_size = macro_maps_allocated_size;
1958 s->macro_maps_locations_size = macro_maps_locations_size;
1959 s->macro_maps_used_size = macro_maps_used_size;
1960 s->duplicated_macro_maps_locations_size =
1961 duplicated_macro_maps_locations_size;
1962 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1963 * sizeof (struct location_adhoc_data));
1964 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1968 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1969 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1970 specifies how many macro maps to dump. */
1972 void
1973 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1974 unsigned int num_macro)
1976 unsigned int i;
1978 if (set == NULL)
1979 return;
1981 if (stream == NULL)
1982 stream = stderr;
1984 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1985 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1986 fprintf (stream, "Include stack depth: %d\n", set->depth);
1987 fprintf (stream, "Highest location: %u\n", set->highest_location);
1989 if (num_ordinary)
1991 fprintf (stream, "\nOrdinary line maps\n");
1992 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
1993 linemap_dump (stream, set, i, false);
1994 fprintf (stream, "\n");
1997 if (num_macro)
1999 fprintf (stream, "\nMacro line maps\n");
2000 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
2001 linemap_dump (stream, set, i, true);
2002 fprintf (stream, "\n");
2006 /* class rich_location. */
2008 /* Construct a rich_location with location LOC as its initial range. */
2010 rich_location::rich_location (line_maps *set, source_location loc) :
2011 m_line_table (set),
2012 m_ranges (),
2013 m_column_override (0),
2014 m_have_expanded_location (false),
2015 m_fixit_hints (),
2016 m_seen_impossible_fixit (false),
2017 m_fixits_cannot_be_auto_applied (false)
2019 add_range (loc, true);
2022 /* The destructor for class rich_location. */
2024 rich_location::~rich_location ()
2026 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2027 delete get_fixit_hint (i);
2030 /* Get location IDX within this rich_location. */
2032 source_location
2033 rich_location::get_loc (unsigned int idx) const
2035 const location_range *locrange = get_range (idx);
2036 return locrange->m_loc;
2039 /* Get range IDX within this rich_location. */
2041 const location_range *
2042 rich_location::get_range (unsigned int idx) const
2044 return &m_ranges[idx];
2047 /* Mutable access to range IDX within this rich_location. */
2049 location_range *
2050 rich_location::get_range (unsigned int idx)
2052 return &m_ranges[idx];
2055 /* Expand location IDX within this rich_location. */
2056 /* Get an expanded_location for this rich_location's primary
2057 location. */
2059 expanded_location
2060 rich_location::get_expanded_location (unsigned int idx)
2062 if (idx == 0)
2064 /* Cache the expansion of the primary location. */
2065 if (!m_have_expanded_location)
2067 m_expanded_location
2068 = linemap_client_expand_location_to_spelling_point (get_loc (0));
2069 if (m_column_override)
2070 m_expanded_location.column = m_column_override;
2071 m_have_expanded_location = true;
2074 return m_expanded_location;
2076 else
2077 return linemap_client_expand_location_to_spelling_point (get_loc (idx));
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 const char *newline = strchr (new_content, '\n');
2331 if (newline)
2333 /* For now, we can only support insertion of whole lines
2334 i.e. starts at start of line, and the newline is at the end of
2335 the insertion point. */
2337 /* It must be an insertion, not a replacement/deletion. */
2338 if (start != next_loc)
2340 stop_supporting_fixits ();
2341 return;
2344 /* The insertion must be at the start of a line. */
2345 expanded_location exploc_start
2346 = linemap_client_expand_location_to_spelling_point (start);
2347 if (exploc_start.column != 1)
2349 stop_supporting_fixits ();
2350 return;
2353 /* The newline must be at end of NEW_CONTENT.
2354 We could eventually split up fix-its at newlines if we wanted
2355 to allow more generality (e.g. to allow adding multiple lines
2356 with one add_fixit call. */
2357 if (newline[1] != '\0')
2359 stop_supporting_fixits ();
2360 return;
2364 /* Consolidate neighboring fixits.
2365 Don't consolidate into newline-insertion fixits. */
2366 fixit_hint *prev = get_last_fixit_hint ();
2367 if (prev && !prev->ends_with_newline_p ())
2368 if (prev->maybe_append (start, next_loc, new_content))
2369 return;
2371 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
2374 /* class fixit_hint. */
2376 fixit_hint::fixit_hint (source_location start,
2377 source_location next_loc,
2378 const char *new_content)
2379 : m_start (start),
2380 m_next_loc (next_loc),
2381 m_bytes (xstrdup (new_content)),
2382 m_len (strlen (new_content))
2386 /* Does this fix-it hint affect the given line? */
2388 bool
2389 fixit_hint::affects_line_p (const char *file, int line) const
2391 expanded_location exploc_start
2392 = linemap_client_expand_location_to_spelling_point (m_start);
2393 if (file != exploc_start.file)
2394 return false;
2395 if (line < exploc_start.line)
2396 return false;
2397 expanded_location exploc_next_loc
2398 = linemap_client_expand_location_to_spelling_point (m_next_loc);
2399 if (file != exploc_next_loc.file)
2400 return false;
2401 if (line > exploc_next_loc.line)
2402 return false;
2403 return true;
2406 /* Method for consolidating fix-it hints, for use by
2407 rich_location::maybe_add_fixit.
2408 If possible, merge a pending fix-it hint with the given params
2409 into this one and return true.
2410 Otherwise return false. */
2412 bool
2413 fixit_hint::maybe_append (source_location start,
2414 source_location next_loc,
2415 const char *new_content)
2417 /* For consolidation to be possible, START must be at this hint's
2418 m_next_loc. */
2419 if (start != m_next_loc)
2420 return false;
2422 /* If so, we have neighboring replacements; merge them. */
2423 m_next_loc = next_loc;
2424 size_t extra_len = strlen (new_content);
2425 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2426 memcpy (m_bytes + m_len, new_content, extra_len);
2427 m_len += extra_len;
2428 m_bytes[m_len] = '\0';
2429 return true;
2432 /* Return true iff this hint's content ends with a newline. */
2434 bool
2435 fixit_hint::ends_with_newline_p () const
2437 if (m_len == 0)
2438 return false;
2439 return m_bytes[m_len - 1] == '\n';