1 /* Map (unsigned int) keys to (source file, line, column) triples.
2 Copyright (C) 2001-2018 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 3, or (at your option) any
7 later version.
8
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.
13
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/>.
17
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! */
21
22 #include "config.h"
23 #include "system.h"
24 #include "line-map.h"
25 #include "cpplib.h"
26 #include "internal.h"
27 #include "hashtab.h"
28
29 /* Highest possible source location encoded within an ordinary or
30 macro map. */
31 const source_location LINE_MAP_MAX_SOURCE_LOCATION = 0x70000000;
32
33 static void trace_include (const struct line_maps *, const line_map_ordinary *);
34 static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
35 source_location);
36 static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
37 source_location);
38 static source_location linemap_macro_map_loc_to_def_point
39 (const line_map_macro *, source_location);
40 static source_location linemap_macro_map_loc_to_exp_point
41 (const line_map_macro *, source_location);
42 static source_location linemap_macro_loc_to_spelling_point
43 (struct line_maps *, source_location, const line_map_ordinary **);
44 static source_location linemap_macro_loc_to_def_point (struct line_maps *,
45 source_location,
46 const line_map_ordinary **);
47 static source_location linemap_macro_loc_to_exp_point (struct line_maps *,
48 source_location,
49 const line_map_ordinary **);
50
51 /* Counters defined in macro.c. */
52 extern unsigned num_expanded_macros_counter;
53 extern unsigned num_macro_tokens_counter;
54
55 /* Destructor for class line_maps.
56 Ensure non-GC-managed memory is released. */
57
~line_maps()58 line_maps::~line_maps ()
59 {
60 if (location_adhoc_data_map.htab)
61 htab_delete (location_adhoc_data_map.htab);
62 }
63
64 /* Hash function for location_adhoc_data hashtable. */
65
66 static hashval_t
location_adhoc_data_hash(const void * l)67 location_adhoc_data_hash (const void *l)
68 {
69 const struct location_adhoc_data *lb =
70 (const struct location_adhoc_data *) l;
71 return ((hashval_t) lb->locus
72 + (hashval_t) lb->src_range.m_start
73 + (hashval_t) lb->src_range.m_finish
74 + (size_t) lb->data);
75 }
76
77 /* Compare function for location_adhoc_data hashtable. */
78
79 static int
location_adhoc_data_eq(const void * l1,const void * l2)80 location_adhoc_data_eq (const void *l1, const void *l2)
81 {
82 const struct location_adhoc_data *lb1 =
83 (const struct location_adhoc_data *) l1;
84 const struct location_adhoc_data *lb2 =
85 (const struct location_adhoc_data *) l2;
86 return (lb1->locus == lb2->locus
87 && lb1->src_range.m_start == lb2->src_range.m_start
88 && lb1->src_range.m_finish == lb2->src_range.m_finish
89 && lb1->data == lb2->data);
90 }
91
92 /* Update the hashtable when location_adhoc_data is reallocated. */
93
94 static int
location_adhoc_data_update(void ** slot,void * data)95 location_adhoc_data_update (void **slot, void *data)
96 {
97 *((char **) slot)
98 = (char *) ((uintptr_t) *((char **) slot) + *((ptrdiff_t *) data));
99 return 1;
100 }
101
102 /* Rebuild the hash table from the location adhoc data. */
103
104 void
rebuild_location_adhoc_htab(struct line_maps * set)105 rebuild_location_adhoc_htab (struct line_maps *set)
106 {
107 unsigned i;
108 set->location_adhoc_data_map.htab =
109 htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
110 for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
111 htab_find_slot (set->location_adhoc_data_map.htab,
112 set->location_adhoc_data_map.data + i, INSERT);
113 }
114
115 /* Helper function for get_combined_adhoc_loc.
116 Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
117 within a source_location, without needing to use an ad-hoc location. */
118
119 static bool
can_be_stored_compactly_p(struct line_maps * set,source_location locus,source_range src_range,void * data)120 can_be_stored_compactly_p (struct line_maps *set,
121 source_location locus,
122 source_range src_range,
123 void *data)
124 {
125 /* If there's an ad-hoc pointer, we can't store it directly in the
126 source_location, we need the lookaside. */
127 if (data)
128 return false;
129
130 /* We only store ranges that begin at the locus and that are sufficiently
131 "sane". */
132 if (src_range.m_start != locus)
133 return false;
134
135 if (src_range.m_finish < src_range.m_start)
136 return false;
137
138 if (src_range.m_start < RESERVED_LOCATION_COUNT)
139 return false;
140
141 if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
142 return false;
143
144 /* All 3 locations must be within ordinary maps, typically, the same
145 ordinary map. */
146 source_location lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
147 if (locus >= lowest_macro_loc)
148 return false;
149 if (src_range.m_start >= lowest_macro_loc)
150 return false;
151 if (src_range.m_finish >= lowest_macro_loc)
152 return false;
153
154 /* Passed all tests. */
155 return true;
156 }
157
158 /* Combine LOCUS and DATA to a combined adhoc loc. */
159
160 source_location
get_combined_adhoc_loc(struct line_maps * set,source_location locus,source_range src_range,void * data)161 get_combined_adhoc_loc (struct line_maps *set,
162 source_location locus,
163 source_range src_range,
164 void *data)
165 {
166 struct location_adhoc_data lb;
167 struct location_adhoc_data **slot;
168
169 if (IS_ADHOC_LOC (locus))
170 locus
171 = set->location_adhoc_data_map.data[locus & MAX_SOURCE_LOCATION].locus;
172 if (locus == 0 && data == NULL)
173 return 0;
174
175 /* Any ordinary locations ought to be "pure" at this point: no
176 compressed ranges. */
177 linemap_assert (locus < RESERVED_LOCATION_COUNT
178 || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
179 || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
180 || pure_location_p (set, locus));
181
182 /* Consider short-range optimization. */
183 if (can_be_stored_compactly_p (set, locus, src_range, data))
184 {
185 /* The low bits ought to be clear. */
186 linemap_assert (pure_location_p (set, locus));
187 const line_map *map = linemap_lookup (set, locus);
188 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
189 unsigned int int_diff = src_range.m_finish - src_range.m_start;
190 unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
191 if (col_diff < (1U << ordmap->m_range_bits))
192 {
193 source_location packed = locus | col_diff;
194 set->num_optimized_ranges++;
195 return packed;
196 }
197 }
198
199 /* We can also compactly store locations
200 when locus == start == finish (and data is NULL). */
201 if (locus == src_range.m_start
202 && locus == src_range.m_finish
203 && !data)
204 return locus;
205
206 if (!data)
207 set->num_unoptimized_ranges++;
208
209 lb.locus = locus;
210 lb.src_range = src_range;
211 lb.data = data;
212 slot = (struct location_adhoc_data **)
213 htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
214 if (*slot == NULL)
215 {
216 if (set->location_adhoc_data_map.curr_loc >=
217 set->location_adhoc_data_map.allocated)
218 {
219 char *orig_data = (char *) set->location_adhoc_data_map.data;
220 ptrdiff_t offset;
221 /* Cast away extern "C" from the type of xrealloc. */
222 line_map_realloc reallocator = (set->reallocator
223 ? set->reallocator
224 : (line_map_realloc) xrealloc);
225
226 if (set->location_adhoc_data_map.allocated == 0)
227 set->location_adhoc_data_map.allocated = 128;
228 else
229 set->location_adhoc_data_map.allocated *= 2;
230 set->location_adhoc_data_map.data = (struct location_adhoc_data *)
231 reallocator (set->location_adhoc_data_map.data,
232 set->location_adhoc_data_map.allocated
233 * sizeof (struct location_adhoc_data));
234 offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
235 if (set->location_adhoc_data_map.allocated > 128)
236 htab_traverse (set->location_adhoc_data_map.htab,
237 location_adhoc_data_update, &offset);
238 }
239 *slot = set->location_adhoc_data_map.data
240 + set->location_adhoc_data_map.curr_loc;
241 set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
242 = lb;
243 }
244 return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
245 }
246
247 /* Return the data for the adhoc loc. */
248
249 void *
get_data_from_adhoc_loc(struct line_maps * set,source_location loc)250 get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
251 {
252 linemap_assert (IS_ADHOC_LOC (loc));
253 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
254 }
255
256 /* Return the location for the adhoc loc. */
257
258 source_location
get_location_from_adhoc_loc(struct line_maps * set,source_location loc)259 get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
260 {
261 linemap_assert (IS_ADHOC_LOC (loc));
262 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
263 }
264
265 /* Return the source_range for adhoc location LOC. */
266
267 static source_range
get_range_from_adhoc_loc(struct line_maps * set,source_location loc)268 get_range_from_adhoc_loc (struct line_maps *set, source_location loc)
269 {
270 linemap_assert (IS_ADHOC_LOC (loc));
271 return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].src_range;
272 }
273
274 /* Get the source_range of location LOC, either from the ad-hoc
275 lookaside table, or embedded inside LOC itself. */
276
277 source_range
get_range_from_loc(struct line_maps * set,source_location loc)278 get_range_from_loc (struct line_maps *set,
279 source_location loc)
280 {
281 if (IS_ADHOC_LOC (loc))
282 return get_range_from_adhoc_loc (set, loc);
283
284 /* For ordinary maps, extract packed range. */
285 if (loc >= RESERVED_LOCATION_COUNT
286 && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
287 && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
288 {
289 const line_map *map = linemap_lookup (set, loc);
290 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
291 source_range result;
292 int offset = loc & ((1 << ordmap->m_range_bits) - 1);
293 result.m_start = loc - offset;
294 result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
295 return result;
296 }
297
298 return source_range::from_location (loc);
299 }
300
301 /* Get whether location LOC is a "pure" location, or
302 whether it is an ad-hoc location, or embeds range information. */
303
304 bool
pure_location_p(line_maps * set,source_location loc)305 pure_location_p (line_maps *set, source_location loc)
306 {
307 if (IS_ADHOC_LOC (loc))
308 return false;
309
310 const line_map *map = linemap_lookup (set, loc);
311 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
312
313 if (loc & ((1U << ordmap->m_range_bits) - 1))
314 return false;
315
316 return true;
317 }
318
319 /* Given location LOC within SET, strip away any packed range information
320 or ad-hoc information. */
321
322 source_location
get_pure_location(line_maps * set,source_location loc)323 get_pure_location (line_maps *set, source_location loc)
324 {
325 if (IS_ADHOC_LOC (loc))
326 loc
327 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
328
329 if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
330 return loc;
331
332 if (loc < RESERVED_LOCATION_COUNT)
333 return loc;
334
335 const line_map *map = linemap_lookup (set, loc);
336 const line_map_ordinary *ordmap = linemap_check_ordinary (map);
337
338 return loc & ~((1 << ordmap->m_range_bits) - 1);
339 }
340
341 /* Initialize a line map set. */
342
343 void
linemap_init(struct line_maps * set,source_location builtin_location)344 linemap_init (struct line_maps *set,
345 source_location builtin_location)
346 {
347 #if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
348 /* PR33916, needed to fix PR82939. */
349 memset (set, 0, sizeof (struct line_maps));
350 #else
351 *set = line_maps ();
352 #endif
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;
358 }
359
360 /* Check for and warn about line_maps entered but not exited. */
361
362 void
linemap_check_files_exited(struct line_maps * set)363 linemap_check_files_exited (struct line_maps *set)
364 {
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);
369 ! MAIN_FILE_P (map);
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));
373 }
374
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. */
379
380 static struct line_map *
new_linemap(struct line_maps * set,enum lc_reason reason)381 new_linemap (struct line_maps *set,
382 enum lc_reason reason)
383 {
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;
388
389 if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
390 {
391 /* We ran out of allocated line maps. Let's allocate more. */
392 size_t alloc_size;
393
394 /* Cast away extern "C" from the type of xrealloc. */
395 line_map_realloc reallocator = (set->reallocator
396 ? set->reallocator
397 : (line_map_realloc) xrealloc);
398 line_map_round_alloc_size_func round_alloc_size =
399 set->round_alloc_size;
400
401 size_t map_size = (macro_map_p
402 ? sizeof (line_map_macro)
403 : sizeof (line_map_ordinary));
404
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
407 ggc-page.c one.
408
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. */
412
413 alloc_size =
414 (2 * LINEMAPS_ALLOCATED (set, macro_map_p) + 256)
415 * map_size;
416
417 /* Get the actual size of memory that is going to be allocated
418 by the allocator. */
419 alloc_size = round_alloc_size (alloc_size);
420
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
424 to. */
425 LINEMAPS_ALLOCATED (set, macro_map_p) =
426 alloc_size / map_size;
427
428 /* And now let's really do the re-allocation. */
429 if (macro_map_p)
430 {
431 set->info_macro.maps
432 = (line_map_macro *) (*reallocator) (set->info_macro.maps,
433 (LINEMAPS_ALLOCATED (set, macro_map_p)
434 * map_size));
435 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
436 }
437 else
438 {
439 set->info_ordinary.maps =
440 (line_map_ordinary *) (*reallocator) (set->info_ordinary.maps,
441 (LINEMAPS_ALLOCATED (set, macro_map_p)
442 * map_size));
443 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
444 }
445 memset (result, 0,
446 ((LINEMAPS_ALLOCATED (set, macro_map_p)
447 - LINEMAPS_USED (set, macro_map_p))
448 * map_size));
449 }
450 else
451 {
452 if (macro_map_p)
453 result = &set->info_macro.maps[LINEMAPS_USED (set, macro_map_p)];
454 else
455 result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
456 }
457
458 LINEMAPS_USED (set, macro_map_p)++;
459
460 result->reason = reason;
461 return result;
462 }
463
464 /* Add a mapping of logical source line to physical source file and
465 line number.
466
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.
472
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. */
476
477 const struct line_map *
linemap_add(struct line_maps * set,enum lc_reason reason,unsigned int sysp,const char * to_file,linenum_type to_line)478 linemap_add (struct line_maps *set, enum lc_reason reason,
479 unsigned int sysp, const char *to_file, linenum_type to_line)
480 {
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)
485 {
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)));
491 }
492 else
493 start_location = set->highest_location + 1;
494
495 linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
496 && (start_location
497 < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));
498
499 /* When we enter the file for the first time reason cannot be
500 LC_RENAME. */
501 linemap_assert (!(set->depth == 0 && reason == LC_RENAME));
502
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))
506 && to_file == NULL)
507 {
508 set->depth--;
509 return NULL;
510 }
511
512 linemap_assert (reason != LC_ENTER_MACRO);
513 line_map_ordinary *map = linemap_check_ordinary (new_linemap (set, reason));
514
515 if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
516 to_file = "<stdin>";
517
518 if (reason == LC_RENAME_VERBATIM)
519 reason = LC_RENAME;
520
521 if (reason == LC_LEAVE)
522 {
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;
528
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);
534
535 /* A TO_FILE of NULL is special - we use the natural values. */
536 if (to_file == NULL)
537 {
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);
541 }
542 else
543 linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
544 to_file) == 0);
545 }
546
547 map->sysp = sysp;
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;
557
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
561 pure_location_p. */
562 linemap_assert (pure_location_p (set, start_location));
563
564 if (reason == LC_ENTER)
565 {
566 map->included_from =
567 set->depth == 0 ? -1 : (int) (LINEMAPS_ORDINARY_USED (set) - 2);
568 set->depth++;
569 if (set->trace_includes)
570 trace_include (set, map);
571 }
572 else if (reason == LC_RENAME)
573 map->included_from = ORDINARY_MAP_INCLUDER_FILE_INDEX (&map[-1]);
574 else if (reason == LC_LEAVE)
575 {
576 set->depth--;
577 map->included_from =
578 ORDINARY_MAP_INCLUDER_FILE_INDEX (INCLUDED_FROM (set, map - 1));
579 }
580
581 return map;
582 }
583
584 /* Returns TRUE if the line table set tracks token locations across
585 macro expansion, FALSE otherwise. */
586
587 bool
linemap_tracks_macro_expansion_locs_p(struct line_maps * set)588 linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
589 {
590 return LINEMAPS_MACRO_MAPS (set) != NULL;
591 }
592
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.
597
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.
610
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. */
615
616 const line_map_macro *
linemap_enter_macro(struct line_maps * set,struct cpp_hashnode * macro_node,source_location expansion,unsigned int num_tokens)617 linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
618 source_location expansion, unsigned int num_tokens)
619 {
620 line_map_macro *map;
621 source_location start_location;
622 /* Cast away extern "C" from the type of xrealloc. */
623 line_map_realloc reallocator = (set->reallocator
624 ? set->reallocator
625 : (line_map_realloc) xrealloc);
626
627 start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
628
629 if (start_location <= set->highest_line
630 || start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
631 /* We ran out of macro map space. */
632 return NULL;
633
634 map = linemap_check_macro (new_linemap (set, LC_ENTER_MACRO));
635
636 map->start_location = start_location;
637 map->macro = macro_node;
638 map->n_tokens = num_tokens;
639 map->macro_locations
640 = (source_location*) reallocator (NULL,
641 2 * num_tokens
642 * sizeof (source_location));
643 map->expansion = expansion;
644 memset (MACRO_MAP_LOCATIONS (map), 0,
645 num_tokens * sizeof (source_location));
646
647 LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;
648
649 return map;
650 }
651
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
655 is.
656
657 A call to this function must come after a call to
658 linemap_enter_macro.
659
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
662 at number 0.
663
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).
670
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
673 replaces. */
674
675 source_location
linemap_add_macro_token(const line_map_macro * map,unsigned int token_no,source_location orig_loc,source_location orig_parm_replacement_loc)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)
680 {
681 source_location result;
682
683 linemap_assert (linemap_macro_expansion_map_p (map));
684 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
685
686 MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
687 MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;
688
689 result = MAP_START_LOCATION (map) + token_no;
690 return result;
691 }
692
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). */
698
699 source_location
linemap_line_start(struct line_maps * set,linenum_type to_line,unsigned int max_column_hint)700 linemap_line_start (struct line_maps *set, linenum_type to_line,
701 unsigned int max_column_hint)
702 {
703 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
704 source_location highest = set->highest_location;
705 source_location r;
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;
712
713 if (line_delta < 0
714 || (line_delta > 10
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)))
722 add_map = true;
723 else
724 max_column_hint = set->max_column_hint;
725 if (add_map)
726 {
727 int column_bits;
728 int range_bits;
729 if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
730 || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
731 {
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). */
735 max_column_hint = 0;
736 column_bits = 0;
737 range_bits = 0;
738 if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
739 return 0;
740 }
741 else
742 {
743 column_bits = 7;
744 if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
745 range_bits = set->default_range_bits;
746 else
747 range_bits = 0;
748 while (max_column_hint >= (1U << column_bits))
749 column_bits++;
750 max_column_hint = 1U << column_bits;
751 column_bits += range_bits;
752 }
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. */
755 if (line_delta < 0
756 || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
757 || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
758 || ( /* We can't reuse the map if the line offset is sufficiently
759 large to cause overflow when computing location_t values. */
760 (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
761 >= (((uint64_t) 1)
762 << (CHAR_BIT * sizeof (linenum_type) - column_bits)))
763 || range_bits < map->m_range_bits)
764 map = linemap_check_ordinary
765 (const_cast <line_map *>
766 (linemap_add (set, LC_RENAME,
767 ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
768 ORDINARY_MAP_FILE_NAME (map),
769 to_line)));
770 map->m_column_and_range_bits = column_bits;
771 map->m_range_bits = range_bits;
772 r = (MAP_START_LOCATION (map)
773 + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
774 << column_bits));
775 }
776 else
777 r = set->highest_line + (line_delta << map->m_column_and_range_bits);
778
779 /* Locations of ordinary tokens are always lower than locations of
780 macro tokens. */
781 if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
782 return 0;
783
784 set->highest_line = r;
785 if (r > set->highest_location)
786 set->highest_location = r;
787 set->max_column_hint = max_column_hint;
788
789 /* At this point, we expect one of:
790 (a) the normal case: a "pure" location with 0 range bits, or
791 (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
792 columns anymore (or ranges), or
793 (c) we're in a region with a column hint exceeding
794 LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
795 with column_bits == 0. */
796 linemap_assert (pure_location_p (set, r)
797 || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
798 || map->m_column_and_range_bits == 0);
799 linemap_assert (SOURCE_LINE (map, r) == to_line);
800 return r;
801 }
802
803 /* Encode and return a source_location from a column number. The
804 source line considered is the last source line used to call
805 linemap_line_start, i.e, the last source line which a location was
806 encoded from. */
807
808 source_location
linemap_position_for_column(struct line_maps * set,unsigned int to_column)809 linemap_position_for_column (struct line_maps *set, unsigned int to_column)
810 {
811 source_location r = set->highest_line;
812
813 linemap_assert
814 (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));
815
816 if (to_column >= set->max_column_hint)
817 {
818 if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
819 || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
820 {
821 /* Running low on source_locations - disable column numbers. */
822 return r;
823 }
824 else
825 {
826 /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
827 with some space to spare. This may or may not lead to a new
828 linemap being created. */
829 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
830 r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
831 map = LINEMAPS_LAST_ORDINARY_MAP (set);
832 if (map->m_column_and_range_bits == 0)
833 {
834 /* ...then the linemap has column-tracking disabled,
835 presumably due to exceeding either
836 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
837 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
838 Return the start of the linemap, which encodes column 0, for
839 the whole line. */
840 return r;
841 }
842 }
843 }
844 line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
845 r = r + (to_column << map->m_range_bits);
846 if (r >= set->highest_location)
847 set->highest_location = r;
848 return r;
849 }
850
851 /* Encode and return a source location from a given line and
852 column. */
853
854 source_location
linemap_position_for_line_and_column(line_maps * set,const line_map_ordinary * ord_map,linenum_type line,unsigned column)855 linemap_position_for_line_and_column (line_maps *set,
856 const line_map_ordinary *ord_map,
857 linenum_type line,
858 unsigned column)
859 {
860 linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
861
862 source_location r = MAP_START_LOCATION (ord_map);
863 r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
864 << ord_map->m_column_and_range_bits);
865 if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
866 r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
867 << ord_map->m_range_bits);
868 source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
869 if (r >= upper_limit)
870 r = upper_limit - 1;
871 if (r > set->highest_location)
872 set->highest_location = r;
873 return r;
874 }
875
876 /* Encode and return a source_location starting from location LOC and
877 shifting it by COLUMN_OFFSET columns. This function does not support
878 virtual locations. */
879
880 source_location
linemap_position_for_loc_and_offset(struct line_maps * set,source_location loc,unsigned int column_offset)881 linemap_position_for_loc_and_offset (struct line_maps *set,
882 source_location loc,
883 unsigned int column_offset)
884 {
885 const line_map_ordinary * map = NULL;
886
887 if (IS_ADHOC_LOC (loc))
888 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
889
890 /* This function does not support virtual locations yet. */
891 if (linemap_location_from_macro_expansion_p (set, loc))
892 return loc;
893
894 if (column_offset == 0
895 /* Adding an offset to a reserved location (like
896 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
897 sense. So let's leave the location intact in that case. */
898 || loc < RESERVED_LOCATION_COUNT)
899 return loc;
900
901 /* We find the real location and shift it. */
902 loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
903 /* The new location (loc + offset) should be higher than the first
904 location encoded by MAP. This can fail if the line information
905 is messed up because of line directives (see PR66415). */
906 if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
907 return loc;
908
909 linenum_type line = SOURCE_LINE (map, loc);
910 unsigned int column = SOURCE_COLUMN (map, loc);
911
912 /* If MAP is not the last line map of its set, then the new location
913 (loc + offset) should be less than the first location encoded by
914 the next line map of the set. Otherwise, we try to encode the
915 location in the next map. */
916 while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
917 && (loc + (column_offset << map->m_range_bits)
918 >= MAP_START_LOCATION (&map[1])))
919 {
920 map = &map[1];
921 /* If the next map starts in a higher line, we cannot encode the
922 location there. */
923 if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
924 return loc;
925 }
926
927 column += column_offset;
928
929 /* Bail out if the column is not representable within the existing
930 linemap. */
931 if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
932 return loc;
933
934 source_location r =
935 linemap_position_for_line_and_column (set, map, line, column);
936 if (linemap_assert_fails (r <= set->highest_location)
937 || linemap_assert_fails (map == linemap_lookup (set, r)))
938 return loc;
939
940 return r;
941 }
942
943 /* Given a virtual source location yielded by a map (either an
944 ordinary or a macro map), returns that map. */
945
946 const struct line_map*
linemap_lookup(struct line_maps * set,source_location line)947 linemap_lookup (struct line_maps *set, source_location line)
948 {
949 if (IS_ADHOC_LOC (line))
950 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
951 if (linemap_location_from_macro_expansion_p (set, line))
952 return linemap_macro_map_lookup (set, line);
953 return linemap_ordinary_map_lookup (set, line);
954 }
955
956 /* Given a source location yielded by an ordinary map, returns that
957 map. Since the set is built chronologically, the logical lines are
958 monotonic increasing, and so the list is sorted and we can use a
959 binary search. */
960
961 static const line_map_ordinary *
linemap_ordinary_map_lookup(struct line_maps * set,source_location line)962 linemap_ordinary_map_lookup (struct line_maps *set, source_location line)
963 {
964 unsigned int md, mn, mx;
965 const line_map_ordinary *cached, *result;
966
967 if (IS_ADHOC_LOC (line))
968 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
969
970 if (set == NULL || line < RESERVED_LOCATION_COUNT)
971 return NULL;
972
973 mn = LINEMAPS_ORDINARY_CACHE (set);
974 mx = LINEMAPS_ORDINARY_USED (set);
975
976 cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
977 /* We should get a segfault if no line_maps have been added yet. */
978 if (line >= MAP_START_LOCATION (cached))
979 {
980 if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
981 return cached;
982 }
983 else
984 {
985 mx = mn;
986 mn = 0;
987 }
988
989 while (mx - mn > 1)
990 {
991 md = (mn + mx) / 2;
992 if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
993 mx = md;
994 else
995 mn = md;
996 }
997
998 LINEMAPS_ORDINARY_CACHE (set) = mn;
999 result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
1000 linemap_assert (line >= MAP_START_LOCATION (result));
1001 return result;
1002 }
1003
1004 /* Given a source location yielded by a macro map, returns that map.
1005 Since the set is built chronologically, the logical lines are
1006 monotonic decreasing, and so the list is sorted and we can use a
1007 binary search. */
1008
1009 static const line_map_macro *
linemap_macro_map_lookup(struct line_maps * set,source_location line)1010 linemap_macro_map_lookup (struct line_maps *set, source_location line)
1011 {
1012 unsigned int md, mn, mx;
1013 const struct line_map_macro *cached, *result;
1014
1015 if (IS_ADHOC_LOC (line))
1016 line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
1017
1018 linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
1019
1020 if (set == NULL)
1021 return NULL;
1022
1023 mn = LINEMAPS_MACRO_CACHE (set);
1024 mx = LINEMAPS_MACRO_USED (set);
1025 cached = LINEMAPS_MACRO_MAP_AT (set, mn);
1026
1027 if (line >= MAP_START_LOCATION (cached))
1028 {
1029 if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
1030 return cached;
1031 mx = mn - 1;
1032 mn = 0;
1033 }
1034
1035 while (mn < mx)
1036 {
1037 md = (mx + mn) / 2;
1038 if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
1039 mn = md + 1;
1040 else
1041 mx = md;
1042 }
1043
1044 LINEMAPS_MACRO_CACHE (set) = mx;
1045 result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
1046 linemap_assert (MAP_START_LOCATION (result) <= line);
1047
1048 return result;
1049 }
1050
1051 /* Return TRUE if MAP encodes locations coming from a macro
1052 replacement-list at macro expansion point. */
1053
1054 bool
linemap_macro_expansion_map_p(const struct line_map * map)1055 linemap_macro_expansion_map_p (const struct line_map *map)
1056 {
1057 if (!map)
1058 return false;
1059 return (map->reason == LC_ENTER_MACRO);
1060 }
1061
1062 /* If LOCATION is the locus of a token in a replacement-list of a
1063 macro expansion return the location of the macro expansion point.
1064
1065 Read the comments of struct line_map and struct line_map_macro in
1066 line-map.h to understand what a macro expansion point is. */
1067
1068 static source_location
linemap_macro_map_loc_to_exp_point(const line_map_macro * map,source_location location ATTRIBUTE_UNUSED)1069 linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
1070 source_location location ATTRIBUTE_UNUSED)
1071 {
1072 linemap_assert (linemap_macro_expansion_map_p (map)
1073 && location >= MAP_START_LOCATION (map));
1074
1075 /* Make sure LOCATION is correct. */
1076 linemap_assert ((location - MAP_START_LOCATION (map))
1077 < MACRO_MAP_NUM_MACRO_TOKENS (map));
1078
1079 return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
1080 }
1081
1082 /* LOCATION is the source location of a token that belongs to a macro
1083 replacement-list as part of the macro expansion denoted by MAP.
1084
1085 Return the location of the token at the definition point of the
1086 macro. */
1087
1088 static source_location
linemap_macro_map_loc_to_def_point(const line_map_macro * map,source_location location)1089 linemap_macro_map_loc_to_def_point (const line_map_macro *map,
1090 source_location location)
1091 {
1092 unsigned token_no;
1093
1094 linemap_assert (linemap_macro_expansion_map_p (map)
1095 && location >= MAP_START_LOCATION (map));
1096 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1097
1098 token_no = location - MAP_START_LOCATION (map);
1099 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1100
1101 location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];
1102
1103 return location;
1104 }
1105
1106 /* If LOCATION is the locus of a token that is an argument of a
1107 function-like macro M and appears in the expansion of M, return the
1108 locus of that argument in the context of the caller of M.
1109
1110 In other words, this returns the xI location presented in the
1111 comments of line_map_macro above. */
1112 source_location
linemap_macro_map_loc_unwind_toward_spelling(line_maps * set,const line_map_macro * map,source_location location)1113 linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
1114 const line_map_macro* map,
1115 source_location location)
1116 {
1117 unsigned token_no;
1118
1119 if (IS_ADHOC_LOC (location))
1120 location = get_location_from_adhoc_loc (set, location);
1121
1122 linemap_assert (linemap_macro_expansion_map_p (map)
1123 && location >= MAP_START_LOCATION (map));
1124 linemap_assert (location >= RESERVED_LOCATION_COUNT);
1125 linemap_assert (!IS_ADHOC_LOC (location));
1126
1127 token_no = location - MAP_START_LOCATION (map);
1128 linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));
1129
1130 location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
1131
1132 return location;
1133 }
1134
1135 /* Return the source line number corresponding to source location
1136 LOCATION. SET is the line map set LOCATION comes from. If
1137 LOCATION is the source location of token that is part of the
1138 replacement-list of a macro expansion return the line number of the
1139 macro expansion point. */
1140
1141 int
linemap_get_expansion_line(struct line_maps * set,source_location location)1142 linemap_get_expansion_line (struct line_maps *set,
1143 source_location location)
1144 {
1145 const line_map_ordinary *map = NULL;
1146
1147 if (IS_ADHOC_LOC (location))
1148 location = set->location_adhoc_data_map.data[location
1149 & MAX_SOURCE_LOCATION].locus;
1150
1151 if (location < RESERVED_LOCATION_COUNT)
1152 return 0;
1153
1154 location =
1155 linemap_macro_loc_to_exp_point (set, location, &map);
1156
1157 return SOURCE_LINE (map, location);
1158 }
1159
1160 /* Return the path of the file corresponding to source code location
1161 LOCATION.
1162
1163 If LOCATION is the source location of token that is part of the
1164 replacement-list of a macro expansion return the file path of the
1165 macro expansion point.
1166
1167 SET is the line map set LOCATION comes from. */
1168
1169 const char*
linemap_get_expansion_filename(struct line_maps * set,source_location location)1170 linemap_get_expansion_filename (struct line_maps *set,
1171 source_location location)
1172 {
1173 const struct line_map_ordinary *map = NULL;
1174
1175 if (IS_ADHOC_LOC (location))
1176 location = set->location_adhoc_data_map.data[location
1177 & MAX_SOURCE_LOCATION].locus;
1178
1179 if (location < RESERVED_LOCATION_COUNT)
1180 return NULL;
1181
1182 location =
1183 linemap_macro_loc_to_exp_point (set, location, &map);
1184
1185 return LINEMAP_FILE (map);
1186 }
1187
1188 /* Return the name of the macro associated to MACRO_MAP. */
1189
1190 const char*
linemap_map_get_macro_name(const line_map_macro * macro_map)1191 linemap_map_get_macro_name (const line_map_macro *macro_map)
1192 {
1193 linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
1194 return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
1195 }
1196
1197 /* Return a positive value if LOCATION is the locus of a token that is
1198 located in a system header, O otherwise. It returns 1 if LOCATION
1199 is the locus of a token that is located in a system header, and 2
1200 if LOCATION is the locus of a token located in a C system header
1201 that therefore needs to be extern "C" protected in C++.
1202
1203 Note that this function returns 1 if LOCATION belongs to a token
1204 that is part of a macro replacement-list defined in a system
1205 header, but expanded in a non-system file. */
1206
1207 int
linemap_location_in_system_header_p(struct line_maps * set,source_location location)1208 linemap_location_in_system_header_p (struct line_maps *set,
1209 source_location location)
1210 {
1211 const struct line_map *map = NULL;
1212
1213 if (IS_ADHOC_LOC (location))
1214 location = set->location_adhoc_data_map.data[location
1215 & MAX_SOURCE_LOCATION].locus;
1216
1217 if (location < RESERVED_LOCATION_COUNT)
1218 return false;
1219
1220 /* Let's look at where the token for LOCATION comes from. */
1221 while (true)
1222 {
1223 map = linemap_lookup (set, location);
1224 if (map != NULL)
1225 {
1226 if (!linemap_macro_expansion_map_p (map))
1227 /* It's a normal token. */
1228 return LINEMAP_SYSP (linemap_check_ordinary (map));
1229 else
1230 {
1231 const line_map_macro *macro_map = linemap_check_macro (map);
1232
1233 /* It's a token resulting from a macro expansion. */
1234 source_location loc =
1235 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
1236 if (loc < RESERVED_LOCATION_COUNT)
1237 /* This token might come from a built-in macro. Let's
1238 look at where that macro got expanded. */
1239 location = linemap_macro_map_loc_to_exp_point (macro_map, location);
1240 else
1241 location = loc;
1242 }
1243 }
1244 else
1245 break;
1246 }
1247 return false;
1248 }
1249
1250 /* Return TRUE if LOCATION is a source code location of a token that is part of
1251 a macro expansion, FALSE otherwise. */
1252
1253 bool
linemap_location_from_macro_expansion_p(const struct line_maps * set,source_location location)1254 linemap_location_from_macro_expansion_p (const struct line_maps *set,
1255 source_location location)
1256 {
1257 if (IS_ADHOC_LOC (location))
1258 location = set->location_adhoc_data_map.data[location
1259 & MAX_SOURCE_LOCATION].locus;
1260
1261 linemap_assert (location <= MAX_SOURCE_LOCATION
1262 && (set->highest_location
1263 < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
1264 if (set == NULL)
1265 return false;
1266 return (location > set->highest_location);
1267 }
1268
1269 /* Given two virtual locations *LOC0 and *LOC1, return the first
1270 common macro map in their macro expansion histories. Return NULL
1271 if no common macro was found. *LOC0 (resp. *LOC1) is set to the
1272 virtual location of the token inside the resulting macro. */
1273
1274 static const struct line_map*
first_map_in_common_1(struct line_maps * set,source_location * loc0,source_location * loc1)1275 first_map_in_common_1 (struct line_maps *set,
1276 source_location *loc0,
1277 source_location *loc1)
1278 {
1279 source_location l0 = *loc0, l1 = *loc1;
1280 const struct line_map *map0 = linemap_lookup (set, l0),
1281 *map1 = linemap_lookup (set, l1);
1282
1283 while (linemap_macro_expansion_map_p (map0)
1284 && linemap_macro_expansion_map_p (map1)
1285 && (map0 != map1))
1286 {
1287 if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
1288 {
1289 l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
1290 l0);
1291 map0 = linemap_lookup (set, l0);
1292 }
1293 else
1294 {
1295 l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
1296 l1);
1297 map1 = linemap_lookup (set, l1);
1298 }
1299 }
1300
1301 if (map0 == map1)
1302 {
1303 *loc0 = l0;
1304 *loc1 = l1;
1305 return map0;
1306 }
1307 return NULL;
1308 }
1309
1310 /* Given two virtual locations LOC0 and LOC1, return the first common
1311 macro map in their macro expansion histories. Return NULL if no
1312 common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the
1313 virtual location of the token inside the resulting macro, upon
1314 return of a non-NULL result. */
1315
1316 static const struct line_map*
first_map_in_common(struct line_maps * set,source_location loc0,source_location loc1,source_location * res_loc0,source_location * res_loc1)1317 first_map_in_common (struct line_maps *set,
1318 source_location loc0,
1319 source_location loc1,
1320 source_location *res_loc0,
1321 source_location *res_loc1)
1322 {
1323 *res_loc0 = loc0;
1324 *res_loc1 = loc1;
1325
1326 return first_map_in_common_1 (set, res_loc0, res_loc1);
1327 }
1328
1329 /* Return a positive value if PRE denotes the location of a token that
1330 comes before the token of POST, 0 if PRE denotes the location of
1331 the same token as the token for POST, and a negative value
1332 otherwise. */
1333
1334 int
linemap_compare_locations(struct line_maps * set,source_location pre,source_location post)1335 linemap_compare_locations (struct line_maps *set,
1336 source_location pre,
1337 source_location post)
1338 {
1339 bool pre_virtual_p, post_virtual_p;
1340 source_location l0 = pre, l1 = post;
1341
1342 if (IS_ADHOC_LOC (l0))
1343 l0 = get_location_from_adhoc_loc (set, l0);
1344 if (IS_ADHOC_LOC (l1))
1345 l1 = get_location_from_adhoc_loc (set, l1);
1346
1347 if (l0 == l1)
1348 return 0;
1349
1350 if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
1351 l0 = linemap_resolve_location (set, l0,
1352 LRK_MACRO_EXPANSION_POINT,
1353 NULL);
1354
1355 if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
1356 l1 = linemap_resolve_location (set, l1,
1357 LRK_MACRO_EXPANSION_POINT,
1358 NULL);
1359
1360 if (l0 == l1
1361 && pre_virtual_p
1362 && post_virtual_p)
1363 {
1364 /* So pre and post represent two tokens that are present in a
1365 same macro expansion. Let's see if the token for pre was
1366 before the token for post in that expansion. */
1367 unsigned i0, i1;
1368 const struct line_map *map =
1369 first_map_in_common (set, pre, post, &l0, &l1);
1370
1371 if (map == NULL)
1372 /* This should not be possible. */
1373 abort ();
1374
1375 i0 = l0 - MAP_START_LOCATION (map);
1376 i1 = l1 - MAP_START_LOCATION (map);
1377 return i1 - i0;
1378 }
1379
1380 if (IS_ADHOC_LOC (l0))
1381 l0 = get_location_from_adhoc_loc (set, l0);
1382 if (IS_ADHOC_LOC (l1))
1383 l1 = get_location_from_adhoc_loc (set, l1);
1384
1385 return l1 - l0;
1386 }
1387
1388 /* Print an include trace, for e.g. the -H option of the preprocessor. */
1389
1390 static void
trace_include(const struct line_maps * set,const line_map_ordinary * map)1391 trace_include (const struct line_maps *set, const line_map_ordinary *map)
1392 {
1393 unsigned int i = set->depth;
1394
1395 while (--i)
1396 putc ('.', stderr);
1397
1398 fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
1399 }
1400
1401 /* Return the spelling location of the token wherever it comes from,
1402 whether part of a macro definition or not.
1403
1404 This is a subroutine for linemap_resolve_location. */
1405
1406 static source_location
linemap_macro_loc_to_spelling_point(struct line_maps * set,source_location location,const line_map_ordinary ** original_map)1407 linemap_macro_loc_to_spelling_point (struct line_maps *set,
1408 source_location location,
1409 const line_map_ordinary **original_map)
1410 {
1411 struct line_map *map;
1412 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1413
1414 while (true)
1415 {
1416 map = const_cast <line_map *> (linemap_lookup (set, location));
1417 if (!linemap_macro_expansion_map_p (map))
1418 break;
1419
1420 location
1421 = linemap_macro_map_loc_unwind_toward_spelling
1422 (set, linemap_check_macro (map),
1423 location);
1424 }
1425
1426 if (original_map)
1427 *original_map = linemap_check_ordinary (map);
1428 return location;
1429 }
1430
1431 /* If LOCATION is the source location of a token that belongs to a
1432 macro replacement-list -- as part of a macro expansion -- then
1433 return the location of the token at the definition point of the
1434 macro. Otherwise, return LOCATION. SET is the set of maps
1435 location come from. ORIGINAL_MAP is an output parm. If non NULL,
1436 the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
1437 returned location comes from.
1438
1439 This is a subroutine of linemap_resolve_location. */
1440
1441 static source_location
linemap_macro_loc_to_def_point(struct line_maps * set,source_location location,const line_map_ordinary ** original_map)1442 linemap_macro_loc_to_def_point (struct line_maps *set,
1443 source_location location,
1444 const line_map_ordinary **original_map)
1445 {
1446 struct line_map *map;
1447
1448 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1449
1450 while (true)
1451 {
1452 source_location caret_loc;
1453 if (IS_ADHOC_LOC (location))
1454 caret_loc = get_location_from_adhoc_loc (set, location);
1455 else
1456 caret_loc = location;
1457
1458 map = const_cast <line_map *> (linemap_lookup (set, caret_loc));
1459 if (!linemap_macro_expansion_map_p (map))
1460 break;
1461
1462 location =
1463 linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
1464 caret_loc);
1465 }
1466
1467 if (original_map)
1468 *original_map = linemap_check_ordinary (map);
1469 return location;
1470 }
1471
1472 /* If LOCATION is the source location of a token that belongs to a
1473 macro replacement-list -- at a macro expansion point -- then return
1474 the location of the topmost expansion point of the macro. We say
1475 topmost because if we are in the context of a nested macro
1476 expansion, the function returns the source location of the first
1477 macro expansion that triggered the nested expansions.
1478
1479 Otherwise, return LOCATION. SET is the set of maps location come
1480 from. ORIGINAL_MAP is an output parm. If non NULL, the function
1481 sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
1482 location comes from.
1483
1484 This is a subroutine of linemap_resolve_location. */
1485
1486 static source_location
linemap_macro_loc_to_exp_point(struct line_maps * set,source_location location,const line_map_ordinary ** original_map)1487 linemap_macro_loc_to_exp_point (struct line_maps *set,
1488 source_location location,
1489 const line_map_ordinary **original_map)
1490 {
1491 struct line_map *map;
1492
1493 if (IS_ADHOC_LOC (location))
1494 location = set->location_adhoc_data_map.data[location
1495 & MAX_SOURCE_LOCATION].locus;
1496
1497 linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
1498
1499 while (true)
1500 {
1501 map = const_cast <line_map *> (linemap_lookup (set, location));
1502 if (!linemap_macro_expansion_map_p (map))
1503 break;
1504 location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
1505 location);
1506 }
1507
1508 if (original_map)
1509 *original_map = linemap_check_ordinary (map);
1510 return location;
1511 }
1512
1513 /* Resolve a virtual location into either a spelling location, an
1514 expansion point location or a token argument replacement point
1515 location. Return the map that encodes the virtual location as well
1516 as the resolved location.
1517
1518 If LOC is *NOT* the location of a token resulting from the
1519 expansion of a macro, then the parameter LRK (which stands for
1520 Location Resolution Kind) is ignored and the resulting location
1521 just equals the one given in argument.
1522
1523 Now if LOC *IS* the location of a token resulting from the
1524 expansion of a macro, this is what happens.
1525
1526 * If LRK is set to LRK_MACRO_EXPANSION_POINT
1527 -------------------------------
1528
1529 The virtual location is resolved to the first macro expansion point
1530 that led to this macro expansion.
1531
1532 * If LRK is set to LRK_SPELLING_LOCATION
1533 -------------------------------------
1534
1535 The virtual location is resolved to the locus where the token has
1536 been spelled in the source. This can follow through all the macro
1537 expansions that led to the token.
1538
1539 * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
1540 --------------------------------------
1541
1542 The virtual location is resolved to the locus of the token in the
1543 context of the macro definition.
1544
1545 If LOC is the locus of a token that is an argument of a
1546 function-like macro [replacing a parameter in the replacement list
1547 of the macro] the virtual location is resolved to the locus of the
1548 parameter that is replaced, in the context of the definition of the
1549 macro.
1550
1551 If LOC is the locus of a token that is not an argument of a
1552 function-like macro, then the function behaves as if LRK was set to
1553 LRK_SPELLING_LOCATION.
1554
1555 If MAP is not NULL, *MAP is set to the map encoding the
1556 returned location. Note that if the returned location wasn't originally
1557 encoded by a map, then *MAP is set to NULL. This can happen if LOC
1558 resolves to a location reserved for the client code, like
1559 UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
1560
1561 source_location
linemap_resolve_location(struct line_maps * set,source_location loc,enum location_resolution_kind lrk,const line_map_ordinary ** map)1562 linemap_resolve_location (struct line_maps *set,
1563 source_location loc,
1564 enum location_resolution_kind lrk,
1565 const line_map_ordinary **map)
1566 {
1567 source_location locus = loc;
1568 if (IS_ADHOC_LOC (loc))
1569 locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1570
1571 if (locus < RESERVED_LOCATION_COUNT)
1572 {
1573 /* A reserved location wasn't encoded in a map. Let's return a
1574 NULL map here, just like what linemap_ordinary_map_lookup
1575 does. */
1576 if (map)
1577 *map = NULL;
1578 return loc;
1579 }
1580
1581 switch (lrk)
1582 {
1583 case LRK_MACRO_EXPANSION_POINT:
1584 loc = linemap_macro_loc_to_exp_point (set, loc, map);
1585 break;
1586 case LRK_SPELLING_LOCATION:
1587 loc = linemap_macro_loc_to_spelling_point (set, loc, map);
1588 break;
1589 case LRK_MACRO_DEFINITION_LOCATION:
1590 loc = linemap_macro_loc_to_def_point (set, loc, map);
1591 break;
1592 default:
1593 abort ();
1594 }
1595 return loc;
1596 }
1597
1598 /* TRUE if LOCATION is a source code location of a token that is part of the
1599 definition of a macro, FALSE otherwise. */
1600
1601 bool
linemap_location_from_macro_definition_p(struct line_maps * set,source_location loc)1602 linemap_location_from_macro_definition_p (struct line_maps *set,
1603 source_location loc)
1604 {
1605 if (IS_ADHOC_LOC (loc))
1606 loc = get_location_from_adhoc_loc (set, loc);
1607
1608 if (!linemap_location_from_macro_expansion_p (set, loc))
1609 return false;
1610
1611 while (true)
1612 {
1613 const struct line_map_macro *map
1614 = linemap_check_macro (linemap_lookup (set, loc));
1615
1616 source_location s_loc
1617 = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
1618 if (linemap_location_from_macro_expansion_p (set, s_loc))
1619 loc = s_loc;
1620 else
1621 {
1622 source_location def_loc
1623 = linemap_macro_map_loc_to_def_point (map, loc);
1624 return s_loc == def_loc;
1625 }
1626 }
1627 }
1628
1629 /*
1630 Suppose that LOC is the virtual location of a token T coming from
1631 the expansion of a macro M. This function then steps up to get the
1632 location L of the point where M got expanded. If L is a spelling
1633 location inside a macro expansion M', then this function returns
1634 the locus of the point where M' was expanded. Said otherwise, this
1635 function returns the location of T in the context that triggered
1636 the expansion of M.
1637
1638 *LOC_MAP must be set to the map of LOC. This function then sets it
1639 to the map of the returned location. */
1640
1641 source_location
linemap_unwind_toward_expansion(struct line_maps * set,source_location loc,const struct line_map ** map)1642 linemap_unwind_toward_expansion (struct line_maps *set,
1643 source_location loc,
1644 const struct line_map **map)
1645 {
1646 source_location resolved_location;
1647 const line_map_macro *macro_map = linemap_check_macro (*map);
1648 const struct line_map *resolved_map;
1649
1650 if (IS_ADHOC_LOC (loc))
1651 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1652
1653 resolved_location =
1654 linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
1655 resolved_map = linemap_lookup (set, resolved_location);
1656
1657 if (!linemap_macro_expansion_map_p (resolved_map))
1658 {
1659 resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
1660 resolved_map = linemap_lookup (set, resolved_location);
1661 }
1662
1663 *map = resolved_map;
1664 return resolved_location;
1665 }
1666
1667 /* If LOC is the virtual location of a token coming from the expansion
1668 of a macro M and if its spelling location is reserved (e.g, a
1669 location for a built-in token), then this function unwinds (using
1670 linemap_unwind_toward_expansion) the location until a location that
1671 is not reserved and is not in a system header is reached. In other
1672 words, this unwinds the reserved location until a location that is
1673 in real source code is reached.
1674
1675 Otherwise, if the spelling location for LOC is not reserved or if
1676 LOC doesn't come from the expansion of a macro, the function
1677 returns LOC as is and *MAP is not touched.
1678
1679 *MAP is set to the map of the returned location if the later is
1680 different from LOC. */
1681 source_location
linemap_unwind_to_first_non_reserved_loc(struct line_maps * set,source_location loc,const struct line_map ** map)1682 linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
1683 source_location loc,
1684 const struct line_map **map)
1685 {
1686 source_location resolved_loc;
1687 const struct line_map *map0 = NULL;
1688 const line_map_ordinary *map1 = NULL;
1689
1690 if (IS_ADHOC_LOC (loc))
1691 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1692
1693 map0 = linemap_lookup (set, loc);
1694 if (!linemap_macro_expansion_map_p (map0))
1695 return loc;
1696
1697 resolved_loc = linemap_resolve_location (set, loc,
1698 LRK_SPELLING_LOCATION,
1699 &map1);
1700
1701 if (resolved_loc >= RESERVED_LOCATION_COUNT
1702 && !LINEMAP_SYSP (map1))
1703 return loc;
1704
1705 while (linemap_macro_expansion_map_p (map0)
1706 && (resolved_loc < RESERVED_LOCATION_COUNT
1707 || LINEMAP_SYSP (map1)))
1708 {
1709 loc = linemap_unwind_toward_expansion (set, loc, &map0);
1710 resolved_loc = linemap_resolve_location (set, loc,
1711 LRK_SPELLING_LOCATION,
1712 &map1);
1713 }
1714
1715 if (map != NULL)
1716 *map = map0;
1717 return loc;
1718 }
1719
1720 /* Expand source code location LOC and return a user readable source
1721 code location. LOC must be a spelling (non-virtual) location. If
1722 it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
1723 location is returned. */
1724
1725 expanded_location
linemap_expand_location(struct line_maps * set,const struct line_map * map,source_location loc)1726 linemap_expand_location (struct line_maps *set,
1727 const struct line_map *map,
1728 source_location loc)
1729
1730 {
1731 expanded_location xloc;
1732
1733 memset (&xloc, 0, sizeof (xloc));
1734 if (IS_ADHOC_LOC (loc))
1735 {
1736 xloc.data
1737 = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
1738 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1739 }
1740
1741 if (loc < RESERVED_LOCATION_COUNT)
1742 /* The location for this token wasn't generated from a line map.
1743 It was probably a location for a builtin token, chosen by some
1744 client code. Let's not try to expand the location in that
1745 case. */;
1746 else if (map == NULL)
1747 /* We shouldn't be getting a NULL map with a location that is not
1748 reserved by the client code. */
1749 abort ();
1750 else
1751 {
1752 /* MAP must be an ordinary map and LOC must be non-virtual,
1753 encoded into this map, obviously; the accessors used on MAP
1754 below ensure it is ordinary. Let's just assert the
1755 non-virtualness of LOC here. */
1756 if (linemap_location_from_macro_expansion_p (set, loc))
1757 abort ();
1758
1759 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1760
1761 xloc.file = LINEMAP_FILE (ord_map);
1762 xloc.line = SOURCE_LINE (ord_map, loc);
1763 xloc.column = SOURCE_COLUMN (ord_map, loc);
1764 xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
1765 }
1766
1767 return xloc;
1768 }
1769
1770
1771 /* Dump line map at index IX in line table SET to STREAM. If STREAM
1772 is NULL, use stderr. IS_MACRO is true if the caller wants to
1773 dump a macro map, false otherwise. */
1774
1775 void
linemap_dump(FILE * stream,struct line_maps * set,unsigned ix,bool is_macro)1776 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
1777 {
1778 const char *lc_reasons_v[LC_ENTER_MACRO + 1]
1779 = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
1780 "LC_ENTER_MACRO" };
1781 const char *reason;
1782 const line_map *map;
1783
1784 if (stream == NULL)
1785 stream = stderr;
1786
1787 if (!is_macro)
1788 map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
1789 else
1790 map = LINEMAPS_MACRO_MAP_AT (set, ix);
1791
1792 reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
1793
1794 fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
1795 ix, (void *) map, map->start_location, reason,
1796 ((!is_macro
1797 && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
1798 ? "yes" : "no"));
1799 if (!is_macro)
1800 {
1801 const line_map_ordinary *ord_map = linemap_check_ordinary (map);
1802 unsigned includer_ix;
1803 const line_map_ordinary *includer_map;
1804
1805 includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (ord_map);
1806 includer_map = includer_ix < LINEMAPS_ORDINARY_USED (set)
1807 ? LINEMAPS_ORDINARY_MAP_AT (set, includer_ix)
1808 : NULL;
1809
1810 fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
1811 ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
1812 fprintf (stream, "Included from: [%d] %s\n", includer_ix,
1813 includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
1814 }
1815 else
1816 {
1817 const line_map_macro *macro_map = linemap_check_macro (map);
1818 fprintf (stream, "Macro: %s (%u tokens)\n",
1819 linemap_map_get_macro_name (macro_map),
1820 MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
1821 }
1822
1823 fprintf (stream, "\n");
1824 }
1825
1826
1827 /* Dump debugging information about source location LOC into the file
1828 stream STREAM. SET is the line map set LOC comes from. */
1829
1830 void
linemap_dump_location(struct line_maps * set,source_location loc,FILE * stream)1831 linemap_dump_location (struct line_maps *set,
1832 source_location loc,
1833 FILE *stream)
1834 {
1835 const line_map_ordinary *map;
1836 source_location location;
1837 const char *path = "", *from = "";
1838 int l = -1, c = -1, s = -1, e = -1;
1839
1840 if (IS_ADHOC_LOC (loc))
1841 loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
1842
1843 if (loc == 0)
1844 return;
1845
1846 location =
1847 linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);
1848
1849 if (map == NULL)
1850 /* Only reserved locations can be tolerated in this case. */
1851 linemap_assert (location < RESERVED_LOCATION_COUNT);
1852 else
1853 {
1854 path = LINEMAP_FILE (map);
1855 l = SOURCE_LINE (map, location);
1856 c = SOURCE_COLUMN (map, location);
1857 s = LINEMAP_SYSP (map) != 0;
1858 e = location != loc;
1859 if (e)
1860 from = "N/A";
1861 else
1862 from = (INCLUDED_FROM (set, map))
1863 ? LINEMAP_FILE (INCLUDED_FROM (set, map))
1864 : "<NULL>";
1865 }
1866
1867 /* P: path, L: line, C: column, S: in-system-header, M: map address,
1868 E: macro expansion?, LOC: original location, R: resolved location */
1869 fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
1870 path, from, l, c, s, (void*)map, e, loc, location);
1871 }
1872
1873 /* Return the highest location emitted for a given file for which
1874 there is a line map in SET. FILE_NAME is the file name to
1875 consider. If the function returns TRUE, *LOC is set to the highest
1876 location emitted for that file. */
1877
1878 bool
linemap_get_file_highest_location(struct line_maps * set,const char * file_name,source_location * loc)1879 linemap_get_file_highest_location (struct line_maps *set,
1880 const char *file_name,
1881 source_location *loc)
1882 {
1883 /* If the set is empty or no ordinary map has been created then
1884 there is no file to look for ... */
1885 if (set == NULL || set->info_ordinary.used == 0)
1886 return false;
1887
1888 /* Now look for the last ordinary map created for FILE_NAME. */
1889 int i;
1890 for (i = set->info_ordinary.used - 1; i >= 0; --i)
1891 {
1892 const char *fname = set->info_ordinary.maps[i].to_file;
1893 if (fname && !filename_cmp (fname, file_name))
1894 break;
1895 }
1896
1897 if (i < 0)
1898 return false;
1899
1900 /* The highest location for a given map is either the starting
1901 location of the next map minus one, or -- if the map is the
1902 latest one -- the highest location of the set. */
1903 source_location result;
1904 if (i == (int) set->info_ordinary.used - 1)
1905 result = set->highest_location;
1906 else
1907 result = set->info_ordinary.maps[i + 1].start_location - 1;
1908
1909 *loc = result;
1910 return true;
1911 }
1912
1913 /* Compute and return statistics about the memory consumption of some
1914 parts of the line table SET. */
1915
1916 void
linemap_get_statistics(struct line_maps * set,struct linemap_stats * s)1917 linemap_get_statistics (struct line_maps *set,
1918 struct linemap_stats *s)
1919 {
1920 long ordinary_maps_allocated_size, ordinary_maps_used_size,
1921 macro_maps_allocated_size, macro_maps_used_size,
1922 macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;
1923
1924 const line_map_macro *cur_map;
1925
1926 ordinary_maps_allocated_size =
1927 LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);
1928
1929 ordinary_maps_used_size =
1930 LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);
1931
1932 macro_maps_allocated_size =
1933 LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);
1934
1935 for (cur_map = LINEMAPS_MACRO_MAPS (set);
1936 cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
1937 ++cur_map)
1938 {
1939 unsigned i;
1940
1941 linemap_assert (linemap_macro_expansion_map_p (cur_map));
1942
1943 macro_maps_locations_size +=
1944 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (source_location);
1945
1946 for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
1947 {
1948 if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
1949 MACRO_MAP_LOCATIONS (cur_map)[i + 1])
1950 duplicated_macro_maps_locations_size +=
1951 sizeof (source_location);
1952 }
1953 }
1954
1955 macro_maps_used_size =
1956 LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);
1957
1958 s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
1959 s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
1960 s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
1961 s->ordinary_maps_used_size = ordinary_maps_used_size;
1962 s->num_expanded_macros = num_expanded_macros_counter;
1963 s->num_macro_tokens = num_macro_tokens_counter;
1964 s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
1965 s->macro_maps_allocated_size = macro_maps_allocated_size;
1966 s->macro_maps_locations_size = macro_maps_locations_size;
1967 s->macro_maps_used_size = macro_maps_used_size;
1968 s->duplicated_macro_maps_locations_size =
1969 duplicated_macro_maps_locations_size;
1970 s->adhoc_table_size = (set->location_adhoc_data_map.allocated
1971 * sizeof (struct location_adhoc_data));
1972 s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
1973 }
1974
1975
1976 /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
1977 NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
1978 specifies how many macro maps to dump. */
1979
1980 void
line_table_dump(FILE * stream,struct line_maps * set,unsigned int num_ordinary,unsigned int num_macro)1981 line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
1982 unsigned int num_macro)
1983 {
1984 unsigned int i;
1985
1986 if (set == NULL)
1987 return;
1988
1989 if (stream == NULL)
1990 stream = stderr;
1991
1992 fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set));
1993 fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set));
1994 fprintf (stream, "Include stack depth: %d\n", set->depth);
1995 fprintf (stream, "Highest location: %u\n", set->highest_location);
1996
1997 if (num_ordinary)
1998 {
1999 fprintf (stream, "\nOrdinary line maps\n");
2000 for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
2001 linemap_dump (stream, set, i, false);
2002 fprintf (stream, "\n");
2003 }
2004
2005 if (num_macro)
2006 {
2007 fprintf (stream, "\nMacro line maps\n");
2008 for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
2009 linemap_dump (stream, set, i, true);
2010 fprintf (stream, "\n");
2011 }
2012 }
2013
2014 /* class rich_location. */
2015
2016 /* Construct a rich_location with location LOC as its initial range. */
2017
rich_location(line_maps * set,source_location loc)2018 rich_location::rich_location (line_maps *set, source_location loc) :
2019 m_line_table (set),
2020 m_ranges (),
2021 m_column_override (0),
2022 m_have_expanded_location (false),
2023 m_fixit_hints (),
2024 m_seen_impossible_fixit (false),
2025 m_fixits_cannot_be_auto_applied (false)
2026 {
2027 add_range (loc, true);
2028 }
2029
2030 /* The destructor for class rich_location. */
2031
~rich_location()2032 rich_location::~rich_location ()
2033 {
2034 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2035 delete get_fixit_hint (i);
2036 }
2037
2038 /* Get location IDX within this rich_location. */
2039
2040 source_location
get_loc(unsigned int idx)2041 rich_location::get_loc (unsigned int idx) const
2042 {
2043 const location_range *locrange = get_range (idx);
2044 return locrange->m_loc;
2045 }
2046
2047 /* Get range IDX within this rich_location. */
2048
2049 const location_range *
get_range(unsigned int idx)2050 rich_location::get_range (unsigned int idx) const
2051 {
2052 return &m_ranges[idx];
2053 }
2054
2055 /* Mutable access to range IDX within this rich_location. */
2056
2057 location_range *
get_range(unsigned int idx)2058 rich_location::get_range (unsigned int idx)
2059 {
2060 return &m_ranges[idx];
2061 }
2062
2063 /* Expand location IDX within this rich_location. */
2064 /* Get an expanded_location for this rich_location's primary
2065 location. */
2066
2067 expanded_location
get_expanded_location(unsigned int idx)2068 rich_location::get_expanded_location (unsigned int idx)
2069 {
2070 if (idx == 0)
2071 {
2072 /* Cache the expansion of the primary location. */
2073 if (!m_have_expanded_location)
2074 {
2075 m_expanded_location
2076 = linemap_client_expand_location_to_spelling_point
2077 (get_loc (0), LOCATION_ASPECT_CARET);
2078 if (m_column_override)
2079 m_expanded_location.column = m_column_override;
2080 m_have_expanded_location = true;
2081 }
2082
2083 return m_expanded_location;
2084 }
2085 else
2086 return linemap_client_expand_location_to_spelling_point
2087 (get_loc (idx), LOCATION_ASPECT_CARET);
2088 }
2089
2090 /* Set the column of the primary location, with 0 meaning
2091 "don't override it". */
2092
2093 void
override_column(int column)2094 rich_location::override_column (int column)
2095 {
2096 m_column_override = column;
2097 m_have_expanded_location = false;
2098 }
2099
2100 /* Add the given range. */
2101
2102 void
add_range(source_location loc,bool show_caret_p)2103 rich_location::add_range (source_location loc, bool show_caret_p)
2104 {
2105 location_range range;
2106 range.m_loc = loc;
2107 range.m_show_caret_p = show_caret_p;
2108 m_ranges.push (range);
2109 }
2110
2111 /* Add or overwrite the location given by IDX, setting its location to LOC,
2112 and setting its "should my caret be printed" flag to SHOW_CARET_P.
2113
2114 It must either overwrite an existing location, or add one *exactly* on
2115 the end of the array.
2116
2117 This is primarily for use by gcc when implementing diagnostic format
2118 decoders e.g.
2119 - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
2120 (which writes the source location of a tree back into location 0 of
2121 the rich_location), and
2122 - the "%C" and "%L" format codes in the Fortran frontend. */
2123
2124 void
set_range(line_maps *,unsigned int idx,source_location loc,bool show_caret_p)2125 rich_location::set_range (line_maps * /*set*/, unsigned int idx,
2126 source_location loc, bool show_caret_p)
2127 {
2128 /* We can either overwrite an existing range, or add one exactly
2129 on the end of the array. */
2130 linemap_assert (idx <= m_ranges.count ());
2131
2132 if (idx == m_ranges.count ())
2133 add_range (loc, show_caret_p);
2134 else
2135 {
2136 location_range *locrange = get_range (idx);
2137 locrange->m_loc = loc;
2138 locrange->m_show_caret_p = show_caret_p;
2139 }
2140
2141 if (idx == 0)
2142 /* Mark any cached value here as dirty. */
2143 m_have_expanded_location = false;
2144 }
2145
2146 /* Methods for adding insertion fix-it hints. */
2147
2148 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2149 immediately before the primary range's start location. */
2150
2151 void
add_fixit_insert_before(const char * new_content)2152 rich_location::add_fixit_insert_before (const char *new_content)
2153 {
2154 add_fixit_insert_before (get_loc (), new_content);
2155 }
2156
2157 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2158 immediately before the start of WHERE. */
2159
2160 void
add_fixit_insert_before(source_location where,const char * new_content)2161 rich_location::add_fixit_insert_before (source_location where,
2162 const char *new_content)
2163 {
2164 source_location start = get_range_from_loc (m_line_table, where).m_start;
2165 maybe_add_fixit (start, start, new_content);
2166 }
2167
2168 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2169 immediately after the primary range's end-point. */
2170
2171 void
add_fixit_insert_after(const char * new_content)2172 rich_location::add_fixit_insert_after (const char *new_content)
2173 {
2174 add_fixit_insert_after (get_loc (), new_content);
2175 }
2176
2177 /* Add a fixit-hint, suggesting insertion of NEW_CONTENT
2178 immediately after the end-point of WHERE. */
2179
2180 void
add_fixit_insert_after(source_location where,const char * new_content)2181 rich_location::add_fixit_insert_after (source_location where,
2182 const char *new_content)
2183 {
2184 source_location finish = get_range_from_loc (m_line_table, where).m_finish;
2185 source_location next_loc
2186 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2187
2188 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2189 its input value. */
2190 if (next_loc == finish)
2191 {
2192 stop_supporting_fixits ();
2193 return;
2194 }
2195
2196 maybe_add_fixit (next_loc, next_loc, new_content);
2197 }
2198
2199 /* Methods for adding removal fix-it hints. */
2200
2201 /* Add a fixit-hint, suggesting removal of the content covered
2202 by range 0. */
2203
2204 void
add_fixit_remove()2205 rich_location::add_fixit_remove ()
2206 {
2207 add_fixit_remove (get_loc ());
2208 }
2209
2210 /* Add a fixit-hint, suggesting removal of the content between
2211 the start and finish of WHERE. */
2212
2213 void
add_fixit_remove(source_location where)2214 rich_location::add_fixit_remove (source_location where)
2215 {
2216 source_range range = get_range_from_loc (m_line_table, where);
2217 add_fixit_remove (range);
2218 }
2219
2220 /* Add a fixit-hint, suggesting removal of the content at
2221 SRC_RANGE. */
2222
2223 void
add_fixit_remove(source_range src_range)2224 rich_location::add_fixit_remove (source_range src_range)
2225 {
2226 add_fixit_replace (src_range, "");
2227 }
2228
2229 /* Add a fixit-hint, suggesting replacement of the content covered
2230 by range 0 with NEW_CONTENT. */
2231
2232 void
add_fixit_replace(const char * new_content)2233 rich_location::add_fixit_replace (const char *new_content)
2234 {
2235 add_fixit_replace (get_loc (), new_content);
2236 }
2237
2238 /* Methods for adding "replace" fix-it hints. */
2239
2240 /* Add a fixit-hint, suggesting replacement of the content between
2241 the start and finish of WHERE with NEW_CONTENT. */
2242
2243 void
add_fixit_replace(source_location where,const char * new_content)2244 rich_location::add_fixit_replace (source_location where,
2245 const char *new_content)
2246 {
2247 source_range range = get_range_from_loc (m_line_table, where);
2248 add_fixit_replace (range, new_content);
2249 }
2250
2251 /* Add a fixit-hint, suggesting replacement of the content at
2252 SRC_RANGE with NEW_CONTENT. */
2253
2254 void
add_fixit_replace(source_range src_range,const char * new_content)2255 rich_location::add_fixit_replace (source_range src_range,
2256 const char *new_content)
2257 {
2258 source_location start = get_pure_location (m_line_table, src_range.m_start);
2259 source_location finish = get_pure_location (m_line_table, src_range.m_finish);
2260
2261 /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */
2262 source_location next_loc
2263 = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
2264 /* linemap_position_for_loc_and_offset can fail, if so, it returns
2265 its input value. */
2266 if (next_loc == finish)
2267 {
2268 stop_supporting_fixits ();
2269 return;
2270 }
2271 finish = next_loc;
2272
2273 maybe_add_fixit (start, finish, new_content);
2274 }
2275
2276 /* Get the last fix-it hint within this rich_location, or NULL if none. */
2277
2278 fixit_hint *
get_last_fixit_hint()2279 rich_location::get_last_fixit_hint () const
2280 {
2281 if (m_fixit_hints.count () > 0)
2282 return get_fixit_hint (m_fixit_hints.count () - 1);
2283 else
2284 return NULL;
2285 }
2286
2287 /* If WHERE is an "awkward" location, then mark this rich_location as not
2288 supporting fixits, purging any thay were already added, and return true.
2289
2290 Otherwise (the common case), return false. */
2291
2292 bool
reject_impossible_fixit(source_location where)2293 rich_location::reject_impossible_fixit (source_location where)
2294 {
2295 /* Fix-its within a rich_location should either all be suggested, or
2296 none of them should be suggested.
2297 Once we've rejected a fixit, we reject any more, even those
2298 with reasonable locations. */
2299 if (m_seen_impossible_fixit)
2300 return true;
2301
2302 if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
2303 /* WHERE is a reasonable location for a fix-it; don't reject it. */
2304 return false;
2305
2306 /* Otherwise we have an attempt to add a fix-it with an "awkward"
2307 location: either one that we can't obtain column information
2308 for (within an ordinary map), or one within a macro expansion. */
2309 stop_supporting_fixits ();
2310 return true;
2311 }
2312
2313 /* Mark this rich_location as not supporting fixits, purging any that were
2314 already added. */
2315
2316 void
stop_supporting_fixits()2317 rich_location::stop_supporting_fixits ()
2318 {
2319 m_seen_impossible_fixit = true;
2320
2321 /* Purge the rich_location of any fix-its that were already added. */
2322 for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
2323 delete get_fixit_hint (i);
2324 m_fixit_hints.truncate (0);
2325 }
2326
2327 /* Add HINT to the fix-it hints in this rich_location,
2328 consolidating into the prior fixit if possible. */
2329
2330 void
maybe_add_fixit(source_location start,source_location next_loc,const char * new_content)2331 rich_location::maybe_add_fixit (source_location start,
2332 source_location next_loc,
2333 const char *new_content)
2334 {
2335 if (reject_impossible_fixit (start))
2336 return;
2337 if (reject_impossible_fixit (next_loc))
2338 return;
2339
2340 /* Only allow fix-it hints that affect a single line in one file.
2341 Compare the end-points. */
2342 expanded_location exploc_start
2343 = linemap_client_expand_location_to_spelling_point (start,
2344 LOCATION_ASPECT_START);
2345 expanded_location exploc_next_loc
2346 = linemap_client_expand_location_to_spelling_point (next_loc,
2347 LOCATION_ASPECT_START);
2348 /* They must be within the same file... */
2349 if (exploc_start.file != exploc_next_loc.file)
2350 {
2351 stop_supporting_fixits ();
2352 return;
2353 }
2354 /* ...and on the same line. */
2355 if (exploc_start.line != exploc_next_loc.line)
2356 {
2357 stop_supporting_fixits ();
2358 return;
2359 }
2360 /* The columns must be in the correct order. This can fail if the
2361 endpoints straddle the boundary for which the linemap can represent
2362 columns (PR c/82050). */
2363 if (exploc_start.column > exploc_next_loc.column)
2364 {
2365 stop_supporting_fixits ();
2366 return;
2367 }
2368
2369 const char *newline = strchr (new_content, '\n');
2370 if (newline)
2371 {
2372 /* For now, we can only support insertion of whole lines
2373 i.e. starts at start of line, and the newline is at the end of
2374 the insertion point. */
2375
2376 /* It must be an insertion, not a replacement/deletion. */
2377 if (start != next_loc)
2378 {
2379 stop_supporting_fixits ();
2380 return;
2381 }
2382
2383 /* The insertion must be at the start of a line. */
2384 if (exploc_start.column != 1)
2385 {
2386 stop_supporting_fixits ();
2387 return;
2388 }
2389
2390 /* The newline must be at end of NEW_CONTENT.
2391 We could eventually split up fix-its at newlines if we wanted
2392 to allow more generality (e.g. to allow adding multiple lines
2393 with one add_fixit call. */
2394 if (newline[1] != '\0')
2395 {
2396 stop_supporting_fixits ();
2397 return;
2398 }
2399 }
2400
2401 /* Consolidate neighboring fixits.
2402 Don't consolidate into newline-insertion fixits. */
2403 fixit_hint *prev = get_last_fixit_hint ();
2404 if (prev && !prev->ends_with_newline_p ())
2405 if (prev->maybe_append (start, next_loc, new_content))
2406 return;
2407
2408 m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
2409 }
2410
2411 /* class fixit_hint. */
2412
fixit_hint(source_location start,source_location next_loc,const char * new_content)2413 fixit_hint::fixit_hint (source_location start,
2414 source_location next_loc,
2415 const char *new_content)
2416 : m_start (start),
2417 m_next_loc (next_loc),
2418 m_bytes (xstrdup (new_content)),
2419 m_len (strlen (new_content))
2420 {
2421 }
2422
2423 /* Does this fix-it hint affect the given line? */
2424
2425 bool
affects_line_p(const char * file,int line)2426 fixit_hint::affects_line_p (const char *file, int line) const
2427 {
2428 expanded_location exploc_start
2429 = linemap_client_expand_location_to_spelling_point (m_start,
2430 LOCATION_ASPECT_START);
2431 if (file != exploc_start.file)
2432 return false;
2433 if (line < exploc_start.line)
2434 return false;
2435 expanded_location exploc_next_loc
2436 = linemap_client_expand_location_to_spelling_point (m_next_loc,
2437 LOCATION_ASPECT_START);
2438 if (file != exploc_next_loc.file)
2439 return false;
2440 if (line > exploc_next_loc.line)
2441 return false;
2442 return true;
2443 }
2444
2445 /* Method for consolidating fix-it hints, for use by
2446 rich_location::maybe_add_fixit.
2447 If possible, merge a pending fix-it hint with the given params
2448 into this one and return true.
2449 Otherwise return false. */
2450
2451 bool
maybe_append(source_location start,source_location next_loc,const char * new_content)2452 fixit_hint::maybe_append (source_location start,
2453 source_location next_loc,
2454 const char *new_content)
2455 {
2456 /* For consolidation to be possible, START must be at this hint's
2457 m_next_loc. */
2458 if (start != m_next_loc)
2459 return false;
2460
2461 /* If so, we have neighboring replacements; merge them. */
2462 m_next_loc = next_loc;
2463 size_t extra_len = strlen (new_content);
2464 m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
2465 memcpy (m_bytes + m_len, new_content, extra_len);
2466 m_len += extra_len;
2467 m_bytes[m_len] = '\0';
2468 return true;
2469 }
2470
2471 /* Return true iff this hint's content ends with a newline. */
2472
2473 bool
ends_with_newline_p()2474 fixit_hint::ends_with_newline_p () const
2475 {
2476 if (m_len == 0)
2477 return false;
2478 return m_bytes[m_len - 1] == '\n';
2479 }
2480