2016-03-02 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libcpp / line-map.c
blob264ae2097b25acfa500a03e85ac37bb8987ab469
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 COLUMN_OFFSET columns. This function does not support
868 virtual locations. */
870 source_location
871 linemap_position_for_loc_and_offset (struct line_maps *set,
872 source_location loc,
873 unsigned int column_offset)
875 const line_map_ordinary * map = NULL;
877 if (IS_ADHOC_LOC (loc))
878 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
880 /* This function does not support virtual locations yet. */
881 if (linemap_assert_fails
882 (!linemap_location_from_macro_expansion_p (set, loc)))
883 return loc;
885 if (column_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 + (column_offset << map->m_range_bits))
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 + (column_offset << map->m_range_bits)
909 >= MAP_START_LOCATION (&map[1])))
911 map = &map[1];
912 /* If the next map starts in a higher line, we cannot encode the
913 location there. */
914 if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
915 return loc;
918 column += column_offset;
919 if (linemap_assert_fails (column < (1u << map->m_column_and_range_bits)))
920 return loc;
922 source_location r =
923 linemap_position_for_line_and_column (set, map, line, column);
924 if (linemap_assert_fails (r <= set->highest_location)
925 || linemap_assert_fails (map == linemap_lookup (set, r)))
926 return loc;
928 return r;
931 /* Given a virtual source location yielded by a map (either an
932 ordinary or a macro map), returns that map. */
934 const struct line_map*
935 linemap_lookup (struct line_maps *set, source_location line)
937 if (IS_ADHOC_LOC (line))
938 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
939 if (linemap_location_from_macro_expansion_p (set, line))
940 return linemap_macro_map_lookup (set, line);
941 return linemap_ordinary_map_lookup (set, line);
944 /* Given a source location yielded by an ordinary map, returns that
945 map. Since the set is built chronologically, the logical lines are
946 monotonic increasing, and so the list is sorted and we can use a
947 binary search. */
949 static const line_map_ordinary *
950 linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
952 unsigned int md, mn, mx;
953 const line_map_ordinary *cached, *result;
955 if (IS_ADHOC_LOC (line))
956 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
958 if (set == NULL || line < RESERVED_LOCATION_COUNT)
959 return NULL;
961 mn = LINEMAPS_ORDINARY_CACHE (set);
962 mx = LINEMAPS_ORDINARY_USED (set);
964 cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
965 /* We should get a segfault if no line_maps have been added yet. */
966 if (line >= MAP_START_LOCATION (cached))
968 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
969 return cached;
971 else
973 mx = mn;
974 mn = 0;
977 while (mx - mn > 1)
979 md = (mn + mx) / 2;
980 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
981 mx = md;
982 else
983 mn = md;
986 LINEMAPS_ORDINARY_CACHE (set) = mn;
987 result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
988 linemap_assert (line >= MAP_START_LOCATION (result));
989 return result;
992 /* Given a source location yielded by a macro map, returns that map.
993 Since the set is built chronologically, the logical lines are
994 monotonic decreasing, and so the list is sorted and we can use a
995 binary search. */
997 static const line_map_macro *
998 linemap_macro_map_lookup (struct line_maps *set, source_location line)
1000 unsigned int md, mn, mx;
1001 const struct line_map_macro *cached, *result;
1003 if (IS_ADHOC_LOC (line))
1004 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
1006 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1008 if (set == NULL)
1009 return NULL;
1011 mn = LINEMAPS_MACRO_CACHE (set);
1012 mx = LINEMAPS_MACRO_USED (set);
1013 cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1015 if (line >= MAP_START_LOCATION (cached))
1017 if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
1018 return cached;
1019 mx = mn - 1;
1020 mn = 0;
1023 while (mn < mx)
1025 md = (mx + mn) / 2;
1026 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1027 mn = md + 1;
1028 else
1029 mx = md;
1032 LINEMAPS_MACRO_CACHE (set) = mx;
1033 result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
1034 linemap_assert (MAP_START_LOCATION (result) <= line);
1036 return result;
1039 /* Return TRUE if MAP encodes locations coming from a macro
1040 replacement-list at macro expansion point. */
1042 bool
1043 linemap_macro_expansion_map_p (const struct line_map *map)
1045 if (!map)
1046 return false;
1047 return (map->reason == LC_ENTER_MACRO);
1050 /* If LOCATION is the locus of a token in a replacement-list of a
1051 macro expansion return the location of the macro expansion point.
1053 Read the comments of struct line_map and struct line_map_macro in
1054 line-map.h to understand what a macro expansion point is. */
1056 static source_location
1057 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1058 source_location location ATTRIBUTE_UNUSED)
1060 linemap_assert (linemap_macro_expansion_map_p (map)
1061 && location >= MAP_START_LOCATION (map));
1063 /* Make sure LOCATION is correct. */
1064 linemap_assert ((location - MAP_START_LOCATION (map))
1065 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1067 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1070 /* LOCATION is the source location of a token that belongs to a macro
1071 replacement-list as part of the macro expansion denoted by MAP.
1073 Return the location of the token at the definition point of the
1074 macro. */
1076 static source_location
1077 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1078 source_location location)
1080 unsigned token_no;
1082 linemap_assert (linemap_macro_expansion_map_p (map)
1083 && location >= MAP_START_LOCATION (map));
1084 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1086 token_no = location - MAP_START_LOCATION (map);
1087 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1089 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1091 return location;
1094 /* If LOCATION is the locus of a token that is an argument of a
1095 function-like macro M and appears in the expansion of M, return the
1096 locus of that argument in the context of the caller of M.
1098 In other words, this returns the xI location presented in the
1099 comments of line_map_macro above. */
1100 source_location
1101 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1102 const line_map_macro* map,
1103 source_location location)
1105 unsigned token_no;
1107 if (IS_ADHOC_LOC (location))
1108 location = get_location_from_adhoc_loc (set, location);
1110 linemap_assert (linemap_macro_expansion_map_p (map)
1111 && location >= MAP_START_LOCATION (map));
1112 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1113 linemap_assert (!IS_ADHOC_LOC (location));
1115 token_no = location - MAP_START_LOCATION (map);
1116 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1118 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1120 return location;
1123 /* Return the source line number corresponding to source location
1124 LOCATION. SET is the line map set LOCATION comes from. If
1125 LOCATION is the source location of token that is part of the
1126 replacement-list of a macro expansion return the line number of the
1127 macro expansion point. */
1130 linemap_get_expansion_line (struct line_maps *set,
1131 source_location location)
1133 const line_map_ordinary *map = NULL;
1135 if (IS_ADHOC_LOC (location))
1136 location = set->location_adhoc_data_map.data[location
1137 & MAX_SOURCE_LOCATION].locus;
1139 if (location < RESERVED_LOCATION_COUNT)
1140 return 0;
1142 location =
1143 linemap_macro_loc_to_exp_point (set, location, &map);
1145 return SOURCE_LINE (map, location);
1148 /* Return the path of the file corresponding to source code location
1149 LOCATION.
1151 If LOCATION is the source location of token that is part of the
1152 replacement-list of a macro expansion return the file path of the
1153 macro expansion point.
1155 SET is the line map set LOCATION comes from. */
1157 const char*
1158 linemap_get_expansion_filename (struct line_maps *set,
1159 source_location location)
1161 const struct line_map_ordinary *map = NULL;
1163 if (IS_ADHOC_LOC (location))
1164 location = set->location_adhoc_data_map.data[location
1165 & MAX_SOURCE_LOCATION].locus;
1167 if (location < RESERVED_LOCATION_COUNT)
1168 return NULL;
1170 location =
1171 linemap_macro_loc_to_exp_point (set, location, &map);
1173 return LINEMAP_FILE (map);
1176 /* Return the name of the macro associated to MACRO_MAP. */
1178 const char*
1179 linemap_map_get_macro_name (const line_map_macro *macro_map)
1181 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1182 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1185 /* Return a positive value if LOCATION is the locus of a token that is
1186 located in a system header, O otherwise. It returns 1 if LOCATION
1187 is the locus of a token that is located in a system header, and 2
1188 if LOCATION is the locus of a token located in a C system header
1189 that therefore needs to be extern "C" protected in C++.
1191 Note that this function returns 1 if LOCATION belongs to a token
1192 that is part of a macro replacement-list defined in a system
1193 header, but expanded in a non-system file. */
1196 linemap_location_in_system_header_p (struct line_maps *set,
1197 source_location location)
1199 const struct line_map *map = NULL;
1201 if (IS_ADHOC_LOC (location))
1202 location = set->location_adhoc_data_map.data[location
1203 & MAX_SOURCE_LOCATION].locus;
1205 if (location < RESERVED_LOCATION_COUNT)
1206 return false;
1208 /* Let's look at where the token for LOCATION comes from. */
1209 while (true)
1211 map = linemap_lookup (set, location);
1212 if (map != NULL)
1214 if (!linemap_macro_expansion_map_p (map))
1215 /* It's a normal token. */
1216 return LINEMAP_SYSP (linemap_check_ordinary (map));
1217 else
1219 const line_map_macro *macro_map = linemap_check_macro (map);
1221 /* It's a token resulting from a macro expansion. */
1222 source_location loc =
1223 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1224 if (loc < RESERVED_LOCATION_COUNT)
1225 /* This token might come from a built-in macro. Let's
1226 look at where that macro got expanded. */
1227 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1228 else
1229 location = loc;
1232 else
1233 break;
1235 return false;
1238 /* Return TRUE if LOCATION is a source code location of a token coming
1239 from a macro replacement-list at a macro expansion point, FALSE
1240 otherwise. */
1242 bool
1243 linemap_location_from_macro_expansion_p (const struct line_maps *set,
1244 source_location location)
1246 if (IS_ADHOC_LOC (location))
1247 location = set->location_adhoc_data_map.data[location
1248 & MAX_SOURCE_LOCATION].locus;
1250 linemap_assert (location <= MAX_SOURCE_LOCATION
1251 && (set->highest_location
1252 < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
1253 if (set == NULL)
1254 return false;
1255 return (location > set->highest_location);
1258 /* Given two virtual locations *LOC0 and *LOC1, return the first
1259 common macro map in their macro expansion histories. Return NULL
1260 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1261 virtual location of the token inside the resulting macro. */
1263 static const struct line_map*
1264 first_map_in_common_1 (struct line_maps *set,
1265 source_location *loc0,
1266 source_location *loc1)
1268 source_location l0 = *loc0, l1 = *loc1;
1269 const struct line_map *map0 = linemap_lookup (set, l0),
1270 *map1 = linemap_lookup (set, l1);
1272 while (linemap_macro_expansion_map_p (map0)
1273 && linemap_macro_expansion_map_p (map1)
1274 && (map0 != map1))
1276 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1278 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1279 l0);
1280 map0 = linemap_lookup (set, l0);
1282 else
1284 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1285 l1);
1286 map1 = linemap_lookup (set, l1);
1290 if (map0 == map1)
1292 *loc0 = l0;
1293 *loc1 = l1;
1294 return map0;
1296 return NULL;
1299 /* Given two virtual locations LOC0 and LOC1, return the first common
1300 macro map in their macro expansion histories. Return NULL if no
1301 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1302 virtual location of the token inside the resulting macro, upon
1303 return of a non-NULL result. */
1305 static const struct line_map*
1306 first_map_in_common (struct line_maps *set,
1307 source_location loc0,
1308 source_location loc1,
1309 source_location *res_loc0,
1310 source_location *res_loc1)
1312 *res_loc0 = loc0;
1313 *res_loc1 = loc1;
1315 return first_map_in_common_1 (set, res_loc0, res_loc1);
1318 /* Return a positive value if PRE denotes the location of a token that
1319 comes before the token of POST, 0 if PRE denotes the location of
1320 the same token as the token for POST, and a negative value
1321 otherwise. */
1324 linemap_compare_locations (struct line_maps *set,
1325 source_location pre,
1326 source_location post)
1328 bool pre_virtual_p, post_virtual_p;
1329 source_location l0 = pre, l1 = post;
1331 if (IS_ADHOC_LOC (l0))
1332 l0 = get_location_from_adhoc_loc (set, l0);
1333 if (IS_ADHOC_LOC (l1))
1334 l1 = get_location_from_adhoc_loc (set, l1);
1336 if (l0 == l1)
1337 return 0;
1339 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1340 l0 = linemap_resolve_location (set, l0,
1341 LRK_MACRO_EXPANSION_POINT,
1342 NULL);
1344 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1345 l1 = linemap_resolve_location (set, l1,
1346 LRK_MACRO_EXPANSION_POINT,
1347 NULL);
1349 if (l0 == l1
1350 && pre_virtual_p
1351 && post_virtual_p)
1353 /* So pre and post represent two tokens that are present in a
1354 same macro expansion. Let's see if the token for pre was
1355 before the token for post in that expansion. */
1356 unsigned i0, i1;
1357 const struct line_map *map =
1358 first_map_in_common (set, pre, post, &l0, &l1);
1360 if (map == NULL)
1361 /* This should not be possible. */
1362 abort ();
1364 i0 = l0 - MAP_START_LOCATION (map);
1365 i1 = l1 - MAP_START_LOCATION (map);
1366 return i1 - i0;
1369 if (IS_ADHOC_LOC (l0))
1370 l0 = get_location_from_adhoc_loc (set, l0);
1371 if (IS_ADHOC_LOC (l1))
1372 l1 = get_location_from_adhoc_loc (set, l1);
1374 return l1 - l0;
1377 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1379 static void
1380 trace_include (const struct line_maps *set, const line_map_ordinary *map)
1382 unsigned int i = set->depth;
1384 while (--i)
1385 putc ('.', stderr);
1387 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1390 /* Return the spelling location of the token wherever it comes from,
1391 whether part of a macro definition or not.
1393 This is a subroutine for linemap_resolve_location. */
1395 static source_location
1396 linemap_macro_loc_to_spelling_point (struct line_maps *set,
1397 source_location location,
1398 const line_map_ordinary **original_map)
1400 struct line_map *map;
1401 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1403 while (true)
1405 map = const_cast <line_map *> (linemap_lookup (set, location));
1406 if (!linemap_macro_expansion_map_p (map))
1407 break;
1409 location
1410 = linemap_macro_map_loc_unwind_toward_spelling
1411 (set, linemap_check_macro (map),
1412 location);
1415 if (original_map)
1416 *original_map = linemap_check_ordinary (map);
1417 return location;
1420 /* If LOCATION is the source location of a token that belongs to a
1421 macro replacement-list -- as part of a macro expansion -- then
1422 return the location of the token at the definition point of the
1423 macro. Otherwise, return LOCATION. SET is the set of maps
1424 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1425 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1426 returned location comes from.
1428 This is a subroutine of linemap_resolve_location. */
1430 static source_location
1431 linemap_macro_loc_to_def_point (struct line_maps *set,
1432 source_location location,
1433 const line_map_ordinary **original_map)
1435 struct line_map *map;
1437 if (IS_ADHOC_LOC (location))
1438 location = set->location_adhoc_data_map.data[location
1439 & MAX_SOURCE_LOCATION].locus;
1441 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1443 while (true)
1445 map = const_cast <line_map *> (linemap_lookup (set, location));
1446 if (!linemap_macro_expansion_map_p (map))
1447 break;
1449 location =
1450 linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
1451 location);
1454 if (original_map)
1455 *original_map = linemap_check_ordinary (map);
1456 return location;
1459 /* If LOCATION is the source location of a token that belongs to a
1460 macro replacement-list -- at a macro expansion point -- then return
1461 the location of the topmost expansion point of the macro. We say
1462 topmost because if we are in the context of a nested macro
1463 expansion, the function returns the source location of the first
1464 macro expansion that triggered the nested expansions.
1466 Otherwise, return LOCATION. SET is the set of maps location come
1467 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1468 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1469 location comes from.
1471 This is a subroutine of linemap_resolve_location. */
1473 static source_location
1474 linemap_macro_loc_to_exp_point (struct line_maps *set,
1475 source_location location,
1476 const line_map_ordinary **original_map)
1478 struct line_map *map;
1480 if (IS_ADHOC_LOC (location))
1481 location = set->location_adhoc_data_map.data[location
1482 & MAX_SOURCE_LOCATION].locus;
1484 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1486 while (true)
1488 map = const_cast <line_map *> (linemap_lookup (set, location));
1489 if (!linemap_macro_expansion_map_p (map))
1490 break;
1491 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1492 location);
1495 if (original_map)
1496 *original_map = linemap_check_ordinary (map);
1497 return location;
1500 /* Resolve a virtual location into either a spelling location, an
1501 expansion point location or a token argument replacement point
1502 location. Return the map that encodes the virtual location as well
1503 as the resolved location.
1505 If LOC is *NOT* the location of a token resulting from the
1506 expansion of a macro, then the parameter LRK (which stands for
1507 Location Resolution Kind) is ignored and the resulting location
1508 just equals the one given in argument.
1510 Now if LOC *IS* the location of a token resulting from the
1511 expansion of a macro, this is what happens.
1513 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1514 -------------------------------
1516 The virtual location is resolved to the first macro expansion point
1517 that led to this macro expansion.
1519 * If LRK is set to LRK_SPELLING_LOCATION
1520 -------------------------------------
1522 The virtual location is resolved to the locus where the token has
1523 been spelled in the source. This can follow through all the macro
1524 expansions that led to the token.
1526 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1527 --------------------------------------
1529 The virtual location is resolved to the locus of the token in the
1530 context of the macro definition.
1532 If LOC is the locus of a token that is an argument of a
1533 function-like macro [replacing a parameter in the replacement list
1534 of the macro] the virtual location is resolved to the locus of the
1535 parameter that is replaced, in the context of the definition of the
1536 macro.
1538 If LOC is the locus of a token that is not an argument of a
1539 function-like macro, then the function behaves as if LRK was set to
1540 LRK_SPELLING_LOCATION.
1542 If MAP is not NULL, *MAP is set to the map encoding the
1543 returned location. Note that if the returned location wasn't originally
1544 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1545 resolves to a location reserved for the client code, like
1546 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1548 source_location
1549 linemap_resolve_location (struct line_maps *set,
1550 source_location loc,
1551 enum location_resolution_kind lrk,
1552 const line_map_ordinary **map)
1554 source_location locus = loc;
1555 if (IS_ADHOC_LOC (loc))
1556 locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1558 if (locus < RESERVED_LOCATION_COUNT)
1560 /* A reserved location wasn't encoded in a map. Let's return a
1561 NULL map here, just like what linemap_ordinary_map_lookup
1562 does. */
1563 if (map)
1564 *map = NULL;
1565 return loc;
1568 switch (lrk)
1570 case LRK_MACRO_EXPANSION_POINT:
1571 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1572 break;
1573 case LRK_SPELLING_LOCATION:
1574 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1575 break;
1576 case LRK_MACRO_DEFINITION_LOCATION:
1577 loc = linemap_macro_loc_to_def_point (set, loc, map);
1578 break;
1579 default:
1580 abort ();
1582 return loc;
1586 Suppose that LOC is the virtual location of a token T coming from
1587 the expansion of a macro M. This function then steps up to get the
1588 location L of the point where M got expanded. If L is a spelling
1589 location inside a macro expansion M', then this function returns
1590 the locus of the point where M' was expanded. Said otherwise, this
1591 function returns the location of T in the context that triggered
1592 the expansion of M.
1594 *LOC_MAP must be set to the map of LOC. This function then sets it
1595 to the map of the returned location. */
1597 source_location
1598 linemap_unwind_toward_expansion (struct line_maps *set,
1599 source_location loc,
1600 const struct line_map **map)
1602 source_location resolved_location;
1603 const line_map_macro *macro_map = linemap_check_macro (*map);
1604 const struct line_map *resolved_map;
1606 if (IS_ADHOC_LOC (loc))
1607 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1609 resolved_location =
1610 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1611 resolved_map = linemap_lookup (set, resolved_location);
1613 if (!linemap_macro_expansion_map_p (resolved_map))
1615 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1616 resolved_map = linemap_lookup (set, resolved_location);
1619 *map = resolved_map;
1620 return resolved_location;
1623 /* If LOC is the virtual location of a token coming from the expansion
1624 of a macro M and if its spelling location is reserved (e.g, a
1625 location for a built-in token), then this function unwinds (using
1626 linemap_unwind_toward_expansion) the location until a location that
1627 is not reserved and is not in a system header is reached. In other
1628 words, this unwinds the reserved location until a location that is
1629 in real source code is reached.
1631 Otherwise, if the spelling location for LOC is not reserved or if
1632 LOC doesn't come from the expansion of a macro, the function
1633 returns LOC as is and *MAP is not touched.
1635 *MAP is set to the map of the returned location if the later is
1636 different from LOC. */
1637 source_location
1638 linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
1639 source_location loc,
1640 const struct line_map **map)
1642 source_location resolved_loc;
1643 const struct line_map *map0 = NULL;
1644 const line_map_ordinary *map1 = NULL;
1646 if (IS_ADHOC_LOC (loc))
1647 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1649 map0 = linemap_lookup (set, loc);
1650 if (!linemap_macro_expansion_map_p (map0))
1651 return loc;
1653 resolved_loc = linemap_resolve_location (set, loc,
1654 LRK_SPELLING_LOCATION,
1655 &map1);
1657 if (resolved_loc >= RESERVED_LOCATION_COUNT
1658 && !LINEMAP_SYSP (map1))
1659 return loc;
1661 while (linemap_macro_expansion_map_p (map0)
1662 && (resolved_loc < RESERVED_LOCATION_COUNT
1663 || LINEMAP_SYSP (map1)))
1665 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1666 resolved_loc = linemap_resolve_location (set, loc,
1667 LRK_SPELLING_LOCATION,
1668 &map1);
1671 if (map != NULL)
1672 *map = map0;
1673 return loc;
1676 /* Expand source code location LOC and return a user readable source
1677 code location. LOC must be a spelling (non-virtual) location. If
1678 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1679 location is returned. */
1681 expanded_location
1682 linemap_expand_location (struct line_maps *set,
1683 const struct line_map *map,
1684 source_location loc)
1687 expanded_location xloc;
1689 memset (&xloc, 0, sizeof (xloc));
1690 if (IS_ADHOC_LOC (loc))
1692 xloc.data
1693 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
1694 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1697 if (loc < RESERVED_LOCATION_COUNT)
1698 /* The location for this token wasn't generated from a line map.
1699 It was probably a location for a builtin token, chosen by some
1700 client code. Let's not try to expand the location in that
1701 case. */;
1702 else if (map == NULL)
1703 /* We shouldn't be getting a NULL map with a location that is not
1704 reserved by the client code. */
1705 abort ();
1706 else
1708 /* MAP must be an ordinary map and LOC must be non-virtual,
1709 encoded into this map, obviously; the accessors used on MAP
1710 below ensure it is ordinary. Let's just assert the
1711 non-virtualness of LOC here. */
1712 if (linemap_location_from_macro_expansion_p (set, loc))
1713 abort ();
1715 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1717 xloc.file = LINEMAP_FILE (ord_map);
1718 xloc.line = SOURCE_LINE (ord_map, loc);
1719 xloc.column = SOURCE_COLUMN (ord_map, loc);
1720 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1723 return xloc;
1727 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1728 is NULL, use stderr. IS_MACRO is true if the caller wants to
1729 dump a macro map, false otherwise. */
1731 void
1732 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
1734 const char *lc_reasons_v[LC_ENTER_MACRO + 1]
1735 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1736 "LC_ENTER_MACRO" };
1737 const char *reason;
1738 const line_map *map;
1740 if (stream == NULL)
1741 stream = stderr;
1743 if (!is_macro)
1744 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1745 else
1746 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1748 reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
1750 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1751 ix, (void *) map, map->start_location, reason,
1752 ((!is_macro
1753 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1754 ? "yes" : "no"));
1755 if (!is_macro)
1757 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1758 unsigned includer_ix;
1759 const line_map_ordinary *includer_map;
1761 includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
1762 includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
1763 ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
1764 : NULL;
1766 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1767 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1768 fprintf (stream, "Included from: [%d] %s\n", includer_ix,
1769 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1771 else
1773 const line_map_macro *macro_map = linemap_check_macro (map);
1774 fprintf (stream, "Macro: %s (%u tokens)\n",
1775 linemap_map_get_macro_name (macro_map),
1776 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1779 fprintf (stream, "\n");
1783 /* Dump debugging information about source location LOC into the file
1784 stream STREAM. SET is the line map set LOC comes from. */
1786 void
1787 linemap_dump_location (struct line_maps *set,
1788 source_location loc,
1789 FILE *stream)
1791 const line_map_ordinary *map;
1792 source_location location;
1793 const char *path = "", *from = "";
1794 int l = -1, c = -1, s = -1, e = -1;
1796 if (IS_ADHOC_LOC (loc))
1797 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1799 if (loc == 0)
1800 return;
1802 location =
1803 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1805 if (map == NULL)
1806 /* Only reserved locations can be tolerated in this case. */
1807 linemap_assert (location < RESERVED_LOCATION_COUNT);
1808 else
1810 path = LINEMAP_FILE (map);
1811 l = SOURCE_LINE (map, location);
1812 c = SOURCE_COLUMN (map, location);
1813 s = LINEMAP_SYSP (map) != 0;
1814 e = location != loc;
1815 if (e)
1816 from = "N/A";
1817 else
1818 from = (INCLUDED_FROM (set, map))
1819 ? LINEMAP_FILE (INCLUDED_FROM (set, map))
1820 : "<NULL>";
1823 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1824 E: macro expansion?, LOC: original location, R: resolved location */
1825 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1826 path, from, l, c, s, (void*)map, e, loc, location);
1829 /* Return the highest location emitted for a given file for which
1830 there is a line map in SET. FILE_NAME is the file name to
1831 consider. If the function returns TRUE, *LOC is set to the highest
1832 location emitted for that file. */
1834 bool
1835 linemap_get_file_highest_location (struct line_maps *set,
1836 const char *file_name,
1837 source_location *loc)
1839 /* If the set is empty or no ordinary map has been created then
1840 there is no file to look for ... */
1841 if (set == NULL || set->info_ordinary.used == 0)
1842 return false;
1844 /* Now look for the last ordinary map created for FILE_NAME. */
1845 int i;
1846 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1848 const char *fname = set->info_ordinary.maps[i].to_file;
1849 if (fname && !filename_cmp (fname, file_name))
1850 break;
1853 if (i < 0)
1854 return false;
1856 /* The highest location for a given map is either the starting
1857 location of the next map minus one, or -- if the map is the
1858 latest one -- the highest location of the set. */
1859 source_location result;
1860 if (i == (int) set->info_ordinary.used - 1)
1861 result = set->highest_location;
1862 else
1863 result = set->info_ordinary.maps[i + 1].start_location - 1;
1865 *loc = result;
1866 return true;
1869 /* Compute and return statistics about the memory consumption of some
1870 parts of the line table SET. */
1872 void
1873 linemap_get_statistics (struct line_maps *set,
1874 struct linemap_stats *s)
1876 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1877 macro_maps_allocated_size, macro_maps_used_size,
1878 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1880 const line_map_macro *cur_map;
1882 ordinary_maps_allocated_size =
1883 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1885 ordinary_maps_used_size =
1886 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1888 macro_maps_allocated_size =
1889 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1891 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1892 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1893 ++cur_map)
1895 unsigned i;
1897 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1899 macro_maps_locations_size +=
1900 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1902 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1904 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1905 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1906 duplicated_macro_maps_locations_size +=
1907 sizeof (source_location);
1911 macro_maps_used_size =
1912 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1914 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1915 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1916 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1917 s->ordinary_maps_used_size = ordinary_maps_used_size;
1918 s->num_expanded_macros = num_expanded_macros_counter;
1919 s->num_macro_tokens = num_macro_tokens_counter;
1920 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1921 s->macro_maps_allocated_size = macro_maps_allocated_size;
1922 s->macro_maps_locations_size = macro_maps_locations_size;
1923 s->macro_maps_used_size = macro_maps_used_size;
1924 s->duplicated_macro_maps_locations_size =
1925 duplicated_macro_maps_locations_size;
1926 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1927 * sizeof (struct location_adhoc_data));
1928 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1932 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1933 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1934 specifies how many macro maps to dump. */
1936 void
1937 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1938 unsigned int num_macro)
1940 unsigned int i;
1942 if (set == NULL)
1943 return;
1945 if (stream == NULL)
1946 stream = stderr;
1948 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1949 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1950 fprintf (stream, "Include stack depth: %d\n", set->depth);
1951 fprintf (stream, "Highest location: %u\n", set->highest_location);
1953 if (num_ordinary)
1955 fprintf (stream, "\nOrdinary line maps\n");
1956 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
1957 linemap_dump (stream, set, i, false);
1958 fprintf (stream, "\n");
1961 if (num_macro)
1963 fprintf (stream, "\nMacro line maps\n");
1964 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
1965 linemap_dump (stream, set, i, true);
1966 fprintf (stream, "\n");
1970 /* struct source_range. */
1972 /* Is there any part of this range on the given line? */
1974 bool
1975 source_range::intersects_line_p (const char *file, int line) const
1977 expanded_location exploc_start
1978 = linemap_client_expand_location_to_spelling_point (m_start);
1979 if (file != exploc_start.file)
1980 return false;
1981 if (line < exploc_start.line)
1982 return false;
1983 expanded_location exploc_finish
1984 = linemap_client_expand_location_to_spelling_point (m_finish);
1985 if (file != exploc_finish.file)
1986 return false;
1987 if (line > exploc_finish.line)
1988 return false;
1989 return true;
1992 /* class rich_location. */
1994 /* Construct a rich_location with location LOC as its initial range. */
1996 rich_location::rich_location (line_maps *set, source_location loc) :
1997 m_loc (loc),
1998 m_num_ranges (0),
1999 m_have_expanded_location (false),
2000 m_num_fixit_hints (0)
2002 /* Set up the 0th range, extracting any range from LOC. */
2003 source_range src_range = get_range_from_loc (set, loc);
2004 add_range (src_range, true);
2005 m_ranges[0].m_caret = lazily_expand_location ();
2008 /* Construct a rich_location with source_range SRC_RANGE as its
2009 initial range. */
2011 rich_location::rich_location (source_range src_range)
2012 : m_loc (src_range.m_start),
2013 m_num_ranges (0),
2014 m_have_expanded_location (false),
2015 m_num_fixit_hints (0)
2017 /* Set up the 0th range: */
2018 add_range (src_range, true);
2021 /* The destructor for class rich_location. */
2023 rich_location::~rich_location ()
2025 for (unsigned int i = 0; i < m_num_fixit_hints; i++)
2026 delete m_fixit_hints[i];
2029 /* Get an expanded_location for this rich_location's primary
2030 location. */
2032 expanded_location
2033 rich_location::lazily_expand_location ()
2035 if (!m_have_expanded_location)
2037 m_expanded_location
2038 = linemap_client_expand_location_to_spelling_point (m_loc);
2039 m_have_expanded_location = true;
2042 return m_expanded_location;
2045 /* Set the column of the primary location. This can only be called for
2046 rich_location instances for which the primary location has
2047 caret==start==finish. */
2049 void
2050 rich_location::override_column (int column)
2052 lazily_expand_location ();
2053 gcc_assert (m_ranges[0].m_show_caret_p);
2054 gcc_assert (m_ranges[0].m_caret.column == m_expanded_location.column);
2055 gcc_assert (m_ranges[0].m_start.column == m_expanded_location.column);
2056 gcc_assert (m_ranges[0].m_finish.column == m_expanded_location.column);
2057 m_expanded_location.column = column;
2058 m_ranges[0].m_caret.column = column;
2059 m_ranges[0].m_start.column = column;
2060 m_ranges[0].m_finish.column = column;
2063 /* Add the given range. */
2065 void
2066 rich_location::add_range (source_location start, source_location finish,
2067 bool show_caret_p)
2069 linemap_assert (m_num_ranges < MAX_RANGES);
2071 location_range *range = &m_ranges[m_num_ranges++];
2072 range->m_start = linemap_client_expand_location_to_spelling_point (start);
2073 range->m_finish = linemap_client_expand_location_to_spelling_point (finish);
2074 range->m_caret = range->m_start;
2075 range->m_show_caret_p = show_caret_p;
2078 /* Add the given range. */
2080 void
2081 rich_location::add_range (source_range src_range, bool show_caret_p)
2083 linemap_assert (m_num_ranges < MAX_RANGES);
2085 add_range (src_range.m_start, src_range.m_finish, show_caret_p);
2088 void
2089 rich_location::add_range (location_range *src_range)
2091 linemap_assert (m_num_ranges < MAX_RANGES);
2093 m_ranges[m_num_ranges++] = *src_range;
2096 /* Add or overwrite the location given by IDX, setting its location to LOC,
2097 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2099 It must either overwrite an existing location, or add one *exactly* on
2100 the end of the array.
2102 This is primarily for use by gcc when implementing diagnostic format
2103 decoders e.g.
2104 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2105 (which writes the source location of a tree back into location 0 of
2106 the rich_location), and
2107 - the "%C" and "%L" format codes in the Fortran frontend. */
2109 void
2110 rich_location::set_range (line_maps *set, unsigned int idx,
2111 source_location loc, bool show_caret_p)
2113 linemap_assert (idx < MAX_RANGES);
2115 /* We can either overwrite an existing range, or add one exactly
2116 on the end of the array. */
2117 linemap_assert (idx <= m_num_ranges);
2119 source_range src_range = get_range_from_loc (set, loc);
2121 location_range *locrange = &m_ranges[idx];
2122 locrange->m_start
2123 = linemap_client_expand_location_to_spelling_point (src_range.m_start);
2124 locrange->m_finish
2125 = linemap_client_expand_location_to_spelling_point (src_range.m_finish);
2127 locrange->m_show_caret_p = show_caret_p;
2128 locrange->m_caret
2129 = linemap_client_expand_location_to_spelling_point (loc);
2131 /* Are we adding a range onto the end? */
2132 if (idx == m_num_ranges)
2133 m_num_ranges = idx + 1;
2135 if (idx == 0)
2137 m_loc = loc;
2138 /* Mark any cached value here as dirty. */
2139 m_have_expanded_location = false;
2143 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2144 at WHERE. */
2146 void
2147 rich_location::add_fixit_insert (source_location where,
2148 const char *new_content)
2150 linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
2151 m_fixit_hints[m_num_fixit_hints++]
2152 = new fixit_insert (where, new_content);
2155 /* Add a fixit-hint, suggesting removal of the content at
2156 SRC_RANGE. */
2158 void
2159 rich_location::add_fixit_remove (source_range src_range)
2161 linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
2162 m_fixit_hints[m_num_fixit_hints++] = new fixit_remove (src_range);
2165 /* Add a fixit-hint, suggesting replacement of the content at
2166 SRC_RANGE with NEW_CONTENT. */
2168 void
2169 rich_location::add_fixit_replace (source_range src_range,
2170 const char *new_content)
2172 linemap_assert (m_num_fixit_hints < MAX_FIXIT_HINTS);
2173 m_fixit_hints[m_num_fixit_hints++]
2174 = new fixit_replace (src_range, new_content);
2177 /* class fixit_insert. */
2179 fixit_insert::fixit_insert (source_location where,
2180 const char *new_content)
2181 : m_where (where),
2182 m_bytes (xstrdup (new_content)),
2183 m_len (strlen (new_content))
2187 fixit_insert::~fixit_insert ()
2189 free (m_bytes);
2192 /* Implementation of fixit_hint::affects_line_p for fixit_insert. */
2194 bool
2195 fixit_insert::affects_line_p (const char *file, int line)
2197 expanded_location exploc
2198 = linemap_client_expand_location_to_spelling_point (m_where);
2199 if (file == exploc.file)
2200 if (line == exploc.line)
2201 return true;
2202 return false;
2205 /* class fixit_remove. */
2207 fixit_remove::fixit_remove (source_range src_range)
2208 : m_src_range (src_range)
2212 /* Implementation of fixit_hint::affects_line_p for fixit_remove. */
2214 bool
2215 fixit_remove::affects_line_p (const char *file, int line)
2217 return m_src_range.intersects_line_p (file, line);
2220 /* class fixit_replace. */
2222 fixit_replace::fixit_replace (source_range src_range,
2223 const char *new_content)
2224 : m_src_range (src_range),
2225 m_bytes (xstrdup (new_content)),
2226 m_len (strlen (new_content))
2230 fixit_replace::~fixit_replace ()
2232 free (m_bytes);
2235 /* Implementation of fixit_hint::affects_line_p for fixit_replace. */
2237 bool
2238 fixit_replace::affects_line_p (const char *file, int line)
2240 return m_src_range.intersects_line_p (file, line);