d: Merge upstream dmd d579c467c1, phobos 88aa69b14.
[official-gcc.git] / libcpp / line-map.cc
blob391f1d4bbc1a63a5bfe94dcc08b150fee942f766
1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2022 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3, or (at your option) any
7 later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>.
18 In other words, you are welcome to use, share and improve this program.
19 You are forbidden to forbid anyone else to use, share and improve
20 what you give them. Help stamp out software-hoarding! */
22 #include "config.h"
23 #include "system.h"
24 #include "line-map.h"
25 #include "cpplib.h"
26 #include "internal.h"
27 #include "hashtab.h"
29 static void trace_include (const line_maps *, const line_map_ordinary *);
30 static const line_map_ordinary * linemap_ordinary_map_lookup (const line_maps *,
31 location_t);
32 static const line_map_macro* linemap_macro_map_lookup (const line_maps *,
33 location_t);
34 static location_t linemap_macro_map_loc_to_def_point
35 (const line_map_macro *, location_t);
36 static location_t linemap_macro_map_loc_to_exp_point
37 (const line_map_macro *, location_t);
38 static location_t linemap_macro_loc_to_spelling_point
39 (line_maps *, location_t, const line_map_ordinary **);
40 static location_t linemap_macro_loc_to_def_point (line_maps *,
41 location_t,
42 const line_map_ordinary **);
43 static location_t linemap_macro_loc_to_exp_point (line_maps *,
44 location_t,
45 const line_map_ordinary **);
47 /* Counters defined in macro.cc. */
48 extern unsigned num_expanded_macros_counter;
49 extern unsigned num_macro_tokens_counter;
51 /* Destructor for class line_maps.
52 Ensure non-GC-managed memory is released. */
54 line_maps::~line_maps ()
56 if (location_adhoc_data_map.htab)
57 htab_delete (location_adhoc_data_map.htab);
60 /* Hash function for location_adhoc_data hashtable. */
62 static hashval_t
63 location_adhoc_data_hash (const void *l)
65 const struct location_adhoc_data *lb =
66 (const struct location_adhoc_data *) l;
67 return ((hashval_t) lb->locus
68 + (hashval_t) lb->src_range.m_start
69 + (hashval_t) lb->src_range.m_finish
70 + (size_t) lb->data);
73 /* Compare function for location_adhoc_data hashtable. */
75 static int
76 location_adhoc_data_eq (const void *l1, const void *l2)
78 const struct location_adhoc_data *lb1 =
79 (const struct location_adhoc_data *) l1;
80 const struct location_adhoc_data *lb2 =
81 (const struct location_adhoc_data *) l2;
82 return (lb1->locus == lb2->locus
83 && lb1->src_range.m_start == lb2->src_range.m_start
84 && lb1->src_range.m_finish == lb2->src_range.m_finish
85 && lb1->data == lb2->data);
88 /* Update the hashtable when location_adhoc_data_map::data is reallocated.
89 The param is an array of two pointers, the previous value of the data
90 pointer, and then the new value. The pointers stored in the hash map
91 are then rebased to be relative to the new data pointer instead of the
92 old one. */
94 static int
95 location_adhoc_data_update (void **slot_v, void *param_v)
97 const auto slot = reinterpret_cast<location_adhoc_data **> (slot_v);
98 const auto param = static_cast<location_adhoc_data **> (param_v);
99 *slot = (*slot - param[0]) + param[1];
100 return 1;
103 /* The adhoc data hash table is not part of the GGC infrastructure, so it was
104 not initialized when SET was reconstructed from PCH; take care of that by
105 rebuilding it from scratch. */
107 void
108 rebuild_location_adhoc_htab (line_maps *set)
110 set->location_adhoc_data_map.htab =
111 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
112 for (auto p = set->location_adhoc_data_map.data,
113 end = p + set->location_adhoc_data_map.curr_loc;
114 p != end; ++p)
116 const auto slot = reinterpret_cast<location_adhoc_data **>
117 (htab_find_slot (set->location_adhoc_data_map.htab, p, INSERT));
118 *slot = p;
122 /* Helper function for get_combined_adhoc_loc.
123 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
124 within a location_t, without needing to use an ad-hoc location. */
126 static bool
127 can_be_stored_compactly_p (line_maps *set,
128 location_t locus,
129 source_range src_range,
130 void *data)
132 /* If there's an ad-hoc pointer, we can't store it directly in the
133 location_t, we need the lookaside. */
134 if (data)
135 return false;
137 /* We only store ranges that begin at the locus and that are sufficiently
138 "sane". */
139 if (src_range.m_start != locus)
140 return false;
142 if (src_range.m_finish < src_range.m_start)
143 return false;
145 if (src_range.m_start < RESERVED_LOCATION_COUNT)
146 return false;
148 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
149 return false;
151 /* All 3 locations must be within ordinary maps, typically, the same
152 ordinary map. */
153 location_t lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
154 if (locus >= lowest_macro_loc)
155 return false;
156 if (src_range.m_start >= lowest_macro_loc)
157 return false;
158 if (src_range.m_finish >= lowest_macro_loc)
159 return false;
161 /* Passed all tests. */
162 return true;
165 /* Combine LOCUS and DATA to a combined adhoc loc. */
167 location_t
168 get_combined_adhoc_loc (line_maps *set,
169 location_t locus,
170 source_range src_range,
171 void *data)
173 struct location_adhoc_data lb;
174 struct location_adhoc_data **slot;
176 if (IS_ADHOC_LOC (locus))
177 locus = get_location_from_adhoc_loc (set, locus);
178 if (locus == 0 && data == NULL)
179 return 0;
181 /* Any ordinary locations ought to be "pure" at this point: no
182 compressed ranges. */
183 linemap_assert (locus < RESERVED_LOCATION_COUNT
184 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
185 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
186 || pure_location_p (set, locus));
188 /* Consider short-range optimization. */
189 if (can_be_stored_compactly_p (set, locus, src_range, data))
191 /* The low bits ought to be clear. */
192 linemap_assert (pure_location_p (set, locus));
193 const line_map *map = linemap_lookup (set, locus);
194 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
195 unsigned int int_diff = src_range.m_finish - src_range.m_start;
196 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
197 if (col_diff < (1U << ordmap->m_range_bits))
199 location_t packed = locus | col_diff;
200 set->num_optimized_ranges++;
201 return packed;
205 /* We can also compactly store locations
206 when locus == start == finish (and data is NULL). */
207 if (locus == src_range.m_start
208 && locus == src_range.m_finish
209 && !data)
210 return locus;
212 if (!data)
213 set->num_unoptimized_ranges++;
215 lb.locus = locus;
216 lb.src_range = src_range;
217 lb.data = data;
218 slot = (struct location_adhoc_data **)
219 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
220 if (*slot == NULL)
222 if (set->location_adhoc_data_map.curr_loc >=
223 set->location_adhoc_data_map.allocated)
225 const auto orig_data = set->location_adhoc_data_map.data;
226 /* Cast away extern "C" from the type of xrealloc. */
227 line_map_realloc reallocator = (set->reallocator
228 ? set->reallocator
229 : (line_map_realloc) xrealloc);
231 if (set->location_adhoc_data_map.allocated == 0)
232 set->location_adhoc_data_map.allocated = 128;
233 else
234 set->location_adhoc_data_map.allocated *= 2;
235 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
236 reallocator (set->location_adhoc_data_map.data,
237 set->location_adhoc_data_map.allocated
238 * sizeof (struct location_adhoc_data));
239 if (set->location_adhoc_data_map.allocated > 128)
241 location_adhoc_data *param[2]
242 = {orig_data, set->location_adhoc_data_map.data};
243 htab_traverse (set->location_adhoc_data_map.htab,
244 location_adhoc_data_update, param);
247 *slot = set->location_adhoc_data_map.data
248 + set->location_adhoc_data_map.curr_loc;
249 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
250 = lb;
252 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
255 /* Return the data for the adhoc loc. */
257 void *
258 get_data_from_adhoc_loc (const class line_maps *set, location_t loc)
260 linemap_assert (IS_ADHOC_LOC (loc));
261 return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
264 /* Return the location for the adhoc loc. */
266 location_t
267 get_location_from_adhoc_loc (const class line_maps *set, location_t loc)
269 linemap_assert (IS_ADHOC_LOC (loc));
270 return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;
273 /* Return the source_range for adhoc location LOC. */
275 static source_range
276 get_range_from_adhoc_loc (const class line_maps *set, location_t loc)
278 linemap_assert (IS_ADHOC_LOC (loc));
279 return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].src_range;
282 /* Get the source_range of location LOC, either from the ad-hoc
283 lookaside table, or embedded inside LOC itself. */
285 source_range
286 get_range_from_loc (line_maps *set,
287 location_t loc)
289 if (IS_ADHOC_LOC (loc))
290 return get_range_from_adhoc_loc (set, loc);
292 /* For ordinary maps, extract packed range. */
293 if (loc >= RESERVED_LOCATION_COUNT
294 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
295 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
297 const line_map *map = linemap_lookup (set, loc);
298 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
299 source_range result;
300 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
301 result.m_start = loc - offset;
302 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
303 return result;
306 return source_range::from_location (loc);
309 /* Get whether location LOC is a "pure" location, or
310 whether it is an ad-hoc location, or embeds range information. */
312 bool
313 pure_location_p (line_maps *set, location_t loc)
315 if (IS_ADHOC_LOC (loc))
316 return false;
318 const line_map *map = linemap_lookup (set, loc);
319 if (map == NULL)
320 return true;
321 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
323 if (loc & ((1U << ordmap->m_range_bits) - 1))
324 return false;
326 return true;
329 /* Given location LOC within SET, strip away any packed range information
330 or ad-hoc information. */
332 location_t
333 get_pure_location (line_maps *set, location_t loc)
335 if (IS_ADHOC_LOC (loc))
336 loc = get_location_from_adhoc_loc (set, loc);
338 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
339 return loc;
341 if (loc < RESERVED_LOCATION_COUNT)
342 return loc;
344 const line_map *map = linemap_lookup (set, loc);
345 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
347 return loc & ~((1 << ordmap->m_range_bits) - 1);
350 /* Initialize a line map set. */
352 void
353 linemap_init (line_maps *set,
354 location_t builtin_location)
356 #if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
357 /* PR33916, needed to fix PR82939. */
358 memset (set, 0, sizeof (line_maps));
359 #else
360 new (set) line_maps();
361 #endif
362 /* Set default reallocator (used for initial alloc too). */
363 set->reallocator = xrealloc;
364 set->highest_location = RESERVED_LOCATION_COUNT - 1;
365 set->highest_line = RESERVED_LOCATION_COUNT - 1;
366 set->location_adhoc_data_map.htab =
367 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
368 set->builtin_location = builtin_location;
371 /* Return the ordinary line map from whence MAP was included. Returns
372 NULL if MAP was not an include. */
374 const line_map_ordinary *
375 linemap_included_from_linemap (line_maps *set, const line_map_ordinary *map)
377 return linemap_ordinary_map_lookup (set, linemap_included_from (map));
380 /* Check for and warn about line_maps entered but not exited. */
382 void
383 linemap_check_files_exited (line_maps *set)
385 /* Depending upon whether we are handling preprocessed input or
386 not, this can be a user error or an ICE. */
387 for (const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
388 ! MAIN_FILE_P (map);
389 map = linemap_included_from_linemap (set, map))
390 fprintf (stderr, "line-map.cc: file \"%s\" entered but not left\n",
391 ORDINARY_MAP_FILE_NAME (map));
394 /* Create NUM zero-initialized maps of type MACRO_P. */
396 line_map *
397 line_map_new_raw (line_maps *set, bool macro_p, unsigned num)
399 unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
400 unsigned num_maps_used = LINEMAPS_USED (set, macro_p);
402 if (num > num_maps_allocated - num_maps_used)
404 /* We need more space! */
405 if (!num_maps_allocated)
406 num_maps_allocated = 128;
407 if (num_maps_allocated < num_maps_used + num)
408 num_maps_allocated = num_maps_used + num;
409 num_maps_allocated *= 2;
411 size_t size_of_a_map;
412 void *buffer;
413 if (macro_p)
415 size_of_a_map = sizeof (line_map_macro);
416 buffer = set->info_macro.maps;
418 else
420 size_of_a_map = sizeof (line_map_ordinary);
421 buffer = set->info_ordinary.maps;
424 /* We are going to execute some dance to try to reduce the
425 overhead of the memory allocator, in case we are using the
426 ggc-page.cc one.
428 The actual size of memory we are going to get back from the
429 allocator may well be larger than what we ask for. Use this
430 hook to find what that size is. */
431 size_t alloc_size
432 = set->round_alloc_size (num_maps_allocated * size_of_a_map);
434 /* Now alloc_size contains the exact memory size we would get if
435 we have asked for the initial alloc_size amount of memory.
436 Let's get back to the number of map that amounts to. */
437 unsigned num_maps = alloc_size / size_of_a_map;
438 buffer = set->reallocator (buffer, num_maps * size_of_a_map);
439 memset ((char *)buffer + num_maps_used * size_of_a_map, 0,
440 (num_maps - num_maps_used) * size_of_a_map);
441 if (macro_p)
442 set->info_macro.maps = (line_map_macro *)buffer;
443 else
444 set->info_ordinary.maps = (line_map_ordinary *)buffer;
445 LINEMAPS_ALLOCATED (set, macro_p) = num_maps;
448 line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used]
449 : (line_map *)&set->info_ordinary.maps[num_maps_used]);
450 LINEMAPS_USED (set, macro_p) += num;
452 return result;
455 /* Create a new line map in the line map set SET, and return it.
456 REASON is the reason of creating the map. It determines the type
457 of map created (ordinary or macro map). Note that ordinary maps and
458 macro maps are allocated in different memory location. */
460 static struct line_map *
461 new_linemap (line_maps *set, location_t start_location)
463 line_map *result = line_map_new_raw (set,
464 start_location >= LINE_MAP_MAX_LOCATION,
467 result->start_location = start_location;
469 return result;
472 /* Return the location of the last source line within an ordinary
473 map. */
474 inline location_t
475 LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
477 return (((map[1].start_location - 1
478 - map->start_location)
479 & ~((1 << map->m_column_and_range_bits) - 1))
480 + map->start_location);
483 /* Add a mapping of logical source line to physical source file and
484 line number.
486 The text pointed to by TO_FILE must have a lifetime
487 at least as long as the final call to lookup_line (). An empty
488 TO_FILE means standard input. If reason is LC_LEAVE, and
489 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
490 natural values considering the file we are returning to.
492 FROM_LINE should be monotonic increasing across calls to this
493 function. A call to this function can relocate the previous set of
494 maps, so any stored line_map pointers should not be used. */
496 const struct line_map *
497 linemap_add (line_maps *set, enum lc_reason reason,
498 unsigned int sysp, const char *to_file, linenum_type to_line)
500 /* Generate a start_location above the current highest_location.
501 If possible, make the low range bits be zero. */
502 location_t start_location = set->highest_location + 1;
503 unsigned range_bits = 0;
504 if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
505 range_bits = set->default_range_bits;
506 start_location += (1 << range_bits) - 1;
507 start_location &= ~((1 << range_bits) - 1);
509 linemap_assert (!LINEMAPS_ORDINARY_USED (set)
510 || (start_location
511 >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
513 /* When we enter the file for the first time reason cannot be
514 LC_RENAME. */
515 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
517 /* If we are leaving the main file, return a NULL map. */
518 if (reason == LC_LEAVE
519 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
520 && to_file == NULL)
522 set->depth--;
523 return NULL;
526 linemap_assert (reason != LC_ENTER_MACRO);
528 if (start_location >= LINE_MAP_MAX_LOCATION)
529 /* We ran out of line map space. */
530 start_location = 0;
532 line_map_ordinary *map
533 = linemap_check_ordinary (new_linemap (set, start_location));
534 map->reason = reason;
536 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
537 to_file = "<stdin>";
539 if (reason == LC_RENAME_VERBATIM)
540 reason = LC_RENAME;
542 const line_map_ordinary *from = NULL;
543 if (reason == LC_LEAVE)
545 /* When we are just leaving an "included" file, and jump to the next
546 location inside the "includer" right after the #include
547 "included", this variable points the map in use right before the
548 #include "included", inside the same "includer" file. */
550 linemap_assert (!MAIN_FILE_P (map - 1));
551 /* (MAP - 1) points to the map we are leaving. The
552 map from which (MAP - 1) got included should be the map
553 that comes right before MAP in the same file. */
554 from = linemap_included_from_linemap (set, map - 1);
556 /* A TO_FILE of NULL is special - we use the natural values. */
557 if (to_file == NULL)
559 to_file = ORDINARY_MAP_FILE_NAME (from);
560 to_line = SOURCE_LINE (from, from[1].start_location);
561 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
563 else
564 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
565 to_file) == 0);
568 map->sysp = sysp;
569 map->to_file = to_file;
570 map->to_line = to_line;
571 LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
572 /* Do not store range_bits here. That's readjusted in
573 linemap_line_start. */
574 map->m_range_bits = map->m_column_and_range_bits = 0;
575 set->highest_location = start_location;
576 set->highest_line = start_location;
577 set->max_column_hint = 0;
579 /* This assertion is placed after set->highest_location has
580 been updated, since the latter affects
581 linemap_location_from_macro_expansion_p, which ultimately affects
582 pure_location_p. */
583 linemap_assert (pure_location_p (set, start_location));
585 if (reason == LC_ENTER)
587 if (set->depth == 0)
588 map->included_from = 0;
589 else
590 /* The location of the end of the just-closed map. */
591 map->included_from
592 = (((map[0].start_location - 1 - map[-1].start_location)
593 & ~((1 << map[-1].m_column_and_range_bits) - 1))
594 + map[-1].start_location);
595 set->depth++;
596 if (set->trace_includes)
597 trace_include (set, map);
599 else if (reason == LC_RENAME)
600 map->included_from = linemap_included_from (&map[-1]);
601 else if (reason == LC_LEAVE)
603 set->depth--;
604 map->included_from = linemap_included_from (from);
607 return map;
610 /* Create a location for a module NAME imported at FROM. */
612 location_t
613 linemap_module_loc (line_maps *set, location_t from, const char *name)
615 const line_map_ordinary *map
616 = linemap_check_ordinary (linemap_add (set, LC_MODULE, false, name, 0));
617 const_cast <line_map_ordinary *> (map)->included_from = from;
619 location_t loc = linemap_line_start (set, 0, 0);
621 return loc;
624 /* The linemap containing LOC is being reparented to be
625 imported/included from ADOPTOR. This can happen when an
626 indirectly imported module is then directly imported, or when
627 partitions are involved. */
629 void
630 linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor)
632 const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc);
633 const_cast<line_map_ordinary *> (map)->included_from = adoptor;
636 /* A linemap at LWM-1 was interrupted to insert module locations & imports.
637 Append a new map, continuing the interrupted one. Return the start location
638 of the new map, or 0 if failed (because we ran out of locations. */
640 unsigned
641 linemap_module_restore (line_maps *set, unsigned lwm)
643 linemap_assert (lwm);
645 const line_map_ordinary *pre_map
646 = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1));
647 unsigned src_line = SOURCE_LINE (pre_map, LAST_SOURCE_LINE_LOCATION (pre_map));
648 location_t inc_at = pre_map->included_from;
649 if (const line_map_ordinary *post_map
650 = (linemap_check_ordinary
651 (linemap_add (set, LC_RENAME_VERBATIM,
652 ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map),
653 ORDINARY_MAP_FILE_NAME (pre_map), src_line))))
655 /* linemap_add will think we were included from the same as the preceeding
656 map. */
657 const_cast <line_map_ordinary *> (post_map)->included_from = inc_at;
659 return post_map->start_location;
662 return 0;
665 /* Returns TRUE if the line table set tracks token locations across
666 macro expansion, FALSE otherwise. */
668 bool
669 linemap_tracks_macro_expansion_locs_p (line_maps *set)
671 return LINEMAPS_MACRO_MAPS (set) != NULL;
674 /* Create a macro map. A macro map encodes source locations of tokens
675 that are part of a macro replacement-list, at a macro expansion
676 point. See the extensive comments of struct line_map and struct
677 line_map_macro, in line-map.h.
679 This map shall be created when the macro is expanded. The map
680 encodes the source location of the expansion point of the macro as
681 well as the "original" source location of each token that is part
682 of the macro replacement-list. If a macro is defined but never
683 expanded, it has no macro map. SET is the set of maps the macro
684 map should be part of. MACRO_NODE is the macro which the new macro
685 map should encode source locations for. EXPANSION is the location
686 of the expansion point of MACRO. For function-like macros
687 invocations, it's best to make it point to the closing parenthesis
688 of the macro, rather than the the location of the first character
689 of the macro. NUM_TOKENS is the number of tokens that are part of
690 the replacement-list of MACRO.
692 Note that when we run out of the integer space available for source
693 locations, this function returns NULL. In that case, callers of
694 this function cannot encode {line,column} pairs into locations of
695 macro tokens anymore. */
697 const line_map_macro *
698 linemap_enter_macro (class line_maps *set, struct cpp_hashnode *macro_node,
699 location_t expansion, unsigned int num_tokens)
701 location_t start_location
702 = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
704 if (start_location < LINE_MAP_MAX_LOCATION)
705 /* We ran out of macro map space. */
706 return NULL;
708 line_map_macro *map = linemap_check_macro (new_linemap (set, start_location));
710 map->macro = macro_node;
711 map->n_tokens = num_tokens;
712 map->macro_locations
713 = (location_t*) set->reallocator (NULL,
714 2 * num_tokens
715 * sizeof (location_t));
716 map->expansion = expansion;
717 memset (MACRO_MAP_LOCATIONS (map), 0,
718 2 * num_tokens * sizeof (location_t));
720 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
722 return map;
725 /* Create and return a virtual location for a token that is part of a
726 macro expansion-list at a macro expansion point. See the comment
727 inside struct line_map_macro to see what an expansion-list exactly
730 A call to this function must come after a call to
731 linemap_enter_macro.
733 MAP is the map into which the source location is created. TOKEN_NO
734 is the index of the token in the macro replacement-list, starting
735 at number 0.
737 ORIG_LOC is the location of the token outside of this macro
738 expansion. If the token comes originally from the macro
739 definition, it is the locus in the macro definition; otherwise it
740 is a location in the context of the caller of this macro expansion
741 (which is a virtual location or a source location if the caller is
742 itself a macro expansion or not).
744 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
745 either of the token itself or of a macro parameter that it
746 replaces. */
748 location_t
749 linemap_add_macro_token (const line_map_macro *map,
750 unsigned int token_no,
751 location_t orig_loc,
752 location_t orig_parm_replacement_loc)
754 location_t result;
756 linemap_assert (linemap_macro_expansion_map_p (map));
757 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
759 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
760 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
762 result = MAP_START_LOCATION (map) + token_no;
763 return result;
766 /* Return a location_t for the start (i.e. column==0) of
767 (physical) line TO_LINE in the current source file (as in the
768 most recent linemap_add). MAX_COLUMN_HINT is the highest column
769 number we expect to use in this line (but it does not change
770 the highest_location). */
772 location_t
773 linemap_line_start (line_maps *set, linenum_type to_line,
774 unsigned int max_column_hint)
776 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
777 location_t highest = set->highest_location;
778 location_t r;
779 linenum_type last_line =
780 SOURCE_LINE (map, set->highest_line);
781 int line_delta = to_line - last_line;
782 bool add_map = false;
783 linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
784 int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
786 if (line_delta < 0
787 || (line_delta > 10
788 && line_delta * map->m_column_and_range_bits > 1000)
789 || (max_column_hint >= (1U << effective_column_bits))
790 || (max_column_hint <= 80 && effective_column_bits >= 10)
791 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
792 && map->m_range_bits > 0)
793 || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
794 && (set->max_column_hint || highest >= LINE_MAP_MAX_LOCATION)))
795 add_map = true;
796 else
797 max_column_hint = set->max_column_hint;
798 if (add_map)
800 int column_bits;
801 int range_bits;
802 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
803 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
805 /* If the column number is ridiculous or we've allocated a huge
806 number of location_ts, give up on column numbers
807 (and on packed ranges). */
808 max_column_hint = 1;
809 column_bits = 0;
810 range_bits = 0;
811 if (highest >= LINE_MAP_MAX_LOCATION)
812 goto overflowed;
814 else
816 column_bits = 7;
817 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
818 range_bits = set->default_range_bits;
819 else
820 range_bits = 0;
821 while (max_column_hint >= (1U << column_bits))
822 column_bits++;
823 max_column_hint = 1U << column_bits;
824 column_bits += range_bits;
827 /* Allocate the new line_map. However, if the current map only has a
828 single line we can sometimes just increase its column_bits instead. */
829 if (line_delta < 0
830 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
831 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
832 || ( /* We can't reuse the map if the line offset is sufficiently
833 large to cause overflow when computing location_t values. */
834 (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
835 >= (((uint64_t) 1)
836 << (CHAR_BIT * sizeof (linenum_type) - column_bits)))
837 || range_bits < map->m_range_bits)
838 map = linemap_check_ordinary
839 (const_cast <line_map *>
840 (linemap_add (set, LC_RENAME,
841 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
842 ORDINARY_MAP_FILE_NAME (map),
843 to_line)));
844 map->m_column_and_range_bits = column_bits;
845 map->m_range_bits = range_bits;
846 r = (MAP_START_LOCATION (map)
847 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
848 << column_bits));
850 else
851 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
853 /* Locations of ordinary tokens are always lower than locations of
854 macro tokens. */
855 if (r >= LINE_MAP_MAX_LOCATION)
857 overflowed:
858 /* Remember we overflowed. */
859 set->highest_line = set->highest_location = LINE_MAP_MAX_LOCATION - 1;
860 /* No column numbers! */
861 set->max_column_hint = 1;
862 return 0;
865 set->highest_line = r;
866 if (r > set->highest_location)
867 set->highest_location = r;
868 set->max_column_hint = max_column_hint;
870 /* At this point, we expect one of:
871 (a) the normal case: a "pure" location with 0 range bits, or
872 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
873 columns anymore (or ranges), or
874 (c) we're in a region with a column hint exceeding
875 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
876 with column_bits == 0. */
877 linemap_assert (pure_location_p (set, r)
878 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
879 || map->m_column_and_range_bits == 0);
880 linemap_assert (SOURCE_LINE (map, r) == to_line);
881 return r;
884 /* Encode and return a location_t from a column number. The
885 source line considered is the last source line used to call
886 linemap_line_start, i.e, the last source line which a location was
887 encoded from. */
889 location_t
890 linemap_position_for_column (line_maps *set, unsigned int to_column)
892 location_t r = set->highest_line;
894 linemap_assert
895 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
897 if (to_column >= set->max_column_hint)
899 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
900 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
902 /* Running low on location_ts - disable column numbers. */
903 return r;
905 else
907 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
908 with some space to spare. This may or may not lead to a new
909 linemap being created. */
910 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
911 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
912 map = LINEMAPS_LAST_ORDINARY_MAP (set);
913 if (map->m_column_and_range_bits == 0)
915 /* ...then the linemap has column-tracking disabled,
916 presumably due to exceeding either
917 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
918 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
919 Return the start of the linemap, which encodes column 0, for
920 the whole line. */
921 return r;
925 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
926 r = r + (to_column << map->m_range_bits);
927 if (r >= set->highest_location)
928 set->highest_location = r;
929 return r;
932 /* Encode and return a source location from a given line and
933 column. */
935 location_t
936 linemap_position_for_line_and_column (line_maps *set,
937 const line_map_ordinary *ord_map,
938 linenum_type line,
939 unsigned column)
941 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
943 location_t r = MAP_START_LOCATION (ord_map);
944 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
945 << ord_map->m_column_and_range_bits);
946 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
947 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
948 << ord_map->m_range_bits);
949 location_t upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
950 if (r >= upper_limit)
951 r = upper_limit - 1;
952 if (r > set->highest_location)
953 set->highest_location = r;
954 return r;
957 /* Encode and return a location_t starting from location LOC and
958 shifting it by COLUMN_OFFSET columns. This function does not support
959 virtual locations. */
961 location_t
962 linemap_position_for_loc_and_offset (line_maps *set,
963 location_t loc,
964 unsigned int column_offset)
966 const line_map_ordinary * map = NULL;
968 if (IS_ADHOC_LOC (loc))
969 loc = get_location_from_adhoc_loc (set, loc);
971 /* This function does not support virtual locations yet. */
972 if (linemap_location_from_macro_expansion_p (set, loc))
973 return loc;
975 if (column_offset == 0
976 /* Adding an offset to a reserved location (like
977 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
978 sense. So let's leave the location intact in that case. */
979 || loc < RESERVED_LOCATION_COUNT)
980 return loc;
982 /* We find the real location and shift it. */
983 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
984 /* The new location (loc + offset) should be higher than the first
985 location encoded by MAP. This can fail if the line information
986 is messed up because of line directives (see PR66415). */
987 if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
988 return loc;
990 linenum_type line = SOURCE_LINE (map, loc);
991 unsigned int column = SOURCE_COLUMN (map, loc);
993 /* If MAP is not the last line map of its set, then the new location
994 (loc + offset) should be less than the first location encoded by
995 the next line map of the set. Otherwise, we try to encode the
996 location in the next map. */
997 for (; map != LINEMAPS_LAST_ORDINARY_MAP (set)
998 && (loc + (column_offset << map->m_range_bits)
999 >= MAP_START_LOCATION (map + 1)); map++)
1000 /* If the next map is a different file, or starts in a higher line, we
1001 cannot encode the location there. */
1002 if ((map + 1)->reason != LC_RENAME
1003 || line < ORDINARY_MAP_STARTING_LINE_NUMBER (map + 1)
1004 || 0 != strcmp (LINEMAP_FILE (map + 1), LINEMAP_FILE (map)))
1005 return loc;
1007 column += column_offset;
1009 /* Bail out if the column is not representable within the existing
1010 linemap. */
1011 if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
1012 return loc;
1014 location_t r =
1015 linemap_position_for_line_and_column (set, map, line, column);
1016 if (linemap_assert_fails (r <= set->highest_location)
1017 || linemap_assert_fails (map == linemap_lookup (set, r)))
1018 return loc;
1020 return r;
1023 /* Given a virtual source location yielded by a map (either an
1024 ordinary or a macro map), returns that map. */
1026 const struct line_map*
1027 linemap_lookup (const line_maps *set, location_t line)
1029 if (IS_ADHOC_LOC (line))
1030 line = get_location_from_adhoc_loc (set, line);
1031 if (linemap_location_from_macro_expansion_p (set, line))
1032 return linemap_macro_map_lookup (set, line);
1033 return linemap_ordinary_map_lookup (set, line);
1036 /* Given a source location yielded by an ordinary map, returns that
1037 map. Since the set is built chronologically, the logical lines are
1038 monotonic increasing, and so the list is sorted and we can use a
1039 binary search. */
1041 static const line_map_ordinary *
1042 linemap_ordinary_map_lookup (const line_maps *set, location_t line)
1044 if (IS_ADHOC_LOC (line))
1045 line = get_location_from_adhoc_loc (set, line);
1047 if (set == NULL || line < RESERVED_LOCATION_COUNT)
1048 return NULL;
1050 unsigned mn = LINEMAPS_ORDINARY_CACHE (set);
1051 unsigned mx = LINEMAPS_ORDINARY_USED (set);
1053 const line_map_ordinary *cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
1054 /* We should get a segfault if no line_maps have been added yet. */
1055 if (line >= MAP_START_LOCATION (cached))
1057 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
1058 return cached;
1060 else
1062 mx = mn;
1063 mn = 0;
1066 while (mx - mn > 1)
1068 unsigned md = (mn + mx) / 2;
1069 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
1070 mx = md;
1071 else
1072 mn = md;
1075 LINEMAPS_ORDINARY_CACHE (set) = mn;
1076 const line_map_ordinary *result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
1077 linemap_assert (line >= MAP_START_LOCATION (result));
1078 return result;
1081 /* Given a source location yielded by a macro map, returns that map.
1082 Since the set is built chronologically, the logical lines are
1083 monotonic decreasing, and so the list is sorted and we can use a
1084 binary search. */
1086 static const line_map_macro *
1087 linemap_macro_map_lookup (const line_maps *set, location_t line)
1089 if (IS_ADHOC_LOC (line))
1090 line = get_location_from_adhoc_loc (set, line);
1092 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1094 if (set == NULL)
1095 return NULL;
1097 unsigned ix = linemap_lookup_macro_index (set, line);
1098 const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix);
1099 linemap_assert (MAP_START_LOCATION (result) <= line);
1101 return result;
1104 unsigned
1105 linemap_lookup_macro_index (const line_maps *set, location_t line)
1107 unsigned mn = LINEMAPS_MACRO_CACHE (set);
1108 unsigned mx = LINEMAPS_MACRO_USED (set);
1109 const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1111 if (line >= MAP_START_LOCATION (cached))
1113 if (line < (MAP_START_LOCATION (cached)
1114 + MACRO_MAP_NUM_MACRO_TOKENS (cached)))
1115 return mn;
1116 mx = mn - 1;
1117 mn = 0;
1120 while (mn < mx)
1122 unsigned md = (mx + mn) / 2;
1123 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1124 mn = md + 1;
1125 else
1126 mx = md;
1129 LINEMAPS_MACRO_CACHE (set) = mx;
1130 return mx;
1133 /* Return TRUE if MAP encodes locations coming from a macro
1134 replacement-list at macro expansion point. */
1136 bool
1137 linemap_macro_expansion_map_p (const struct line_map *map)
1139 return map && !MAP_ORDINARY_P (map);
1142 /* If LOCATION is the locus of a token in a replacement-list of a
1143 macro expansion return the location of the macro expansion point.
1145 Read the comments of struct line_map and struct line_map_macro in
1146 line-map.h to understand what a macro expansion point is. */
1148 static location_t
1149 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1150 location_t location ATTRIBUTE_UNUSED)
1152 linemap_assert (linemap_macro_expansion_map_p (map)
1153 && location >= MAP_START_LOCATION (map));
1155 /* Make sure LOCATION is correct. */
1156 linemap_assert ((location - MAP_START_LOCATION (map))
1157 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1159 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1162 /* LOCATION is the source location of a token that belongs to a macro
1163 replacement-list as part of the macro expansion denoted by MAP.
1165 Return the location of the token at the definition point of the
1166 macro. */
1168 static location_t
1169 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1170 location_t location)
1172 unsigned token_no;
1174 linemap_assert (linemap_macro_expansion_map_p (map)
1175 && location >= MAP_START_LOCATION (map));
1176 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1178 token_no = location - MAP_START_LOCATION (map);
1179 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1181 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1183 return location;
1186 /* If LOCATION is the locus of a token that is an argument of a
1187 function-like macro M and appears in the expansion of M, return the
1188 locus of that argument in the context of the caller of M.
1190 In other words, this returns the xI location presented in the
1191 comments of line_map_macro above. */
1192 location_t
1193 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1194 const line_map_macro* map,
1195 location_t location)
1197 unsigned token_no;
1199 if (IS_ADHOC_LOC (location))
1200 location = get_location_from_adhoc_loc (set, location);
1202 linemap_assert (linemap_macro_expansion_map_p (map)
1203 && location >= MAP_START_LOCATION (map));
1204 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1205 linemap_assert (!IS_ADHOC_LOC (location));
1207 token_no = location - MAP_START_LOCATION (map);
1208 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1210 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1212 return location;
1215 /* Return the source line number corresponding to source location
1216 LOCATION. SET is the line map set LOCATION comes from. If
1217 LOCATION is the source location of token that is part of the
1218 replacement-list of a macro expansion return the line number of the
1219 macro expansion point. */
1222 linemap_get_expansion_line (line_maps *set,
1223 location_t location)
1225 const line_map_ordinary *map = NULL;
1227 if (IS_ADHOC_LOC (location))
1228 location = get_location_from_adhoc_loc (set, location);
1230 if (location < RESERVED_LOCATION_COUNT)
1231 return 0;
1233 location =
1234 linemap_macro_loc_to_exp_point (set, location, &map);
1236 return SOURCE_LINE (map, location);
1239 /* Return the path of the file corresponding to source code location
1240 LOCATION.
1242 If LOCATION is the source location of token that is part of the
1243 replacement-list of a macro expansion return the file path of the
1244 macro expansion point.
1246 SET is the line map set LOCATION comes from. */
1248 const char*
1249 linemap_get_expansion_filename (line_maps *set,
1250 location_t location)
1252 const struct line_map_ordinary *map = NULL;
1254 if (IS_ADHOC_LOC (location))
1255 location = get_location_from_adhoc_loc (set, location);
1257 if (location < RESERVED_LOCATION_COUNT)
1258 return NULL;
1260 linemap_macro_loc_to_exp_point (set, location, &map);
1262 return LINEMAP_FILE (map);
1265 /* Return the name of the macro associated to MACRO_MAP. */
1267 const char*
1268 linemap_map_get_macro_name (const line_map_macro *macro_map)
1270 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1271 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1274 /* Return a positive value if LOCATION is the locus of a token that is
1275 located in a system header, O otherwise. It returns 1 if LOCATION
1276 is the locus of a token that is located in a system header, and 2
1277 if LOCATION is the locus of a token located in a C system header
1278 that therefore needs to be extern "C" protected in C++.
1280 Note that this function returns 1 if LOCATION belongs to a token
1281 that is part of a macro replacement-list defined in a system
1282 header, but expanded in a non-system file. */
1285 linemap_location_in_system_header_p (line_maps *set,
1286 location_t location)
1288 const struct line_map *map = NULL;
1290 if (IS_ADHOC_LOC (location))
1291 location = get_location_from_adhoc_loc (set, location);
1293 if (location < RESERVED_LOCATION_COUNT)
1294 return false;
1296 /* Let's look at where the token for LOCATION comes from. */
1297 while (true)
1299 map = linemap_lookup (set, location);
1300 if (map != NULL)
1302 if (!linemap_macro_expansion_map_p (map))
1303 /* It's a normal token. */
1304 return LINEMAP_SYSP (linemap_check_ordinary (map));
1305 else
1307 const line_map_macro *macro_map = linemap_check_macro (map);
1309 /* It's a token resulting from a macro expansion. */
1310 location_t loc =
1311 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1312 if (loc < RESERVED_LOCATION_COUNT)
1313 /* This token might come from a built-in macro. Let's
1314 look at where that macro got expanded. */
1315 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1316 else
1317 location = loc;
1320 else
1321 break;
1323 return false;
1326 /* Return TRUE if LOCATION is a source code location of a token that is part of
1327 a macro expansion, FALSE otherwise. */
1329 bool
1330 linemap_location_from_macro_expansion_p (const class line_maps *set,
1331 location_t location)
1333 if (IS_ADHOC_LOC (location))
1334 location = get_location_from_adhoc_loc (set, location);
1336 return location >= LINEMAPS_MACRO_LOWEST_LOCATION (set);
1339 /* Given two virtual locations *LOC0 and *LOC1, return the first
1340 common macro map in their macro expansion histories. Return NULL
1341 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1342 virtual location of the token inside the resulting macro. */
1344 static const struct line_map*
1345 first_map_in_common_1 (line_maps *set,
1346 location_t *loc0,
1347 location_t *loc1)
1349 location_t l0 = *loc0, l1 = *loc1;
1350 const struct line_map *map0 = linemap_lookup (set, l0);
1351 if (IS_ADHOC_LOC (l0))
1352 l0 = get_location_from_adhoc_loc (set, l0);
1354 const struct line_map *map1 = linemap_lookup (set, l1);
1355 if (IS_ADHOC_LOC (l1))
1356 l1 = get_location_from_adhoc_loc (set, l1);
1358 while (linemap_macro_expansion_map_p (map0)
1359 && linemap_macro_expansion_map_p (map1)
1360 && (map0 != map1))
1362 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1364 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1365 l0);
1366 map0 = linemap_lookup (set, l0);
1368 else
1370 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1371 l1);
1372 map1 = linemap_lookup (set, l1);
1376 if (map0 == map1)
1378 *loc0 = l0;
1379 *loc1 = l1;
1380 return map0;
1382 return NULL;
1385 /* Given two virtual locations LOC0 and LOC1, return the first common
1386 macro map in their macro expansion histories. Return NULL if no
1387 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1388 virtual location of the token inside the resulting macro, upon
1389 return of a non-NULL result. */
1391 const struct line_map*
1392 first_map_in_common (line_maps *set,
1393 location_t loc0,
1394 location_t loc1,
1395 location_t *res_loc0,
1396 location_t *res_loc1)
1398 *res_loc0 = loc0;
1399 *res_loc1 = loc1;
1401 return first_map_in_common_1 (set, res_loc0, res_loc1);
1404 /* Return a positive value if PRE denotes the location of a token that
1405 comes before the token of POST, 0 if PRE denotes the location of
1406 the same token as the token for POST, and a negative value
1407 otherwise. */
1410 linemap_compare_locations (line_maps *set,
1411 location_t pre,
1412 location_t post)
1414 bool pre_virtual_p, post_virtual_p;
1415 location_t l0 = pre, l1 = post;
1417 if (IS_ADHOC_LOC (l0))
1418 l0 = get_location_from_adhoc_loc (set, l0);
1419 if (IS_ADHOC_LOC (l1))
1420 l1 = get_location_from_adhoc_loc (set, l1);
1422 if (l0 == l1)
1423 return 0;
1425 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1426 l0 = linemap_resolve_location (set, l0,
1427 LRK_MACRO_EXPANSION_POINT,
1428 NULL);
1430 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1431 l1 = linemap_resolve_location (set, l1,
1432 LRK_MACRO_EXPANSION_POINT,
1433 NULL);
1435 if (l0 == l1
1436 && pre_virtual_p
1437 && post_virtual_p)
1439 /* So pre and post represent two tokens that are present in a
1440 same macro expansion. Let's see if the token for pre was
1441 before the token for post in that expansion. */
1442 const struct line_map *map =
1443 first_map_in_common (set, pre, post, &l0, &l1);
1445 if (map == NULL)
1446 /* This should not be possible while we have column information, but if
1447 we don't, the tokens could be from separate macro expansions on the
1448 same line. */
1449 gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS);
1450 else
1452 unsigned i0 = l0 - MAP_START_LOCATION (map);
1453 unsigned i1 = l1 - MAP_START_LOCATION (map);
1454 return i1 - i0;
1458 if (IS_ADHOC_LOC (l0))
1459 l0 = get_location_from_adhoc_loc (set, l0);
1460 if (IS_ADHOC_LOC (l1))
1461 l1 = get_location_from_adhoc_loc (set, l1);
1463 return l1 - l0;
1466 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1468 static void
1469 trace_include (const class line_maps *set, const line_map_ordinary *map)
1471 unsigned int i = set->depth;
1473 while (--i)
1474 putc ('.', stderr);
1476 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1479 /* Return the spelling location of the token wherever it comes from,
1480 whether part of a macro definition or not.
1482 This is a subroutine for linemap_resolve_location. */
1484 static location_t
1485 linemap_macro_loc_to_spelling_point (line_maps *set,
1486 location_t location,
1487 const line_map_ordinary **original_map)
1489 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1491 while (true)
1493 const struct line_map *map = linemap_lookup (set, location);
1494 if (!map || MAP_ORDINARY_P (map))
1496 if (original_map)
1497 *original_map = (const line_map_ordinary *)map;
1498 break;
1501 location = linemap_macro_map_loc_unwind_toward_spelling
1502 (set, linemap_check_macro (map), location);
1505 return location;
1508 /* If LOCATION is the source location of a token that belongs to a
1509 macro replacement-list -- as part of a macro expansion -- then
1510 return the location of the token at the definition point of the
1511 macro. Otherwise, return LOCATION. SET is the set of maps
1512 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1513 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1514 returned location comes from.
1516 This is a subroutine of linemap_resolve_location. */
1518 static location_t
1519 linemap_macro_loc_to_def_point (line_maps *set,
1520 location_t location,
1521 const line_map_ordinary **original_map)
1523 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1525 for (;;)
1527 location_t caret_loc = location;
1528 if (IS_ADHOC_LOC (caret_loc))
1529 caret_loc = get_location_from_adhoc_loc (set, caret_loc);
1531 const line_map *map = linemap_lookup (set, caret_loc);
1532 if (!map || MAP_ORDINARY_P (map))
1534 if (original_map)
1535 *original_map = (const line_map_ordinary *)map;
1536 break;
1539 location = linemap_macro_map_loc_to_def_point
1540 (linemap_check_macro (map), caret_loc);
1543 return location;
1546 /* If LOCATION is the source location of a token that belongs to a
1547 macro replacement-list -- at a macro expansion point -- then return
1548 the location of the topmost expansion point of the macro. We say
1549 topmost because if we are in the context of a nested macro
1550 expansion, the function returns the source location of the first
1551 macro expansion that triggered the nested expansions.
1553 Otherwise, return LOCATION. SET is the set of maps location come
1554 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1555 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1556 location comes from.
1558 This is a subroutine of linemap_resolve_location. */
1560 static location_t
1561 linemap_macro_loc_to_exp_point (line_maps *set,
1562 location_t location,
1563 const line_map_ordinary **original_map)
1565 struct line_map *map;
1567 if (IS_ADHOC_LOC (location))
1568 location = get_location_from_adhoc_loc (set, location);
1570 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1572 while (true)
1574 map = const_cast <line_map *> (linemap_lookup (set, location));
1575 if (!linemap_macro_expansion_map_p (map))
1576 break;
1577 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1578 location);
1581 if (original_map)
1582 *original_map = linemap_check_ordinary (map);
1583 return location;
1586 /* Resolve a virtual location into either a spelling location, an
1587 expansion point location or a token argument replacement point
1588 location. Return the map that encodes the virtual location as well
1589 as the resolved location.
1591 If LOC is *NOT* the location of a token resulting from the
1592 expansion of a macro, then the parameter LRK (which stands for
1593 Location Resolution Kind) is ignored and the resulting location
1594 just equals the one given in argument.
1596 Now if LOC *IS* the location of a token resulting from the
1597 expansion of a macro, this is what happens.
1599 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1600 -------------------------------
1602 The virtual location is resolved to the first macro expansion point
1603 that led to this macro expansion.
1605 * If LRK is set to LRK_SPELLING_LOCATION
1606 -------------------------------------
1608 The virtual location is resolved to the locus where the token has
1609 been spelled in the source. This can follow through all the macro
1610 expansions that led to the token.
1612 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1613 --------------------------------------
1615 The virtual location is resolved to the locus of the token in the
1616 context of the macro definition.
1618 If LOC is the locus of a token that is an argument of a
1619 function-like macro [replacing a parameter in the replacement list
1620 of the macro] the virtual location is resolved to the locus of the
1621 parameter that is replaced, in the context of the definition of the
1622 macro.
1624 If LOC is the locus of a token that is not an argument of a
1625 function-like macro, then the function behaves as if LRK was set to
1626 LRK_SPELLING_LOCATION.
1628 If MAP is not NULL, *MAP is set to the map encoding the
1629 returned location. Note that if the returned location wasn't originally
1630 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1631 resolves to a location reserved for the client code, like
1632 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1634 location_t
1635 linemap_resolve_location (line_maps *set,
1636 location_t loc,
1637 enum location_resolution_kind lrk,
1638 const line_map_ordinary **map)
1640 location_t locus = loc;
1641 if (IS_ADHOC_LOC (loc))
1642 locus = get_location_from_adhoc_loc (set, loc);
1644 if (locus < RESERVED_LOCATION_COUNT)
1646 /* A reserved location wasn't encoded in a map. Let's return a
1647 NULL map here, just like what linemap_ordinary_map_lookup
1648 does. */
1649 if (map)
1650 *map = NULL;
1651 return loc;
1654 switch (lrk)
1656 case LRK_MACRO_EXPANSION_POINT:
1657 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1658 break;
1659 case LRK_SPELLING_LOCATION:
1660 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1661 break;
1662 case LRK_MACRO_DEFINITION_LOCATION:
1663 loc = linemap_macro_loc_to_def_point (set, loc, map);
1664 break;
1665 default:
1666 abort ();
1668 return loc;
1671 /* TRUE if LOCATION is a source code location of a token that is part of the
1672 definition of a macro, FALSE otherwise. */
1674 bool
1675 linemap_location_from_macro_definition_p (line_maps *set,
1676 location_t loc)
1678 if (IS_ADHOC_LOC (loc))
1679 loc = get_location_from_adhoc_loc (set, loc);
1681 if (!linemap_location_from_macro_expansion_p (set, loc))
1682 return false;
1684 while (true)
1686 const struct line_map_macro *map
1687 = linemap_check_macro (linemap_lookup (set, loc));
1689 location_t s_loc
1690 = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
1691 if (linemap_location_from_macro_expansion_p (set, s_loc))
1692 loc = s_loc;
1693 else
1695 location_t def_loc
1696 = linemap_macro_map_loc_to_def_point (map, loc);
1697 return s_loc == def_loc;
1703 Suppose that LOC is the virtual location of a token T coming from
1704 the expansion of a macro M. This function then steps up to get the
1705 location L of the point where M got expanded. If L is a spelling
1706 location inside a macro expansion M', then this function returns
1707 the locus of the point where M' was expanded. Said otherwise, this
1708 function returns the location of T in the context that triggered
1709 the expansion of M.
1711 *LOC_MAP must be set to the map of LOC. This function then sets it
1712 to the map of the returned location. */
1714 location_t
1715 linemap_unwind_toward_expansion (line_maps *set,
1716 location_t loc,
1717 const struct line_map **map)
1719 location_t resolved_location;
1720 const line_map_macro *macro_map = linemap_check_macro (*map);
1721 const struct line_map *resolved_map;
1723 if (IS_ADHOC_LOC (loc))
1724 loc = get_location_from_adhoc_loc (set, loc);
1726 resolved_location =
1727 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1728 resolved_map = linemap_lookup (set, resolved_location);
1730 if (!linemap_macro_expansion_map_p (resolved_map))
1732 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1733 resolved_map = linemap_lookup (set, resolved_location);
1736 *map = resolved_map;
1737 return resolved_location;
1740 /* If LOC is the virtual location of a token coming from the expansion
1741 of a macro M and if its spelling location is reserved (e.g, a
1742 location for a built-in token), then this function unwinds (using
1743 linemap_unwind_toward_expansion) the location until a location that
1744 is not reserved and is not in a system header is reached. In other
1745 words, this unwinds the reserved location until a location that is
1746 in real source code is reached.
1748 Otherwise, if the spelling location for LOC is not reserved or if
1749 LOC doesn't come from the expansion of a macro, the function
1750 returns LOC as is and *MAP is not touched.
1752 *MAP is set to the map of the returned location if the later is
1753 different from LOC. */
1754 location_t
1755 linemap_unwind_to_first_non_reserved_loc (line_maps *set,
1756 location_t loc,
1757 const struct line_map **map)
1759 location_t resolved_loc;
1760 const struct line_map *map0 = NULL;
1761 const line_map_ordinary *map1 = NULL;
1763 if (IS_ADHOC_LOC (loc))
1764 loc = get_location_from_adhoc_loc (set, loc);
1766 map0 = linemap_lookup (set, loc);
1767 if (!linemap_macro_expansion_map_p (map0))
1768 return loc;
1770 resolved_loc = linemap_resolve_location (set, loc,
1771 LRK_SPELLING_LOCATION,
1772 &map1);
1774 if (resolved_loc >= RESERVED_LOCATION_COUNT
1775 && !LINEMAP_SYSP (map1))
1776 return loc;
1778 while (linemap_macro_expansion_map_p (map0)
1779 && (resolved_loc < RESERVED_LOCATION_COUNT
1780 || LINEMAP_SYSP (map1)))
1782 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1783 resolved_loc = linemap_resolve_location (set, loc,
1784 LRK_SPELLING_LOCATION,
1785 &map1);
1788 if (map != NULL)
1789 *map = map0;
1790 return loc;
1793 /* Expand source code location LOC and return a user readable source
1794 code location. LOC must be a spelling (non-virtual) location. If
1795 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1796 location is returned. */
1798 expanded_location
1799 linemap_expand_location (line_maps *set,
1800 const struct line_map *map,
1801 location_t loc)
1804 expanded_location xloc;
1806 memset (&xloc, 0, sizeof (xloc));
1807 if (IS_ADHOC_LOC (loc))
1809 xloc.data = get_data_from_adhoc_loc (set, loc);
1810 loc = get_location_from_adhoc_loc (set, loc);
1813 if (loc < RESERVED_LOCATION_COUNT)
1814 /* The location for this token wasn't generated from a line map.
1815 It was probably a location for a builtin token, chosen by some
1816 client code. Let's not try to expand the location in that
1817 case. */;
1818 else if (map == NULL)
1819 /* We shouldn't be getting a NULL map with a location that is not
1820 reserved by the client code. */
1821 abort ();
1822 else
1824 /* MAP must be an ordinary map and LOC must be non-virtual,
1825 encoded into this map, obviously; the accessors used on MAP
1826 below ensure it is ordinary. Let's just assert the
1827 non-virtualness of LOC here. */
1828 if (linemap_location_from_macro_expansion_p (set, loc))
1829 abort ();
1831 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1833 xloc.file = LINEMAP_FILE (ord_map);
1834 xloc.line = SOURCE_LINE (ord_map, loc);
1835 xloc.column = SOURCE_COLUMN (ord_map, loc);
1836 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1839 return xloc;
1843 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1844 is NULL, use stderr. IS_MACRO is true if the caller wants to
1845 dump a macro map, false otherwise. */
1847 void
1848 linemap_dump (FILE *stream, class line_maps *set, unsigned ix, bool is_macro)
1850 const char *const lc_reasons_v[LC_HWM]
1851 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1852 "LC_ENTER_MACRO", "LC_MODULE" };
1853 const line_map *map;
1854 unsigned reason;
1856 if (stream == NULL)
1857 stream = stderr;
1859 if (!is_macro)
1861 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1862 reason = linemap_check_ordinary (map)->reason;
1864 else
1866 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1867 reason = LC_ENTER_MACRO;
1870 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1871 ix, (void *) map, map->start_location,
1872 reason < LC_HWM ? lc_reasons_v[reason] : "???",
1873 ((!is_macro
1874 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1875 ? "yes" : "no"));
1876 if (!is_macro)
1878 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1879 const line_map_ordinary *includer_map
1880 = linemap_included_from_linemap (set, ord_map);
1882 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1883 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1884 fprintf (stream, "Included from: [%d] %s\n",
1885 includer_map ? int (includer_map - set->info_ordinary.maps) : -1,
1886 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1888 else
1890 const line_map_macro *macro_map = linemap_check_macro (map);
1891 fprintf (stream, "Macro: %s (%u tokens)\n",
1892 linemap_map_get_macro_name (macro_map),
1893 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1896 fprintf (stream, "\n");
1900 /* Dump debugging information about source location LOC into the file
1901 stream STREAM. SET is the line map set LOC comes from. */
1903 void
1904 linemap_dump_location (line_maps *set,
1905 location_t loc,
1906 FILE *stream)
1908 const line_map_ordinary *map;
1909 location_t location;
1910 const char *path = "", *from = "";
1911 int l = -1, c = -1, s = -1, e = -1;
1913 if (IS_ADHOC_LOC (loc))
1914 loc = get_location_from_adhoc_loc (set, loc);
1916 if (loc == 0)
1917 return;
1919 location =
1920 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1922 if (map == NULL)
1923 /* Only reserved locations can be tolerated in this case. */
1924 linemap_assert (location < RESERVED_LOCATION_COUNT);
1925 else
1927 path = LINEMAP_FILE (map);
1928 l = SOURCE_LINE (map, location);
1929 c = SOURCE_COLUMN (map, location);
1930 s = LINEMAP_SYSP (map) != 0;
1931 e = location != loc;
1932 if (e)
1933 from = "N/A";
1934 else
1936 const line_map_ordinary *from_map
1937 = linemap_included_from_linemap (set, map);
1938 from = from_map ? LINEMAP_FILE (from_map) : "<NULL>";
1942 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1943 E: macro expansion?, LOC: original location, R: resolved location */
1944 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1945 path, from, l, c, s, (void*)map, e, loc, location);
1948 /* Return the highest location emitted for a given file for which
1949 there is a line map in SET. FILE_NAME is the file name to
1950 consider. If the function returns TRUE, *LOC is set to the highest
1951 location emitted for that file. */
1953 bool
1954 linemap_get_file_highest_location (line_maps *set,
1955 const char *file_name,
1956 location_t *loc)
1958 /* If the set is empty or no ordinary map has been created then
1959 there is no file to look for ... */
1960 if (set == NULL || set->info_ordinary.used == 0)
1961 return false;
1963 /* Now look for the last ordinary map created for FILE_NAME. */
1964 int i;
1965 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1967 const char *fname = set->info_ordinary.maps[i].to_file;
1968 if (fname && !filename_cmp (fname, file_name))
1969 break;
1972 if (i < 0)
1973 return false;
1975 /* The highest location for a given map is either the starting
1976 location of the next map minus one, or -- if the map is the
1977 latest one -- the highest location of the set. */
1978 location_t result;
1979 if (i == (int) set->info_ordinary.used - 1)
1980 result = set->highest_location;
1981 else
1982 result = set->info_ordinary.maps[i + 1].start_location - 1;
1984 *loc = result;
1985 return true;
1988 /* Compute and return statistics about the memory consumption of some
1989 parts of the line table SET. */
1991 void
1992 linemap_get_statistics (line_maps *set,
1993 struct linemap_stats *s)
1995 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1996 macro_maps_allocated_size, macro_maps_used_size,
1997 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1999 const line_map_macro *cur_map;
2001 ordinary_maps_allocated_size =
2002 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
2004 ordinary_maps_used_size =
2005 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
2007 macro_maps_allocated_size =
2008 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
2010 for (cur_map = LINEMAPS_MACRO_MAPS (set);
2011 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
2012 ++cur_map)
2014 unsigned i;
2016 linemap_assert (linemap_macro_expansion_map_p (cur_map));
2018 macro_maps_locations_size +=
2019 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (location_t);
2021 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
2023 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
2024 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
2025 duplicated_macro_maps_locations_size +=
2026 sizeof (location_t);
2030 macro_maps_used_size =
2031 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
2033 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
2034 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
2035 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
2036 s->ordinary_maps_used_size = ordinary_maps_used_size;
2037 s->num_expanded_macros = num_expanded_macros_counter;
2038 s->num_macro_tokens = num_macro_tokens_counter;
2039 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
2040 s->macro_maps_allocated_size = macro_maps_allocated_size;
2041 s->macro_maps_locations_size = macro_maps_locations_size;
2042 s->macro_maps_used_size = macro_maps_used_size;
2043 s->duplicated_macro_maps_locations_size =
2044 duplicated_macro_maps_locations_size;
2045 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
2046 * sizeof (struct location_adhoc_data));
2047 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
2051 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
2052 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
2053 specifies how many macro maps to dump. */
2055 void
2056 line_table_dump (FILE *stream, class line_maps *set, unsigned int num_ordinary,
2057 unsigned int num_macro)
2059 unsigned int i;
2061 if (set == NULL)
2062 return;
2064 if (stream == NULL)
2065 stream = stderr;
2067 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
2068 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
2069 fprintf (stream, "Include stack depth: %d\n", set->depth);
2070 fprintf (stream, "Highest location: %u\n", set->highest_location);
2072 if (num_ordinary)
2074 fprintf (stream, "\nOrdinary line maps\n");
2075 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
2076 linemap_dump (stream, set, i, false);
2077 fprintf (stream, "\n");
2080 if (num_macro)
2082 fprintf (stream, "\nMacro line maps\n");
2083 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
2084 linemap_dump (stream, set, i, true);
2085 fprintf (stream, "\n");
2089 /* class rich_location. */
2091 /* Construct a rich_location with location LOC as its initial range. */
2093 rich_location::rich_location (line_maps *set, location_t loc,
2094 const range_label *label) :
2095 m_line_table (set),
2096 m_ranges (),
2097 m_column_override (0),
2098 m_have_expanded_location (false),
2099 m_seen_impossible_fixit (false),
2100 m_fixits_cannot_be_auto_applied (false),
2101 m_escape_on_output (false),
2102 m_fixit_hints (),
2103 m_path (NULL)
2105 add_range (loc, SHOW_RANGE_WITH_CARET, label);
2108 /* The destructor for class rich_location. */
2110 rich_location::~rich_location ()
2112 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2113 delete get_fixit_hint (i);
2116 /* Get location IDX within this rich_location. */
2118 location_t
2119 rich_location::get_loc (unsigned int idx) const
2121 const location_range *locrange = get_range (idx);
2122 return locrange->m_loc;
2125 /* Get range IDX within this rich_location. */
2127 const location_range *
2128 rich_location::get_range (unsigned int idx) const
2130 return &m_ranges[idx];
2133 /* Mutable access to range IDX within this rich_location. */
2135 location_range *
2136 rich_location::get_range (unsigned int idx)
2138 return &m_ranges[idx];
2141 /* Expand location IDX within this rich_location. */
2142 /* Get an expanded_location for this rich_location's primary
2143 location. */
2145 expanded_location
2146 rich_location::get_expanded_location (unsigned int idx)
2148 if (idx == 0)
2150 /* Cache the expansion of the primary location. */
2151 if (!m_have_expanded_location)
2153 m_expanded_location
2154 = linemap_client_expand_location_to_spelling_point
2155 (get_loc (0), LOCATION_ASPECT_CARET);
2156 if (m_column_override)
2157 m_expanded_location.column = m_column_override;
2158 m_have_expanded_location = true;
2161 return m_expanded_location;
2163 else
2164 return linemap_client_expand_location_to_spelling_point
2165 (get_loc (idx), LOCATION_ASPECT_CARET);
2168 /* Set the column of the primary location, with 0 meaning
2169 "don't override it". */
2171 void
2172 rich_location::override_column (int column)
2174 m_column_override = column;
2175 m_have_expanded_location = false;
2178 /* Add the given range. */
2180 void
2181 rich_location::add_range (location_t loc,
2182 enum range_display_kind range_display_kind,
2183 const range_label *label)
2185 location_range range;
2186 range.m_loc = loc;
2187 range.m_range_display_kind = range_display_kind;
2188 range.m_label = label;
2189 m_ranges.push (range);
2192 /* Add or overwrite the location given by IDX, setting its location to LOC,
2193 and setting its m_range_display_kind to RANGE_DISPLAY_KIND.
2195 It must either overwrite an existing location, or add one *exactly* on
2196 the end of the array.
2198 This is primarily for use by gcc when implementing diagnostic format
2199 decoders e.g.
2200 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2201 (which writes the source location of a tree back into location 0 of
2202 the rich_location), and
2203 - the "%C" and "%L" format codes in the Fortran frontend. */
2205 void
2206 rich_location::set_range (unsigned int idx, location_t loc,
2207 enum range_display_kind range_display_kind)
2209 /* We can either overwrite an existing range, or add one exactly
2210 on the end of the array. */
2211 linemap_assert (idx <= m_ranges.count ());
2213 if (idx == m_ranges.count ())
2214 add_range (loc, range_display_kind);
2215 else
2217 location_range *locrange = get_range (idx);
2218 locrange->m_loc = loc;
2219 locrange->m_range_display_kind = range_display_kind;
2222 if (idx == 0)
2223 /* Mark any cached value here as dirty. */
2224 m_have_expanded_location = false;
2227 /* Methods for adding insertion fix-it hints. */
2229 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2230 immediately before the primary range's start location. */
2232 void
2233 rich_location::add_fixit_insert_before (const char *new_content)
2235 add_fixit_insert_before (get_loc (), new_content);
2238 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2239 immediately before the start of WHERE. */
2241 void
2242 rich_location::add_fixit_insert_before (location_t where,
2243 const char *new_content)
2245 location_t start = get_range_from_loc (m_line_table, where).m_start;
2246 maybe_add_fixit (start, start, new_content);
2249 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2250 immediately after the primary range's end-point. */
2252 void
2253 rich_location::add_fixit_insert_after (const char *new_content)
2255 add_fixit_insert_after (get_loc (), new_content);
2258 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2259 immediately after the end-point of WHERE. */
2261 void
2262 rich_location::add_fixit_insert_after (location_t where,
2263 const char *new_content)
2265 location_t finish = get_range_from_loc (m_line_table, where).m_finish;
2266 location_t next_loc
2267 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2269 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2270 its input value. */
2271 if (next_loc == finish)
2273 stop_supporting_fixits ();
2274 return;
2277 maybe_add_fixit (next_loc, next_loc, new_content);
2280 /* Methods for adding removal fix-it hints. */
2282 /* Add a fixit-hint, suggesting removal of the content covered
2283 by range 0. */
2285 void
2286 rich_location::add_fixit_remove ()
2288 add_fixit_remove (get_loc ());
2291 /* Add a fixit-hint, suggesting removal of the content between
2292 the start and finish of WHERE. */
2294 void
2295 rich_location::add_fixit_remove (location_t where)
2297 source_range range = get_range_from_loc (m_line_table, where);
2298 add_fixit_remove (range);
2301 /* Add a fixit-hint, suggesting removal of the content at
2302 SRC_RANGE. */
2304 void
2305 rich_location::add_fixit_remove (source_range src_range)
2307 add_fixit_replace (src_range, "");
2310 /* Add a fixit-hint, suggesting replacement of the content covered
2311 by range 0 with NEW_CONTENT. */
2313 void
2314 rich_location::add_fixit_replace (const char *new_content)
2316 add_fixit_replace (get_loc (), new_content);
2319 /* Methods for adding "replace" fix-it hints. */
2321 /* Add a fixit-hint, suggesting replacement of the content between
2322 the start and finish of WHERE with NEW_CONTENT. */
2324 void
2325 rich_location::add_fixit_replace (location_t where,
2326 const char *new_content)
2328 source_range range = get_range_from_loc (m_line_table, where);
2329 add_fixit_replace (range, new_content);
2332 /* Add a fixit-hint, suggesting replacement of the content at
2333 SRC_RANGE with NEW_CONTENT. */
2335 void
2336 rich_location::add_fixit_replace (source_range src_range,
2337 const char *new_content)
2339 location_t start = get_pure_location (m_line_table, src_range.m_start);
2340 location_t finish = get_pure_location (m_line_table, src_range.m_finish);
2342 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2343 location_t next_loc
2344 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2345 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2346 its input value. */
2347 if (next_loc == finish)
2349 stop_supporting_fixits ();
2350 return;
2352 finish = next_loc;
2354 maybe_add_fixit (start, finish, new_content);
2357 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2359 fixit_hint *
2360 rich_location::get_last_fixit_hint () const
2362 if (m_fixit_hints.count () > 0)
2363 return get_fixit_hint (m_fixit_hints.count () - 1);
2364 else
2365 return NULL;
2368 /* If WHERE is an "awkward" location, then mark this rich_location as not
2369 supporting fixits, purging any thay were already added, and return true.
2371 Otherwise (the common case), return false. */
2373 bool
2374 rich_location::reject_impossible_fixit (location_t where)
2376 /* Fix-its within a rich_location should either all be suggested, or
2377 none of them should be suggested.
2378 Once we've rejected a fixit, we reject any more, even those
2379 with reasonable locations. */
2380 if (m_seen_impossible_fixit)
2381 return true;
2383 if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
2384 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2385 return false;
2387 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2388 location: either one that we can't obtain column information
2389 for (within an ordinary map), or one within a macro expansion. */
2390 stop_supporting_fixits ();
2391 return true;
2394 /* Mark this rich_location as not supporting fixits, purging any that were
2395 already added. */
2397 void
2398 rich_location::stop_supporting_fixits ()
2400 m_seen_impossible_fixit = true;
2402 /* Purge the rich_location of any fix-its that were already added. */
2403 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2404 delete get_fixit_hint (i);
2405 m_fixit_hints.truncate (0);
2408 /* Add HINT to the fix-it hints in this rich_location,
2409 consolidating into the prior fixit if possible. */
2411 void
2412 rich_location::maybe_add_fixit (location_t start,
2413 location_t next_loc,
2414 const char *new_content)
2416 if (reject_impossible_fixit (start))
2417 return;
2418 if (reject_impossible_fixit (next_loc))
2419 return;
2421 /* Only allow fix-it hints that affect a single line in one file.
2422 Compare the end-points. */
2423 expanded_location exploc_start
2424 = linemap_client_expand_location_to_spelling_point (start,
2425 LOCATION_ASPECT_START);
2426 expanded_location exploc_next_loc
2427 = linemap_client_expand_location_to_spelling_point (next_loc,
2428 LOCATION_ASPECT_START);
2429 /* They must be within the same file... */
2430 if (exploc_start.file != exploc_next_loc.file)
2432 stop_supporting_fixits ();
2433 return;
2435 /* ...and on the same line. */
2436 if (exploc_start.line != exploc_next_loc.line)
2438 stop_supporting_fixits ();
2439 return;
2441 /* The columns must be in the correct order. This can fail if the
2442 endpoints straddle the boundary for which the linemap can represent
2443 columns (PR c/82050). */
2444 if (exploc_start.column > exploc_next_loc.column)
2446 stop_supporting_fixits ();
2447 return;
2449 /* If we have very long lines, tokens will eventually fall back to
2450 having column == 0.
2451 We can't handle fix-it hints that use such locations. */
2452 if (exploc_start.column == 0 || exploc_next_loc.column == 0)
2454 stop_supporting_fixits ();
2455 return;
2458 const char *newline = strchr (new_content, '\n');
2459 if (newline)
2461 /* For now, we can only support insertion of whole lines
2462 i.e. starts at start of line, and the newline is at the end of
2463 the insertion point. */
2465 /* It must be an insertion, not a replacement/deletion. */
2466 if (start != next_loc)
2468 stop_supporting_fixits ();
2469 return;
2472 /* The insertion must be at the start of a line. */
2473 if (exploc_start.column != 1)
2475 stop_supporting_fixits ();
2476 return;
2479 /* The newline must be at end of NEW_CONTENT.
2480 We could eventually split up fix-its at newlines if we wanted
2481 to allow more generality (e.g. to allow adding multiple lines
2482 with one add_fixit call. */
2483 if (newline[1] != '\0')
2485 stop_supporting_fixits ();
2486 return;
2490 /* Consolidate neighboring fixits.
2491 Don't consolidate into newline-insertion fixits. */
2492 fixit_hint *prev = get_last_fixit_hint ();
2493 if (prev && !prev->ends_with_newline_p ())
2494 if (prev->maybe_append (start, next_loc, new_content))
2495 return;
2497 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
2500 /* class fixit_hint. */
2502 fixit_hint::fixit_hint (location_t start,
2503 location_t next_loc,
2504 const char *new_content)
2505 : m_start (start),
2506 m_next_loc (next_loc),
2507 m_bytes (xstrdup (new_content)),
2508 m_len (strlen (new_content))
2512 /* Does this fix-it hint affect the given line? */
2514 bool
2515 fixit_hint::affects_line_p (const char *file, int line) const
2517 expanded_location exploc_start
2518 = linemap_client_expand_location_to_spelling_point (m_start,
2519 LOCATION_ASPECT_START);
2520 if (file != exploc_start.file)
2521 return false;
2522 if (line < exploc_start.line)
2523 return false;
2524 expanded_location exploc_next_loc
2525 = linemap_client_expand_location_to_spelling_point (m_next_loc,
2526 LOCATION_ASPECT_START);
2527 if (file != exploc_next_loc.file)
2528 return false;
2529 if (line > exploc_next_loc.line)
2530 return false;
2531 return true;
2534 /* Method for consolidating fix-it hints, for use by
2535 rich_location::maybe_add_fixit.
2536 If possible, merge a pending fix-it hint with the given params
2537 into this one and return true.
2538 Otherwise return false. */
2540 bool
2541 fixit_hint::maybe_append (location_t start,
2542 location_t next_loc,
2543 const char *new_content)
2545 /* For consolidation to be possible, START must be at this hint's
2546 m_next_loc. */
2547 if (start != m_next_loc)
2548 return false;
2550 /* If so, we have neighboring replacements; merge them. */
2551 m_next_loc = next_loc;
2552 size_t extra_len = strlen (new_content);
2553 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2554 memcpy (m_bytes + m_len, new_content, extra_len);
2555 m_len += extra_len;
2556 m_bytes[m_len] = '\0';
2557 return true;
2560 /* Return true iff this hint's content ends with a newline. */
2562 bool
2563 fixit_hint::ends_with_newline_p () const
2565 if (m_len == 0)
2566 return false;
2567 return m_bytes[m_len - 1] == '\n';