1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2017 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3, or (at your option) any
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 /* 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
32 const unsigned int LINE_MAP_MAX_COLUMN_NUMBER
= (1U << 12);
34 /* Highest possible source location encoded within an ordinary or
36 const source_location LINE_MAP_MAX_SOURCE_LOCATION
= 0x70000000;
38 static void trace_include (const struct line_maps
*, const line_map_ordinary
*);
39 static const line_map_ordinary
* linemap_ordinary_map_lookup (struct line_maps
*,
41 static const line_map_macro
* linemap_macro_map_lookup (struct line_maps
*,
43 static source_location linemap_macro_map_loc_to_def_point
44 (const line_map_macro
*, source_location
);
45 static source_location linemap_macro_map_loc_to_exp_point
46 (const line_map_macro
*, source_location
);
47 static source_location linemap_macro_loc_to_spelling_point
48 (struct line_maps
*, source_location
, const line_map_ordinary
**);
49 static source_location
linemap_macro_loc_to_def_point (struct line_maps
*,
51 const line_map_ordinary
**);
52 static source_location
linemap_macro_loc_to_exp_point (struct line_maps
*,
54 const line_map_ordinary
**);
56 /* Counters defined in macro.c. */
57 extern unsigned num_expanded_macros_counter
;
58 extern unsigned num_macro_tokens_counter
;
60 /* Destructor for class line_maps.
61 Ensure non-GC-managed memory is released. */
63 line_maps::~line_maps ()
65 if (location_adhoc_data_map
.htab
)
66 htab_delete (location_adhoc_data_map
.htab
);
69 /* Hash function for location_adhoc_data hashtable. */
72 location_adhoc_data_hash (const void *l
)
74 const struct location_adhoc_data
*lb
=
75 (const struct location_adhoc_data
*) l
;
76 return ((hashval_t
) lb
->locus
77 + (hashval_t
) lb
->src_range
.m_start
78 + (hashval_t
) lb
->src_range
.m_finish
82 /* Compare function for location_adhoc_data hashtable. */
85 location_adhoc_data_eq (const void *l1
, const void *l2
)
87 const struct location_adhoc_data
*lb1
=
88 (const struct location_adhoc_data
*) l1
;
89 const struct location_adhoc_data
*lb2
=
90 (const struct location_adhoc_data
*) l2
;
91 return (lb1
->locus
== lb2
->locus
92 && lb1
->src_range
.m_start
== lb2
->src_range
.m_start
93 && lb1
->src_range
.m_finish
== lb2
->src_range
.m_finish
94 && lb1
->data
== lb2
->data
);
97 /* Update the hashtable when location_adhoc_data is reallocated. */
100 location_adhoc_data_update (void **slot
, void *data
)
103 = (char *) ((uintptr_t) *((char **) slot
) + *((ptrdiff_t *) data
));
107 /* Rebuild the hash table from the location adhoc data. */
110 rebuild_location_adhoc_htab (struct line_maps
*set
)
113 set
->location_adhoc_data_map
.htab
=
114 htab_create (100, location_adhoc_data_hash
, location_adhoc_data_eq
, NULL
);
115 for (i
= 0; i
< set
->location_adhoc_data_map
.curr_loc
; i
++)
116 htab_find_slot (set
->location_adhoc_data_map
.htab
,
117 set
->location_adhoc_data_map
.data
+ i
, INSERT
);
120 /* Helper function for get_combined_adhoc_loc.
121 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
122 within a source_location, without needing to use an ad-hoc location. */
125 can_be_stored_compactly_p (struct line_maps
*set
,
126 source_location locus
,
127 source_range src_range
,
130 /* If there's an ad-hoc pointer, we can't store it directly in the
131 source_location, we need the lookaside. */
135 /* We only store ranges that begin at the locus and that are sufficiently
137 if (src_range
.m_start
!= locus
)
140 if (src_range
.m_finish
< src_range
.m_start
)
143 if (src_range
.m_start
< RESERVED_LOCATION_COUNT
)
146 if (locus
>= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
)
149 /* All 3 locations must be within ordinary maps, typically, the same
151 source_location lowest_macro_loc
= LINEMAPS_MACRO_LOWEST_LOCATION (set
);
152 if (locus
>= lowest_macro_loc
)
154 if (src_range
.m_start
>= lowest_macro_loc
)
156 if (src_range
.m_finish
>= lowest_macro_loc
)
159 /* Passed all tests. */
163 /* Combine LOCUS and DATA to a combined adhoc loc. */
166 get_combined_adhoc_loc (struct line_maps
*set
,
167 source_location locus
,
168 source_range src_range
,
171 struct location_adhoc_data lb
;
172 struct location_adhoc_data
**slot
;
174 if (IS_ADHOC_LOC (locus
))
176 = set
->location_adhoc_data_map
.data
[locus
& MAX_SOURCE_LOCATION
].locus
;
177 if (locus
== 0 && data
== NULL
)
180 /* Any ordinary locations ought to be "pure" at this point: no
181 compressed ranges. */
182 linemap_assert (locus
< RESERVED_LOCATION_COUNT
183 || locus
>= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
184 || locus
>= LINEMAPS_MACRO_LOWEST_LOCATION (set
)
185 || pure_location_p (set
, locus
));
187 /* Consider short-range optimization. */
188 if (can_be_stored_compactly_p (set
, locus
, src_range
, data
))
190 /* The low bits ought to be clear. */
191 linemap_assert (pure_location_p (set
, locus
));
192 const line_map
*map
= linemap_lookup (set
, locus
);
193 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
194 unsigned int int_diff
= src_range
.m_finish
- src_range
.m_start
;
195 unsigned int col_diff
= (int_diff
>> ordmap
->m_range_bits
);
196 if (col_diff
< (1U << ordmap
->m_range_bits
))
198 source_location packed
= locus
| col_diff
;
199 set
->num_optimized_ranges
++;
204 /* We can also compactly store locations
205 when locus == start == finish (and data is NULL). */
206 if (locus
== src_range
.m_start
207 && locus
== src_range
.m_finish
212 set
->num_unoptimized_ranges
++;
215 lb
.src_range
= src_range
;
217 slot
= (struct location_adhoc_data
**)
218 htab_find_slot (set
->location_adhoc_data_map
.htab
, &lb
, INSERT
);
221 if (set
->location_adhoc_data_map
.curr_loc
>=
222 set
->location_adhoc_data_map
.allocated
)
224 char *orig_data
= (char *) set
->location_adhoc_data_map
.data
;
226 /* Cast away extern "C" from the type of xrealloc. */
227 line_map_realloc reallocator
= (set
->reallocator
229 : (line_map_realloc
) xrealloc
);
231 if (set
->location_adhoc_data_map
.allocated
== 0)
232 set
->location_adhoc_data_map
.allocated
= 128;
234 set
->location_adhoc_data_map
.allocated
*= 2;
235 set
->location_adhoc_data_map
.data
= (struct location_adhoc_data
*)
236 reallocator (set
->location_adhoc_data_map
.data
,
237 set
->location_adhoc_data_map
.allocated
238 * sizeof (struct location_adhoc_data
));
239 offset
= (char *) (set
->location_adhoc_data_map
.data
) - orig_data
;
240 if (set
->location_adhoc_data_map
.allocated
> 128)
241 htab_traverse (set
->location_adhoc_data_map
.htab
,
242 location_adhoc_data_update
, &offset
);
244 *slot
= set
->location_adhoc_data_map
.data
245 + set
->location_adhoc_data_map
.curr_loc
;
246 set
->location_adhoc_data_map
.data
[set
->location_adhoc_data_map
.curr_loc
++]
249 return ((*slot
) - set
->location_adhoc_data_map
.data
) | 0x80000000;
252 /* Return the data for the adhoc loc. */
255 get_data_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
].data
;
261 /* Return the location for the adhoc loc. */
264 get_location_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
].locus
;
270 /* Return the source_range for adhoc location LOC. */
273 get_range_from_adhoc_loc (struct line_maps
*set
, source_location loc
)
275 linemap_assert (IS_ADHOC_LOC (loc
));
276 return set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].src_range
;
279 /* Get the source_range of location LOC, either from the ad-hoc
280 lookaside table, or embedded inside LOC itself. */
283 get_range_from_loc (struct line_maps
*set
,
286 if (IS_ADHOC_LOC (loc
))
287 return get_range_from_adhoc_loc (set
, loc
);
289 /* For ordinary maps, extract packed range. */
290 if (loc
>= RESERVED_LOCATION_COUNT
291 && loc
< LINEMAPS_MACRO_LOWEST_LOCATION (set
)
292 && loc
<= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
)
294 const line_map
*map
= linemap_lookup (set
, loc
);
295 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
297 int offset
= loc
& ((1 << ordmap
->m_range_bits
) - 1);
298 result
.m_start
= loc
- offset
;
299 result
.m_finish
= result
.m_start
+ (offset
<< ordmap
->m_range_bits
);
303 return source_range::from_location (loc
);
306 /* Get whether location LOC is a "pure" location, or
307 whether it is an ad-hoc location, or embeds range information. */
310 pure_location_p (line_maps
*set
, source_location loc
)
312 if (IS_ADHOC_LOC (loc
))
315 const line_map
*map
= linemap_lookup (set
, loc
);
316 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
318 if (loc
& ((1U << ordmap
->m_range_bits
) - 1))
324 /* Given location LOC within SET, strip away any packed range information
325 or ad-hoc information. */
328 get_pure_location (line_maps
*set
, source_location loc
)
330 if (IS_ADHOC_LOC (loc
))
332 = set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
334 if (loc
>= LINEMAPS_MACRO_LOWEST_LOCATION (set
))
337 if (loc
< RESERVED_LOCATION_COUNT
)
340 const line_map
*map
= linemap_lookup (set
, loc
);
341 const line_map_ordinary
*ordmap
= linemap_check_ordinary (map
);
343 return loc
& ~((1 << ordmap
->m_range_bits
) - 1);
346 /* Initialize a line map set. */
349 linemap_init (struct line_maps
*set
,
350 source_location builtin_location
)
353 set
->highest_location
= RESERVED_LOCATION_COUNT
- 1;
354 set
->highest_line
= RESERVED_LOCATION_COUNT
- 1;
355 set
->location_adhoc_data_map
.htab
=
356 htab_create (100, location_adhoc_data_hash
, location_adhoc_data_eq
, NULL
);
357 set
->builtin_location
= builtin_location
;
360 /* Check for and warn about line_maps entered but not exited. */
363 linemap_check_files_exited (struct line_maps
*set
)
365 const line_map_ordinary
*map
;
366 /* Depending upon whether we are handling preprocessed input or
367 not, this can be a user error or an ICE. */
368 for (map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
370 map
= INCLUDED_FROM (set
, map
))
371 fprintf (stderr
, "line-map.c: file \"%s\" entered but not left\n",
372 ORDINARY_MAP_FILE_NAME (map
));
375 /* Create a new line map in the line map set SET, and return it.
376 REASON is the reason of creating the map. It determines the type
377 of map created (ordinary or macro map). Note that ordinary maps and
378 macro maps are allocated in different memory location. */
380 static struct line_map
*
381 new_linemap (struct line_maps
*set
,
382 enum lc_reason reason
)
384 /* Depending on this variable, a macro map would be allocated in a
385 different memory location than an ordinary map. */
386 bool macro_map_p
= (reason
== LC_ENTER_MACRO
);
387 struct line_map
*result
;
389 if (LINEMAPS_USED (set
, macro_map_p
) == LINEMAPS_ALLOCATED (set
, macro_map_p
))
391 /* We ran out of allocated line maps. Let's allocate more. */
394 /* Cast away extern "C" from the type of xrealloc. */
395 line_map_realloc reallocator
= (set
->reallocator
397 : (line_map_realloc
) xrealloc
);
398 line_map_round_alloc_size_func round_alloc_size
=
399 set
->round_alloc_size
;
401 size_t map_size
= (macro_map_p
402 ? sizeof (line_map_macro
)
403 : sizeof (line_map_ordinary
));
405 /* We are going to execute some dance to try to reduce the
406 overhead of the memory allocator, in case we are using the
409 The actual size of memory we are going to get back from the
410 allocator is the smallest power of 2 that is greater than the
411 size we requested. So let's consider that size then. */
414 (2 * LINEMAPS_ALLOCATED (set
, macro_map_p
) + 256)
417 /* Get the actual size of memory that is going to be allocated
419 alloc_size
= round_alloc_size (alloc_size
);
421 /* Now alloc_size contains the exact memory size we would get if
422 we have asked for the initial alloc_size amount of memory.
423 Let's get back to the number of macro map that amounts
425 LINEMAPS_ALLOCATED (set
, macro_map_p
) =
426 alloc_size
/ map_size
;
428 /* And now let's really do the re-allocation. */
432 = (line_map_macro
*) (*reallocator
) (set
->info_macro
.maps
,
433 (LINEMAPS_ALLOCATED (set
, macro_map_p
)
435 result
= &set
->info_macro
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
439 set
->info_ordinary
.maps
=
440 (line_map_ordinary
*) (*reallocator
) (set
->info_ordinary
.maps
,
441 (LINEMAPS_ALLOCATED (set
, macro_map_p
)
443 result
= &set
->info_ordinary
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
446 ((LINEMAPS_ALLOCATED (set
, macro_map_p
)
447 - LINEMAPS_USED (set
, macro_map_p
))
453 result
= &set
->info_macro
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
455 result
= &set
->info_ordinary
.maps
[LINEMAPS_USED (set
, macro_map_p
)];
458 LINEMAPS_USED (set
, macro_map_p
)++;
460 result
->reason
= reason
;
464 /* Add a mapping of logical source line to physical source file and
467 The text pointed to by TO_FILE must have a lifetime
468 at least as long as the final call to lookup_line (). An empty
469 TO_FILE means standard input. If reason is LC_LEAVE, and
470 TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
471 natural values considering the file we are returning to.
473 FROM_LINE should be monotonic increasing across calls to this
474 function. A call to this function can relocate the previous set of
475 maps, so any stored line_map pointers should not be used. */
477 const struct line_map
*
478 linemap_add (struct line_maps
*set
, enum lc_reason reason
,
479 unsigned int sysp
, const char *to_file
, linenum_type to_line
)
481 /* Generate a start_location above the current highest_location.
482 If possible, make the low range bits be zero. */
483 source_location start_location
;
484 if (set
->highest_location
< LINE_MAP_MAX_LOCATION_WITH_COLS
)
486 start_location
= set
->highest_location
+ (1 << set
->default_range_bits
);
487 if (set
->default_range_bits
)
488 start_location
&= ~((1 << set
->default_range_bits
) - 1);
489 linemap_assert (0 == (start_location
490 & ((1 << set
->default_range_bits
) - 1)));
493 start_location
= set
->highest_location
+ 1;
495 linemap_assert (!(LINEMAPS_ORDINARY_USED (set
)
497 < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set
)))));
499 /* When we enter the file for the first time reason cannot be
501 linemap_assert (!(set
->depth
== 0 && reason
== LC_RENAME
));
503 /* If we are leaving the main file, return a NULL map. */
504 if (reason
== LC_LEAVE
505 && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set
))
512 linemap_assert (reason
!= LC_ENTER_MACRO
);
513 line_map_ordinary
*map
= linemap_check_ordinary (new_linemap (set
, reason
));
515 if (to_file
&& *to_file
== '\0' && reason
!= LC_RENAME_VERBATIM
)
518 if (reason
== LC_RENAME_VERBATIM
)
521 if (reason
== LC_LEAVE
)
523 /* When we are just leaving an "included" file, and jump to the next
524 location inside the "includer" right after the #include
525 "included", this variable points the map in use right before the
526 #include "included", inside the same "includer" file. */
527 line_map_ordinary
*from
;
529 linemap_assert (!MAIN_FILE_P (map
- 1));
530 /* (MAP - 1) points to the map we are leaving. The
531 map from which (MAP - 1) got included should be the map
532 that comes right before MAP in the same file. */
533 from
= INCLUDED_FROM (set
, map
- 1);
535 /* A TO_FILE of NULL is special - we use the natural values. */
538 to_file
= ORDINARY_MAP_FILE_NAME (from
);
539 to_line
= SOURCE_LINE (from
, from
[1].start_location
);
540 sysp
= ORDINARY_MAP_IN_SYSTEM_HEADER_P (from
);
543 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from
),
548 map
->start_location
= start_location
;
549 map
->to_file
= to_file
;
550 map
->to_line
= to_line
;
551 LINEMAPS_ORDINARY_CACHE (set
) = LINEMAPS_ORDINARY_USED (set
) - 1;
552 map
->m_column_and_range_bits
= 0;
553 map
->m_range_bits
= 0;
554 set
->highest_location
= start_location
;
555 set
->highest_line
= start_location
;
556 set
->max_column_hint
= 0;
558 /* This assertion is placed after set->highest_location has
559 been updated, since the latter affects
560 linemap_location_from_macro_expansion_p, which ultimately affects
562 linemap_assert (pure_location_p (set
, start_location
));
564 if (reason
== LC_ENTER
)
567 set
->depth
== 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set
) - 2);
569 if (set
->trace_includes
)
570 trace_include (set
, map
);
572 else if (reason
== LC_RENAME
)
573 map
->included_from
= ORDINARY_MAP_INCLUDER_FILE_INDEX (&map
[-1]);
574 else if (reason
== LC_LEAVE
)
578 ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set
, map
- 1));
584 /* Returns TRUE if the line table set tracks token locations across
585 macro expansion, FALSE otherwise. */
588 linemap_tracks_macro_expansion_locs_p (struct line_maps
*set
)
590 return LINEMAPS_MACRO_MAPS (set
) != NULL
;
593 /* Create a macro map. A macro map encodes source locations of tokens
594 that are part of a macro replacement-list, at a macro expansion
595 point. See the extensive comments of struct line_map and struct
596 line_map_macro, in line-map.h.
598 This map shall be created when the macro is expanded. The map
599 encodes the source location of the expansion point of the macro as
600 well as the "original" source location of each token that is part
601 of the macro replacement-list. If a macro is defined but never
602 expanded, it has no macro map. SET is the set of maps the macro
603 map should be part of. MACRO_NODE is the macro which the new macro
604 map should encode source locations for. EXPANSION is the location
605 of the expansion point of MACRO. For function-like macros
606 invocations, it's best to make it point to the closing parenthesis
607 of the macro, rather than the the location of the first character
608 of the macro. NUM_TOKENS is the number of tokens that are part of
609 the replacement-list of MACRO.
611 Note that when we run out of the integer space available for source
612 locations, this function returns NULL. In that case, callers of
613 this function cannot encode {line,column} pairs into locations of
614 macro tokens anymore. */
616 const line_map_macro
*
617 linemap_enter_macro (struct line_maps
*set
, struct cpp_hashnode
*macro_node
,
618 source_location expansion
, unsigned int num_tokens
)
621 source_location start_location
;
622 /* Cast away extern "C" from the type of xrealloc. */
623 line_map_realloc reallocator
= (set
->reallocator
625 : (line_map_realloc
) xrealloc
);
627 start_location
= LINEMAPS_MACRO_LOWEST_LOCATION (set
) - num_tokens
;
629 if (start_location
<= set
->highest_line
630 || start_location
> LINEMAPS_MACRO_LOWEST_LOCATION (set
))
631 /* We ran out of macro map space. */
634 map
= linemap_check_macro (new_linemap (set
, LC_ENTER_MACRO
));
636 map
->start_location
= start_location
;
637 map
->macro
= macro_node
;
638 map
->n_tokens
= num_tokens
;
640 = (source_location
*) reallocator (NULL
,
642 * sizeof (source_location
));
643 map
->expansion
= expansion
;
644 memset (MACRO_MAP_LOCATIONS (map
), 0,
645 num_tokens
* sizeof (source_location
));
647 LINEMAPS_MACRO_CACHE (set
) = LINEMAPS_MACRO_USED (set
) - 1;
652 /* Create and return a virtual location for a token that is part of a
653 macro expansion-list at a macro expansion point. See the comment
654 inside struct line_map_macro to see what an expansion-list exactly
657 A call to this function must come after a call to
660 MAP is the map into which the source location is created. TOKEN_NO
661 is the index of the token in the macro replacement-list, starting
664 ORIG_LOC is the location of the token outside of this macro
665 expansion. If the token comes originally from the macro
666 definition, it is the locus in the macro definition; otherwise it
667 is a location in the context of the caller of this macro expansion
668 (which is a virtual location or a source location if the caller is
669 itself a macro expansion or not).
671 ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
672 either of the token itself or of a macro parameter that it
676 linemap_add_macro_token (const line_map_macro
*map
,
677 unsigned int token_no
,
678 source_location orig_loc
,
679 source_location orig_parm_replacement_loc
)
681 source_location result
;
683 linemap_assert (linemap_macro_expansion_map_p (map
));
684 linemap_assert (token_no
< MACRO_MAP_NUM_MACRO_TOKENS (map
));
686 MACRO_MAP_LOCATIONS (map
)[2 * token_no
] = orig_loc
;
687 MACRO_MAP_LOCATIONS (map
)[2 * token_no
+ 1] = orig_parm_replacement_loc
;
689 result
= MAP_START_LOCATION (map
) + token_no
;
693 /* Return a source_location for the start (i.e. column==0) of
694 (physical) line TO_LINE in the current source file (as in the
695 most recent linemap_add). MAX_COLUMN_HINT is the highest column
696 number we expect to use in this line (but it does not change
697 the highest_location). */
700 linemap_line_start (struct line_maps
*set
, linenum_type to_line
,
701 unsigned int max_column_hint
)
703 line_map_ordinary
*map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
704 source_location highest
= set
->highest_location
;
706 linenum_type last_line
=
707 SOURCE_LINE (map
, set
->highest_line
);
708 int line_delta
= to_line
- last_line
;
709 bool add_map
= false;
710 linemap_assert (map
->m_column_and_range_bits
>= map
->m_range_bits
);
711 int effective_column_bits
= map
->m_column_and_range_bits
- map
->m_range_bits
;
715 && line_delta
* map
->m_column_and_range_bits
> 1000)
716 || (max_column_hint
>= (1U << effective_column_bits
))
717 || (max_column_hint
<= 80 && effective_column_bits
>= 10)
718 || (highest
> LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
719 && map
->m_range_bits
> 0)
720 || (highest
> LINE_MAP_MAX_LOCATION_WITH_COLS
721 && (set
->max_column_hint
|| highest
>= LINE_MAP_MAX_SOURCE_LOCATION
)))
724 max_column_hint
= set
->max_column_hint
;
729 if (max_column_hint
> LINE_MAP_MAX_COLUMN_NUMBER
730 || highest
> LINE_MAP_MAX_LOCATION_WITH_COLS
)
732 /* If the column number is ridiculous or we've allocated a huge
733 number of source_locations, give up on column numbers
734 (and on packed ranges). */
738 if (highest
> LINE_MAP_MAX_SOURCE_LOCATION
)
744 if (highest
<= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
)
745 range_bits
= set
->default_range_bits
;
748 while (max_column_hint
>= (1U << column_bits
))
750 max_column_hint
= 1U << column_bits
;
751 column_bits
+= range_bits
;
753 /* Allocate the new line_map. However, if the current map only has a
754 single line we can sometimes just increase its column_bits instead. */
756 || last_line
!= ORDINARY_MAP_STARTING_LINE_NUMBER (map
)
757 || SOURCE_COLUMN (map
, highest
) >= (1U << (column_bits
- range_bits
))
758 || range_bits
< map
->m_range_bits
)
759 map
= linemap_check_ordinary
760 (const_cast <line_map
*>
761 (linemap_add (set
, LC_RENAME
,
762 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map
),
763 ORDINARY_MAP_FILE_NAME (map
),
765 map
->m_column_and_range_bits
= column_bits
;
766 map
->m_range_bits
= range_bits
;
767 r
= (MAP_START_LOCATION (map
)
768 + ((to_line
- ORDINARY_MAP_STARTING_LINE_NUMBER (map
))
772 r
= set
->highest_line
+ (line_delta
<< map
->m_column_and_range_bits
);
774 /* Locations of ordinary tokens are always lower than locations of
776 if (r
>= LINEMAPS_MACRO_LOWEST_LOCATION (set
))
779 set
->highest_line
= r
;
780 if (r
> set
->highest_location
)
781 set
->highest_location
= r
;
782 set
->max_column_hint
= max_column_hint
;
784 /* At this point, we expect one of:
785 (a) the normal case: a "pure" location with 0 range bits, or
786 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
787 columns anymore (or ranges), or
788 (c) we're in a region with a column hint exceeding
789 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
790 with column_bits == 0. */
791 linemap_assert (pure_location_p (set
, r
)
792 || r
>= LINE_MAP_MAX_LOCATION_WITH_COLS
793 || map
->m_column_and_range_bits
== 0);
794 linemap_assert (SOURCE_LINE (map
, r
) == to_line
);
798 /* Encode and return a source_location from a column number. The
799 source line considered is the last source line used to call
800 linemap_line_start, i.e, the last source line which a location was
804 linemap_position_for_column (struct line_maps
*set
, unsigned int to_column
)
806 source_location r
= set
->highest_line
;
809 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set
)));
811 if (to_column
>= set
->max_column_hint
)
813 if (r
> LINE_MAP_MAX_LOCATION_WITH_COLS
814 || to_column
> LINE_MAP_MAX_COLUMN_NUMBER
)
816 /* Running low on source_locations - disable column numbers. */
821 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
822 with some space to spare. This may or may not lead to a new
823 linemap being created. */
824 line_map_ordinary
*map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
825 r
= linemap_line_start (set
, SOURCE_LINE (map
, r
), to_column
+ 50);
826 map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
827 if (map
->m_column_and_range_bits
== 0)
829 /* ...then the linemap has column-tracking disabled,
830 presumably due to exceeding either
831 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
832 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
833 Return the start of the linemap, which encodes column 0, for
839 line_map_ordinary
*map
= LINEMAPS_LAST_ORDINARY_MAP (set
);
840 r
= r
+ (to_column
<< map
->m_range_bits
);
841 if (r
>= set
->highest_location
)
842 set
->highest_location
= r
;
846 /* Encode and return a source location from a given line and
850 linemap_position_for_line_and_column (line_maps
*set
,
851 const line_map_ordinary
*ord_map
,
855 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map
) <= line
);
857 source_location r
= MAP_START_LOCATION (ord_map
);
858 r
+= ((line
- ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map
))
859 << ord_map
->m_column_and_range_bits
);
860 if (r
<= LINE_MAP_MAX_LOCATION_WITH_COLS
)
861 r
+= ((column
& ((1 << ord_map
->m_column_and_range_bits
) - 1))
862 << ord_map
->m_range_bits
);
863 source_location upper_limit
= LINEMAPS_MACRO_LOWEST_LOCATION (set
);
864 if (r
>= upper_limit
)
866 if (r
> set
->highest_location
)
867 set
->highest_location
= r
;
871 /* Encode and return a source_location starting from location LOC and
872 shifting it by COLUMN_OFFSET columns. This function does not support
873 virtual locations. */
876 linemap_position_for_loc_and_offset (struct line_maps
*set
,
878 unsigned int column_offset
)
880 const line_map_ordinary
* map
= NULL
;
882 if (IS_ADHOC_LOC (loc
))
883 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
885 /* This function does not support virtual locations yet. */
886 if (linemap_location_from_macro_expansion_p (set
, loc
))
889 if (column_offset
== 0
890 /* Adding an offset to a reserved location (like
891 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
892 sense. So let's leave the location intact in that case. */
893 || loc
< RESERVED_LOCATION_COUNT
)
896 /* We find the real location and shift it. */
897 loc
= linemap_resolve_location (set
, loc
, LRK_SPELLING_LOCATION
, &map
);
898 /* The new location (loc + offset) should be higher than the first
899 location encoded by MAP. This can fail if the line information
900 is messed up because of line directives (see PR66415). */
901 if (MAP_START_LOCATION (map
) >= loc
+ (column_offset
<< map
->m_range_bits
))
904 linenum_type line
= SOURCE_LINE (map
, loc
);
905 unsigned int column
= SOURCE_COLUMN (map
, loc
);
907 /* If MAP is not the last line map of its set, then the new location
908 (loc + offset) should be less than the first location encoded by
909 the next line map of the set. Otherwise, we try to encode the
910 location in the next map. */
911 while (map
!= LINEMAPS_LAST_ORDINARY_MAP (set
)
912 && (loc
+ (column_offset
<< map
->m_range_bits
)
913 >= MAP_START_LOCATION (&map
[1])))
916 /* If the next map starts in a higher line, we cannot encode the
918 if (line
< ORDINARY_MAP_STARTING_LINE_NUMBER (map
))
922 column
+= column_offset
;
924 /* Bail out if the column is not representable within the existing
926 if (column
>= (1u << (map
->m_column_and_range_bits
- map
->m_range_bits
)))
930 linemap_position_for_line_and_column (set
, map
, line
, column
);
931 if (linemap_assert_fails (r
<= set
->highest_location
)
932 || linemap_assert_fails (map
== linemap_lookup (set
, r
)))
938 /* Given a virtual source location yielded by a map (either an
939 ordinary or a macro map), returns that map. */
941 const struct line_map
*
942 linemap_lookup (struct line_maps
*set
, source_location line
)
944 if (IS_ADHOC_LOC (line
))
945 line
= set
->location_adhoc_data_map
.data
[line
& MAX_SOURCE_LOCATION
].locus
;
946 if (linemap_location_from_macro_expansion_p (set
, line
))
947 return linemap_macro_map_lookup (set
, line
);
948 return linemap_ordinary_map_lookup (set
, line
);
951 /* Given a source location yielded by an ordinary map, returns that
952 map. Since the set is built chronologically, the logical lines are
953 monotonic increasing, and so the list is sorted and we can use a
956 static const line_map_ordinary
*
957 linemap_ordinary_map_lookup (struct line_maps
*set
, source_location line
)
959 unsigned int md
, mn
, mx
;
960 const line_map_ordinary
*cached
, *result
;
962 if (IS_ADHOC_LOC (line
))
963 line
= set
->location_adhoc_data_map
.data
[line
& MAX_SOURCE_LOCATION
].locus
;
965 if (set
== NULL
|| line
< RESERVED_LOCATION_COUNT
)
968 mn
= LINEMAPS_ORDINARY_CACHE (set
);
969 mx
= LINEMAPS_ORDINARY_USED (set
);
971 cached
= LINEMAPS_ORDINARY_MAP_AT (set
, mn
);
972 /* We should get a segfault if no line_maps have been added yet. */
973 if (line
>= MAP_START_LOCATION (cached
))
975 if (mn
+ 1 == mx
|| line
< MAP_START_LOCATION (&cached
[1]))
987 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set
, md
)) > line
)
993 LINEMAPS_ORDINARY_CACHE (set
) = mn
;
994 result
= LINEMAPS_ORDINARY_MAP_AT (set
, mn
);
995 linemap_assert (line
>= MAP_START_LOCATION (result
));
999 /* Given a source location yielded by a macro map, returns that map.
1000 Since the set is built chronologically, the logical lines are
1001 monotonic decreasing, and so the list is sorted and we can use a
1004 static const line_map_macro
*
1005 linemap_macro_map_lookup (struct line_maps
*set
, source_location line
)
1007 unsigned int md
, mn
, mx
;
1008 const struct line_map_macro
*cached
, *result
;
1010 if (IS_ADHOC_LOC (line
))
1011 line
= set
->location_adhoc_data_map
.data
[line
& MAX_SOURCE_LOCATION
].locus
;
1013 linemap_assert (line
>= LINEMAPS_MACRO_LOWEST_LOCATION (set
));
1018 mn
= LINEMAPS_MACRO_CACHE (set
);
1019 mx
= LINEMAPS_MACRO_USED (set
);
1020 cached
= LINEMAPS_MACRO_MAP_AT (set
, mn
);
1022 if (line
>= MAP_START_LOCATION (cached
))
1024 if (mn
== 0 || line
< MAP_START_LOCATION (&cached
[-1]))
1033 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set
, md
)) > line
)
1039 LINEMAPS_MACRO_CACHE (set
) = mx
;
1040 result
= LINEMAPS_MACRO_MAP_AT (set
, LINEMAPS_MACRO_CACHE (set
));
1041 linemap_assert (MAP_START_LOCATION (result
) <= line
);
1046 /* Return TRUE if MAP encodes locations coming from a macro
1047 replacement-list at macro expansion point. */
1050 linemap_macro_expansion_map_p (const struct line_map
*map
)
1054 return (map
->reason
== LC_ENTER_MACRO
);
1057 /* If LOCATION is the locus of a token in a replacement-list of a
1058 macro expansion return the location of the macro expansion point.
1060 Read the comments of struct line_map and struct line_map_macro in
1061 line-map.h to understand what a macro expansion point is. */
1063 static source_location
1064 linemap_macro_map_loc_to_exp_point (const line_map_macro
*map
,
1065 source_location location ATTRIBUTE_UNUSED
)
1067 linemap_assert (linemap_macro_expansion_map_p (map
)
1068 && location
>= MAP_START_LOCATION (map
));
1070 /* Make sure LOCATION is correct. */
1071 linemap_assert ((location
- MAP_START_LOCATION (map
))
1072 < MACRO_MAP_NUM_MACRO_TOKENS (map
));
1074 return MACRO_MAP_EXPANSION_POINT_LOCATION (map
);
1077 /* LOCATION is the source location of a token that belongs to a macro
1078 replacement-list as part of the macro expansion denoted by MAP.
1080 Return the location of the token at the definition point of the
1083 static source_location
1084 linemap_macro_map_loc_to_def_point (const line_map_macro
*map
,
1085 source_location location
)
1089 linemap_assert (linemap_macro_expansion_map_p (map
)
1090 && location
>= MAP_START_LOCATION (map
));
1091 linemap_assert (location
>= RESERVED_LOCATION_COUNT
);
1093 token_no
= location
- MAP_START_LOCATION (map
);
1094 linemap_assert (token_no
< MACRO_MAP_NUM_MACRO_TOKENS (map
));
1096 location
= MACRO_MAP_LOCATIONS (map
)[2 * token_no
+ 1];
1101 /* If LOCATION is the locus of a token that is an argument of a
1102 function-like macro M and appears in the expansion of M, return the
1103 locus of that argument in the context of the caller of M.
1105 In other words, this returns the xI location presented in the
1106 comments of line_map_macro above. */
1108 linemap_macro_map_loc_unwind_toward_spelling (line_maps
*set
,
1109 const line_map_macro
* map
,
1110 source_location location
)
1114 if (IS_ADHOC_LOC (location
))
1115 location
= get_location_from_adhoc_loc (set
, location
);
1117 linemap_assert (linemap_macro_expansion_map_p (map
)
1118 && location
>= MAP_START_LOCATION (map
));
1119 linemap_assert (location
>= RESERVED_LOCATION_COUNT
);
1120 linemap_assert (!IS_ADHOC_LOC (location
));
1122 token_no
= location
- MAP_START_LOCATION (map
);
1123 linemap_assert (token_no
< MACRO_MAP_NUM_MACRO_TOKENS (map
));
1125 location
= MACRO_MAP_LOCATIONS (map
)[2 * token_no
];
1130 /* Return the source line number corresponding to source location
1131 LOCATION. SET is the line map set LOCATION comes from. If
1132 LOCATION is the source location of token that is part of the
1133 replacement-list of a macro expansion return the line number of the
1134 macro expansion point. */
1137 linemap_get_expansion_line (struct line_maps
*set
,
1138 source_location location
)
1140 const line_map_ordinary
*map
= NULL
;
1142 if (IS_ADHOC_LOC (location
))
1143 location
= set
->location_adhoc_data_map
.data
[location
1144 & MAX_SOURCE_LOCATION
].locus
;
1146 if (location
< RESERVED_LOCATION_COUNT
)
1150 linemap_macro_loc_to_exp_point (set
, location
, &map
);
1152 return SOURCE_LINE (map
, location
);
1155 /* Return the path of the file corresponding to source code location
1158 If LOCATION is the source location of token that is part of the
1159 replacement-list of a macro expansion return the file path of the
1160 macro expansion point.
1162 SET is the line map set LOCATION comes from. */
1165 linemap_get_expansion_filename (struct line_maps
*set
,
1166 source_location location
)
1168 const struct line_map_ordinary
*map
= NULL
;
1170 if (IS_ADHOC_LOC (location
))
1171 location
= set
->location_adhoc_data_map
.data
[location
1172 & MAX_SOURCE_LOCATION
].locus
;
1174 if (location
< RESERVED_LOCATION_COUNT
)
1178 linemap_macro_loc_to_exp_point (set
, location
, &map
);
1180 return LINEMAP_FILE (map
);
1183 /* Return the name of the macro associated to MACRO_MAP. */
1186 linemap_map_get_macro_name (const line_map_macro
*macro_map
)
1188 linemap_assert (macro_map
&& linemap_macro_expansion_map_p (macro_map
));
1189 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map
));
1192 /* Return a positive value if LOCATION is the locus of a token that is
1193 located in a system header, O otherwise. It returns 1 if LOCATION
1194 is the locus of a token that is located in a system header, and 2
1195 if LOCATION is the locus of a token located in a C system header
1196 that therefore needs to be extern "C" protected in C++.
1198 Note that this function returns 1 if LOCATION belongs to a token
1199 that is part of a macro replacement-list defined in a system
1200 header, but expanded in a non-system file. */
1203 linemap_location_in_system_header_p (struct line_maps
*set
,
1204 source_location location
)
1206 const struct line_map
*map
= NULL
;
1208 if (IS_ADHOC_LOC (location
))
1209 location
= set
->location_adhoc_data_map
.data
[location
1210 & MAX_SOURCE_LOCATION
].locus
;
1212 if (location
< RESERVED_LOCATION_COUNT
)
1215 /* Let's look at where the token for LOCATION comes from. */
1218 map
= linemap_lookup (set
, location
);
1221 if (!linemap_macro_expansion_map_p (map
))
1222 /* It's a normal token. */
1223 return LINEMAP_SYSP (linemap_check_ordinary (map
));
1226 const line_map_macro
*macro_map
= linemap_check_macro (map
);
1228 /* It's a token resulting from a macro expansion. */
1229 source_location loc
=
1230 linemap_macro_map_loc_unwind_toward_spelling (set
, macro_map
, location
);
1231 if (loc
< RESERVED_LOCATION_COUNT
)
1232 /* This token might come from a built-in macro. Let's
1233 look at where that macro got expanded. */
1234 location
= linemap_macro_map_loc_to_exp_point (macro_map
, location
);
1245 /* Return TRUE if LOCATION is a source code location of a token that is part of
1246 a macro expansion, FALSE otherwise. */
1249 linemap_location_from_macro_expansion_p (const struct line_maps
*set
,
1250 source_location location
)
1252 if (IS_ADHOC_LOC (location
))
1253 location
= set
->location_adhoc_data_map
.data
[location
1254 & MAX_SOURCE_LOCATION
].locus
;
1256 linemap_assert (location
<= MAX_SOURCE_LOCATION
1257 && (set
->highest_location
1258 < LINEMAPS_MACRO_LOWEST_LOCATION (set
)));
1261 return (location
> set
->highest_location
);
1264 /* Given two virtual locations *LOC0 and *LOC1, return the first
1265 common macro map in their macro expansion histories. Return NULL
1266 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1267 virtual location of the token inside the resulting macro. */
1269 static const struct line_map
*
1270 first_map_in_common_1 (struct line_maps
*set
,
1271 source_location
*loc0
,
1272 source_location
*loc1
)
1274 source_location l0
= *loc0
, l1
= *loc1
;
1275 const struct line_map
*map0
= linemap_lookup (set
, l0
),
1276 *map1
= linemap_lookup (set
, l1
);
1278 while (linemap_macro_expansion_map_p (map0
)
1279 && linemap_macro_expansion_map_p (map1
)
1282 if (MAP_START_LOCATION (map0
) < MAP_START_LOCATION (map1
))
1284 l0
= linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0
),
1286 map0
= linemap_lookup (set
, l0
);
1290 l1
= linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1
),
1292 map1
= linemap_lookup (set
, l1
);
1305 /* Given two virtual locations LOC0 and LOC1, return the first common
1306 macro map in their macro expansion histories. Return NULL if no
1307 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1308 virtual location of the token inside the resulting macro, upon
1309 return of a non-NULL result. */
1311 static const struct line_map
*
1312 first_map_in_common (struct line_maps
*set
,
1313 source_location loc0
,
1314 source_location loc1
,
1315 source_location
*res_loc0
,
1316 source_location
*res_loc1
)
1321 return first_map_in_common_1 (set
, res_loc0
, res_loc1
);
1324 /* Return a positive value if PRE denotes the location of a token that
1325 comes before the token of POST, 0 if PRE denotes the location of
1326 the same token as the token for POST, and a negative value
1330 linemap_compare_locations (struct line_maps
*set
,
1331 source_location pre
,
1332 source_location post
)
1334 bool pre_virtual_p
, post_virtual_p
;
1335 source_location l0
= pre
, l1
= post
;
1337 if (IS_ADHOC_LOC (l0
))
1338 l0
= get_location_from_adhoc_loc (set
, l0
);
1339 if (IS_ADHOC_LOC (l1
))
1340 l1
= get_location_from_adhoc_loc (set
, l1
);
1345 if ((pre_virtual_p
= linemap_location_from_macro_expansion_p (set
, l0
)))
1346 l0
= linemap_resolve_location (set
, l0
,
1347 LRK_MACRO_EXPANSION_POINT
,
1350 if ((post_virtual_p
= linemap_location_from_macro_expansion_p (set
, l1
)))
1351 l1
= linemap_resolve_location (set
, l1
,
1352 LRK_MACRO_EXPANSION_POINT
,
1359 /* So pre and post represent two tokens that are present in a
1360 same macro expansion. Let's see if the token for pre was
1361 before the token for post in that expansion. */
1363 const struct line_map
*map
=
1364 first_map_in_common (set
, pre
, post
, &l0
, &l1
);
1367 /* This should not be possible. */
1370 i0
= l0
- MAP_START_LOCATION (map
);
1371 i1
= l1
- MAP_START_LOCATION (map
);
1375 if (IS_ADHOC_LOC (l0
))
1376 l0
= get_location_from_adhoc_loc (set
, l0
);
1377 if (IS_ADHOC_LOC (l1
))
1378 l1
= get_location_from_adhoc_loc (set
, l1
);
1383 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1386 trace_include (const struct line_maps
*set
, const line_map_ordinary
*map
)
1388 unsigned int i
= set
->depth
;
1393 fprintf (stderr
, " %s\n", ORDINARY_MAP_FILE_NAME (map
));
1396 /* Return the spelling location of the token wherever it comes from,
1397 whether part of a macro definition or not.
1399 This is a subroutine for linemap_resolve_location. */
1401 static source_location
1402 linemap_macro_loc_to_spelling_point (struct line_maps
*set
,
1403 source_location location
,
1404 const line_map_ordinary
**original_map
)
1406 struct line_map
*map
;
1407 linemap_assert (set
&& location
>= RESERVED_LOCATION_COUNT
);
1411 map
= const_cast <line_map
*> (linemap_lookup (set
, location
));
1412 if (!linemap_macro_expansion_map_p (map
))
1416 = linemap_macro_map_loc_unwind_toward_spelling
1417 (set
, linemap_check_macro (map
),
1422 *original_map
= linemap_check_ordinary (map
);
1426 /* If LOCATION is the source location of a token that belongs to a
1427 macro replacement-list -- as part of a macro expansion -- then
1428 return the location of the token at the definition point of the
1429 macro. Otherwise, return LOCATION. SET is the set of maps
1430 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1431 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1432 returned location comes from.
1434 This is a subroutine of linemap_resolve_location. */
1436 static source_location
1437 linemap_macro_loc_to_def_point (struct line_maps
*set
,
1438 source_location location
,
1439 const line_map_ordinary
**original_map
)
1441 struct line_map
*map
;
1443 linemap_assert (set
&& location
>= RESERVED_LOCATION_COUNT
);
1447 source_location caret_loc
;
1448 if (IS_ADHOC_LOC (location
))
1449 caret_loc
= get_location_from_adhoc_loc (set
, location
);
1451 caret_loc
= location
;
1453 map
= const_cast <line_map
*> (linemap_lookup (set
, caret_loc
));
1454 if (!linemap_macro_expansion_map_p (map
))
1458 linemap_macro_map_loc_to_def_point (linemap_check_macro (map
),
1463 *original_map
= linemap_check_ordinary (map
);
1467 /* If LOCATION is the source location of a token that belongs to a
1468 macro replacement-list -- at a macro expansion point -- then return
1469 the location of the topmost expansion point of the macro. We say
1470 topmost because if we are in the context of a nested macro
1471 expansion, the function returns the source location of the first
1472 macro expansion that triggered the nested expansions.
1474 Otherwise, return LOCATION. SET is the set of maps location come
1475 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1476 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1477 location comes from.
1479 This is a subroutine of linemap_resolve_location. */
1481 static source_location
1482 linemap_macro_loc_to_exp_point (struct line_maps
*set
,
1483 source_location location
,
1484 const line_map_ordinary
**original_map
)
1486 struct line_map
*map
;
1488 if (IS_ADHOC_LOC (location
))
1489 location
= set
->location_adhoc_data_map
.data
[location
1490 & MAX_SOURCE_LOCATION
].locus
;
1492 linemap_assert (set
&& location
>= RESERVED_LOCATION_COUNT
);
1496 map
= const_cast <line_map
*> (linemap_lookup (set
, location
));
1497 if (!linemap_macro_expansion_map_p (map
))
1499 location
= linemap_macro_map_loc_to_exp_point (linemap_check_macro (map
),
1504 *original_map
= linemap_check_ordinary (map
);
1508 /* Resolve a virtual location into either a spelling location, an
1509 expansion point location or a token argument replacement point
1510 location. Return the map that encodes the virtual location as well
1511 as the resolved location.
1513 If LOC is *NOT* the location of a token resulting from the
1514 expansion of a macro, then the parameter LRK (which stands for
1515 Location Resolution Kind) is ignored and the resulting location
1516 just equals the one given in argument.
1518 Now if LOC *IS* the location of a token resulting from the
1519 expansion of a macro, this is what happens.
1521 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1522 -------------------------------
1524 The virtual location is resolved to the first macro expansion point
1525 that led to this macro expansion.
1527 * If LRK is set to LRK_SPELLING_LOCATION
1528 -------------------------------------
1530 The virtual location is resolved to the locus where the token has
1531 been spelled in the source. This can follow through all the macro
1532 expansions that led to the token.
1534 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1535 --------------------------------------
1537 The virtual location is resolved to the locus of the token in the
1538 context of the macro definition.
1540 If LOC is the locus of a token that is an argument of a
1541 function-like macro [replacing a parameter in the replacement list
1542 of the macro] the virtual location is resolved to the locus of the
1543 parameter that is replaced, in the context of the definition of the
1546 If LOC is the locus of a token that is not an argument of a
1547 function-like macro, then the function behaves as if LRK was set to
1548 LRK_SPELLING_LOCATION.
1550 If MAP is not NULL, *MAP is set to the map encoding the
1551 returned location. Note that if the returned location wasn't originally
1552 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1553 resolves to a location reserved for the client code, like
1554 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1557 linemap_resolve_location (struct line_maps
*set
,
1558 source_location loc
,
1559 enum location_resolution_kind lrk
,
1560 const line_map_ordinary
**map
)
1562 source_location locus
= loc
;
1563 if (IS_ADHOC_LOC (loc
))
1564 locus
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1566 if (locus
< RESERVED_LOCATION_COUNT
)
1568 /* A reserved location wasn't encoded in a map. Let's return a
1569 NULL map here, just like what linemap_ordinary_map_lookup
1578 case LRK_MACRO_EXPANSION_POINT
:
1579 loc
= linemap_macro_loc_to_exp_point (set
, loc
, map
);
1581 case LRK_SPELLING_LOCATION
:
1582 loc
= linemap_macro_loc_to_spelling_point (set
, loc
, map
);
1584 case LRK_MACRO_DEFINITION_LOCATION
:
1585 loc
= linemap_macro_loc_to_def_point (set
, loc
, map
);
1593 /* TRUE if LOCATION is a source code location of a token that is part of the
1594 definition of a macro, FALSE otherwise. */
1597 linemap_location_from_macro_definition_p (struct line_maps
*set
,
1598 source_location loc
)
1600 if (IS_ADHOC_LOC (loc
))
1601 loc
= get_location_from_adhoc_loc (set
, loc
);
1603 if (!linemap_location_from_macro_expansion_p (set
, loc
))
1608 const struct line_map_macro
*map
1609 = linemap_check_macro (linemap_lookup (set
, loc
));
1611 source_location s_loc
1612 = linemap_macro_map_loc_unwind_toward_spelling (set
, map
, loc
);
1613 if (linemap_location_from_macro_expansion_p (set
, s_loc
))
1617 source_location def_loc
1618 = linemap_macro_map_loc_to_def_point (map
, loc
);
1619 return s_loc
== def_loc
;
1625 Suppose that LOC is the virtual location of a token T coming from
1626 the expansion of a macro M. This function then steps up to get the
1627 location L of the point where M got expanded. If L is a spelling
1628 location inside a macro expansion M', then this function returns
1629 the locus of the point where M' was expanded. Said otherwise, this
1630 function returns the location of T in the context that triggered
1633 *LOC_MAP must be set to the map of LOC. This function then sets it
1634 to the map of the returned location. */
1637 linemap_unwind_toward_expansion (struct line_maps
*set
,
1638 source_location loc
,
1639 const struct line_map
**map
)
1641 source_location resolved_location
;
1642 const line_map_macro
*macro_map
= linemap_check_macro (*map
);
1643 const struct line_map
*resolved_map
;
1645 if (IS_ADHOC_LOC (loc
))
1646 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1649 linemap_macro_map_loc_unwind_toward_spelling (set
, macro_map
, loc
);
1650 resolved_map
= linemap_lookup (set
, resolved_location
);
1652 if (!linemap_macro_expansion_map_p (resolved_map
))
1654 resolved_location
= linemap_macro_map_loc_to_exp_point (macro_map
, loc
);
1655 resolved_map
= linemap_lookup (set
, resolved_location
);
1658 *map
= resolved_map
;
1659 return resolved_location
;
1662 /* If LOC is the virtual location of a token coming from the expansion
1663 of a macro M and if its spelling location is reserved (e.g, a
1664 location for a built-in token), then this function unwinds (using
1665 linemap_unwind_toward_expansion) the location until a location that
1666 is not reserved and is not in a system header is reached. In other
1667 words, this unwinds the reserved location until a location that is
1668 in real source code is reached.
1670 Otherwise, if the spelling location for LOC is not reserved or if
1671 LOC doesn't come from the expansion of a macro, the function
1672 returns LOC as is and *MAP is not touched.
1674 *MAP is set to the map of the returned location if the later is
1675 different from LOC. */
1677 linemap_unwind_to_first_non_reserved_loc (struct line_maps
*set
,
1678 source_location loc
,
1679 const struct line_map
**map
)
1681 source_location resolved_loc
;
1682 const struct line_map
*map0
= NULL
;
1683 const line_map_ordinary
*map1
= NULL
;
1685 if (IS_ADHOC_LOC (loc
))
1686 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1688 map0
= linemap_lookup (set
, loc
);
1689 if (!linemap_macro_expansion_map_p (map0
))
1692 resolved_loc
= linemap_resolve_location (set
, loc
,
1693 LRK_SPELLING_LOCATION
,
1696 if (resolved_loc
>= RESERVED_LOCATION_COUNT
1697 && !LINEMAP_SYSP (map1
))
1700 while (linemap_macro_expansion_map_p (map0
)
1701 && (resolved_loc
< RESERVED_LOCATION_COUNT
1702 || LINEMAP_SYSP (map1
)))
1704 loc
= linemap_unwind_toward_expansion (set
, loc
, &map0
);
1705 resolved_loc
= linemap_resolve_location (set
, loc
,
1706 LRK_SPELLING_LOCATION
,
1715 /* Expand source code location LOC and return a user readable source
1716 code location. LOC must be a spelling (non-virtual) location. If
1717 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1718 location is returned. */
1721 linemap_expand_location (struct line_maps
*set
,
1722 const struct line_map
*map
,
1723 source_location loc
)
1726 expanded_location xloc
;
1728 memset (&xloc
, 0, sizeof (xloc
));
1729 if (IS_ADHOC_LOC (loc
))
1732 = set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].data
;
1733 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1736 if (loc
< RESERVED_LOCATION_COUNT
)
1737 /* The location for this token wasn't generated from a line map.
1738 It was probably a location for a builtin token, chosen by some
1739 client code. Let's not try to expand the location in that
1741 else if (map
== NULL
)
1742 /* We shouldn't be getting a NULL map with a location that is not
1743 reserved by the client code. */
1747 /* MAP must be an ordinary map and LOC must be non-virtual,
1748 encoded into this map, obviously; the accessors used on MAP
1749 below ensure it is ordinary. Let's just assert the
1750 non-virtualness of LOC here. */
1751 if (linemap_location_from_macro_expansion_p (set
, loc
))
1754 const line_map_ordinary
*ord_map
= linemap_check_ordinary (map
);
1756 xloc
.file
= LINEMAP_FILE (ord_map
);
1757 xloc
.line
= SOURCE_LINE (ord_map
, loc
);
1758 xloc
.column
= SOURCE_COLUMN (ord_map
, loc
);
1759 xloc
.sysp
= LINEMAP_SYSP (ord_map
) != 0;
1766 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1767 is NULL, use stderr. IS_MACRO is true if the caller wants to
1768 dump a macro map, false otherwise. */
1771 linemap_dump (FILE *stream
, struct line_maps
*set
, unsigned ix
, bool is_macro
)
1773 const char *lc_reasons_v
[LC_ENTER_MACRO
+ 1]
1774 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1777 const line_map
*map
;
1783 map
= LINEMAPS_ORDINARY_MAP_AT (set
, ix
);
1785 map
= LINEMAPS_MACRO_MAP_AT (set
, ix
);
1787 reason
= (map
->reason
<= LC_ENTER_MACRO
) ? lc_reasons_v
[map
->reason
] : "???";
1789 fprintf (stream
, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1790 ix
, (void *) map
, map
->start_location
, reason
,
1792 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map
)))
1796 const line_map_ordinary
*ord_map
= linemap_check_ordinary (map
);
1797 unsigned includer_ix
;
1798 const line_map_ordinary
*includer_map
;
1800 includer_ix
= ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map
);
1801 includer_map
= includer_ix
< LINEMAPS_ORDINARY_USED (set
)
1802 ? LINEMAPS_ORDINARY_MAP_AT (set
, includer_ix
)
1805 fprintf (stream
, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map
),
1806 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map
));
1807 fprintf (stream
, "Included from: [%d] %s\n", includer_ix
,
1808 includer_map
? ORDINARY_MAP_FILE_NAME (includer_map
) : "None");
1812 const line_map_macro
*macro_map
= linemap_check_macro (map
);
1813 fprintf (stream
, "Macro: %s (%u tokens)\n",
1814 linemap_map_get_macro_name (macro_map
),
1815 MACRO_MAP_NUM_MACRO_TOKENS (macro_map
));
1818 fprintf (stream
, "\n");
1822 /* Dump debugging information about source location LOC into the file
1823 stream STREAM. SET is the line map set LOC comes from. */
1826 linemap_dump_location (struct line_maps
*set
,
1827 source_location loc
,
1830 const line_map_ordinary
*map
;
1831 source_location location
;
1832 const char *path
= "", *from
= "";
1833 int l
= -1, c
= -1, s
= -1, e
= -1;
1835 if (IS_ADHOC_LOC (loc
))
1836 loc
= set
->location_adhoc_data_map
.data
[loc
& MAX_SOURCE_LOCATION
].locus
;
1842 linemap_resolve_location (set
, loc
, LRK_MACRO_DEFINITION_LOCATION
, &map
);
1845 /* Only reserved locations can be tolerated in this case. */
1846 linemap_assert (location
< RESERVED_LOCATION_COUNT
);
1849 path
= LINEMAP_FILE (map
);
1850 l
= SOURCE_LINE (map
, location
);
1851 c
= SOURCE_COLUMN (map
, location
);
1852 s
= LINEMAP_SYSP (map
) != 0;
1853 e
= location
!= loc
;
1857 from
= (INCLUDED_FROM (set
, map
))
1858 ? LINEMAP_FILE (INCLUDED_FROM (set
, map
))
1862 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1863 E: macro expansion?, LOC: original location, R: resolved location */
1864 fprintf (stream
, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1865 path
, from
, l
, c
, s
, (void*)map
, e
, loc
, location
);
1868 /* Return the highest location emitted for a given file for which
1869 there is a line map in SET. FILE_NAME is the file name to
1870 consider. If the function returns TRUE, *LOC is set to the highest
1871 location emitted for that file. */
1874 linemap_get_file_highest_location (struct line_maps
*set
,
1875 const char *file_name
,
1876 source_location
*loc
)
1878 /* If the set is empty or no ordinary map has been created then
1879 there is no file to look for ... */
1880 if (set
== NULL
|| set
->info_ordinary
.used
== 0)
1883 /* Now look for the last ordinary map created for FILE_NAME. */
1885 for (i
= set
->info_ordinary
.used
- 1; i
>= 0; --i
)
1887 const char *fname
= set
->info_ordinary
.maps
[i
].to_file
;
1888 if (fname
&& !filename_cmp (fname
, file_name
))
1895 /* The highest location for a given map is either the starting
1896 location of the next map minus one, or -- if the map is the
1897 latest one -- the highest location of the set. */
1898 source_location result
;
1899 if (i
== (int) set
->info_ordinary
.used
- 1)
1900 result
= set
->highest_location
;
1902 result
= set
->info_ordinary
.maps
[i
+ 1].start_location
- 1;
1908 /* Compute and return statistics about the memory consumption of some
1909 parts of the line table SET. */
1912 linemap_get_statistics (struct line_maps
*set
,
1913 struct linemap_stats
*s
)
1915 long ordinary_maps_allocated_size
, ordinary_maps_used_size
,
1916 macro_maps_allocated_size
, macro_maps_used_size
,
1917 macro_maps_locations_size
= 0, duplicated_macro_maps_locations_size
= 0;
1919 const line_map_macro
*cur_map
;
1921 ordinary_maps_allocated_size
=
1922 LINEMAPS_ORDINARY_ALLOCATED (set
) * sizeof (struct line_map_ordinary
);
1924 ordinary_maps_used_size
=
1925 LINEMAPS_ORDINARY_USED (set
) * sizeof (struct line_map_ordinary
);
1927 macro_maps_allocated_size
=
1928 LINEMAPS_MACRO_ALLOCATED (set
) * sizeof (struct line_map_macro
);
1930 for (cur_map
= LINEMAPS_MACRO_MAPS (set
);
1931 cur_map
&& cur_map
<= LINEMAPS_LAST_MACRO_MAP (set
);
1936 linemap_assert (linemap_macro_expansion_map_p (cur_map
));
1938 macro_maps_locations_size
+=
1939 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map
) * sizeof (source_location
);
1941 for (i
= 0; i
< 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map
); i
+= 2)
1943 if (MACRO_MAP_LOCATIONS (cur_map
)[i
] ==
1944 MACRO_MAP_LOCATIONS (cur_map
)[i
+ 1])
1945 duplicated_macro_maps_locations_size
+=
1946 sizeof (source_location
);
1950 macro_maps_used_size
=
1951 LINEMAPS_MACRO_USED (set
) * sizeof (struct line_map_macro
);
1953 s
->num_ordinary_maps_allocated
= LINEMAPS_ORDINARY_ALLOCATED (set
);
1954 s
->num_ordinary_maps_used
= LINEMAPS_ORDINARY_USED (set
);
1955 s
->ordinary_maps_allocated_size
= ordinary_maps_allocated_size
;
1956 s
->ordinary_maps_used_size
= ordinary_maps_used_size
;
1957 s
->num_expanded_macros
= num_expanded_macros_counter
;
1958 s
->num_macro_tokens
= num_macro_tokens_counter
;
1959 s
->num_macro_maps_used
= LINEMAPS_MACRO_USED (set
);
1960 s
->macro_maps_allocated_size
= macro_maps_allocated_size
;
1961 s
->macro_maps_locations_size
= macro_maps_locations_size
;
1962 s
->macro_maps_used_size
= macro_maps_used_size
;
1963 s
->duplicated_macro_maps_locations_size
=
1964 duplicated_macro_maps_locations_size
;
1965 s
->adhoc_table_size
= (set
->location_adhoc_data_map
.allocated
1966 * sizeof (struct location_adhoc_data
));
1967 s
->adhoc_table_entries_used
= set
->location_adhoc_data_map
.curr_loc
;
1971 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1972 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1973 specifies how many macro maps to dump. */
1976 line_table_dump (FILE *stream
, struct line_maps
*set
, unsigned int num_ordinary
,
1977 unsigned int num_macro
)
1987 fprintf (stream
, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set
));
1988 fprintf (stream
, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set
));
1989 fprintf (stream
, "Include stack depth: %d\n", set
->depth
);
1990 fprintf (stream
, "Highest location: %u\n", set
->highest_location
);
1994 fprintf (stream
, "\nOrdinary line maps\n");
1995 for (i
= 0; i
< num_ordinary
&& i
< LINEMAPS_ORDINARY_USED (set
); i
++)
1996 linemap_dump (stream
, set
, i
, false);
1997 fprintf (stream
, "\n");
2002 fprintf (stream
, "\nMacro line maps\n");
2003 for (i
= 0; i
< num_macro
&& i
< LINEMAPS_MACRO_USED (set
); i
++)
2004 linemap_dump (stream
, set
, i
, true);
2005 fprintf (stream
, "\n");
2009 /* class rich_location. */
2011 /* Construct a rich_location with location LOC as its initial range. */
2013 rich_location::rich_location (line_maps
*set
, source_location loc
) :
2016 m_column_override (0),
2017 m_have_expanded_location (false),
2019 m_seen_impossible_fixit (false),
2020 m_fixits_cannot_be_auto_applied (false)
2022 add_range (loc
, true);
2025 /* The destructor for class rich_location. */
2027 rich_location::~rich_location ()
2029 for (unsigned int i
= 0; i
< m_fixit_hints
.count (); i
++)
2030 delete get_fixit_hint (i
);
2033 /* Get location IDX within this rich_location. */
2036 rich_location::get_loc (unsigned int idx
) const
2038 const location_range
*locrange
= get_range (idx
);
2039 return locrange
->m_loc
;
2042 /* Get range IDX within this rich_location. */
2044 const location_range
*
2045 rich_location::get_range (unsigned int idx
) const
2047 return &m_ranges
[idx
];
2050 /* Mutable access to range IDX within this rich_location. */
2053 rich_location::get_range (unsigned int idx
)
2055 return &m_ranges
[idx
];
2058 /* Expand location IDX within this rich_location. */
2059 /* Get an expanded_location for this rich_location's primary
2063 rich_location::get_expanded_location (unsigned int idx
)
2067 /* Cache the expansion of the primary location. */
2068 if (!m_have_expanded_location
)
2071 = linemap_client_expand_location_to_spelling_point
2072 (get_loc (0), LOCATION_ASPECT_CARET
);
2073 if (m_column_override
)
2074 m_expanded_location
.column
= m_column_override
;
2075 m_have_expanded_location
= true;
2078 return m_expanded_location
;
2081 return linemap_client_expand_location_to_spelling_point
2082 (get_loc (idx
), LOCATION_ASPECT_CARET
);
2085 /* Set the column of the primary location, with 0 meaning
2086 "don't override it". */
2089 rich_location::override_column (int column
)
2091 m_column_override
= column
;
2092 m_have_expanded_location
= false;
2095 /* Add the given range. */
2098 rich_location::add_range (source_location loc
, bool show_caret_p
)
2100 location_range range
;
2102 range
.m_show_caret_p
= show_caret_p
;
2103 m_ranges
.push (range
);
2106 /* Add or overwrite the location given by IDX, setting its location to LOC,
2107 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2109 It must either overwrite an existing location, or add one *exactly* on
2110 the end of the array.
2112 This is primarily for use by gcc when implementing diagnostic format
2114 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2115 (which writes the source location of a tree back into location 0 of
2116 the rich_location), and
2117 - the "%C" and "%L" format codes in the Fortran frontend. */
2120 rich_location::set_range (line_maps
* /*set*/, unsigned int idx
,
2121 source_location loc
, bool show_caret_p
)
2123 /* We can either overwrite an existing range, or add one exactly
2124 on the end of the array. */
2125 linemap_assert (idx
<= m_ranges
.count ());
2127 if (idx
== m_ranges
.count ())
2128 add_range (loc
, show_caret_p
);
2131 location_range
*locrange
= get_range (idx
);
2132 locrange
->m_loc
= loc
;
2133 locrange
->m_show_caret_p
= show_caret_p
;
2137 /* Mark any cached value here as dirty. */
2138 m_have_expanded_location
= false;
2141 /* Methods for adding insertion fix-it hints. */
2143 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2144 immediately before the primary range's start location. */
2147 rich_location::add_fixit_insert_before (const char *new_content
)
2149 add_fixit_insert_before (get_loc (), new_content
);
2152 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2153 immediately before the start of WHERE. */
2156 rich_location::add_fixit_insert_before (source_location where
,
2157 const char *new_content
)
2159 source_location start
= get_range_from_loc (m_line_table
, where
).m_start
;
2160 maybe_add_fixit (start
, start
, new_content
);
2163 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2164 immediately after the primary range's end-point. */
2167 rich_location::add_fixit_insert_after (const char *new_content
)
2169 add_fixit_insert_after (get_loc (), new_content
);
2172 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2173 immediately after the end-point of WHERE. */
2176 rich_location::add_fixit_insert_after (source_location where
,
2177 const char *new_content
)
2179 source_location finish
= get_range_from_loc (m_line_table
, where
).m_finish
;
2180 source_location next_loc
2181 = linemap_position_for_loc_and_offset (m_line_table
, finish
, 1);
2183 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2185 if (next_loc
== finish
)
2187 stop_supporting_fixits ();
2191 maybe_add_fixit (next_loc
, next_loc
, new_content
);
2194 /* Methods for adding removal fix-it hints. */
2196 /* Add a fixit-hint, suggesting removal of the content covered
2200 rich_location::add_fixit_remove ()
2202 add_fixit_remove (get_loc ());
2205 /* Add a fixit-hint, suggesting removal of the content between
2206 the start and finish of WHERE. */
2209 rich_location::add_fixit_remove (source_location where
)
2211 source_range range
= get_range_from_loc (m_line_table
, where
);
2212 add_fixit_remove (range
);
2215 /* Add a fixit-hint, suggesting removal of the content at
2219 rich_location::add_fixit_remove (source_range src_range
)
2221 add_fixit_replace (src_range
, "");
2224 /* Add a fixit-hint, suggesting replacement of the content covered
2225 by range 0 with NEW_CONTENT. */
2228 rich_location::add_fixit_replace (const char *new_content
)
2230 add_fixit_replace (get_loc (), new_content
);
2233 /* Methods for adding "replace" fix-it hints. */
2235 /* Add a fixit-hint, suggesting replacement of the content between
2236 the start and finish of WHERE with NEW_CONTENT. */
2239 rich_location::add_fixit_replace (source_location where
,
2240 const char *new_content
)
2242 source_range range
= get_range_from_loc (m_line_table
, where
);
2243 add_fixit_replace (range
, new_content
);
2246 /* Add a fixit-hint, suggesting replacement of the content at
2247 SRC_RANGE with NEW_CONTENT. */
2250 rich_location::add_fixit_replace (source_range src_range
,
2251 const char *new_content
)
2253 source_location start
= get_pure_location (m_line_table
, src_range
.m_start
);
2254 source_location finish
= get_pure_location (m_line_table
, src_range
.m_finish
);
2256 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2257 source_location next_loc
2258 = linemap_position_for_loc_and_offset (m_line_table
, finish
, 1);
2259 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2261 if (next_loc
== finish
)
2263 stop_supporting_fixits ();
2268 maybe_add_fixit (start
, finish
, new_content
);
2271 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2274 rich_location::get_last_fixit_hint () const
2276 if (m_fixit_hints
.count () > 0)
2277 return get_fixit_hint (m_fixit_hints
.count () - 1);
2282 /* If WHERE is an "awkward" location, then mark this rich_location as not
2283 supporting fixits, purging any thay were already added, and return true.
2285 Otherwise (the common case), return false. */
2288 rich_location::reject_impossible_fixit (source_location where
)
2290 /* Fix-its within a rich_location should either all be suggested, or
2291 none of them should be suggested.
2292 Once we've rejected a fixit, we reject any more, even those
2293 with reasonable locations. */
2294 if (m_seen_impossible_fixit
)
2297 if (where
<= LINE_MAP_MAX_LOCATION_WITH_COLS
)
2298 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2301 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2302 location: either one that we can't obtain column information
2303 for (within an ordinary map), or one within a macro expansion. */
2304 stop_supporting_fixits ();
2308 /* Mark this rich_location as not supporting fixits, purging any that were
2312 rich_location::stop_supporting_fixits ()
2314 m_seen_impossible_fixit
= true;
2316 /* Purge the rich_location of any fix-its that were already added. */
2317 for (unsigned int i
= 0; i
< m_fixit_hints
.count (); i
++)
2318 delete get_fixit_hint (i
);
2319 m_fixit_hints
.truncate (0);
2322 /* Add HINT to the fix-it hints in this rich_location,
2323 consolidating into the prior fixit if possible. */
2326 rich_location::maybe_add_fixit (source_location start
,
2327 source_location next_loc
,
2328 const char *new_content
)
2330 if (reject_impossible_fixit (start
))
2332 if (reject_impossible_fixit (next_loc
))
2335 /* Only allow fix-it hints that affect a single line in one file.
2336 Compare the end-points. */
2337 expanded_location exploc_start
2338 = linemap_client_expand_location_to_spelling_point (start
,
2339 LOCATION_ASPECT_START
);
2340 expanded_location exploc_next_loc
2341 = linemap_client_expand_location_to_spelling_point (next_loc
,
2342 LOCATION_ASPECT_START
);
2343 /* They must be within the same file... */
2344 if (exploc_start
.file
!= exploc_next_loc
.file
)
2346 stop_supporting_fixits ();
2349 /* ...and on the same line. */
2350 if (exploc_start
.line
!= exploc_next_loc
.line
)
2352 stop_supporting_fixits ();
2356 const char *newline
= strchr (new_content
, '\n');
2359 /* For now, we can only support insertion of whole lines
2360 i.e. starts at start of line, and the newline is at the end of
2361 the insertion point. */
2363 /* It must be an insertion, not a replacement/deletion. */
2364 if (start
!= next_loc
)
2366 stop_supporting_fixits ();
2370 /* The insertion must be at the start of a line. */
2371 if (exploc_start
.column
!= 1)
2373 stop_supporting_fixits ();
2377 /* The newline must be at end of NEW_CONTENT.
2378 We could eventually split up fix-its at newlines if we wanted
2379 to allow more generality (e.g. to allow adding multiple lines
2380 with one add_fixit call. */
2381 if (newline
[1] != '\0')
2383 stop_supporting_fixits ();
2388 /* Consolidate neighboring fixits.
2389 Don't consolidate into newline-insertion fixits. */
2390 fixit_hint
*prev
= get_last_fixit_hint ();
2391 if (prev
&& !prev
->ends_with_newline_p ())
2392 if (prev
->maybe_append (start
, next_loc
, new_content
))
2395 m_fixit_hints
.push (new fixit_hint (start
, next_loc
, new_content
));
2398 /* class fixit_hint. */
2400 fixit_hint::fixit_hint (source_location start
,
2401 source_location next_loc
,
2402 const char *new_content
)
2404 m_next_loc (next_loc
),
2405 m_bytes (xstrdup (new_content
)),
2406 m_len (strlen (new_content
))
2410 /* Does this fix-it hint affect the given line? */
2413 fixit_hint::affects_line_p (const char *file
, int line
) const
2415 expanded_location exploc_start
2416 = linemap_client_expand_location_to_spelling_point (m_start
,
2417 LOCATION_ASPECT_START
);
2418 if (file
!= exploc_start
.file
)
2420 if (line
< exploc_start
.line
)
2422 expanded_location exploc_next_loc
2423 = linemap_client_expand_location_to_spelling_point (m_next_loc
,
2424 LOCATION_ASPECT_START
);
2425 if (file
!= exploc_next_loc
.file
)
2427 if (line
> exploc_next_loc
.line
)
2432 /* Method for consolidating fix-it hints, for use by
2433 rich_location::maybe_add_fixit.
2434 If possible, merge a pending fix-it hint with the given params
2435 into this one and return true.
2436 Otherwise return false. */
2439 fixit_hint::maybe_append (source_location start
,
2440 source_location next_loc
,
2441 const char *new_content
)
2443 /* For consolidation to be possible, START must be at this hint's
2445 if (start
!= m_next_loc
)
2448 /* If so, we have neighboring replacements; merge them. */
2449 m_next_loc
= next_loc
;
2450 size_t extra_len
= strlen (new_content
);
2451 m_bytes
= (char *)xrealloc (m_bytes
, m_len
+ extra_len
+ 1);
2452 memcpy (m_bytes
+ m_len
, new_content
, extra_len
);
2454 m_bytes
[m_len
] = '\0';
2458 /* Return true iff this hint's content ends with a newline. */
2461 fixit_hint::ends_with_newline_p () const
2465 return m_bytes
[m_len
- 1] == '\n';