/* Map (unsigned int) keys to (source file, line, column) triples.
   Copyright (C) 2001-2019 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.

 In other words, you are welcome to use, share and improve this program.
 You are forbidden to forbid anyone else to use, share and improve
 what you give them.   Help stamp out software-hoarding!  */

#include "config.h"
#include "system.h"
#include "line-map.h"
#include "cpplib.h"
#include "internal.h"
#include "hashtab.h"

static void trace_include (const struct line_maps *, const line_map_ordinary *);
static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
							      location_t);
static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
						       location_t);
static location_t linemap_macro_map_loc_to_def_point
(const line_map_macro *, location_t);
static location_t linemap_macro_map_loc_to_exp_point
(const line_map_macro *, location_t);
static location_t linemap_macro_loc_to_spelling_point
(struct line_maps *, location_t, const line_map_ordinary **);
static location_t linemap_macro_loc_to_def_point (line_maps *,
						  location_t,
						  const line_map_ordinary **);
static location_t linemap_macro_loc_to_exp_point (line_maps *,
						  location_t,
						  const line_map_ordinary **);

/* Counters defined in macro.c.  */
extern unsigned num_expanded_macros_counter;
extern unsigned num_macro_tokens_counter;

/* Destructor for class line_maps.
   Ensure non-GC-managed memory is released.  */

line_maps::~line_maps ()
{
  if (location_adhoc_data_map.htab)
    htab_delete (location_adhoc_data_map.htab);
}

/* Hash function for location_adhoc_data hashtable.  */

static hashval_t
location_adhoc_data_hash (const void *l)
{
  const struct location_adhoc_data *lb =
      (const struct location_adhoc_data *) l;
  return ((hashval_t) lb->locus
	  + (hashval_t) lb->src_range.m_start
	  + (hashval_t) lb->src_range.m_finish
	  + (size_t) lb->data);
}

/* Compare function for location_adhoc_data hashtable.  */

static int
location_adhoc_data_eq (const void *l1, const void *l2)
{
  const struct location_adhoc_data *lb1 =
      (const struct location_adhoc_data *) l1;
  const struct location_adhoc_data *lb2 =
      (const struct location_adhoc_data *) l2;
  return (lb1->locus == lb2->locus
	  && lb1->src_range.m_start == lb2->src_range.m_start
	  && lb1->src_range.m_finish == lb2->src_range.m_finish
	  && lb1->data == lb2->data);
}

/* Update the hashtable when location_adhoc_data is reallocated.  */

static int
location_adhoc_data_update (void **slot, void *data)
{
  *((char **) slot)
    = (char *) ((uintptr_t) *((char **) slot) + *((ptrdiff_t *) data));
  return 1;
}

/* Rebuild the hash table from the location adhoc data.  */

void
rebuild_location_adhoc_htab (struct line_maps *set)
{
  unsigned i;
  set->location_adhoc_data_map.htab =
      htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
  for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++)
    htab_find_slot (set->location_adhoc_data_map.htab,
		    set->location_adhoc_data_map.data + i, INSERT);
}

/* Helper function for get_combined_adhoc_loc.
   Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly
   within a location_t, without needing to use an ad-hoc location.  */

static bool
can_be_stored_compactly_p (struct line_maps *set,
			   location_t locus,
			   source_range src_range,
			   void *data)
{
  /* If there's an ad-hoc pointer, we can't store it directly in the
     location_t, we need the lookaside.  */
  if (data)
    return false;

  /* We only store ranges that begin at the locus and that are sufficiently
     "sane".  */
  if (src_range.m_start != locus)
    return false;

  if (src_range.m_finish < src_range.m_start)
    return false;

  if (src_range.m_start < RESERVED_LOCATION_COUNT)
    return false;

  if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
    return false;

  /* All 3 locations must be within ordinary maps, typically, the same
     ordinary map.  */
  location_t lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set);
  if (locus >= lowest_macro_loc)
    return false;
  if (src_range.m_start >= lowest_macro_loc)
    return false;
  if (src_range.m_finish >= lowest_macro_loc)
    return false;

  /* Passed all tests.  */
  return true;
}

/* Combine LOCUS and DATA to a combined adhoc loc.  */

location_t
get_combined_adhoc_loc (struct line_maps *set,
			location_t locus,
			source_range src_range,
			void *data)
{
  struct location_adhoc_data lb;
  struct location_adhoc_data **slot;

  if (IS_ADHOC_LOC (locus))
    locus
      = set->location_adhoc_data_map.data[locus & MAX_LOCATION_T].locus;
  if (locus == 0 && data == NULL)
    return 0;

  /* Any ordinary locations ought to be "pure" at this point: no
     compressed ranges.  */
  linemap_assert (locus < RESERVED_LOCATION_COUNT
		  || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
		  || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set)
		  || pure_location_p (set, locus));

  /* Consider short-range optimization.  */
  if (can_be_stored_compactly_p (set, locus, src_range, data))
    {
      /* The low bits ought to be clear.  */
      linemap_assert (pure_location_p (set, locus));
      const line_map *map = linemap_lookup (set, locus);
      const line_map_ordinary *ordmap = linemap_check_ordinary (map);
      unsigned int int_diff = src_range.m_finish - src_range.m_start;
      unsigned int col_diff = (int_diff >> ordmap->m_range_bits);
      if (col_diff < (1U << ordmap->m_range_bits))
	{
	  location_t packed = locus | col_diff;
	  set->num_optimized_ranges++;
	  return packed;
	}
    }

  /* We can also compactly store locations
     when locus == start == finish (and data is NULL).  */
  if (locus == src_range.m_start
      && locus == src_range.m_finish
      && !data)
    return locus;

  if (!data)
    set->num_unoptimized_ranges++;

  lb.locus = locus;
  lb.src_range = src_range;
  lb.data = data;
  slot = (struct location_adhoc_data **)
      htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
  if (*slot == NULL)
    {
      if (set->location_adhoc_data_map.curr_loc >=
	  set->location_adhoc_data_map.allocated)
	{
	  char *orig_data = (char *) set->location_adhoc_data_map.data;
	  ptrdiff_t offset;
	  /* Cast away extern "C" from the type of xrealloc.  */
	  line_map_realloc reallocator = (set->reallocator
					  ? set->reallocator
					  : (line_map_realloc) xrealloc);

	  if (set->location_adhoc_data_map.allocated == 0)
	    set->location_adhoc_data_map.allocated = 128;
	  else
	    set->location_adhoc_data_map.allocated *= 2;
	  set->location_adhoc_data_map.data = (struct location_adhoc_data *)
	      reallocator (set->location_adhoc_data_map.data,
			   set->location_adhoc_data_map.allocated
			   * sizeof (struct location_adhoc_data));
	  offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
	  if (set->location_adhoc_data_map.allocated > 128)
	    htab_traverse (set->location_adhoc_data_map.htab,
			   location_adhoc_data_update, &offset);
	}
      *slot = set->location_adhoc_data_map.data
	      + set->location_adhoc_data_map.curr_loc;
      set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++]
	= lb;
    }
  return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
}

/* Return the data for the adhoc loc.  */

void *
get_data_from_adhoc_loc (struct line_maps *set, location_t loc)
{
  linemap_assert (IS_ADHOC_LOC (loc));
  return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
}

/* Return the location for the adhoc loc.  */

location_t
get_location_from_adhoc_loc (struct line_maps *set, location_t loc)
{
  linemap_assert (IS_ADHOC_LOC (loc));
  return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;
}

/* Return the source_range for adhoc location LOC.  */

static source_range
get_range_from_adhoc_loc (struct line_maps *set, location_t loc)
{
  linemap_assert (IS_ADHOC_LOC (loc));
  return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].src_range;
}

/* Get the source_range of location LOC, either from the ad-hoc
   lookaside table, or embedded inside LOC itself.  */

source_range
get_range_from_loc (struct line_maps *set,
		    location_t loc)
{
  if (IS_ADHOC_LOC (loc))
    return get_range_from_adhoc_loc (set, loc);

  /* For ordinary maps, extract packed range.  */
  if (loc >= RESERVED_LOCATION_COUNT
      && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set)
      && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
    {
      const line_map *map = linemap_lookup (set, loc);
      const line_map_ordinary *ordmap = linemap_check_ordinary (map);
      source_range result;
      int offset = loc & ((1 << ordmap->m_range_bits) - 1);
      result.m_start = loc - offset;
      result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
      return result;
    }

  return source_range::from_location (loc);
}

/* Get whether location LOC is a "pure" location, or
   whether it is an ad-hoc location, or embeds range information.  */

bool
pure_location_p (line_maps *set, location_t loc)
{
  if (IS_ADHOC_LOC (loc))
    return false;

  const line_map *map = linemap_lookup (set, loc);
  if (map == NULL)
    return true;
  const line_map_ordinary *ordmap = linemap_check_ordinary (map);

  if (loc & ((1U << ordmap->m_range_bits) - 1))
    return false;

  return true;
}

/* Given location LOC within SET, strip away any packed range information
   or ad-hoc information.  */

location_t
get_pure_location (line_maps *set, location_t loc)
{
  if (IS_ADHOC_LOC (loc))
    loc
      = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;

  if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
    return loc;

  if (loc < RESERVED_LOCATION_COUNT)
    return loc;

  const line_map *map = linemap_lookup (set, loc);
  const line_map_ordinary *ordmap = linemap_check_ordinary (map);

  return loc & ~((1 << ordmap->m_range_bits) - 1);
}

/* Initialize a line map set.  */

void
linemap_init (struct line_maps *set,
	      location_t builtin_location)
{
#if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
  /* PR33916, needed to fix PR82939.  */
  memset (set, 0, sizeof (struct line_maps));
#else
  new (set) line_maps();
#endif
  /* Set default reallocator (used for initial alloc too).  */
  set->reallocator = xrealloc;
  set->highest_location = RESERVED_LOCATION_COUNT - 1;
  set->highest_line = RESERVED_LOCATION_COUNT - 1;
  set->location_adhoc_data_map.htab =
      htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
  set->builtin_location = builtin_location;
}

/* Return the ordinary line map from whence MAP was included.  Returns
   NULL if MAP was not an include.  */

const line_map_ordinary *
linemap_included_from_linemap (line_maps *set, const line_map_ordinary *map)
{
  return linemap_ordinary_map_lookup (set, linemap_included_from (map));
}

/* Check for and warn about line_maps entered but not exited.  */

void
linemap_check_files_exited (struct line_maps *set)
{
  /* Depending upon whether we are handling preprocessed input or
     not, this can be a user error or an ICE.  */
  for (const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
       ! MAIN_FILE_P (map);
       map = linemap_included_from_linemap (set, map))
    fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
	     ORDINARY_MAP_FILE_NAME (map));
}

/* Create a new line map in the line map set SET, and return it.
   REASON is the reason of creating the map. It determines the type
   of map created (ordinary or macro map). Note that ordinary maps and
   macro maps are allocated in different memory location.  */

static struct line_map *
new_linemap (struct line_maps *set,  location_t start_location)
{
  bool macro_p = start_location >= LINE_MAP_MAX_LOCATION;
  unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
  unsigned num_maps_used = LINEMAPS_USED (set, macro_p);

  if (num_maps_used == num_maps_allocated)
    {
      /* We need more space!  */
      if (!num_maps_allocated)
	num_maps_allocated = 128;
      num_maps_allocated *= 2;

      size_t size_of_a_map;
      void *buffer;
      if (macro_p)
	{
	  size_of_a_map = sizeof (line_map_macro);
	  buffer = set->info_macro.maps;
	}
      else
	{
	  size_of_a_map = sizeof (line_map_ordinary);
	  buffer = set->info_ordinary.maps;
	}

      /* We are going to execute some dance to try to reduce the
	 overhead of the memory allocator, in case we are using the
	 ggc-page.c one.
	 
	 The actual size of memory we are going to get back from the
	 allocator may well be larger than what we ask for.  Use this
	 hook to find what that size is.  */
      size_t alloc_size
	= set->round_alloc_size (num_maps_allocated * size_of_a_map);

      /* Now alloc_size contains the exact memory size we would get if
	 we have asked for the initial alloc_size amount of memory.
	 Let's get back to the number of map that amounts to.  */
      unsigned num_maps = alloc_size / size_of_a_map;
      buffer = set->reallocator (buffer, num_maps * size_of_a_map);
      memset ((char *)buffer + num_maps_used * size_of_a_map, 0,
	      (num_maps - num_maps_used) * size_of_a_map);
      if (macro_p)
	set->info_macro.maps = (line_map_macro *)buffer;
      else
	set->info_ordinary.maps = (line_map_ordinary *)buffer;
      LINEMAPS_ALLOCATED (set, macro_p) = num_maps;
    }

  line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used]
		      : (line_map *)&set->info_ordinary.maps[num_maps_used]);
  LINEMAPS_USED (set, macro_p)++;

  result->start_location = start_location;

  return result;
}

/* Add a mapping of logical source line to physical source file and
   line number.

   The text pointed to by TO_FILE must have a lifetime
   at least as long as the final call to lookup_line ().  An empty
   TO_FILE means standard input.  If reason is LC_LEAVE, and
   TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
   natural values considering the file we are returning to.

   FROM_LINE should be monotonic increasing across calls to this
   function.  A call to this function can relocate the previous set of
   maps, so any stored line_map pointers should not be used.  */

const struct line_map *
linemap_add (struct line_maps *set, enum lc_reason reason,
	     unsigned int sysp, const char *to_file, linenum_type to_line)
{
  /* Generate a start_location above the current highest_location.
     If possible, make the low range bits be zero.  */
  location_t start_location;
  if (set->highest_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
    {
      start_location = set->highest_location + (1 << set->default_range_bits);
      if (set->default_range_bits)
	start_location &= ~((1 << set->default_range_bits) - 1);
      linemap_assert (0 == (start_location
			    & ((1 << set->default_range_bits) - 1)));
    }
  else
    start_location = set->highest_location + 1;

  linemap_assert (!LINEMAPS_ORDINARY_USED (set)
		  || (start_location
		      >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));

  /* When we enter the file for the first time reason cannot be
     LC_RENAME.  */
  linemap_assert (!(set->depth == 0 && reason == LC_RENAME));

  /* If we are leaving the main file, return a NULL map.  */
  if (reason == LC_LEAVE
      && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set))
      && to_file == NULL)
    {
      set->depth--;
      return NULL;
    }

  linemap_assert (reason != LC_ENTER_MACRO);

  if (start_location >= LINE_MAP_MAX_LOCATION)
    /* We ran out of line map space.   */
    start_location = 0;

  line_map_ordinary *map
    = linemap_check_ordinary (new_linemap (set, start_location));
  map->reason = reason;

  if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
    to_file = "<stdin>";

  if (reason == LC_RENAME_VERBATIM)
    reason = LC_RENAME;

  const line_map_ordinary *from = NULL;
  if (reason == LC_LEAVE)
    {
      /* When we are just leaving an "included" file, and jump to the next
	 location inside the "includer" right after the #include
	 "included", this variable points the map in use right before the
	 #include "included", inside the same "includer" file.  */

      linemap_assert (!MAIN_FILE_P (map - 1));
      /* (MAP - 1) points to the map we are leaving. The
	 map from which (MAP - 1) got included should be the map
	 that comes right before MAP in the same file.  */
      from = linemap_included_from_linemap (set, map - 1);

      /* A TO_FILE of NULL is special - we use the natural values.  */
      if (to_file == NULL)
	{
	  to_file = ORDINARY_MAP_FILE_NAME (from);
	  to_line = SOURCE_LINE (from, from[1].start_location);
	  sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from);
	}
      else
	linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from),
				      to_file) == 0);
    }

  map->sysp = sysp;
  map->to_file = to_file;
  map->to_line = to_line;
  LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
  map->m_column_and_range_bits = 0;
  map->m_range_bits = 0;
  set->highest_location = start_location;
  set->highest_line = start_location;
  set->max_column_hint = 0;

  /* This assertion is placed after set->highest_location has
     been updated, since the latter affects
     linemap_location_from_macro_expansion_p, which ultimately affects
     pure_location_p.  */
  linemap_assert (pure_location_p (set, start_location));

  if (reason == LC_ENTER)
    {
      if (set->depth == 0)
	map->included_from = 0;
      else
	/* The location of the end of the just-closed map.  */
	map->included_from
	  = (((map[0].start_location - 1 - map[-1].start_location)
	      & ~((1 << map[-1].m_column_and_range_bits) - 1))
	     + map[-1].start_location);
      set->depth++;
      if (set->trace_includes)
	trace_include (set, map);
    }
  else if (reason == LC_RENAME)
    map->included_from = linemap_included_from (&map[-1]);
  else if (reason == LC_LEAVE)
    {
      set->depth--;
      map->included_from = linemap_included_from (from);
    }

  return map;
}

/* Returns TRUE if the line table set tracks token locations across
   macro expansion, FALSE otherwise.  */

bool
linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
{
  return LINEMAPS_MACRO_MAPS (set) != NULL;
}

/* Create a macro map.  A macro map encodes source locations of tokens
   that are part of a macro replacement-list, at a macro expansion
   point.  See the extensive comments of struct line_map and struct
   line_map_macro, in line-map.h.

   This map shall be created when the macro is expanded.  The map
   encodes the source location of the expansion point of the macro as
   well as the "original" source location of each token that is part
   of the macro replacement-list.  If a macro is defined but never
   expanded, it has no macro map.  SET is the set of maps the macro
   map should be part of.  MACRO_NODE is the macro which the new macro
   map should encode source locations for.  EXPANSION is the location
   of the expansion point of MACRO. For function-like macros
   invocations, it's best to make it point to the closing parenthesis
   of the macro, rather than the the location of the first character
   of the macro.  NUM_TOKENS is the number of tokens that are part of
   the replacement-list of MACRO.

   Note that when we run out of the integer space available for source
   locations, this function returns NULL.  In that case, callers of
   this function cannot encode {line,column} pairs into locations of
   macro tokens anymore.  */

const line_map_macro *
linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
		     location_t expansion, unsigned int num_tokens)
{
  location_t start_location
    = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;

  if (start_location < LINE_MAP_MAX_LOCATION)
    /* We ran out of macro map space.   */
    return NULL;

  line_map_macro *map = linemap_check_macro (new_linemap (set, start_location));

  map->macro = macro_node;
  map->n_tokens = num_tokens;
  map->macro_locations
    = (location_t*) set->reallocator (NULL,
					   2 * num_tokens
					   * sizeof (location_t));
  map->expansion = expansion;
  memset (MACRO_MAP_LOCATIONS (map), 0,
	  2 * num_tokens * sizeof (location_t));

  LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1;

  return map;
}

/* Create and return a virtual location for a token that is part of a
   macro expansion-list at a macro expansion point.  See the comment
   inside struct line_map_macro to see what an expansion-list exactly
   is.

   A call to this function must come after a call to
   linemap_enter_macro.

   MAP is the map into which the source location is created.  TOKEN_NO
   is the index of the token in the macro replacement-list, starting
   at number 0.

   ORIG_LOC is the location of the token outside of this macro
   expansion.  If the token comes originally from the macro
   definition, it is the locus in the macro definition; otherwise it
   is a location in the context of the caller of this macro expansion
   (which is a virtual location or a source location if the caller is
   itself a macro expansion or not).

   ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition,
   either of the token itself or of a macro parameter that it
   replaces.  */

location_t
linemap_add_macro_token (const line_map_macro *map,
			 unsigned int token_no,
			 location_t orig_loc,
			 location_t orig_parm_replacement_loc)
{
  location_t result;

  linemap_assert (linemap_macro_expansion_map_p (map));
  linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));

  MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc;
  MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc;

  result = MAP_START_LOCATION (map) + token_no;
  return result;
}

/* Return a location_t for the start (i.e. column==0) of
   (physical) line TO_LINE in the current source file (as in the
   most recent linemap_add).   MAX_COLUMN_HINT is the highest column
   number we expect to use in this line (but it does not change
   the highest_location).  */

location_t
linemap_line_start (struct line_maps *set, linenum_type to_line,
		    unsigned int max_column_hint)
{
  line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
  location_t highest = set->highest_location;
  location_t r;
  linenum_type last_line =
    SOURCE_LINE (map, set->highest_line);
  int line_delta = to_line - last_line;
  bool add_map = false;
  linemap_assert (map->m_column_and_range_bits >= map->m_range_bits);
  int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits;

  if (line_delta < 0
      || (line_delta > 10
	  && line_delta * map->m_column_and_range_bits > 1000)
      || (max_column_hint >= (1U << effective_column_bits))
      || (max_column_hint <= 80 && effective_column_bits >= 10)
      || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
	  && map->m_range_bits > 0)
      || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
	  && (set->max_column_hint || highest >= LINE_MAP_MAX_LOCATION)))
    add_map = true;
  else
    max_column_hint = set->max_column_hint;
  if (add_map)
    {
      int column_bits;
      int range_bits;
      if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER
	  || highest > LINE_MAP_MAX_LOCATION_WITH_COLS)
	{
	  /* If the column number is ridiculous or we've allocated a huge
	     number of location_ts, give up on column numbers
	     (and on packed ranges).  */
	  max_column_hint = 0;
	  column_bits = 0;
	  range_bits = 0;
	  if (highest >= LINE_MAP_MAX_LOCATION)
	    return 0;
	}
      else
	{
	  column_bits = 7;
	  if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES)
	    range_bits = set->default_range_bits;
	  else
	    range_bits = 0;
	  while (max_column_hint >= (1U << column_bits))
	    column_bits++;
	  max_column_hint = 1U << column_bits;
	  column_bits += range_bits;
	}
      /* Allocate the new line_map.  However, if the current map only has a
	 single line we can sometimes just increase its column_bits instead. */
      if (line_delta < 0
	  || last_line != ORDINARY_MAP_STARTING_LINE_NUMBER (map)
	  || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits))
	  || ( /* We can't reuse the map if the line offset is sufficiently
		  large to cause overflow when computing location_t values.  */
	      (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
	      >= (((uint64_t) 1)
		  << (CHAR_BIT * sizeof (linenum_type) - column_bits)))
	  || range_bits < map->m_range_bits)
	map = linemap_check_ordinary
	        (const_cast <line_map *>
		  (linemap_add (set, LC_RENAME,
				ORDINARY_MAP_IN_SYSTEM_HEADER_P (map),
				ORDINARY_MAP_FILE_NAME (map),
				to_line)));
      map->m_column_and_range_bits = column_bits;
      map->m_range_bits = range_bits;
      r = (MAP_START_LOCATION (map)
	   + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
	      << column_bits));
    }
  else
    r = set->highest_line + (line_delta << map->m_column_and_range_bits);

  /* Locations of ordinary tokens are always lower than locations of
     macro tokens.  */
  if (r >= LINE_MAP_MAX_LOCATION)
    return 0;

  set->highest_line = r;
  if (r > set->highest_location)
    set->highest_location = r;
  set->max_column_hint = max_column_hint;

  /* At this point, we expect one of:
     (a) the normal case: a "pure" location with 0 range bits, or
     (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track
        columns anymore (or ranges), or
     (c) we're in a region with a column hint exceeding
        LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off,
	with column_bits == 0.  */
  linemap_assert (pure_location_p (set, r)
		  || r >= LINE_MAP_MAX_LOCATION_WITH_COLS
		  || map->m_column_and_range_bits == 0);
  linemap_assert (SOURCE_LINE (map, r) == to_line);
  return r;
}

/* Encode and return a location_t from a column number. The
   source line considered is the last source line used to call
   linemap_line_start, i.e, the last source line which a location was
   encoded from.  */

location_t
linemap_position_for_column (struct line_maps *set, unsigned int to_column)
{
  location_t r = set->highest_line;

  linemap_assert
    (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set)));

  if (to_column >= set->max_column_hint)
    {
      if (r > LINE_MAP_MAX_LOCATION_WITH_COLS
	  || to_column > LINE_MAP_MAX_COLUMN_NUMBER)
	{
	  /* Running low on location_ts - disable column numbers.  */
	  return r;
	}
      else
	{
	  /* Otherwise, attempt to start a new line that can hold TO_COLUMN,
	     with some space to spare.  This may or may not lead to a new
	     linemap being created.  */
	  line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
	  r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50);
	  map = LINEMAPS_LAST_ORDINARY_MAP (set);
	  if (map->m_column_and_range_bits == 0)
	    {
	      /* ...then the linemap has column-tracking disabled,
		 presumably due to exceeding either
		 LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or
		 LINE_MAP_MAX_COLUMN_NUMBER (within this line).
		 Return the start of the linemap, which encodes column 0, for
		 the whole line.  */
	      return r;
	    }
	}
    }
  line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
  r = r + (to_column << map->m_range_bits);
  if (r >= set->highest_location)
    set->highest_location = r;
  return r;
}

/* Encode and return a source location from a given line and
   column.  */

location_t
linemap_position_for_line_and_column (line_maps *set,
				      const line_map_ordinary *ord_map,
				      linenum_type line,
				      unsigned column)
{
  linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);

  location_t r = MAP_START_LOCATION (ord_map);
  r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
	<< ord_map->m_column_and_range_bits);
  if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
    r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
	  << ord_map->m_range_bits);
  location_t upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
  if (r >= upper_limit)
    r = upper_limit - 1;
  if (r > set->highest_location)
    set->highest_location = r;
  return r;
}

/* Encode and return a location_t starting from location LOC and
   shifting it by COLUMN_OFFSET columns.  This function does not support
   virtual locations.  */

location_t
linemap_position_for_loc_and_offset (struct line_maps *set,
				     location_t loc,
				     unsigned int column_offset)
{
  const line_map_ordinary * map = NULL;

  if (IS_ADHOC_LOC (loc))
    loc = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;

  /* This function does not support virtual locations yet.  */
  if (linemap_location_from_macro_expansion_p (set, loc))
    return loc;

  if (column_offset == 0
      /* Adding an offset to a reserved location (like
	 UNKNOWN_LOCATION for the C/C++ FEs) does not really make
	 sense.  So let's leave the location intact in that case.  */
      || loc < RESERVED_LOCATION_COUNT)
    return loc;

  /* We find the real location and shift it.  */
  loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
  /* The new location (loc + offset) should be higher than the first
     location encoded by MAP.  This can fail if the line information
     is messed up because of line directives (see PR66415).  */
  if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits))
    return loc;

  linenum_type line = SOURCE_LINE (map, loc);
  unsigned int column = SOURCE_COLUMN (map, loc);

  /* If MAP is not the last line map of its set, then the new location
     (loc + offset) should be less than the first location encoded by
     the next line map of the set.  Otherwise, we try to encode the
     location in the next map.  */
  while (map != LINEMAPS_LAST_ORDINARY_MAP (set)
	 && (loc + (column_offset << map->m_range_bits)
	     >= MAP_START_LOCATION (&map[1])))
    {
      map = &map[1];
      /* If the next map starts in a higher line, we cannot encode the
	 location there.  */
      if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map))
	return loc;
    }

  column += column_offset;

  /* Bail out if the column is not representable within the existing
     linemap.  */
  if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits)))
    return loc;

  location_t r = 
    linemap_position_for_line_and_column (set, map, line, column);
  if (linemap_assert_fails (r <= set->highest_location)
      || linemap_assert_fails (map == linemap_lookup (set, r)))
    return loc;

  return r;
}

/* Given a virtual source location yielded by a map (either an
   ordinary or a macro map), returns that map.  */

const struct line_map*
linemap_lookup (struct line_maps *set, location_t line)
{
  if (IS_ADHOC_LOC (line))
    line = set->location_adhoc_data_map.data[line & MAX_LOCATION_T].locus;
  if (linemap_location_from_macro_expansion_p (set, line))
    return linemap_macro_map_lookup (set, line);
  return linemap_ordinary_map_lookup (set, line);
}

/* Given a source location yielded by an ordinary map, returns that
   map.  Since the set is built chronologically, the logical lines are
   monotonic increasing, and so the list is sorted and we can use a
   binary search.  */

static const line_map_ordinary *
linemap_ordinary_map_lookup (struct line_maps *set, location_t line)
{
  unsigned int md, mn, mx;
  const line_map_ordinary *cached, *result;

  if (IS_ADHOC_LOC (line))
    line = set->location_adhoc_data_map.data[line & MAX_LOCATION_T].locus;

  if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
    return NULL;

  mn = LINEMAPS_ORDINARY_CACHE (set);
  mx = LINEMAPS_ORDINARY_USED (set);
  
  cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
  /* We should get a segfault if no line_maps have been added yet.  */
  if (line >= MAP_START_LOCATION (cached))
    {
      if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1]))
	return cached;
    }
  else
    {
      mx = mn;
      mn = 0;
    }

  while (mx - mn > 1)
    {
      md = (mn + mx) / 2;
      if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
	mx = md;
      else
	mn = md;
    }

  LINEMAPS_ORDINARY_CACHE (set) = mn;
  result = LINEMAPS_ORDINARY_MAP_AT (set, mn);
  linemap_assert (line >= MAP_START_LOCATION (result));
  return result;
}

/* Given a source location yielded by a macro map, returns that map.
   Since the set is built chronologically, the logical lines are
   monotonic decreasing, and so the list is sorted and we can use a
   binary search.  */

static const line_map_macro *
linemap_macro_map_lookup (struct line_maps *set, location_t line)
{
  unsigned int md, mn, mx;
  const struct line_map_macro *cached, *result;

  if (IS_ADHOC_LOC (line))
    line = set->location_adhoc_data_map.data[line & MAX_LOCATION_T].locus;

  linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));

  if (set ==  NULL)
    return NULL;

  mn = LINEMAPS_MACRO_CACHE (set);
  mx = LINEMAPS_MACRO_USED (set);
  cached = LINEMAPS_MACRO_MAP_AT (set, mn);
  
  if (line >= MAP_START_LOCATION (cached))
    {
      if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
	return cached;
      mx = mn - 1;
      mn = 0;
    }

  while (mn < mx)
    {
      md = (mx + mn) / 2;
      if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
	mn = md + 1;
      else
	mx = md;
    }

  LINEMAPS_MACRO_CACHE (set) = mx;
  result = LINEMAPS_MACRO_MAP_AT (set, LINEMAPS_MACRO_CACHE (set));
  linemap_assert (MAP_START_LOCATION (result) <= line);

  return result;
}

/* Return TRUE if MAP encodes locations coming from a macro
   replacement-list at macro expansion point.  */

bool
linemap_macro_expansion_map_p (const struct line_map *map)
{
  return map && !MAP_ORDINARY_P (map);
}

/* If LOCATION is the locus of a token in a replacement-list of a
   macro expansion return the location of the macro expansion point.

   Read the comments of struct line_map and struct line_map_macro in
   line-map.h to understand what a macro expansion point is.  */

static location_t
linemap_macro_map_loc_to_exp_point (const line_map_macro *map,
				    location_t location ATTRIBUTE_UNUSED)
{
  linemap_assert (linemap_macro_expansion_map_p (map)
		  && location >= MAP_START_LOCATION (map));

  /* Make sure LOCATION is correct.  */
  linemap_assert ((location - MAP_START_LOCATION (map))
		  <  MACRO_MAP_NUM_MACRO_TOKENS (map));

  return MACRO_MAP_EXPANSION_POINT_LOCATION (map);
}

/* LOCATION is the source location of a token that belongs to a macro
   replacement-list as part of the macro expansion denoted by MAP.

   Return the location of the token at the definition point of the
   macro.  */

static location_t
linemap_macro_map_loc_to_def_point (const line_map_macro *map,
				    location_t location)
{
  unsigned token_no;

  linemap_assert (linemap_macro_expansion_map_p (map)
		  && location >= MAP_START_LOCATION (map));
  linemap_assert (location >= RESERVED_LOCATION_COUNT);

  token_no = location - MAP_START_LOCATION (map);
  linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));

  location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1];

  return location;
}

/* If LOCATION is the locus of a token that is an argument of a
   function-like macro M and appears in the expansion of M, return the
   locus of that argument in the context of the caller of M.

   In other words, this returns the xI location presented in the
   comments of line_map_macro above.  */
location_t
linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
					      const line_map_macro* map,
					      location_t location)
{
  unsigned token_no;

  if (IS_ADHOC_LOC (location))
    location = get_location_from_adhoc_loc (set, location);

  linemap_assert (linemap_macro_expansion_map_p (map)
		  && location >= MAP_START_LOCATION (map));
  linemap_assert (location >= RESERVED_LOCATION_COUNT);
  linemap_assert (!IS_ADHOC_LOC (location));

  token_no = location - MAP_START_LOCATION (map);
  linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map));

  location = MACRO_MAP_LOCATIONS (map)[2 * token_no];
  
  return location;
}

/* Return the source line number corresponding to source location
   LOCATION.  SET is the line map set LOCATION comes from.  If
   LOCATION is the source location of token that is part of the
   replacement-list of a macro expansion return the line number of the
   macro expansion point.  */

int
linemap_get_expansion_line (struct line_maps *set,
			    location_t location)
{
  const line_map_ordinary *map = NULL;

  if (IS_ADHOC_LOC (location))
    location = set->location_adhoc_data_map.data[location
						 & MAX_LOCATION_T].locus;

  if (location < RESERVED_LOCATION_COUNT)
    return 0;

  location =
    linemap_macro_loc_to_exp_point (set, location, &map);

  return SOURCE_LINE (map, location);
}

/* Return the path of the file corresponding to source code location
   LOCATION.

   If LOCATION is the source location of token that is part of the
   replacement-list of a macro expansion return the file path of the
   macro expansion point.

   SET is the line map set LOCATION comes from.  */

const char*
linemap_get_expansion_filename (struct line_maps *set,
				location_t location)
{
  const struct line_map_ordinary *map = NULL;

  if (IS_ADHOC_LOC (location))
    location = set->location_adhoc_data_map.data[location
						 & MAX_LOCATION_T].locus;

  if (location < RESERVED_LOCATION_COUNT)
    return NULL;

  location =
    linemap_macro_loc_to_exp_point (set, location, &map);

  return LINEMAP_FILE (map);
}

/* Return the name of the macro associated to MACRO_MAP.  */

const char*
linemap_map_get_macro_name (const line_map_macro *macro_map)
{
  linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map));
  return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map));
}

/* Return a positive value if LOCATION is the locus of a token that is
   located in a system header, O otherwise. It returns 1 if LOCATION
   is the locus of a token that is located in a system header, and 2
   if LOCATION is the locus of a token located in a C system header
   that therefore needs to be extern "C" protected in C++.

   Note that this function returns 1 if LOCATION belongs to a token
   that is part of a macro replacement-list defined in a system
   header, but expanded in a non-system file.  */

int
linemap_location_in_system_header_p (struct line_maps *set,
				     location_t location)
{
  const struct line_map *map = NULL;

  if (IS_ADHOC_LOC (location))
    location = set->location_adhoc_data_map.data[location
						 & MAX_LOCATION_T].locus;

  if (location < RESERVED_LOCATION_COUNT)
    return false;

  /* Let's look at where the token for LOCATION comes from.  */
  while (true)
    {
      map = linemap_lookup (set, location);
      if (map != NULL)
	{
	  if (!linemap_macro_expansion_map_p (map))
	    /* It's a normal token.  */
	    return LINEMAP_SYSP (linemap_check_ordinary (map));
	  else
	    {
	      const line_map_macro *macro_map = linemap_check_macro (map);

	      /* It's a token resulting from a macro expansion.  */
	      location_t loc =
		linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location);
	      if (loc < RESERVED_LOCATION_COUNT)
		/* This token might come from a built-in macro.  Let's
		   look at where that macro got expanded.  */
		location = linemap_macro_map_loc_to_exp_point (macro_map, location);
	      else
		location = loc;
	    }
	}
      else
	break;
    }
  return false;
}

/* Return TRUE if LOCATION is a source code location of a token that is part of
   a macro expansion, FALSE otherwise.  */

bool
linemap_location_from_macro_expansion_p (const struct line_maps *set,
					 location_t location)
{
  if (IS_ADHOC_LOC (location))
    location = set->location_adhoc_data_map.data[location
						 & MAX_LOCATION_T].locus;

  return IS_MACRO_LOC (location);
}

/* Given two virtual locations *LOC0 and *LOC1, return the first
   common macro map in their macro expansion histories.  Return NULL
   if no common macro was found.  *LOC0 (resp. *LOC1) is set to the
   virtual location of the token inside the resulting macro.  */

static const struct line_map*
first_map_in_common_1 (struct line_maps *set,
		       location_t *loc0,
		       location_t *loc1)
{
  location_t l0 = *loc0, l1 = *loc1;
  const struct line_map *map0 = linemap_lookup (set, l0),
    *map1 = linemap_lookup (set, l1);

  while (linemap_macro_expansion_map_p (map0)
	 && linemap_macro_expansion_map_p (map1)
	 && (map0 != map1))
    {
      if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1))
	{
	  l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0),
						   l0);
	  map0 = linemap_lookup (set, l0);
	}
      else
	{
	  l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1),
						   l1);
	  map1 = linemap_lookup (set, l1);
	}
    }

  if (map0 == map1)
    {
      *loc0 = l0;
      *loc1 = l1;
      return map0;
    }
  return NULL;
}

/* Given two virtual locations LOC0 and LOC1, return the first common
   macro map in their macro expansion histories.  Return NULL if no
   common macro was found.  *RES_LOC0 (resp. *RES_LOC1) is set to the
   virtual location of the token inside the resulting macro, upon
   return of a non-NULL result.  */

static const struct line_map*
first_map_in_common (struct line_maps *set,
		     location_t loc0,
		     location_t loc1,
		     location_t  *res_loc0,
		     location_t  *res_loc1)
{
  *res_loc0 = loc0;
  *res_loc1 = loc1;

  return first_map_in_common_1 (set, res_loc0, res_loc1);
}

/* Return a positive value if PRE denotes the location of a token that
   comes before the token of POST, 0 if PRE denotes the location of
   the same token as the token for POST, and a negative value
   otherwise.  */

int
linemap_compare_locations (struct line_maps *set,
			   location_t  pre,
			   location_t post)
{
  bool pre_virtual_p, post_virtual_p;
  location_t l0 = pre, l1 = post;

  if (IS_ADHOC_LOC (l0))
    l0 = get_location_from_adhoc_loc (set, l0);
  if (IS_ADHOC_LOC (l1))
    l1 = get_location_from_adhoc_loc (set, l1);

  if (l0 == l1)
    return 0;

  if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0)))
    l0 = linemap_resolve_location (set, l0,
				   LRK_MACRO_EXPANSION_POINT,
				   NULL);

  if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1)))
    l1 = linemap_resolve_location (set, l1,
				   LRK_MACRO_EXPANSION_POINT,
				   NULL);

  if (l0 == l1
      && pre_virtual_p
      && post_virtual_p)
    {
      /* So pre and post represent two tokens that are present in a
	 same macro expansion.  Let's see if the token for pre was
	 before the token for post in that expansion.  */
      unsigned i0, i1;
      const struct line_map *map =
	first_map_in_common (set, pre, post, &l0, &l1);

      if (map == NULL)
	/* This should not be possible.  */
	abort ();

      i0 = l0 - MAP_START_LOCATION (map);
      i1 = l1 - MAP_START_LOCATION (map);
      return i1 - i0;
    }

  if (IS_ADHOC_LOC (l0))
    l0 = get_location_from_adhoc_loc (set, l0);
  if (IS_ADHOC_LOC (l1))
    l1 = get_location_from_adhoc_loc (set, l1);

  return l1 - l0;
}

/* Print an include trace, for e.g. the -H option of the preprocessor.  */

static void
trace_include (const struct line_maps *set, const line_map_ordinary *map)
{
  unsigned int i = set->depth;

  while (--i)
    putc ('.', stderr);

  fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map));
}

/* Return the spelling location of the token wherever it comes from,
   whether part of a macro definition or not.

   This is a subroutine for linemap_resolve_location.  */

static location_t
linemap_macro_loc_to_spelling_point (struct line_maps *set,
				     location_t location,
				     const line_map_ordinary **original_map)
{
  linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

  while (true)
    {
      const struct line_map *map = linemap_lookup (set, location);
      if (!map || MAP_ORDINARY_P (map))
	{
	  if (original_map)
	    *original_map = (const line_map_ordinary *)map;
	  break;
	}

      location = linemap_macro_map_loc_unwind_toward_spelling
	(set, linemap_check_macro (map), location);
    }

  return location;
}

/* If LOCATION is the source location of a token that belongs to a
   macro replacement-list -- as part of a macro expansion -- then
   return the location of the token at the definition point of the
   macro.  Otherwise, return LOCATION.  SET is the set of maps
   location come from.  ORIGINAL_MAP is an output parm. If non NULL,
   the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the
   returned location comes from. 

   This is a subroutine of linemap_resolve_location.  */

static location_t
linemap_macro_loc_to_def_point (struct line_maps *set,
				location_t location,
				const line_map_ordinary **original_map)
{
  linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

  for (;;)
    {
      location_t caret_loc = location;
      if (IS_ADHOC_LOC (caret_loc))
	caret_loc = get_location_from_adhoc_loc (set, caret_loc);

      const line_map *map = linemap_lookup (set, caret_loc);
      if (!map || MAP_ORDINARY_P (map))
	{
	  if (original_map)
	    *original_map = (const line_map_ordinary *)map;
	  break;
	}

      location = linemap_macro_map_loc_to_def_point
	(linemap_check_macro (map), caret_loc);
    }

  return location;
}

/* If LOCATION is the source location of a token that belongs to a
   macro replacement-list -- at a macro expansion point -- then return
   the location of the topmost expansion point of the macro.  We say
   topmost because if we are in the context of a nested macro
   expansion, the function returns the source location of the first
   macro expansion that triggered the nested expansions.

   Otherwise, return LOCATION.  SET is the set of maps location come
   from.  ORIGINAL_MAP is an output parm. If non NULL, the function
   sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned
   location comes from.

   This is a subroutine of linemap_resolve_location.  */

static location_t
linemap_macro_loc_to_exp_point (struct line_maps *set,
				location_t location,
				const line_map_ordinary **original_map)
{
  struct line_map *map;

  if (IS_ADHOC_LOC (location))
    location = set->location_adhoc_data_map.data[location
						 & MAX_LOCATION_T].locus;

  linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

  while (true)
    {
      map = const_cast <line_map *> (linemap_lookup (set, location));
      if (!linemap_macro_expansion_map_p (map))
	break;
      location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map),
						     location);
    }

  if (original_map)
    *original_map = linemap_check_ordinary (map);
  return location;
}

/* Resolve a virtual location into either a spelling location, an
   expansion point location or a token argument replacement point
   location.  Return the map that encodes the virtual location as well
   as the resolved location.

   If LOC is *NOT* the location of a token resulting from the
   expansion of a macro, then the parameter LRK (which stands for
   Location Resolution Kind) is ignored and the resulting location
   just equals the one given in argument.

   Now if LOC *IS* the location of a token resulting from the
   expansion of a macro, this is what happens.

   * If LRK is set to LRK_MACRO_EXPANSION_POINT
   -------------------------------

   The virtual location is resolved to the first macro expansion point
   that led to this macro expansion.

   * If LRK is set to LRK_SPELLING_LOCATION
   -------------------------------------

   The virtual location is resolved to the locus where the token has
   been spelled in the source.   This can follow through all the macro
   expansions that led to the token.

   * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
   --------------------------------------

   The virtual location is resolved to the locus of the token in the
   context of the macro definition.

   If LOC is the locus of a token that is an argument of a
   function-like macro [replacing a parameter in the replacement list
   of the macro] the virtual location is resolved to the locus of the
   parameter that is replaced, in the context of the definition of the
   macro.

   If LOC is the locus of a token that is not an argument of a
   function-like macro, then the function behaves as if LRK was set to
   LRK_SPELLING_LOCATION.

   If MAP is not NULL, *MAP is set to the map encoding the
   returned location.  Note that if the returned location wasn't originally
   encoded by a map, then *MAP is set to NULL.  This can happen if LOC
   resolves to a location reserved for the client code, like
   UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC.  */

location_t
linemap_resolve_location (struct line_maps *set,
			  location_t loc,
			  enum location_resolution_kind lrk,
			  const line_map_ordinary **map)
{
  location_t locus = loc;
  if (IS_ADHOC_LOC (loc))
    locus = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;

  if (locus < RESERVED_LOCATION_COUNT)
    {
      /* A reserved location wasn't encoded in a map.  Let's return a
	 NULL map here, just like what linemap_ordinary_map_lookup
	 does.  */
      if (map)
	*map = NULL;
      return loc;
    }

  switch (lrk)
    {
    case LRK_MACRO_EXPANSION_POINT:
      loc = linemap_macro_loc_to_exp_point (set, loc, map);
      break;
    case LRK_SPELLING_LOCATION:
      loc = linemap_macro_loc_to_spelling_point (set, loc, map);
      break;
    case LRK_MACRO_DEFINITION_LOCATION:
      loc = linemap_macro_loc_to_def_point (set, loc, map);
      break;
    default:
      abort ();
    }
  return loc;
}

/* TRUE if LOCATION is a source code location of a token that is part of the
   definition of a macro, FALSE otherwise.  */

bool
linemap_location_from_macro_definition_p (struct line_maps *set,
					  location_t loc)
{
  if (IS_ADHOC_LOC (loc))
    loc = get_location_from_adhoc_loc (set, loc);

  if (!linemap_location_from_macro_expansion_p (set, loc))
    return false;

  while (true)
    {
      const struct line_map_macro *map
	= linemap_check_macro (linemap_lookup (set, loc));

      location_t s_loc
	= linemap_macro_map_loc_unwind_toward_spelling (set, map, loc);
      if (linemap_location_from_macro_expansion_p (set, s_loc))
	loc = s_loc;
      else
	{
	  location_t def_loc
	    = linemap_macro_map_loc_to_def_point (map, loc);
	  return s_loc == def_loc;
	}
    }
}

/* 
   Suppose that LOC is the virtual location of a token T coming from
   the expansion of a macro M.  This function then steps up to get the
   location L of the point where M got expanded.  If L is a spelling
   location inside a macro expansion M', then this function returns
   the locus of the point where M' was expanded.  Said otherwise, this
   function returns the location of T in the context that triggered
   the expansion of M. 

   *LOC_MAP must be set to the map of LOC.  This function then sets it
   to the map of the returned location.  */

location_t
linemap_unwind_toward_expansion (struct line_maps *set,
				 location_t loc,
				 const struct line_map **map)
{
  location_t resolved_location;
  const line_map_macro *macro_map = linemap_check_macro (*map);
  const struct line_map *resolved_map;

  if (IS_ADHOC_LOC (loc))
    loc = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;

  resolved_location =
    linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc);
  resolved_map = linemap_lookup (set, resolved_location);

  if (!linemap_macro_expansion_map_p (resolved_map))
    {
      resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc);
      resolved_map = linemap_lookup (set, resolved_location);
    }

  *map = resolved_map;
  return resolved_location;
}

/* If LOC is the virtual location of a token coming from the expansion
   of a macro M and if its spelling location is reserved (e.g, a
   location for a built-in token), then this function unwinds (using
   linemap_unwind_toward_expansion) the location until a location that
   is not reserved and is not in a system header is reached.  In other
   words, this unwinds the reserved location until a location that is
   in real source code is reached.

   Otherwise, if the spelling location for LOC is not reserved or if
   LOC doesn't come from the expansion of a macro, the function
   returns LOC as is and *MAP is not touched.

   *MAP is set to the map of the returned location if the later is
   different from LOC.  */
location_t
linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
					  location_t loc,
					  const struct line_map **map)
{
  location_t resolved_loc;
  const struct line_map *map0 = NULL;
  const line_map_ordinary *map1 = NULL;

  if (IS_ADHOC_LOC (loc))
    loc = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;

  map0 = linemap_lookup (set, loc);
  if (!linemap_macro_expansion_map_p (map0))
    return loc;

  resolved_loc = linemap_resolve_location (set, loc,
					   LRK_SPELLING_LOCATION,
					   &map1);

  if (resolved_loc >= RESERVED_LOCATION_COUNT
      && !LINEMAP_SYSP (map1))
    return loc;

  while (linemap_macro_expansion_map_p (map0)
	 && (resolved_loc < RESERVED_LOCATION_COUNT
	     || LINEMAP_SYSP (map1)))
    {
      loc = linemap_unwind_toward_expansion (set, loc, &map0);
      resolved_loc = linemap_resolve_location (set, loc,
					       LRK_SPELLING_LOCATION,
					       &map1);
    }

  if (map != NULL)
    *map = map0;
  return loc;
}

/* Expand source code location LOC and return a user readable source
   code location.  LOC must be a spelling (non-virtual) location.  If
   it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
   location is returned.  */

expanded_location
linemap_expand_location (struct line_maps *set,
			 const struct line_map *map,
			 location_t loc)

{
  expanded_location xloc;

  memset (&xloc, 0, sizeof (xloc));
  if (IS_ADHOC_LOC (loc))
    {
      xloc.data
	= set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
      loc = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;
    }

  if (loc < RESERVED_LOCATION_COUNT)
    /* The location for this token wasn't generated from a line map.
       It was probably a location for a builtin token, chosen by some
       client code.  Let's not try to expand the location in that
       case.  */;
  else if (map == NULL)
    /* We shouldn't be getting a NULL map with a location that is not
       reserved by the client code.  */
    abort ();
  else
    {
      /* MAP must be an ordinary map and LOC must be non-virtual,
	 encoded into this map, obviously; the accessors used on MAP
	 below ensure it is ordinary.  Let's just assert the
	 non-virtualness of LOC here.  */
      if (linemap_location_from_macro_expansion_p (set, loc))
	abort ();

      const line_map_ordinary *ord_map = linemap_check_ordinary (map);

      xloc.file = LINEMAP_FILE (ord_map);
      xloc.line = SOURCE_LINE (ord_map, loc);
      xloc.column = SOURCE_COLUMN (ord_map, loc);
      xloc.sysp = LINEMAP_SYSP (ord_map) != 0;
    }

  return xloc;
}


/* Dump line map at index IX in line table SET to STREAM.  If STREAM
   is NULL, use stderr.  IS_MACRO is true if the caller wants to
   dump a macro map, false otherwise.  */

void
linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
{
  const char *const lc_reasons_v[LC_HWM]
      = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
	  "LC_ENTER_MACRO" };
  const line_map *map;
  unsigned reason;

  if (stream == NULL)
    stream = stderr;

  if (!is_macro)
    {
      map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
      reason = linemap_check_ordinary (map)->reason;
    }
  else
    {
      map = LINEMAPS_MACRO_MAP_AT (set, ix);
      reason = LC_ENTER_MACRO;
    }

  fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
	   ix, (void *) map, map->start_location,
	   reason < LC_HWM ? lc_reasons_v[reason] : "???",
	   ((!is_macro
	     && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
	    ? "yes" : "no"));
  if (!is_macro)
    {
      const line_map_ordinary *ord_map = linemap_check_ordinary (map);
      const line_map_ordinary *includer_map
	= linemap_included_from_linemap (set, ord_map);

      fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
	       ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
      fprintf (stream, "Included from: [%d] %s\n",
	       includer_map ? int (includer_map - set->info_ordinary.maps) : -1,
	       includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
    }
  else
    {
      const line_map_macro *macro_map = linemap_check_macro (map);
      fprintf (stream, "Macro: %s (%u tokens)\n",
	       linemap_map_get_macro_name (macro_map),
	       MACRO_MAP_NUM_MACRO_TOKENS (macro_map));
    }

  fprintf (stream, "\n");
}


/* Dump debugging information about source location LOC into the file
   stream STREAM. SET is the line map set LOC comes from.  */

void
linemap_dump_location (struct line_maps *set,
		       location_t loc,
		       FILE *stream)
{
  const line_map_ordinary *map;
  location_t location;
  const char *path = "", *from = "";
  int l = -1, c = -1, s = -1, e = -1;

  if (IS_ADHOC_LOC (loc))
    loc = set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;

  if (loc == 0)
    return;

  location =
    linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map);

  if (map == NULL)
    /* Only reserved locations can be tolerated in this case.  */
    linemap_assert (location < RESERVED_LOCATION_COUNT);
  else
    {
      path = LINEMAP_FILE (map);
      l = SOURCE_LINE (map, location);
      c = SOURCE_COLUMN (map, location);
      s = LINEMAP_SYSP (map) != 0;
      e = location != loc;
      if (e)
	from = "N/A";
      else
	{
	  const line_map_ordinary *from_map
	    = linemap_included_from_linemap (set, map);
	  from = from_map ? LINEMAP_FILE (from_map) : "<NULL>";
	}
    }

  /* P: path, L: line, C: column, S: in-system-header, M: map address,
     E: macro expansion?, LOC: original location, R: resolved location   */
  fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}",
	   path, from, l, c, s, (void*)map, e, loc, location);
}

/* Return the highest location emitted for a given file for which
   there is a line map in SET.  FILE_NAME is the file name to
   consider.  If the function returns TRUE, *LOC is set to the highest
   location emitted for that file.  */

bool
linemap_get_file_highest_location (struct line_maps *set,
				   const char *file_name,
				   location_t *loc)
{
  /* If the set is empty or no ordinary map has been created then
     there is no file to look for ...  */
  if (set == NULL || set->info_ordinary.used == 0)
    return false;

  /* Now look for the last ordinary map created for FILE_NAME.  */
  int i;
  for (i = set->info_ordinary.used - 1; i >= 0; --i)
    {
      const char *fname = set->info_ordinary.maps[i].to_file;
      if (fname && !filename_cmp (fname, file_name))
	break;
    }

  if (i < 0)
    return false;

  /* The highest location for a given map is either the starting
     location of the next map minus one, or -- if the map is the
     latest one -- the highest location of the set.  */
  location_t result;
  if (i == (int) set->info_ordinary.used - 1)
    result = set->highest_location;
  else
    result = set->info_ordinary.maps[i + 1].start_location - 1;

  *loc = result;
  return true;
}

/* Compute and return statistics about the memory consumption of some
   parts of the line table SET.  */

void
linemap_get_statistics (struct line_maps *set,
			struct linemap_stats *s)
{
  long ordinary_maps_allocated_size, ordinary_maps_used_size,
    macro_maps_allocated_size, macro_maps_used_size,
    macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0;

  const line_map_macro *cur_map;

  ordinary_maps_allocated_size =
    LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary);

  ordinary_maps_used_size =
    LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary);

  macro_maps_allocated_size =
    LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro);

  for (cur_map = LINEMAPS_MACRO_MAPS (set);
       cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set);
       ++cur_map)
    {
      unsigned i;

      linemap_assert (linemap_macro_expansion_map_p (cur_map));

      macro_maps_locations_size +=
	2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (location_t);

      for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2)
	{
	  if (MACRO_MAP_LOCATIONS (cur_map)[i] ==
	      MACRO_MAP_LOCATIONS (cur_map)[i + 1])
	    duplicated_macro_maps_locations_size +=
	      sizeof (location_t);
	}
    }

  macro_maps_used_size =
    LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro);

  s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set);
  s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set);
  s->ordinary_maps_allocated_size = ordinary_maps_allocated_size;
  s->ordinary_maps_used_size = ordinary_maps_used_size;
  s->num_expanded_macros = num_expanded_macros_counter;
  s->num_macro_tokens = num_macro_tokens_counter;
  s->num_macro_maps_used = LINEMAPS_MACRO_USED (set);
  s->macro_maps_allocated_size = macro_maps_allocated_size;
  s->macro_maps_locations_size = macro_maps_locations_size;
  s->macro_maps_used_size = macro_maps_used_size;
  s->duplicated_macro_maps_locations_size =
    duplicated_macro_maps_locations_size;
  s->adhoc_table_size = (set->location_adhoc_data_map.allocated
			 * sizeof (struct location_adhoc_data));
  s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc;
}


/* Dump line table SET to STREAM.  If STREAM is NULL, stderr is used.
   NUM_ORDINARY specifies how many ordinary maps to dump.  NUM_MACRO
   specifies how many macro maps to dump.  */

void
line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
		 unsigned int num_macro)
{
  unsigned int i;

  if (set == NULL)
    return;

  if (stream == NULL)
    stream = stderr;

  fprintf (stream, "# of ordinary maps:  %d\n", LINEMAPS_ORDINARY_USED (set));
  fprintf (stream, "# of macro maps:     %d\n", LINEMAPS_MACRO_USED (set));
  fprintf (stream, "Include stack depth: %d\n", set->depth);
  fprintf (stream, "Highest location:    %u\n", set->highest_location);

  if (num_ordinary)
    {
      fprintf (stream, "\nOrdinary line maps\n");
      for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++)
	linemap_dump (stream, set, i, false);
      fprintf (stream, "\n");
    }

  if (num_macro)
    {
      fprintf (stream, "\nMacro line maps\n");
      for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++)
	linemap_dump (stream, set, i, true);
      fprintf (stream, "\n");
    }
}

/* class rich_location.  */

/* Construct a rich_location with location LOC as its initial range.  */

rich_location::rich_location (line_maps *set, location_t loc,
			      const range_label *label) :
  m_line_table (set),
  m_ranges (),
  m_column_override (0),
  m_have_expanded_location (false),
  m_fixit_hints (),
  m_seen_impossible_fixit (false),
  m_fixits_cannot_be_auto_applied (false)
{
  add_range (loc, SHOW_RANGE_WITH_CARET, label);
}

/* The destructor for class rich_location.  */

rich_location::~rich_location ()
{
  for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
    delete get_fixit_hint (i);
}

/* Get location IDX within this rich_location.  */

location_t
rich_location::get_loc (unsigned int idx) const
{
  const location_range *locrange = get_range (idx);
  return locrange->m_loc;
}

/* Get range IDX within this rich_location.  */

const location_range *
rich_location::get_range (unsigned int idx) const
{
  return &m_ranges[idx];
}

/* Mutable access to range IDX within this rich_location.  */

location_range *
rich_location::get_range (unsigned int idx)
{
  return &m_ranges[idx];
}

/* Expand location IDX within this rich_location.  */
/* Get an expanded_location for this rich_location's primary
   location.  */

expanded_location
rich_location::get_expanded_location (unsigned int idx)
{
  if (idx == 0)
   {
     /* Cache the expansion of the primary location.  */
     if (!m_have_expanded_location)
       {
	  m_expanded_location
	    = linemap_client_expand_location_to_spelling_point
		(get_loc (0), LOCATION_ASPECT_CARET);
	  if (m_column_override)
	    m_expanded_location.column = m_column_override;
	  m_have_expanded_location = true;
       }

     return m_expanded_location;
   }
  else
    return linemap_client_expand_location_to_spelling_point
	     (get_loc (idx), LOCATION_ASPECT_CARET);
}

/* Set the column of the primary location, with 0 meaning
   "don't override it".  */

void
rich_location::override_column (int column)
{
  m_column_override = column;
  m_have_expanded_location = false;
}

/* Add the given range.  */

void
rich_location::add_range (location_t loc,
			  enum range_display_kind range_display_kind,
			  const range_label *label)
{
  location_range range;
  range.m_loc = loc;
  range.m_range_display_kind = range_display_kind;
  range.m_label = label;
  m_ranges.push (range);
}

/* Add or overwrite the location given by IDX, setting its location to LOC,
   and setting its m_range_display_kind to RANGE_DISPLAY_KIND.

   It must either overwrite an existing location, or add one *exactly* on
   the end of the array.

   This is primarily for use by gcc when implementing diagnostic format
   decoders e.g.
   - the "+" in the C/C++ frontends, for handling format codes like "%q+D"
     (which writes the source location of a tree back into location 0 of
     the rich_location), and
   - the "%C" and "%L" format codes in the Fortran frontend.  */

void
rich_location::set_range (unsigned int idx, location_t loc,
			  enum range_display_kind range_display_kind)
{
  /* We can either overwrite an existing range, or add one exactly
     on the end of the array.  */
  linemap_assert (idx <= m_ranges.count ());

  if (idx == m_ranges.count ())
    add_range (loc, range_display_kind);
  else
    {
      location_range *locrange = get_range (idx);
      locrange->m_loc = loc;
      locrange->m_range_display_kind = range_display_kind;
    }

  if (idx == 0)
    /* Mark any cached value here as dirty.  */
    m_have_expanded_location = false;
}

/* Methods for adding insertion fix-it hints.  */

/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
   immediately before the primary range's start location.  */

void
rich_location::add_fixit_insert_before (const char *new_content)
{
  add_fixit_insert_before (get_loc (), new_content);
}

/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
   immediately before the start of WHERE.  */

void
rich_location::add_fixit_insert_before (location_t where,
					const char *new_content)
{
  location_t start = get_range_from_loc (m_line_table, where).m_start;
  maybe_add_fixit (start, start, new_content);
}

/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
   immediately after the primary range's end-point.  */

void
rich_location::add_fixit_insert_after (const char *new_content)
{
  add_fixit_insert_after (get_loc (), new_content);
}

/* Add a fixit-hint, suggesting insertion of NEW_CONTENT
   immediately after the end-point of WHERE.  */

void
rich_location::add_fixit_insert_after (location_t where,
				       const char *new_content)
{
  location_t finish = get_range_from_loc (m_line_table, where).m_finish;
  location_t next_loc
    = linemap_position_for_loc_and_offset (m_line_table, finish, 1);

  /* linemap_position_for_loc_and_offset can fail, if so, it returns
     its input value.  */
  if (next_loc == finish)
    {
      stop_supporting_fixits ();
      return;
    }

  maybe_add_fixit (next_loc, next_loc, new_content);
}

/* Methods for adding removal fix-it hints.  */

/* Add a fixit-hint, suggesting removal of the content covered
   by range 0.  */

void
rich_location::add_fixit_remove ()
{
  add_fixit_remove (get_loc ());
}

/* Add a fixit-hint, suggesting removal of the content between
   the start and finish of WHERE.  */

void
rich_location::add_fixit_remove (location_t where)
{
  source_range range = get_range_from_loc (m_line_table, where);
  add_fixit_remove (range);
}

/* Add a fixit-hint, suggesting removal of the content at
   SRC_RANGE.  */

void
rich_location::add_fixit_remove (source_range src_range)
{
  add_fixit_replace (src_range, "");
}

/* Add a fixit-hint, suggesting replacement of the content covered
   by range 0 with NEW_CONTENT.  */

void
rich_location::add_fixit_replace (const char *new_content)
{
  add_fixit_replace (get_loc (), new_content);
}

/* Methods for adding "replace" fix-it hints.  */

/* Add a fixit-hint, suggesting replacement of the content between
   the start and finish of WHERE with NEW_CONTENT.  */

void
rich_location::add_fixit_replace (location_t where,
				  const char *new_content)
{
  source_range range = get_range_from_loc (m_line_table, where);
  add_fixit_replace (range, new_content);
}

/* Add a fixit-hint, suggesting replacement of the content at
   SRC_RANGE with NEW_CONTENT.  */

void
rich_location::add_fixit_replace (source_range src_range,
				  const char *new_content)
{
  location_t start = get_pure_location (m_line_table, src_range.m_start);
  location_t finish = get_pure_location (m_line_table, src_range.m_finish);

  /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint.  */
  location_t next_loc
    = linemap_position_for_loc_and_offset (m_line_table, finish, 1);
  /* linemap_position_for_loc_and_offset can fail, if so, it returns
     its input value.  */
  if (next_loc == finish)
    {
      stop_supporting_fixits ();
      return;
    }
  finish = next_loc;

  maybe_add_fixit (start, finish, new_content);
}

/* Get the last fix-it hint within this rich_location, or NULL if none.  */

fixit_hint *
rich_location::get_last_fixit_hint () const
{
  if (m_fixit_hints.count () > 0)
    return get_fixit_hint (m_fixit_hints.count () - 1);
  else
    return NULL;
}

/* If WHERE is an "awkward" location, then mark this rich_location as not
   supporting fixits, purging any thay were already added, and return true.

   Otherwise (the common case), return false.  */

bool
rich_location::reject_impossible_fixit (location_t where)
{
  /* Fix-its within a rich_location should either all be suggested, or
     none of them should be suggested.
     Once we've rejected a fixit, we reject any more, even those
     with reasonable locations.  */
  if (m_seen_impossible_fixit)
    return true;

  if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS)
    /* WHERE is a reasonable location for a fix-it; don't reject it.  */
    return false;

  /* Otherwise we have an attempt to add a fix-it with an "awkward"
     location: either one that we can't obtain column information
     for (within an ordinary map), or one within a macro expansion.  */
  stop_supporting_fixits ();
  return true;
}

/* Mark this rich_location as not supporting fixits, purging any that were
   already added.  */

void
rich_location::stop_supporting_fixits ()
{
  m_seen_impossible_fixit = true;

  /* Purge the rich_location of any fix-its that were already added. */
  for (unsigned int i = 0; i < m_fixit_hints.count (); i++)
    delete get_fixit_hint (i);
  m_fixit_hints.truncate (0);
}

/* Add HINT to the fix-it hints in this rich_location,
   consolidating into the prior fixit if possible.  */

void
rich_location::maybe_add_fixit (location_t start,
				location_t next_loc,
				const char *new_content)
{
  if (reject_impossible_fixit (start))
    return;
  if (reject_impossible_fixit (next_loc))
    return;

  /* Only allow fix-it hints that affect a single line in one file.
     Compare the end-points.  */
  expanded_location exploc_start
    = linemap_client_expand_location_to_spelling_point (start,
							LOCATION_ASPECT_START);
  expanded_location exploc_next_loc
    = linemap_client_expand_location_to_spelling_point (next_loc,
							LOCATION_ASPECT_START);
  /* They must be within the same file...  */
  if (exploc_start.file != exploc_next_loc.file)
    {
      stop_supporting_fixits ();
      return;
    }
  /* ...and on the same line.  */
  if (exploc_start.line != exploc_next_loc.line)
    {
      stop_supporting_fixits ();
      return;
    }
  /* The columns must be in the correct order.  This can fail if the
     endpoints straddle the boundary for which the linemap can represent
     columns (PR c/82050).  */
  if (exploc_start.column > exploc_next_loc.column)
    {
      stop_supporting_fixits ();
      return;
    }

  const char *newline = strchr (new_content, '\n');
  if (newline)
    {
      /* For now, we can only support insertion of whole lines
	 i.e. starts at start of line, and the newline is at the end of
	 the insertion point.  */

      /* It must be an insertion, not a replacement/deletion.  */
      if (start != next_loc)
	{
	  stop_supporting_fixits ();
	  return;
	}

      /* The insertion must be at the start of a line.  */
      if (exploc_start.column != 1)
	{
	  stop_supporting_fixits ();
	  return;
	}

      /* The newline must be at end of NEW_CONTENT.
	 We could eventually split up fix-its at newlines if we wanted
	 to allow more generality (e.g. to allow adding multiple lines
	 with one add_fixit call.  */
      if (newline[1] != '\0')
	{
	  stop_supporting_fixits ();
	  return;
	}
    }

  /* Consolidate neighboring fixits.
     Don't consolidate into newline-insertion fixits.  */
  fixit_hint *prev = get_last_fixit_hint ();
  if (prev && !prev->ends_with_newline_p ())
    if (prev->maybe_append (start, next_loc, new_content))
      return;

  m_fixit_hints.push (new fixit_hint (start, next_loc, new_content));
}

/* class fixit_hint.  */

fixit_hint::fixit_hint (location_t start,
			location_t next_loc,
			const char *new_content)
: m_start (start),
  m_next_loc (next_loc),
  m_bytes (xstrdup (new_content)),
  m_len (strlen (new_content))
{
}

/* Does this fix-it hint affect the given line?  */

bool
fixit_hint::affects_line_p (const char *file, int line) const
{
  expanded_location exploc_start
    = linemap_client_expand_location_to_spelling_point (m_start,
							LOCATION_ASPECT_START);
  if (file != exploc_start.file)
    return false;
  if (line < exploc_start.line)
      return false;
  expanded_location exploc_next_loc
    = linemap_client_expand_location_to_spelling_point (m_next_loc,
							LOCATION_ASPECT_START);
  if (file != exploc_next_loc.file)
    return false;
  if (line > exploc_next_loc.line)
      return false;
  return true;
}

/* Method for consolidating fix-it hints, for use by
   rich_location::maybe_add_fixit.
   If possible, merge a pending fix-it hint with the given params
   into this one and return true.
   Otherwise return false.  */

bool
fixit_hint::maybe_append (location_t start,
			  location_t next_loc,
			  const char *new_content)
{
  /* For consolidation to be possible, START must be at this hint's
     m_next_loc.  */
  if (start != m_next_loc)
    return false;

  /* If so, we have neighboring replacements; merge them.  */
  m_next_loc = next_loc;
  size_t extra_len = strlen (new_content);
  m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1);
  memcpy (m_bytes + m_len, new_content, extra_len);
  m_len += extra_len;
  m_bytes[m_len] = '\0';
  return true;
}

/* Return true iff this hint's content ends with a newline.  */

bool
fixit_hint::ends_with_newline_p () const
{
  if (m_len == 0)
    return false;
  return m_bytes[m_len - 1] == '\n';
}
