Daily bump.
[official-gcc.git] / libcpp / line-map.c
blobe9175dfa307017c81307ec46b365878677fc2e21
1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2016 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 /* Do not pack ranges if locations get higher than this.
35 If you change this, update:
36 gcc.dg/plugin/location_overflow_plugin.c
37 gcc.dg/plugin/location-overflow-test-*.c. */
38 const source_location LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES = 0x50000000;
40 /* Do not track column numbers if locations get higher than this.
41 If you change this, update:
42 gcc.dg/plugin/location_overflow_plugin.c
43 gcc.dg/plugin/location-overflow-test-*.c. */
44 const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
46 /* Highest possible source location encoded within an ordinary or
47 macro map. */
48 const source_location LINE_MAP_MAX_SOURCE_LOCATION = 0x70000000;
50 static void trace_include (const struct line_maps *, const line_map_ordinary *);
51 static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
52 source_location);
53 static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
54 source_location);
55 static source_location linemap_macro_map_loc_to_def_point
56 (const line_map_macro *, source_location);
57 static source_location linemap_macro_map_loc_unwind_toward_spelling
58 (line_maps *set, const line_map_macro *, source_location);
59 static source_location linemap_macro_map_loc_to_exp_point
60 (const line_map_macro *, source_location);
61 static source_location linemap_macro_loc_to_spelling_point
62 (struct line_maps *, source_location, const line_map_ordinary **);
63 static source_location linemap_macro_loc_to_def_point (struct line_maps *,
64 source_location,
65 const line_map_ordinary **);
66 static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
67 source_location,
68 const line_map_ordinary **);
70 /* Counters defined in macro.c. */
71 extern unsigned num_expanded_macros_counter;
72 extern unsigned num_macro_tokens_counter;
74 /* Hash function for location_adhoc_data hashtable. */
76 static hashval_t
77 location_adhoc_data_hash (const void *l)
79 const struct location_adhoc_data *lb =
80 (const struct location_adhoc_data *) l;
81 return ((hashval_t) lb->locus
82 + (hashval_t) lb->src_range.m_start
83 + (hashval_t) lb->src_range.m_finish
84 + (size_t) lb->data);
87 /* Compare function for location_adhoc_data hashtable. */
89 static int
90 location_adhoc_data_eq (const void *l1, const void *l2)
92 const struct location_adhoc_data *lb1 =
93 (const struct location_adhoc_data *) l1;
94 const struct location_adhoc_data *lb2 =
95 (const struct location_adhoc_data *) l2;
96 return (lb1->locus == lb2->locus
97 && lb1->src_range.m_start == lb2->src_range.m_start
98 && lb1->src_range.m_finish == lb2->src_range.m_finish
99 && lb1->data == lb2->data);
102 /* Update the hashtable when location_adhoc_data is reallocated. */
104 static int
105 location_adhoc_data_update (void **slot, void *data)
107 *((char **) slot) += *((long long *) data);
108 return 1;
111 /* Rebuild the hash table from the location adhoc data. */
113 void
114 rebuild_location_adhoc_htab (struct line_maps *set)
116 unsigned i;
117 set->location_adhoc_data_map.htab =
118 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
119 for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
120 htab_find_slot (set->location_adhoc_data_map.htab,
121 set->location_adhoc_data_map.data + i, INSERT);
124 /* Helper function for get_combined_adhoc_loc.
125 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
126 within a source_location, without needing to use an ad-hoc location. */
128 static bool
129 can_be_stored_compactly_p (struct line_maps *set,
130 source_location locus,
131 source_range src_range,
132 void *data)
134 /* If there's an ad-hoc pointer, we can't store it directly in the
135 source_location, we need the lookaside. */
136 if (data)
137 return false;
139 /* We only store ranges that begin at the locus and that are sufficiently
140 "sane". */
141 if (src_range.m_start != locus)
142 return false;
144 if (src_range.m_finish < src_range.m_start)
145 return false;
147 if (src_range.m_start < RESERVED_LOCATION_COUNT)
148 return false;
150 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
151 return false;
153 /* All 3 locations must be within ordinary maps, typically, the same
154 ordinary map. */
155 source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
156 if (locus >= lowest_macro_loc)
157 return false;
158 if (src_range.m_start >= lowest_macro_loc)
159 return false;
160 if (src_range.m_finish >= lowest_macro_loc)
161 return false;
163 /* Passed all tests. */
164 return true;
167 /* Combine LOCUS and DATA to a combined adhoc loc. */
169 source_location
170 get_combined_adhoc_loc (struct line_maps *set,
171 source_location locus,
172 source_range src_range,
173 void *data)
175 struct location_adhoc_data lb;
176 struct location_adhoc_data **slot;
178 if (IS_ADHOC_LOC (locus))
179 locus
180 = set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
181 if (locus == 0 && data == NULL)
182 return 0;
184 /* Any ordinary locations ought to be "pure" at this point: no
185 compressed ranges. */
186 linemap_assert (locus < RESERVED_LOCATION_COUNT
187 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
188 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
189 || pure_location_p (set, locus));
191 /* Consider short-range optimization. */
192 if (can_be_stored_compactly_p (set, locus, src_range, data))
194 /* The low bits ought to be clear. */
195 linemap_assert (pure_location_p (set, locus));
196 const line_map *map = linemap_lookup (set, locus);
197 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
198 unsigned int int_diff = src_range.m_finish - src_range.m_start;
199 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
200 if (col_diff < (1U << ordmap->m_range_bits))
202 source_location packed = locus | col_diff;
203 set->num_optimized_ranges++;
204 return packed;
208 /* We can also compactly store locations
209 when locus == start == finish (and data is NULL). */
210 if (locus == src_range.m_start
211 && locus == src_range.m_finish
212 && !data)
213 return locus;
215 if (!data)
216 set->num_unoptimized_ranges++;
218 lb.locus = locus;
219 lb.src_range = src_range;
220 lb.data = data;
221 slot = (struct location_adhoc_data **)
222 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
223 if (*slot == NULL)
225 if (set->location_adhoc_data_map.curr_loc >=
226 set->location_adhoc_data_map.allocated)
228 char *orig_data = (char *) set->location_adhoc_data_map.data;
229 long long offset;
230 /* Cast away extern "C" from the type of xrealloc. */
231 line_map_realloc reallocator = (set->reallocator
232 ? set->reallocator
233 : (line_map_realloc) xrealloc);
235 if (set->location_adhoc_data_map.allocated == 0)
236 set->location_adhoc_data_map.allocated = 128;
237 else
238 set->location_adhoc_data_map.allocated *= 2;
239 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
240 reallocator (set->location_adhoc_data_map.data,
241 set->location_adhoc_data_map.allocated
242 * sizeof (struct location_adhoc_data));
243 offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
244 if (set->location_adhoc_data_map.allocated > 128)
245 htab_traverse (set->location_adhoc_data_map.htab,
246 location_adhoc_data_update, &offset);
248 *slot = set->location_adhoc_data_map.data
249 + set->location_adhoc_data_map.curr_loc;
250 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
251 = lb;
253 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
256 /* Return the data for the adhoc loc. */
258 void *
259 get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
261 linemap_assert (IS_ADHOC_LOC (loc));
262 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
265 /* Return the location for the adhoc loc. */
267 source_location
268 get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
270 linemap_assert (IS_ADHOC_LOC (loc));
271 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
274 /* Return the source_range for adhoc location LOC. */
276 static source_range
277 get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
279 linemap_assert (IS_ADHOC_LOC (loc));
280 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
283 /* Get the source_range of location LOC, either from the ad-hoc
284 lookaside table, or embedded inside LOC itself. */
286 source_range
287 get_range_from_loc (struct line_maps *set,
288 source_location loc)
290 if (IS_ADHOC_LOC (loc))
291 return get_range_from_adhoc_loc (set, loc);
293 /* For ordinary maps, extract packed range. */
294 if (loc >= RESERVED_LOCATION_COUNT
295 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
296 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
298 const line_map *map = linemap_lookup (set, loc);
299 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
300 source_range result;
301 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
302 result.m_start = loc - offset;
303 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
304 return result;
307 return source_range::from_location (loc);
310 /* Get whether location LOC is a "pure" location, or
311 whether it is an ad-hoc location, or embeds range information. */
313 bool
314 pure_location_p (line_maps *set, source_location loc)
316 if (IS_ADHOC_LOC (loc))
317 return false;
319 const line_map *map = linemap_lookup (set, loc);
320 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
322 if (loc & ((1U << ordmap->m_range_bits) - 1))
323 return false;
325 return true;
328 /* Finalize the location_adhoc_data structure. */
329 void
330 location_adhoc_data_fini (struct line_maps *set)
332 htab_delete (set->location_adhoc_data_map.htab);
335 /* Initialize a line map set. */
337 void
338 linemap_init (struct line_maps *set,
339 source_location builtin_location)
341 memset (set, 0, sizeof (struct line_maps));
342 set->highest_location = RESERVED_LOCATION_COUNT - 1;
343 set->highest_line = RESERVED_LOCATION_COUNT - 1;
344 set->location_adhoc_data_map.htab =
345 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
346 set->builtin_location = builtin_location;
349 /* Check for and warn about line_maps entered but not exited. */
351 void
352 linemap_check_files_exited (struct line_maps *set)
354 const line_map_ordinary *map;
355 /* Depending upon whether we are handling preprocessed input or
356 not, this can be a user error or an ICE. */
357 for (map = LINEMAPS_LAST_ORDINARY_MAP (set);
358 ! MAIN_FILE_P (map);
359 map = INCLUDED_FROM (set, map))
360 fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
361 ORDINARY_MAP_FILE_NAME (map));
364 /* Create a new line map in the line map set SET, and return it.
365 REASON is the reason of creating the map. It determines the type
366 of map created (ordinary or macro map). Note that ordinary maps and
367 macro maps are allocated in different memory location. */
369 static struct line_map *
370 new_linemap (struct line_maps *set,
371 enum lc_reason reason)
373 /* Depending on this variable, a macro map would be allocated in a
374 different memory location than an ordinary map. */
375 bool macro_map_p = (reason == LC_ENTER_MACRO);
376 struct line_map *result;
378 if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
380 /* We ran out of allocated line maps. Let's allocate more. */
381 unsigned alloc_size;
383 /* Cast away extern "C" from the type of xrealloc. */
384 line_map_realloc reallocator = (set->reallocator
385 ? set->reallocator
386 : (line_map_realloc) xrealloc);
387 line_map_round_alloc_size_func round_alloc_size =
388 set->round_alloc_size;
390 size_t map_size = (macro_map_p
391 ? sizeof (line_map_macro)
392 : sizeof (line_map_ordinary));
394 /* We are going to execute some dance to try to reduce the
395 overhead of the memory allocator, in case we are using the
396 ggc-page.c one.
398 The actual size of memory we are going to get back from the
399 allocator is the smallest power of 2 that is greater than the
400 size we requested. So let's consider that size then. */
402 alloc_size =
403 (2 * LINEMAPS_ALLOCATED (set, macro_map_p) + 256)
404 * map_size;
406 /* Get the actual size of memory that is going to be allocated
407 by the allocator. */
408 alloc_size = round_alloc_size (alloc_size);
410 /* Now alloc_size contains the exact memory size we would get if
411 we have asked for the initial alloc_size amount of memory.
412 Let's get back to the number of macro map that amounts
413 to. */
414 LINEMAPS_ALLOCATED (set, macro_map_p) =
415 alloc_size / map_size;
417 /* And now let's really do the re-allocation. */
418 if (macro_map_p)
420 set->info_macro.maps
421 = (line_map_macro *) (*reallocator) (set->info_macro.maps,
422 (LINEMAPS_ALLOCATED (set, macro_map_p)
423 * map_size));
424 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
426 else
428 set->info_ordinary.maps =
429 (line_map_ordinary *) (*reallocator) (set->info_ordinary.maps,
430 (LINEMAPS_ALLOCATED (set, macro_map_p)
431 * map_size));
432 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
434 memset (result, 0,
435 ((LINEMAPS_ALLOCATED (set, macro_map_p)
436 - LINEMAPS_USED (set, macro_map_p))
437 * map_size));
439 else
441 if (macro_map_p)
442 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
443 else
444 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
447 LINEMAPS_USED (set, macro_map_p)++;
449 result->reason = reason;
450 return result;
453 /* Add a mapping of logical source line to physical source file and
454 line number.
456 The text pointed to by TO_FILE must have a lifetime
457 at least as long as the final call to lookup_line (). An empty
458 TO_FILE means standard input. If reason is LC_LEAVE, and
459 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
460 natural values considering the file we are returning to.
462 FROM_LINE should be monotonic increasing across calls to this
463 function. A call to this function can relocate the previous set of
464 maps, so any stored line_map pointers should not be used. */
466 const struct line_map *
467 linemap_add (struct line_maps *set, enum lc_reason reason,
468 unsigned int sysp, const char *to_file, linenum_type to_line)
470 /* Generate a start_location above the current highest_location.
471 If possible, make the low range bits be zero. */
472 source_location start_location;
473 if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
475 start_location = set->highest_location + (1 << set->default_range_bits);
476 if (set->default_range_bits)
477 start_location &= ~((1 << set->default_range_bits) - 1);
478 linemap_assert (0 == (start_location
479 & ((1 << set->default_range_bits) - 1)));
481 else
482 start_location = set->highest_location + 1;
484 linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
485 && (start_location
486 < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));
488 /* When we enter the file for the first time reason cannot be
489 LC_RENAME. */
490 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
492 /* If we are leaving the main file, return a NULL map. */
493 if (reason == LC_LEAVE
494 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
495 && to_file == NULL)
497 set->depth--;
498 return NULL;
501 linemap_assert (reason != LC_ENTER_MACRO);
502 line_map_ordinary *map = linemap_check_ordinary (new_linemap (set, reason));
504 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
505 to_file = "<stdin>";
507 if (reason == LC_RENAME_VERBATIM)
508 reason = LC_RENAME;
510 if (reason == LC_LEAVE)
512 /* When we are just leaving an "included" file, and jump to the next
513 location inside the "includer" right after the #include
514 "included", this variable points the map in use right before the
515 #include "included", inside the same "includer" file. */
516 line_map_ordinary *from;
517 bool error;
519 if (MAIN_FILE_P (map - 1))
521 /* So this _should_ mean we are leaving the main file --
522 effectively ending the compilation unit. But to_file not
523 being NULL means the caller thinks we are leaving to
524 another file. This is an erroneous behaviour but we'll
525 try to recover from it. Let's pretend we are not leaving
526 the main file. */
527 error = true;
528 reason = LC_RENAME;
529 from = map - 1;
531 else
533 /* (MAP - 1) points to the map we are leaving. The
534 map from which (MAP - 1) got included should be the map
535 that comes right before MAP in the same file. */
536 from = INCLUDED_FROM (set, map - 1);
537 error = to_file && filename_cmp (ORDINARY_MAP_FILE_NAME (from),
538 to_file);
541 /* Depending upon whether we are handling preprocessed input or
542 not, this can be a user error or an ICE. */
543 if (error)
544 fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
545 to_file);
547 /* A TO_FILE of NULL is special - we use the natural values. */
548 if (error || to_file == NULL)
550 to_file = ORDINARY_MAP_FILE_NAME (from);
551 to_line = SOURCE_LINE (from, from[1].start_location);
552 sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
556 map->sysp = sysp;
557 map->start_location = start_location;
558 map->to_file = to_file;
559 map->to_line = to_line;
560 LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
561 map->m_column_and_range_bits = 0;
562 map->m_range_bits = 0;
563 set->highest_location = start_location;
564 set->highest_line = start_location;
565 set->max_column_hint = 0;
567 /* This assertion is placed after set->highest_location has
568 been updated, since the latter affects
569 linemap_location_from_macro_expansion_p, which ultimately affects
570 pure_location_p. */
571 linemap_assert (pure_location_p (set, start_location));
573 if (reason == LC_ENTER)
575 map->included_from =
576 set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
577 set->depth++;
578 if (set->trace_includes)
579 trace_include (set, map);
581 else if (reason == LC_RENAME)
582 map->included_from = ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
583 else if (reason == LC_LEAVE)
585 set->depth--;
586 map->included_from =
587 ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
590 return map;
593 /* Returns TRUE if the line table set tracks token locations across
594 macro expansion, FALSE otherwise. */
596 bool
597 linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
599 return LINEMAPS_MACRO_MAPS (set) != NULL;
602 /* Create a macro map. A macro map encodes source locations of tokens
603 that are part of a macro replacement-list, at a macro expansion
604 point. See the extensive comments of struct line_map and struct
605 line_map_macro, in line-map.h.
607 This map shall be created when the macro is expanded. The map
608 encodes the source location of the expansion point of the macro as
609 well as the "original" source location of each token that is part
610 of the macro replacement-list. If a macro is defined but never
611 expanded, it has no macro map. SET is the set of maps the macro
612 map should be part of. MACRO_NODE is the macro which the new macro
613 map should encode source locations for. EXPANSION is the location
614 of the expansion point of MACRO. For function-like macros
615 invocations, it's best to make it point to the closing parenthesis
616 of the macro, rather than the the location of the first character
617 of the macro. NUM_TOKENS is the number of tokens that are part of
618 the replacement-list of MACRO.
620 Note that when we run out of the integer space available for source
621 locations, this function returns NULL. In that case, callers of
622 this function cannot encode {line,column} pairs into locations of
623 macro tokens anymore. */
625 const line_map_macro *
626 linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
627 source_location expansion, unsigned int num_tokens)
629 line_map_macro *map;
630 source_location start_location;
631 /* Cast away extern "C" from the type of xrealloc. */
632 line_map_realloc reallocator = (set->reallocator
633 ? set->reallocator
634 : (line_map_realloc) xrealloc);
636 start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
638 if (start_location <= set->highest_line
639 || start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
640 /* We ran out of macro map space. */
641 return NULL;
643 map = linemap_check_macro (new_linemap (set, LC_ENTER_MACRO));
645 map->start_location = start_location;
646 map->macro = macro_node;
647 map->n_tokens = num_tokens;
648 map->macro_locations
649 = (source_location*) reallocator (NULL,
650 2 * num_tokens
651 * sizeof (source_location));
652 map->expansion = expansion;
653 memset (MACRO_MAP_LOCATIONS (map), 0,
654 num_tokens * sizeof (source_location));
656 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
658 return map;
661 /* Create and return a virtual location for a token that is part of a
662 macro expansion-list at a macro expansion point. See the comment
663 inside struct line_map_macro to see what an expansion-list exactly
666 A call to this function must come after a call to
667 linemap_enter_macro.
669 MAP is the map into which the source location is created. TOKEN_NO
670 is the index of the token in the macro replacement-list, starting
671 at number 0.
673 ORIG_LOC is the location of the token outside of this macro
674 expansion. If the token comes originally from the macro
675 definition, it is the locus in the macro definition; otherwise it
676 is a location in the context of the caller of this macro expansion
677 (which is a virtual location or a source location if the caller is
678 itself a macro expansion or not).
680 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
681 either of the token itself or of a macro parameter that it
682 replaces. */
684 source_location
685 linemap_add_macro_token (const line_map_macro *map,
686 unsigned int token_no,
687 source_location orig_loc,
688 source_location orig_parm_replacement_loc)
690 source_location result;
692 linemap_assert (linemap_macro_expansion_map_p (map));
693 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
695 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
696 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
698 result = MAP_START_LOCATION (map) + token_no;
699 return result;
702 /* Return a source_location for the start (i.e. column==0) of
703 (physical) line TO_LINE in the current source file (as in the
704 most recent linemap_add). MAX_COLUMN_HINT is the highest column
705 number we expect to use in this line (but it does not change
706 the highest_location). */
708 source_location
709 linemap_line_start (struct line_maps *set, linenum_type to_line,
710 unsigned int max_column_hint)
712 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
713 source_location highest = set->highest_location;
714 source_location r;
715 linenum_type last_line =
716 SOURCE_LINE (map, set->highest_line);
717 int line_delta = to_line - last_line;
718 bool add_map = false;
719 linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
720 int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;
722 if (line_delta < 0
723 || (line_delta > 10
724 && line_delta * map->m_column_and_range_bits > 1000)
725 || (max_column_hint >= (1U << effective_column_bits))
726 || (max_column_hint <= 80 && effective_column_bits >= 10)
727 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
728 && map->m_range_bits > 0)
729 || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
730 && (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
731 add_map = true;
732 else
733 max_column_hint = set->max_column_hint;
734 if (add_map)
736 int column_bits;
737 int range_bits;
738 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
739 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
741 /* If the column number is ridiculous or we've allocated a huge
742 number of source_locations, give up on column numbers
743 (and on packed ranges). */
744 max_column_hint = 0;
745 column_bits = 0;
746 range_bits = 0;
747 if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
748 return 0;
750 else
752 column_bits = 7;
753 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
754 range_bits = set->default_range_bits;
755 else
756 range_bits = 0;
757 while (max_column_hint >= (1U << column_bits))
758 column_bits++;
759 max_column_hint = 1U << column_bits;
760 column_bits += range_bits;
762 /* Allocate the new line_map. However, if the current map only has a
763 single line we can sometimes just increase its column_bits instead. */
764 if (line_delta < 0
765 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
766 || SOURCE_COLUMN (map, highest) >= (1U << column_bits)
767 || range_bits < map->m_range_bits)
768 map = linemap_check_ordinary
769 (const_cast <line_map *>
770 (linemap_add (set, LC_RENAME,
771 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
772 ORDINARY_MAP_FILE_NAME (map),
773 to_line)));
774 map->m_column_and_range_bits = column_bits;
775 map->m_range_bits = range_bits;
776 r = (MAP_START_LOCATION (map)
777 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
778 << column_bits));
780 else
781 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
783 /* Locations of ordinary tokens are always lower than locations of
784 macro tokens. */
785 if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
786 return 0;
788 set->highest_line = r;
789 if (r > set->highest_location)
790 set->highest_location = r;
791 set->max_column_hint = max_column_hint;
793 /* At this point, we expect one of:
794 (a) the normal case: a "pure" location with 0 range bits, or
795 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
796 columns anymore (or ranges), or
797 (c) we're in a region with a column hint exceeding
798 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
799 with column_bits == 0. */
800 linemap_assert (pure_location_p (set, r)
801 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
802 || map->m_column_and_range_bits == 0);
803 linemap_assert (SOURCE_LINE (map, r) == to_line);
804 return r;
807 /* Encode and return a source_location from a column number. The
808 source line considered is the last source line used to call
809 linemap_line_start, i.e, the last source line which a location was
810 encoded from. */
812 source_location
813 linemap_position_for_column (struct line_maps *set, unsigned int to_column)
815 source_location r = set->highest_line;
817 linemap_assert
818 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
820 if (to_column >= set->max_column_hint)
822 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
823 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
825 /* Running low on source_locations - disable column numbers. */
826 return r;
828 else
830 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
831 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
834 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
835 r = r + (to_column << map->m_range_bits);
836 if (r >= set->highest_location)
837 set->highest_location = r;
838 return r;
841 /* Encode and return a source location from a given line and
842 column. */
844 source_location
845 linemap_position_for_line_and_column (line_maps *set,
846 const line_map_ordinary *ord_map,
847 linenum_type line,
848 unsigned column)
850 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
852 source_location r = MAP_START_LOCATION (ord_map);
853 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
854 << ord_map->m_column_and_range_bits);
855 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
856 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
857 << ord_map->m_range_bits);
858 source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
859 if (r >= upper_limit)
860 r = upper_limit - 1;
861 if (r > set->highest_location)
862 set->highest_location = r;
863 return r;
866 /* Encode and return a source_location starting from location LOC and
867 shifting it by OFFSET columns. This function does not support
868 virtual locations. */
870 source_location
871 linemap_position_for_loc_and_offset (struct line_maps *set,
872 source_location loc,
873 unsigned int offset)
875 const line_map_ordinary * map = NULL;
877 if (IS_ADHOC_LOC (loc))
878 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
880 /* This function does not support virtual locations yet. */
881 if (linemap_assert_fails
882 (!linemap_location_from_macro_expansion_p (set, loc)))
883 return loc;
885 if (offset == 0
886 /* Adding an offset to a reserved location (like
887 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
888 sense. So let's leave the location intact in that case. */
889 || loc < RESERVED_LOCATION_COUNT)
890 return loc;
892 /* We find the real location and shift it. */
893 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
894 /* The new location (loc + offset) should be higher than the first
895 location encoded by MAP. This can fail if the line information
896 is messed up because of line directives (see PR66415). */
897 if (MAP_START_LOCATION (map) >= loc + offset)
898 return loc;
900 linenum_type line = SOURCE_LINE (map, loc);
901 unsigned int column = SOURCE_COLUMN (map, loc);
903 /* If MAP is not the last line map of its set, then the new location
904 (loc + offset) should be less than the first location encoded by
905 the next line map of the set. Otherwise, we try to encode the
906 location in the next map. */
907 while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
908 && loc + offset >= MAP_START_LOCATION (&map[1]))
910 map = &map[1];
911 /* If the next map starts in a higher line, we cannot encode the
912 location there. */
913 if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
914 return loc;
917 offset += column;
918 if (linemap_assert_fails (offset < (1u << map->m_column_and_range_bits)))
919 return loc;
921 source_location r =
922 linemap_position_for_line_and_column (set, map, line, offset);
923 if (linemap_assert_fails (r <= set->highest_location)
924 || linemap_assert_fails (map == linemap_lookup (set, r)))
925 return loc;
927 return r;
930 /* Given a virtual source location yielded by a map (either an
931 ordinary or a macro map), returns that map. */
933 const struct line_map*
934 linemap_lookup (struct line_maps *set, source_location line)
936 if (IS_ADHOC_LOC (line))
937 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
938 if (linemap_location_from_macro_expansion_p (set, line))
939 return linemap_macro_map_lookup (set, line);
940 return linemap_ordinary_map_lookup (set, line);
943 /* Given a source location yielded by an ordinary map, returns that
944 map. Since the set is built chronologically, the logical lines are
945 monotonic increasing, and so the list is sorted and we can use a
946 binary search. */
948 static const line_map_ordinary *
949 linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
951 unsigned int md, mn, mx;
952 const line_map_ordinary *cached, *result;
954 if (IS_ADHOC_LOC (line))
955 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
957 if (set == NULL || line < RESERVED_LOCATION_COUNT)
958 return NULL;
960 mn = LINEMAPS_ORDINARY_CACHE (set);
961 mx = LINEMAPS_ORDINARY_USED (set);
963 cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
964 /* We should get a segfault if no line_maps have been added yet. */
965 if (line >= MAP_START_LOCATION (cached))
967 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
968 return cached;
970 else
972 mx = mn;
973 mn = 0;
976 while (mx - mn > 1)
978 md = (mn + mx) / 2;
979 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
980 mx = md;
981 else
982 mn = md;
985 LINEMAPS_ORDINARY_CACHE (set) = mn;
986 result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
987 linemap_assert (line >= MAP_START_LOCATION (result));
988 return result;
991 /* Given a source location yielded by a macro map, returns that map.
992 Since the set is built chronologically, the logical lines are
993 monotonic decreasing, and so the list is sorted and we can use a
994 binary search. */
996 static const line_map_macro *
997 linemap_macro_map_lookup (struct line_maps *set, source_location line)
999 unsigned int md, mn, mx;
1000 const struct line_map_macro *cached, *result;
1002 if (IS_ADHOC_LOC (line))
1003 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
1005 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1007 if (set == NULL)
1008 return NULL;
1010 mn = LINEMAPS_MACRO_CACHE (set);
1011 mx = LINEMAPS_MACRO_USED (set);
1012 cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1014 if (line >= MAP_START_LOCATION (cached))
1016 if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
1017 return cached;
1018 mx = mn - 1;
1019 mn = 0;
1022 while (mn < mx)
1024 md = (mx + mn) / 2;
1025 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1026 mn = md + 1;
1027 else
1028 mx = md;
1031 LINEMAPS_MACRO_CACHE (set) = mx;
1032 result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
1033 linemap_assert (MAP_START_LOCATION (result) <= line);
1035 return result;
1038 /* Return TRUE if MAP encodes locations coming from a macro
1039 replacement-list at macro expansion point. */
1041 bool
1042 linemap_macro_expansion_map_p (const struct line_map *map)
1044 if (!map)
1045 return false;
1046 return (map->reason == LC_ENTER_MACRO);
1049 /* If LOCATION is the locus of a token in a replacement-list of a
1050 macro expansion return the location of the macro expansion point.
1052 Read the comments of struct line_map and struct line_map_macro in
1053 line-map.h to understand what a macro expansion point is. */
1055 static source_location
1056 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1057 source_location location ATTRIBUTE_UNUSED)
1059 linemap_assert (linemap_macro_expansion_map_p (map)
1060 && location >= MAP_START_LOCATION (map));
1062 /* Make sure LOCATION is correct. */
1063 linemap_assert ((location - MAP_START_LOCATION (map))
1064 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1066 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1069 /* LOCATION is the source location of a token that belongs to a macro
1070 replacement-list as part of the macro expansion denoted by MAP.
1072 Return the location of the token at the definition point of the
1073 macro. */
1075 static source_location
1076 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1077 source_location location)
1079 unsigned token_no;
1081 linemap_assert (linemap_macro_expansion_map_p (map)
1082 && location >= MAP_START_LOCATION (map));
1083 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1085 token_no = location - MAP_START_LOCATION (map);
1086 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1088 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1090 return location;
1093 /* If LOCATION is the locus of a token that is an argument of a
1094 function-like macro M and appears in the expansion of M, return the
1095 locus of that argument in the context of the caller of M.
1097 In other words, this returns the xI location presented in the
1098 comments of line_map_macro above. */
1099 source_location
1100 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1101 const line_map_macro* map,
1102 source_location location)
1104 unsigned token_no;
1106 if (IS_ADHOC_LOC (location))
1107 location = get_location_from_adhoc_loc (set, location);
1109 linemap_assert (linemap_macro_expansion_map_p (map)
1110 && location >= MAP_START_LOCATION (map));
1111 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1112 linemap_assert (!IS_ADHOC_LOC (location));
1114 token_no = location - MAP_START_LOCATION (map);
1115 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1117 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1119 return location;
1122 /* Return the source line number corresponding to source location
1123 LOCATION. SET is the line map set LOCATION comes from. If
1124 LOCATION is the source location of token that is part of the
1125 replacement-list of a macro expansion return the line number of the
1126 macro expansion point. */
1129 linemap_get_expansion_line (struct line_maps *set,
1130 source_location location)
1132 const line_map_ordinary *map = NULL;
1134 if (IS_ADHOC_LOC (location))
1135 location = set->location_adhoc_data_map.data[location
1136 & MAX_SOURCE_LOCATION].locus;
1138 if (location < RESERVED_LOCATION_COUNT)
1139 return 0;
1141 location =
1142 linemap_macro_loc_to_exp_point (set, location, &map);
1144 return SOURCE_LINE (map, location);
1147 /* Return the path of the file corresponding to source code location
1148 LOCATION.
1150 If LOCATION is the source location of token that is part of the
1151 replacement-list of a macro expansion return the file path of the
1152 macro expansion point.
1154 SET is the line map set LOCATION comes from. */
1156 const char*
1157 linemap_get_expansion_filename (struct line_maps *set,
1158 source_location location)
1160 const struct line_map_ordinary *map = NULL;
1162 if (IS_ADHOC_LOC (location))
1163 location = set->location_adhoc_data_map.data[location
1164 & MAX_SOURCE_LOCATION].locus;
1166 if (location < RESERVED_LOCATION_COUNT)
1167 return NULL;
1169 location =
1170 linemap_macro_loc_to_exp_point (set, location, &map);
1172 return LINEMAP_FILE (map);
1175 /* Return the name of the macro associated to MACRO_MAP. */
1177 const char*
1178 linemap_map_get_macro_name (const line_map_macro *macro_map)
1180 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1181 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1184 /* Return a positive value if LOCATION is the locus of a token that is
1185 located in a system header, O otherwise. It returns 1 if LOCATION
1186 is the locus of a token that is located in a system header, and 2
1187 if LOCATION is the locus of a token located in a C system header
1188 that therefore needs to be extern "C" protected in C++.
1190 Note that this function returns 1 if LOCATION belongs to a token
1191 that is part of a macro replacement-list defined in a system
1192 header, but expanded in a non-system file. */
1195 linemap_location_in_system_header_p (struct line_maps *set,
1196 source_location location)
1198 const struct line_map *map = NULL;
1200 if (IS_ADHOC_LOC (location))
1201 location = set->location_adhoc_data_map.data[location
1202 & MAX_SOURCE_LOCATION].locus;
1204 if (location < RESERVED_LOCATION_COUNT)
1205 return false;
1207 /* Let's look at where the token for LOCATION comes from. */
1208 while (true)
1210 map = linemap_lookup (set, location);
1211 if (map != NULL)
1213 if (!linemap_macro_expansion_map_p (map))
1214 /* It's a normal token. */
1215 return LINEMAP_SYSP (linemap_check_ordinary (map));
1216 else
1218 const line_map_macro *macro_map = linemap_check_macro (map);
1220 /* It's a token resulting from a macro expansion. */
1221 source_location loc =
1222 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1223 if (loc < RESERVED_LOCATION_COUNT)
1224 /* This token might come from a built-in macro. Let's
1225 look at where that macro got expanded. */
1226 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1227 else
1228 location = loc;
1231 else
1232 break;
1234 return false;
1237 /* Return TRUE if LOCATION is a source code location of a token coming
1238 from a macro replacement-list at a macro expansion point, FALSE
1239 otherwise. */
1241 bool
1242 linemap_location_from_macro_expansion_p (const struct line_maps *set,
1243 source_location location)
1245 if (IS_ADHOC_LOC (location))
1246 location = set->location_adhoc_data_map.data[location
1247 & MAX_SOURCE_LOCATION].locus;
1249 linemap_assert (location <= MAX_SOURCE_LOCATION
1250 && (set->highest_location
1251 < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
1252 if (set == NULL)
1253 return false;
1254 return (location > set->highest_location);
1257 /* Given two virtual locations *LOC0 and *LOC1, return the first
1258 common macro map in their macro expansion histories. Return NULL
1259 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1260 virtual location of the token inside the resulting macro. */
1262 static const struct line_map*
1263 first_map_in_common_1 (struct line_maps *set,
1264 source_location *loc0,
1265 source_location *loc1)
1267 source_location l0 = *loc0, l1 = *loc1;
1268 const struct line_map *map0 = linemap_lookup (set, l0),
1269 *map1 = linemap_lookup (set, l1);
1271 while (linemap_macro_expansion_map_p (map0)
1272 && linemap_macro_expansion_map_p (map1)
1273 && (map0 != map1))
1275 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1277 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1278 l0);
1279 map0 = linemap_lookup (set, l0);
1281 else
1283 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1284 l1);
1285 map1 = linemap_lookup (set, l1);
1289 if (map0 == map1)
1291 *loc0 = l0;
1292 *loc1 = l1;
1293 return map0;
1295 return NULL;
1298 /* Given two virtual locations LOC0 and LOC1, return the first common
1299 macro map in their macro expansion histories. Return NULL if no
1300 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1301 virtual location of the token inside the resulting macro, upon
1302 return of a non-NULL result. */
1304 static const struct line_map*
1305 first_map_in_common (struct line_maps *set,
1306 source_location loc0,
1307 source_location loc1,
1308 source_location *res_loc0,
1309 source_location *res_loc1)
1311 *res_loc0 = loc0;
1312 *res_loc1 = loc1;
1314 return first_map_in_common_1 (set, res_loc0, res_loc1);
1317 /* Return a positive value if PRE denotes the location of a token that
1318 comes before the token of POST, 0 if PRE denotes the location of
1319 the same token as the token for POST, and a negative value
1320 otherwise. */
1323 linemap_compare_locations (struct line_maps *set,
1324 source_location pre,
1325 source_location post)
1327 bool pre_virtual_p, post_virtual_p;
1328 source_location l0 = pre, l1 = post;
1330 if (IS_ADHOC_LOC (l0))
1331 l0 = set->location_adhoc_data_map.data[l0 & MAX_SOURCE_LOCATION].locus;
1332 if (IS_ADHOC_LOC (l1))
1333 l1 = set->location_adhoc_data_map.data[l1 & MAX_SOURCE_LOCATION].locus;
1335 if (l0 == l1)
1336 return 0;
1338 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1339 l0 = linemap_resolve_location (set, l0,
1340 LRK_MACRO_EXPANSION_POINT,
1341 NULL);
1343 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1344 l1 = linemap_resolve_location (set, l1,
1345 LRK_MACRO_EXPANSION_POINT,
1346 NULL);
1348 if (l0 == l1
1349 && pre_virtual_p
1350 && post_virtual_p)
1352 /* So pre and post represent two tokens that are present in a
1353 same macro expansion. Let's see if the token for pre was
1354 before the token for post in that expansion. */
1355 unsigned i0, i1;
1356 const struct line_map *map =
1357 first_map_in_common (set, pre, post, &l0, &l1);
1359 if (map == NULL)
1360 /* This should not be possible. */
1361 abort ();
1363 i0 = l0 - MAP_START_LOCATION (map);
1364 i1 = l1 - MAP_START_LOCATION (map);
1365 return i1 - i0;
1368 return l1 - l0;
1371 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1373 static void
1374 trace_include (const struct line_maps *set, const line_map_ordinary *map)
1376 unsigned int i = set->depth;
1378 while (--i)
1379 putc ('.', stderr);
1381 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1384 /* Return the spelling location of the token wherever it comes from,
1385 whether part of a macro definition or not.
1387 This is a subroutine for linemap_resolve_location. */
1389 static source_location
1390 linemap_macro_loc_to_spelling_point (struct line_maps *set,
1391 source_location location,
1392 const line_map_ordinary **original_map)
1394 struct line_map *map;
1395 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1397 while (true)
1399 map = const_cast <line_map *> (linemap_lookup (set, location));
1400 if (!linemap_macro_expansion_map_p (map))
1401 break;
1403 location
1404 = linemap_macro_map_loc_unwind_toward_spelling
1405 (set, linemap_check_macro (map),
1406 location);
1409 if (original_map)
1410 *original_map = linemap_check_ordinary (map);
1411 return location;
1414 /* If LOCATION is the source location of a token that belongs to a
1415 macro replacement-list -- as part of a macro expansion -- then
1416 return the location of the token at the definition point of the
1417 macro. Otherwise, return LOCATION. SET is the set of maps
1418 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1419 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1420 returned location comes from.
1422 This is a subroutine of linemap_resolve_location. */
1424 static source_location
1425 linemap_macro_loc_to_def_point (struct line_maps *set,
1426 source_location location,
1427 const line_map_ordinary **original_map)
1429 struct line_map *map;
1431 if (IS_ADHOC_LOC (location))
1432 location = set->location_adhoc_data_map.data[location
1433 & MAX_SOURCE_LOCATION].locus;
1435 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1437 while (true)
1439 map = const_cast <line_map *> (linemap_lookup (set, location));
1440 if (!linemap_macro_expansion_map_p (map))
1441 break;
1443 location =
1444 linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
1445 location);
1448 if (original_map)
1449 *original_map = linemap_check_ordinary (map);
1450 return location;
1453 /* If LOCATION is the source location of a token that belongs to a
1454 macro replacement-list -- at a macro expansion point -- then return
1455 the location of the topmost expansion point of the macro. We say
1456 topmost because if we are in the context of a nested macro
1457 expansion, the function returns the source location of the first
1458 macro expansion that triggered the nested expansions.
1460 Otherwise, return LOCATION. SET is the set of maps location come
1461 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1462 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1463 location comes from.
1465 This is a subroutine of linemap_resolve_location. */
1467 static source_location
1468 linemap_macro_loc_to_exp_point (struct line_maps *set,
1469 source_location location,
1470 const line_map_ordinary **original_map)
1472 struct line_map *map;
1474 if (IS_ADHOC_LOC (location))
1475 location = set->location_adhoc_data_map.data[location
1476 & MAX_SOURCE_LOCATION].locus;
1478 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1480 while (true)
1482 map = const_cast <line_map *> (linemap_lookup (set, location));
1483 if (!linemap_macro_expansion_map_p (map))
1484 break;
1485 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1486 location);
1489 if (original_map)
1490 *original_map = linemap_check_ordinary (map);
1491 return location;
1494 /* Resolve a virtual location into either a spelling location, an
1495 expansion point location or a token argument replacement point
1496 location. Return the map that encodes the virtual location as well
1497 as the resolved location.
1499 If LOC is *NOT* the location of a token resulting from the
1500 expansion of a macro, then the parameter LRK (which stands for
1501 Location Resolution Kind) is ignored and the resulting location
1502 just equals the one given in argument.
1504 Now if LOC *IS* the location of a token resulting from the
1505 expansion of a macro, this is what happens.
1507 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1508 -------------------------------
1510 The virtual location is resolved to the first macro expansion point
1511 that led to this macro expansion.
1513 * If LRK is set to LRK_SPELLING_LOCATION
1514 -------------------------------------
1516 The virtual location is resolved to the locus where the token has
1517 been spelled in the source. This can follow through all the macro
1518 expansions that led to the token.
1520 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1521 --------------------------------------
1523 The virtual location is resolved to the locus of the token in the
1524 context of the macro definition.
1526 If LOC is the locus of a token that is an argument of a
1527 function-like macro [replacing a parameter in the replacement list
1528 of the macro] the virtual location is resolved to the locus of the
1529 parameter that is replaced, in the context of the definition of the
1530 macro.
1532 If LOC is the locus of a token that is not an argument of a
1533 function-like macro, then the function behaves as if LRK was set to
1534 LRK_SPELLING_LOCATION.
1536 If MAP is not NULL, *MAP is set to the map encoding the
1537 returned location. Note that if the returned location wasn't originally
1538 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1539 resolves to a location reserved for the client code, like
1540 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1542 source_location
1543 linemap_resolve_location (struct line_maps *set,
1544 source_location loc,
1545 enum location_resolution_kind lrk,
1546 const line_map_ordinary **map)
1548 source_location locus = loc;
1549 if (IS_ADHOC_LOC (loc))
1550 locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1552 if (locus < RESERVED_LOCATION_COUNT)
1554 /* A reserved location wasn't encoded in a map. Let's return a
1555 NULL map here, just like what linemap_ordinary_map_lookup
1556 does. */
1557 if (map)
1558 *map = NULL;
1559 return loc;
1562 switch (lrk)
1564 case LRK_MACRO_EXPANSION_POINT:
1565 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1566 break;
1567 case LRK_SPELLING_LOCATION:
1568 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1569 break;
1570 case LRK_MACRO_DEFINITION_LOCATION:
1571 loc = linemap_macro_loc_to_def_point (set, loc, map);
1572 break;
1573 default:
1574 abort ();
1576 return loc;
1580 Suppose that LOC is the virtual location of a token T coming from
1581 the expansion of a macro M. This function then steps up to get the
1582 location L of the point where M got expanded. If L is a spelling
1583 location inside a macro expansion M', then this function returns
1584 the locus of the point where M' was expanded. Said otherwise, this
1585 function returns the location of T in the context that triggered
1586 the expansion of M.
1588 *LOC_MAP must be set to the map of LOC. This function then sets it
1589 to the map of the returned location. */
1591 source_location
1592 linemap_unwind_toward_expansion (struct line_maps *set,
1593 source_location loc,
1594 const struct line_map **map)
1596 source_location resolved_location;
1597 const line_map_macro *macro_map = linemap_check_macro (*map);
1598 const struct line_map *resolved_map;
1600 if (IS_ADHOC_LOC (loc))
1601 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1603 resolved_location =
1604 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1605 resolved_map = linemap_lookup (set, resolved_location);
1607 if (!linemap_macro_expansion_map_p (resolved_map))
1609 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1610 resolved_map = linemap_lookup (set, resolved_location);
1613 *map = resolved_map;
1614 return resolved_location;
1617 /* If LOC is the virtual location of a token coming from the expansion
1618 of a macro M and if its spelling location is reserved (e.g, a
1619 location for a built-in token), then this function unwinds (using
1620 linemap_unwind_toward_expansion) the location until a location that
1621 is not reserved and is not in a system header is reached. In other
1622 words, this unwinds the reserved location until a location that is
1623 in real source code is reached.
1625 Otherwise, if the spelling location for LOC is not reserved or if
1626 LOC doesn't come from the expansion of a macro, the function
1627 returns LOC as is and *MAP is not touched.
1629 *MAP is set to the map of the returned location if the later is
1630 different from LOC. */
1631 source_location
1632 linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
1633 source_location loc,
1634 const struct line_map **map)
1636 source_location resolved_loc;
1637 const struct line_map *map0 = NULL;
1638 const line_map_ordinary *map1 = NULL;
1640 if (IS_ADHOC_LOC (loc))
1641 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1643 map0 = linemap_lookup (set, loc);
1644 if (!linemap_macro_expansion_map_p (map0))
1645 return loc;
1647 resolved_loc = linemap_resolve_location (set, loc,
1648 LRK_SPELLING_LOCATION,
1649 &map1);
1651 if (resolved_loc >= RESERVED_LOCATION_COUNT
1652 && !LINEMAP_SYSP (map1))
1653 return loc;
1655 while (linemap_macro_expansion_map_p (map0)
1656 && (resolved_loc < RESERVED_LOCATION_COUNT
1657 || LINEMAP_SYSP (map1)))
1659 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1660 resolved_loc = linemap_resolve_location (set, loc,
1661 LRK_SPELLING_LOCATION,
1662 &map1);
1665 if (map != NULL)
1666 *map = map0;
1667 return loc;
1670 /* Expand source code location LOC and return a user readable source
1671 code location. LOC must be a spelling (non-virtual) location. If
1672 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1673 location is returned. */
1675 expanded_location
1676 linemap_expand_location (struct line_maps *set,
1677 const struct line_map *map,
1678 source_location loc)
1681 expanded_location xloc;
1683 memset (&xloc, 0, sizeof (xloc));
1684 if (IS_ADHOC_LOC (loc))
1686 xloc.data
1687 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
1688 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1691 if (loc < RESERVED_LOCATION_COUNT)
1692 /* The location for this token wasn't generated from a line map.
1693 It was probably a location for a builtin token, chosen by some
1694 client code. Let's not try to expand the location in that
1695 case. */;
1696 else if (map == NULL)
1697 /* We shouldn't be getting a NULL map with a location that is not
1698 reserved by the client code. */
1699 abort ();
1700 else
1702 /* MAP must be an ordinary map and LOC must be non-virtual,
1703 encoded into this map, obviously; the accessors used on MAP
1704 below ensure it is ordinary. Let's just assert the
1705 non-virtualness of LOC here. */
1706 if (linemap_location_from_macro_expansion_p (set, loc))
1707 abort ();
1709 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1711 xloc.file = LINEMAP_FILE (ord_map);
1712 xloc.line = SOURCE_LINE (ord_map, loc);
1713 xloc.column = SOURCE_COLUMN (ord_map, loc);
1714 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1717 return xloc;
1721 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1722 is NULL, use stderr. IS_MACRO is true if the caller wants to
1723 dump a macro map, false otherwise. */
1725 void
1726 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
1728 const char *lc_reasons_v[LC_ENTER_MACRO + 1]
1729 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1730 "LC_ENTER_MACRO" };
1731 const char *reason;
1732 const line_map *map;
1734 if (stream == NULL)
1735 stream = stderr;
1737 if (!is_macro)
1738 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1739 else
1740 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1742 reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
1744 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1745 ix, (void *) map, map->start_location, reason,
1746 ((!is_macro
1747 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1748 ? "yes" : "no"));
1749 if (!is_macro)
1751 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1752 unsigned includer_ix;
1753 const line_map_ordinary *includer_map;
1755 includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
1756 includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
1757 ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
1758 : NULL;
1760 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1761 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1762 fprintf (stream, "Included from: [%d] %s\n", includer_ix,
1763 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1765 else
1767 const line_map_macro *macro_map = linemap_check_macro (map);
1768 fprintf (stream, "Macro: %s (%u tokens)\n",
1769 linemap_map_get_macro_name (macro_map),
1770 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1773 fprintf (stream, "\n");
1777 /* Dump debugging information about source location LOC into the file
1778 stream STREAM. SET is the line map set LOC comes from. */
1780 void
1781 linemap_dump_location (struct line_maps *set,
1782 source_location loc,
1783 FILE *stream)
1785 const line_map_ordinary *map;
1786 source_location location;
1787 const char *path = "", *from = "";
1788 int l = -1, c = -1, s = -1, e = -1;
1790 if (IS_ADHOC_LOC (loc))
1791 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1793 if (loc == 0)
1794 return;
1796 location =
1797 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1799 if (map == NULL)
1800 /* Only reserved locations can be tolerated in this case. */
1801 linemap_assert (location < RESERVED_LOCATION_COUNT);
1802 else
1804 path = LINEMAP_FILE (map);
1805 l = SOURCE_LINE (map, location);
1806 c = SOURCE_COLUMN (map, location);
1807 s = LINEMAP_SYSP (map) != 0;
1808 e = location != loc;
1809 if (e)
1810 from = "N/A";
1811 else
1812 from = (INCLUDED_FROM (set, map))
1813 ? LINEMAP_FILE (INCLUDED_FROM (set, map))
1814 : "<NULL>";
1817 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1818 E: macro expansion?, LOC: original location, R: resolved location */
1819 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1820 path, from, l, c, s, (void*)map, e, loc, location);
1823 /* Return the highest location emitted for a given file for which
1824 there is a line map in SET. FILE_NAME is the file name to
1825 consider. If the function returns TRUE, *LOC is set to the highest
1826 location emitted for that file. */
1828 bool
1829 linemap_get_file_highest_location (struct line_maps *set,
1830 const char *file_name,
1831 source_location *loc)
1833 /* If the set is empty or no ordinary map has been created then
1834 there is no file to look for ... */
1835 if (set == NULL || set->info_ordinary.used == 0)
1836 return false;
1838 /* Now look for the last ordinary map created for FILE_NAME. */
1839 int i;
1840 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1842 const char *fname = set->info_ordinary.maps[i].to_file;
1843 if (fname && !filename_cmp (fname, file_name))
1844 break;
1847 if (i < 0)
1848 return false;
1850 /* The highest location for a given map is either the starting
1851 location of the next map minus one, or -- if the map is the
1852 latest one -- the highest location of the set. */
1853 source_location result;
1854 if (i == (int) set->info_ordinary.used - 1)
1855 result = set->highest_location;
1856 else
1857 result = set->info_ordinary.maps[i + 1].start_location - 1;
1859 *loc = result;
1860 return true;
1863 /* Compute and return statistics about the memory consumption of some
1864 parts of the line table SET. */
1866 void
1867 linemap_get_statistics (struct line_maps *set,
1868 struct linemap_stats *s)
1870 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1871 macro_maps_allocated_size, macro_maps_used_size,
1872 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1874 const line_map_macro *cur_map;
1876 ordinary_maps_allocated_size =
1877 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1879 ordinary_maps_used_size =
1880 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1882 macro_maps_allocated_size =
1883 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1885 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1886 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1887 ++cur_map)
1889 unsigned i;
1891 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1893 macro_maps_locations_size +=
1894 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1896 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1898 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1899 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1900 duplicated_macro_maps_locations_size +=
1901 sizeof (source_location);
1905 macro_maps_used_size =
1906 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1908 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1909 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1910 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1911 s->ordinary_maps_used_size = ordinary_maps_used_size;
1912 s->num_expanded_macros = num_expanded_macros_counter;
1913 s->num_macro_tokens = num_macro_tokens_counter;
1914 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1915 s->macro_maps_allocated_size = macro_maps_allocated_size;
1916 s->macro_maps_locations_size = macro_maps_locations_size;
1917 s->macro_maps_used_size = macro_maps_used_size;
1918 s->duplicated_macro_maps_locations_size =
1919 duplicated_macro_maps_locations_size;
1920 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1921 * sizeof (struct location_adhoc_data));
1922 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1926 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1927 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1928 specifies how many macro maps to dump. */
1930 void
1931 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1932 unsigned int num_macro)
1934 unsigned int i;
1936 if (set == NULL)
1937 return;
1939 if (stream == NULL)
1940 stream = stderr;
1942 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1943 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1944 fprintf (stream, "Include stack depth: %d\n", set->depth);
1945 fprintf (stream, "Highest location: %u\n", set->highest_location);
1947 if (num_ordinary)
1949 fprintf (stream, "\nOrdinary line maps\n");
1950 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
1951 linemap_dump (stream, set, i, false);
1952 fprintf (stream, "\n");
1955 if (num_macro)
1957 fprintf (stream, "\nMacro line maps\n");
1958 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
1959 linemap_dump (stream, set, i, true);
1960 fprintf (stream, "\n");
1964 /* struct source_range. */
1966 /* Is there any part of this range on the given line? */
1968 bool
1969 source_range::intersects_line_p (const char *file, int line) const
1971 expanded_location exploc_start
1972 = linemap_client_expand_location_to_spelling_point (m_start);
1973 if (file != exploc_start.file)
1974 return false;
1975 if (line < exploc_start.line)
1976 return false;
1977 expanded_location exploc_finish
1978 = linemap_client_expand_location_to_spelling_point (m_finish);
1979 if (file != exploc_finish.file)
1980 return false;
1981 if (line > exploc_finish.line)
1982 return false;
1983 return true;
1986 /* class rich_location. */
1988 /* Construct a rich_location with location LOC as its initial range. */
1990 rich_location::rich_location (line_maps *set, source_location loc) :
1991 m_loc (loc),
1992 m_num_ranges (0),
1993 m_have_expanded_location (false),
1994 m_num_fixit_hints (0)
1996 /* Set up the 0th range, extracting any range from LOC. */
1997 source_range src_range = get_range_from_loc (set, loc);
1998 add_range (src_range, true);
1999 m_ranges[0].m_caret = lazily_expand_location ();
2002 /* Construct a rich_location with source_range SRC_RANGE as its
2003 initial range. */
2005 rich_location::rich_location (source_range src_range)
2006 : m_loc (src_range.m_start),
2007 m_num_ranges (0),
2008 m_have_expanded_location (false),
2009 m_num_fixit_hints (0)
2011 /* Set up the 0th range: */
2012 add_range (src_range, true);
2015 /* The destructor for class rich_location. */
2017 rich_location::~rich_location ()
2019 for (unsigned int i = 0; i < m_num_fixit_hints; i++)
2020 delete m_fixit_hints[i];
2023 /* Get an expanded_location for this rich_location's primary
2024 location. */
2026 expanded_location
2027 rich_location::lazily_expand_location ()
2029 if (!m_have_expanded_location)
2031 m_expanded_location
2032 = linemap_client_expand_location_to_spelling_point (m_loc);
2033 m_have_expanded_location = true;
2036 return m_expanded_location;
2039 /* Set the column of the primary location. This can only be called for
2040 rich_location instances for which the primary location has
2041 caret==start==finish. */
2043 void
2044 rich_location::override_column (int column)
2046 lazily_expand_location ();
2047 gcc_assert (m_ranges[0].m_show_caret_p);
2048 gcc_assert (m_ranges[0].m_caret.column == m_expanded_location.column);
2049 gcc_assert (m_ranges[0].m_start.column == m_expanded_location.column);
2050 gcc_assert (m_ranges[0].m_finish.column == m_expanded_location.column);
2051 m_expanded_location.column = column;
2052 m_ranges[0].m_caret.column = column;
2053 m_ranges[0].m_start.column = column;
2054 m_ranges[0].m_finish.column = column;
2057 /* Add the given range. */
2059 void
2060 rich_location::add_range (source_location start, source_location finish,
2061 bool show_caret_p)
2063 linemap_assert (m_num_ranges < MAX_RANGES);
2065 location_range *range = &m_ranges[m_num_ranges++];
2066 range->m_start = linemap_client_expand_location_to_spelling_point (start);
2067 range->m_finish = linemap_client_expand_location_to_spelling_point (finish);
2068 range->m_caret = range->m_start;
2069 range->m_show_caret_p = show_caret_p;
2072 /* Add the given range. */
2074 void
2075 rich_location::add_range (source_range src_range, bool show_caret_p)
2077 linemap_assert (m_num_ranges < MAX_RANGES);
2079 add_range (src_range.m_start, src_range.m_finish, show_caret_p);
2082 void
2083 rich_location::add_range (location_range *src_range)
2085 linemap_assert (m_num_ranges < MAX_RANGES);
2087 m_ranges[m_num_ranges++] = *src_range;
2090 /* Add or overwrite the location given by IDX, setting its location to LOC,
2091 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2093 It must either overwrite an existing location, or add one *exactly* on
2094 the end of the array.
2096 This is primarily for use by gcc when implementing diagnostic format
2097 decoders e.g.
2098 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2099 (which writes the source location of a tree back into location 0 of
2100 the rich_location), and
2101 - the "%C" and "%L" format codes in the Fortran frontend. */
2103 void
2104 rich_location::set_range (line_maps *set, unsigned int idx,
2105 source_location loc, bool show_caret_p)
2107 linemap_assert (idx < MAX_RANGES);
2109 /* We can either overwrite an existing range, or add one exactly
2110 on the end of the array. */
2111 linemap_assert (idx <= m_num_ranges);
2113 source_range src_range = get_range_from_loc (set, loc);
2115 location_range *locrange = &m_ranges[idx];
2116 locrange->m_start
2117 = linemap_client_expand_location_to_spelling_point (src_range.m_start);
2118 locrange->m_finish
2119 = linemap_client_expand_location_to_spelling_point (src_range.m_finish);
2121 locrange->m_show_caret_p = show_caret_p;
2122 locrange->m_caret
2123 = linemap_client_expand_location_to_spelling_point (loc);
2125 /* Are we adding a range onto the end? */
2126 if (idx == m_num_ranges)
2127 m_num_ranges = idx + 1;
2129 if (idx == 0)
2131 m_loc = loc;
2132 /* Mark any cached value here as dirty. */
2133 m_have_expanded_location = false;
2137 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2138 at WHERE. */
2140 void
2141 rich_location::add_fixit_insert (source_location where,
2142 const char *new_content)
2144 linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
2145 m_fixit_hints[m_num_fixit_hints++]
2146 = new fixit_insert (where, new_content);
2149 /* Add a fixit-hint, suggesting removal of the content at
2150 SRC_RANGE. */
2152 void
2153 rich_location::add_fixit_remove (source_range src_range)
2155 linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
2156 m_fixit_hints[m_num_fixit_hints++] = new fixit_remove (src_range);
2159 /* Add a fixit-hint, suggesting replacement of the content at
2160 SRC_RANGE with NEW_CONTENT. */
2162 void
2163 rich_location::add_fixit_replace (source_range src_range,
2164 const char *new_content)
2166 linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
2167 m_fixit_hints[m_num_fixit_hints++]
2168 = new fixit_replace (src_range, new_content);
2171 /* class fixit_insert. */
2173 fixit_insert::fixit_insert (source_location where,
2174 const char *new_content)
2175 : m_where (where),
2176 m_bytes (xstrdup (new_content)),
2177 m_len (strlen (new_content))
2181 fixit_insert::~fixit_insert ()
2183 free (m_bytes);
2186 /* Implementation of fixit_hint::affects_line_p for fixit_insert. */
2188 bool
2189 fixit_insert::affects_line_p (const char *file, int line)
2191 expanded_location exploc
2192 = linemap_client_expand_location_to_spelling_point (m_where);
2193 if (file == exploc.file)
2194 if (line == exploc.line)
2195 return true;
2196 return false;
2199 /* class fixit_remove. */
2201 fixit_remove::fixit_remove (source_range src_range)
2202 : m_src_range (src_range)
2206 /* Implementation of fixit_hint::affects_line_p for fixit_remove. */
2208 bool
2209 fixit_remove::affects_line_p (const char *file, int line)
2211 return m_src_range.intersects_line_p (file, line);
2214 /* class fixit_replace. */
2216 fixit_replace::fixit_replace (source_range src_range,
2217 const char *new_content)
2218 : m_src_range (src_range),
2219 m_bytes (xstrdup (new_content)),
2220 m_len (strlen (new_content))
2224 fixit_replace::~fixit_replace ()
2226 free (m_bytes);
2229 /* Implementation of fixit_hint::affects_line_p for fixit_replace. */
2231 bool
2232 fixit_replace::affects_line_p (const char *file, int line)
2234 return m_src_range.intersects_line_p (file, line);