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