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