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