1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2018 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3, or (at your option) any
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! */
29 static void trace_include (const struct line_maps
*, const line_map_ordinary
*);
30 static const line_map_ordinary
* linemap_ordinary_map_lookup (struct line_maps
*,
32 static const line_map_macro
* linemap_macro_map_lookup (struct line_maps
*,
34 static source_location linemap_macro_map_loc_to_def_point
35 (const line_map_macro
*, source_location
);
36 static source_location linemap_macro_map_loc_to_exp_point
37 (const line_map_macro
*, source_location
);
38 static source_location linemap_macro_loc_to_spelling_point
39 (struct line_maps
*, source_location
, const line_map_ordinary
**);
40 static source_location
linemap_macro_loc_to_def_point (struct line_maps
*,
42 const line_map_ordinary
**);
43 static source_location
linemap_macro_loc_to_exp_point (struct line_maps
*,
45 const line_map_ordinary
**);
47 /* Counters defined in macro.c. */
48 extern unsigned num_expanded_macros_counter
;
49 extern unsigned num_macro_tokens_counter
;
51 /* Destructor for class line_maps.
52 Ensure non-GC-managed memory is released. */
54 line_maps::~line_maps ()
56 if (location_adhoc_data_map
.htab
)
57 htab_delete (location_adhoc_data_map
.htab
);
60 /* Hash function for location_adhoc_data hashtable. */
63 location_adhoc_data_hash (const void *l
)
65 const struct location_adhoc_data
*lb
=
66 (const struct location_adhoc_data
*) l
;
67 return ((hashval_t
) lb
->locus
68 + (hashval_t
) lb
->src_range
.m_start
69 + (hashval_t
) lb
->src_range
.m_finish
73 /* Compare function for location_adhoc_data hashtable. */
76 location_adhoc_data_eq (const void *l1
, const void *l2
)
78 const struct location_adhoc_data
*lb1
=
79 (const struct location_adhoc_data
*) l1
;
80 const struct location_adhoc_data
*lb2
=
81 (const struct location_adhoc_data
*) l2
;
82 return (lb1
->locus
== lb2
->locus
83 && lb1
->src_range
.m_start
== lb2
->src_range
.m_start
84 && lb1
->src_range
.m_finish
== lb2
->src_range
.m_finish
85 && lb1
->data
== lb2
->data
);
88 /* Update the hashtable when location_adhoc_data is reallocated. */
91 location_adhoc_data_update (void **slot
, void *data
)
94 = (char *) ((uintptr_t) *((char **) slot
) + *((ptrdiff_t *) data
));
98 /* Rebuild the hash table from the location adhoc data. */
101 rebuild_location_adhoc_htab (struct line_maps
*set
)
104 set
->location_adhoc_data_map
.htab
=
105 htab_create (100, location_adhoc_data_hash
, location_adhoc_data_eq
, NULL
);
106 for (i
= 0; i
< set
->location_adhoc_data_map
.curr_loc
; i
++)
107 htab_find_slot (set
->location_adhoc_data_map
.htab
,
108 set
->location_adhoc_data_map
.data
+ i
, INSERT
);
111 /* Helper function for get_combined_adhoc_loc.
112 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
113 within a source_location, without needing to use an ad-hoc location. */
116 can_be_stored_compactly_p (struct line_maps
*set
,
117 source_location locus
,
118 source_range src_range
,
121 /* If there's an ad-hoc pointer, we can't store it directly in the
122 source_location, we need the lookaside. */
126 /* We only store ranges that begin at the locus and that are sufficiently
128 if (src_range
.m_start
!= locus
)
131 if (src_range
.m_finish
< src_range
.m_start
)
134 if (src_range
.m_start
< RESERVED_LOCATION_COUNT
)
137 if (locus
>= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
)
140 /* All 3 locations must be within ordinary maps, typically, the same
142 source_location lowest_macro_loc
= LINEMAPS_MACRO_LOWEST_LOCATION (set
);
143 if (locus
>= lowest_macro_loc
)
145 if (src_range
.m_start
>= lowest_macro_loc
)
147 if (src_range
.m_finish
>= lowest_macro_loc
)
150 /* Passed all tests. */
154 /* Combine LOCUS and DATA to a combined adhoc loc. */
157 get_combined_adhoc_loc (struct line_maps
*set
,
158 source_location locus
,
159 source_range src_range
,
162 struct location_adhoc_data lb
;
163 struct location_adhoc_data
**slot
;
165 if (IS_ADHOC_LOC (locus
))
167 = set
->location_adhoc_data_map
.data
[locus
& MAX_SOURCE_LOCATION
].locus
;
168 if (locus
== 0 && data
== NULL
)
171 /* Any ordinary locations ought to be "pure" at this point: no
172 compressed ranges. */
173 linemap_assert (locus
< RESERVED_LOCATION_COUNT
174 || locus
>= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
175 || locus
>= LINEMAPS_MACRO_LOWEST_LOCATION (set
)
176 || pure_location_p (set
, locus
));
178 /* Consider short-range optimization. */
179 if (can_be_stored_compactly_p (set
, locus
, src_range
, data
))
181 /* The low bits ought to be clear. */
182 linemap_assert (pure_location_p (set
, locus
));
183 const line_map
*map
= linemap_lookup (set
, locus
);
184 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
185 unsigned int int_diff
= src_range
.m_finish
- src_range
.m_start
;
186 unsigned int col_diff
= (int_diff
>> ordmap
->m_range_bits
);
187 if (col_diff
< (1U << ordmap
->m_range_bits
))
189 source_location packed
= locus
| col_diff
;
190 set
->num_optimized_ranges
++;
195 /* We can also compactly store locations
196 when locus == start == finish (and data is NULL). */
197 if (locus
== src_range
.m_start
198 && locus
== src_range
.m_finish
203 set
->num_unoptimized_ranges
++;
206 lb
.src_range
= src_range
;
208 slot
= (struct location_adhoc_data
**)
209 htab_find_slot (set
->location_adhoc_data_map
.htab
, &lb
, INSERT
);
212 if (set
->location_adhoc_data_map
.curr_loc
>=
213 set
->location_adhoc_data_map
.allocated
)
215 char *orig_data
= (char *) set
->location_adhoc_data_map
.data
;
217 /* Cast away extern "C" from the type of xrealloc. */
218 line_map_realloc reallocator
= (set
->reallocator
220 : (line_map_realloc
) xrealloc
);
222 if (set
->location_adhoc_data_map
.allocated
== 0)
223 set
->location_adhoc_data_map
.allocated
= 128;
225 set
->location_adhoc_data_map
.allocated
*= 2;
226 set
->location_adhoc_data_map
.data
= (struct location_adhoc_data
*)
227 reallocator (set
->location_adhoc_data_map
.data
,
228 set
->location_adhoc_data_map
.allocated
229 * sizeof (struct location_adhoc_data
));
230 offset
= (char *) (set
->location_adhoc_data_map
.data
) - orig_data
;
231 if (set
->location_adhoc_data_map
.allocated
> 128)
232 htab_traverse (set
->location_adhoc_data_map
.htab
,
233 location_adhoc_data_update
, &offset
);
235 *slot
= set
->location_adhoc_data_map
.data
236 + set
->location_adhoc_data_map
.curr_loc
;
237 set
->location_adhoc_data_map
.data
[set
->location_adhoc_data_map
.curr_loc
++]
240 return ((*slot
) - set
->location_adhoc_data_map
.data
) | 0x80000000;
243 /* Return the data for the adhoc loc. */
246 get_data_from_adhoc_loc (struct line_maps
*set
, source_location loc
)
248 linemap_assert (IS_ADHOC_LOC (loc
));
249 return set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].data
;
252 /* Return the location for the adhoc loc. */
255 get_location_from_adhoc_loc (struct line_maps
*set
, source_location loc
)
257 linemap_assert (IS_ADHOC_LOC (loc
));
258 return set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
261 /* Return the source_range for adhoc location LOC. */
264 get_range_from_adhoc_loc (struct line_maps
*set
, source_location loc
)
266 linemap_assert (IS_ADHOC_LOC (loc
));
267 return set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].src_range
;
270 /* Get the source_range of location LOC, either from the ad-hoc
271 lookaside table, or embedded inside LOC itself. */
274 get_range_from_loc (struct line_maps
*set
,
277 if (IS_ADHOC_LOC (loc
))
278 return get_range_from_adhoc_loc (set
, loc
);
280 /* For ordinary maps, extract packed range. */
281 if (loc
>= RESERVED_LOCATION_COUNT
282 && loc
< LINEMAPS_MACRO_LOWEST_LOCATION (set
)
283 && loc
<= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
)
285 const line_map
*map
= linemap_lookup (set
, loc
);
286 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
288 int offset
= loc
& ((1 << ordmap
->m_range_bits
) - 1);
289 result
.m_start
= loc
- offset
;
290 result
.m_finish
= result
.m_start
+ (offset
<< ordmap
->m_range_bits
);
294 return source_range::from_location (loc
);
297 /* Get whether location LOC is a "pure" location, or
298 whether it is an ad-hoc location, or embeds range information. */
301 pure_location_p (line_maps
*set
, source_location loc
)
303 if (IS_ADHOC_LOC (loc
))
306 const line_map
*map
= linemap_lookup (set
, loc
);
307 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
309 if (loc
& ((1U << ordmap
->m_range_bits
) - 1))
315 /* Given location LOC within SET, strip away any packed range information
316 or ad-hoc information. */
319 get_pure_location (line_maps
*set
, source_location loc
)
321 if (IS_ADHOC_LOC (loc
))
323 = set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
325 if (loc
>= LINEMAPS_MACRO_LOWEST_LOCATION (set
))
328 if (loc
< RESERVED_LOCATION_COUNT
)
331 const line_map
*map
= linemap_lookup (set
, loc
);
332 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
334 return loc
& ~((1 << ordmap
->m_range_bits
) - 1);
337 /* Initialize a line map set. */
340 linemap_init (struct line_maps
*set
,
341 source_location builtin_location
)
343 #if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
344 /* PR33916, needed to fix PR82939. */
345 memset (set
, 0, sizeof (struct line_maps
));
347 new (set
) line_maps();
349 set
->highest_location
= RESERVED_LOCATION_COUNT
- 1;
350 set
->highest_line
= RESERVED_LOCATION_COUNT
- 1;
351 set
->location_adhoc_data_map
.htab
=
352 htab_create (100, location_adhoc_data_hash
, location_adhoc_data_eq
, NULL
);
353 set
->builtin_location
= builtin_location
;
356 /* Check for and warn about line_maps entered but not exited. */
359 linemap_check_files_exited (struct line_maps
*set
)
361 const line_map_ordinary
*map
;
362 /* Depending upon whether we are handling preprocessed input or
363 not, this can be a user error or an ICE. */
364 for (map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
366 map
= INCLUDED_FROM (set
, map
))
367 fprintf (stderr
, "line-map.c: file \"%s\" entered but not left\n",
368 ORDINARY_MAP_FILE_NAME (map
));
371 /* Create a new line map in the line map set SET, and return it.
372 REASON is the reason of creating the map. It determines the type
373 of map created (ordinary or macro map). Note that ordinary maps and
374 macro maps are allocated in different memory location. */
376 static struct line_map
*
377 new_linemap (struct line_maps
*set
, source_location start_location
)
379 struct line_map
*result
;
380 bool macro_map_p
= start_location
>= LINE_MAP_MAX_LOCATION
;
382 if (LINEMAPS_USED (set
, macro_map_p
) == LINEMAPS_ALLOCATED (set
, macro_map_p
))
384 /* We ran out of allocated line maps. Let's allocate more. */
387 /* Cast away extern "C" from the type of xrealloc. */
388 line_map_realloc reallocator
= (set
->reallocator
390 : (line_map_realloc
) xrealloc
);
391 line_map_round_alloc_size_func round_alloc_size
=
392 set
->round_alloc_size
;
394 size_t map_size
= (macro_map_p
395 ? sizeof (line_map_macro
)
396 : sizeof (line_map_ordinary
));
398 /* We are going to execute some dance to try to reduce the
399 overhead of the memory allocator, in case we are using the
402 The actual size of memory we are going to get back from the
403 allocator is the smallest power of 2 that is greater than the
404 size we requested. So let's consider that size then. */
407 (2 * LINEMAPS_ALLOCATED (set
, macro_map_p
) + 256)
410 /* Get the actual size of memory that is going to be allocated
412 alloc_size
= round_alloc_size (alloc_size
);
414 /* Now alloc_size contains the exact memory size we would get if
415 we have asked for the initial alloc_size amount of memory.
416 Let's get back to the number of macro map that amounts
418 LINEMAPS_ALLOCATED (set
, macro_map_p
) =
419 alloc_size
/ map_size
;
421 /* And now let's really do the re-allocation. */
425 = (line_map_macro
*) (*reallocator
) (set
->info_macro
.maps
,
426 (LINEMAPS_ALLOCATED (set
, macro_map_p
)
428 result
= &set
->info_macro
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
432 set
->info_ordinary
.maps
=
433 (line_map_ordinary
*) (*reallocator
) (set
->info_ordinary
.maps
,
434 (LINEMAPS_ALLOCATED (set
, macro_map_p
)
436 result
= &set
->info_ordinary
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
439 ((LINEMAPS_ALLOCATED (set
, macro_map_p
)
440 - LINEMAPS_USED (set
, macro_map_p
))
446 result
= &set
->info_macro
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
448 result
= &set
->info_ordinary
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
451 result
->start_location
= start_location
;
453 LINEMAPS_USED (set
, macro_map_p
)++;
458 /* Add a mapping of logical source line to physical source file and
461 The text pointed to by TO_FILE must have a lifetime
462 at least as long as the final call to lookup_line (). An empty
463 TO_FILE means standard input. If reason is LC_LEAVE, and
464 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
465 natural values considering the file we are returning to.
467 FROM_LINE should be monotonic increasing across calls to this
468 function. A call to this function can relocate the previous set of
469 maps, so any stored line_map pointers should not be used. */
471 const struct line_map
*
472 linemap_add (struct line_maps
*set
, enum lc_reason reason
,
473 unsigned int sysp
, const char *to_file
, linenum_type to_line
)
475 /* Generate a start_location above the current highest_location.
476 If possible, make the low range bits be zero. */
477 source_location start_location
;
478 if (set
->highest_location
< LINE_MAP_MAX_LOCATION_WITH_COLS
)
480 start_location
= set
->highest_location
+ (1 << set
->default_range_bits
);
481 if (set
->default_range_bits
)
482 start_location
&= ~((1 << set
->default_range_bits
) - 1);
483 linemap_assert (0 == (start_location
484 & ((1 << set
->default_range_bits
) - 1)));
487 start_location
= set
->highest_location
+ 1;
489 linemap_assert (!LINEMAPS_ORDINARY_USED (set
)
491 >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set
))));
493 /* When we enter the file for the first time reason cannot be
495 linemap_assert (!(set
->depth
== 0 && reason
== LC_RENAME
));
497 /* If we are leaving the main file, return a NULL map. */
498 if (reason
== LC_LEAVE
499 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set
))
506 linemap_assert (reason
!= LC_ENTER_MACRO
);
507 line_map_ordinary
*map
508 = linemap_check_ordinary (new_linemap (set
, start_location
));
509 map
->reason
= reason
;
511 if (to_file
&& *to_file
== '\0' && reason
!= LC_RENAME_VERBATIM
)
514 if (reason
== LC_RENAME_VERBATIM
)
517 if (reason
== LC_LEAVE
)
519 /* When we are just leaving an "included" file, and jump to the next
520 location inside the "includer" right after the #include
521 "included", this variable points the map in use right before the
522 #include "included", inside the same "includer" file. */
523 line_map_ordinary
*from
;
525 linemap_assert (!MAIN_FILE_P (map
- 1));
526 /* (MAP - 1) points to the map we are leaving. The
527 map from which (MAP - 1) got included should be the map
528 that comes right before MAP in the same file. */
529 from
= INCLUDED_FROM (set
, map
- 1);
531 /* A TO_FILE of NULL is special - we use the natural values. */
534 to_file
= ORDINARY_MAP_FILE_NAME (from
);
535 to_line
= SOURCE_LINE (from
, from
[1].start_location
);
536 sysp
= ORDINARY_MAP_IN_SYSTEM_HEADER_P (from
);
539 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from
),
544 map
->to_file
= to_file
;
545 map
->to_line
= to_line
;
546 LINEMAPS_ORDINARY_CACHE (set
) = LINEMAPS_ORDINARY_USED (set
) - 1;
547 map
->m_column_and_range_bits
= 0;
548 map
->m_range_bits
= 0;
549 set
->highest_location
= start_location
;
550 set
->highest_line
= start_location
;
551 set
->max_column_hint
= 0;
553 /* This assertion is placed after set->highest_location has
554 been updated, since the latter affects
555 linemap_location_from_macro_expansion_p, which ultimately affects
557 linemap_assert (pure_location_p (set
, start_location
));
559 if (reason
== LC_ENTER
)
562 set
->depth
== 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set
) - 2);
564 if (set
->trace_includes
)
565 trace_include (set
, map
);
567 else if (reason
== LC_RENAME
)
568 map
->included_from
= ORDINARY_MAP_INCLUDER_FILE_INDEX (&map
[-1]);
569 else if (reason
== LC_LEAVE
)
573 ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set
, map
- 1));
579 /* Returns TRUE if the line table set tracks token locations across
580 macro expansion, FALSE otherwise. */
583 linemap_tracks_macro_expansion_locs_p (struct line_maps
*set
)
585 return LINEMAPS_MACRO_MAPS (set
) != NULL
;
588 /* Create a macro map. A macro map encodes source locations of tokens
589 that are part of a macro replacement-list, at a macro expansion
590 point. See the extensive comments of struct line_map and struct
591 line_map_macro, in line-map.h.
593 This map shall be created when the macro is expanded. The map
594 encodes the source location of the expansion point of the macro as
595 well as the "original" source location of each token that is part
596 of the macro replacement-list. If a macro is defined but never
597 expanded, it has no macro map. SET is the set of maps the macro
598 map should be part of. MACRO_NODE is the macro which the new macro
599 map should encode source locations for. EXPANSION is the location
600 of the expansion point of MACRO. For function-like macros
601 invocations, it's best to make it point to the closing parenthesis
602 of the macro, rather than the the location of the first character
603 of the macro. NUM_TOKENS is the number of tokens that are part of
604 the replacement-list of MACRO.
606 Note that when we run out of the integer space available for source
607 locations, this function returns NULL. In that case, callers of
608 this function cannot encode {line,column} pairs into locations of
609 macro tokens anymore. */
611 const line_map_macro
*
612 linemap_enter_macro (struct line_maps
*set
, struct cpp_hashnode
*macro_node
,
613 source_location expansion
, unsigned int num_tokens
)
616 source_location start_location
;
617 /* Cast away extern "C" from the type of xrealloc. */
618 line_map_realloc reallocator
= (set
->reallocator
620 : (line_map_realloc
) xrealloc
);
622 start_location
= LINEMAPS_MACRO_LOWEST_LOCATION (set
) - num_tokens
;
624 if (start_location
< LINE_MAP_MAX_LOCATION
)
625 /* We ran out of macro map space. */
628 map
= linemap_check_macro (new_linemap (set
, start_location
));
630 map
->macro
= macro_node
;
631 map
->n_tokens
= num_tokens
;
633 = (source_location
*) reallocator (NULL
,
635 * sizeof (source_location
));
636 map
->expansion
= expansion
;
637 memset (MACRO_MAP_LOCATIONS (map
), 0,
638 num_tokens
* sizeof (source_location
));
640 LINEMAPS_MACRO_CACHE (set
) = LINEMAPS_MACRO_USED (set
) - 1;
645 /* Create and return a virtual location for a token that is part of a
646 macro expansion-list at a macro expansion point. See the comment
647 inside struct line_map_macro to see what an expansion-list exactly
650 A call to this function must come after a call to
653 MAP is the map into which the source location is created. TOKEN_NO
654 is the index of the token in the macro replacement-list, starting
657 ORIG_LOC is the location of the token outside of this macro
658 expansion. If the token comes originally from the macro
659 definition, it is the locus in the macro definition; otherwise it
660 is a location in the context of the caller of this macro expansion
661 (which is a virtual location or a source location if the caller is
662 itself a macro expansion or not).
664 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
665 either of the token itself or of a macro parameter that it
669 linemap_add_macro_token (const line_map_macro
*map
,
670 unsigned int token_no
,
671 source_location orig_loc
,
672 source_location orig_parm_replacement_loc
)
674 source_location result
;
676 linemap_assert (linemap_macro_expansion_map_p (map
));
677 linemap_assert (token_no
< MACRO_MAP_NUM_MACRO_TOKENS (map
));
679 MACRO_MAP_LOCATIONS (map
)[2 * token_no
] = orig_loc
;
680 MACRO_MAP_LOCATIONS (map
)[2 * token_no
+ 1] = orig_parm_replacement_loc
;
682 result
= MAP_START_LOCATION (map
) + token_no
;
686 /* Return a source_location for the start (i.e. column==0) of
687 (physical) line TO_LINE in the current source file (as in the
688 most recent linemap_add). MAX_COLUMN_HINT is the highest column
689 number we expect to use in this line (but it does not change
690 the highest_location). */
693 linemap_line_start (struct line_maps
*set
, linenum_type to_line
,
694 unsigned int max_column_hint
)
696 line_map_ordinary
*map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
697 source_location highest
= set
->highest_location
;
699 linenum_type last_line
=
700 SOURCE_LINE (map
, set
->highest_line
);
701 int line_delta
= to_line
- last_line
;
702 bool add_map
= false;
703 linemap_assert (map
->m_column_and_range_bits
>= map
->m_range_bits
);
704 int effective_column_bits
= map
->m_column_and_range_bits
- map
->m_range_bits
;
708 && line_delta
* map
->m_column_and_range_bits
> 1000)
709 || (max_column_hint
>= (1U << effective_column_bits
))
710 || (max_column_hint
<= 80 && effective_column_bits
>= 10)
711 || (highest
> LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
712 && map
->m_range_bits
> 0)
713 || (highest
> LINE_MAP_MAX_LOCATION_WITH_COLS
714 && (set
->max_column_hint
|| highest
>= LINE_MAP_MAX_LOCATION
)))
717 max_column_hint
= set
->max_column_hint
;
722 if (max_column_hint
> LINE_MAP_MAX_COLUMN_NUMBER
723 || highest
> LINE_MAP_MAX_LOCATION_WITH_COLS
)
725 /* If the column number is ridiculous or we've allocated a huge
726 number of source_locations, give up on column numbers
727 (and on packed ranges). */
731 if (highest
>= LINE_MAP_MAX_LOCATION
)
737 if (highest
<= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
)
738 range_bits
= set
->default_range_bits
;
741 while (max_column_hint
>= (1U << column_bits
))
743 max_column_hint
= 1U << column_bits
;
744 column_bits
+= range_bits
;
746 /* Allocate the new line_map. However, if the current map only has a
747 single line we can sometimes just increase its column_bits instead. */
749 || last_line
!= ORDINARY_MAP_STARTING_LINE_NUMBER (map
)
750 || SOURCE_COLUMN (map
, highest
) >= (1U << (column_bits
- range_bits
))
751 || range_bits
< map
->m_range_bits
)
752 map
= linemap_check_ordinary
753 (const_cast <line_map
*>
754 (linemap_add (set
, LC_RENAME
,
755 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map
),
756 ORDINARY_MAP_FILE_NAME (map
),
758 map
->m_column_and_range_bits
= column_bits
;
759 map
->m_range_bits
= range_bits
;
760 r
= (MAP_START_LOCATION (map
)
761 + ((to_line
- ORDINARY_MAP_STARTING_LINE_NUMBER (map
))
765 r
= set
->highest_line
+ (line_delta
<< map
->m_column_and_range_bits
);
767 /* Locations of ordinary tokens are always lower than locations of
769 if (r
>= LINE_MAP_MAX_LOCATION
)
772 set
->highest_line
= r
;
773 if (r
> set
->highest_location
)
774 set
->highest_location
= r
;
775 set
->max_column_hint
= max_column_hint
;
777 /* At this point, we expect one of:
778 (a) the normal case: a "pure" location with 0 range bits, or
779 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
780 columns anymore (or ranges), or
781 (c) we're in a region with a column hint exceeding
782 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
783 with column_bits == 0. */
784 linemap_assert (pure_location_p (set
, r
)
785 || r
>= LINE_MAP_MAX_LOCATION_WITH_COLS
786 || map
->m_column_and_range_bits
== 0);
787 linemap_assert (SOURCE_LINE (map
, r
) == to_line
);
791 /* Encode and return a source_location from a column number. The
792 source line considered is the last source line used to call
793 linemap_line_start, i.e, the last source line which a location was
797 linemap_position_for_column (struct line_maps
*set
, unsigned int to_column
)
799 source_location r
= set
->highest_line
;
802 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set
)));
804 if (to_column
>= set
->max_column_hint
)
806 if (r
> LINE_MAP_MAX_LOCATION_WITH_COLS
807 || to_column
> LINE_MAP_MAX_COLUMN_NUMBER
)
809 /* Running low on source_locations - disable column numbers. */
814 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
815 with some space to spare. This may or may not lead to a new
816 linemap being created. */
817 line_map_ordinary
*map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
818 r
= linemap_line_start (set
, SOURCE_LINE (map
, r
), to_column
+ 50);
819 map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
820 if (map
->m_column_and_range_bits
== 0)
822 /* ...then the linemap has column-tracking disabled,
823 presumably due to exceeding either
824 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
825 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
826 Return the start of the linemap, which encodes column 0, for
832 line_map_ordinary
*map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
833 r
= r
+ (to_column
<< map
->m_range_bits
);
834 if (r
>= set
->highest_location
)
835 set
->highest_location
= r
;
839 /* Encode and return a source location from a given line and
843 linemap_position_for_line_and_column (line_maps
*set
,
844 const line_map_ordinary
*ord_map
,
848 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map
) <= line
);
850 source_location r
= MAP_START_LOCATION (ord_map
);
851 r
+= ((line
- ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map
))
852 << ord_map
->m_column_and_range_bits
);
853 if (r
<= LINE_MAP_MAX_LOCATION_WITH_COLS
)
854 r
+= ((column
& ((1 << ord_map
->m_column_and_range_bits
) - 1))
855 << ord_map
->m_range_bits
);
856 source_location upper_limit
= LINEMAPS_MACRO_LOWEST_LOCATION (set
);
857 if (r
>= upper_limit
)
859 if (r
> set
->highest_location
)
860 set
->highest_location
= r
;
864 /* Encode and return a source_location starting from location LOC and
865 shifting it by COLUMN_OFFSET columns. This function does not support
866 virtual locations. */
869 linemap_position_for_loc_and_offset (struct line_maps
*set
,
871 unsigned int column_offset
)
873 const line_map_ordinary
* map
= NULL
;
875 if (IS_ADHOC_LOC (loc
))
876 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
878 /* This function does not support virtual locations yet. */
879 if (linemap_location_from_macro_expansion_p (set
, loc
))
882 if (column_offset
== 0
883 /* Adding an offset to a reserved location (like
884 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
885 sense. So let's leave the location intact in that case. */
886 || loc
< RESERVED_LOCATION_COUNT
)
889 /* We find the real location and shift it. */
890 loc
= linemap_resolve_location (set
, loc
, LRK_SPELLING_LOCATION
, &map
);
891 /* The new location (loc + offset) should be higher than the first
892 location encoded by MAP. This can fail if the line information
893 is messed up because of line directives (see PR66415). */
894 if (MAP_START_LOCATION (map
) >= loc
+ (column_offset
<< map
->m_range_bits
))
897 linenum_type line
= SOURCE_LINE (map
, loc
);
898 unsigned int column
= SOURCE_COLUMN (map
, loc
);
900 /* If MAP is not the last line map of its set, then the new location
901 (loc + offset) should be less than the first location encoded by
902 the next line map of the set. Otherwise, we try to encode the
903 location in the next map. */
904 while (map
!= LINEMAPS_LAST_ORDINARY_MAP (set
)
905 && (loc
+ (column_offset
<< map
->m_range_bits
)
906 >= MAP_START_LOCATION (&map
[1])))
909 /* If the next map starts in a higher line, we cannot encode the
911 if (line
< ORDINARY_MAP_STARTING_LINE_NUMBER (map
))
915 column
+= column_offset
;
917 /* Bail out if the column is not representable within the existing
919 if (column
>= (1u << (map
->m_column_and_range_bits
- map
->m_range_bits
)))
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
)))
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
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
)
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]))
980 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set
, md
)) > line
)
986 LINEMAPS_ORDINARY_CACHE (set
) = mn
;
987 result
= LINEMAPS_ORDINARY_MAP_AT (set
, mn
);
988 linemap_assert (line
>= MAP_START_LOCATION (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
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
));
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]))
1026 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set
, md
)) > line
)
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
);
1039 /* Return TRUE if MAP encodes locations coming from a macro
1040 replacement-list at macro expansion point. */
1043 linemap_macro_expansion_map_p (const struct line_map
*map
)
1045 return map
&& !MAP_ORDINARY_P (map
);
1048 /* If LOCATION is the locus of a token in a replacement-list of a
1049 macro expansion return the location of the macro expansion point.
1051 Read the comments of struct line_map and struct line_map_macro in
1052 line-map.h to understand what a macro expansion point is. */
1054 static source_location
1055 linemap_macro_map_loc_to_exp_point (const line_map_macro
*map
,
1056 source_location location ATTRIBUTE_UNUSED
)
1058 linemap_assert (linemap_macro_expansion_map_p (map
)
1059 && location
>= MAP_START_LOCATION (map
));
1061 /* Make sure LOCATION is correct. */
1062 linemap_assert ((location
- MAP_START_LOCATION (map
))
1063 < MACRO_MAP_NUM_MACRO_TOKENS (map
));
1065 return MACRO_MAP_EXPANSION_POINT_LOCATION (map
);
1068 /* LOCATION is the source location of a token that belongs to a macro
1069 replacement-list as part of the macro expansion denoted by MAP.
1071 Return the location of the token at the definition point of the
1074 static source_location
1075 linemap_macro_map_loc_to_def_point (const line_map_macro
*map
,
1076 source_location location
)
1080 linemap_assert (linemap_macro_expansion_map_p (map
)
1081 && location
>= MAP_START_LOCATION (map
));
1082 linemap_assert (location
>= RESERVED_LOCATION_COUNT
);
1084 token_no
= location
- MAP_START_LOCATION (map
);
1085 linemap_assert (token_no
< MACRO_MAP_NUM_MACRO_TOKENS (map
));
1087 location
= MACRO_MAP_LOCATIONS (map
)[2 * token_no
+ 1];
1092 /* If LOCATION is the locus of a token that is an argument of a
1093 function-like macro M and appears in the expansion of M, return the
1094 locus of that argument in the context of the caller of M.
1096 In other words, this returns the xI location presented in the
1097 comments of line_map_macro above. */
1099 linemap_macro_map_loc_unwind_toward_spelling (line_maps
*set
,
1100 const line_map_macro
* map
,
1101 source_location location
)
1105 if (IS_ADHOC_LOC (location
))
1106 location
= get_location_from_adhoc_loc (set
, location
);
1108 linemap_assert (linemap_macro_expansion_map_p (map
)
1109 && location
>= MAP_START_LOCATION (map
));
1110 linemap_assert (location
>= RESERVED_LOCATION_COUNT
);
1111 linemap_assert (!IS_ADHOC_LOC (location
));
1113 token_no
= location
- MAP_START_LOCATION (map
);
1114 linemap_assert (token_no
< MACRO_MAP_NUM_MACRO_TOKENS (map
));
1116 location
= MACRO_MAP_LOCATIONS (map
)[2 * token_no
];
1121 /* Return the source line number corresponding to source location
1122 LOCATION. SET is the line map set LOCATION comes from. If
1123 LOCATION is the source location of token that is part of the
1124 replacement-list of a macro expansion return the line number of the
1125 macro expansion point. */
1128 linemap_get_expansion_line (struct line_maps
*set
,
1129 source_location location
)
1131 const line_map_ordinary
*map
= NULL
;
1133 if (IS_ADHOC_LOC (location
))
1134 location
= set
->location_adhoc_data_map
.data
[location
1135 & MAX_SOURCE_LOCATION
].locus
;
1137 if (location
< RESERVED_LOCATION_COUNT
)
1141 linemap_macro_loc_to_exp_point (set
, location
, &map
);
1143 return SOURCE_LINE (map
, location
);
1146 /* Return the path of the file corresponding to source code location
1149 If LOCATION is the source location of token that is part of the
1150 replacement-list of a macro expansion return the file path of the
1151 macro expansion point.
1153 SET is the line map set LOCATION comes from. */
1156 linemap_get_expansion_filename (struct line_maps
*set
,
1157 source_location location
)
1159 const struct line_map_ordinary
*map
= NULL
;
1161 if (IS_ADHOC_LOC (location
))
1162 location
= set
->location_adhoc_data_map
.data
[location
1163 & MAX_SOURCE_LOCATION
].locus
;
1165 if (location
< RESERVED_LOCATION_COUNT
)
1169 linemap_macro_loc_to_exp_point (set
, location
, &map
);
1171 return LINEMAP_FILE (map
);
1174 /* Return the name of the macro associated to MACRO_MAP. */
1177 linemap_map_get_macro_name (const line_map_macro
*macro_map
)
1179 linemap_assert (macro_map
&& linemap_macro_expansion_map_p (macro_map
));
1180 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map
));
1183 /* Return a positive value if LOCATION is the locus of a token that is
1184 located in a system header, O otherwise. It returns 1 if LOCATION
1185 is the locus of a token that is located in a system header, and 2
1186 if LOCATION is the locus of a token located in a C system header
1187 that therefore needs to be extern "C" protected in C++.
1189 Note that this function returns 1 if LOCATION belongs to a token
1190 that is part of a macro replacement-list defined in a system
1191 header, but expanded in a non-system file. */
1194 linemap_location_in_system_header_p (struct line_maps
*set
,
1195 source_location location
)
1197 const struct line_map
*map
= NULL
;
1199 if (IS_ADHOC_LOC (location
))
1200 location
= set
->location_adhoc_data_map
.data
[location
1201 & MAX_SOURCE_LOCATION
].locus
;
1203 if (location
< RESERVED_LOCATION_COUNT
)
1206 /* Let's look at where the token for LOCATION comes from. */
1209 map
= linemap_lookup (set
, location
);
1212 if (!linemap_macro_expansion_map_p (map
))
1213 /* It's a normal token. */
1214 return LINEMAP_SYSP (linemap_check_ordinary (map
));
1217 const line_map_macro
*macro_map
= linemap_check_macro (map
);
1219 /* It's a token resulting from a macro expansion. */
1220 source_location loc
=
1221 linemap_macro_map_loc_unwind_toward_spelling (set
, macro_map
, location
);
1222 if (loc
< RESERVED_LOCATION_COUNT
)
1223 /* This token might come from a built-in macro. Let's
1224 look at where that macro got expanded. */
1225 location
= linemap_macro_map_loc_to_exp_point (macro_map
, location
);
1236 /* Return TRUE if LOCATION is a source code location of a token that is part of
1237 a macro expansion, FALSE otherwise. */
1240 linemap_location_from_macro_expansion_p (const struct line_maps
*set
,
1241 source_location location
)
1243 if (IS_ADHOC_LOC (location
))
1244 location
= set
->location_adhoc_data_map
.data
[location
1245 & MAX_SOURCE_LOCATION
].locus
;
1247 return location
>= LINE_MAP_MAX_LOCATION
;
1250 /* Given two virtual locations *LOC0 and *LOC1, return the first
1251 common macro map in their macro expansion histories. Return NULL
1252 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1253 virtual location of the token inside the resulting macro. */
1255 static const struct line_map
*
1256 first_map_in_common_1 (struct line_maps
*set
,
1257 source_location
*loc0
,
1258 source_location
*loc1
)
1260 source_location l0
= *loc0
, l1
= *loc1
;
1261 const struct line_map
*map0
= linemap_lookup (set
, l0
),
1262 *map1
= linemap_lookup (set
, l1
);
1264 while (linemap_macro_expansion_map_p (map0
)
1265 && linemap_macro_expansion_map_p (map1
)
1268 if (MAP_START_LOCATION (map0
) < MAP_START_LOCATION (map1
))
1270 l0
= linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0
),
1272 map0
= linemap_lookup (set
, l0
);
1276 l1
= linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1
),
1278 map1
= linemap_lookup (set
, l1
);
1291 /* Given two virtual locations LOC0 and LOC1, return the first common
1292 macro map in their macro expansion histories. Return NULL if no
1293 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1294 virtual location of the token inside the resulting macro, upon
1295 return of a non-NULL result. */
1297 static const struct line_map
*
1298 first_map_in_common (struct line_maps
*set
,
1299 source_location loc0
,
1300 source_location loc1
,
1301 source_location
*res_loc0
,
1302 source_location
*res_loc1
)
1307 return first_map_in_common_1 (set
, res_loc0
, res_loc1
);
1310 /* Return a positive value if PRE denotes the location of a token that
1311 comes before the token of POST, 0 if PRE denotes the location of
1312 the same token as the token for POST, and a negative value
1316 linemap_compare_locations (struct line_maps
*set
,
1317 source_location pre
,
1318 source_location post
)
1320 bool pre_virtual_p
, post_virtual_p
;
1321 source_location l0
= pre
, l1
= post
;
1323 if (IS_ADHOC_LOC (l0
))
1324 l0
= get_location_from_adhoc_loc (set
, l0
);
1325 if (IS_ADHOC_LOC (l1
))
1326 l1
= get_location_from_adhoc_loc (set
, l1
);
1331 if ((pre_virtual_p
= linemap_location_from_macro_expansion_p (set
, l0
)))
1332 l0
= linemap_resolve_location (set
, l0
,
1333 LRK_MACRO_EXPANSION_POINT
,
1336 if ((post_virtual_p
= linemap_location_from_macro_expansion_p (set
, l1
)))
1337 l1
= linemap_resolve_location (set
, l1
,
1338 LRK_MACRO_EXPANSION_POINT
,
1345 /* So pre and post represent two tokens that are present in a
1346 same macro expansion. Let's see if the token for pre was
1347 before the token for post in that expansion. */
1349 const struct line_map
*map
=
1350 first_map_in_common (set
, pre
, post
, &l0
, &l1
);
1353 /* This should not be possible. */
1356 i0
= l0
- MAP_START_LOCATION (map
);
1357 i1
= l1
- MAP_START_LOCATION (map
);
1361 if (IS_ADHOC_LOC (l0
))
1362 l0
= get_location_from_adhoc_loc (set
, l0
);
1363 if (IS_ADHOC_LOC (l1
))
1364 l1
= get_location_from_adhoc_loc (set
, l1
);
1369 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1372 trace_include (const struct line_maps
*set
, const line_map_ordinary
*map
)
1374 unsigned int i
= set
->depth
;
1379 fprintf (stderr
, " %s\n", ORDINARY_MAP_FILE_NAME (map
));
1382 /* Return the spelling location of the token wherever it comes from,
1383 whether part of a macro definition or not.
1385 This is a subroutine for linemap_resolve_location. */
1387 static source_location
1388 linemap_macro_loc_to_spelling_point (struct line_maps
*set
,
1389 source_location location
,
1390 const line_map_ordinary
**original_map
)
1392 linemap_assert (set
&& location
>= RESERVED_LOCATION_COUNT
);
1396 const struct line_map
*map
= linemap_lookup (set
, location
);
1397 if (!map
|| MAP_ORDINARY_P (map
))
1400 *original_map
= (const line_map_ordinary
*)map
;
1404 location
= linemap_macro_map_loc_unwind_toward_spelling
1405 (set
, linemap_check_macro (map
), location
);
1411 /* If LOCATION is the source location of a token that belongs to a
1412 macro replacement-list -- as part of a macro expansion -- then
1413 return the location of the token at the definition point of the
1414 macro. Otherwise, return LOCATION. SET is the set of maps
1415 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1416 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1417 returned location comes from.
1419 This is a subroutine of linemap_resolve_location. */
1421 static source_location
1422 linemap_macro_loc_to_def_point (struct line_maps
*set
,
1423 source_location location
,
1424 const line_map_ordinary
**original_map
)
1426 linemap_assert (set
&& location
>= RESERVED_LOCATION_COUNT
);
1430 source_location caret_loc
= location
;
1431 if (IS_ADHOC_LOC (caret_loc
))
1432 caret_loc
= get_location_from_adhoc_loc (set
, caret_loc
);
1434 const line_map
*map
= linemap_lookup (set
, caret_loc
);
1435 if (!map
|| MAP_ORDINARY_P (map
))
1438 *original_map
= (const line_map_ordinary
*)map
;
1442 location
= linemap_macro_map_loc_to_def_point
1443 (linemap_check_macro (map
), caret_loc
);
1449 /* If LOCATION is the source location of a token that belongs to a
1450 macro replacement-list -- at a macro expansion point -- then return
1451 the location of the topmost expansion point of the macro. We say
1452 topmost because if we are in the context of a nested macro
1453 expansion, the function returns the source location of the first
1454 macro expansion that triggered the nested expansions.
1456 Otherwise, return LOCATION. SET is the set of maps location come
1457 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1458 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1459 location comes from.
1461 This is a subroutine of linemap_resolve_location. */
1463 static source_location
1464 linemap_macro_loc_to_exp_point (struct line_maps
*set
,
1465 source_location location
,
1466 const line_map_ordinary
**original_map
)
1468 struct line_map
*map
;
1470 if (IS_ADHOC_LOC (location
))
1471 location
= set
->location_adhoc_data_map
.data
[location
1472 & MAX_SOURCE_LOCATION
].locus
;
1474 linemap_assert (set
&& location
>= RESERVED_LOCATION_COUNT
);
1478 map
= const_cast <line_map
*> (linemap_lookup (set
, location
));
1479 if (!linemap_macro_expansion_map_p (map
))
1481 location
= linemap_macro_map_loc_to_exp_point (linemap_check_macro (map
),
1486 *original_map
= linemap_check_ordinary (map
);
1490 /* Resolve a virtual location into either a spelling location, an
1491 expansion point location or a token argument replacement point
1492 location. Return the map that encodes the virtual location as well
1493 as the resolved location.
1495 If LOC is *NOT* the location of a token resulting from the
1496 expansion of a macro, then the parameter LRK (which stands for
1497 Location Resolution Kind) is ignored and the resulting location
1498 just equals the one given in argument.
1500 Now if LOC *IS* the location of a token resulting from the
1501 expansion of a macro, this is what happens.
1503 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1504 -------------------------------
1506 The virtual location is resolved to the first macro expansion point
1507 that led to this macro expansion.
1509 * If LRK is set to LRK_SPELLING_LOCATION
1510 -------------------------------------
1512 The virtual location is resolved to the locus where the token has
1513 been spelled in the source. This can follow through all the macro
1514 expansions that led to the token.
1516 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1517 --------------------------------------
1519 The virtual location is resolved to the locus of the token in the
1520 context of the macro definition.
1522 If LOC is the locus of a token that is an argument of a
1523 function-like macro [replacing a parameter in the replacement list
1524 of the macro] the virtual location is resolved to the locus of the
1525 parameter that is replaced, in the context of the definition of the
1528 If LOC is the locus of a token that is not an argument of a
1529 function-like macro, then the function behaves as if LRK was set to
1530 LRK_SPELLING_LOCATION.
1532 If MAP is not NULL, *MAP is set to the map encoding the
1533 returned location. Note that if the returned location wasn't originally
1534 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1535 resolves to a location reserved for the client code, like
1536 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1539 linemap_resolve_location (struct line_maps
*set
,
1540 source_location loc
,
1541 enum location_resolution_kind lrk
,
1542 const line_map_ordinary
**map
)
1544 source_location locus
= loc
;
1545 if (IS_ADHOC_LOC (loc
))
1546 locus
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1548 if (locus
< RESERVED_LOCATION_COUNT
)
1550 /* A reserved location wasn't encoded in a map. Let's return a
1551 NULL map here, just like what linemap_ordinary_map_lookup
1560 case LRK_MACRO_EXPANSION_POINT
:
1561 loc
= linemap_macro_loc_to_exp_point (set
, loc
, map
);
1563 case LRK_SPELLING_LOCATION
:
1564 loc
= linemap_macro_loc_to_spelling_point (set
, loc
, map
);
1566 case LRK_MACRO_DEFINITION_LOCATION
:
1567 loc
= linemap_macro_loc_to_def_point (set
, loc
, map
);
1575 /* TRUE if LOCATION is a source code location of a token that is part of the
1576 definition of a macro, FALSE otherwise. */
1579 linemap_location_from_macro_definition_p (struct line_maps
*set
,
1580 source_location loc
)
1582 if (IS_ADHOC_LOC (loc
))
1583 loc
= get_location_from_adhoc_loc (set
, loc
);
1585 if (!linemap_location_from_macro_expansion_p (set
, loc
))
1590 const struct line_map_macro
*map
1591 = linemap_check_macro (linemap_lookup (set
, loc
));
1593 source_location s_loc
1594 = linemap_macro_map_loc_unwind_toward_spelling (set
, map
, loc
);
1595 if (linemap_location_from_macro_expansion_p (set
, s_loc
))
1599 source_location def_loc
1600 = linemap_macro_map_loc_to_def_point (map
, loc
);
1601 return s_loc
== def_loc
;
1607 Suppose that LOC is the virtual location of a token T coming from
1608 the expansion of a macro M. This function then steps up to get the
1609 location L of the point where M got expanded. If L is a spelling
1610 location inside a macro expansion M', then this function returns
1611 the locus of the point where M' was expanded. Said otherwise, this
1612 function returns the location of T in the context that triggered
1615 *LOC_MAP must be set to the map of LOC. This function then sets it
1616 to the map of the returned location. */
1619 linemap_unwind_toward_expansion (struct line_maps
*set
,
1620 source_location loc
,
1621 const struct line_map
**map
)
1623 source_location resolved_location
;
1624 const line_map_macro
*macro_map
= linemap_check_macro (*map
);
1625 const struct line_map
*resolved_map
;
1627 if (IS_ADHOC_LOC (loc
))
1628 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1631 linemap_macro_map_loc_unwind_toward_spelling (set
, macro_map
, loc
);
1632 resolved_map
= linemap_lookup (set
, resolved_location
);
1634 if (!linemap_macro_expansion_map_p (resolved_map
))
1636 resolved_location
= linemap_macro_map_loc_to_exp_point (macro_map
, loc
);
1637 resolved_map
= linemap_lookup (set
, resolved_location
);
1640 *map
= resolved_map
;
1641 return resolved_location
;
1644 /* If LOC is the virtual location of a token coming from the expansion
1645 of a macro M and if its spelling location is reserved (e.g, a
1646 location for a built-in token), then this function unwinds (using
1647 linemap_unwind_toward_expansion) the location until a location that
1648 is not reserved and is not in a system header is reached. In other
1649 words, this unwinds the reserved location until a location that is
1650 in real source code is reached.
1652 Otherwise, if the spelling location for LOC is not reserved or if
1653 LOC doesn't come from the expansion of a macro, the function
1654 returns LOC as is and *MAP is not touched.
1656 *MAP is set to the map of the returned location if the later is
1657 different from LOC. */
1659 linemap_unwind_to_first_non_reserved_loc (struct line_maps
*set
,
1660 source_location loc
,
1661 const struct line_map
**map
)
1663 source_location resolved_loc
;
1664 const struct line_map
*map0
= NULL
;
1665 const line_map_ordinary
*map1
= NULL
;
1667 if (IS_ADHOC_LOC (loc
))
1668 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1670 map0
= linemap_lookup (set
, loc
);
1671 if (!linemap_macro_expansion_map_p (map0
))
1674 resolved_loc
= linemap_resolve_location (set
, loc
,
1675 LRK_SPELLING_LOCATION
,
1678 if (resolved_loc
>= RESERVED_LOCATION_COUNT
1679 && !LINEMAP_SYSP (map1
))
1682 while (linemap_macro_expansion_map_p (map0
)
1683 && (resolved_loc
< RESERVED_LOCATION_COUNT
1684 || LINEMAP_SYSP (map1
)))
1686 loc
= linemap_unwind_toward_expansion (set
, loc
, &map0
);
1687 resolved_loc
= linemap_resolve_location (set
, loc
,
1688 LRK_SPELLING_LOCATION
,
1697 /* Expand source code location LOC and return a user readable source
1698 code location. LOC must be a spelling (non-virtual) location. If
1699 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1700 location is returned. */
1703 linemap_expand_location (struct line_maps
*set
,
1704 const struct line_map
*map
,
1705 source_location loc
)
1708 expanded_location xloc
;
1710 memset (&xloc
, 0, sizeof (xloc
));
1711 if (IS_ADHOC_LOC (loc
))
1714 = set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].data
;
1715 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1718 if (loc
< RESERVED_LOCATION_COUNT
)
1719 /* The location for this token wasn't generated from a line map.
1720 It was probably a location for a builtin token, chosen by some
1721 client code. Let's not try to expand the location in that
1723 else if (map
== NULL
)
1724 /* We shouldn't be getting a NULL map with a location that is not
1725 reserved by the client code. */
1729 /* MAP must be an ordinary map and LOC must be non-virtual,
1730 encoded into this map, obviously; the accessors used on MAP
1731 below ensure it is ordinary. Let's just assert the
1732 non-virtualness of LOC here. */
1733 if (linemap_location_from_macro_expansion_p (set
, loc
))
1736 const line_map_ordinary
*ord_map
= linemap_check_ordinary (map
);
1738 xloc
.file
= LINEMAP_FILE (ord_map
);
1739 xloc
.line
= SOURCE_LINE (ord_map
, loc
);
1740 xloc
.column
= SOURCE_COLUMN (ord_map
, loc
);
1741 xloc
.sysp
= LINEMAP_SYSP (ord_map
) != 0;
1748 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1749 is NULL, use stderr. IS_MACRO is true if the caller wants to
1750 dump a macro map, false otherwise. */
1753 linemap_dump (FILE *stream
, struct line_maps
*set
, unsigned ix
, bool is_macro
)
1755 const char *const lc_reasons_v
[LC_HWM
]
1756 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1758 const line_map
*map
;
1766 map
= LINEMAPS_ORDINARY_MAP_AT (set
, ix
);
1767 reason
= linemap_check_ordinary (map
)->reason
;
1771 map
= LINEMAPS_MACRO_MAP_AT (set
, ix
);
1772 reason
= LC_ENTER_MACRO
;
1775 fprintf (stream
, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1776 ix
, (void *) map
, map
->start_location
,
1777 reason
< LC_HWM
? lc_reasons_v
[reason
] : "???",
1779 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map
)))
1783 const line_map_ordinary
*ord_map
= linemap_check_ordinary (map
);
1784 unsigned includer_ix
;
1785 const line_map_ordinary
*includer_map
;
1787 includer_ix
= ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map
);
1788 includer_map
= includer_ix
< LINEMAPS_ORDINARY_USED (set
)
1789 ? LINEMAPS_ORDINARY_MAP_AT (set
, includer_ix
)
1792 fprintf (stream
, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map
),
1793 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map
));
1794 fprintf (stream
, "Included from: [%d] %s\n", includer_ix
,
1795 includer_map
? ORDINARY_MAP_FILE_NAME (includer_map
) : "None");
1799 const line_map_macro
*macro_map
= linemap_check_macro (map
);
1800 fprintf (stream
, "Macro: %s (%u tokens)\n",
1801 linemap_map_get_macro_name (macro_map
),
1802 MACRO_MAP_NUM_MACRO_TOKENS (macro_map
));
1805 fprintf (stream
, "\n");
1809 /* Dump debugging information about source location LOC into the file
1810 stream STREAM. SET is the line map set LOC comes from. */
1813 linemap_dump_location (struct line_maps
*set
,
1814 source_location loc
,
1817 const line_map_ordinary
*map
;
1818 source_location location
;
1819 const char *path
= "", *from
= "";
1820 int l
= -1, c
= -1, s
= -1, e
= -1;
1822 if (IS_ADHOC_LOC (loc
))
1823 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1829 linemap_resolve_location (set
, loc
, LRK_MACRO_DEFINITION_LOCATION
, &map
);
1832 /* Only reserved locations can be tolerated in this case. */
1833 linemap_assert (location
< RESERVED_LOCATION_COUNT
);
1836 path
= LINEMAP_FILE (map
);
1837 l
= SOURCE_LINE (map
, location
);
1838 c
= SOURCE_COLUMN (map
, location
);
1839 s
= LINEMAP_SYSP (map
) != 0;
1840 e
= location
!= loc
;
1844 from
= (INCLUDED_FROM (set
, map
))
1845 ? LINEMAP_FILE (INCLUDED_FROM (set
, map
))
1849 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1850 E: macro expansion?, LOC: original location, R: resolved location */
1851 fprintf (stream
, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1852 path
, from
, l
, c
, s
, (void*)map
, e
, loc
, location
);
1855 /* Return the highest location emitted for a given file for which
1856 there is a line map in SET. FILE_NAME is the file name to
1857 consider. If the function returns TRUE, *LOC is set to the highest
1858 location emitted for that file. */
1861 linemap_get_file_highest_location (struct line_maps
*set
,
1862 const char *file_name
,
1863 source_location
*loc
)
1865 /* If the set is empty or no ordinary map has been created then
1866 there is no file to look for ... */
1867 if (set
== NULL
|| set
->info_ordinary
.used
== 0)
1870 /* Now look for the last ordinary map created for FILE_NAME. */
1872 for (i
= set
->info_ordinary
.used
- 1; i
>= 0; --i
)
1874 const char *fname
= set
->info_ordinary
.maps
[i
].to_file
;
1875 if (fname
&& !filename_cmp (fname
, file_name
))
1882 /* The highest location for a given map is either the starting
1883 location of the next map minus one, or -- if the map is the
1884 latest one -- the highest location of the set. */
1885 source_location result
;
1886 if (i
== (int) set
->info_ordinary
.used
- 1)
1887 result
= set
->highest_location
;
1889 result
= set
->info_ordinary
.maps
[i
+ 1].start_location
- 1;
1895 /* Compute and return statistics about the memory consumption of some
1896 parts of the line table SET. */
1899 linemap_get_statistics (struct line_maps
*set
,
1900 struct linemap_stats
*s
)
1902 long ordinary_maps_allocated_size
, ordinary_maps_used_size
,
1903 macro_maps_allocated_size
, macro_maps_used_size
,
1904 macro_maps_locations_size
= 0, duplicated_macro_maps_locations_size
= 0;
1906 const line_map_macro
*cur_map
;
1908 ordinary_maps_allocated_size
=
1909 LINEMAPS_ORDINARY_ALLOCATED (set
) * sizeof (struct line_map_ordinary
);
1911 ordinary_maps_used_size
=
1912 LINEMAPS_ORDINARY_USED (set
) * sizeof (struct line_map_ordinary
);
1914 macro_maps_allocated_size
=
1915 LINEMAPS_MACRO_ALLOCATED (set
) * sizeof (struct line_map_macro
);
1917 for (cur_map
= LINEMAPS_MACRO_MAPS (set
);
1918 cur_map
&& cur_map
<= LINEMAPS_LAST_MACRO_MAP (set
);
1923 linemap_assert (linemap_macro_expansion_map_p (cur_map
));
1925 macro_maps_locations_size
+=
1926 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map
) * sizeof (source_location
);
1928 for (i
= 0; i
< 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map
); i
+= 2)
1930 if (MACRO_MAP_LOCATIONS (cur_map
)[i
] ==
1931 MACRO_MAP_LOCATIONS (cur_map
)[i
+ 1])
1932 duplicated_macro_maps_locations_size
+=
1933 sizeof (source_location
);
1937 macro_maps_used_size
=
1938 LINEMAPS_MACRO_USED (set
) * sizeof (struct line_map_macro
);
1940 s
->num_ordinary_maps_allocated
= LINEMAPS_ORDINARY_ALLOCATED (set
);
1941 s
->num_ordinary_maps_used
= LINEMAPS_ORDINARY_USED (set
);
1942 s
->ordinary_maps_allocated_size
= ordinary_maps_allocated_size
;
1943 s
->ordinary_maps_used_size
= ordinary_maps_used_size
;
1944 s
->num_expanded_macros
= num_expanded_macros_counter
;
1945 s
->num_macro_tokens
= num_macro_tokens_counter
;
1946 s
->num_macro_maps_used
= LINEMAPS_MACRO_USED (set
);
1947 s
->macro_maps_allocated_size
= macro_maps_allocated_size
;
1948 s
->macro_maps_locations_size
= macro_maps_locations_size
;
1949 s
->macro_maps_used_size
= macro_maps_used_size
;
1950 s
->duplicated_macro_maps_locations_size
=
1951 duplicated_macro_maps_locations_size
;
1952 s
->adhoc_table_size
= (set
->location_adhoc_data_map
.allocated
1953 * sizeof (struct location_adhoc_data
));
1954 s
->adhoc_table_entries_used
= set
->location_adhoc_data_map
.curr_loc
;
1958 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1959 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1960 specifies how many macro maps to dump. */
1963 line_table_dump (FILE *stream
, struct line_maps
*set
, unsigned int num_ordinary
,
1964 unsigned int num_macro
)
1974 fprintf (stream
, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set
));
1975 fprintf (stream
, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set
));
1976 fprintf (stream
, "Include stack depth: %d\n", set
->depth
);
1977 fprintf (stream
, "Highest location: %u\n", set
->highest_location
);
1981 fprintf (stream
, "\nOrdinary line maps\n");
1982 for (i
= 0; i
< num_ordinary
&& i
< LINEMAPS_ORDINARY_USED (set
); i
++)
1983 linemap_dump (stream
, set
, i
, false);
1984 fprintf (stream
, "\n");
1989 fprintf (stream
, "\nMacro line maps\n");
1990 for (i
= 0; i
< num_macro
&& i
< LINEMAPS_MACRO_USED (set
); i
++)
1991 linemap_dump (stream
, set
, i
, true);
1992 fprintf (stream
, "\n");
1996 /* class rich_location. */
1998 /* Construct a rich_location with location LOC as its initial range. */
2000 rich_location::rich_location (line_maps
*set
, source_location loc
) :
2003 m_column_override (0),
2004 m_have_expanded_location (false),
2006 m_seen_impossible_fixit (false),
2007 m_fixits_cannot_be_auto_applied (false)
2009 add_range (loc
, true);
2012 /* The destructor for class rich_location. */
2014 rich_location::~rich_location ()
2016 for (unsigned int i
= 0; i
< m_fixit_hints
.count (); i
++)
2017 delete get_fixit_hint (i
);
2020 /* Get location IDX within this rich_location. */
2023 rich_location::get_loc (unsigned int idx
) const
2025 const location_range
*locrange
= get_range (idx
);
2026 return locrange
->m_loc
;
2029 /* Get range IDX within this rich_location. */
2031 const location_range
*
2032 rich_location::get_range (unsigned int idx
) const
2034 return &m_ranges
[idx
];
2037 /* Mutable access to range IDX within this rich_location. */
2040 rich_location::get_range (unsigned int idx
)
2042 return &m_ranges
[idx
];
2045 /* Expand location IDX within this rich_location. */
2046 /* Get an expanded_location for this rich_location's primary
2050 rich_location::get_expanded_location (unsigned int idx
)
2054 /* Cache the expansion of the primary location. */
2055 if (!m_have_expanded_location
)
2058 = linemap_client_expand_location_to_spelling_point
2059 (get_loc (0), LOCATION_ASPECT_CARET
);
2060 if (m_column_override
)
2061 m_expanded_location
.column
= m_column_override
;
2062 m_have_expanded_location
= true;
2065 return m_expanded_location
;
2068 return linemap_client_expand_location_to_spelling_point
2069 (get_loc (idx
), LOCATION_ASPECT_CARET
);
2072 /* Set the column of the primary location, with 0 meaning
2073 "don't override it". */
2076 rich_location::override_column (int column
)
2078 m_column_override
= column
;
2079 m_have_expanded_location
= false;
2082 /* Add the given range. */
2085 rich_location::add_range (source_location loc
, bool show_caret_p
)
2087 location_range range
;
2089 range
.m_show_caret_p
= show_caret_p
;
2090 m_ranges
.push (range
);
2093 /* Add or overwrite the location given by IDX, setting its location to LOC,
2094 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2096 It must either overwrite an existing location, or add one *exactly* on
2097 the end of the array.
2099 This is primarily for use by gcc when implementing diagnostic format
2101 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2102 (which writes the source location of a tree back into location 0 of
2103 the rich_location), and
2104 - the "%C" and "%L" format codes in the Fortran frontend. */
2107 rich_location::set_range (unsigned int idx
, source_location loc
,
2110 /* We can either overwrite an existing range, or add one exactly
2111 on the end of the array. */
2112 linemap_assert (idx
<= m_ranges
.count ());
2114 if (idx
== m_ranges
.count ())
2115 add_range (loc
, show_caret_p
);
2118 location_range
*locrange
= get_range (idx
);
2119 locrange
->m_loc
= loc
;
2120 locrange
->m_show_caret_p
= show_caret_p
;
2124 /* Mark any cached value here as dirty. */
2125 m_have_expanded_location
= false;
2128 /* Methods for adding insertion fix-it hints. */
2130 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2131 immediately before the primary range's start location. */
2134 rich_location::add_fixit_insert_before (const char *new_content
)
2136 add_fixit_insert_before (get_loc (), new_content
);
2139 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2140 immediately before the start of WHERE. */
2143 rich_location::add_fixit_insert_before (source_location where
,
2144 const char *new_content
)
2146 source_location start
= get_range_from_loc (m_line_table
, where
).m_start
;
2147 maybe_add_fixit (start
, start
, new_content
);
2150 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2151 immediately after the primary range's end-point. */
2154 rich_location::add_fixit_insert_after (const char *new_content
)
2156 add_fixit_insert_after (get_loc (), new_content
);
2159 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2160 immediately after the end-point of WHERE. */
2163 rich_location::add_fixit_insert_after (source_location where
,
2164 const char *new_content
)
2166 source_location finish
= get_range_from_loc (m_line_table
, where
).m_finish
;
2167 source_location next_loc
2168 = linemap_position_for_loc_and_offset (m_line_table
, finish
, 1);
2170 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2172 if (next_loc
== finish
)
2174 stop_supporting_fixits ();
2178 maybe_add_fixit (next_loc
, next_loc
, new_content
);
2181 /* Methods for adding removal fix-it hints. */
2183 /* Add a fixit-hint, suggesting removal of the content covered
2187 rich_location::add_fixit_remove ()
2189 add_fixit_remove (get_loc ());
2192 /* Add a fixit-hint, suggesting removal of the content between
2193 the start and finish of WHERE. */
2196 rich_location::add_fixit_remove (source_location where
)
2198 source_range range
= get_range_from_loc (m_line_table
, where
);
2199 add_fixit_remove (range
);
2202 /* Add a fixit-hint, suggesting removal of the content at
2206 rich_location::add_fixit_remove (source_range src_range
)
2208 add_fixit_replace (src_range
, "");
2211 /* Add a fixit-hint, suggesting replacement of the content covered
2212 by range 0 with NEW_CONTENT. */
2215 rich_location::add_fixit_replace (const char *new_content
)
2217 add_fixit_replace (get_loc (), new_content
);
2220 /* Methods for adding "replace" fix-it hints. */
2222 /* Add a fixit-hint, suggesting replacement of the content between
2223 the start and finish of WHERE with NEW_CONTENT. */
2226 rich_location::add_fixit_replace (source_location where
,
2227 const char *new_content
)
2229 source_range range
= get_range_from_loc (m_line_table
, where
);
2230 add_fixit_replace (range
, new_content
);
2233 /* Add a fixit-hint, suggesting replacement of the content at
2234 SRC_RANGE with NEW_CONTENT. */
2237 rich_location::add_fixit_replace (source_range src_range
,
2238 const char *new_content
)
2240 source_location start
= get_pure_location (m_line_table
, src_range
.m_start
);
2241 source_location finish
= get_pure_location (m_line_table
, src_range
.m_finish
);
2243 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2244 source_location next_loc
2245 = linemap_position_for_loc_and_offset (m_line_table
, finish
, 1);
2246 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2248 if (next_loc
== finish
)
2250 stop_supporting_fixits ();
2255 maybe_add_fixit (start
, finish
, new_content
);
2258 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2261 rich_location::get_last_fixit_hint () const
2263 if (m_fixit_hints
.count () > 0)
2264 return get_fixit_hint (m_fixit_hints
.count () - 1);
2269 /* If WHERE is an "awkward" location, then mark this rich_location as not
2270 supporting fixits, purging any thay were already added, and return true.
2272 Otherwise (the common case), return false. */
2275 rich_location::reject_impossible_fixit (source_location where
)
2277 /* Fix-its within a rich_location should either all be suggested, or
2278 none of them should be suggested.
2279 Once we've rejected a fixit, we reject any more, even those
2280 with reasonable locations. */
2281 if (m_seen_impossible_fixit
)
2284 if (where
<= LINE_MAP_MAX_LOCATION_WITH_COLS
)
2285 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2288 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2289 location: either one that we can't obtain column information
2290 for (within an ordinary map), or one within a macro expansion. */
2291 stop_supporting_fixits ();
2295 /* Mark this rich_location as not supporting fixits, purging any that were
2299 rich_location::stop_supporting_fixits ()
2301 m_seen_impossible_fixit
= true;
2303 /* Purge the rich_location of any fix-its that were already added. */
2304 for (unsigned int i
= 0; i
< m_fixit_hints
.count (); i
++)
2305 delete get_fixit_hint (i
);
2306 m_fixit_hints
.truncate (0);
2309 /* Add HINT to the fix-it hints in this rich_location,
2310 consolidating into the prior fixit if possible. */
2313 rich_location::maybe_add_fixit (source_location start
,
2314 source_location next_loc
,
2315 const char *new_content
)
2317 if (reject_impossible_fixit (start
))
2319 if (reject_impossible_fixit (next_loc
))
2322 /* Only allow fix-it hints that affect a single line in one file.
2323 Compare the end-points. */
2324 expanded_location exploc_start
2325 = linemap_client_expand_location_to_spelling_point (start
,
2326 LOCATION_ASPECT_START
);
2327 expanded_location exploc_next_loc
2328 = linemap_client_expand_location_to_spelling_point (next_loc
,
2329 LOCATION_ASPECT_START
);
2330 /* They must be within the same file... */
2331 if (exploc_start
.file
!= exploc_next_loc
.file
)
2333 stop_supporting_fixits ();
2336 /* ...and on the same line. */
2337 if (exploc_start
.line
!= exploc_next_loc
.line
)
2339 stop_supporting_fixits ();
2342 /* The columns must be in the correct order. This can fail if the
2343 endpoints straddle the boundary for which the linemap can represent
2344 columns (PR c/82050). */
2345 if (exploc_start
.column
> exploc_next_loc
.column
)
2347 stop_supporting_fixits ();
2351 const char *newline
= strchr (new_content
, '\n');
2354 /* For now, we can only support insertion of whole lines
2355 i.e. starts at start of line, and the newline is at the end of
2356 the insertion point. */
2358 /* It must be an insertion, not a replacement/deletion. */
2359 if (start
!= next_loc
)
2361 stop_supporting_fixits ();
2365 /* The insertion must be at the start of a line. */
2366 if (exploc_start
.column
!= 1)
2368 stop_supporting_fixits ();
2372 /* The newline must be at end of NEW_CONTENT.
2373 We could eventually split up fix-its at newlines if we wanted
2374 to allow more generality (e.g. to allow adding multiple lines
2375 with one add_fixit call. */
2376 if (newline
[1] != '\0')
2378 stop_supporting_fixits ();
2383 /* Consolidate neighboring fixits.
2384 Don't consolidate into newline-insertion fixits. */
2385 fixit_hint
*prev
= get_last_fixit_hint ();
2386 if (prev
&& !prev
->ends_with_newline_p ())
2387 if (prev
->maybe_append (start
, next_loc
, new_content
))
2390 m_fixit_hints
.push (new fixit_hint (start
, next_loc
, new_content
));
2393 /* class fixit_hint. */
2395 fixit_hint::fixit_hint (source_location start
,
2396 source_location next_loc
,
2397 const char *new_content
)
2399 m_next_loc (next_loc
),
2400 m_bytes (xstrdup (new_content
)),
2401 m_len (strlen (new_content
))
2405 /* Does this fix-it hint affect the given line? */
2408 fixit_hint::affects_line_p (const char *file
, int line
) const
2410 expanded_location exploc_start
2411 = linemap_client_expand_location_to_spelling_point (m_start
,
2412 LOCATION_ASPECT_START
);
2413 if (file
!= exploc_start
.file
)
2415 if (line
< exploc_start
.line
)
2417 expanded_location exploc_next_loc
2418 = linemap_client_expand_location_to_spelling_point (m_next_loc
,
2419 LOCATION_ASPECT_START
);
2420 if (file
!= exploc_next_loc
.file
)
2422 if (line
> exploc_next_loc
.line
)
2427 /* Method for consolidating fix-it hints, for use by
2428 rich_location::maybe_add_fixit.
2429 If possible, merge a pending fix-it hint with the given params
2430 into this one and return true.
2431 Otherwise return false. */
2434 fixit_hint::maybe_append (source_location start
,
2435 source_location next_loc
,
2436 const char *new_content
)
2438 /* For consolidation to be possible, START must be at this hint's
2440 if (start
!= m_next_loc
)
2443 /* If so, we have neighboring replacements; merge them. */
2444 m_next_loc
= next_loc
;
2445 size_t extra_len
= strlen (new_content
);
2446 m_bytes
= (char *)xrealloc (m_bytes
, m_len
+ extra_len
+ 1);
2447 memcpy (m_bytes
+ m_len
, new_content
, extra_len
);
2449 m_bytes
[m_len
] = '\0';
2453 /* Return true iff this hint's content ends with a newline. */
2456 fixit_hint::ends_with_newline_p () const
2460 return m_bytes
[m_len
- 1] == '\n';