This patch adds support in the libcpp line-maps infrastructure for a 64-bit
location_t type that is capable of representing more source locations than
the current 32-bit location_t. The support will be made configurable at
build time in a subsequent patch; for now it will be off by default.

libcpp/ChangeLog:

        * include/line-map.h (location_t): Conditionally make this typedef a
        64-bit integer if so configured, and adjust related constants to
        match.
        (line_map_uint_t): New typedef, the same type as location_t.
        (struct line_map): Adjust comments about the struct layout.
        (struct line_map_macro): Likewise.
        (struct line_map_ordinary): Likewise, and also reorder the fields to
        avoid padding in case 64-bit location was configured.
        (struct maps_info_ordinary): Change member types from "unsigned int"
        to "line_map_uint_t".
        (struct maps_info_macro): Likewise.
        (struct location_adhoc_data_map): Likewise.
        (LINEMAPS_ALLOCATED): Change return type from "unsigned int" to
        "line_map_uint_t".
        (LINEMAPS_ORDINARY_ALLOCATED): Likewise.
        (LINEMAPS_MACRO_ALLOCATED): Likewise.
        (LINEMAPS_USED): Likewise.
        (LINEMAPS_ORDINARY_USED): Likewise.
        (LINEMAPS_MACRO_USED): Likewise.
        (linemap_lookup_macro_index): Likewise.
        (LINEMAPS_MAP_AT): Change argument type from "unsigned int" to
        "line_map_uint_t".
        (LINEMAPS_ORDINARY_MAP_AT): Likewise.
        (LINEMAPS_MACRO_MAP_AT): Likewise.
        (line_map_new_raw): Likewise.
        (linemap_module_restore): Likewise.
        (linemap_dump): Likewise.
        (line_table_dump): Likewise.
        (LINEMAPS_LAST_MAP): Add a linemap_assert() for safety.
        (SOURCE_COLUMN): Handle 64-bit location_t.
        * line-map.cc (location_adhoc_data_hash): Don't truncate locations
        to 32-bit prematurely.
        (line_maps::get_or_create_combined_loc): Adapt types to support
        64-bit location_t. Use MAX_LOCATION_T rather than a hard-coded
        constant.
        (line_maps::get_range_from_loc): Adapt types and constants to
        support 64-bit location_t.
        (line_maps::pure_location_p): Likewise.
        (line_maps::get_pure_location): Likewise.
        (line_map_new_raw): Likewise.
        (LAST_SOURCE_LINE_LOCATION): Likewise.
        (linemap_add): Likewise.
        (linemap_module_restore): Likewise.
        (linemap_line_start): Likewise.
        (linemap_position_for_column): Likewise.
        (linemap_position_for_line_and_column): Likewise.
        (linemap_position_for_loc_and_offset): Likewise.
        (linemap_ordinary_map_lookup): Likewise.
        (linemap_lookup_macro_index): Likewise.
        (linemap_dump): Likewise.
        (linemap_dump_location): Likewise.
        (linemap_get_file_highest_location): Likewise.
        (line_table_dump): Likewise.
        (linemap_compare_locations): Avoid signed int overflow in the result.
        * include/cpplib.h (struct cpp_identifier): Update comment about the
        struct layout.
        * macro.cc (num_expanded_macros_counter): Change type of global
        variable from "unsigned int" to "line_map_uint_t".
        (num_macro_tokens_counter): Likewise.
---
 libcpp/include/cpplib.h   |   3 +-
 libcpp/include/line-map.h | 139 +++++++++++++++++++++++++-------------
 libcpp/line-map.cc        | 138 +++++++++++++++++++++----------------
 libcpp/macro.cc           |   4 +-
 4 files changed, 176 insertions(+), 108 deletions(-)

diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 267d28147ab..f4913ac4313 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -256,7 +256,8 @@ struct GTY(()) cpp_identifier {
 };
 
 /* A preprocessing token.  This has been carefully packed and should
-   occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
+   occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  With
+   64-bit locations enabled, it occupies rather 32 bytes.  */
 struct GTY(()) cpp_token {
 
   /* Location of first char of token, together with range of full token.  */
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 732ec5e6445..65610b5a2ef 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -291,7 +291,12 @@ enum lc_reason
 
    To further see how location_t works in practice, see the
    worked example in libcpp/location-example.txt.  */
+
+#ifndef ENABLE_LARGE_SOURCE_LOCATIONS
+
+static constexpr bool LINE_MAP_LARGE_MODE = false;
 typedef unsigned int location_t;
+typedef int location_diff_t;
 
 /* Do not track column numbers higher than this one.  As a result, the
    range of column_bits is [12, 18] (or 0 if column numbers are
@@ -311,6 +316,43 @@ const location_t LINE_MAP_MAX_LOCATION_WITH_COLS = 
0x60000000;
 /* Highest possible source location encoded within an ordinary map.  */
 const location_t LINE_MAP_MAX_LOCATION = 0x70000000;
 
+/* This is the highest possible source location encoded within an
+   ordinary or macro map.  */
+const location_t MAX_LOCATION_T = 0x7FFFFFFF;
+
+/* This is the number of range bits suggested to enable, if range tracking is
+   desired.  */
+const int line_map_suggested_range_bits = 5;
+
+#else
+
+static constexpr bool LINE_MAP_LARGE_MODE = true;
+typedef uint64_t location_t;
+typedef int64_t location_diff_t;
+
+/* In 64-bit mode, we only use 63 of the 64 bits, so that two location_t can be
+   safely subtracted and stored in an int64_t.  As in the 32-bit case, we
+   reserve half of the values for ad-hoc locations and the other half for
+   ordinary and macro map locations.  We do not limit the max column number,
+   other than ensuring it fits in a signed 32-bit int.  */
+
+const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 31) - 1;
+const location_t LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
+  = location_t (0x50000000) << 31;
+const location_t LINE_MAP_MAX_LOCATION_WITH_COLS
+  = location_t (0x60000000) << 31;
+const location_t LINE_MAP_MAX_LOCATION = location_t (0x70000000) << 31;
+const location_t MAX_LOCATION_T = location_t (-1) >> 2;
+const int line_map_suggested_range_bits = 7;
+
+#endif
+
+/* Sometimes we need a type that has the same size as location_t but that does
+   not represent a location.  This typedef provides more clarity in those
+   cases.  */
+
+typedef location_t line_map_uint_t;
+
 /* A range of source locations.
 
    Ranges are closed:
@@ -387,7 +429,7 @@ typedef size_t (*line_map_round_alloc_size_func) (size_t);
 struct GTY((tag ("0"), desc ("MAP_ORDINARY_P (&%h) ? 1 : 2"))) line_map {
   location_t start_location;
 
-  /* Size and alignment is (usually) 4 bytes.  */
+  /* Size and alignment is 4 (8) bytes for 32-bit (64-bit) locations.  */
 };
 
 /* An ordinary line map encodes physical source locations. Those
@@ -403,7 +445,7 @@ struct GTY((tag ("0"), desc ("MAP_ORDINARY_P (&%h) ? 1 : 
2"))) line_map {
 
    The highest possible source location is MAX_LOCATION_T.  */
 struct GTY((tag ("1"))) line_map_ordinary : public line_map {
-  /* Base class is 4 bytes.  */
+  /* Base class is 4 (8) bytes for 32-bit (64-bit) locations.  */
 
   /* 4 bytes of integers, each 1 byte for easy extraction/insertion.  */
 
@@ -435,9 +477,7 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map 
{
      +-------------------------+-----------------------+-------------------+ */
   unsigned int m_range_bits : 8;
 
-  /* Pointer alignment boundary on both 32 and 64-bit systems.  */
-
-  const char *to_file;
+  /* 32-bit int even in 64-bit mode.  */
   linenum_type to_line;
 
   /* Location from whence this line map was included.  For regular
@@ -446,12 +486,14 @@ struct GTY((tag ("1"))) line_map_ordinary : public 
line_map {
      within a map.  */
   location_t included_from;
 
-  /* Size is 20 or 24 bytes, no padding  */
-};
+  /* Pointer alignment boundary, whether 32-bit or 64-bit mode.  */
+  const char *to_file;
 
-/* This is the highest possible source location encoded within an
-   ordinary or macro map.  */
-const location_t MAX_LOCATION_T = 0x7FFFFFFF;
+  /* Size is one of the following, no padding needed:
+     32-bit system: 20 bytes
+     64-bit system, 32-bit locations: 24 bytes
+     64-bit system, 64-bit locations: 32 bytes.  */
+};
 
 struct cpp_hashnode;
 
@@ -470,7 +512,7 @@ struct GTY((tag ("2"))) line_map_macro : public line_map {
     return m_expansion;
   }
 
-  /* Base is 4 bytes.  */
+  /* Base is 4 (8) bytes for 32-bit (64-bit) locations.  */
 
   /* The number of tokens inside the replacement-list of MACRO.  */
   unsigned int n_tokens;
@@ -546,7 +588,10 @@ struct GTY((tag ("2"))) line_map_macro : public line_map {
      if we are in a nested expansion context not.  */
   location_t m_expansion;
 
-  /* Size is 20 or 32 (4 bytes padding on 64-bit).  */
+  /* Size is one of the following:
+     32-bit system: 20 bytes (no padding)
+     64-bit system, 32-bit locations: 32 bytes (4 of which are padding)
+     64-bit system, 64-bit locations: 40 bytes (8 of which are padding).  */
 };
 
 #if CHECKING_P && (GCC_VERSION >= 2007)
@@ -728,15 +773,15 @@ struct GTY(()) maps_info_ordinary {
   line_map_ordinary * GTY ((length ("%h.used"))) maps;
 
   /* The total number of allocated maps.  */
-  unsigned int allocated;
+  line_map_uint_t allocated;
 
   /* The number of elements used in maps. This number is smaller
      or equal to ALLOCATED.  */
-  unsigned int used;
+  line_map_uint_t used;
 
   /* The index of the last ordinary map that was looked up with
      linemap_lookup.  */
-  mutable unsigned int m_cache;
+  mutable line_map_uint_t m_cache;
 };
 
 struct GTY(()) maps_info_macro {
@@ -745,15 +790,15 @@ struct GTY(()) maps_info_macro {
   line_map_macro * GTY ((length ("%h.used"))) maps;
 
   /* The total number of allocated maps.  */
-  unsigned int allocated;
+  line_map_uint_t allocated;
 
   /* The number of elements used in maps. This number is smaller
      or equal to ALLOCATED.  */
-  unsigned int used;
+  line_map_uint_t used;
 
   /* The index of the last macro map that was looked up with
      linemap_lookup.  */
-  mutable unsigned int m_cache;
+  mutable line_map_uint_t m_cache;
 };
 
 /* Data structure to associate a source_range together with an arbitrary
@@ -780,7 +825,7 @@ struct htab;
 struct GTY(()) location_adhoc_data_map {
   struct htab * GTY((skip)) htab;
   location_t curr_loc;
-  unsigned int allocated;
+  line_map_uint_t allocated;
   struct location_adhoc_data GTY((length ("%h.allocated"))) *data;
 };
 
@@ -861,13 +906,13 @@ public:
   /* The default value of range_bits in ordinary line maps.  */
   unsigned int default_range_bits;
 
-  unsigned int m_num_optimized_ranges;
-  unsigned int m_num_unoptimized_ranges;
+  line_map_uint_t m_num_optimized_ranges;
+  line_map_uint_t m_num_unoptimized_ranges;
 };
 
 /* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
    if we are interested in macro maps, FALSE otherwise.  */
-inline unsigned int
+inline line_map_uint_t
 LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind)
 {
   if (map_kind)
@@ -878,7 +923,7 @@ LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind)
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
-inline unsigned int &
+inline line_map_uint_t &
 LINEMAPS_ALLOCATED (line_maps *set, bool map_kind)
 {
   if (map_kind)
@@ -889,7 +934,7 @@ LINEMAPS_ALLOCATED (line_maps *set, bool map_kind)
 
 /* Returns the number of used maps so far. MAP_KIND shall be TRUE if
    we are interested in macro maps, FALSE otherwise.*/
-inline unsigned int
+inline line_map_uint_t
 LINEMAPS_USED (const line_maps *set, bool map_kind)
 {
   if (map_kind)
@@ -900,7 +945,7 @@ LINEMAPS_USED (const line_maps *set, bool map_kind)
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
-inline unsigned int &
+inline line_map_uint_t &
 LINEMAPS_USED (line_maps *set, bool map_kind)
 {
   if (map_kind)
@@ -911,7 +956,7 @@ LINEMAPS_USED (line_maps *set, bool map_kind)
 
 /* Return the map at a given index.  */
 inline line_map *
-LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index)
+LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, line_map_uint_t index)
 {
   if (map_kind)
     return &set->info_macro.maps[index];
@@ -925,29 +970,29 @@ LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int 
index)
 inline line_map *
 LINEMAPS_LAST_MAP (const line_maps *set, bool map_kind)
 {
+  linemap_assert (LINEMAPS_USED (set, map_kind));
   return LINEMAPS_MAP_AT (set, map_kind,
                          LINEMAPS_USED (set, map_kind) - 1);
 }
 
 /* Returns the INDEXth ordinary map.  */
 inline line_map_ordinary *
-LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, int index)
+LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, line_map_uint_t index)
 {
-  linemap_assert (index >= 0
-                 && (unsigned int)index < LINEMAPS_USED (set, false));
+  linemap_assert (index < LINEMAPS_USED (set, false));
   return (line_map_ordinary *)LINEMAPS_MAP_AT (set, false, index);
 }
 
 /* Return the number of ordinary maps allocated in the line table
    SET.  */
-inline unsigned int
+inline line_map_uint_t
 LINEMAPS_ORDINARY_ALLOCATED (const line_maps *set)
 {
   return LINEMAPS_ALLOCATED (set, false);
 }
 
 /* Return the number of ordinary maps used in the line table SET.  */
-inline unsigned int
+inline line_map_uint_t
 LINEMAPS_ORDINARY_USED (const line_maps *set)
 {
   return LINEMAPS_USED (set, false);
@@ -963,23 +1008,22 @@ LINEMAPS_LAST_ORDINARY_MAP (const line_maps *set)
 
 /* Returns the INDEXth macro map.  */
 inline line_map_macro *
-LINEMAPS_MACRO_MAP_AT (const line_maps *set, int index)
+LINEMAPS_MACRO_MAP_AT (const line_maps *set, line_map_uint_t index)
 {
-  linemap_assert (index >= 0
-                 && (unsigned int)index < LINEMAPS_USED (set, true));
+  linemap_assert (index < LINEMAPS_USED (set, true));
   return (line_map_macro *)LINEMAPS_MAP_AT (set, true, index);
 }
 
 /* Returns the number of macro maps that were allocated in the line
    table SET.  */
-inline unsigned int
+inline line_map_uint_t
 LINEMAPS_MACRO_ALLOCATED (const line_maps *set)
 {
   return LINEMAPS_ALLOCATED (set, true);
 }
 
 /* Returns the number of macro maps used in the line table SET.  */
-inline unsigned int
+inline line_map_uint_t
 LINEMAPS_MACRO_USED (const line_maps *set)
 {
   return LINEMAPS_USED (set, true);
@@ -1044,7 +1088,7 @@ extern location_t linemap_line_start
 (class line_maps *set, linenum_type to_line,  unsigned int max_column_hint);
 
 /* Allocate a raw block of line maps, zero initialized.  */
-extern line_map *line_map_new_raw (line_maps *, bool, unsigned);
+extern line_map *line_map_new_raw (line_maps *, bool, line_map_uint_t);
 
 /* Add a mapping of logical source line to physical source file and
    line number. This function creates an "ordinary map", which is a
@@ -1094,8 +1138,8 @@ extern void linemap_module_reparent
 
 /* Restore the linemap state such that the map at LWM-1 continues.
    Return start location of the new map.  */
-extern unsigned linemap_module_restore
-  (line_maps *, unsigned lwm);
+extern location_t linemap_module_restore
+  (line_maps *, line_map_uint_t lwm);
 
 /* Given a logical source location, returns the map which the
    corresponding (source file, line, column) triplet can be deduced
@@ -1106,7 +1150,7 @@ extern unsigned linemap_module_restore
 extern const line_map *linemap_lookup
   (const line_maps *, location_t);
 
-unsigned linemap_lookup_macro_index (const line_maps *, location_t);
+line_map_uint_t linemap_lookup_macro_index (const line_maps *, location_t);
 
 /* Returns TRUE if the line table set tracks token locations across
    macro expansion, FALSE otherwise.  */
@@ -1165,7 +1209,8 @@ inline linenum_type
 SOURCE_COLUMN (const line_map_ordinary *ord_map, location_t loc)
 {
   return ((loc - ord_map->start_location)
-         & ((1 << ord_map->m_column_and_range_bits) - 1)) >> 
ord_map->m_range_bits;
+         & ((location_t (1) << ord_map->m_column_and_range_bits) - 1))
+    >> ord_map->m_range_bits;
 }
 
 
@@ -1244,9 +1289,10 @@ const struct line_map *first_map_in_common (const 
line_maps *set,
    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 (const line_maps *set,
-                              location_t   pre,
-                              location_t   post);
+int
+linemap_compare_locations (const line_maps *set,
+                          location_t pre,
+                          location_t post);
 
 /* Return TRUE if LOC_A denotes the location a token that comes
    topogically before the token denoted by location LOC_B, or if they
@@ -1413,12 +1459,13 @@ void linemap_dump_location (const line_maps *, 
location_t, FILE *);
 /* 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 *, const line_maps *, unsigned, bool);
+void linemap_dump (FILE *, const line_maps *, line_map_uint_t, bool);
 
 /* 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 *, const line_maps *, unsigned int, unsigned int);
+void line_table_dump (FILE *, const line_maps *,
+                     line_map_uint_t, line_map_uint_t);
 
 /* An enum for distinguishing the various parts within a location_t.  */
 
diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc
index ac765c78bf5..8ad31b1e755 100644
--- a/libcpp/line-map.cc
+++ b/libcpp/line-map.cc
@@ -26,6 +26,10 @@ along with this program; see the file COPYING3.  If not see
 #include "internal.h"
 #include "hashtab.h"
 
+/* Useful for the bit manipulations in this file, since the size of a 
location_t
+   is configurable.  */
+static constexpr location_t loc_one = 1;
+
 static void trace_include (const line_maps *, const line_map_ordinary *);
 static const line_map_ordinary * linemap_ordinary_map_lookup (const line_maps 
*,
                                                              location_t);
@@ -45,8 +49,8 @@ static location_t linemap_macro_loc_to_exp_point (const 
line_maps *,
                                                  const line_map_ordinary **);
 
 /* Counters defined in macro.cc.  */
-extern unsigned num_expanded_macros_counter;
-extern unsigned num_macro_tokens_counter;
+extern line_map_uint_t num_expanded_macros_counter;
+extern line_map_uint_t num_macro_tokens_counter;
 
 /* Destructor for class line_maps.
    Ensure non-GC-managed memory is released.  */
@@ -64,11 +68,11 @@ 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
-         + lb->discriminator);
+  return lb->locus
+    + lb->src_range.m_start
+    + lb->src_range.m_finish
+    + (size_t) lb->data
+    + lb->discriminator;
 }
 
 /* Compare function for location_adhoc_data hashtable.  */
@@ -197,9 +201,9 @@ line_maps::get_or_create_combined_loc (location_t locus,
       linemap_assert (pure_location_p (locus));
       const line_map *map = linemap_lookup (this, 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))
+      auto int_diff = src_range.m_finish - src_range.m_start;
+      auto col_diff = (int_diff >> ordmap->m_range_bits);
+      if (col_diff < (loc_one << ordmap->m_range_bits))
        {
          location_t packed = locus | col_diff;
          m_num_optimized_ranges++;
@@ -255,7 +259,7 @@ line_maps::get_or_create_combined_loc (location_t locus,
       m_location_adhoc_data_map.data[m_location_adhoc_data_map.curr_loc++]
        = lb;
     }
-  return ((*slot) - m_location_adhoc_data_map.data) | 0x80000000;
+  return ((*slot) - m_location_adhoc_data_map.data) | (1 + MAX_LOCATION_T);
 }
 
 /* Construct a location with caret at CARET, ranging from START to
@@ -339,7 +343,7 @@ line_maps::get_range_from_loc (location_t loc) const
       const line_map *map = linemap_lookup (this, loc);
       const line_map_ordinary *ordmap = linemap_check_ordinary (map);
       source_range result;
-      int offset = loc & ((1 << ordmap->m_range_bits) - 1);
+      auto offset = loc & ((loc_one << ordmap->m_range_bits) - 1);
       result.m_start = loc - offset;
       result.m_finish = result.m_start + (offset << ordmap->m_range_bits);
       return result;
@@ -378,7 +382,7 @@ line_maps::pure_location_p (location_t loc) const
     return true;
   const line_map_ordinary *ordmap = linemap_check_ordinary (map);
 
-  if (loc & ((1U << ordmap->m_range_bits) - 1))
+  if (loc & ((loc_one << ordmap->m_range_bits) - 1))
     return false;
 
   return true;
@@ -408,7 +412,7 @@ line_maps::get_pure_location (location_t loc) const
   const line_map *map = linemap_lookup (this, loc);
   const line_map_ordinary *ordmap = linemap_check_ordinary (map);
 
-  return loc & ~((1 << ordmap->m_range_bits) - 1);
+  return loc & ~((loc_one << ordmap->m_range_bits) - 1);
 }
 
 location_t
@@ -464,10 +468,10 @@ linemap_check_files_exited (const line_maps *set)
 /* Create NUM zero-initialized maps of type MACRO_P.  */
 
 line_map *
-line_map_new_raw (line_maps *set, bool macro_p, unsigned num)
+line_map_new_raw (line_maps *set, bool macro_p, line_map_uint_t num)
 {
-  unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
-  unsigned num_maps_used = LINEMAPS_USED (set, macro_p);
+  auto num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
+  auto num_maps_used = LINEMAPS_USED (set, macro_p);
 
   if (num > num_maps_allocated - num_maps_used)
     {
@@ -504,7 +508,7 @@ line_map_new_raw (line_maps *set, bool macro_p, unsigned 
num)
       /* 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;
+      line_map_uint_t num_maps = alloc_size / size_of_a_map;
       buffer = set->m_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);
@@ -546,7 +550,7 @@ LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
 {
   return (((map[1].start_location - 1
            - map->start_location)
-          & ~((1 << map->m_column_and_range_bits) - 1))
+          & ~((loc_one << map->m_column_and_range_bits) - 1))
          + map->start_location);
 }
 
@@ -573,8 +577,8 @@ linemap_add (line_maps *set, enum lc_reason reason,
   unsigned range_bits = 0;
   if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS)
     range_bits = set->default_range_bits;
-  start_location += (1 << range_bits) - 1;
-  start_location &=  ~((1 << range_bits) - 1);
+  start_location += (loc_one << range_bits) - 1;
+  start_location &=  ~((loc_one << range_bits) - 1);
 
   linemap_assert (!LINEMAPS_ORDINARY_USED (set)
                  || (start_location
@@ -660,7 +664,7 @@ linemap_add (line_maps *set, enum lc_reason reason,
        /* 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))
+             & ~((loc_one << map[-1].m_column_and_range_bits) - 1))
             + map[-1].start_location);
       set->depth++;
       if (set->trace_includes)
@@ -707,8 +711,8 @@ linemap_module_reparent (line_maps *set, location_t loc, 
location_t adoptor)
    Append a new map, continuing the interrupted one.  Return the start location
    of the new map, or 0 if failed (because we ran out of locations.  */
 
-unsigned
-linemap_module_restore (line_maps *set, unsigned lwm)
+location_t
+linemap_module_restore (line_maps *set, line_map_uint_t lwm)
 {
   linemap_assert (lwm);
 
@@ -847,7 +851,7 @@ linemap_line_start (line_maps *set, linenum_type to_line,
   location_t r;
   linenum_type last_line =
     SOURCE_LINE (map, set->highest_line);
-  int line_delta = to_line - last_line;
+  auto line_delta = (linenum_arith_t) to_line - (linenum_arith_t) 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;
@@ -897,7 +901,8 @@ linemap_line_start (line_maps *set, linenum_type to_line,
         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))
+         || SOURCE_COLUMN (map, highest) >= (loc_one
+                                             << (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))
@@ -913,11 +918,12 @@ linemap_line_start (line_maps *set, linenum_type 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))
+          + (location_t (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map))
              << column_bits));
     }
   else
-    r = set->highest_line + (line_delta << map->m_column_and_range_bits);
+    r = set->highest_line + (location_t (line_delta)
+                            << map->m_column_and_range_bits);
 
   /* Locations of ordinary tokens are always lower than locations of
      macro tokens.  */
@@ -992,7 +998,7 @@ linemap_position_for_column (line_maps *set, unsigned int 
to_column)
        }
     }
   line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
-  r = r + (to_column << map->m_range_bits);
+  r = r + (location_t (to_column) << map->m_range_bits);
   if (r >= set->highest_location)
     set->highest_location = r;
   return r;
@@ -1010,10 +1016,10 @@ linemap_position_for_line_and_column (line_maps *set,
   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))
+  r += (location_t (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))
+    r += ((column & ((loc_one << 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)
@@ -1050,10 +1056,12 @@ linemap_position_for_loc_and_offset (line_maps *set,
 
   /* We find the real location and shift it.  */
   loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map);
+  auto shifted_offset = location_t (column_offset) << map->m_range_bits;
+
   /* 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))
+  if (MAP_START_LOCATION (map) >= loc + shifted_offset)
     return loc;
 
   linenum_type line = SOURCE_LINE (map, loc);
@@ -1064,8 +1072,7 @@ linemap_position_for_loc_and_offset (line_maps *set,
      the next line map of the set.  Otherwise, we try to encode the
      location in the next map.  */
   for (; map != LINEMAPS_LAST_ORDINARY_MAP (set)
-        && (loc + (column_offset << map->m_range_bits)
-            >= MAP_START_LOCATION (map + 1)); map++)
+        && loc + shifted_offset >= MAP_START_LOCATION (map + 1); map++)
     /* If the next map is a different file, or starts in a higher line, we
        cannot encode the location there.  */
     if ((map + 1)->reason != LC_RENAME
@@ -1116,8 +1123,8 @@ linemap_ordinary_map_lookup (const line_maps *set, 
location_t line)
   if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
     return NULL;
 
-  unsigned mn = set->info_ordinary.m_cache;
-  unsigned mx = LINEMAPS_ORDINARY_USED (set);
+  auto mn = set->info_ordinary.m_cache;
+  auto mx = LINEMAPS_ORDINARY_USED (set);
 
   const line_map_ordinary *cached = LINEMAPS_ORDINARY_MAP_AT (set, mn);
   /* We should get a segfault if no line_maps have been added yet.  */
@@ -1134,7 +1141,7 @@ linemap_ordinary_map_lookup (const line_maps *set, 
location_t line)
 
   while (mx - mn > 1)
     {
-      unsigned md = (mn + mx) / 2;
+      auto md = (mn + mx) / 2;
       if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line)
        mx = md;
       else
@@ -1163,18 +1170,18 @@ linemap_macro_map_lookup (const line_maps *set, 
location_t line)
   if (set == NULL)
     return NULL;
 
-  unsigned ix = linemap_lookup_macro_index (set, line);
+  auto ix = linemap_lookup_macro_index (set, line);
   const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix);
   linemap_assert (MAP_START_LOCATION (result) <= line);
 
   return result;
 }
 
-unsigned
+line_map_uint_t
 linemap_lookup_macro_index (const line_maps *set, location_t line)
 {
-  unsigned mn = set->info_macro.m_cache;
-  unsigned mx = LINEMAPS_MACRO_USED (set);
+  auto mn = set->info_macro.m_cache;
+  auto mx = LINEMAPS_MACRO_USED (set);
   const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn);
 
   if (line >= MAP_START_LOCATION (cached))
@@ -1188,7 +1195,7 @@ linemap_lookup_macro_index (const line_maps *set, 
location_t line)
 
   while (mn < mx)
     {
-      unsigned md = (mx + mn) / 2;
+      auto md = (mx + mn) / 2;
       if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line)
        mn = md + 1;
       else
@@ -1529,7 +1536,10 @@ linemap_compare_locations (const line_maps *set,
   if (IS_ADHOC_LOC (l1))
     l1 = get_location_from_adhoc_loc (set, l1);
 
-  return l1 - l0;
+  /* This function is intended e.g. for implementing a qsort() comparator, so 
it
+     needs to return really an "int" and not something larger.  */
+  const location_diff_t res = l1 - l0;
+  return res < INT_MIN ? INT_MIN : res > INT_MAX ? INT_MAX : res;
 }
 
 /* Print an include trace, for e.g. the -H option of the preprocessor.  */
@@ -1914,7 +1924,8 @@ linemap_expand_location (const line_maps *set,
    dump a macro map, false otherwise.  */
 
 void
-linemap_dump (FILE *stream, const line_maps *set, unsigned ix, bool is_macro)
+linemap_dump (FILE *stream, const line_maps *set, line_map_uint_t ix,
+             bool is_macro)
 {
   const char *const lc_reasons_v[LC_HWM]
       = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
@@ -1936,8 +1947,10 @@ linemap_dump (FILE *stream, const line_maps *set, 
unsigned ix, bool is_macro)
       reason = LC_ENTER_MACRO;
     }
 
-  fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
-          ix, (void *) map, map->start_location,
+  fprintf (stream, "Map #%llu [%p] - LOC: %llu - REASON: %s - SYSP: %s\n",
+          (unsigned long long) ix,
+          (void *) map,
+          (unsigned long long) map->start_location,
           reason < LC_HWM ? lc_reasons_v[reason] : "???",
           ((!is_macro
             && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
@@ -1948,10 +1961,12 @@ linemap_dump (FILE *stream, const line_maps *set, 
unsigned ix, bool is_macro)
       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),
+      fprintf (stream, "File: %s:%u\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,
+      const long long from_ind
+       = includer_map ? includer_map - set->info_ordinary.maps : -1;
+      fprintf (stream, "Included from: [%lld] %s\n",
+              from_ind,
               includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
     }
   else
@@ -2010,8 +2025,10 @@ linemap_dump_location (const line_maps *set,
 
   /* 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);
+  fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%llu,R:%llu}",
+          path, from, l, c, s, (void*)map, e,
+          (unsigned long long) loc,
+          (unsigned long long) location);
 }
 
 /* Return the highest location emitted for a given file for which
@@ -2030,7 +2047,7 @@ linemap_get_file_highest_location (const line_maps *set,
     return false;
 
   /* Now look for the last ordinary map created for FILE_NAME.  */
-  int i;
+  location_diff_t i;
   for (i = set->info_ordinary.used - 1; i >= 0; --i)
     {
       const char *fname = set->info_ordinary.maps[i].to_file;
@@ -2045,7 +2062,7 @@ linemap_get_file_highest_location (const line_maps *set,
      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)
+  if ((location_t) i == set->info_ordinary.used - 1)
     result = set->highest_location;
   else
     result = set->info_ordinary.maps[i + 1].start_location - 1;
@@ -2122,10 +2139,10 @@ linemap_get_statistics (const line_maps *set,
    specifies how many macro maps to dump.  */
 
 void
-line_table_dump (FILE *stream, const line_maps *set, unsigned int num_ordinary,
-                unsigned int num_macro)
+line_table_dump (FILE *stream, const line_maps *set,
+                line_map_uint_t num_ordinary, line_map_uint_t num_macro)
 {
-  unsigned int i;
+  line_map_uint_t i;
 
   if (set == NULL)
     return;
@@ -2133,10 +2150,13 @@ line_table_dump (FILE *stream, const line_maps *set, 
unsigned int num_ordinary,
   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, "# of ordinary maps:  %llu\n",
+          (unsigned long long) LINEMAPS_ORDINARY_USED (set));
+  fprintf (stream, "# of macro maps:     %llu\n",
+          (unsigned long long) LINEMAPS_MACRO_USED (set));
   fprintf (stream, "Include stack depth: %d\n", set->depth);
-  fprintf (stream, "Highest location:    %u\n", set->highest_location);
+  fprintf (stream, "Highest location:    %llu\n",
+          (unsigned long long) set->highest_location);
 
   if (num_ordinary)
     {
diff --git a/libcpp/macro.cc b/libcpp/macro.cc
index 907af873df1..0b8eebee061 100644
--- a/libcpp/macro.cc
+++ b/libcpp/macro.cc
@@ -364,10 +364,10 @@ static cpp_hashnode* macro_of_context (cpp_context 
*context);
 
 /* Statistical counter tracking the number of macros that got
    expanded.  */
-unsigned num_expanded_macros_counter = 0;
+line_map_uint_t num_expanded_macros_counter = 0;
 /* Statistical counter tracking the total number tokens resulting
    from macro expansion.  */
-unsigned num_macro_tokens_counter = 0;
+line_map_uint_t num_macro_tokens_counter = 0;
 
 /* Wrapper around cpp_get_token to skip CPP_PADDING tokens
    and not consume CPP_EOF.  */

Reply via email to