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